o add ff lib
o add ff lib samples o add ff linux sample
This commit is contained in:
52
tools/ffsample/avr/Makefile_ata
Normal file
52
tools/ffsample/avr/Makefile_ata
Normal file
@@ -0,0 +1,52 @@
|
||||
TARGET = avr_ata
|
||||
CSRC = main.c uart.c ff.c ata.c rtc.c
|
||||
ASRC = xitoa.S
|
||||
MCU_TARGET = atmega64
|
||||
OPTIMIZE = -Os -mcall-prologues
|
||||
DEFS =
|
||||
LIBS =
|
||||
DEBUG = dwarf-2
|
||||
|
||||
CC = avr-gcc
|
||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
ALL_ASFLAGS = -mmcu=$(MCU_TARGET) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
CFLAGS = -g$(DEBUG) -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
LDFLAGS = -Wl,-Map,$(TARGET).map
|
||||
OBJ = $(CSRC:.c=.o) $(ASRC:.S=.o)
|
||||
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
|
||||
|
||||
|
||||
all: $(TARGET).elf lst text size
|
||||
|
||||
$(TARGET).elf: $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(TARGET).elf *.eps *.bak *.a
|
||||
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
|
||||
rm -rf $(TARGET).hex
|
||||
|
||||
size: $(TARGET).elf
|
||||
$(SIZE) -C --mcu=$(MCU_TARGET) $(TARGET).elf
|
||||
|
||||
lst: $(TARGET).lst
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
%.o : %.S
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
text: hex
|
||||
hex: $(TARGET).hex
|
||||
|
||||
%.hex: %.elf
|
||||
$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||
|
||||
|
||||
52
tools/ffsample/avr/Makefile_cfc
Normal file
52
tools/ffsample/avr/Makefile_cfc
Normal file
@@ -0,0 +1,52 @@
|
||||
TARGET = avr_cfc
|
||||
CSRC = main.c uart.c ff.c cfc.c rtc.c
|
||||
ASRC = xitoa.S
|
||||
MCU_TARGET = atmega64
|
||||
OPTIMIZE = -Os -mcall-prologues
|
||||
DEFS =
|
||||
LIBS =
|
||||
DEBUG = dwarf-2
|
||||
|
||||
CC = avr-gcc
|
||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
ALL_ASFLAGS = -mmcu=$(MCU_TARGET) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
CFLAGS = -g$(DEBUG) -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
LDFLAGS = -Wl,-Map,$(TARGET).map
|
||||
OBJ = $(CSRC:.c=.o) $(ASRC:.S=.o)
|
||||
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
|
||||
|
||||
|
||||
all: $(TARGET).elf lst text size
|
||||
|
||||
$(TARGET).elf: $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(TARGET).elf *.eps *.bak *.a
|
||||
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
|
||||
rm -rf $(TARGET).hex
|
||||
|
||||
size: $(TARGET).elf
|
||||
$(SIZE) -C --mcu=$(MCU_TARGET) $(TARGET).elf
|
||||
|
||||
lst: $(TARGET).lst
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
%.o : %.S
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
text: hex
|
||||
hex: $(TARGET).hex
|
||||
|
||||
%.hex: %.elf
|
||||
$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||
|
||||
|
||||
52
tools/ffsample/avr/Makefile_cfmm
Normal file
52
tools/ffsample/avr/Makefile_cfmm
Normal file
@@ -0,0 +1,52 @@
|
||||
TARGET = avr_cfmm
|
||||
CSRC = main.c uart.c ff.c cfmm.c rtc.c
|
||||
ASRC = xitoa.S
|
||||
MCU_TARGET = atmega64
|
||||
OPTIMIZE = -Os -mcall-prologues
|
||||
DEFS =
|
||||
LIBS =
|
||||
DEBUG = dwarf-2
|
||||
|
||||
CC = avr-gcc
|
||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
ALL_ASFLAGS = -mmcu=$(MCU_TARGET) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
CFLAGS = -g$(DEBUG) -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
LDFLAGS = -Wl,-Map,$(TARGET).map
|
||||
OBJ = $(CSRC:.c=.o) $(ASRC:.S=.o)
|
||||
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
|
||||
|
||||
|
||||
all: $(TARGET).elf lst text size
|
||||
|
||||
$(TARGET).elf: $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(TARGET).elf *.eps *.bak *.a
|
||||
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
|
||||
rm -rf $(TARGET).hex
|
||||
|
||||
size: $(TARGET).elf
|
||||
$(SIZE) -C --mcu=$(MCU_TARGET) $(TARGET).elf
|
||||
|
||||
lst: $(TARGET).lst
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
%.o : %.S
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
text: hex
|
||||
hex: $(TARGET).hex
|
||||
|
||||
%.hex: %.elf
|
||||
$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||
|
||||
|
||||
52
tools/ffsample/avr/Makefile_mmc
Normal file
52
tools/ffsample/avr/Makefile_mmc
Normal file
@@ -0,0 +1,52 @@
|
||||
TARGET = avr_mmc
|
||||
CSRC = main.c uart.c ff.c mmc.c rtc.c
|
||||
ASRC = xitoa.S
|
||||
MCU_TARGET = atmega64
|
||||
OPTIMIZE = -Os -mcall-prologues
|
||||
DEFS =
|
||||
LIBS =
|
||||
DEBUG = dwarf-2
|
||||
|
||||
CC = avr-gcc
|
||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
ALL_ASFLAGS = -mmcu=$(MCU_TARGET) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
CFLAGS = -g$(DEBUG) -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||
LDFLAGS = -Wl,-Map,$(TARGET).map
|
||||
OBJ = $(CSRC:.c=.o) $(ASRC:.S=.o)
|
||||
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
|
||||
|
||||
|
||||
all: $(TARGET).elf lst text size
|
||||
|
||||
$(TARGET).elf: $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(TARGET).elf *.eps *.bak *.a
|
||||
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
|
||||
rm -rf $(TARGET).hex
|
||||
|
||||
size: $(TARGET).elf
|
||||
$(SIZE) -C --mcu=$(MCU_TARGET) $(TARGET).elf
|
||||
|
||||
lst: $(TARGET).lst
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
%.o : %.S
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
text: hex
|
||||
hex: $(TARGET).hex
|
||||
|
||||
%.hex: %.elf
|
||||
$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||
|
||||
|
||||
453
tools/ffsample/avr/ata.c
Normal file
453
tools/ffsample/avr/ata.c
Normal file
@@ -0,0 +1,453 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* ATA control module (C)ChaN, 2007 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
#include "diskio.h"
|
||||
|
||||
|
||||
/* ATA command */
|
||||
#define CMD_RESET 0x08 /* DEVICE RESET */
|
||||
#define CMD_READ 0x20 /* READ SECTOR(S) */
|
||||
#define CMD_WRITE 0x30 /* WRITE SECTOR(S) */
|
||||
#define CMD_IDENTIFY 0xEC /* DEVICE IDENTIFY */
|
||||
#define CMD_SETFEATURES 0xEF /* SET FEATURES */
|
||||
|
||||
/* ATA register bit definitions */
|
||||
#define LBA 0x40
|
||||
#define BSY 0x80
|
||||
#define DRDY 0x40
|
||||
#define DF 0x20
|
||||
#define DRQ 0x08
|
||||
#define ERR 0x01
|
||||
#define SRST 0x40
|
||||
#define nIEN 0x20
|
||||
|
||||
/* Contorl Ports */
|
||||
#define CTRL_PORT PORTA
|
||||
#define CTRL_DDR DDRA
|
||||
#define DAT1_PORT PORTC
|
||||
#define DAT1_DDR DDRC
|
||||
#define DAT1_PIN PINC
|
||||
#define DAT0_PORT PORTD
|
||||
#define DAT0_DDR DDRD
|
||||
#define DAT0_PIN PIND
|
||||
|
||||
/* Bit definitions for Control Port */
|
||||
#define CTL_READ 0x20
|
||||
#define CTL_WRITE 0x40
|
||||
#define CTL_RESET 0x80
|
||||
#define REG_DATA 0xF0
|
||||
#define REG_ERROR 0xF1
|
||||
#define REG_FEATURES 0xF1
|
||||
#define REG_COUNT 0xF2
|
||||
#define REG_SECTOR 0xF3
|
||||
#define REG_CYLL 0xF4
|
||||
#define REG_CYLH 0xF5
|
||||
#define REG_DEV 0xF6
|
||||
#define REG_COMMAND 0xF7
|
||||
#define REG_STATUS 0xF7
|
||||
#define REG_DEVCTRL 0xEE
|
||||
#define REG_ALTSTAT 0xEE
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
static volatile
|
||||
WORD Timer; /* 100Hz decrement timer */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read an ATA register */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE read_ata (
|
||||
BYTE reg /* Register to be read */
|
||||
)
|
||||
{
|
||||
BYTE rd;
|
||||
|
||||
|
||||
CTRL_PORT = reg;
|
||||
CTRL_PORT &= ~CTL_READ;
|
||||
CTRL_PORT &= ~CTL_READ;
|
||||
CTRL_PORT &= ~CTL_READ;
|
||||
rd = DAT0_PIN;
|
||||
CTRL_PORT |= CTL_READ;
|
||||
return rd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write a byte to an ATA register */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void write_ata (
|
||||
BYTE reg, /* Register to be written */
|
||||
BYTE dat /* Data to be written */
|
||||
)
|
||||
{
|
||||
CTRL_PORT = reg;
|
||||
DAT0_PORT = dat;
|
||||
DAT0_DDR = 0xFF;
|
||||
CTRL_PORT &= ~CTL_WRITE;
|
||||
CTRL_PORT &= ~CTL_WRITE;
|
||||
CTRL_PORT |= CTL_WRITE;
|
||||
DAT0_PORT = 0xFF;
|
||||
DAT0_DDR = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read a part of data block */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void read_part (
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
BYTE ofs, /* Offset of the part of data in unit of word */
|
||||
BYTE count /* Number of word to pick up */
|
||||
)
|
||||
{
|
||||
BYTE c = 0, dl, dh;
|
||||
|
||||
|
||||
CTRL_PORT = REG_DATA; /* Select Data register */
|
||||
do {
|
||||
CTRL_PORT &= ~CTL_READ; /* IORD = L */
|
||||
CTRL_PORT &= ~CTL_READ; /* delay */
|
||||
dl = DAT0_PIN; /* Read even data */
|
||||
dh = DAT1_PIN; /* Read odd data */
|
||||
CTRL_PORT |= CTL_READ; /* IORD = H */
|
||||
if (count && (c >= ofs)) { /* Pick up a part of block */
|
||||
*buff++ = dl;
|
||||
*buff++ = dh;
|
||||
count--;
|
||||
}
|
||||
} while (++c);
|
||||
read_ata(REG_ALTSTAT);
|
||||
read_ata(REG_STATUS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait for Data Ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BOOL wait_data (void)
|
||||
{
|
||||
WORD w;
|
||||
BYTE s;
|
||||
|
||||
|
||||
cli(); Timer = 1000; sei(); /* Time out = 10 sec */
|
||||
do {
|
||||
cli(); w = Timer; sei();
|
||||
if (!w) return FALSE; /* Abort when timeout occured */
|
||||
s = read_ata(REG_STATUS); /* Get status */
|
||||
} while ((s & (BSY|DRQ)) != DRQ); /* Wait for BSY goes low and DRQ goes high */
|
||||
|
||||
read_ata(REG_ALTSTAT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
WORD w;
|
||||
|
||||
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
Stat |= STA_NOINIT;
|
||||
|
||||
/* Initialize the ATA control port */
|
||||
DAT0_PORT = 0xFF;
|
||||
DAT1_PORT = 0xFF;
|
||||
DAT0_DDR = 0;
|
||||
DAT1_DDR = 0;
|
||||
CTRL_PORT = CTL_READ | CTL_WRITE; /* Assert RESET */
|
||||
CTRL_DDR = 0xFF;
|
||||
|
||||
for (Timer = 2; Timer; ); /* 20ms */
|
||||
CTRL_PORT |= CTL_RESET; /* Deassert RESET */
|
||||
for (Timer = 1; Timer; ); /* 10ms */
|
||||
write_ata(REG_DEV, 0); /* Select Device 0 */
|
||||
|
||||
cli(); Timer = 1000; sei();
|
||||
do {
|
||||
cli(); w = Timer; sei();
|
||||
if (!w) return Stat;
|
||||
} while (!(read_ata(REG_STATUS) & (BSY | DRQ)));
|
||||
|
||||
write_ata(REG_DEVCTRL, SRST | nIEN); /* Software reset */
|
||||
for (Timer = 2; Timer; );
|
||||
write_ata(REG_DEVCTRL, nIEN);
|
||||
for (Timer = 2; Timer; );
|
||||
|
||||
cli(); Timer = 1000; sei();
|
||||
do {
|
||||
cli(); w = Timer; sei();
|
||||
if (!w) return Stat;
|
||||
} while ((read_ata(REG_STATUS) & (DRDY|BSY)) != DRDY);
|
||||
|
||||
write_ata(REG_FEATURES, 3); /* Select PIO default mode without IORDY */
|
||||
write_ata(REG_COUNT, 1);
|
||||
write_ata(REG_COMMAND, CMD_SETFEATURES);
|
||||
Timer = 100;
|
||||
do {
|
||||
if (!Timer) return Stat;
|
||||
} while (read_ata(REG_STATUS) & BSY);
|
||||
|
||||
|
||||
Stat &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Return Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
BYTE c, iord_l, iord_h;
|
||||
|
||||
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
/* Issue Read Setor(s) command */
|
||||
write_ata(REG_COUNT, count);
|
||||
write_ata(REG_SECTOR, (BYTE)sector);
|
||||
write_ata(REG_CYLL, (BYTE)(sector >> 8));
|
||||
write_ata(REG_CYLH, (BYTE)(sector >> 16));
|
||||
write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
|
||||
write_ata(REG_COMMAND, CMD_READ);
|
||||
|
||||
do {
|
||||
if (!wait_data()) return RES_ERROR; /* Wait data ready */
|
||||
CTRL_PORT = REG_DATA;
|
||||
iord_h = REG_DATA;
|
||||
iord_l = REG_DATA & ~CTL_READ;
|
||||
c = 128;
|
||||
do {
|
||||
CTRL_PORT = iord_l; /* IORD = L */
|
||||
CTRL_PORT = iord_l; /* delay */
|
||||
*buff++ = DAT0_PIN; /* Get even data */
|
||||
*buff++ = DAT1_PIN; /* Get odd data */
|
||||
CTRL_PORT = iord_h; /* IORD = H */
|
||||
CTRL_PORT = iord_l; /* IORD = L */
|
||||
CTRL_PORT = iord_l; /* delay */
|
||||
*buff++ = DAT0_PIN; /* Get even data */
|
||||
*buff++ = DAT1_PIN; /* Get odd data */
|
||||
CTRL_PORT = iord_h; /* IORD = H */
|
||||
} while (--c);
|
||||
} while (--count);
|
||||
|
||||
read_ata(REG_ALTSTAT);
|
||||
read_ata(REG_STATUS);
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
BYTE s, c, iowr_l, iowr_h;
|
||||
|
||||
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
/* Issue Write Setor(s) command */
|
||||
write_ata(REG_COUNT, count);
|
||||
write_ata(REG_SECTOR, (BYTE)sector);
|
||||
write_ata(REG_CYLL, (BYTE)(sector >> 8));
|
||||
write_ata(REG_CYLH, (BYTE)(sector >> 16));
|
||||
write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
|
||||
write_ata(REG_COMMAND, CMD_WRITE);
|
||||
|
||||
do {
|
||||
if (!wait_data()) return RES_ERROR;
|
||||
CTRL_PORT = REG_DATA;
|
||||
iowr_h = REG_DATA;
|
||||
iowr_l = REG_DATA & ~CTL_WRITE;
|
||||
DAT0_DDR = 0xFF; /* Set D0-D15 as output */
|
||||
DAT1_DDR = 0xFF;
|
||||
c = 128;
|
||||
do {
|
||||
DAT0_PORT = *buff++; /* Set even data */
|
||||
DAT1_PORT = *buff++; /* Set odd data */
|
||||
CTRL_PORT = iowr_l; /* IOWR = L */
|
||||
CTRL_PORT = iowr_h; /* IOWR = H */
|
||||
DAT0_PORT = *buff++; /* Set even data */
|
||||
DAT1_PORT = *buff++; /* Set odd data */
|
||||
CTRL_PORT = iowr_l; /* IOWR = L */
|
||||
CTRL_PORT = iowr_h; /* IOWR = H */
|
||||
} while (--c);
|
||||
DAT0_PORT = 0xFF; /* Set D0-D15 as input */
|
||||
DAT1_PORT = 0xFF;
|
||||
DAT0_DDR = 0;
|
||||
DAT1_DDR = 0;
|
||||
} while (--count);
|
||||
|
||||
Timer = 100;
|
||||
do {
|
||||
if (!Timer) return RES_ERROR;
|
||||
s = read_ata(REG_STATUS);
|
||||
} while (s & BSY);
|
||||
if (s & ERR) return RES_ERROR;
|
||||
|
||||
read_ata(REG_ALTSTAT);
|
||||
read_ata(REG_STATUS);
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
#endif /* _READONLY == 0 */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL != 0
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive data block */
|
||||
)
|
||||
{
|
||||
BYTE n, dl, dh, ofs, w, *ptr = buff;
|
||||
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
switch (ctrl) {
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
ofs = 60; w = 2; n = 0;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
|
||||
*(WORD*)buff = 512;
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */
|
||||
*(DWORD*)buff = 1;
|
||||
return RES_OK;
|
||||
|
||||
case CTRL_SYNC : /* Nothing to do */
|
||||
return RES_OK;
|
||||
|
||||
case ATA_GET_REV : /* Get firmware revision (8 chars) */
|
||||
ofs = 23; w = 4; n = 4;
|
||||
break;
|
||||
|
||||
case ATA_GET_MODEL : /* Get model name (40 chars) */
|
||||
ofs = 27; w = 20; n = 20;
|
||||
break;
|
||||
|
||||
case ATA_GET_SN : /* Get serial number (20 chars) */
|
||||
ofs = 10; w = 10; n = 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
write_ata(REG_COMMAND, CMD_IDENTIFY);
|
||||
if (!wait_data()) return RES_ERROR;
|
||||
read_part(ptr, ofs, w);
|
||||
while (n--) {
|
||||
dl = *ptr; dh = *(ptr+1);
|
||||
*ptr++ = dh; *ptr++ = dl;
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
#endif /* _USE_IOCTL != 0 */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Device timer interrupt procedure */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This function must be called in period of 10ms */
|
||||
|
||||
void disk_timerproc (void)
|
||||
{
|
||||
WORD n;
|
||||
|
||||
|
||||
n = Timer; /* 100Hz decrement timer */
|
||||
if (n) Timer = --n;
|
||||
}
|
||||
|
||||
BIN
tools/ffsample/avr/avr_ata.png
Normal file
BIN
tools/ffsample/avr/avr_ata.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
tools/ffsample/avr/avr_cfc.png
Normal file
BIN
tools/ffsample/avr/avr_cfc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
tools/ffsample/avr/avr_mmc.png
Normal file
BIN
tools/ffsample/avr/avr_mmc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
464
tools/ffsample/avr/cfc.c
Normal file
464
tools/ffsample/avr/cfc.c
Normal file
@@ -0,0 +1,464 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* CompactFlash control module (C)ChaN, 2007 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
#include "diskio.h"
|
||||
|
||||
|
||||
/* ATA command */
|
||||
#define CMD_RESET 0x08 /* DEVICE RESET */
|
||||
#define CMD_READ 0x20 /* READ SECTOR(S) */
|
||||
#define CMD_WRITE 0x30 /* WRITE SECTOR(S) */
|
||||
#define CMD_IDENTIFY 0xEC /* DEVICE IDENTIFY */
|
||||
#define CMD_SETFEATURES 0xEF /* SET FEATURES */
|
||||
|
||||
/* ATA register bit definitions */
|
||||
#define LBA 0xE0
|
||||
#define BUSY 0x80
|
||||
#define DRDY 0x40
|
||||
#define DF 0x20
|
||||
#define DRQ 0x08
|
||||
#define ERR 0x01
|
||||
#define SRST 0x40
|
||||
#define nIEN 0x20
|
||||
|
||||
/* Contorl Ports */
|
||||
#define CTRL_PORT PORTA
|
||||
#define CTRL_DDR DDRA
|
||||
#define SOCK_PORT PORTC
|
||||
#define SOCK_DDR DDRC
|
||||
#define SOCK_PIN PINC
|
||||
#define DAT0_PORT PORTD
|
||||
#define DAT0_DDR DDRD
|
||||
#define DAT0_PIN PIND
|
||||
#define SOCKINS 0x03
|
||||
#define SOCKPWR 0x04
|
||||
|
||||
/* Bit definitions for Control Port */
|
||||
#define CTL_READ 0x20
|
||||
#define CTL_WRITE 0x40
|
||||
#define CTL_RESET 0x80
|
||||
#define REG_DATA 0xF0
|
||||
#define REG_ERROR 0xF1
|
||||
#define REG_FEATURES 0xF1
|
||||
#define REG_COUNT 0xF2
|
||||
#define REG_SECTOR 0xF3
|
||||
#define REG_CYLL 0xF4
|
||||
#define REG_CYLH 0xF5
|
||||
#define REG_DEV 0xF6
|
||||
#define REG_COMMAND 0xF7
|
||||
#define REG_STATUS 0xF7
|
||||
#define REG_DEVCTRL 0xEE
|
||||
#define REG_ALTSTAT 0xEE
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
static volatile
|
||||
BYTE Timer; /* 100Hz decrement timer */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read an ATA register */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE read_ata (
|
||||
BYTE reg /* Register to be read */
|
||||
)
|
||||
{
|
||||
BYTE rd;
|
||||
|
||||
|
||||
CTRL_PORT = reg;
|
||||
CTRL_PORT &= ~CTL_READ;
|
||||
CTRL_PORT &= ~CTL_READ;
|
||||
CTRL_PORT &= ~CTL_READ;
|
||||
rd = DAT0_PIN;
|
||||
CTRL_PORT |= CTL_READ;
|
||||
return rd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write a byte to an ATA register */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void write_ata (
|
||||
BYTE reg, /* Register to be written */
|
||||
BYTE dat /* Data to be written */
|
||||
)
|
||||
{
|
||||
CTRL_PORT = reg;
|
||||
DAT0_PORT = dat;
|
||||
DAT0_DDR = 0xFF;
|
||||
CTRL_PORT &= ~CTL_WRITE;
|
||||
CTRL_PORT &= ~CTL_WRITE;
|
||||
CTRL_PORT |= CTL_WRITE;
|
||||
DAT0_PORT = 0xFF;
|
||||
DAT0_DDR = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read a part of data block */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void read_part (
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
BYTE ofs, /* Offset of the part of data in unit of word */
|
||||
BYTE count /* Number of word to pick up */
|
||||
)
|
||||
{
|
||||
BYTE c = 0, dl, dh;
|
||||
|
||||
|
||||
CTRL_PORT = REG_DATA; /* Select Data register */
|
||||
do {
|
||||
CTRL_PORT &= ~CTL_READ; /* IORD = L */
|
||||
CTRL_PORT &= ~CTL_READ; /* delay */
|
||||
dl = DAT0_PIN; /* Read Even data */
|
||||
CTRL_PORT |= CTL_READ; /* IORD = H */
|
||||
CTRL_PORT &= ~CTL_READ; /* IORD = L */
|
||||
CTRL_PORT &= ~CTL_READ; /* delay */
|
||||
dh = DAT0_PIN; /* Read Odd data */
|
||||
CTRL_PORT |= CTL_READ; /* IORD = H */
|
||||
if (count && (c >= ofs)) { /* Pick up a part of block */
|
||||
*buff++ = dl;
|
||||
*buff++ = dh;
|
||||
count--;
|
||||
}
|
||||
} while (++c);
|
||||
read_ata(REG_ALTSTAT);
|
||||
read_ata(REG_STATUS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait for Data Ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BOOL wait_data (void)
|
||||
{
|
||||
BYTE s;
|
||||
|
||||
|
||||
Timer = 100; /* Time out = 1 sec */
|
||||
do {
|
||||
if (!Timer) return FALSE; /* Abort when timeout occured */
|
||||
s = read_ata(REG_STATUS); /* Get status */
|
||||
} while ((s & (BUSY|DRQ)) != DRQ); /* Wait for BUSY goes low and DRQ goes high */
|
||||
|
||||
read_ata(REG_ALTSTAT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
|
||||
Stat |= STA_NOINIT;
|
||||
|
||||
SOCK_PORT = 0xFF; /* Power OFF */
|
||||
SOCK_DDR = SOCKPWR;
|
||||
DAT0_PORT = 0;
|
||||
CTRL_DDR = 0;
|
||||
for (Timer = 10; Timer; ); /* 100ms */
|
||||
|
||||
if (Stat & STA_NODISK) return Stat; /* Exit when socket is empty */
|
||||
|
||||
/* Initialize CFC control port */
|
||||
SOCK_PORT &= ~SOCKPWR; /* Power ON */
|
||||
for (Timer = 1; Timer; ); /* 10ms */
|
||||
CTRL_PORT = CTL_READ | CTL_WRITE; /* Enable control signals */
|
||||
CTRL_DDR = 0xFF;
|
||||
DAT0_PORT = 0xFF; /* Pull-up D0-D7 */
|
||||
for (Timer = 5; Timer; ); /* 50ms */
|
||||
CTRL_PORT |= CTL_RESET; /* RESET = H */
|
||||
for (Timer = 5; Timer; ); /* 50ms */
|
||||
write_ata(REG_DEV, LBA); /* Select Device 0 */
|
||||
Timer = 200;
|
||||
do { /* Wait for card goes ready */
|
||||
if (!Timer) return Stat;
|
||||
} while (read_ata(REG_STATUS) & BUSY);
|
||||
|
||||
write_ata(REG_DEVCTRL, SRST | nIEN); /* Software reset */
|
||||
for (Timer = 2; Timer; ); /* 20ms */
|
||||
write_ata(REG_DEVCTRL, nIEN); /* Release software reset */
|
||||
for (Timer = 2; Timer; ); /* 20ms */
|
||||
Timer = 200;
|
||||
do { /* Wait for card goes ready */
|
||||
if (!Timer) return Stat;
|
||||
} while ((read_ata(REG_STATUS) & (DRDY|BUSY)) != DRDY);
|
||||
|
||||
write_ata(REG_FEATURES, 0x01); /* Select 8-bit PIO transfer mode */
|
||||
write_ata(REG_COMMAND, CMD_SETFEATURES);
|
||||
Timer = 100;
|
||||
do {
|
||||
if (!Timer) return Stat;
|
||||
} while (read_ata(REG_STATUS) & BUSY);
|
||||
|
||||
Stat &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Return Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
BYTE c, iord_l, iord_h;
|
||||
|
||||
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
/* Issue Read Setor(s) command */
|
||||
write_ata(REG_COUNT, count);
|
||||
write_ata(REG_SECTOR, (BYTE)sector);
|
||||
write_ata(REG_CYLL, (BYTE)(sector >> 8));
|
||||
write_ata(REG_CYLH, (BYTE)(sector >> 16));
|
||||
write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
|
||||
write_ata(REG_COMMAND, CMD_READ);
|
||||
|
||||
do {
|
||||
if (!wait_data()) return RES_ERROR; /* Wait data ready */
|
||||
CTRL_PORT = REG_DATA;
|
||||
iord_h = REG_DATA;
|
||||
iord_l = REG_DATA & ~CTL_READ;
|
||||
c = 0;
|
||||
do {
|
||||
CTRL_PORT = iord_l; /* IORD = L */
|
||||
CTRL_PORT = iord_l; /* delay */
|
||||
CTRL_PORT = iord_l; /* delay */
|
||||
*buff++ = DAT0_PIN; /* Get even data */
|
||||
CTRL_PORT = iord_h; /* IORD = H */
|
||||
CTRL_PORT = iord_l; /* IORD = L */
|
||||
CTRL_PORT = iord_l; /* delay */
|
||||
CTRL_PORT = iord_l; /* delay */
|
||||
*buff++ = DAT0_PIN; /* Get Odd data */
|
||||
CTRL_PORT = iord_h; /* IORD = H */
|
||||
} while (--c);
|
||||
} while (--count);
|
||||
|
||||
read_ata(REG_ALTSTAT);
|
||||
read_ata(REG_STATUS);
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
BYTE s, c, iowr_l, iowr_h;
|
||||
|
||||
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
/* Issue Write Setor(s) command */
|
||||
write_ata(REG_COUNT, count);
|
||||
write_ata(REG_SECTOR, (BYTE)sector);
|
||||
write_ata(REG_CYLL, (BYTE)(sector >> 8));
|
||||
write_ata(REG_CYLH, (BYTE)(sector >> 16));
|
||||
write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
|
||||
write_ata(REG_COMMAND, CMD_WRITE);
|
||||
|
||||
do {
|
||||
if (!wait_data()) return RES_ERROR;
|
||||
CTRL_PORT = REG_DATA;
|
||||
iowr_h = REG_DATA;
|
||||
iowr_l = REG_DATA & ~CTL_WRITE;
|
||||
DAT0_DDR = 0xFF; /* Set D0-D7 as output */
|
||||
c = 0;
|
||||
do {
|
||||
DAT0_PORT = *buff++; /* Set even data */
|
||||
CTRL_PORT = iowr_l; /* IOWR = L */
|
||||
CTRL_PORT = iowr_h; /* IOWR = H */
|
||||
DAT0_PORT = *buff++; /* Set odd data */
|
||||
CTRL_PORT = iowr_l; /* IOWR = L */
|
||||
CTRL_PORT = iowr_h; /* IOWR = H */
|
||||
} while (--c);
|
||||
DAT0_PORT = 0xFF; /* Set D0-D7 as input */
|
||||
DAT0_DDR = 0;
|
||||
} while (--count);
|
||||
|
||||
Timer = 100;
|
||||
do {
|
||||
if (!Timer) return RES_ERROR;
|
||||
s = read_ata(REG_STATUS);
|
||||
} while (s & BUSY);
|
||||
if (s & ERR) return RES_ERROR;
|
||||
|
||||
read_ata(REG_ALTSTAT);
|
||||
read_ata(REG_STATUS);
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL != 0
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive data block */
|
||||
)
|
||||
{
|
||||
BYTE n, w, ofs, dl, dh, *ptr = buff;
|
||||
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
switch (ctrl) {
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
ofs = 60; w = 2; n = 0;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
|
||||
*(WORD*)buff = 512;
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */
|
||||
*(DWORD*)buff = 32;
|
||||
return RES_OK;
|
||||
|
||||
case CTRL_SYNC : /* Nothing to do */
|
||||
return RES_OK;
|
||||
|
||||
case ATA_GET_REV : /* Get firmware revision (8 chars) */
|
||||
ofs = 23; w = 4; n = 4;
|
||||
break;
|
||||
|
||||
case ATA_GET_MODEL : /* Get model name (40 chars) */
|
||||
ofs = 27; w = 20; n = 20;
|
||||
break;
|
||||
|
||||
case ATA_GET_SN : /* Get serial number (20 chars) */
|
||||
ofs = 10; w = 10; n = 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
write_ata(REG_COMMAND, CMD_IDENTIFY);
|
||||
if (!wait_data()) return RES_ERROR;
|
||||
read_part(ptr, ofs, w);
|
||||
while (n--) {
|
||||
dl = *ptr; dh = *(ptr+1);
|
||||
*ptr++ = dh; *ptr++ = dl;
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
#endif /* _USE_IOCTL != 0 */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Device timer interrupt procedure */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This function must be called in period of 10ms */
|
||||
|
||||
|
||||
void disk_timerproc (void)
|
||||
{
|
||||
static BYTE pv;
|
||||
BYTE n;
|
||||
|
||||
|
||||
n = Timer; /* 100Hz decrement timer */
|
||||
if (n) Timer = --n;
|
||||
|
||||
n = pv;
|
||||
pv = SOCK_PIN & SOCKINS; /* Sapmle socket switch */
|
||||
|
||||
if (n == pv) { /* Have contacts stabled? */
|
||||
if (pv & SOCKINS) { /* CD1 or CD2 is high (Socket empty) */
|
||||
Stat |= (STA_NODISK | STA_NOINIT);
|
||||
DAT0_DDR = 0; DAT0_PORT = 0; /* Float D0-D7 */
|
||||
CTRL_DDR = CTL_RESET; CTRL_PORT = 0; /* Assert RESET# */
|
||||
SOCK_PORT |= SOCKPWR; /* Power OFF */
|
||||
} else { /* CD1 and CD2 are low (Card inserted) */
|
||||
Stat &= ~STA_NODISK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1038
tools/ffsample/avr/cfmm.c
Normal file
1038
tools/ffsample/avr/cfmm.c
Normal file
File diff suppressed because it is too large
Load Diff
81
tools/ffsample/avr/diskio.h
Normal file
81
tools/ffsample/avr/diskio.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file R0.05 (C)ChaN, 2007
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Read-only mode */
|
||||
#define _USE_IOCTL 1
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
#endif
|
||||
DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||
void disk_timerproc (void);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl() */
|
||||
|
||||
/* Generic command */
|
||||
#define CTRL_SYNC 0 /* Mandatory for write functions */
|
||||
#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */
|
||||
#define GET_SECTOR_SIZE 2
|
||||
#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */
|
||||
#define CTRL_POWER 4
|
||||
#define CTRL_LOCK 5
|
||||
#define CTRL_EJECT 6
|
||||
/* MMC/SDC command */
|
||||
#define MMC_GET_TYPE 10
|
||||
#define MMC_GET_CSD 11
|
||||
#define MMC_GET_CID 12
|
||||
#define MMC_GET_OCR 13
|
||||
#define MMC_GET_SDSTAT 14
|
||||
/* ATA/CF command */
|
||||
#define ATA_GET_REV 20
|
||||
#define ATA_GET_MODEL 21
|
||||
#define ATA_GET_SN 22
|
||||
|
||||
|
||||
|
||||
/* Card type flags (CardType) */
|
||||
#define CT_MMC 0x01
|
||||
#define CT_SD1 0x02
|
||||
#define CT_SD2 0x04
|
||||
#define CT_SDC (CT_SD1|CT_SD2)
|
||||
#define CT_BLOCK 0x08
|
||||
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
||||
2936
tools/ffsample/avr/ff.c
Normal file
2936
tools/ffsample/avr/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
547
tools/ffsample/avr/ff.h
Normal file
547
tools/ffsample/avr/ff.h
Normal file
@@ -0,0 +1,547 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.07a (C)ChaN, 2009
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is an open source software to implement FAT file system to
|
||||
/ small embedded systems. This is a free software and is opened for education,
|
||||
/ research and commercial developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Configuration Options
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FATFS
|
||||
#define _FATFS
|
||||
|
||||
#define _WORD_ACCESS 1
|
||||
/* The _WORD_ACCESS option defines which access method is used to the word
|
||||
/ data in the FAT structure.
|
||||
/
|
||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned
|
||||
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code efficiency. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||
/ 3: f_lseek is removed in addition to level 2. */
|
||||
|
||||
|
||||
#define _FS_TINY 1
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _DRIVES 2
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512
|
||||
/* Maximum sector size to be handled. (512/1024/2048/4096) */
|
||||
/* 512 for memroy card and hard disk, 1024 for floppy disk, 2048 for MO disk */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
||||
/ drive number and can mount only first primaly partition. When it is set to 1,
|
||||
/ each volume is tied to the partitions listed in Drives[]. */
|
||||
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ When it is non LFN configuration, there is no difference between SBCS code
|
||||
/ pages. When LFN is enabled, the code page must always be set correctly.
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift-JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
/ 1258 - Vietnam
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (max:255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN.
|
||||
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
||||
/ 2: Enable LFN with dynamic working buffer on the caller's STACK.
|
||||
/
|
||||
/ The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
||||
/ a Unicode - OEM code conversion function ff_convert() must be added to
|
||||
/ the project. */
|
||||
|
||||
|
||||
#define _FS_REENTRANT 0
|
||||
#define _TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* Type of sync object used on the OS. */
|
||||
/* e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
|
||||
/ provided synchronization handlers, ff_req_grant, ff_rel_grant,
|
||||
/ ff_del_syncobj and ff_cre_syncobj function to the project. */
|
||||
|
||||
|
||||
|
||||
/* End of configuration options. Do not change followings without care. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multiple sector size */
|
||||
|
||||
#if _MAX_SS == 512
|
||||
#define SS(fs) 512
|
||||
#else
|
||||
#if _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
|
||||
#define SS(fs) ((fs)->s_size)
|
||||
#else
|
||||
#error Sector size must be 512, 1024, 2048 or 4096.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure */
|
||||
|
||||
typedef struct _FATFS {
|
||||
BYTE fs_type; /* FAT sub type */
|
||||
BYTE drive; /* Physical drive number */
|
||||
BYTE csize; /* Number of sectors per cluster */
|
||||
BYTE n_fats; /* Number of FAT copies */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE pad1;
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if _MAX_SS != 512U
|
||||
WORD s_size; /* Sector size */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
BYTE pad2;
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector */
|
||||
#endif
|
||||
DWORD sects_fat; /* Sectors per fat */
|
||||
DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure */
|
||||
|
||||
typedef struct _DIR {
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current index number */
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
DWORD sclust; /* Table start cluster (0:Static table) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File object structure */
|
||||
|
||||
typedef struct _FIL {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE csect; /* Sector address in the cluster */
|
||||
DWORD fptr; /* File R/W pointer */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS];/* File R/W buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* File status structure */
|
||||
|
||||
typedef struct _FILINFO {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
char fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
char *lfname; /* Pointer to the LFN buffer */
|
||||
int lfsize; /* Size of LFN buffer [bytes] */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* DBCS code ranges */
|
||||
|
||||
#if _CODE_PAGE == 932 /* CP932 (Japanese Shift-JIS) */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* CP936 (Simplified Chinese GBK) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* CP949 (Korean) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* CP950 (Traditional Chinese Big5) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#else /* SBCS code pages */
|
||||
#define _DF1S 0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Character code support macros */
|
||||
|
||||
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
||||
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
||||
#define IsDigit(c) (((c)>='0')&&((c)<='9'))
|
||||
|
||||
#if _DF1S /* DBCS configuration */
|
||||
|
||||
#if _DF2S /* Two 1st byte areas */
|
||||
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
||||
#else /* One 1st byte area */
|
||||
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
||||
#endif
|
||||
|
||||
#if _DS3S /* Three 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
||||
#else /* Two 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
||||
#endif
|
||||
|
||||
#else /* SBCS configuration */
|
||||
|
||||
#define IsDBCS1(c) 0
|
||||
#define IsDBCS2(c) 0
|
||||
|
||||
#endif /* _DF1S */
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multi partition */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
|
||||
typedef struct _PARTITION {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
|
||||
extern
|
||||
const PARTITION Drives[]; /* Logical drive# to physical location conversion table */
|
||||
#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */
|
||||
#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
|
||||
#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */
|
||||
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* 0 */
|
||||
FR_DISK_ERR, /* 1 */
|
||||
FR_INT_ERR, /* 2 */
|
||||
FR_NOT_READY, /* 3 */
|
||||
FR_NO_FILE, /* 4 */
|
||||
FR_NO_PATH, /* 5 */
|
||||
FR_INVALID_NAME, /* 6 */
|
||||
FR_DENIED, /* 7 */
|
||||
FR_EXIST, /* 8 */
|
||||
FR_INVALID_OBJECT, /* 9 */
|
||||
FR_WRITE_PROTECTED, /* 10 */
|
||||
FR_INVALID_DRIVE, /* 11 */
|
||||
FR_NOT_ENABLED, /* 12 */
|
||||
FR_NO_FILESYSTEM, /* 13 */
|
||||
FR_MKFS_ABORTED, /* 14 */
|
||||
FR_TIMEOUT /* 15 */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
|
||||
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const char*); /* Create a new directory */
|
||||
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const char*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||
|
||||
#if _USE_STRFUNC
|
||||
int f_putc (int, FIL*); /* Put a character to the file */
|
||||
int f_puts (const char*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */
|
||||
char* f_gets (char*, int, FIL*); /* Get a string from the file */
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#ifndef EOF
|
||||
#define EOF -1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* User defined functions */
|
||||
|
||||
/* Real time clock */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
|
||||
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
|
||||
#endif
|
||||
|
||||
/* Unicode - OEM code conversion */
|
||||
#if _USE_LFN
|
||||
WCHAR ff_convert (WCHAR, UINT);
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
|
||||
BOOL ff_del_syncobj(_SYNC_t);
|
||||
BOOL ff_req_grant(_SYNC_t);
|
||||
void ff_rel_grant(_SYNC_t);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#if _FS_READONLY == 0
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* FatFs refers the members in the FAT structures with byte offset instead
|
||||
/ of structure member because there are incompatibility of the packing option
|
||||
/ between various compilers. */
|
||||
|
||||
#define BS_jmpBoot 0
|
||||
#define BS_OEMName 3
|
||||
#define BPB_BytsPerSec 11
|
||||
#define BPB_SecPerClus 13
|
||||
#define BPB_RsvdSecCnt 14
|
||||
#define BPB_NumFATs 16
|
||||
#define BPB_RootEntCnt 17
|
||||
#define BPB_TotSec16 19
|
||||
#define BPB_Media 21
|
||||
#define BPB_FATSz16 22
|
||||
#define BPB_SecPerTrk 24
|
||||
#define BPB_NumHeads 26
|
||||
#define BPB_HiddSec 28
|
||||
#define BPB_TotSec32 32
|
||||
#define BS_55AA 510
|
||||
|
||||
#define BS_DrvNum 36
|
||||
#define BS_BootSig 38
|
||||
#define BS_VolID 39
|
||||
#define BS_VolLab 43
|
||||
#define BS_FilSysType 54
|
||||
|
||||
#define BPB_FATSz32 36
|
||||
#define BPB_ExtFlags 40
|
||||
#define BPB_FSVer 42
|
||||
#define BPB_RootClus 44
|
||||
#define BPB_FSInfo 48
|
||||
#define BPB_BkBootSec 50
|
||||
#define BS_DrvNum32 64
|
||||
#define BS_BootSig32 66
|
||||
#define BS_VolID32 67
|
||||
#define BS_VolLab32 71
|
||||
#define BS_FilSysType32 82
|
||||
|
||||
#define FSI_LeadSig 0
|
||||
#define FSI_StrucSig 484
|
||||
#define FSI_Free_Count 488
|
||||
#define FSI_Nxt_Free 492
|
||||
|
||||
#define MBR_Table 446
|
||||
|
||||
#define DIR_Name 0
|
||||
#define DIR_Attr 11
|
||||
#define DIR_NTres 12
|
||||
#define DIR_CrtTime 14
|
||||
#define DIR_CrtDate 16
|
||||
#define DIR_FstClusHI 20
|
||||
#define DIR_WrtTime 22
|
||||
#define DIR_WrtDate 24
|
||||
#define DIR_FstClusLO 26
|
||||
#define DIR_FileSize 28
|
||||
#define LDIR_Ord 0
|
||||
#define LDIR_Attr 11
|
||||
#define LDIR_Type 12
|
||||
#define LDIR_Chksum 13
|
||||
#define LDIR_FstClusLO 26
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _FATFS */
|
||||
37
tools/ffsample/avr/integer.h
Normal file
37
tools/ffsample/avr/integer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef signed char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* Boolean type */
|
||||
typedef enum { FALSE = 0, TRUE } BOOL;
|
||||
|
||||
#endif
|
||||
|
||||
#define _INTEGER
|
||||
#endif
|
||||
556
tools/ffsample/avr/main.c
Normal file
556
tools/ffsample/avr/main.c
Normal file
@@ -0,0 +1,556 @@
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* FAT file system sample project for FatFs R0.06 (C)ChaN, 2008 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
#include "uart.h"
|
||||
#include "xitoa.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
|
||||
DWORD acc_size; /* Work register for fs command */
|
||||
WORD acc_files, acc_dirs;
|
||||
FILINFO finfo;
|
||||
|
||||
BYTE line[120]; /* Console input buffer */
|
||||
|
||||
FATFS fatfs[2]; /* File system object for each logical drive */
|
||||
BYTE Buff[1024]; /* Working buffer */
|
||||
|
||||
|
||||
volatile WORD Timer; /* 100Hz increment timer */
|
||||
|
||||
|
||||
|
||||
#if _MULTI_PARTITION != 0
|
||||
const PARTITION Drives[] = { {0,0}, {0,1} };
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* 100Hz timer interrupt generated by OC2 */
|
||||
/*---------------------------------------------------------*/
|
||||
|
||||
|
||||
ISR(TIMER2_COMP_vect)
|
||||
{
|
||||
Timer++; /* Performance counter for this module */
|
||||
disk_timerproc(); /* Drive timer procedure of low level disk I/O module */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* User Provided Timer Function for FatFs module */
|
||||
/*---------------------------------------------------------*/
|
||||
/* This is a real time clock service to be called from */
|
||||
/* FatFs module. Any valid time must be returned even if */
|
||||
/* the system does not support a real time clock. */
|
||||
/* This is not required in read-only configuration. */
|
||||
|
||||
|
||||
DWORD get_fattime ()
|
||||
{
|
||||
RTC rtc;
|
||||
|
||||
|
||||
rtc_gettime(&rtc);
|
||||
|
||||
return ((DWORD)(rtc.year - 1980) << 25)
|
||||
| ((DWORD)rtc.month << 21)
|
||||
| ((DWORD)rtc.mday << 16)
|
||||
| ((DWORD)rtc.hour << 11)
|
||||
| ((DWORD)rtc.min << 5)
|
||||
| ((DWORD)rtc.sec >> 1);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Monitor */
|
||||
|
||||
|
||||
static
|
||||
void put_dump (const BYTE *buff, uint32_t ofs, BYTE cnt)
|
||||
{
|
||||
BYTE n;
|
||||
|
||||
|
||||
xprintf(PSTR("%08lX "), ofs);
|
||||
for(n = 0; n < cnt; n++)
|
||||
xprintf(PSTR(" %02X"), buff[n]);
|
||||
xputc(' ');
|
||||
for(n = 0; n < cnt; n++) {
|
||||
if ((buff[n] < 0x20)||(buff[n] >= 0x7F))
|
||||
xputc('.');
|
||||
else
|
||||
xputc(buff[n]);
|
||||
}
|
||||
xputc('\n');
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void get_line (char *buff, int len)
|
||||
{
|
||||
char c;
|
||||
int idx = 0;
|
||||
|
||||
|
||||
for (;;) {
|
||||
c = uart_get();
|
||||
if (c == '\r') break;
|
||||
if ((c == '\b') && idx) {
|
||||
idx--; uart_put(c);
|
||||
}
|
||||
if (((BYTE)c >= ' ') && (idx < len - 1)) {
|
||||
buff[idx++] = c; uart_put(c);
|
||||
}
|
||||
}
|
||||
buff[idx] = 0;
|
||||
uart_put(c);
|
||||
uart_put('\n');
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
FRESULT scan_files (char* path)
|
||||
{
|
||||
DIR dirs;
|
||||
FRESULT res;
|
||||
int i;
|
||||
|
||||
if ((res = f_opendir(&dirs, path)) == FR_OK) {
|
||||
i = strlen(path);
|
||||
while (((res = f_readdir(&dirs, &finfo)) == FR_OK) && finfo.fname[0]) {
|
||||
if (finfo.fattrib & AM_DIR) {
|
||||
acc_dirs++;
|
||||
*(path+i) = '/'; strcpy(path+i+1, &finfo.fname[0]);
|
||||
res = scan_files(path);
|
||||
*(path+i) = '\0';
|
||||
if (res != FR_OK) break;
|
||||
} else {
|
||||
acc_files++;
|
||||
acc_size += finfo.fsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void put_rc (FRESULT rc)
|
||||
{
|
||||
const prog_char *p;
|
||||
static const prog_char str[] =
|
||||
"OK\0" "DISK_ERR\0" "INT_ERR\0" "NOT_READY\0" "NO_FILE\0" "NO_PATH\0"
|
||||
"INVALID_NAME\0" "DENIED\0" "EXIST\0" "INVALID_OBJECT\0" "WRITE_PROTECTED\0"
|
||||
"INVALID_DRIVE\0" "NOT_ENABLED\0" "NO_FILE_SYSTEM\0" "MKFS_ABORTED\0" "TIMEOUT\0";
|
||||
FRESULT i;
|
||||
|
||||
for (p = str, i = 0; i != rc && pgm_read_byte_near(p); i++) {
|
||||
while(pgm_read_byte_near(p++));
|
||||
}
|
||||
xprintf(PSTR("rc=%u FR_%S\n"), (WORD)rc, p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
void IoInit ()
|
||||
{
|
||||
PORTA = 0b11111111; // Port A
|
||||
|
||||
PORTB = 0b10110000; // Port B
|
||||
DDRB = 0b11000000;
|
||||
|
||||
PORTC = 0b11111111; // Port C
|
||||
|
||||
PORTD = 0b11111111; // Port D
|
||||
|
||||
PORTE = 0b11110010; // Port E
|
||||
DDRE = 0b10000010;
|
||||
|
||||
PORTF = 0b11111111; // Port F
|
||||
|
||||
PORTG = 0b11111; // Port G
|
||||
|
||||
uart_init(); // Initialize UART driver
|
||||
|
||||
/*
|
||||
OCR1A = 51; // Timer1: LCD bias generator (OC1B)
|
||||
OCR1B = 51;
|
||||
TCCR1A = 0b00010000;
|
||||
TCCR1B = 0b00001010;
|
||||
*/
|
||||
OCR2 = 90-1; // Timer2: 100Hz interval (OC2)
|
||||
TCCR2 = 0b00001101;
|
||||
|
||||
TIMSK = 0b10000000; // Enable TC2.oc, interrupt
|
||||
|
||||
rtc_init(); // Initialize RTC
|
||||
|
||||
sei();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Main */
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
char *ptr, *ptr2;
|
||||
DWORD p1, p2, p3;
|
||||
BYTE res, b1;
|
||||
WORD w1;
|
||||
UINT s1, s2, cnt;
|
||||
DWORD ofs, sect = 0;
|
||||
RTC rtc;
|
||||
FATFS *fs;
|
||||
DIR dir; /* Directory object */
|
||||
FIL file1, file2; /* File object */
|
||||
|
||||
|
||||
IoInit();
|
||||
|
||||
/* Join xitoa module to uart module */
|
||||
xfunc_out = (void (*)(char))uart_put;
|
||||
|
||||
xputs(PSTR("FatFs module test monitor\n"));
|
||||
|
||||
for (;;) {
|
||||
xputc('>');
|
||||
get_line(line, sizeof(line));
|
||||
ptr = line;
|
||||
|
||||
switch (*ptr++) {
|
||||
|
||||
case 'd' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* dd <phy_drv#> [<sector>] - Dump secrtor */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) p2 = sect;
|
||||
res = disk_read((BYTE)p1, Buff, p2, 1);
|
||||
if (res) { xprintf(PSTR("rc=%d\n"), (WORD)res); break; }
|
||||
sect = p2 + 1;
|
||||
xprintf(PSTR("Sector:%lu\n"), p2);
|
||||
for (ptr=Buff, ofs = 0; ofs < 0x200; ptr+=16, ofs+=16)
|
||||
put_dump(ptr, ofs, 16);
|
||||
break;
|
||||
|
||||
case 'i' : /* di <phy_drv#> - Initialize disk */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
xprintf(PSTR("rc=%d\n"), (WORD)disk_initialize((BYTE)p1));
|
||||
break;
|
||||
|
||||
case 's' : /* ds <phy_drv#> - Show disk status */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &p2) == RES_OK)
|
||||
{ xprintf(PSTR("Drive size: %lu sectors\n"), p2); }
|
||||
if (disk_ioctl((BYTE)p1, GET_SECTOR_SIZE, &w1) == RES_OK)
|
||||
{ xprintf(PSTR("Sector size: %u\n"), w1); }
|
||||
if (disk_ioctl((BYTE)p1, GET_BLOCK_SIZE, &p2) == RES_OK)
|
||||
{ xprintf(PSTR("Erase block size: %lu sectors\n"), p2); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_TYPE, &b1) == RES_OK)
|
||||
{ xprintf(PSTR("Card type: %u\n"), b1); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_CSD, Buff) == RES_OK)
|
||||
{ xputs(PSTR("CSD:\n")); put_dump(Buff, 0, 16); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_CID, Buff) == RES_OK)
|
||||
{ xputs(PSTR("CID:\n")); put_dump(Buff, 0, 16); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_OCR, Buff) == RES_OK)
|
||||
{ xputs(PSTR("OCR:\n")); put_dump(Buff, 0, 4); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_SDSTAT, Buff) == RES_OK) {
|
||||
xputs(PSTR("SD Status:\n"));
|
||||
for (s1 = 0; s1 < 64; s1 += 16) put_dump(Buff+s1, s1, 16);
|
||||
}
|
||||
if (disk_ioctl((BYTE)p1, ATA_GET_MODEL, line) == RES_OK)
|
||||
{ line[40] = '\0'; xprintf(PSTR("Model: %s\n"), line); }
|
||||
if (disk_ioctl((BYTE)p1, ATA_GET_SN, line) == RES_OK)
|
||||
{ line[20] = '\0'; xprintf(PSTR("S/N: %s\n"), line); }
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'b' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* bd <addr> - Dump R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
for (ptr=&Buff[p1], ofs = p1, cnt = 32; cnt; cnt--, ptr+=16, ofs+=16)
|
||||
put_dump(ptr, ofs, 16);
|
||||
break;
|
||||
|
||||
case 'e' : /* be <addr> [<data>] ... - Edit R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (xatoi(&ptr, &p2)) {
|
||||
do {
|
||||
Buff[p1++] = (BYTE)p2;
|
||||
} while (xatoi(&ptr, &p2));
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
xprintf(PSTR("%04X %02X-"), (WORD)(p1), (WORD)Buff[p1]);
|
||||
get_line(line, sizeof(line));
|
||||
ptr = line;
|
||||
if (*ptr == '.') break;
|
||||
if (*ptr < ' ') { p1++; continue; }
|
||||
if (xatoi(&ptr, &p2))
|
||||
Buff[p1++] = (BYTE)p2;
|
||||
else
|
||||
xputs(PSTR("???\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r' : /* br <phy_drv#> <sector> [<n>] - Read disk into R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) break;
|
||||
if (!xatoi(&ptr, &p3)) p3 = 1;
|
||||
xprintf(PSTR("rc=%u\n"), (WORD)disk_read((BYTE)p1, Buff, p2, p3));
|
||||
break;
|
||||
|
||||
case 'w' : /* bw <phy_drv#> <sector> [<n>] - Write R/W buffer into disk */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) break;
|
||||
if (!xatoi(&ptr, &p3)) p3 = 1;
|
||||
xprintf(PSTR("rc=%u\n"), (WORD)disk_write((BYTE)p1, Buff, p2, p3));
|
||||
break;
|
||||
|
||||
case 'f' : /* bf <n> - Fill working buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
memset(Buff, (BYTE)p1, sizeof(Buff));
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f' :
|
||||
switch (*ptr++) {
|
||||
|
||||
case 'i' : /* fi <log drv#> - Initialize logical drive */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
put_rc(f_mount((BYTE)p1, &fatfs[p1]));
|
||||
break;
|
||||
|
||||
case 's' : /* fs [<path>] - Show logical drive status */
|
||||
while (*ptr == ' ') ptr++;
|
||||
res = f_getfree(ptr, &p2, &fs);
|
||||
if (res) { put_rc(res); break; }
|
||||
xprintf(PSTR("FAT type = %u\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
|
||||
"Root DIR entries = %u\nSectors/FAT = %lu\nNumber of clusters = %lu\n"
|
||||
"FAT start (lba) = %lu\nDIR start (lba,clustor) = %lu\nData start (lba) = %lu\n"),
|
||||
(WORD)fs->fs_type, (DWORD)fs->csize * 512, (WORD)fs->n_fats,
|
||||
fs->n_rootdir, (DWORD)fs->sects_fat, (DWORD)fs->max_clust - 2,
|
||||
fs->fatbase, fs->dirbase, fs->database
|
||||
);
|
||||
acc_size = acc_files = acc_dirs = 0;
|
||||
res = scan_files(ptr);
|
||||
if (res) { put_rc(res); break; }
|
||||
xprintf(PSTR("%u files, %lu bytes.\n%u folders.\n"
|
||||
"%lu KB total disk space.\n%lu KB available.\n"),
|
||||
acc_files, acc_size, acc_dirs,
|
||||
(fs->max_clust - 2) * (fs->csize / 2), p2 * (fs->csize / 2)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'l' : /* fl [<path>] - Directory listing */
|
||||
while (*ptr == ' ') ptr++;
|
||||
res = f_opendir(&dir, ptr);
|
||||
if (res) { put_rc(res); break; }
|
||||
p1 = s1 = s2 = 0;
|
||||
for(;;) {
|
||||
res = f_readdir(&dir, &finfo);
|
||||
if ((res != FR_OK) || !finfo.fname[0]) break;
|
||||
if (finfo.fattrib & AM_DIR) {
|
||||
s2++;
|
||||
} else {
|
||||
s1++; p1 += finfo.fsize;
|
||||
}
|
||||
xprintf(PSTR("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s\n"),
|
||||
(finfo.fattrib & AM_DIR) ? 'D' : '-',
|
||||
(finfo.fattrib & AM_RDO) ? 'R' : '-',
|
||||
(finfo.fattrib & AM_HID) ? 'H' : '-',
|
||||
(finfo.fattrib & AM_SYS) ? 'S' : '-',
|
||||
(finfo.fattrib & AM_ARC) ? 'A' : '-',
|
||||
(finfo.fdate >> 9) + 1980, (finfo.fdate >> 5) & 15, finfo.fdate & 31,
|
||||
(finfo.ftime >> 11), (finfo.ftime >> 5) & 63,
|
||||
finfo.fsize, &(finfo.fname[0]));
|
||||
}
|
||||
xprintf(PSTR("%4u File(s),%10lu bytes total\n%4u Dir(s)"), s1, p1, s2);
|
||||
if (f_getfree(ptr, &p1, &fs) == FR_OK)
|
||||
xprintf(PSTR(", %10luK bytes free\n"), p1 * fs->csize / 2);
|
||||
break;
|
||||
|
||||
case 'o' : /* fo <mode> <name> - Open a file */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_open(&file1, ptr, (BYTE)p1));
|
||||
break;
|
||||
|
||||
case 'c' : /* fc - Close a file */
|
||||
put_rc(f_close(&file1));
|
||||
break;
|
||||
|
||||
case 'e' : /* fe - Seek file pointer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
res = f_lseek(&file1, p1);
|
||||
put_rc(res);
|
||||
if (res == FR_OK)
|
||||
xprintf(PSTR("fptr = %lu(0x%lX)\n"), file1.fptr, file1.fptr);
|
||||
break;
|
||||
|
||||
case 'r' : /* fr <len> - read file */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
p2 = 0;
|
||||
Timer = 0;
|
||||
while (p1) {
|
||||
if (p1 >= sizeof(Buff)) { cnt = sizeof(Buff); p1 -= sizeof(Buff); }
|
||||
else { cnt = (WORD)p1; p1 = 0; }
|
||||
res = f_read(&file1, Buff, cnt, &s2);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
p2 += s2;
|
||||
if (cnt != s2) break;
|
||||
}
|
||||
s2 = Timer;
|
||||
xprintf(PSTR("%lu bytes read with %lu bytes/sec.\n"), p2, p2 * 100 / s2);
|
||||
break;
|
||||
|
||||
case 'd' : /* fd <len> - read and dump file from current fp */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
ofs = file1.fptr;
|
||||
while (p1) {
|
||||
if (p1 >= 16) { cnt = 16; p1 -= 16; }
|
||||
else { cnt = (WORD)p1; p1 = 0; }
|
||||
res = f_read(&file1, Buff, cnt, &cnt);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
if (!cnt) break;
|
||||
put_dump(Buff, ofs, cnt);
|
||||
ofs += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w' : /* fw <len> <val> - write file */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
|
||||
memset(Buff, (BYTE)p2, sizeof(Buff));
|
||||
p2 = 0;
|
||||
Timer = 0;
|
||||
while (p1) {
|
||||
if (p1 >= sizeof(Buff)) { cnt = sizeof(Buff); p1 -= sizeof(Buff); }
|
||||
else { cnt = (WORD)p1; p1 = 0; }
|
||||
res = f_write(&file1, Buff, cnt, &s2);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
p2 += s2;
|
||||
if (cnt != s2) break;
|
||||
}
|
||||
s2 = Timer;
|
||||
xprintf(PSTR("%lu bytes written with %lu bytes/sec.\n"), p2, p2 * 100 / s2);
|
||||
break;
|
||||
|
||||
case 'v' : /* fv - Truncate file */
|
||||
put_rc(f_truncate(&file1));
|
||||
break;
|
||||
|
||||
case 'n' : /* fn <old_name> <new_name> - Change file/dir name */
|
||||
while (*ptr == ' ') ptr++;
|
||||
ptr2 = strchr(ptr, ' ');
|
||||
if (!ptr2) break;
|
||||
*ptr2++ = 0;
|
||||
while (*ptr2 == ' ') ptr2++;
|
||||
put_rc(f_rename(ptr, ptr2));
|
||||
break;
|
||||
|
||||
case 'u' : /* fu <name> - Unlink a file or dir */
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_unlink(ptr));
|
||||
break;
|
||||
|
||||
case 'k' : /* fk <name> - Create a directory */
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_mkdir(ptr));
|
||||
break;
|
||||
|
||||
case 'a' : /* fa <atrr> <mask> <name> - Change file/dir attribute */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_chmod(ptr, p1, p2));
|
||||
break;
|
||||
|
||||
case 't' : /* ft <year> <month> <day> <hour> <min> <sec> <name> */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31);
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
finfo.ftime = ((p1 & 31) << 11) | ((p1 & 63) << 5) | ((p1 >> 1) & 31);
|
||||
put_rc(f_utime(ptr, &finfo));
|
||||
break;
|
||||
|
||||
case 'x' : /* fx <src_name> <dst_name> - Copy file */
|
||||
while (*ptr == ' ') ptr++;
|
||||
ptr2 = strchr(ptr, ' ');
|
||||
if (!ptr2) break;
|
||||
*ptr2++ = 0;
|
||||
xprintf(PSTR("Opening \"%s\""), ptr);
|
||||
res = f_open(&file1, ptr, FA_OPEN_EXISTING | FA_READ);
|
||||
if (res) {
|
||||
put_rc(res);
|
||||
break;
|
||||
}
|
||||
xprintf(PSTR("\nCreating \"%s\""), ptr2);
|
||||
res = f_open(&file2, ptr2, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res) {
|
||||
put_rc(res);
|
||||
f_close(&file1);
|
||||
break;
|
||||
}
|
||||
xprintf(PSTR("\nCopying..."));
|
||||
p1 = 0;
|
||||
for (;;) {
|
||||
res = f_read(&file1, Buff, sizeof(Buff), &s1);
|
||||
if (res || s1 == 0) break; /* error or eof */
|
||||
res = f_write(&file2, Buff, s1, &s2);
|
||||
p1 += s2;
|
||||
if (res || s2 < s1) break; /* error or disk full */
|
||||
}
|
||||
if (res) put_rc(res);
|
||||
xprintf(PSTR("\n%lu bytes copied.\n"), p1);
|
||||
f_close(&file1);
|
||||
f_close(&file2);
|
||||
break;
|
||||
#if _USE_MKFS
|
||||
case 'm' : /* fm <logi drv#> <part type> <bytes/clust> - Create file system */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
xprintf(PSTR("The drive %u will be formatted. Are you sure? (Y/n)="), (WORD)p1);
|
||||
get_line(ptr, sizeof(line));
|
||||
if (*ptr == 'Y') put_rc(f_mkfs((BYTE)p1, (BYTE)p2, (WORD)p3));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case 't' : /* t [<year> <mon> <mday> <hour> <min> <sec>] */
|
||||
if (xatoi(&ptr, &p1)) {
|
||||
rtc.year = (WORD)p1;
|
||||
xatoi(&ptr, &p1); rtc.month = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); rtc.mday = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); rtc.hour = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); rtc.min = (BYTE)p1;
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
rtc.sec = (BYTE)p1;
|
||||
rtc_settime(&rtc);
|
||||
}
|
||||
rtc_gettime(&rtc);
|
||||
xprintf(PSTR("%u/%u/%u %02u:%02u:%02u\n"), rtc.year, rtc.month, rtc.mday, rtc.hour, rtc.min, rtc.sec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
600
tools/ffsample/avr/mmc.c
Normal file
600
tools/ffsample/avr/mmc.c
Normal file
@@ -0,0 +1,600 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* MMC/SDSC/SDHC (in SPI mode) control module (C)ChaN, 2007 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */
|
||||
/* are platform dependent. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "diskio.h"
|
||||
|
||||
|
||||
/* Definitions for MMC/SDC command */
|
||||
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
|
||||
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
|
||||
#define CMD8 (0x40+8) /* SEND_IF_COND */
|
||||
#define CMD9 (0x40+9) /* SEND_CSD */
|
||||
#define CMD10 (0x40+10) /* SEND_CID */
|
||||
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
|
||||
#define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
|
||||
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */
|
||||
#define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
||||
#define CMD24 (0x40+24) /* WRITE_BLOCK */
|
||||
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
|
||||
#define CMD55 (0x40+55) /* APP_CMD */
|
||||
#define CMD58 (0x40+58) /* READ_OCR */
|
||||
|
||||
|
||||
/* Port Controls (Platform dependent) */
|
||||
#define SELECT() PORTB &= ~1 /* MMC CS = L */
|
||||
#define DESELECT() PORTB |= 1 /* MMC CS = H */
|
||||
|
||||
#define SOCKPORT PINB /* Socket contact port */
|
||||
#define SOCKWP 0x20 /* Write protect switch (PB5) */
|
||||
#define SOCKINS 0x10 /* Card detect switch (PB4) */
|
||||
|
||||
#define FCLK_SLOW() /* Set slow clock (100k-400k) */
|
||||
#define FCLK_FAST() /* Set fast clock (depends on the CSD) */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
static volatile
|
||||
BYTE Timer1, Timer2; /* 100Hz decrement timer */
|
||||
|
||||
static
|
||||
BYTE CardType; /* Card type flags */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Transmit a byte to MMC via SPI (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#define xmit_spi(dat) SPDR=(dat); loop_until_bit_is_set(SPSR,SPIF)
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive a byte from MMC via SPI (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE rcvr_spi (void)
|
||||
{
|
||||
SPDR = 0xFF;
|
||||
loop_until_bit_is_set(SPSR, SPIF);
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
/* Alternative macro to receive data fast */
|
||||
#define rcvr_spi_m(dst) SPDR=0xFF; loop_until_bit_is_set(SPSR,SPIF); *(dst)=SPDR
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait for card ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE wait_ready (void)
|
||||
{
|
||||
BYTE res;
|
||||
|
||||
|
||||
Timer2 = 50; /* Wait for ready in timeout of 500ms */
|
||||
rcvr_spi();
|
||||
do
|
||||
res = rcvr_spi();
|
||||
while ((res != 0xFF) && Timer2);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Deselect the card and release SPI bus */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void release_spi (void)
|
||||
{
|
||||
DESELECT();
|
||||
rcvr_spi();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Power Control (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* When the target system does not support socket power control, there */
|
||||
/* is nothing to do in these functions and chk_power always returns 1. */
|
||||
|
||||
static
|
||||
void power_on (void)
|
||||
{
|
||||
PORTE &= ~0x80; /* Socket power ON */
|
||||
for (Timer1 = 3; Timer1; ); /* Wait for 30ms */
|
||||
PORTB = 0b10110101; /* Enable drivers */
|
||||
DDRB = 0b11000111;
|
||||
SPCR = 0b01010000; /* Initialize SPI port (Mode 0) */
|
||||
SPSR = 0b00000001;
|
||||
}
|
||||
|
||||
static
|
||||
void power_off (void)
|
||||
{
|
||||
SELECT(); /* Wait for card ready */
|
||||
wait_ready();
|
||||
release_spi();
|
||||
|
||||
SPCR = 0; /* Disable SPI function */
|
||||
DDRB = 0b11000000; /* Disable drivers */
|
||||
PORTB = 0b10110000;
|
||||
PORTE |= 0x80; /* Socket power OFF */
|
||||
Stat |= STA_NOINIT; /* Set STA_NOINIT */
|
||||
}
|
||||
|
||||
static
|
||||
int chk_power(void) /* Socket power state: 0=off, 1=on */
|
||||
{
|
||||
return (PORTE & 0x80) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive a data packet from MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BOOL rcvr_datablock (
|
||||
BYTE *buff, /* Data buffer to store received data */
|
||||
UINT btr /* Byte count (must be multiple of 4) */
|
||||
)
|
||||
{
|
||||
BYTE token;
|
||||
|
||||
|
||||
Timer1 = 10;
|
||||
do { /* Wait for data packet in timeout of 100ms */
|
||||
token = rcvr_spi();
|
||||
} while ((token == 0xFF) && Timer1);
|
||||
if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */
|
||||
|
||||
do { /* Receive the data block into buffer */
|
||||
rcvr_spi_m(buff++);
|
||||
rcvr_spi_m(buff++);
|
||||
rcvr_spi_m(buff++);
|
||||
rcvr_spi_m(buff++);
|
||||
} while (btr -= 4);
|
||||
rcvr_spi(); /* Discard CRC */
|
||||
rcvr_spi();
|
||||
|
||||
return TRUE; /* Return with success */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a data packet to MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
static
|
||||
BOOL xmit_datablock (
|
||||
const BYTE *buff, /* 512 byte data block to be transmitted */
|
||||
BYTE token /* Data/Stop token */
|
||||
)
|
||||
{
|
||||
BYTE resp, wc;
|
||||
|
||||
|
||||
if (wait_ready() != 0xFF) return FALSE;
|
||||
|
||||
xmit_spi(token); /* Xmit data token */
|
||||
if (token != 0xFD) { /* Is data token */
|
||||
wc = 0;
|
||||
do { /* Xmit the 512 byte data block to MMC */
|
||||
xmit_spi(*buff++);
|
||||
xmit_spi(*buff++);
|
||||
} while (--wc);
|
||||
xmit_spi(0xFF); /* CRC (Dummy) */
|
||||
xmit_spi(0xFF);
|
||||
resp = rcvr_spi(); /* Reveive data response */
|
||||
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE send_cmd (
|
||||
BYTE cmd, /* Command byte */
|
||||
DWORD arg /* Argument */
|
||||
)
|
||||
{
|
||||
BYTE n, res;
|
||||
|
||||
|
||||
if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
|
||||
cmd &= 0x7F;
|
||||
res = send_cmd(CMD55, 0);
|
||||
if (res > 1) return res;
|
||||
}
|
||||
|
||||
/* Select the card and wait for ready */
|
||||
DESELECT();
|
||||
SELECT();
|
||||
if (wait_ready() != 0xFF) return 0xFF;
|
||||
|
||||
/* Send command packet */
|
||||
xmit_spi(cmd); /* Start + Command index */
|
||||
xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
|
||||
xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
|
||||
xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
|
||||
xmit_spi((BYTE)arg); /* Argument[7..0] */
|
||||
n = 0x01; /* Dummy CRC + Stop */
|
||||
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
|
||||
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
|
||||
xmit_spi(n);
|
||||
|
||||
/* Receive command response */
|
||||
if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
|
||||
n = 10; /* Wait for a valid response in timeout of 10 attempts */
|
||||
do
|
||||
res = rcvr_spi();
|
||||
while ((res & 0x80) && --n);
|
||||
|
||||
return res; /* Return with the response value */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
BYTE n, cmd, ty, ocr[4];
|
||||
|
||||
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
|
||||
|
||||
power_on(); /* Force socket power on */
|
||||
FCLK_SLOW();
|
||||
for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */
|
||||
|
||||
ty = 0;
|
||||
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
|
||||
Timer1 = 100; /* Initialization timeout of 1000 msec */
|
||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */
|
||||
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */
|
||||
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
|
||||
while (Timer1 && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
|
||||
if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
||||
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
|
||||
ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
|
||||
}
|
||||
}
|
||||
} else { /* SDSC or MMC */
|
||||
if (send_cmd(ACMD41, 0) <= 1) {
|
||||
ty = CT_SD1; cmd = ACMD41; /* SDSC */
|
||||
} else {
|
||||
ty = CT_MMC; cmd = CMD1; /* MMC */
|
||||
}
|
||||
while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */
|
||||
if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
|
||||
ty = 0;
|
||||
}
|
||||
}
|
||||
CardType = ty;
|
||||
release_spi();
|
||||
|
||||
if (ty) { /* Initialization succeded */
|
||||
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
|
||||
FCLK_FAST();
|
||||
} else { /* Initialization failed */
|
||||
power_off();
|
||||
}
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
||||
|
||||
if (count == 1) { /* Single block read */
|
||||
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
|
||||
&& rcvr_datablock(buff, 512))
|
||||
count = 0;
|
||||
}
|
||||
else { /* Multiple block read */
|
||||
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!rcvr_datablock(buff, 512)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
|
||||
}
|
||||
}
|
||||
release_spi();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Pointer to the data to be written */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
if (Stat & STA_PROTECT) return RES_WRPRT;
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
||||
|
||||
if (count == 1) { /* Single block write */
|
||||
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
|
||||
&& xmit_datablock(buff, 0xFE))
|
||||
count = 0;
|
||||
}
|
||||
else { /* Multiple block write */
|
||||
if (CardType & CT_SDC) send_cmd(ACMD23, count);
|
||||
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!xmit_datablock(buff, 0xFC)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
release_spi();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
#endif /* _READONLY == 0 */
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL != 0
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
BYTE n, csd[16], *ptr = buff;
|
||||
WORD csize;
|
||||
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
|
||||
res = RES_ERROR;
|
||||
|
||||
if (ctrl == CTRL_POWER) {
|
||||
switch (*ptr) {
|
||||
case 0: /* Sub control code == 0 (POWER_OFF) */
|
||||
if (chk_power())
|
||||
power_off(); /* Power off */
|
||||
res = RES_OK;
|
||||
break;
|
||||
case 1: /* Sub control code == 1 (POWER_ON) */
|
||||
power_on(); /* Power on */
|
||||
res = RES_OK;
|
||||
break;
|
||||
case 2: /* Sub control code == 2 (POWER_GET) */
|
||||
*(ptr+1) = (BYTE)chk_power();
|
||||
res = RES_OK;
|
||||
break;
|
||||
default :
|
||||
res = RES_PARERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
switch (ctrl) {
|
||||
case CTRL_SYNC : /* Make sure that no pending write process */
|
||||
SELECT();
|
||||
if (wait_ready() == 0xFF)
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
|
||||
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
|
||||
csize = csd[9] + ((WORD)csd[8] << 8) + 1;
|
||||
*(DWORD*)buff = (DWORD)csize << 10;
|
||||
} else { /* SDC ver 1.XX or MMC*/
|
||||
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
|
||||
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
|
||||
*(DWORD*)buff = (DWORD)csize << (n - 9);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
|
||||
*(WORD*)buff = 512;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
||||
if (CardType & CT_SD2) { /* SDC ver 2.00 */
|
||||
if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
|
||||
rcvr_spi();
|
||||
if (rcvr_datablock(csd, 16)) { /* Read partial block */
|
||||
for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */
|
||||
*(DWORD*)buff = 16UL << (csd[10] >> 4);
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
} else { /* SDC ver 1.XX or MMC */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
|
||||
if (CardType & CT_SD1) { /* SDC ver 1.XX */
|
||||
*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
|
||||
} else { /* MMC */
|
||||
*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MMC_GET_TYPE : /* Get card type flags (1 byte) */
|
||||
*ptr = CardType;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
|
||||
if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
|
||||
&& rcvr_datablock(ptr, 16))
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
|
||||
if (send_cmd(CMD10, 0) == 0 /* READ_CID */
|
||||
&& rcvr_datablock(ptr, 16))
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
|
||||
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
|
||||
for (n = 4; n; n--) *ptr++ = rcvr_spi();
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */
|
||||
if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
|
||||
rcvr_spi();
|
||||
if (rcvr_datablock(ptr, 64))
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
}
|
||||
|
||||
release_spi();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif /* _USE_IOCTL != 0 */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Device Timer Interrupt Procedure (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This function must be called in period of 10ms */
|
||||
|
||||
void disk_timerproc (void)
|
||||
{
|
||||
static BYTE pv;
|
||||
BYTE n, s;
|
||||
|
||||
|
||||
n = Timer1; /* 100Hz decrement timer */
|
||||
if (n) Timer1 = --n;
|
||||
n = Timer2;
|
||||
if (n) Timer2 = --n;
|
||||
|
||||
n = pv;
|
||||
pv = SOCKPORT & (SOCKWP | SOCKINS); /* Sample socket switch */
|
||||
|
||||
if (n == pv) { /* Have contacts stabled? */
|
||||
s = Stat;
|
||||
|
||||
if (pv & SOCKWP) /* WP is H (write protected) */
|
||||
s |= STA_PROTECT;
|
||||
else /* WP is L (write enabled) */
|
||||
s &= ~STA_PROTECT;
|
||||
|
||||
if (pv & SOCKINS) /* INS = H (Socket empty) */
|
||||
s |= (STA_NODISK | STA_NOINIT);
|
||||
else /* INS = L (Card inserted) */
|
||||
s &= ~STA_NODISK;
|
||||
|
||||
Stat = s;
|
||||
}
|
||||
}
|
||||
|
||||
249
tools/ffsample/avr/rtc.c
Normal file
249
tools/ffsample/avr/rtc.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RTC controls */
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
|
||||
#define SCL_LOW() DDRE |= 0x04 /* SCL = LOW */
|
||||
#define SCL_HIGH() DDRE &= 0xFB /* SCL = High-Z */
|
||||
#define SCL_VAL ((PINE & 0x04) ? 1 : 0) /* SCL input level */
|
||||
#define SDA_LOW() DDRE |= 0x08 /* SDA = LOW */
|
||||
#define SDA_HIGH() DDRE &= 0xF7 /* SDA = High-Z */
|
||||
#define SDA_VAL ((PINE & 0x08) ? 1 : 0) /* SDA input level */
|
||||
|
||||
|
||||
|
||||
static
|
||||
void iic_delay (void)
|
||||
{
|
||||
int n;
|
||||
BYTE d;
|
||||
|
||||
for (n = 4; n; n--) d = PINE;
|
||||
}
|
||||
|
||||
|
||||
/* Generate start condition on the IIC bus */
|
||||
static
|
||||
void iic_start (void)
|
||||
{
|
||||
SDA_HIGH();
|
||||
iic_delay();
|
||||
SCL_HIGH();
|
||||
iic_delay();
|
||||
SDA_LOW();
|
||||
iic_delay();
|
||||
SCL_LOW();
|
||||
iic_delay();
|
||||
}
|
||||
|
||||
|
||||
/* Generate stop condition on the IIC bus */
|
||||
static
|
||||
void iic_stop (void)
|
||||
{
|
||||
SDA_LOW();
|
||||
iic_delay();
|
||||
SCL_HIGH();
|
||||
iic_delay();
|
||||
SDA_HIGH();
|
||||
iic_delay();
|
||||
}
|
||||
|
||||
|
||||
/* Send a byte to the IIC bus */
|
||||
static
|
||||
BOOL iic_send (BYTE dat)
|
||||
{
|
||||
BYTE b = 0x80;
|
||||
BOOL ack;
|
||||
|
||||
|
||||
do {
|
||||
if (dat & b) { /* SDA = Z/L */
|
||||
SDA_HIGH();
|
||||
} else {
|
||||
SDA_LOW();
|
||||
}
|
||||
iic_delay();
|
||||
SCL_HIGH();
|
||||
iic_delay();
|
||||
SCL_LOW();
|
||||
iic_delay();
|
||||
} while (b >>= 1);
|
||||
SDA_HIGH();
|
||||
iic_delay();
|
||||
SCL_HIGH();
|
||||
ack = SDA_VAL ? FALSE : TRUE; /* Sample ACK */
|
||||
iic_delay();
|
||||
SCL_LOW();
|
||||
iic_delay();
|
||||
return ack;
|
||||
}
|
||||
|
||||
|
||||
/* Receive a byte from the IIC bus */
|
||||
static
|
||||
BYTE iic_rcvr (BOOL ack)
|
||||
{
|
||||
UINT d = 1;
|
||||
|
||||
|
||||
do {
|
||||
d <<= 1;
|
||||
SCL_HIGH();
|
||||
if (SDA_VAL) d++;
|
||||
iic_delay();
|
||||
SCL_LOW();
|
||||
iic_delay();
|
||||
} while (d < 0x100);
|
||||
if (ack) { /* SDA = ACK */
|
||||
SDA_LOW();
|
||||
} else {
|
||||
SDA_HIGH();
|
||||
}
|
||||
iic_delay();
|
||||
SCL_HIGH();
|
||||
iic_delay();
|
||||
SCL_LOW();
|
||||
SDA_HIGH();
|
||||
iic_delay();
|
||||
|
||||
return (BYTE)d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL rtc_read (
|
||||
UINT adr, /* Read start address */
|
||||
UINT cnt, /* Read byte count */
|
||||
void* buff /* Read data buffer */
|
||||
)
|
||||
{
|
||||
BYTE *rbuff = buff;
|
||||
int n;
|
||||
|
||||
|
||||
if (!cnt) return FALSE;
|
||||
|
||||
n = 10;
|
||||
do { /* Select DS1338 (0xD0) */
|
||||
iic_start();
|
||||
} while (!iic_send(0xD0) && --n);
|
||||
if (!n) return FALSE;
|
||||
|
||||
if (iic_send((BYTE)adr)) { /* Set start address */
|
||||
iic_start(); /* Reselect DS1338 in read mode (0xD1) */
|
||||
if (iic_send(0xD1)) {
|
||||
do { /* Receive data */
|
||||
cnt--;
|
||||
*rbuff++ = iic_rcvr(cnt ? TRUE : FALSE);
|
||||
} while (cnt);
|
||||
}
|
||||
}
|
||||
|
||||
iic_stop(); /* Deselect device */
|
||||
|
||||
return cnt ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL rtc_write (
|
||||
UINT adr, /* Write start address */
|
||||
UINT cnt, /* Write byte count */
|
||||
const void* buff /* Data to be written */
|
||||
)
|
||||
{
|
||||
const BYTE *wbuff = buff;
|
||||
int n;
|
||||
|
||||
|
||||
if (!cnt) return FALSE;
|
||||
|
||||
n = 10;
|
||||
do { /* Select DS1338 (0xD0) */
|
||||
iic_start();
|
||||
} while (!iic_send(0xD0) && --n);
|
||||
if (!n) return FALSE;
|
||||
|
||||
if (iic_send((BYTE)adr)) { /* Set start address */
|
||||
do { /* Send data */
|
||||
if (!iic_send(*wbuff++)) break;
|
||||
} while (--cnt);
|
||||
}
|
||||
|
||||
iic_stop(); /* Deselect device */
|
||||
|
||||
return cnt ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL rtc_gettime (RTC *rtc)
|
||||
{
|
||||
BYTE buf[8];
|
||||
|
||||
|
||||
if (!rtc_read(0, 7, buf)) return FALSE;
|
||||
|
||||
rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10;
|
||||
rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10;
|
||||
rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10;
|
||||
rtc->wday = (buf[2] & 0x07);
|
||||
rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10;
|
||||
rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10;
|
||||
rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL rtc_settime (const RTC *rtc)
|
||||
{
|
||||
|
||||
BYTE buf[8];
|
||||
|
||||
|
||||
buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10;
|
||||
buf[1] = rtc->min / 10 * 16 + rtc->min % 10;
|
||||
buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10;
|
||||
buf[3] = rtc->wday & 7;
|
||||
buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10;
|
||||
buf[5] = rtc->month / 10 * 16 + rtc->month % 10;
|
||||
buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10;
|
||||
return rtc_write(0, 7, buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL rtc_init (void)
|
||||
{
|
||||
BYTE buf[8]; /* RTC R/W buffer */
|
||||
UINT adr;
|
||||
|
||||
|
||||
/* Read RTC registers */
|
||||
if (!rtc_read(0, 8, buf)) return FALSE; /* IIC error */
|
||||
|
||||
if (buf[7] & 0x20) { /* When data has been volatiled, set default time */
|
||||
/* Clear nv-ram. Reg[8..63] */
|
||||
memset(buf, 0, 8);
|
||||
for (adr = 8; adr < 64; adr += 8)
|
||||
rtc_write(adr, 8, buf);
|
||||
/* Reset time to Jan 1, '08. Reg[0..7] */
|
||||
buf[4] = 1; buf[5] = 1; buf[6] = 8;
|
||||
rtc_write(0, 8, buf);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
18
tools/ffsample/avr/rtc.h
Normal file
18
tools/ffsample/avr/rtc.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "integer.h"
|
||||
|
||||
typedef struct {
|
||||
WORD year; /* 2000..2099 */
|
||||
BYTE month; /* 1..12 */
|
||||
BYTE mday; /* 1.. 31 */
|
||||
BYTE wday; /* 1..7 */
|
||||
BYTE hour; /* 0..23 */
|
||||
BYTE min; /* 0..59 */
|
||||
BYTE sec; /* 0..59 */
|
||||
} RTC;
|
||||
|
||||
BOOL rtc_init (void); /* Initialize RTC */
|
||||
BOOL rtc_gettime (RTC*); /* Get time */
|
||||
BOOL rtc_settime (const RTC*); /* Set time */
|
||||
BOOL rtc_write (UINT, UINT, const void*); /* Write RTC regs */
|
||||
BOOL rtc_read (UINT, UINT, void*); /* Read RTC regs */
|
||||
|
||||
128
tools/ffsample/avr/uart.c
Normal file
128
tools/ffsample/avr/uart.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*------------------------------------------------*/
|
||||
/* UART functions */
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "uart.h"
|
||||
|
||||
#define SYSCLK 9216000
|
||||
#define BAUD 115200
|
||||
|
||||
|
||||
typedef struct _fifo {
|
||||
uint8_t idx_w;
|
||||
uint8_t idx_r;
|
||||
uint8_t count;
|
||||
uint8_t buff[64];
|
||||
} FIFO;
|
||||
|
||||
|
||||
static volatile
|
||||
FIFO txfifo, rxfifo;
|
||||
|
||||
|
||||
|
||||
/* Initialize UART */
|
||||
|
||||
void uart_init()
|
||||
{
|
||||
rxfifo.idx_r = 0;
|
||||
rxfifo.idx_w = 0;
|
||||
rxfifo.count = 0;
|
||||
txfifo.idx_r = 0;
|
||||
txfifo.idx_w = 0;
|
||||
txfifo.count = 0;
|
||||
|
||||
UBRR0L = SYSCLK/BAUD/16-1;
|
||||
UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0);
|
||||
}
|
||||
|
||||
|
||||
/* Get a received character */
|
||||
|
||||
uint8_t uart_test ()
|
||||
{
|
||||
return rxfifo.count;
|
||||
}
|
||||
|
||||
|
||||
uint8_t uart_get ()
|
||||
{
|
||||
uint8_t d, i;
|
||||
|
||||
|
||||
i = rxfifo.idx_r;
|
||||
while(rxfifo.count == 0);
|
||||
d = rxfifo.buff[i++];
|
||||
cli();
|
||||
rxfifo.count--;
|
||||
sei();
|
||||
if(i >= sizeof(rxfifo.buff))
|
||||
i = 0;
|
||||
rxfifo.idx_r = i;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
/* Put a character to transmit */
|
||||
|
||||
void uart_put (uint8_t d)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
|
||||
i = txfifo.idx_w;
|
||||
while(txfifo.count >= sizeof(txfifo.buff));
|
||||
txfifo.buff[i++] = d;
|
||||
cli();
|
||||
txfifo.count++;
|
||||
UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0)|_BV(UDRIE0);
|
||||
sei();
|
||||
if(i >= sizeof(txfifo.buff))
|
||||
i = 0;
|
||||
txfifo.idx_w = i;
|
||||
}
|
||||
|
||||
|
||||
/* UART RXC interrupt */
|
||||
|
||||
SIGNAL(SIG_UART0_RECV)
|
||||
{
|
||||
uint8_t d, n, i;
|
||||
|
||||
|
||||
d = UDR0;
|
||||
n = rxfifo.count;
|
||||
if(n < sizeof(rxfifo.buff)) {
|
||||
rxfifo.count = ++n;
|
||||
i = rxfifo.idx_w;
|
||||
rxfifo.buff[i++] = d;
|
||||
if(i >= sizeof(rxfifo.buff))
|
||||
i = 0;
|
||||
rxfifo.idx_w = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* UART UDRE interrupt */
|
||||
|
||||
SIGNAL(SIG_UART0_DATA)
|
||||
{
|
||||
uint8_t n, i;
|
||||
|
||||
|
||||
n = txfifo.count;
|
||||
if(n) {
|
||||
txfifo.count = --n;
|
||||
i = txfifo.idx_r;
|
||||
UDR0 = txfifo.buff[i++];
|
||||
if(i >= sizeof(txfifo.buff))
|
||||
i = 0;
|
||||
txfifo.idx_r = i;
|
||||
}
|
||||
if(n == 0)
|
||||
UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0);
|
||||
}
|
||||
|
||||
4
tools/ffsample/avr/uart.h
Normal file
4
tools/ffsample/avr/uart.h
Normal file
@@ -0,0 +1,4 @@
|
||||
void uart_init(void); /* Initialize UART and Flush FIFOs */
|
||||
uint8_t uart_get (void); /* Get a byte from UART Rx FIFO */
|
||||
uint8_t uart_test(void); /* Check number of data in UART Rx FIFO */
|
||||
void uart_put (uint8_t); /* Put a byte into UART Tx FIFO */
|
||||
419
tools/ffsample/avr/xitoa.S
Normal file
419
tools/ffsample/avr/xitoa.S
Normal file
@@ -0,0 +1,419 @@
|
||||
;---------------------------------------------------------------------------;
|
||||
; Extended itoa, puts, printf and atoi (C)ChaN, 2006
|
||||
;
|
||||
; Module size: 277/261 words (max)
|
||||
;
|
||||
|
||||
#define USE_XPUTS
|
||||
#define USE_XITOA
|
||||
#define USE_XPRINTF
|
||||
#define CR_CRLF
|
||||
#define USE_XATOI
|
||||
|
||||
|
||||
|
||||
.nolist
|
||||
#include <avr/io.h> // Include device specific definitions.
|
||||
.list
|
||||
|
||||
#ifdef SPM_PAGESIZE // Recent devices have "lpm Rd,Z+" and "movw".
|
||||
.macro _LPMI reg
|
||||
lpm \reg, Z+
|
||||
.endm
|
||||
.macro _MOVW dh,dl, sh,sl
|
||||
movw \dl, \sl
|
||||
.endm
|
||||
#else // Earlier devices do not have "lpm Rd,Z+" nor "movw".
|
||||
.macro _LPMI reg
|
||||
lpm
|
||||
mov \reg, r0
|
||||
adiw ZL, 1
|
||||
.endm
|
||||
.macro _MOVW dh,dl, sh,sl
|
||||
mov \dl, \sl
|
||||
mov \dh, \sh
|
||||
.endm
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Stub function to forward to user output function
|
||||
;
|
||||
;Prototype: void xputc (char chr // a character to be output
|
||||
; );
|
||||
;Size: 15/15 words
|
||||
|
||||
.section .bss
|
||||
|
||||
.global xfunc_out ; xfunc_out must be initialized before using this module.
|
||||
xfunc_out: .ds.w 1
|
||||
|
||||
.section .text
|
||||
|
||||
|
||||
.global xputc
|
||||
.func xputc
|
||||
xputc:
|
||||
#ifdef CR_CRLF
|
||||
cpi r24, 10 ;LF --> CRLF
|
||||
brne 1f ;
|
||||
ldi r24, 13 ;
|
||||
rcall 1f ;
|
||||
ldi r24, 10 ;/
|
||||
1:
|
||||
#endif
|
||||
push ZH
|
||||
push ZL
|
||||
lds ZL, xfunc_out+0 ;Pointer to the registered output function.
|
||||
lds ZH, xfunc_out+1 ;/
|
||||
icall
|
||||
pop ZL
|
||||
pop ZH
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Direct ROM string output
|
||||
;
|
||||
;Prototype: void xputs (const prog_char *str // rom string to be output
|
||||
; );
|
||||
;Size: 10/7 words
|
||||
|
||||
#ifdef USE_XPUTS
|
||||
.global xputs
|
||||
.func xputs
|
||||
xputs:
|
||||
_MOVW ZH,ZL, r25,r24 ; Z = pointer to rom string
|
||||
1: _LPMI r24
|
||||
cpi r24, 0
|
||||
breq 2f
|
||||
rcall xputc
|
||||
rjmp 1b
|
||||
2: ret
|
||||
.endfunc
|
||||
#endif
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Extended direct numeral string output (32bit version)
|
||||
;
|
||||
;Prototype: void xitoa (long value, // value to be output
|
||||
; char radix, // radix
|
||||
; char width); // minimum width
|
||||
;Size: 59/59 words
|
||||
;
|
||||
|
||||
#ifdef USE_XITOA
|
||||
.global xitoa
|
||||
.func xitoa
|
||||
xitoa:
|
||||
;r25:r22 = value, r20 = base, r18 = digits
|
||||
clr r31 ;r31 = stack level
|
||||
ldi r30, ' ' ;r30 = sign
|
||||
ldi r19, ' ' ;r19 = filler
|
||||
sbrs r20, 7 ;When base indicates signd format and the value
|
||||
rjmp 0f ;is minus, add a '-'.
|
||||
neg r20 ;
|
||||
sbrs r25, 7 ;
|
||||
rjmp 0f ;
|
||||
ldi r30, '-' ;
|
||||
com r22 ;
|
||||
com r23 ;
|
||||
com r24 ;
|
||||
com r25 ;
|
||||
adc r22, r1 ;
|
||||
adc r23, r1 ;
|
||||
adc r24, r1 ;
|
||||
adc r25, r1 ;/
|
||||
0: sbrs r18, 7 ;When digits indicates zero filled,
|
||||
rjmp 1f ;filler is '0'.
|
||||
neg r18 ;
|
||||
ldi r19, '0' ;/
|
||||
;----- string conversion loop
|
||||
1: ldi r21, 32 ;r26 = r25:r22 % r20
|
||||
clr r26 ;r25:r22 /= r20
|
||||
2: lsl r22 ;
|
||||
rol r23 ;
|
||||
rol r24 ;
|
||||
rol r25 ;
|
||||
rol r26 ;
|
||||
cp r26, r20 ;
|
||||
brcs 3f ;
|
||||
sub r26, r20 ;
|
||||
inc r22 ;
|
||||
3: dec r21 ;
|
||||
brne 2b ;/
|
||||
cpi r26, 10 ;r26 is a numeral digit '0'-'F'
|
||||
brcs 4f ;
|
||||
subi r26, -7 ;
|
||||
4: subi r26, -'0' ;/
|
||||
push r26 ;Stack it
|
||||
inc r31 ;/
|
||||
cp r22, r1 ;Repeat until r25:r22 gets zero
|
||||
cpc r23, r1 ;
|
||||
cpc r24, r1 ;
|
||||
cpc r25, r1 ;
|
||||
brne 1b ;/
|
||||
|
||||
cpi r30, '-' ;Minus sign if needed
|
||||
brne 5f ;
|
||||
push r30 ;
|
||||
inc r31 ;/
|
||||
5: cp r31, r18 ;Filler
|
||||
brcc 6f ;
|
||||
push r19 ;
|
||||
inc r31 ;
|
||||
rjmp 5b ;/
|
||||
|
||||
6: pop r24 ;Flush stacked digits and exit
|
||||
rcall xputc ;
|
||||
dec r31 ;
|
||||
brne 6b ;/
|
||||
|
||||
ret
|
||||
.endfunc
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------;
|
||||
; Formatted string output (16/32bit version)
|
||||
;
|
||||
;Prototype:
|
||||
; void xprintf (const prog_char *format, ...);
|
||||
;Size: 104/94 words
|
||||
;
|
||||
|
||||
#ifdef USE_XPRINTF
|
||||
.global xprintf
|
||||
.func xprintf
|
||||
xprintf:
|
||||
push YH
|
||||
push YL
|
||||
in YL, _SFR_IO_ADDR(SPL)
|
||||
#ifdef SPH
|
||||
in YH, _SFR_IO_ADDR(SPH)
|
||||
#else
|
||||
clr YH
|
||||
#endif
|
||||
#if FLASHEND > 0x1FFFF
|
||||
adiw YL, 6 ;Y = pointer to arguments
|
||||
#else
|
||||
adiw YL, 5 ;Y = pointer to arguments
|
||||
#endif
|
||||
ld ZL, Y+ ;Z = pointer to format string
|
||||
ld ZH, Y+ ;/
|
||||
|
||||
0: _LPMI r24 ;Get a format char
|
||||
cpi r24, 0 ;End of format string?
|
||||
breq 90f ;/
|
||||
cpi r24, '%' ;Is format?
|
||||
breq 20f ;/
|
||||
1: rcall xputc ;Put a normal character
|
||||
rjmp 0b ;/
|
||||
90: pop YL
|
||||
pop YH
|
||||
ret
|
||||
|
||||
20: ldi r18, 0 ;r18: digits
|
||||
clt ;T: filler
|
||||
_LPMI r21 ;Get flags
|
||||
cpi r21, '%' ;Is a %?
|
||||
breq 1b ;/
|
||||
cpi r21, '0' ;Zero filled?
|
||||
brne 23f ;
|
||||
set ;/
|
||||
22: _LPMI r21 ;Get width
|
||||
23: cpi r21, '9'+1 ;
|
||||
brcc 24f ;
|
||||
subi r21, '0' ;
|
||||
brcs 90b ;
|
||||
lsl r18 ;
|
||||
mov r0, r18 ;
|
||||
lsl r18 ;
|
||||
lsl r18 ;
|
||||
add r18, r0 ;
|
||||
add r18, r21 ;
|
||||
rjmp 22b ;/
|
||||
|
||||
24: brtc 25f ;get value (low word)
|
||||
neg r18 ;
|
||||
25: ld r24, Y+ ;
|
||||
ld r25, Y+ ;/
|
||||
cpi r21, 'c' ;Is type character?
|
||||
breq 1b ;/
|
||||
cpi r21, 's' ;Is type RAM string?
|
||||
breq 50f ;/
|
||||
cpi r21, 'S' ;Is type ROM string?
|
||||
breq 60f ;/
|
||||
_MOVW r23,r22,r25,r24 ;r25:r22 = value
|
||||
clr r24 ;
|
||||
clr r25 ;
|
||||
clt ;/
|
||||
cpi r21, 'l' ;Is long int?
|
||||
brne 26f ;
|
||||
ld r24, Y+ ;get value (high word)
|
||||
ld r25, Y+ ;
|
||||
set ;
|
||||
_LPMI r21 ;/
|
||||
26: cpi r21, 'd' ;Is type signed decimal?
|
||||
brne 27f ;/
|
||||
ldi r20, -10 ;
|
||||
brts 40f ;
|
||||
sbrs r23, 7 ;
|
||||
rjmp 40f ;
|
||||
ldi r24, -1 ;
|
||||
ldi r25, -1 ;
|
||||
rjmp 40f ;/
|
||||
27: cpi r21, 'u' ;Is type unsigned decimal?
|
||||
ldi r20, 10 ;
|
||||
breq 40f ;/
|
||||
cpi r21, 'X' ;Is type hexdecimal?
|
||||
ldi r20, 16 ;
|
||||
breq 40f ;/
|
||||
cpi r21, 'b' ;Is type binary?
|
||||
ldi r20, 2 ;
|
||||
breq 40f ;/
|
||||
rjmp 90b ;abort
|
||||
40: push ZH ;Output the value
|
||||
push ZL ;
|
||||
rcall xitoa ;
|
||||
42: pop ZL ;
|
||||
pop ZH ;
|
||||
rjmp 0b ;/
|
||||
|
||||
50: push ZH ;Put a string on the RAM
|
||||
push ZL
|
||||
_MOVW ZH,ZL, r25,r24
|
||||
51: ld r24, Z+
|
||||
cpi r24, 0
|
||||
breq 42b
|
||||
rcall xputc
|
||||
rjmp 51b
|
||||
|
||||
60: push ZH ;Put a string on the ROM
|
||||
push ZL
|
||||
rcall xputs
|
||||
rjmp 42b
|
||||
|
||||
.endfunc
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Extended numeral string input
|
||||
;
|
||||
;Prototype:
|
||||
; char xatoi ( /* 1: Successful, 0: Failed */
|
||||
; const char **str, /* pointer to pointer to source string */
|
||||
; long *res /* result */
|
||||
; );
|
||||
;Size: 94/91 words
|
||||
;
|
||||
|
||||
#ifdef USE_XATOI
|
||||
.global xatoi
|
||||
.func xatoi
|
||||
xatoi:
|
||||
_MOVW r1, r0, r23, r22
|
||||
_MOVW XH, XL, r25, r24
|
||||
ld ZL, X+
|
||||
ld ZH, X+
|
||||
clr r18 ;r21:r18 = 0;
|
||||
clr r19 ;
|
||||
clr r20 ;
|
||||
clr r21 ;/
|
||||
clt ;T = 0;
|
||||
|
||||
ldi r25, 10 ;r25 = 10;
|
||||
rjmp 41f ;/
|
||||
40: adiw ZL, 1 ;Z++;
|
||||
41: ld r22, Z ;r22 = *Z;
|
||||
cpi r22, ' ' ;if(r22 == ' ') continue
|
||||
breq 40b ;/
|
||||
brcs 70f ;if(r22 < ' ') error;
|
||||
cpi r22, '-' ;if(r22 == '-') {
|
||||
brne 42f ; T = 1;
|
||||
set ; continue;
|
||||
rjmp 40b ;}
|
||||
42: cpi r22, '9'+1 ;if(r22 > '9') error;
|
||||
brcc 70f ;/
|
||||
cpi r22, '0' ;if(r22 < '0') error;
|
||||
brcs 70f ;/
|
||||
brne 51f ;if(r22 > '0') cv_start;
|
||||
ldi r25, 8 ;r25 = 8;
|
||||
adiw ZL, 1 ;r22 = *(++Z);
|
||||
ld r22, Z ;/
|
||||
cpi r22, ' '+1 ;if(r22 <= ' ') exit;
|
||||
brcs 80f ;/
|
||||
cpi r22, 'b' ;if(r22 == 'b') {
|
||||
brne 43f ; r25 = 2;
|
||||
ldi r25, 2 ; cv_start;
|
||||
rjmp 50f ;}
|
||||
43: cpi r22, 'x' ;if(r22 != 'x') error;
|
||||
brne 51f ;/
|
||||
ldi r25, 16 ;r25 = 16;
|
||||
|
||||
50: adiw ZL, 1 ;Z++;
|
||||
ld r22, Z ;r22 = *Z;
|
||||
51: cpi r22, ' '+1 ;if(r22 <= ' ') break;
|
||||
brcs 80f ;/
|
||||
cpi r22, 'a' ;if(r22 >= 'a') r22 =- 0x20;
|
||||
brcs 52f ;
|
||||
subi r22, 0x20 ;/
|
||||
52: subi r22, '0' ;if((r22 -= '0') < 0) error;
|
||||
brcs 70f ;/
|
||||
cpi r22, 10 ;if(r22 >= 10) {
|
||||
brcs 53f ; r22 -= 7;
|
||||
subi r22, 7 ; if(r22 < 10)
|
||||
cpi r22, 10 ;
|
||||
brcs 70f ;}
|
||||
53: cp r22, r25 ;if(r22 >= r25) error;
|
||||
brcc 70f ;/
|
||||
60: ldi r24, 33 ;r21:r18 *= r25;
|
||||
sub r23, r23 ;
|
||||
61: brcc 62f ;
|
||||
add r23, r25 ;
|
||||
62: lsr r23 ;
|
||||
ror r21 ;
|
||||
ror r20 ;
|
||||
ror r19 ;
|
||||
ror r18 ;
|
||||
dec r24 ;
|
||||
brne 61b ;/
|
||||
add r18, r22 ;r21:r18 += r22;
|
||||
adc r19, r24 ;
|
||||
adc r20, r24 ;
|
||||
adc r21, r24 ;/
|
||||
rjmp 50b ;repeat
|
||||
|
||||
70: ldi r24, 0
|
||||
rjmp 81f
|
||||
80: ldi r24, 1
|
||||
81: brtc 82f
|
||||
clr r22
|
||||
com r18
|
||||
com r19
|
||||
com r20
|
||||
com r21
|
||||
adc r18, r22
|
||||
adc r19, r22
|
||||
adc r20, r22
|
||||
adc r21, r22
|
||||
82: st -X, ZH
|
||||
st -X, ZL
|
||||
_MOVW XH, XL, r1, r0
|
||||
st X+, r18
|
||||
st X+, r19
|
||||
st X+, r20
|
||||
st X+, r21
|
||||
clr r1
|
||||
ret
|
||||
.endfunc
|
||||
#endif
|
||||
|
||||
|
||||
96
tools/ffsample/avr/xitoa.h
Normal file
96
tools/ffsample/avr/xitoa.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
Extended itoa, puts and printf (C)ChaN, 2006
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef XITOA
|
||||
#define XITOA
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
extern void (*xfunc_out)(char);
|
||||
|
||||
/* This is a pointer to user defined output function. It must be initialized
|
||||
before using this modle.
|
||||
*/
|
||||
|
||||
void xputc(char chr);
|
||||
|
||||
/* This is a stub function to forward outputs to user defined output function.
|
||||
All outputs from this module are output via this function.
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void xputs(const prog_char *string);
|
||||
|
||||
/* The string placed in the ROM is forwarded to xputc() directly.
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void xitoa(long value, char radix, char width);
|
||||
|
||||
/* Extended itoa().
|
||||
|
||||
value radix width output
|
||||
100 10 6 " 100"
|
||||
100 10 -6 "000100"
|
||||
100 10 0 "100"
|
||||
4294967295 10 0 "4294967295"
|
||||
4294967295 -10 0 "-1"
|
||||
655360 16 -8 "000A0000"
|
||||
1024 16 0 "400"
|
||||
0x55 2 -8 "01010101"
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void xprintf(const prog_char *format, ...);
|
||||
|
||||
/* Format string is placed in the ROM. The format flags is similar to printf().
|
||||
|
||||
%[flag][width][size]type
|
||||
|
||||
flag
|
||||
A '0' means filled with '0' when output is shorter than width.
|
||||
' ' is used in default. This is effective only numeral type.
|
||||
width
|
||||
Minimum width in decimal number. This is effective only numeral type.
|
||||
Default width is zero.
|
||||
size
|
||||
A 'l' means the argument is long(32bit). Default is short(16bit).
|
||||
This is effective only numeral type.
|
||||
type
|
||||
'c' : Character, argument is the value
|
||||
's' : String placed on the RAM, argument is the pointer
|
||||
'S' : String placed on the ROM, argument is the pointer
|
||||
'd' : Signed decimal, argument is the value
|
||||
'u' : Unsigned decimal, argument is the value
|
||||
'X' : Hex decimal, argument is the value
|
||||
'b' : Binary, argument is the value
|
||||
'%' : '%'
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
char xatoi(char **str, long *ret);
|
||||
|
||||
/* Get value of the numeral string.
|
||||
|
||||
str
|
||||
Pointer to pointer to source string
|
||||
|
||||
"0b11001010" binary
|
||||
"0377" octal
|
||||
"0xff800" hexdecimal
|
||||
"1250000" decimal
|
||||
"-25000" decimal
|
||||
|
||||
ret
|
||||
Pointer to return value
|
||||
*/
|
||||
|
||||
#endif /* XITOA */
|
||||
|
||||
17
tools/ffsample/linux/Makefile
Normal file
17
tools/ffsample/linux/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
bin = fftest
|
||||
src = ff.c main.c diskio.c
|
||||
objs=$(src:.c=.o)
|
||||
|
||||
|
||||
all: $(src) $(bin)
|
||||
|
||||
$(bin): $(objs)
|
||||
gcc $(ldflags) $(objs) -o $@
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -c $<
|
||||
|
||||
|
||||
|
||||
168
tools/ffsample/linux/diskio.c
Normal file
168
tools/ffsample/linux/diskio.c
Normal file
@@ -0,0 +1,168 @@
|
||||
|
||||
#include "integer.h"
|
||||
#include "diskio.h"
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
/*
|
||||
[david@slap]Transfer/ffsample/linux % sudo mkfs.vfat -F 32 -v disk00.vfat [941]
|
||||
mkfs.vfat 2.11 (12 Mar 2005)
|
||||
disk00.vfat has 64 heads and 32 sectors per track,
|
||||
logical sector size is 512,
|
||||
using 0xf8 media descriptor, with 8192 sectors;
|
||||
file system has 2 32-bit FATs and 1 sector per cluster.
|
||||
FAT size is 63 sectors, and provides 8034 clusters.
|
||||
Volume ID is 4a1424ec, no volume label.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (BYTE drv) {
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
|
||||
Stat |= STA_NOINIT;
|
||||
/* map image */
|
||||
|
||||
Stat &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Return Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (BYTE drv){
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
BYTE c, iord_l, iord_h;
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
/* Issue Read Setor(s) command */
|
||||
/*
|
||||
write_ata(REG_COUNT, count);
|
||||
write_ata(REG_SECTOR, (BYTE)sector);
|
||||
write_ata(REG_CYLL, (BYTE)(sector >> 8));
|
||||
write_ata(REG_CYLH, (BYTE)(sector >> 16));
|
||||
write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
|
||||
write_ata(REG_COMMAND, CMD_READ);
|
||||
*/
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector number (LBA) */
|
||||
BYTE count /* Sector count (1..255) */
|
||||
)
|
||||
{
|
||||
BYTE s, c, iowr_l, iowr_h;
|
||||
|
||||
|
||||
if (drv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
/* Issue Write Setor(s) command */
|
||||
/*
|
||||
write_ata(REG_COUNT, count);
|
||||
write_ata(REG_SECTOR, (BYTE)sector);
|
||||
write_ata(REG_CYLL, (BYTE)(sector >> 8));
|
||||
write_ata(REG_CYLH, (BYTE)(sector >> 16));
|
||||
write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
|
||||
write_ata(REG_COMMAND, CMD_WRITE);
|
||||
*/
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL != 0
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive data block */
|
||||
)
|
||||
{
|
||||
BYTE n, w, ofs, dl, dh, *ptr = buff;
|
||||
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
switch (ctrl) {
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
ofs = 60; w = 2; n = 0;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
|
||||
*(WORD*)buff = 512;
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in sectors (DWORD) */
|
||||
*(DWORD*)buff = 32;
|
||||
return RES_OK;
|
||||
|
||||
case CTRL_SYNC : /* Nothing to do */
|
||||
return RES_OK;
|
||||
|
||||
case ATA_GET_REV : /* Get firmware revision (8 chars) */
|
||||
ofs = 23; w = 4; n = 4;
|
||||
break;
|
||||
|
||||
case ATA_GET_MODEL : /* Get model name (40 chars) */
|
||||
ofs = 27; w = 20; n = 20;
|
||||
break;
|
||||
|
||||
case ATA_GET_SN : /* Get serial number (20 chars) */
|
||||
ofs = 10; w = 10; n = 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
/*
|
||||
write_ata(REG_COMMAND, CMD_IDENTIFY);
|
||||
if (!wait_data()) return RES_ERROR;
|
||||
read_part(ptr, ofs, w);
|
||||
while (n--) {
|
||||
dl = *ptr; dh = *(ptr+1);
|
||||
*ptr++ = dh; *ptr++ = dl;
|
||||
}
|
||||
*/
|
||||
return RES_OK;
|
||||
}
|
||||
#endif /* _USE_IOCTL != 0 */
|
||||
|
||||
|
||||
|
||||
|
||||
81
tools/ffsample/linux/diskio.h
Normal file
81
tools/ffsample/linux/diskio.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file R0.05 (C)ChaN, 2007
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Read-only mode */
|
||||
#define _USE_IOCTL 1
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
#endif
|
||||
DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||
void disk_timerproc (void);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl() */
|
||||
|
||||
/* Generic command */
|
||||
#define CTRL_SYNC 0 /* Mandatory for write functions */
|
||||
#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */
|
||||
#define GET_SECTOR_SIZE 2
|
||||
#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */
|
||||
#define CTRL_POWER 4
|
||||
#define CTRL_LOCK 5
|
||||
#define CTRL_EJECT 6
|
||||
/* MMC/SDC command */
|
||||
#define MMC_GET_TYPE 10
|
||||
#define MMC_GET_CSD 11
|
||||
#define MMC_GET_CID 12
|
||||
#define MMC_GET_OCR 13
|
||||
#define MMC_GET_SDSTAT 14
|
||||
/* ATA/CF command */
|
||||
#define ATA_GET_REV 20
|
||||
#define ATA_GET_MODEL 21
|
||||
#define ATA_GET_SN 22
|
||||
|
||||
|
||||
|
||||
/* Card type flags (CardType) */
|
||||
#define CT_MMC 0x01
|
||||
#define CT_SD1 0x02
|
||||
#define CT_SD2 0x04
|
||||
#define CT_SDC (CT_SD1|CT_SD2)
|
||||
#define CT_BLOCK 0x08
|
||||
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
||||
2936
tools/ffsample/linux/ff.c
Normal file
2936
tools/ffsample/linux/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
547
tools/ffsample/linux/ff.h
Normal file
547
tools/ffsample/linux/ff.h
Normal file
@@ -0,0 +1,547 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.07a (C)ChaN, 2009
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is an open source software to implement FAT file system to
|
||||
/ small embedded systems. This is a free software and is opened for education,
|
||||
/ research and commercial developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Configuration Options
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FATFS
|
||||
#define _FATFS
|
||||
|
||||
#define _WORD_ACCESS 1
|
||||
/* The _WORD_ACCESS option defines which access method is used to the word
|
||||
/ data in the FAT structure.
|
||||
/
|
||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned
|
||||
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code efficiency. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||
/ 3: f_lseek is removed in addition to level 2. */
|
||||
|
||||
|
||||
#define _FS_TINY 1
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _DRIVES 2
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512
|
||||
/* Maximum sector size to be handled. (512/1024/2048/4096) */
|
||||
/* 512 for memroy card and hard disk, 1024 for floppy disk, 2048 for MO disk */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
||||
/ drive number and can mount only first primaly partition. When it is set to 1,
|
||||
/ each volume is tied to the partitions listed in Drives[]. */
|
||||
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ When it is non LFN configuration, there is no difference between SBCS code
|
||||
/ pages. When LFN is enabled, the code page must always be set correctly.
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift-JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
/ 1258 - Vietnam
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (max:255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN.
|
||||
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
||||
/ 2: Enable LFN with dynamic working buffer on the caller's STACK.
|
||||
/
|
||||
/ The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
||||
/ a Unicode - OEM code conversion function ff_convert() must be added to
|
||||
/ the project. */
|
||||
|
||||
|
||||
#define _FS_REENTRANT 0
|
||||
#define _TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* Type of sync object used on the OS. */
|
||||
/* e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
|
||||
/ provided synchronization handlers, ff_req_grant, ff_rel_grant,
|
||||
/ ff_del_syncobj and ff_cre_syncobj function to the project. */
|
||||
|
||||
|
||||
|
||||
/* End of configuration options. Do not change followings without care. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multiple sector size */
|
||||
|
||||
#if _MAX_SS == 512
|
||||
#define SS(fs) 512
|
||||
#else
|
||||
#if _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
|
||||
#define SS(fs) ((fs)->s_size)
|
||||
#else
|
||||
#error Sector size must be 512, 1024, 2048 or 4096.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure */
|
||||
|
||||
typedef struct _FATFS {
|
||||
BYTE fs_type; /* FAT sub type */
|
||||
BYTE drive; /* Physical drive number */
|
||||
BYTE csize; /* Number of sectors per cluster */
|
||||
BYTE n_fats; /* Number of FAT copies */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE pad1;
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if _MAX_SS != 512U
|
||||
WORD s_size; /* Sector size */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
BYTE pad2;
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector */
|
||||
#endif
|
||||
DWORD sects_fat; /* Sectors per fat */
|
||||
DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure */
|
||||
|
||||
typedef struct _DIR {
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current index number */
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
DWORD sclust; /* Table start cluster (0:Static table) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File object structure */
|
||||
|
||||
typedef struct _FIL {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE csect; /* Sector address in the cluster */
|
||||
DWORD fptr; /* File R/W pointer */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS];/* File R/W buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* File status structure */
|
||||
|
||||
typedef struct _FILINFO {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
char fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
char *lfname; /* Pointer to the LFN buffer */
|
||||
int lfsize; /* Size of LFN buffer [bytes] */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* DBCS code ranges */
|
||||
|
||||
#if _CODE_PAGE == 932 /* CP932 (Japanese Shift-JIS) */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* CP936 (Simplified Chinese GBK) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* CP949 (Korean) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* CP950 (Traditional Chinese Big5) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#else /* SBCS code pages */
|
||||
#define _DF1S 0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Character code support macros */
|
||||
|
||||
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
||||
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
||||
#define IsDigit(c) (((c)>='0')&&((c)<='9'))
|
||||
|
||||
#if _DF1S /* DBCS configuration */
|
||||
|
||||
#if _DF2S /* Two 1st byte areas */
|
||||
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
||||
#else /* One 1st byte area */
|
||||
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
||||
#endif
|
||||
|
||||
#if _DS3S /* Three 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
||||
#else /* Two 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
||||
#endif
|
||||
|
||||
#else /* SBCS configuration */
|
||||
|
||||
#define IsDBCS1(c) 0
|
||||
#define IsDBCS2(c) 0
|
||||
|
||||
#endif /* _DF1S */
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multi partition */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
|
||||
typedef struct _PARTITION {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
|
||||
extern
|
||||
const PARTITION Drives[]; /* Logical drive# to physical location conversion table */
|
||||
#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */
|
||||
#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
|
||||
#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */
|
||||
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* 0 */
|
||||
FR_DISK_ERR, /* 1 */
|
||||
FR_INT_ERR, /* 2 */
|
||||
FR_NOT_READY, /* 3 */
|
||||
FR_NO_FILE, /* 4 */
|
||||
FR_NO_PATH, /* 5 */
|
||||
FR_INVALID_NAME, /* 6 */
|
||||
FR_DENIED, /* 7 */
|
||||
FR_EXIST, /* 8 */
|
||||
FR_INVALID_OBJECT, /* 9 */
|
||||
FR_WRITE_PROTECTED, /* 10 */
|
||||
FR_INVALID_DRIVE, /* 11 */
|
||||
FR_NOT_ENABLED, /* 12 */
|
||||
FR_NO_FILESYSTEM, /* 13 */
|
||||
FR_MKFS_ABORTED, /* 14 */
|
||||
FR_TIMEOUT /* 15 */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
|
||||
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const char*); /* Create a new directory */
|
||||
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const char*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||
|
||||
#if _USE_STRFUNC
|
||||
int f_putc (int, FIL*); /* Put a character to the file */
|
||||
int f_puts (const char*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */
|
||||
char* f_gets (char*, int, FIL*); /* Get a string from the file */
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#ifndef EOF
|
||||
#define EOF -1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* User defined functions */
|
||||
|
||||
/* Real time clock */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
|
||||
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
|
||||
#endif
|
||||
|
||||
/* Unicode - OEM code conversion */
|
||||
#if _USE_LFN
|
||||
WCHAR ff_convert (WCHAR, UINT);
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
|
||||
BOOL ff_del_syncobj(_SYNC_t);
|
||||
BOOL ff_req_grant(_SYNC_t);
|
||||
void ff_rel_grant(_SYNC_t);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#if _FS_READONLY == 0
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* FatFs refers the members in the FAT structures with byte offset instead
|
||||
/ of structure member because there are incompatibility of the packing option
|
||||
/ between various compilers. */
|
||||
|
||||
#define BS_jmpBoot 0
|
||||
#define BS_OEMName 3
|
||||
#define BPB_BytsPerSec 11
|
||||
#define BPB_SecPerClus 13
|
||||
#define BPB_RsvdSecCnt 14
|
||||
#define BPB_NumFATs 16
|
||||
#define BPB_RootEntCnt 17
|
||||
#define BPB_TotSec16 19
|
||||
#define BPB_Media 21
|
||||
#define BPB_FATSz16 22
|
||||
#define BPB_SecPerTrk 24
|
||||
#define BPB_NumHeads 26
|
||||
#define BPB_HiddSec 28
|
||||
#define BPB_TotSec32 32
|
||||
#define BS_55AA 510
|
||||
|
||||
#define BS_DrvNum 36
|
||||
#define BS_BootSig 38
|
||||
#define BS_VolID 39
|
||||
#define BS_VolLab 43
|
||||
#define BS_FilSysType 54
|
||||
|
||||
#define BPB_FATSz32 36
|
||||
#define BPB_ExtFlags 40
|
||||
#define BPB_FSVer 42
|
||||
#define BPB_RootClus 44
|
||||
#define BPB_FSInfo 48
|
||||
#define BPB_BkBootSec 50
|
||||
#define BS_DrvNum32 64
|
||||
#define BS_BootSig32 66
|
||||
#define BS_VolID32 67
|
||||
#define BS_VolLab32 71
|
||||
#define BS_FilSysType32 82
|
||||
|
||||
#define FSI_LeadSig 0
|
||||
#define FSI_StrucSig 484
|
||||
#define FSI_Free_Count 488
|
||||
#define FSI_Nxt_Free 492
|
||||
|
||||
#define MBR_Table 446
|
||||
|
||||
#define DIR_Name 0
|
||||
#define DIR_Attr 11
|
||||
#define DIR_NTres 12
|
||||
#define DIR_CrtTime 14
|
||||
#define DIR_CrtDate 16
|
||||
#define DIR_FstClusHI 20
|
||||
#define DIR_WrtTime 22
|
||||
#define DIR_WrtDate 24
|
||||
#define DIR_FstClusLO 26
|
||||
#define DIR_FileSize 28
|
||||
#define LDIR_Ord 0
|
||||
#define LDIR_Attr 11
|
||||
#define LDIR_Type 12
|
||||
#define LDIR_Chksum 13
|
||||
#define LDIR_FstClusLO 26
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _FATFS */
|
||||
BIN
tools/ffsample/linux/fftest
Normal file
BIN
tools/ffsample/linux/fftest
Normal file
Binary file not shown.
37
tools/ffsample/linux/integer.h
Normal file
37
tools/ffsample/linux/integer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef signed char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* Boolean type */
|
||||
typedef enum { FALSE = 0, TRUE } BOOL;
|
||||
|
||||
#endif
|
||||
|
||||
#define _INTEGER
|
||||
#endif
|
||||
522
tools/ffsample/linux/main.c
Normal file
522
tools/ffsample/linux/main.c
Normal file
@@ -0,0 +1,522 @@
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* FAT file system sample project for FatFs R0.06 (C)ChaN, 2008 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
|
||||
DWORD acc_size; /* Work register for fs command */
|
||||
WORD acc_files, acc_dirs;
|
||||
|
||||
FILINFO finfo;
|
||||
|
||||
BYTE line[120]; /* Console input buffer */
|
||||
FATFS fatfs[2]; /* File system object for each logical drive */
|
||||
BYTE Buff[1024]; /* Working buffer */
|
||||
|
||||
volatile WORD Timer; /* 100Hz increment timer */
|
||||
|
||||
|
||||
|
||||
#if _MULTI_PARTITION != 0
|
||||
const PARTITION Drives[] = { {0,0}, {0,1} };
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
char xatoi(char **str, long *ret){
|
||||
*ret = atoi(*str);
|
||||
//printf("'%s' '%li'\n",*str,*ret);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* User Provided Timer Function for FatFs module */
|
||||
/*---------------------------------------------------------*/
|
||||
/* This is a real time clock service to be called from */
|
||||
/* FatFs module. Any valid time must be returned even if */
|
||||
/* the system does not support a real time clock. */
|
||||
/* This is not required in read-only configuration. */
|
||||
|
||||
|
||||
DWORD get_fattime ()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm * ptm;
|
||||
time ( &rawtime );
|
||||
ptm = gmtime ( &rawtime );
|
||||
return ((DWORD)(ptm->tm_year - 80) << 25)
|
||||
| ((DWORD)(ptm->tm_mon +1) << 21)
|
||||
| ((DWORD)ptm->tm_mday << 16)
|
||||
| ((DWORD)ptm->tm_hour << 11)
|
||||
| ((DWORD)ptm->tm_min << 5)
|
||||
| ((DWORD)ptm->tm_sec >> 1);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Monitor */
|
||||
|
||||
|
||||
static
|
||||
void put_dump (const BYTE *buff, LONG ofs, BYTE cnt)
|
||||
{
|
||||
BYTE n;
|
||||
|
||||
|
||||
printf("%08lX ", ofs);
|
||||
for(n = 0; n < cnt; n++)
|
||||
printf(" %02X", buff[n]);
|
||||
printf(" ");
|
||||
for(n = 0; n < cnt; n++) {
|
||||
if ((buff[n] < 0x20)||(buff[n] >= 0x7F))
|
||||
printf(".");
|
||||
else
|
||||
printf("%c",buff[n]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void get_line (char *buff, int len)
|
||||
{
|
||||
char c;
|
||||
int idx = 0;
|
||||
|
||||
for (;;) {
|
||||
c = getc(stdin);
|
||||
if (c == 0x0a) break;
|
||||
if ((c == '\b') && idx) {
|
||||
idx--;
|
||||
}
|
||||
if (((BYTE)c >= ' ') && (idx < len - 1)) {
|
||||
buff[idx++] = c;
|
||||
}
|
||||
}
|
||||
printf("return %s\n",buff);
|
||||
buff[idx] = 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
FRESULT scan_files (char* path)
|
||||
{
|
||||
DIR dirs;
|
||||
FRESULT res;
|
||||
int i;
|
||||
|
||||
if ((res = f_opendir(&dirs, path)) == FR_OK) {
|
||||
i = strlen(path);
|
||||
while (((res = f_readdir(&dirs, &finfo)) == FR_OK) && finfo.fname[0]) {
|
||||
if (finfo.fattrib & AM_DIR) {
|
||||
acc_dirs++;
|
||||
*(path+i) = '/'; strcpy(path+i+1, &finfo.fname[0]);
|
||||
res = scan_files(path);
|
||||
*(path+i) = '\0';
|
||||
if (res != FR_OK) break;
|
||||
} else {
|
||||
acc_files++;
|
||||
acc_size += finfo.fsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void put_rc (FRESULT rc)
|
||||
{
|
||||
const char* str[] = {
|
||||
"OK",
|
||||
"DISK_ERR",
|
||||
"INT_ERR",
|
||||
"NOT_READY",
|
||||
"NO_FILE",
|
||||
"NO_PATH",
|
||||
"INVALID_NAME",
|
||||
"DENIED",
|
||||
"EXIST",
|
||||
"INVALID_OBJECT",
|
||||
"WRITE_PROTECTED",
|
||||
"INVALID_DRIVE",
|
||||
"NOT_ENABLED",
|
||||
"NO_FILE_SYSTEM",
|
||||
"MKFS_ABORTED",
|
||||
"TIMEOUT"
|
||||
};
|
||||
printf("rc=%u FR_%s\n", (WORD)rc, str[rc]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
void IoInit ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Main */
|
||||
|
||||
int main (void)
|
||||
{
|
||||
char *ptr, *ptr2;
|
||||
DWORD p1, p2, p3;
|
||||
BYTE res, b1;
|
||||
WORD w1;
|
||||
UINT s1, s2, cnt;
|
||||
DWORD ofs, sect = 0;
|
||||
time_t rawtime;
|
||||
struct tm * ptm;
|
||||
|
||||
FATFS *fs;
|
||||
DIR dir; /* Directory object */
|
||||
FIL file1, file2; /* File object */
|
||||
|
||||
|
||||
IoInit();
|
||||
|
||||
|
||||
printf("FatFs module test monitor\n");
|
||||
|
||||
for (;;) {
|
||||
printf(">");
|
||||
get_line(line, sizeof(line));
|
||||
ptr = line;
|
||||
switch (*ptr++) {
|
||||
case 'd' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* dd <phy_drv#> [<sector>] - Dump secrtor */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) p2 = sect;
|
||||
res = disk_read((BYTE)p1, Buff, p2, 1);
|
||||
if (res) { printf("rc=%d\n", (WORD)res); break; }
|
||||
sect = p2 + 1;
|
||||
printf("Sector:%lu\n", p2);
|
||||
for (ptr=Buff, ofs = 0; ofs < 0x200; ptr+=16, ofs+=16)
|
||||
put_dump(ptr, ofs, 16);
|
||||
break;
|
||||
|
||||
case 'i' : /* di <phy_drv#> - Initialize disk */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
printf("rc=%d\n", (WORD)disk_initialize((BYTE)p1));
|
||||
break;
|
||||
|
||||
case 's' : /* ds <phy_drv#> - Show disk status */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &p2) == RES_OK)
|
||||
{ printf("Drive size: %lu sectors\n", p2); }
|
||||
if (disk_ioctl((BYTE)p1, GET_SECTOR_SIZE, &w1) == RES_OK)
|
||||
{ printf("Sector size: %u\n", w1); }
|
||||
if (disk_ioctl((BYTE)p1, GET_BLOCK_SIZE, &p2) == RES_OK)
|
||||
{ printf("Erase block size: %lu sectors\n", p2); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_TYPE, &b1) == RES_OK)
|
||||
{ printf("Card type: %u\n", b1); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_CSD, Buff) == RES_OK)
|
||||
{ printf("CSD:\n"); put_dump(Buff, 0, 16); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_CID, Buff) == RES_OK)
|
||||
{ printf("CID:\n"); put_dump(Buff, 0, 16); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_OCR, Buff) == RES_OK)
|
||||
{ printf("OCR:\n"); put_dump(Buff, 0, 4); }
|
||||
if (disk_ioctl((BYTE)p1, MMC_GET_SDSTAT, Buff) == RES_OK) {
|
||||
printf("SD Status:\n");
|
||||
for (s1 = 0; s1 < 64; s1 += 16) put_dump(Buff+s1, s1, 16);
|
||||
}
|
||||
if (disk_ioctl((BYTE)p1, ATA_GET_MODEL, line) == RES_OK)
|
||||
{ line[40] = '\0'; printf("Model: %s\n", line); }
|
||||
if (disk_ioctl((BYTE)p1, ATA_GET_SN, line) == RES_OK)
|
||||
{ line[20] = '\0'; printf("S/N: %s\n", line); }
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'b' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* bd <addr> - Dump R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
for (ptr=&Buff[p1], ofs = p1, cnt = 32; cnt; cnt--, ptr+=16, ofs+=16)
|
||||
put_dump(ptr, ofs, 16);
|
||||
break;
|
||||
|
||||
case 'e' : /* be <addr> [<data>] ... - Edit R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (xatoi(&ptr, &p2)) {
|
||||
do {
|
||||
Buff[p1++] = (BYTE)p2;
|
||||
} while (xatoi(&ptr, &p2));
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
printf("%04X %02X-", (WORD)(p1), (WORD)Buff[p1]);
|
||||
get_line(line, sizeof(line));
|
||||
ptr = line;
|
||||
if (*ptr == '.') break;
|
||||
if (*ptr < ' ') { p1++; continue; }
|
||||
if (xatoi(&ptr, &p2))
|
||||
Buff[p1++] = (BYTE)p2;
|
||||
else
|
||||
printf("???\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r' : /* br <phy_drv#> <sector> [<n>] - Read disk into R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) break;
|
||||
if (!xatoi(&ptr, &p3)) p3 = 1;
|
||||
printf("rc=%u\n", (WORD)disk_read((BYTE)p1, Buff, p2, p3));
|
||||
break;
|
||||
|
||||
case 'w' : /* bw <phy_drv#> <sector> [<n>] - Write R/W buffer into disk */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) break;
|
||||
if (!xatoi(&ptr, &p3)) p3 = 1;
|
||||
printf("rc=%u\n", (WORD)disk_write((BYTE)p1, Buff, p2, p3));
|
||||
break;
|
||||
|
||||
case 'f' : /* bf <n> - Fill working buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
memset(Buff, (BYTE)p1, sizeof(Buff));
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f' :
|
||||
switch (*ptr++) {
|
||||
|
||||
case 'i' : /* fi <log drv#> - Initialize logical drive */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
put_rc(f_mount((BYTE)p1, &fatfs[p1]));
|
||||
break;
|
||||
|
||||
case 's' : /* fs [<path>] - Show logical drive status */
|
||||
while (*ptr == ' ') ptr++;
|
||||
res = f_getfree(ptr, &p2, &fs);
|
||||
if (res) { put_rc(res); break; }
|
||||
printf("FAT type = %u\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
|
||||
"Root DIR entries = %u\nSectors/FAT = %lu\nNumber of clusters = %lu\n"
|
||||
"FAT start (lba) = %lu\nDIR start (lba,clustor) = %lu\nData start (lba) = %lu\n",
|
||||
(WORD)fs->fs_type, (DWORD)fs->csize * 512, (WORD)fs->n_fats,
|
||||
fs->n_rootdir, (DWORD)fs->sects_fat, (DWORD)fs->max_clust - 2,
|
||||
fs->fatbase, fs->dirbase, fs->database
|
||||
);
|
||||
acc_size = acc_files = acc_dirs = 0;
|
||||
res = scan_files(ptr);
|
||||
if (res) { put_rc(res); break; }
|
||||
printf("%u files, %lu bytes.\n%u folders.\n"
|
||||
"%lu KB total disk space.\n%lu KB available.\n",
|
||||
acc_files, acc_size, acc_dirs,
|
||||
(fs->max_clust - 2) * (fs->csize / 2), p2 * (fs->csize / 2)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'l' : /* fl [<path>] - Directory listing */
|
||||
while (*ptr == ' ') ptr++;
|
||||
res = f_opendir(&dir, ptr);
|
||||
if (res) { put_rc(res); break; }
|
||||
p1 = s1 = s2 = 0;
|
||||
for(;;) {
|
||||
res = f_readdir(&dir, &finfo);
|
||||
if ((res != FR_OK) || !finfo.fname[0]) break;
|
||||
if (finfo.fattrib & AM_DIR) {
|
||||
s2++;
|
||||
} else {
|
||||
s1++; p1 += finfo.fsize;
|
||||
}
|
||||
printf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s\n",
|
||||
(finfo.fattrib & AM_DIR) ? 'D' : '-',
|
||||
(finfo.fattrib & AM_RDO) ? 'R' : '-',
|
||||
(finfo.fattrib & AM_HID) ? 'H' : '-',
|
||||
(finfo.fattrib & AM_SYS) ? 'S' : '-',
|
||||
(finfo.fattrib & AM_ARC) ? 'A' : '-',
|
||||
(finfo.fdate >> 9) + 1980, (finfo.fdate >> 5) & 15, finfo.fdate & 31,
|
||||
(finfo.ftime >> 11), (finfo.ftime >> 5) & 63,
|
||||
finfo.fsize, &(finfo.fname[0]));
|
||||
}
|
||||
printf("%4u File(s),%10lu bytes total\n%4u Dir(s)", s1, p1, s2);
|
||||
if (f_getfree(ptr, &p1, &fs) == FR_OK)
|
||||
printf(", %10luK bytes free\n", p1 * fs->csize / 2);
|
||||
break;
|
||||
|
||||
case 'o' : /* fo <mode> <name> - Open a file */
|
||||
if (!(&ptr, &p1)) break;
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_open(&file1, ptr, (BYTE)p1));
|
||||
break;
|
||||
|
||||
case 'c' : /* fc - Close a file */
|
||||
put_rc(f_close(&file1));
|
||||
break;
|
||||
|
||||
case 'e' : /* fe - Seek file pointer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
res = f_lseek(&file1, p1);
|
||||
put_rc(res);
|
||||
if (res == FR_OK)
|
||||
printf("fptr = %lu(0x%lX)\n", file1.fptr, file1.fptr);
|
||||
break;
|
||||
|
||||
case 'r' : /* fr <len> - read file */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
p2 = 0;
|
||||
Timer = 0;
|
||||
while (p1) {
|
||||
if (p1 >= sizeof(Buff)) { cnt = sizeof(Buff); p1 -= sizeof(Buff); }
|
||||
else { cnt = (WORD)p1; p1 = 0; }
|
||||
res = f_read(&file1, Buff, cnt, &s2);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
p2 += s2;
|
||||
if (cnt != s2) break;
|
||||
}
|
||||
s2 = Timer;
|
||||
printf("%lu bytes read with %lu bytes/sec.\n", p2, p2 * 100 / s2);
|
||||
break;
|
||||
|
||||
case 'd' : /* fd <len> - read and dump file from current fp */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
ofs = file1.fptr;
|
||||
while (p1) {
|
||||
if (p1 >= 16) { cnt = 16; p1 -= 16; }
|
||||
else { cnt = (WORD)p1; p1 = 0; }
|
||||
res = f_read(&file1, Buff, cnt, &cnt);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
if (!cnt) break;
|
||||
put_dump(Buff, ofs, cnt);
|
||||
ofs += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w' : /* fw <len> <val> - write file */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
|
||||
memset(Buff, (BYTE)p2, sizeof(Buff));
|
||||
p2 = 0;
|
||||
Timer = 0;
|
||||
while (p1) {
|
||||
if (p1 >= sizeof(Buff)) { cnt = sizeof(Buff); p1 -= sizeof(Buff); }
|
||||
else { cnt = (WORD)p1; p1 = 0; }
|
||||
res = f_write(&file1, Buff, cnt, &s2);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
p2 += s2;
|
||||
if (cnt != s2) break;
|
||||
}
|
||||
s2 = Timer;
|
||||
printf("%lu bytes written with %lu bytes/sec.\n", p2, p2 * 100 / s2);
|
||||
break;
|
||||
|
||||
case 'v' : /* fv - Truncate file */
|
||||
put_rc(f_truncate(&file1));
|
||||
break;
|
||||
|
||||
case 'n' : /* fn <old_name> <new_name> - Change file/dir name */
|
||||
while (*ptr == ' ') ptr++;
|
||||
ptr2 = strchr(ptr, ' ');
|
||||
if (!ptr2) break;
|
||||
*ptr2++ = 0;
|
||||
while (*ptr2 == ' ') ptr2++;
|
||||
put_rc(f_rename(ptr, ptr2));
|
||||
break;
|
||||
|
||||
case 'u' : /* fu <name> - Unlink a file or dir */
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_unlink(ptr));
|
||||
break;
|
||||
|
||||
case 'k' : /* fk <name> - Create a directory */
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_mkdir(ptr));
|
||||
break;
|
||||
|
||||
case 'a' : /* fa <atrr> <mask> <name> - Change file/dir attribute */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_chmod(ptr, p1, p2));
|
||||
break;
|
||||
|
||||
case 't' : /* ft <year> <month> <day> <hour> <min> <sec> <name> */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31);
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
finfo.ftime = ((p1 & 31) << 11) | ((p1 & 63) << 5) | ((p1 >> 1) & 31);
|
||||
put_rc(f_utime(ptr, &finfo));
|
||||
break;
|
||||
|
||||
case 'x' : /* fx <src_name> <dst_name> - Copy file */
|
||||
while (*ptr == ' ') ptr++;
|
||||
ptr2 = strchr(ptr, ' ');
|
||||
if (!ptr2) break;
|
||||
*ptr2++ = 0;
|
||||
printf("Opening \"%s\"", ptr);
|
||||
res = f_open(&file1, ptr, FA_OPEN_EXISTING | FA_READ);
|
||||
if (res) {
|
||||
put_rc(res);
|
||||
break;
|
||||
}
|
||||
printf("\nCreating \"%s\"", ptr2);
|
||||
res = f_open(&file2, ptr2, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res) {
|
||||
put_rc(res);
|
||||
f_close(&file1);
|
||||
break;
|
||||
}
|
||||
printf("\nCopying...");
|
||||
p1 = 0;
|
||||
for (;;) {
|
||||
res = f_read(&file1, Buff, sizeof(Buff), &s1);
|
||||
if (res || s1 == 0) break; /* error or eof */
|
||||
res = f_write(&file2, Buff, s1, &s2);
|
||||
p1 += s2;
|
||||
if (res || s2 < s1) break; /* error or disk full */
|
||||
}
|
||||
if (res) put_rc(res);
|
||||
printf("\n%lu bytes copied.\n", p1);
|
||||
f_close(&file1);
|
||||
f_close(&file2);
|
||||
break;
|
||||
#if _USE_MKFS
|
||||
case 'm' : /* fm <logi drv#> <part type> <bytes/clust> - Create file system */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
printf("The drive %u will be formatted. Are you sure? (Y/n)=", (WORD)p1);
|
||||
get_line(ptr, sizeof(line));
|
||||
if (*ptr == 'Y') put_rc(f_mkfs((BYTE)p1, (BYTE)p2, (WORD)p3));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case 't' : /* t [<year> <mon> <mday> <hour> <min> <sec>] */
|
||||
if (xatoi(&ptr, &p1)) {
|
||||
time ( &rawtime );
|
||||
ptm = gmtime ( &rawtime );
|
||||
ptm->tm_year = (WORD)p1;
|
||||
xatoi(&ptr, &p1); ptm->tm_mon = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); ptm->tm_mday = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); ptm->tm_hour = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); ptm->tm_min = (BYTE)p1;
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
ptm->tm_sec = (BYTE)p1;
|
||||
//rtc_settime(&rtc);
|
||||
}
|
||||
time ( &rawtime );
|
||||
ptm = gmtime ( &rawtime );
|
||||
printf("%u/%u/%u %02u:%02u:%02u\n", 1900 + ptm->tm_year, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
957
tools/ffsample/lpc2k/LPC2300.h
Normal file
957
tools/ffsample/lpc2k/LPC2300.h
Normal file
@@ -0,0 +1,957 @@
|
||||
/* LPC2300 peripheral registers */
|
||||
#ifndef __LPC2300
|
||||
#define __LPC2300
|
||||
#include "integer.h"
|
||||
|
||||
#define VICIRQStatus (*(volatile DWORD*)(0xFFFFF000))
|
||||
#define VICFIQStatus (*(volatile DWORD*)(0xFFFFF004))
|
||||
#define VICRawIntr (*(volatile DWORD*)(0xFFFFF008))
|
||||
#define VICIntSelect (*(volatile DWORD*)(0xFFFFF00C))
|
||||
#define VICIntEnable (*(volatile DWORD*)(0xFFFFF010))
|
||||
#define VICIntEnClr (*(volatile DWORD*)(0xFFFFF014))
|
||||
#define VICSoftInt (*(volatile DWORD*)(0xFFFFF018))
|
||||
#define VICSoftIntClr (*(volatile DWORD*)(0xFFFFF01C))
|
||||
#define VICProtection (*(volatile DWORD*)(0xFFFFF020))
|
||||
#define VICSWPrioMask (*(volatile DWORD*)(0xFFFFF024))
|
||||
#define VICVectAddr0 (*(volatile DWORD*)(0xFFFFF100))
|
||||
#define VICVectAddr1 (*(volatile DWORD*)(0xFFFFF104))
|
||||
#define VICVectAddr2 (*(volatile DWORD*)(0xFFFFF108))
|
||||
#define VICVectAddr3 (*(volatile DWORD*)(0xFFFFF10C))
|
||||
#define VICVectAddr4 (*(volatile DWORD*)(0xFFFFF110))
|
||||
#define VICVectAddr5 (*(volatile DWORD*)(0xFFFFF114))
|
||||
#define VICVectAddr6 (*(volatile DWORD*)(0xFFFFF118))
|
||||
#define VICVectAddr7 (*(volatile DWORD*)(0xFFFFF11C))
|
||||
#define VICVectAddr8 (*(volatile DWORD*)(0xFFFFF120))
|
||||
#define VICVectAddr9 (*(volatile DWORD*)(0xFFFFF124))
|
||||
#define VICVectAddr10 (*(volatile DWORD*)(0xFFFFF128))
|
||||
#define VICVectAddr11 (*(volatile DWORD*)(0xFFFFF12C))
|
||||
#define VICVectAddr12 (*(volatile DWORD*)(0xFFFFF130))
|
||||
#define VICVectAddr13 (*(volatile DWORD*)(0xFFFFF134))
|
||||
#define VICVectAddr14 (*(volatile DWORD*)(0xFFFFF138))
|
||||
#define VICVectAddr15 (*(volatile DWORD*)(0xFFFFF13C))
|
||||
#define VICVectAddr16 (*(volatile DWORD*)(0xFFFFF140))
|
||||
#define VICVectAddr17 (*(volatile DWORD*)(0xFFFFF144))
|
||||
#define VICVectAddr18 (*(volatile DWORD*)(0xFFFFF148))
|
||||
#define VICVectAddr19 (*(volatile DWORD*)(0xFFFFF14C))
|
||||
#define VICVectAddr20 (*(volatile DWORD*)(0xFFFFF150))
|
||||
#define VICVectAddr21 (*(volatile DWORD*)(0xFFFFF154))
|
||||
#define VICVectAddr22 (*(volatile DWORD*)(0xFFFFF158))
|
||||
#define VICVectAddr23 (*(volatile DWORD*)(0xFFFFF15C))
|
||||
#define VICVectAddr24 (*(volatile DWORD*)(0xFFFFF160))
|
||||
#define VICVectAddr25 (*(volatile DWORD*)(0xFFFFF164))
|
||||
#define VICVectAddr26 (*(volatile DWORD*)(0xFFFFF168))
|
||||
#define VICVectAddr27 (*(volatile DWORD*)(0xFFFFF16C))
|
||||
#define VICVectAddr28 (*(volatile DWORD*)(0xFFFFF170))
|
||||
#define VICVectAddr29 (*(volatile DWORD*)(0xFFFFF174))
|
||||
#define VICVectAddr30 (*(volatile DWORD*)(0xFFFFF178))
|
||||
#define VICVectAddr31 (*(volatile DWORD*)(0xFFFFF17C))
|
||||
#define VICVectCntl0 (*(volatile DWORD*)(0xFFFFF200))
|
||||
#define VICVectCntl1 (*(volatile DWORD*)(0xFFFFF204))
|
||||
#define VICVectCntl2 (*(volatile DWORD*)(0xFFFFF208))
|
||||
#define VICVectCntl3 (*(volatile DWORD*)(0xFFFFF20C))
|
||||
#define VICVectCntl4 (*(volatile DWORD*)(0xFFFFF210))
|
||||
#define VICVectCntl5 (*(volatile DWORD*)(0xFFFFF214))
|
||||
#define VICVectCntl6 (*(volatile DWORD*)(0xFFFFF218))
|
||||
#define VICVectCntl7 (*(volatile DWORD*)(0xFFFFF21C))
|
||||
#define VICVectCntl8 (*(volatile DWORD*)(0xFFFFF220))
|
||||
#define VICVectCntl9 (*(volatile DWORD*)(0xFFFFF224))
|
||||
#define VICVectCntl10 (*(volatile DWORD*)(0xFFFFF228))
|
||||
#define VICVectCntl11 (*(volatile DWORD*)(0xFFFFF22C))
|
||||
#define VICVectCntl12 (*(volatile DWORD*)(0xFFFFF230))
|
||||
#define VICVectCntl13 (*(volatile DWORD*)(0xFFFFF234))
|
||||
#define VICVectCntl14 (*(volatile DWORD*)(0xFFFFF238))
|
||||
#define VICVectCntl15 (*(volatile DWORD*)(0xFFFFF23C))
|
||||
#define VICVectCntl16 (*(volatile DWORD*)(0xFFFFF240))
|
||||
#define VICVectCntl17 (*(volatile DWORD*)(0xFFFFF244))
|
||||
#define VICVectCntl18 (*(volatile DWORD*)(0xFFFFF248))
|
||||
#define VICVectCntl19 (*(volatile DWORD*)(0xFFFFF24C))
|
||||
#define VICVectCntl20 (*(volatile DWORD*)(0xFFFFF250))
|
||||
#define VICVectCntl21 (*(volatile DWORD*)(0xFFFFF254))
|
||||
#define VICVectCntl22 (*(volatile DWORD*)(0xFFFFF258))
|
||||
#define VICVectCntl23 (*(volatile DWORD*)(0xFFFFF25C))
|
||||
#define VICVectCntl24 (*(volatile DWORD*)(0xFFFFF260))
|
||||
#define VICVectCntl25 (*(volatile DWORD*)(0xFFFFF264))
|
||||
#define VICVectCntl26 (*(volatile DWORD*)(0xFFFFF268))
|
||||
#define VICVectCntl27 (*(volatile DWORD*)(0xFFFFF26C))
|
||||
#define VICVectCntl28 (*(volatile DWORD*)(0xFFFFF270))
|
||||
#define VICVectCntl29 (*(volatile DWORD*)(0xFFFFF274))
|
||||
#define VICVectCntl30 (*(volatile DWORD*)(0xFFFFF278))
|
||||
#define VICVectCntl31 (*(volatile DWORD*)(0xFFFFF27C))
|
||||
#define VICVectAddr (*(volatile DWORD*)(0xFFFFFF00))
|
||||
|
||||
#define PINSEL0 (*(volatile DWORD*)(0xE002C000))
|
||||
#define PINSEL1 (*(volatile DWORD*)(0xE002C004))
|
||||
#define PINSEL2 (*(volatile DWORD*)(0xE002C008))
|
||||
#define PINSEL3 (*(volatile DWORD*)(0xE002C00C))
|
||||
#define PINSEL4 (*(volatile DWORD*)(0xE002C010))
|
||||
#define PINSEL5 (*(volatile DWORD*)(0xE002C014))
|
||||
#define PINSEL6 (*(volatile DWORD*)(0xE002C018))
|
||||
#define PINSEL7 (*(volatile DWORD*)(0xE002C01C))
|
||||
#define PINSEL8 (*(volatile DWORD*)(0xE002C020))
|
||||
#define PINSEL9 (*(volatile DWORD*)(0xE002C024))
|
||||
#define PINSEL10 (*(volatile DWORD*)(0xE002C028))
|
||||
|
||||
#define PINMODE0 (*(volatile DWORD*)(0xE002C040))
|
||||
#define PINMODE1 (*(volatile DWORD*)(0xE002C044))
|
||||
#define PINMODE2 (*(volatile DWORD*)(0xE002C048))
|
||||
#define PINMODE3 (*(volatile DWORD*)(0xE002C04C))
|
||||
#define PINMODE4 (*(volatile DWORD*)(0xE002C050))
|
||||
#define PINMODE5 (*(volatile DWORD*)(0xE002C054))
|
||||
#define PINMODE6 (*(volatile DWORD*)(0xE002C058))
|
||||
#define PINMODE7 (*(volatile DWORD*)(0xE002C05C))
|
||||
#define PINMODE8 (*(volatile DWORD*)(0xE002C060))
|
||||
#define PINMODE9 (*(volatile DWORD*)(0xE002C064))
|
||||
|
||||
#define IOPIN0 (*(volatile DWORD*)(0xE0028000))
|
||||
#define IOSET0 (*(volatile DWORD*)(0xE0028004))
|
||||
#define IODIR0 (*(volatile DWORD*)(0xE0028008))
|
||||
#define IOCLR0 (*(volatile DWORD*)(0xE002800C))
|
||||
#define IOPIN1 (*(volatile DWORD*)(0xE0028010))
|
||||
#define IOSET1 (*(volatile DWORD*)(0xE0028014))
|
||||
#define IODIR1 (*(volatile DWORD*)(0xE0028018))
|
||||
#define IOCLR1 (*(volatile DWORD*)(0xE002801C))
|
||||
|
||||
#define IO0_INT_EN_R (*(volatile DWORD*)(0xE0028090))
|
||||
#define IO0_INT_EN_F (*(volatile DWORD*)(0xE0028094))
|
||||
#define IO0_INT_STAT_R (*(volatile DWORD*)(0xE0028084))
|
||||
#define IO0_INT_STAT_F (*(volatile DWORD*)(0xE0028088))
|
||||
#define IO0_INT_CLR (*(volatile DWORD*)(0xE002808C))
|
||||
#define IO2_INT_EN_R (*(volatile DWORD*)(0xE00280B0))
|
||||
#define IO2_INT_EN_F (*(volatile DWORD*)(0xE00280B4))
|
||||
#define IO2_INT_STAT_R (*(volatile DWORD*)(0xE00280A4))
|
||||
#define IO2_INT_STAT_F (*(volatile DWORD*)(0xE00280A8))
|
||||
#define IO2_INT_CLR (*(volatile DWORD*)(0xE00280AC))
|
||||
#define IO_INT_STAT (*(volatile DWORD*)(0xE0028080))
|
||||
|
||||
#define PARTCFG (*(volatile DWORD*)(0x3FFF8000))
|
||||
|
||||
#define FIO0DIR (*(volatile DWORD*)(0x3FFFC000))
|
||||
#define FIO0MASK (*(volatile DWORD*)(0x3FFFC010))
|
||||
#define FIO0PIN (*(volatile DWORD*)(0x3FFFC014))
|
||||
#define FIO0SET (*(volatile DWORD*)(0x3FFFC018))
|
||||
#define FIO0CLR (*(volatile DWORD*)(0x3FFFC01C))
|
||||
#define FIO1DIR (*(volatile DWORD*)(0x3FFFC020))
|
||||
#define FIO1MASK (*(volatile DWORD*)(0x3FFFC030))
|
||||
#define FIO1PIN (*(volatile DWORD*)(0x3FFFC034))
|
||||
#define FIO1SET (*(volatile DWORD*)(0x3FFFC038))
|
||||
#define FIO1CLR (*(volatile DWORD*)(0x3FFFC03C))
|
||||
#define FIO2DIR (*(volatile DWORD*)(0x3FFFC040))
|
||||
#define FIO2MASK (*(volatile DWORD*)(0x3FFFC050))
|
||||
#define FIO2PIN (*(volatile DWORD*)(0x3FFFC054))
|
||||
#define FIO2SET (*(volatile DWORD*)(0x3FFFC058))
|
||||
#define FIO2CLR (*(volatile DWORD*)(0x3FFFC05C))
|
||||
#define FIO3DIR (*(volatile DWORD*)(0x3FFFC060))
|
||||
#define FIO3MASK (*(volatile DWORD*)(0x3FFFC070))
|
||||
#define FIO3PIN (*(volatile DWORD*)(0x3FFFC074))
|
||||
#define FIO3SET (*(volatile DWORD*)(0x3FFFC078))
|
||||
#define FIO3CLR (*(volatile DWORD*)(0x3FFFC07C))
|
||||
#define FIO4DIR (*(volatile DWORD*)(0x3FFFC080))
|
||||
#define FIO4MASK (*(volatile DWORD*)(0x3FFFC090))
|
||||
#define FIO4PIN (*(volatile DWORD*)(0x3FFFC094))
|
||||
#define FIO4SET (*(volatile DWORD*)(0x3FFFC098))
|
||||
#define FIO4CLR (*(volatile DWORD*)(0x3FFFC09C))
|
||||
|
||||
#define FIO0DIR0 (*(volatile BYTE*)(0x3FFFC000))
|
||||
#define FIO1DIR0 (*(volatile BYTE*)(0x3FFFC020))
|
||||
#define FIO2DIR0 (*(volatile BYTE*)(0x3FFFC040))
|
||||
#define FIO3DIR0 (*(volatile BYTE*)(0x3FFFC060))
|
||||
#define FIO4DIR0 (*(volatile BYTE*)(0x3FFFC080))
|
||||
#define FIO0DIR1 (*(volatile BYTE*)(0x3FFFC001))
|
||||
#define FIO1DIR1 (*(volatile BYTE*)(0x3FFFC021))
|
||||
#define FIO2DIR1 (*(volatile BYTE*)(0x3FFFC041))
|
||||
#define FIO3DIR1 (*(volatile BYTE*)(0x3FFFC061))
|
||||
#define FIO4DIR1 (*(volatile BYTE*)(0x3FFFC081))
|
||||
#define FIO0DIR2 (*(volatile BYTE*)(0x3FFFC002))
|
||||
#define FIO1DIR2 (*(volatile BYTE*)(0x3FFFC022))
|
||||
#define FIO2DIR2 (*(volatile BYTE*)(0x3FFFC042))
|
||||
#define FIO3DIR2 (*(volatile BYTE*)(0x3FFFC062))
|
||||
#define FIO4DIR2 (*(volatile BYTE*)(0x3FFFC082))
|
||||
#define FIO0DIR3 (*(volatile BYTE*)(0x3FFFC003))
|
||||
#define FIO1DIR3 (*(volatile BYTE*)(0x3FFFC023))
|
||||
#define FIO2DIR3 (*(volatile BYTE*)(0x3FFFC043))
|
||||
#define FIO3DIR3 (*(volatile BYTE*)(0x3FFFC063))
|
||||
#define FIO4DIR3 (*(volatile BYTE*)(0x3FFFC083))
|
||||
|
||||
#define FIO0DIRL (*(volatile WORD*)(0x3FFFC000))
|
||||
#define FIO1DIRL (*(volatile WORD*)(0x3FFFC020))
|
||||
#define FIO2DIRL (*(volatile WORD*)(0x3FFFC040))
|
||||
#define FIO3DIRL (*(volatile WORD*)(0x3FFFC060))
|
||||
#define FIO4DIRL (*(volatile WORD*)(0x3FFFC080))
|
||||
#define FIO0DIRU (*(volatile WORD*)(0x3FFFC002))
|
||||
#define FIO1DIRU (*(volatile WORD*)(0x3FFFC022))
|
||||
#define FIO2DIRU (*(volatile WORD*)(0x3FFFC042))
|
||||
#define FIO3DIRU (*(volatile WORD*)(0x3FFFC062))
|
||||
#define FIO4DIRU (*(volatile WORD*)(0x3FFFC082))
|
||||
|
||||
#define FIO0MASK0 (*(volatile BYTE*)(0x3FFFC010))
|
||||
#define FIO1MASK0 (*(volatile BYTE*)(0x3FFFC030))
|
||||
#define FIO2MASK0 (*(volatile BYTE*)(0x3FFFC050))
|
||||
#define FIO3MASK0 (*(volatile BYTE*)(0x3FFFC070))
|
||||
#define FIO4MASK0 (*(volatile BYTE*)(0x3FFFC090))
|
||||
#define FIO0MASK1 (*(volatile BYTE*)(0x3FFFC011))
|
||||
#define FIO1MASK1 (*(volatile BYTE*)(0x3FFFC021))
|
||||
#define FIO2MASK1 (*(volatile BYTE*)(0x3FFFC051))
|
||||
#define FIO3MASK1 (*(volatile BYTE*)(0x3FFFC071))
|
||||
#define FIO4MASK1 (*(volatile BYTE*)(0x3FFFC091))
|
||||
#define FIO0MASK2 (*(volatile BYTE*)(0x3FFFC012))
|
||||
#define FIO1MASK2 (*(volatile BYTE*)(0x3FFFC032))
|
||||
#define FIO2MASK2 (*(volatile BYTE*)(0x3FFFC052))
|
||||
#define FIO3MASK2 (*(volatile BYTE*)(0x3FFFC072))
|
||||
#define FIO4MASK2 (*(volatile BYTE*)(0x3FFFC092))
|
||||
#define FIO0MASK3 (*(volatile BYTE*)(0x3FFFC013))
|
||||
#define FIO1MASK3 (*(volatile BYTE*)(0x3FFFC033))
|
||||
#define FIO2MASK3 (*(volatile BYTE*)(0x3FFFC053))
|
||||
#define FIO3MASK3 (*(volatile BYTE*)(0x3FFFC073))
|
||||
#define FIO4MASK3 (*(volatile BYTE*)(0x3FFFC093))
|
||||
|
||||
#define FIO0MASKL (*(volatile WORD*)(0x3FFFC010))
|
||||
#define FIO1MASKL (*(volatile WORD*)(0x3FFFC030))
|
||||
#define FIO2MASKL (*(volatile WORD*)(0x3FFFC050))
|
||||
#define FIO3MASKL (*(volatile WORD*)(0x3FFFC070))
|
||||
#define FIO4MASKL (*(volatile WORD*)(0x3FFFC090))
|
||||
#define FIO0MASKU (*(volatile WORD*)(0x3FFFC012))
|
||||
#define FIO1MASKU (*(volatile WORD*)(0x3FFFC032))
|
||||
#define FIO2MASKU (*(volatile WORD*)(0x3FFFC052))
|
||||
#define FIO3MASKU (*(volatile WORD*)(0x3FFFC072))
|
||||
#define FIO4MASKU (*(volatile WORD*)(0x3FFFC092))
|
||||
|
||||
#define FIO0PIN0 (*(volatile BYTE*)(0x3FFFC014))
|
||||
#define FIO1PIN0 (*(volatile BYTE*)(0x3FFFC034))
|
||||
#define FIO2PIN0 (*(volatile BYTE*)(0x3FFFC054))
|
||||
#define FIO3PIN0 (*(volatile BYTE*)(0x3FFFC074))
|
||||
#define FIO4PIN0 (*(volatile BYTE*)(0x3FFFC094))
|
||||
#define FIO0PIN1 (*(volatile BYTE*)(0x3FFFC015))
|
||||
#define FIO1PIN1 (*(volatile BYTE*)(0x3FFFC025))
|
||||
#define FIO2PIN1 (*(volatile BYTE*)(0x3FFFC055))
|
||||
#define FIO3PIN1 (*(volatile BYTE*)(0x3FFFC075))
|
||||
#define FIO4PIN1 (*(volatile BYTE*)(0x3FFFC095))
|
||||
#define FIO0PIN2 (*(volatile BYTE*)(0x3FFFC016))
|
||||
#define FIO1PIN2 (*(volatile BYTE*)(0x3FFFC036))
|
||||
#define FIO2PIN2 (*(volatile BYTE*)(0x3FFFC056))
|
||||
#define FIO3PIN2 (*(volatile BYTE*)(0x3FFFC076))
|
||||
#define FIO4PIN2 (*(volatile BYTE*)(0x3FFFC096))
|
||||
#define FIO0PIN3 (*(volatile BYTE*)(0x3FFFC017))
|
||||
#define FIO1PIN3 (*(volatile BYTE*)(0x3FFFC037))
|
||||
#define FIO2PIN3 (*(volatile BYTE*)(0x3FFFC057))
|
||||
#define FIO3PIN3 (*(volatile BYTE*)(0x3FFFC077))
|
||||
#define FIO4PIN3 (*(volatile BYTE*)(0x3FFFC097))
|
||||
|
||||
#define FIO0PINL (*(volatile WORD*)(0x3FFFC014))
|
||||
#define FIO1PINL (*(volatile WORD*)(0x3FFFC034))
|
||||
#define FIO2PINL (*(volatile WORD*)(0x3FFFC054))
|
||||
#define FIO3PINL (*(volatile WORD*)(0x3FFFC074))
|
||||
#define FIO4PINL (*(volatile WORD*)(0x3FFFC094))
|
||||
#define FIO0PINU (*(volatile WORD*)(0x3FFFC016))
|
||||
#define FIO1PINU (*(volatile WORD*)(0x3FFFC036))
|
||||
#define FIO2PINU (*(volatile WORD*)(0x3FFFC056))
|
||||
#define FIO3PINU (*(volatile WORD*)(0x3FFFC076))
|
||||
#define FIO4PINU (*(volatile WORD*)(0x3FFFC096))
|
||||
|
||||
#define FIO0SET0 (*(volatile BYTE*)(0x3FFFC018))
|
||||
#define FIO1SET0 (*(volatile BYTE*)(0x3FFFC038))
|
||||
#define FIO2SET0 (*(volatile BYTE*)(0x3FFFC058))
|
||||
#define FIO3SET0 (*(volatile BYTE*)(0x3FFFC078))
|
||||
#define FIO4SET0 (*(volatile BYTE*)(0x3FFFC098))
|
||||
#define FIO0SET1 (*(volatile BYTE*)(0x3FFFC019))
|
||||
#define FIO1SET1 (*(volatile BYTE*)(0x3FFFC029))
|
||||
#define FIO2SET1 (*(volatile BYTE*)(0x3FFFC059))
|
||||
#define FIO3SET1 (*(volatile BYTE*)(0x3FFFC079))
|
||||
#define FIO4SET1 (*(volatile BYTE*)(0x3FFFC099))
|
||||
#define FIO0SET2 (*(volatile BYTE*)(0x3FFFC01A))
|
||||
#define FIO1SET2 (*(volatile BYTE*)(0x3FFFC03A))
|
||||
#define FIO2SET2 (*(volatile BYTE*)(0x3FFFC05A))
|
||||
#define FIO3SET2 (*(volatile BYTE*)(0x3FFFC07A))
|
||||
#define FIO4SET2 (*(volatile BYTE*)(0x3FFFC09A))
|
||||
#define FIO0SET3 (*(volatile BYTE*)(0x3FFFC01B))
|
||||
#define FIO1SET3 (*(volatile BYTE*)(0x3FFFC03B))
|
||||
#define FIO2SET3 (*(volatile BYTE*)(0x3FFFC05B))
|
||||
#define FIO3SET3 (*(volatile BYTE*)(0x3FFFC07B))
|
||||
#define FIO4SET3 (*(volatile BYTE*)(0x3FFFC09B))
|
||||
|
||||
#define FIO0SETL (*(volatile WORD*)(0x3FFFC018))
|
||||
#define FIO1SETL (*(volatile WORD*)(0x3FFFC038))
|
||||
#define FIO2SETL (*(volatile WORD*)(0x3FFFC058))
|
||||
#define FIO3SETL (*(volatile WORD*)(0x3FFFC078))
|
||||
#define FIO4SETL (*(volatile WORD*)(0x3FFFC098))
|
||||
#define FIO0SETU (*(volatile WORD*)(0x3FFFC01A))
|
||||
#define FIO1SETU (*(volatile WORD*)(0x3FFFC03A))
|
||||
#define FIO2SETU (*(volatile WORD*)(0x3FFFC05A))
|
||||
#define FIO3SETU (*(volatile WORD*)(0x3FFFC07A))
|
||||
#define FIO4SETU (*(volatile WORD*)(0x3FFFC09A))
|
||||
|
||||
#define FIO0CLR0 (*(volatile BYTE*)(0x3FFFC01C))
|
||||
#define FIO1CLR0 (*(volatile BYTE*)(0x3FFFC03C))
|
||||
#define FIO2CLR0 (*(volatile BYTE*)(0x3FFFC05C))
|
||||
#define FIO3CLR0 (*(volatile BYTE*)(0x3FFFC07C))
|
||||
#define FIO4CLR0 (*(volatile BYTE*)(0x3FFFC09C))
|
||||
#define FIO0CLR1 (*(volatile BYTE*)(0x3FFFC01D))
|
||||
#define FIO1CLR1 (*(volatile BYTE*)(0x3FFFC02D))
|
||||
#define FIO2CLR1 (*(volatile BYTE*)(0x3FFFC05D))
|
||||
#define FIO3CLR1 (*(volatile BYTE*)(0x3FFFC07D))
|
||||
#define FIO4CLR1 (*(volatile BYTE*)(0x3FFFC09D))
|
||||
#define FIO0CLR2 (*(volatile BYTE*)(0x3FFFC01E))
|
||||
#define FIO1CLR2 (*(volatile BYTE*)(0x3FFFC03E))
|
||||
#define FIO2CLR2 (*(volatile BYTE*)(0x3FFFC05E))
|
||||
#define FIO3CLR2 (*(volatile BYTE*)(0x3FFFC07E))
|
||||
#define FIO4CLR2 (*(volatile BYTE*)(0x3FFFC09E))
|
||||
#define FIO0CLR3 (*(volatile BYTE*)(0x3FFFC01F))
|
||||
#define FIO1CLR3 (*(volatile BYTE*)(0x3FFFC03F))
|
||||
#define FIO2CLR3 (*(volatile BYTE*)(0x3FFFC05F))
|
||||
#define FIO3CLR3 (*(volatile BYTE*)(0x3FFFC07F))
|
||||
#define FIO4CLR3 (*(volatile BYTE*)(0x3FFFC09F))
|
||||
|
||||
#define FIO0CLRL (*(volatile WORD*)(0x3FFFC01C))
|
||||
#define FIO1CLRL (*(volatile WORD*)(0x3FFFC03C))
|
||||
#define FIO2CLRL (*(volatile WORD*)(0x3FFFC05C))
|
||||
#define FIO3CLRL (*(volatile WORD*)(0x3FFFC07C))
|
||||
#define FIO4CLRL (*(volatile WORD*)(0x3FFFC09C))
|
||||
#define FIO0CLRU (*(volatile WORD*)(0x3FFFC01E))
|
||||
#define FIO1CLRU (*(volatile WORD*)(0x3FFFC03E))
|
||||
#define FIO2CLRU (*(volatile WORD*)(0x3FFFC05E))
|
||||
#define FIO3CLRU (*(volatile WORD*)(0x3FFFC07E))
|
||||
#define FIO4CLRU (*(volatile WORD*)(0x3FFFC09E))
|
||||
|
||||
#define MAMCR (*(volatile DWORD*)(0xE01FC000))
|
||||
#define MAMTIM (*(volatile DWORD*)(0xE01FC004))
|
||||
#define MEMMAP (*(volatile DWORD*)(0xE01FC040))
|
||||
|
||||
#define PLLCON (*(volatile DWORD*)(0xE01FC080))
|
||||
#define PLLCFG (*(volatile DWORD*)(0xE01FC084))
|
||||
#define PLLSTAT (*(volatile DWORD*)(0xE01FC088))
|
||||
#define PLLFEED (*(volatile DWORD*)(0xE01FC08C))
|
||||
|
||||
#define PCON (*(volatile DWORD*)(0xE01FC0C0))
|
||||
#define PCONP (*(volatile DWORD*)(0xE01FC0C4))
|
||||
|
||||
#define CCLKCFG (*(volatile DWORD*)(0xE01FC104))
|
||||
#define USBCLKCFG (*(volatile DWORD*)(0xE01FC108))
|
||||
#define CLKSRCSEL (*(volatile DWORD*)(0xE01FC10C))
|
||||
#define PCLKSEL0 (*(volatile DWORD*)(0xE01FC1A8))
|
||||
#define PCLKSEL1 (*(volatile DWORD*)(0xE01FC1AC))
|
||||
|
||||
#define EXTINT (*(volatile DWORD*)(0xE01FC140))
|
||||
#define INTWAKE (*(volatile DWORD*)(0xE01FC144))
|
||||
#define EXTMODE (*(volatile DWORD*)(0xE01FC148))
|
||||
#define EXTPOLAR (*(volatile DWORD*)(0xE01FC14C))
|
||||
|
||||
#define RSIR (*(volatile DWORD*)(0xE01FC180))
|
||||
|
||||
#define CSPR (*(volatile DWORD*)(0xE01FC184))
|
||||
|
||||
#define AHBCFG1 (*(volatile DWORD*)(0xE01FC188))
|
||||
#define AHBCFG2 (*(volatile DWORD*)(0xE01FC18C))
|
||||
|
||||
#define SCS (*(volatile DWORD*)(0xE01FC1A0))
|
||||
|
||||
#define EMC_CTRL (*(volatile DWORD*)(0xFFE08000))
|
||||
#define EMC_STAT (*(volatile DWORD*)(0xFFE08004))
|
||||
#define EMC_CONFIG (*(volatile DWORD*)(0xFFE08008))
|
||||
|
||||
#define EMC_DYN_CTRL (*(volatile DWORD*)(0xFFE08020))
|
||||
#define EMC_DYN_RFSH (*(volatile DWORD*)(0xFFE08024))
|
||||
#define EMC_DYN_RD_CFG (*(volatile DWORD*)(0xFFE08028))
|
||||
#define EMC_DYN_RP (*(volatile DWORD*)(0xFFE08030))
|
||||
#define EMC_DYN_RAS (*(volatile DWORD*)(0xFFE08034))
|
||||
#define EMC_DYN_SREX (*(volatile DWORD*)(0xFFE08038))
|
||||
#define EMC_DYN_APR (*(volatile DWORD*)(0xFFE0803C))
|
||||
#define EMC_DYN_DAL (*(volatile DWORD*)(0xFFE08040))
|
||||
#define EMC_DYN_WR (*(volatile DWORD*)(0xFFE08044))
|
||||
#define EMC_DYN_RC (*(volatile DWORD*)(0xFFE08048))
|
||||
#define EMC_DYN_RFC (*(volatile DWORD*)(0xFFE0804C))
|
||||
#define EMC_DYN_XSR (*(volatile DWORD*)(0xFFE08050))
|
||||
#define EMC_DYN_RRD (*(volatile DWORD*)(0xFFE08054))
|
||||
#define EMC_DYN_MRD (*(volatile DWORD*)(0xFFE08058))
|
||||
|
||||
#define EMC_DYN_CFG0 (*(volatile DWORD*)(0xFFE08100))
|
||||
#define EMC_DYN_RASCAS0 (*(volatile DWORD*)(0xFFE08104))
|
||||
#define EMC_DYN_CFG1 (*(volatile DWORD*)(0xFFE08140))
|
||||
#define EMC_DYN_RASCAS1 (*(volatile DWORD*)(0xFFE08144))
|
||||
#define EMC_DYN_CFG2 (*(volatile DWORD*)(0xFFE08160))
|
||||
#define EMC_DYN_RASCAS2 (*(volatile DWORD*)(0xFFE08164))
|
||||
#define EMC_DYN_CFG3 (*(volatile DWORD*)(0xFFE08180))
|
||||
#define EMC_DYN_RASCAS3 (*(volatile DWORD*)(0xFFE08184))
|
||||
|
||||
#define EMC_STA_CFG0 (*(volatile DWORD*)(0xFFE08200))
|
||||
#define EMC_STA_WAITWEN0 (*(volatile DWORD*)(0xFFE08204))
|
||||
#define EMC_STA_WAITOEN0 (*(volatile DWORD*)(0xFFE08208))
|
||||
#define EMC_STA_WAITRD0 (*(volatile DWORD*)(0xFFE0820C))
|
||||
#define EMC_STA_WAITPAGE0 (*(volatile DWORD*)(0xFFE08210))
|
||||
#define EMC_STA_WAITWR0 (*(volatile DWORD*)(0xFFE08214))
|
||||
#define EMC_STA_WAITTURN0 (*(volatile DWORD*)(0xFFE08218))
|
||||
|
||||
#define EMC_STA_CFG1 (*(volatile DWORD*)(0xFFE08220))
|
||||
#define EMC_STA_WAITWEN1 (*(volatile DWORD*)(0xFFE08224))
|
||||
#define EMC_STA_WAITOEN1 (*(volatile DWORD*)(0xFFE08228))
|
||||
#define EMC_STA_WAITRD1 (*(volatile DWORD*)(0xFFE0822C))
|
||||
#define EMC_STA_WAITPAGE1 (*(volatile DWORD*)(0xFFE08230))
|
||||
#define EMC_STA_WAITWR1 (*(volatile DWORD*)(0xFFE08234))
|
||||
#define EMC_STA_WAITTURN1 (*(volatile DWORD*)(0xFFE08238))
|
||||
|
||||
#define EMC_STA_CFG2 (*(volatile DWORD*)(0xFFE08240))
|
||||
#define EMC_STA_WAITWEN2 (*(volatile DWORD*)(0xFFE08244))
|
||||
#define EMC_STA_WAITOEN2 (*(volatile DWORD*)(0xFFE08248))
|
||||
#define EMC_STA_WAITRD2 (*(volatile DWORD*)(0xFFE0824C))
|
||||
#define EMC_STA_WAITPAGE2 (*(volatile DWORD*)(0xFFE08250))
|
||||
#define EMC_STA_WAITWR2 (*(volatile DWORD*)(0xFFE08254))
|
||||
#define EMC_STA_WAITTURN2 (*(volatile DWORD*)(0xFFE08258))
|
||||
|
||||
#define EMC_STA_CFG3 (*(volatile DWORD*)(0xFFE08260))
|
||||
#define EMC_STA_WAITWEN3 (*(volatile DWORD*)(0xFFE08264))
|
||||
#define EMC_STA_WAITOEN3 (*(volatile DWORD*)(0xFFE08268))
|
||||
#define EMC_STA_WAITRD3 (*(volatile DWORD*)(0xFFE0826C))
|
||||
#define EMC_STA_WAITPAGE3 (*(volatile DWORD*)(0xFFE08270))
|
||||
#define EMC_STA_WAITWR3 (*(volatile DWORD*)(0xFFE08274))
|
||||
#define EMC_STA_WAITTURN3 (*(volatile DWORD*)(0xFFE08278))
|
||||
|
||||
#define EMC_STA_EXT_WAIT (*(volatile DWORD*)(0xFFE08880))
|
||||
|
||||
#define T0IR (*(volatile DWORD*)(0xE0004000))
|
||||
#define T0TCR (*(volatile DWORD*)(0xE0004004))
|
||||
#define T0TC (*(volatile DWORD*)(0xE0004008))
|
||||
#define T0PR (*(volatile DWORD*)(0xE000400C))
|
||||
#define T0PC (*(volatile DWORD*)(0xE0004010))
|
||||
#define T0MCR (*(volatile DWORD*)(0xE0004014))
|
||||
#define T0MR0 (*(volatile DWORD*)(0xE0004018))
|
||||
#define T0MR1 (*(volatile DWORD*)(0xE000401C))
|
||||
#define T0MR2 (*(volatile DWORD*)(0xE0004020))
|
||||
#define T0MR3 (*(volatile DWORD*)(0xE0004024))
|
||||
#define T0CCR (*(volatile DWORD*)(0xE0004028))
|
||||
#define T0CR0 (*(volatile DWORD*)(0xE000402C))
|
||||
#define T0CR1 (*(volatile DWORD*)(0xE0004030))
|
||||
#define T0CR2 (*(volatile DWORD*)(0xE0004034))
|
||||
#define T0CR3 (*(volatile DWORD*)(0xE0004038))
|
||||
#define T0EMR (*(volatile DWORD*)(0xE000403C))
|
||||
#define T0CTCR (*(volatile DWORD*)(0xE0004070))
|
||||
|
||||
#define T1IR (*(volatile DWORD*)(0xE0008000))
|
||||
#define T1TCR (*(volatile DWORD*)(0xE0008004))
|
||||
#define T1TC (*(volatile DWORD*)(0xE0008008))
|
||||
#define T1PR (*(volatile DWORD*)(0xE000800C))
|
||||
#define T1PC (*(volatile DWORD*)(0xE0008010))
|
||||
#define T1MCR (*(volatile DWORD*)(0xE0008014))
|
||||
#define T1MR0 (*(volatile DWORD*)(0xE0008018))
|
||||
#define T1MR1 (*(volatile DWORD*)(0xE000801C))
|
||||
#define T1MR2 (*(volatile DWORD*)(0xE0008020))
|
||||
#define T1MR3 (*(volatile DWORD*)(0xE0008024))
|
||||
#define T1CCR (*(volatile DWORD*)(0xE0008028))
|
||||
#define T1CR0 (*(volatile DWORD*)(0xE000802C))
|
||||
#define T1CR1 (*(volatile DWORD*)(0xE0008030))
|
||||
#define T1CR2 (*(volatile DWORD*)(0xE0008034))
|
||||
#define T1CR3 (*(volatile DWORD*)(0xE0008038))
|
||||
#define T1EMR (*(volatile DWORD*)(0xE000803C))
|
||||
#define T1CTCR (*(volatile DWORD*)(0xE0008070))
|
||||
|
||||
#define T2IR (*(volatile DWORD*)(0xE0070000))
|
||||
#define T2TCR (*(volatile DWORD*)(0xE0070004))
|
||||
#define T2TC (*(volatile DWORD*)(0xE0070008))
|
||||
#define T2PR (*(volatile DWORD*)(0xE007000C))
|
||||
#define T2PC (*(volatile DWORD*)(0xE0070010))
|
||||
#define T2MCR (*(volatile DWORD*)(0xE0070014))
|
||||
#define T2MR0 (*(volatile DWORD*)(0xE0070018))
|
||||
#define T2MR1 (*(volatile DWORD*)(0xE007001C))
|
||||
#define T2MR2 (*(volatile DWORD*)(0xE0070020))
|
||||
#define T2MR3 (*(volatile DWORD*)(0xE0070024))
|
||||
#define T2CCR (*(volatile DWORD*)(0xE0070028))
|
||||
#define T2CR0 (*(volatile DWORD*)(0xE007002C))
|
||||
#define T2CR1 (*(volatile DWORD*)(0xE0070030))
|
||||
#define T2CR2 (*(volatile DWORD*)(0xE0070034))
|
||||
#define T2CR3 (*(volatile DWORD*)(0xE0070038))
|
||||
#define T2EMR (*(volatile DWORD*)(0xE007003C))
|
||||
#define T2CTCR (*(volatile DWORD*)(0xE0070070))
|
||||
|
||||
#define T3IR (*(volatile DWORD*)(0xE0074000))
|
||||
#define T3TCR (*(volatile DWORD*)(0xE0074004))
|
||||
#define T3TC (*(volatile DWORD*)(0xE0074008))
|
||||
#define T3PR (*(volatile DWORD*)(0xE007400C))
|
||||
#define T3PC (*(volatile DWORD*)(0xE0074010))
|
||||
#define T3MCR (*(volatile DWORD*)(0xE0074014))
|
||||
#define T3MR0 (*(volatile DWORD*)(0xE0074018))
|
||||
#define T3MR1 (*(volatile DWORD*)(0xE007401C))
|
||||
#define T3MR2 (*(volatile DWORD*)(0xE0074020))
|
||||
#define T3MR3 (*(volatile DWORD*)(0xE0074024))
|
||||
#define T3CCR (*(volatile DWORD*)(0xE0074028))
|
||||
#define T3CR0 (*(volatile DWORD*)(0xE007402C))
|
||||
#define T3CR1 (*(volatile DWORD*)(0xE0074030))
|
||||
#define T3CR2 (*(volatile DWORD*)(0xE0074034))
|
||||
#define T3CR3 (*(volatile DWORD*)(0xE0074038))
|
||||
#define T3EMR (*(volatile DWORD*)(0xE007403C))
|
||||
#define T3CTCR (*(volatile DWORD*)(0xE0074070))
|
||||
|
||||
#define PWM0IR (*(volatile DWORD*)(0xE0014000))
|
||||
#define PWM0TCR (*(volatile DWORD*)(0xE0014004))
|
||||
#define PWM0TC (*(volatile DWORD*)(0xE0014008))
|
||||
#define PWM0PR (*(volatile DWORD*)(0xE001400C))
|
||||
#define PWM0PC (*(volatile DWORD*)(0xE0014010))
|
||||
#define PWM0MCR (*(volatile DWORD*)(0xE0014014))
|
||||
#define PWM0MR0 (*(volatile DWORD*)(0xE0014018))
|
||||
#define PWM0MR1 (*(volatile DWORD*)(0xE001401C))
|
||||
#define PWM0MR2 (*(volatile DWORD*)(0xE0014020))
|
||||
#define PWM0MR3 (*(volatile DWORD*)(0xE0014024))
|
||||
#define PWM0CCR (*(volatile DWORD*)(0xE0014028))
|
||||
#define PWM0CR0 (*(volatile DWORD*)(0xE001402C))
|
||||
#define PWM0CR1 (*(volatile DWORD*)(0xE0014030))
|
||||
#define PWM0CR2 (*(volatile DWORD*)(0xE0014034))
|
||||
#define PWM0CR3 (*(volatile DWORD*)(0xE0014038))
|
||||
#define PWM0EMR (*(volatile DWORD*)(0xE001403C))
|
||||
#define PWM0MR4 (*(volatile DWORD*)(0xE0014040))
|
||||
#define PWM0MR5 (*(volatile DWORD*)(0xE0014044))
|
||||
#define PWM0MR6 (*(volatile DWORD*)(0xE0014048))
|
||||
#define PWM0PCR (*(volatile DWORD*)(0xE001404C))
|
||||
#define PWM0LER (*(volatile DWORD*)(0xE0014050))
|
||||
#define PWM0CTCR (*(volatile DWORD*)(0xE0014070))
|
||||
|
||||
#define PWM1IR (*(volatile DWORD*)(0xE0018000))
|
||||
#define PWM1TCR (*(volatile DWORD*)(0xE0018004))
|
||||
#define PWM1TC (*(volatile DWORD*)(0xE0018008))
|
||||
#define PWM1PR (*(volatile DWORD*)(0xE001800C))
|
||||
#define PWM1PC (*(volatile DWORD*)(0xE0018010))
|
||||
#define PWM1MCR (*(volatile DWORD*)(0xE0018014))
|
||||
#define PWM1MR0 (*(volatile DWORD*)(0xE0018018))
|
||||
#define PWM1MR1 (*(volatile DWORD*)(0xE001801C))
|
||||
#define PWM1MR2 (*(volatile DWORD*)(0xE0018020))
|
||||
#define PWM1MR3 (*(volatile DWORD*)(0xE0018024))
|
||||
#define PWM1CCR (*(volatile DWORD*)(0xE0018028))
|
||||
#define PWM1CR0 (*(volatile DWORD*)(0xE001802C))
|
||||
#define PWM1CR1 (*(volatile DWORD*)(0xE0018030))
|
||||
#define PWM1CR2 (*(volatile DWORD*)(0xE0018034))
|
||||
#define PWM1CR3 (*(volatile DWORD*)(0xE0018038))
|
||||
#define PWM1EMR (*(volatile DWORD*)(0xE001803C))
|
||||
#define PWM1MR4 (*(volatile DWORD*)(0xE0018040))
|
||||
#define PWM1MR5 (*(volatile DWORD*)(0xE0018044))
|
||||
#define PWM1MR6 (*(volatile DWORD*)(0xE0018048))
|
||||
#define PWM1PCR (*(volatile DWORD*)(0xE001804C))
|
||||
#define PWM1LER (*(volatile DWORD*)(0xE0018050))
|
||||
#define PWM1CTCR (*(volatile DWORD*)(0xE0018070))
|
||||
|
||||
#define U0RBR (*(volatile DWORD*)(0xE000C000))
|
||||
#define U0THR (*(volatile DWORD*)(0xE000C000))
|
||||
#define U0DLL (*(volatile DWORD*)(0xE000C000))
|
||||
#define U0DLM (*(volatile DWORD*)(0xE000C004))
|
||||
#define U0IER (*(volatile DWORD*)(0xE000C004))
|
||||
#define U0IIR (*(volatile DWORD*)(0xE000C008))
|
||||
#define U0FCR (*(volatile DWORD*)(0xE000C008))
|
||||
#define U0LCR (*(volatile DWORD*)(0xE000C00C))
|
||||
#define U0LSR (*(volatile DWORD*)(0xE000C014))
|
||||
#define U0SCR (*(volatile DWORD*)(0xE000C01C))
|
||||
#define U0ACR (*(volatile DWORD*)(0xE000C020))
|
||||
#define U0ICR (*(volatile DWORD*)(0xE000C024))
|
||||
#define U0FDR (*(volatile DWORD*)(0xE000C028))
|
||||
#define U0TER (*(volatile DWORD*)(0xE000C030))
|
||||
|
||||
#define U1RBR (*(volatile DWORD*)(0xE0010000))
|
||||
#define U1THR (*(volatile DWORD*)(0xE0010000))
|
||||
#define U1DLL (*(volatile DWORD*)(0xE0010000))
|
||||
#define U1DLM (*(volatile DWORD*)(0xE0010004))
|
||||
#define U1IER (*(volatile DWORD*)(0xE0010004))
|
||||
#define U1IIR (*(volatile DWORD*)(0xE0010008))
|
||||
#define U1FCR (*(volatile DWORD*)(0xE0010008))
|
||||
#define U1LCR (*(volatile DWORD*)(0xE001000C))
|
||||
#define U1MCR (*(volatile DWORD*)(0xE0010010))
|
||||
#define U1LSR (*(volatile DWORD*)(0xE0010014))
|
||||
#define U1MSR (*(volatile DWORD*)(0xE0010018))
|
||||
#define U1SCR (*(volatile DWORD*)(0xE001001C))
|
||||
#define U1ACR (*(volatile DWORD*)(0xE0010020))
|
||||
#define U1FDR (*(volatile DWORD*)(0xE0010028))
|
||||
#define U1TER (*(volatile DWORD*)(0xE0010030))
|
||||
|
||||
#define U2RBR (*(volatile DWORD*)(0xE0078000))
|
||||
#define U2THR (*(volatile DWORD*)(0xE0078000))
|
||||
#define U2DLL (*(volatile DWORD*)(0xE0078000))
|
||||
#define U2DLM (*(volatile DWORD*)(0xE0078004))
|
||||
#define U2IER (*(volatile DWORD*)(0xE0078004))
|
||||
#define U2IIR (*(volatile DWORD*)(0xE0078008))
|
||||
#define U2FCR (*(volatile DWORD*)(0xE0078008))
|
||||
#define U2LCR (*(volatile DWORD*)(0xE007800C))
|
||||
#define U2LSR (*(volatile DWORD*)(0xE0078014))
|
||||
#define U2SCR (*(volatile DWORD*)(0xE007801C))
|
||||
#define U2ACR (*(volatile DWORD*)(0xE0078020))
|
||||
#define U2ICR (*(volatile DWORD*)(0xE0078024))
|
||||
#define U2FDR (*(volatile DWORD*)(0xE0078028))
|
||||
#define U2TER (*(volatile DWORD*)(0xE0078030))
|
||||
|
||||
#define U3RBR (*(volatile DWORD*)(0xE007C000))
|
||||
#define U3THR (*(volatile DWORD*)(0xE007C000))
|
||||
#define U3DLL (*(volatile DWORD*)(0xE007C000))
|
||||
#define U3DLM (*(volatile DWORD*)(0xE007C004))
|
||||
#define U3IER (*(volatile DWORD*)(0xE007C004))
|
||||
#define U3IIR (*(volatile DWORD*)(0xE007C008))
|
||||
#define U3FCR (*(volatile DWORD*)(0xE007C008))
|
||||
#define U3LCR (*(volatile DWORD*)(0xE007C00C))
|
||||
#define U3LSR (*(volatile DWORD*)(0xE007C014))
|
||||
#define U3SCR (*(volatile DWORD*)(0xE007C01C))
|
||||
#define U3ACR (*(volatile DWORD*)(0xE007C020))
|
||||
#define U3ICR (*(volatile DWORD*)(0xE007C024))
|
||||
#define U3FDR (*(volatile DWORD*)(0xE007C028))
|
||||
#define U3TER (*(volatile DWORD*)(0xE007C030))
|
||||
|
||||
#define I20CONSET (*(volatile DWORD*)(0xE001C000))
|
||||
#define I20STAT (*(volatile DWORD*)(0xE001C004))
|
||||
#define I20DAT (*(volatile DWORD*)(0xE001C008))
|
||||
#define I20ADR (*(volatile DWORD*)(0xE001C00C))
|
||||
#define I20SCLH (*(volatile DWORD*)(0xE001C010))
|
||||
#define I20SCLL (*(volatile DWORD*)(0xE001C014))
|
||||
#define I20CONCLR (*(volatile DWORD*)(0xE001C018))
|
||||
|
||||
#define I21CONSET (*(volatile DWORD*)(0xE005C000))
|
||||
#define I21STAT (*(volatile DWORD*)(0xE005C004))
|
||||
#define I21DAT (*(volatile DWORD*)(0xE005C008))
|
||||
#define I21ADR (*(volatile DWORD*)(0xE005C00C))
|
||||
#define I21SCLH (*(volatile DWORD*)(0xE005C010))
|
||||
#define I21SCLL (*(volatile DWORD*)(0xE005C014))
|
||||
#define I21CONCLR (*(volatile DWORD*)(0xE005C018))
|
||||
|
||||
#define I22CONSET (*(volatile DWORD*)(0xE0080000))
|
||||
#define I22STAT (*(volatile DWORD*)(0xE0080004))
|
||||
#define I22DAT (*(volatile DWORD*)(0xE0080008))
|
||||
#define I22ADR (*(volatile DWORD*)(0xE008000C))
|
||||
#define I22SCLH (*(volatile DWORD*)(0xE0080010))
|
||||
#define I22SCLL (*(volatile DWORD*)(0xE0080014))
|
||||
#define I22CONCLR (*(volatile DWORD*)(0xE0080018))
|
||||
|
||||
#define S0SPCR (*(volatile DWORD*)(0xE0020000))
|
||||
#define S0SPSR (*(volatile DWORD*)(0xE0020004))
|
||||
#define S0SPDR (*(volatile DWORD*)(0xE0020008))
|
||||
#define S0SPCCR (*(volatile DWORD*)(0xE002000C))
|
||||
#define S0SPINT (*(volatile DWORD*)(0xE002001C))
|
||||
|
||||
#define SSP0CR0 (*(volatile DWORD*)(0xE0068000))
|
||||
#define SSP0CR1 (*(volatile DWORD*)(0xE0068004))
|
||||
#define SSP0DR (*(volatile DWORD*)(0xE0068008))
|
||||
#define SSP0SR (*(volatile DWORD*)(0xE006800C))
|
||||
#define SSP0CPSR (*(volatile DWORD*)(0xE0068010))
|
||||
#define SSP0IMSC (*(volatile DWORD*)(0xE0068014))
|
||||
#define SSP0RIS (*(volatile DWORD*)(0xE0068018))
|
||||
#define SSP0MIS (*(volatile DWORD*)(0xE006801C))
|
||||
#define SSP0ICR (*(volatile DWORD*)(0xE0068020))
|
||||
#define SSP0DMACR (*(volatile DWORD*)(0xE0068024))
|
||||
|
||||
#define SSP1CR0 (*(volatile DWORD*)(0xE0030000))
|
||||
#define SSP1CR1 (*(volatile DWORD*)(0xE0030004))
|
||||
#define SSP1DR (*(volatile DWORD*)(0xE0030008))
|
||||
#define SSP1SR (*(volatile DWORD*)(0xE003000C))
|
||||
#define SSP1CPSR (*(volatile DWORD*)(0xE0030010))
|
||||
#define SSP1IMSC (*(volatile DWORD*)(0xE0030014))
|
||||
#define SSP1RIS (*(volatile DWORD*)(0xE0030018))
|
||||
#define SSP1MIS (*(volatile DWORD*)(0xE003001C))
|
||||
#define SSP1ICR (*(volatile DWORD*)(0xE0030020))
|
||||
#define SSP1DMACR (*(volatile DWORD*)(0xE0030024))
|
||||
|
||||
#define RTC_ILR (*(volatile DWORD*)(0xE0024000))
|
||||
#define RTC_CTC (*(volatile DWORD*)(0xE0024004))
|
||||
#define RTC_CCR (*(volatile DWORD*)(0xE0024008))
|
||||
#define RTC_CIIR (*(volatile DWORD*)(0xE002400C))
|
||||
#define RTC_AMR (*(volatile DWORD*)(0xE0024010))
|
||||
#define RTC_CTIME0 (*(volatile DWORD*)(0xE0024014))
|
||||
#define RTC_CTIME1 (*(volatile DWORD*)(0xE0024018))
|
||||
#define RTC_CTIME2 (*(volatile DWORD*)(0xE002401C))
|
||||
#define RTC_SEC (*(volatile DWORD*)(0xE0024020))
|
||||
#define RTC_MIN (*(volatile DWORD*)(0xE0024024))
|
||||
#define RTC_HOUR (*(volatile DWORD*)(0xE0024028))
|
||||
#define RTC_DOM (*(volatile DWORD*)(0xE002402C))
|
||||
#define RTC_DOW (*(volatile DWORD*)(0xE0024030))
|
||||
#define RTC_DOY (*(volatile DWORD*)(0xE0024034))
|
||||
#define RTC_MONTH (*(volatile DWORD*)(0xE0024038))
|
||||
#define RTC_YEAR (*(volatile DWORD*)(0xE002403C))
|
||||
#define RTC_CISS (*(volatile DWORD*)(0xE0024040))
|
||||
#define RTC_ALSEC (*(volatile DWORD*)(0xE0024060))
|
||||
#define RTC_ALMIN (*(volatile DWORD*)(0xE0024064))
|
||||
#define RTC_ALHOUR (*(volatile DWORD*)(0xE0024068))
|
||||
#define RTC_ALDOM (*(volatile DWORD*)(0xE002406C))
|
||||
#define RTC_ALDOW (*(volatile DWORD*)(0xE0024070))
|
||||
#define RTC_ALDOY (*(volatile DWORD*)(0xE0024074))
|
||||
#define RTC_ALMON (*(volatile DWORD*)(0xE0024078))
|
||||
#define RTC_ALYEAR (*(volatile DWORD*)(0xE002407C))
|
||||
#define RTC_PREINT (*(volatile DWORD*)(0xE0024080))
|
||||
#define RTC_PREFRAC (*(volatile DWORD*)(0xE0024084))
|
||||
|
||||
#define AD0CR (*(volatile DWORD*)(0xE0034000))
|
||||
#define AD0GDR (*(volatile DWORD*)(0xE0034004))
|
||||
#define AD0INTEN (*(volatile DWORD*)(0xE003400C))
|
||||
#define AD0DR0 (*(volatile DWORD*)(0xE0034010))
|
||||
#define AD0DR1 (*(volatile DWORD*)(0xE0034014))
|
||||
#define AD0DR2 (*(volatile DWORD*)(0xE0034018))
|
||||
#define AD0DR3 (*(volatile DWORD*)(0xE003401C))
|
||||
#define AD0DR4 (*(volatile DWORD*)(0xE0034020))
|
||||
#define AD0DR5 (*(volatile DWORD*)(0xE0034024))
|
||||
#define AD0DR6 (*(volatile DWORD*)(0xE0034028))
|
||||
#define AD0DR7 (*(volatile DWORD*)(0xE003402C))
|
||||
#define AD0STAT (*(volatile DWORD*)(0xE0034030))
|
||||
|
||||
#define DACR (*(volatile DWORD*)(0xE006C000))
|
||||
|
||||
#define WDMOD (*(volatile DWORD*)(0xE0000000))
|
||||
#define WDTC (*(volatile DWORD*)(0xE0000004))
|
||||
#define WDFEED (*(volatile DWORD*)(0xE0000008))
|
||||
#define WDTV (*(volatile DWORD*)(0xE000000C))
|
||||
#define WDCLKSEL (*(volatile DWORD*)(0xE0000010))
|
||||
|
||||
#define CAN_AFMR (*(volatile DWORD*)(0xE003C000))
|
||||
#define CAN_SFF_SA (*(volatile DWORD*)(0xE003C004))
|
||||
#define CAN_SFF_GRP_SA (*(volatile DWORD*)(0xE003C008))
|
||||
#define CAN_EFF_SA (*(volatile DWORD*)(0xE003C00C))
|
||||
#define CAN_EFF_GRP_SA (*(volatile DWORD*)(0xE003C010))
|
||||
#define CAN_EOT (*(volatile DWORD*)(0xE003C014))
|
||||
#define CAN_LUT_ERR_ADR (*(volatile DWORD*)(0xE003C018))
|
||||
#define CAN_LUT_ERR (*(volatile DWORD*)(0xE003C01C))
|
||||
|
||||
#define CAN_TX_SR (*(volatile DWORD*)(0xE0040000))
|
||||
#define CAN_RX_SR (*(volatile DWORD*)(0xE0040004))
|
||||
#define CAN_MSR (*(volatile DWORD*)(0xE0040008))
|
||||
|
||||
#define CAN1MOD (*(volatile DWORD*)(0xE0044000))
|
||||
#define CAN1CMR (*(volatile DWORD*)(0xE0044004))
|
||||
#define CAN1GSR (*(volatile DWORD*)(0xE0044008))
|
||||
#define CAN1ICR (*(volatile DWORD*)(0xE004400C))
|
||||
#define CAN1IER (*(volatile DWORD*)(0xE0044010))
|
||||
#define CAN1BTR (*(volatile DWORD*)(0xE0044014))
|
||||
#define CAN1EWL (*(volatile DWORD*)(0xE0044018))
|
||||
#define CAN1SR (*(volatile DWORD*)(0xE004401C))
|
||||
#define CAN1RFS (*(volatile DWORD*)(0xE0044020))
|
||||
#define CAN1RID (*(volatile DWORD*)(0xE0044024))
|
||||
#define CAN1RDA (*(volatile DWORD*)(0xE0044028))
|
||||
#define CAN1RDB (*(volatile DWORD*)(0xE004402C))
|
||||
|
||||
#define CAN1TFI1 (*(volatile DWORD*)(0xE0044030))
|
||||
#define CAN1TID1 (*(volatile DWORD*)(0xE0044034))
|
||||
#define CAN1TDA1 (*(volatile DWORD*)(0xE0044038))
|
||||
#define CAN1TDB1 (*(volatile DWORD*)(0xE004403C))
|
||||
#define CAN1TFI2 (*(volatile DWORD*)(0xE0044040))
|
||||
#define CAN1TID2 (*(volatile DWORD*)(0xE0044044))
|
||||
#define CAN1TDA2 (*(volatile DWORD*)(0xE0044048))
|
||||
#define CAN1TDB2 (*(volatile DWORD*)(0xE004404C))
|
||||
#define CAN1TFI3 (*(volatile DWORD*)(0xE0044050))
|
||||
#define CAN1TID3 (*(volatile DWORD*)(0xE0044054))
|
||||
#define CAN1TDA3 (*(volatile DWORD*)(0xE0044058))
|
||||
#define CAN1TDB3 (*(volatile DWORD*)(0xE004405C))
|
||||
|
||||
#define CAN2MOD (*(volatile DWORD*)(0xE0048000))
|
||||
#define CAN2CMR (*(volatile DWORD*)(0xE0048004))
|
||||
#define CAN2GSR (*(volatile DWORD*)(0xE0048008))
|
||||
#define CAN2ICR (*(volatile DWORD*)(0xE004800C))
|
||||
#define CAN2IER (*(volatile DWORD*)(0xE0048010))
|
||||
#define CAN2BTR (*(volatile DWORD*)(0xE0048014))
|
||||
#define CAN2EWL (*(volatile DWORD*)(0xE0048018))
|
||||
#define CAN2SR (*(volatile DWORD*)(0xE004801C))
|
||||
#define CAN2RFS (*(volatile DWORD*)(0xE0048020))
|
||||
#define CAN2RID (*(volatile DWORD*)(0xE0048024))
|
||||
#define CAN2RDA (*(volatile DWORD*)(0xE0048028))
|
||||
#define CAN2RDB (*(volatile DWORD*)(0xE004802C))
|
||||
|
||||
#define CAN2TFI1 (*(volatile DWORD*)(0xE0048030))
|
||||
#define CAN2TID1 (*(volatile DWORD*)(0xE0048034))
|
||||
#define CAN2TDA1 (*(volatile DWORD*)(0xE0048038))
|
||||
#define CAN2TDB1 (*(volatile DWORD*)(0xE004803C))
|
||||
#define CAN2TFI2 (*(volatile DWORD*)(0xE0048040))
|
||||
#define CAN2TID2 (*(volatile DWORD*)(0xE0048044))
|
||||
#define CAN2TDA2 (*(volatile DWORD*)(0xE0048048))
|
||||
#define CAN2TDB2 (*(volatile DWORD*)(0xE004804C))
|
||||
#define CAN2TFI3 (*(volatile DWORD*)(0xE0048050))
|
||||
#define CAN2TID3 (*(volatile DWORD*)(0xE0048054))
|
||||
#define CAN2TDA3 (*(volatile DWORD*)(0xE0048058))
|
||||
#define CAN2TDB3 (*(volatile DWORD*)(0xE004805C))
|
||||
|
||||
#define MCI_POWER (*(volatile DWORD*)(0xE008C000))
|
||||
#define MCI_CLOCK (*(volatile DWORD*)(0xE008C004))
|
||||
#define MCI_ARGUMENT (*(volatile DWORD*)(0xE008C008))
|
||||
#define MCI_COMMAND (*(volatile DWORD*)(0xE008C00C))
|
||||
#define MCI_RESP_CMD (*(volatile DWORD*)(0xE008C010))
|
||||
#define MCI_RESP0 (*(volatile DWORD*)(0xE008C014))
|
||||
#define MCI_RESP1 (*(volatile DWORD*)(0xE008C018))
|
||||
#define MCI_RESP2 (*(volatile DWORD*)(0xE008C01C))
|
||||
#define MCI_RESP3 (*(volatile DWORD*)(0xE008C020))
|
||||
#define MCI_DATA_TMR (*(volatile DWORD*)(0xE008C024))
|
||||
#define MCI_DATA_LEN (*(volatile DWORD*)(0xE008C028))
|
||||
#define MCI_DATA_CTRL (*(volatile DWORD*)(0xE008C02C))
|
||||
#define MCI_DATA_CNT (*(volatile DWORD*)(0xE008C030))
|
||||
#define MCI_STATUS (*(volatile DWORD*)(0xE008C034))
|
||||
#define MCI_CLEAR (*(volatile DWORD*)(0xE008C038))
|
||||
#define MCI_MASK0 (*(volatile DWORD*)(0xE008C03C))
|
||||
#define MCI_MASK1 (*(volatile DWORD*)(0xE008C040))
|
||||
#define MCI_FIFO_CNT (*(volatile DWORD*)(0xE008C048))
|
||||
#define MCI_FIFO (*(volatile DWORD*)(0xE008C080))
|
||||
|
||||
#define I2S_DAO (*(volatile DWORD*)(0xE0088000))
|
||||
#define I2S_DAI (*(volatile DWORD*)(0xE0088004))
|
||||
#define I2S_TX_FIFO (*(volatile DWORD*)(0xE0088008))
|
||||
#define I2S_RX_FIFO (*(volatile DWORD*)(0xE008800C))
|
||||
#define I2S_STATE (*(volatile DWORD*)(0xE0088010))
|
||||
#define I2S_DMA1 (*(volatile DWORD*)(0xE0088014))
|
||||
#define I2S_DMA2 (*(volatile DWORD*)(0xE0088018))
|
||||
#define I2S_IRQ (*(volatile DWORD*)(0xE008801C))
|
||||
#define I2S_TXRATE (*(volatile DWORD*)(0xE0088020))
|
||||
#define I2S_RXRATE (*(volatile DWORD*)(0xE0088024))
|
||||
|
||||
#define GPDMA_INT_STAT (*(volatile DWORD*)(0xFFE04000))
|
||||
#define GPDMA_INT_TCSTAT (*(volatile DWORD*)(0xFFE04004))
|
||||
#define GPDMA_INT_TCCLR (*(volatile DWORD*)(0xFFE04008))
|
||||
#define GPDMA_INT_ERR_STAT (*(volatile DWORD*)(0xFFE0400C))
|
||||
#define GPDMA_INT_ERR_CLR (*(volatile DWORD*)(0xFFE04010))
|
||||
#define GPDMA_RAW_INT_TCSTAT (*(volatile DWORD*)(0xFFE04014))
|
||||
#define GPDMA_RAW_INT_ERR_STAT (*(volatile DWORD*)(0xFFE04018))
|
||||
#define GPDMA_ENABLED_CHNS (*(volatile DWORD*)(0xFFE0401C))
|
||||
#define GPDMA_SOFT_BREQ (*(volatile DWORD*)(0xFFE04020))
|
||||
#define GPDMA_SOFT_SREQ (*(volatile DWORD*)(0xFFE04024))
|
||||
#define GPDMA_SOFT_LBREQ (*(volatile DWORD*)(0xFFE04028))
|
||||
#define GPDMA_SOFT_LSREQ (*(volatile DWORD*)(0xFFE0402C))
|
||||
#define GPDMA_CONFIG (*(volatile DWORD*)(0xFFE04030))
|
||||
#define GPDMA_SYNC (*(volatile DWORD*)(0xFFE04034))
|
||||
|
||||
#define GPDMA_CH0_SRC (*(volatile DWORD*)(0xFFE04100))
|
||||
#define GPDMA_CH0_DEST (*(volatile DWORD*)(0xFFE04104))
|
||||
#define GPDMA_CH0_LLI (*(volatile DWORD*)(0xFFE04108))
|
||||
#define GPDMA_CH0_CTRL (*(volatile DWORD*)(0xFFE0410C))
|
||||
#define GPDMA_CH0_CFG (*(volatile DWORD*)(0xFFE04110))
|
||||
|
||||
#define GPDMA_CH1_SRC (*(volatile DWORD*)(0xFFE04120))
|
||||
#define GPDMA_CH1_DEST (*(volatile DWORD*)(0xFFE04124))
|
||||
#define GPDMA_CH1_LLI (*(volatile DWORD*)(0xFFE04128))
|
||||
#define GPDMA_CH1_CTRL (*(volatile DWORD*)(0xFFE0412C))
|
||||
#define GPDMA_CH1_CFG (*(volatile DWORD*)(0xFFE04130))
|
||||
|
||||
#define USB_INT_STAT (*(volatile DWORD*)(0xE01FC1C0))
|
||||
|
||||
#define DEV_INT_STAT (*(volatile DWORD*)(0xFFE0C200))
|
||||
#define DEV_INT_EN (*(volatile DWORD*)(0xFFE0C204))
|
||||
#define DEV_INT_CLR (*(volatile DWORD*)(0xFFE0C208))
|
||||
#define DEV_INT_SET (*(volatile DWORD*)(0xFFE0C20C))
|
||||
#define DEV_INT_PRIO (*(volatile DWORD*)(0xFFE0C22C))
|
||||
|
||||
#define EP_INT_STAT (*(volatile DWORD*)(0xFFE0C230))
|
||||
#define EP_INT_EN (*(volatile DWORD*)(0xFFE0C234))
|
||||
#define EP_INT_CLR (*(volatile DWORD*)(0xFFE0C238))
|
||||
#define EP_INT_SET (*(volatile DWORD*)(0xFFE0C23C))
|
||||
#define EP_INT_PRIO (*(volatile DWORD*)(0xFFE0C240))
|
||||
|
||||
#define REALIZE_EP (*(volatile DWORD*)(0xFFE0C244))
|
||||
#define EP_INDEX (*(volatile DWORD*)(0xFFE0C248))
|
||||
#define MAXPACKET_SIZE (*(volatile DWORD*)(0xFFE0C24C))
|
||||
|
||||
#define CMD_CODE (*(volatile DWORD*)(0xFFE0C210))
|
||||
#define CMD_DATA (*(volatile DWORD*)(0xFFE0C214))
|
||||
|
||||
#define RX_DATA (*(volatile DWORD*)(0xFFE0C218))
|
||||
#define TX_DATA (*(volatile DWORD*)(0xFFE0C21C))
|
||||
#define RX_PLENGTH (*(volatile DWORD*)(0xFFE0C220))
|
||||
#define TX_PLENGTH (*(volatile DWORD*)(0xFFE0C224))
|
||||
#define USB_CTRL (*(volatile DWORD*)(0xFFE0C228))
|
||||
|
||||
#define DMA_REQ_STAT (*(volatile DWORD*)(0xFFE0C250))
|
||||
#define DMA_REQ_CLR (*(volatile DWORD*)(0xFFE0C254))
|
||||
#define DMA_REQ_SET (*(volatile DWORD*)(0xFFE0C258))
|
||||
#define UDCA_HEAD (*(volatile DWORD*)(0xFFE0C280))
|
||||
#define EP_DMA_STAT (*(volatile DWORD*)(0xFFE0C284))
|
||||
#define EP_DMA_EN (*(volatile DWORD*)(0xFFE0C288))
|
||||
#define EP_DMA_DIS (*(volatile DWORD*)(0xFFE0C28C))
|
||||
#define DMA_INT_STAT (*(volatile DWORD*)(0xFFE0C290))
|
||||
#define DMA_INT_EN (*(volatile DWORD*)(0xFFE0C294))
|
||||
#define EOT_INT_STAT (*(volatile DWORD*)(0xFFE0C2A0))
|
||||
#define EOT_INT_CLR (*(volatile DWORD*)(0xFFE0C2A4))
|
||||
#define EOT_INT_SET (*(volatile DWORD*)(0xFFE0C2A8))
|
||||
#define NDD_REQ_INT_STAT (*(volatile DWORD*)(0xFFE0C2AC))
|
||||
#define NDD_REQ_INT_CLR (*(volatile DWORD*)(0xFFE0C2B0))
|
||||
#define NDD_REQ_INT_SET (*(volatile DWORD*)(0xFFE0C2B4))
|
||||
#define SYS_ERR_INT_STAT (*(volatile DWORD*)(0xFFE0C2B8))
|
||||
#define SYS_ERR_INT_CLR (*(volatile DWORD*)(0xFFE0C2BC))
|
||||
#define SYS_ERR_INT_SET (*(volatile DWORD*)(0xFFE0C2C0))
|
||||
|
||||
#define HC_REVISION (*(volatile DWORD*)(0xFFE0C000))
|
||||
#define HC_CONTROL (*(volatile DWORD*)(0xFFE0C004))
|
||||
#define HC_CMD_STAT (*(volatile DWORD*)(0xFFE0C008))
|
||||
#define HC_INT_STAT (*(volatile DWORD*)(0xFFE0C00C))
|
||||
#define HC_INT_EN (*(volatile DWORD*)(0xFFE0C010))
|
||||
#define HC_INT_DIS (*(volatile DWORD*)(0xFFE0C014))
|
||||
#define HC_HCCA (*(volatile DWORD*)(0xFFE0C018))
|
||||
#define HC_PERIOD_CUR_ED (*(volatile DWORD*)(0xFFE0C01C))
|
||||
#define HC_CTRL_HEAD_ED (*(volatile DWORD*)(0xFFE0C020))
|
||||
#define HC_CTRL_CUR_ED (*(volatile DWORD*)(0xFFE0C024))
|
||||
#define HC_BULK_HEAD_ED (*(volatile DWORD*)(0xFFE0C028))
|
||||
#define HC_BULK_CUR_ED (*(volatile DWORD*)(0xFFE0C02C))
|
||||
#define HC_DONE_HEAD (*(volatile DWORD*)(0xFFE0C030))
|
||||
#define HC_FM_INTERVAL (*(volatile DWORD*)(0xFFE0C034))
|
||||
#define HC_FM_REMAINING (*(volatile DWORD*)(0xFFE0C038))
|
||||
#define HC_FM_NUMBER (*(volatile DWORD*)(0xFFE0C03C))
|
||||
#define HC_PERIOD_START (*(volatile DWORD*)(0xFFE0C040))
|
||||
#define HC_LS_THRHLD (*(volatile DWORD*)(0xFFE0C044))
|
||||
#define HC_RH_DESCA (*(volatile DWORD*)(0xFFE0C048))
|
||||
#define HC_RH_DESCB (*(volatile DWORD*)(0xFFE0C04C))
|
||||
#define HC_RH_STAT (*(volatile DWORD*)(0xFFE0C050))
|
||||
#define HC_RH_PORT_STAT1 (*(volatile DWORD*)(0xFFE0C054))
|
||||
#define HC_RH_PORT_STAT2 (*(volatile DWORD*)(0xFFE0C058))
|
||||
|
||||
#define OTG_INT_STAT (*(volatile DWORD*)(0xFFE0C100))
|
||||
#define OTG_INT_EN (*(volatile DWORD*)(0xFFE0C104))
|
||||
#define OTG_INT_SET (*(volatile DWORD*)(0xFFE0C108))
|
||||
#define OTG_INT_CLR (*(volatile DWORD*)(0xFFE0C10C))
|
||||
#define OTG_STAT_CTRL (*(volatile DWORD*)(0xFFE0C110))
|
||||
#define OTG_TIMER (*(volatile DWORD*)(0xFFE0C114))
|
||||
|
||||
#define OTG_I2C_RX (*(volatile DWORD*)(0xFFE0C300))
|
||||
#define OTG_I2C_TX (*(volatile DWORD*)(0xFFE0C300))
|
||||
#define OTG_I2C_STS (*(volatile DWORD*)(0xFFE0C304))
|
||||
#define OTG_I2C_CTL (*(volatile DWORD*)(0xFFE0C308))
|
||||
#define OTG_I2C_CLKHI (*(volatile DWORD*)(0xFFE0C30C))
|
||||
#define OTG_I2C_CLKLO (*(volatile DWORD*)(0xFFE0C310))
|
||||
|
||||
#define OTG_CLK_CTRL (*(volatile DWORD*)(0xFFE0CFF4))
|
||||
#define OTG_CLK_STAT (*(volatile DWORD*)(0xFFE0CFF8))
|
||||
|
||||
#define USBPortSel (*(volatile DWORD*)(0xFFE0C110))
|
||||
#define USBClkCtrl (*(volatile DWORD*)(0xFFE0CFF4))
|
||||
#define USBClkSt (*(volatile DWORD*)(0xFFE0CFF8))
|
||||
|
||||
#define MAC_MAC1 (*(volatile DWORD*)(0xFFE00000))
|
||||
#define MAC_MAC2 (*(volatile DWORD*)(0xFFE00004))
|
||||
#define MAC_IPGT (*(volatile DWORD*)(0xFFE00008))
|
||||
#define MAC_IPGR (*(volatile DWORD*)(0xFFE0000C))
|
||||
#define MAC_CLRT (*(volatile DWORD*)(0xFFE00010))
|
||||
#define MAC_MAXF (*(volatile DWORD*)(0xFFE00014))
|
||||
#define MAC_SUPP (*(volatile DWORD*)(0xFFE00018))
|
||||
#define MAC_TEST (*(volatile DWORD*)(0xFFE0001C))
|
||||
#define MAC_MCFG (*(volatile DWORD*)(0xFFE00020))
|
||||
#define MAC_MCMD (*(volatile DWORD*)(0xFFE00024))
|
||||
#define MAC_MADR (*(volatile DWORD*)(0xFFE00028))
|
||||
#define MAC_MWTD (*(volatile DWORD*)(0xFFE0002C))
|
||||
#define MAC_MRDD (*(volatile DWORD*)(0xFFE00030))
|
||||
#define MAC_MIND (*(volatile DWORD*)(0xFFE00034))
|
||||
|
||||
#define MAC_SA0 (*(volatile DWORD*)(0xFFE00040))
|
||||
#define MAC_SA1 (*(volatile DWORD*)(0xFFE00044))
|
||||
#define MAC_SA2 (*(volatile DWORD*)(0xFFE00048))
|
||||
|
||||
#define MAC_COMMAND (*(volatile DWORD*)(0xFFE00100))
|
||||
#define MAC_STATUS (*(volatile DWORD*)(0xFFE00104))
|
||||
#define MAC_RXDESCRIPTOR (*(volatile DWORD*)(0xFFE00108))
|
||||
#define MAC_RXSTATUS (*(volatile DWORD*)(0xFFE0010C))
|
||||
#define MAC_RXDESCRIPTORNUM (*(volatile DWORD*)(0xFFE00110))
|
||||
#define MAC_RXPRODUCEINDEX (*(volatile DWORD*)(0xFFE00114))
|
||||
#define MAC_RXCONSUMEINDEX (*(volatile DWORD*)(0xFFE00118))
|
||||
#define MAC_TXDESCRIPTOR (*(volatile DWORD*)(0xFFE0011C))
|
||||
#define MAC_TXSTATUS (*(volatile DWORD*)(0xFFE00120))
|
||||
#define MAC_TXDESCRIPTORNUM (*(volatile DWORD*)(0xFFE00124))
|
||||
#define MAC_TXPRODUCEINDEX (*(volatile DWORD*)(0xFFE00128))
|
||||
#define MAC_TXCONSUMEINDEX (*(volatile DWORD*)(0xFFE0012C))
|
||||
|
||||
#define MAC_TSV0 (*(volatile DWORD*)(0xFFE00158))
|
||||
#define MAC_TSV1 (*(volatile DWORD*)(0xFFE0015C))
|
||||
#define MAC_RSV (*(volatile DWORD*)(0xFFE00160))
|
||||
|
||||
#define MAC_FLOWCONTROLCNT (*(volatile DWORD*)(0xFFE00170))
|
||||
#define MAC_FLOWCONTROLSTS (*(volatile DWORD*)(0xFFE00174))
|
||||
|
||||
#define MAC_RXFILTERCTRL (*(volatile DWORD*)(0xFFE00200))
|
||||
#define MAC_RXFILTERWOLSTS (*(volatile DWORD*)(0xFFE00204))
|
||||
#define MAC_RXFILTERWOLCLR (*(volatile DWORD*)(0xFFE00208))
|
||||
|
||||
#define MAC_HASHFILTERL (*(volatile DWORD*)(0xFFE00210))
|
||||
#define MAC_HASHFILTERH (*(volatile DWORD*)(0xFFE00214))
|
||||
|
||||
#define MAC_INTSTATUS (*(volatile DWORD*)(0xFFE00FE0))
|
||||
#define MAC_INTENABLE (*(volatile DWORD*)(0xFFE00FE4))
|
||||
#define MAC_INTCLEAR (*(volatile DWORD*)(0xFFE00FE8))
|
||||
#define MAC_INTSET (*(volatile DWORD*)(0xFFE00FEC))
|
||||
|
||||
#define MAC_POWERDOWN (*(volatile DWORD*)(0xFFE00FF4))
|
||||
#define MAC_MODULEID (*(volatile DWORD*)(0xFFE00FFC))
|
||||
|
||||
#endif
|
||||
|
||||
136
tools/ffsample/lpc2k/LPC2368-ROM.ld
Normal file
136
tools/ffsample/lpc2k/LPC2368-ROM.ld
Normal file
@@ -0,0 +1,136 @@
|
||||
/* LPC2368 Memory Definitions */
|
||||
MEMORY
|
||||
{
|
||||
ROM (rx) : ORIGIN = 0x00000000, LENGTH = (512k-8k) /* Flash: 512k - boot code */
|
||||
RAM (w) : ORIGIN = 0x40000000, LENGTH = (32k-32) /* SRAM: 32k - IAP work */
|
||||
URAM (w) : ORIGIN = 0x7FD00000, LENGTH = (8k) /* USB RAM: 8k */
|
||||
ERAM (w) : ORIGIN = 0x7FE00000, LENGTH = (16k) /* Ethernet RAM: 16k */
|
||||
BRAM (w) : ORIGIN = 0xE0084000, LENGTH = (2k) /* Battery RAM: 2k */
|
||||
}
|
||||
|
||||
|
||||
/* Section Definitions */
|
||||
SECTIONS
|
||||
{
|
||||
/* The first section which is used for code */
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.VECTOR)) /* Exception vector table */
|
||||
*(.text .text.*) /* Program code */
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata) /* Read-only data (constants) */
|
||||
*(.rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
} > ROM
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = . ;
|
||||
PROVIDE (etext = .);
|
||||
|
||||
/* .data section which has initialized data */
|
||||
/* Located in RAM but linked to ROM at end of .text */
|
||||
/* This section will be initialized with ROM data by startup code */
|
||||
.data : AT (_etext)
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = . ;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
/* .bss section which is initialized by 0 */
|
||||
/* This section will be filled with zero by startup code */
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
__bss_start = . ;
|
||||
__bss_start__ = . ;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = . ;
|
||||
PROVIDE (__bss_end = .);
|
||||
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
*(.STACK)
|
||||
PROVIDE (_stack = .);
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
|
||||
.usbram (NOLOAD) :
|
||||
{
|
||||
__usbram_start = . ;
|
||||
__usbram_start__ = . ;
|
||||
*(.usbram)
|
||||
. = ALIGN(4);
|
||||
} > URAM
|
||||
|
||||
.etherram (NOLOAD) :
|
||||
{
|
||||
__etherram_start = . ;
|
||||
__etherram_start__ = . ;
|
||||
*(.etherram)
|
||||
. = ALIGN(4);
|
||||
} > ERAM
|
||||
|
||||
.batteryram (NOLOAD) :
|
||||
{
|
||||
__batteryram_start = . ;
|
||||
__batteryram_start__ = . ;
|
||||
*(.batteryram)
|
||||
. = ALIGN(4);
|
||||
} > BRAM
|
||||
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
}
|
||||
391
tools/ffsample/lpc2k/Makefile
Normal file
391
tools/ffsample/lpc2k/Makefile
Normal file
@@ -0,0 +1,391 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#
|
||||
# WinARM template makefile
|
||||
# by Martin Thomas, Kaiserslautern, Germany
|
||||
# <eversmith@heizung-thomas.de>
|
||||
#
|
||||
# based on the WinAVR makefile written by Eric B. Weddington, J<><4A>g Wunsch, et al.
|
||||
# Released to the Public Domain
|
||||
# Please read the make user manual!
|
||||
#
|
||||
#
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# (TODO: make filename.s = Just compile filename.c into the assembler code only)
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#
|
||||
# Changelog:
|
||||
# - 17. Feb. 2005 - added thumb-interwork support (mth)
|
||||
# - 28. Apr. 2005 - added C++ support (mth)
|
||||
# - 29. Arp. 2005 - changed handling for lst-Filename (mth)
|
||||
# - 1. Nov. 2005 - exception-vector placement options (mth)
|
||||
# - 15. Nov. 2005 - added library-search-path (EXTRA_LIB...) (mth)
|
||||
# - 2. Dec. 2005 - fixed ihex and binary file extensions (mth)
|
||||
# - 22. Feb. 2006 - added AT91LIBNOWARN setting (mth)
|
||||
# - 19. Apr. 2006 - option FLASH_TOOL (default lpc21isp); variable IMGEXT (mth)
|
||||
# - 23. Jun. 2006 - option USE_THUMB_MODE -> THUMB/THUMB_IW
|
||||
# - 3. Aug. 2006 - added -ffunction-sections -fdata-sections to CFLAGS
|
||||
# and --gc-sections to LDFLAGS. Only available for gcc 4 (mth)
|
||||
# - 4. Aug. 2006 - pass SUBMDL-define to frontend (mth)
|
||||
# - 11. Nov. 2006 - FLASH_TOOL-config, TCHAIN-config (mth)
|
||||
# - 28. Mar. 2007 - remove .dep-Directory with rm -r -f and force "no error"
|
||||
# - 24. Aprl 2007 - added "both" option for format (.bin and .hex)
|
||||
|
||||
# Toolchain prefix (i.e arm-elf -> arm-elf-gcc.exe)
|
||||
|
||||
# - 2. Oct. 2008 - Changed for example project of FatFs moddule (chan)
|
||||
|
||||
|
||||
# MCU name and submodel
|
||||
MCU = arm7tdmi-s
|
||||
THUMB_MODE = NO
|
||||
SUBMDL = LPC2368
|
||||
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = lpcmci
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
# use file-extension c for "c-only"-files
|
||||
SRC = main.c comm.c rtc.c monitor.c mci.c ff.c unicode/cc932.c
|
||||
|
||||
# List C source files here which must be compiled in ARM-Mode.
|
||||
# use file-extension c for "c-only"-files
|
||||
SRCARM =
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
# List Assembler source files here which must be assembled in ARM-Mode..
|
||||
ASRCARM = asmfunc.S
|
||||
|
||||
## Output format. (can be ihex or binary or both)
|
||||
## (binary i.e. for openocd and SAM-BA, hex i.e. for lpc21isp and uVision)
|
||||
FORMAT = ihex
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = -Os
|
||||
|
||||
## Using the Atmel AT91_lib produces warning with
|
||||
## the default warning-levels.
|
||||
## yes - disable these warnings; no - keep default settings
|
||||
#AT91LIBNOWARN = yes
|
||||
AT91LIBNOWARN = no
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
|
||||
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
|
||||
#DEBUG = stabs
|
||||
DEBUG = dwarf-2
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
# List any extra directories to look for library files here.
|
||||
# Each directory must be seperated by a space.
|
||||
EXTRA_LIBDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 - "ANSI" C
|
||||
# gnu89 - c89 plus GCC extensions
|
||||
# c99 - ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 - c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu89
|
||||
|
||||
# Place -D or -U options for C here
|
||||
RUN_MODE=ROM_RUN
|
||||
CDEFS = -D$(RUN_MODE)
|
||||
|
||||
# Place -D or -U options for ASM here
|
||||
ADEFS = -D$(RUN_MODE)
|
||||
|
||||
CDEFS += -D__WinARM__ -D__WINARMSUBMDL_$(SUBMDL)__
|
||||
ADEFS += -D__WinARM__ -D__WINARMSUBMDL_$(SUBMDL)__
|
||||
|
||||
# Compiler flags.
|
||||
|
||||
ifeq ($(THUMB_MODE),YES)
|
||||
THUMB = -mthumb
|
||||
THUMB_IW = -mthumb-interwork
|
||||
else
|
||||
THUMB =
|
||||
THUMB_IW =
|
||||
endif
|
||||
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
#
|
||||
# Flags for C and C++ (arm-elf-gcc/arm-elf-g++)
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS) $(CINCS)
|
||||
CFLAGS += $(OPT)
|
||||
CFLAGS += -Wall -Wcast-align -Wimplicit
|
||||
CFLAGS += -Wpointer-arith -Wswitch
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
|
||||
# flags only for C
|
||||
CONLYFLAGS += -Wnested-externs
|
||||
CONLYFLAGS += $(CSTANDARD)
|
||||
|
||||
ifneq ($(AT91LIBNOWARN),yes)
|
||||
#AT91-lib warnings with:
|
||||
CFLAGS += -Wcast-qual
|
||||
CONLYFLAGS += -Wstrict-prototypes
|
||||
#CONLYFLAGS += -Wmissing-declarations
|
||||
#CONLYFLAGS += -Wmissing-prototypes
|
||||
endif
|
||||
|
||||
# flags only for C++ (arm-elf-g++)
|
||||
# CPPFLAGS = -fno-rtti -fno-exceptions
|
||||
CPPFLAGS =
|
||||
|
||||
# Assembler flags.
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -ahlns: create listing
|
||||
# -g$(DEBUG): have the assembler create line number information
|
||||
ASFLAGS = $(ADEFS) -Wa,-g$(DEBUG)
|
||||
|
||||
|
||||
#Additional libraries.
|
||||
|
||||
# Extra libraries
|
||||
# Each library-name must be seperated by a space.
|
||||
# To add libxyz.a, libabc.a and libefsl.a:
|
||||
# EXTRA_LIBS = xyz abc efsl
|
||||
#EXTRA_LIBS = efsl
|
||||
EXTRA_LIBS =
|
||||
|
||||
#Support for newlibc-lpc (file: libnewlibc-lpc.a)
|
||||
#NEWLIBLPC = -lnewlib-lpc
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
# CPLUSPLUS_LIB = -lstdc++
|
||||
|
||||
|
||||
# Linker flags.
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref,--gc-sections
|
||||
LDFLAGS += -lc
|
||||
LDFLAGS += $(NEWLIBLPC) $(MATH_LIB)
|
||||
LDFLAGS += -lc -lgcc
|
||||
LDFLAGS += $(CPLUSPLUS_LIB)
|
||||
LDFLAGS += $(patsubst %,-L%,$(EXTRA_LIBDIRS))
|
||||
LDFLAGS += $(patsubst %,-l%,$(EXTRA_LIBS))
|
||||
|
||||
# Set Linker-Script Depending On Selected Memory and Controller
|
||||
LDFLAGS +=-T$(SUBMDL)-ROM.ld
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = arm-elf-gcc
|
||||
AR = arm-elf-ar
|
||||
OBJCOPY = arm-elf-objcopy
|
||||
OBJDUMP = arm-elf-objdump
|
||||
SIZE = arm-elf-size
|
||||
NM = arm-elf-nm
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rm -f -r
|
||||
COPY = cp
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_END = -------- end --------
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_LST = Creating listing file
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling C:
|
||||
MSG_COMPILING_ARM = "Compiling C (ARM-only):"
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_ASSEMBLING_ARM = "Assembling (ARM-only):"
|
||||
MSG_CLEANING = Cleaning project:
|
||||
MSG_FORMATERROR = Can not handle output-format
|
||||
MSG_LPC21_RESETREMINDER = You may have to bring the target in bootloader-mode now.
|
||||
|
||||
# Define all object files.
|
||||
COBJ = $(SRC:.c=.o)
|
||||
AOBJ = $(ASRC:.S=.o)
|
||||
COBJARM = $(SRCARM:.c=.o)
|
||||
AOBJARM = $(ASRCARM:.S=.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(TARGET).lst $(ASRC:.S=.lst) $(ASRCARM:.S=.lst) $(SRC:.c=.lst) $(SRCARM:.c=.lst)
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
|
||||
GENDEPFLAGS =
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
# Default target.
|
||||
all: version build size
|
||||
|
||||
ifeq ($(FORMAT),ihex)
|
||||
build: elf hex lst sym
|
||||
hex: $(TARGET).hex
|
||||
IMGEXT=hex
|
||||
else
|
||||
ifeq ($(FORMAT),binary)
|
||||
build: elf bin lst sym
|
||||
bin: $(TARGET).bin
|
||||
IMGEXT=bin
|
||||
else
|
||||
ifeq ($(FORMAT),both)
|
||||
build: elf hex bin lst sym
|
||||
hex: $(TARGET).hex
|
||||
bin: $(TARGET).bin
|
||||
else
|
||||
$(error "$(MSG_FORMATERROR) $(FORMAT)")
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
elf: $(TARGET).elf
|
||||
lst: $(TARGET).lst
|
||||
sym: $(TARGET).sym
|
||||
|
||||
|
||||
# Display size of file.
|
||||
ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||
|
||||
size:
|
||||
@if [ -f $(TARGET).elf ]; then $(ELFSIZE); fi
|
||||
|
||||
# Display compiler version information.
|
||||
version :
|
||||
@$(CC) --version
|
||||
|
||||
# Create final output file (.hex) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
# Create final output file (.bin) from ELF output file.
|
||||
%.bin: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
# testing: option -C
|
||||
%.lst: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S -C $< > $@
|
||||
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ)
|
||||
%.elf: $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(THUMB) $(ALL_CFLAGS) $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ) --output $@ $(LDFLAGS)
|
||||
|
||||
# Compile: create object files from C source files. ARM/Thumb
|
||||
$(COBJ) : %.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(THUMB) $(ALL_CFLAGS) $(CONLYFLAGS) $< -o $@
|
||||
|
||||
# Compile: create object files from C source files. ARM-only
|
||||
$(COBJARM) : %.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING_ARM) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $(CONLYFLAGS) $< -o $@
|
||||
|
||||
# Compile: create assembler files from C source files. ARM/Thumb
|
||||
## does not work - TODO - hints welcome
|
||||
##$(COBJ) : %.s : %.c
|
||||
## $(CC) $(THUMB) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files. ARM/Thumb
|
||||
$(AOBJ) : %.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(THUMB) $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files. ARM-only
|
||||
$(AOBJARM) : %.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING_ARM) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: clean_list
|
||||
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).bin
|
||||
$(REMOVE) $(TARGET).obj
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).obj
|
||||
$(REMOVE) $(TARGET).a90
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lnk
|
||||
$(REMOVE) $(TARGET).lst
|
||||
$(REMOVE) $(COBJ)
|
||||
$(REMOVE) $(AOBJ)
|
||||
$(REMOVE) $(COBJARM)
|
||||
$(REMOVE) $(AOBJARM)
|
||||
$(REMOVE) $(LST)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
# $(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) $(SRCARM:.c=.s)
|
||||
# $(REMOVE) $(SRCARM:.c=.d)
|
||||
# $(REMOVEDIR) .dep | exit 0
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
#-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end size gccversion \
|
||||
build elf hex bin lss sym clean clean_list program
|
||||
|
||||
417
tools/ffsample/lpc2k/asmfunc.S
Normal file
417
tools/ffsample/lpc2k/asmfunc.S
Normal file
@@ -0,0 +1,417 @@
|
||||
@-----------------------------------------------------------@
|
||||
@ LPC2300 startup code and asm functions
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
|
||||
.equ UND_Stack_Size, 0
|
||||
.equ SVC_Stack_Size, 256 @ Used by ISRs and SWIs
|
||||
.equ ABT_Stack_Size, 0
|
||||
.equ FIQ_Stack_Size, 0 @ Used by FIQ handler
|
||||
.equ IRQ_Stack_Size, 256 @ Requres ISR nesting level * 28 bytes
|
||||
.equ USR_Stack_Size, 1024 @ Used by user mode programs
|
||||
.equ Stack_Size, (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||
FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)
|
||||
.equ Heap_Size, 0
|
||||
|
||||
.equ B_Irq, 0x80
|
||||
.equ B_Fiq, 0x40
|
||||
.equ B_Thumb, 0x20
|
||||
.equ M_USR, 0x10
|
||||
.equ M_FIQ, 0x11
|
||||
.equ M_IRQ, 0x12
|
||||
.equ M_SVC, 0x13
|
||||
.equ M_ABT, 0x17
|
||||
.equ M_UND, 0x1B
|
||||
.equ M_SYS, 0x1F
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ Stack area (located in RAM)
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.arm
|
||||
.section .STACK, "w"
|
||||
.align 3
|
||||
Stack_Mem:
|
||||
.space Stack_Size
|
||||
.equ Stack_Top, Stack_Mem + Stack_Size
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ Heap area (located in RAM)
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.section .HEAP, "w"
|
||||
.align 3
|
||||
HeapMem:
|
||||
.if (Heap_Size > 0)
|
||||
.space Heap_Size
|
||||
.endif
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ Exception entries (located in ROM, address 0x00000000)
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.section .VECTOR, "ax"
|
||||
.arm
|
||||
|
||||
LDR PC, [PC, #24] @ Reset entry, jump to reset handler
|
||||
LDR PC, [PC, #24] @ Undef entry, trap
|
||||
LDR PC, [PC, #24] @ SWI entry, jump to SWI handler
|
||||
LDR PC, [PC, #24] @ PAbt entry, trap
|
||||
LDR PC, [PC, #24] @ DAbt entry, trap
|
||||
.word 0
|
||||
LDR PC, [PC, #20] @ IRQ entry, jump to IRQ handler
|
||||
LDR PC, [PC, #20] @ FIQ entry, trap
|
||||
|
||||
.word Reset_Handler @ Reset handler
|
||||
.word Trap @ Undefined Instruction handler
|
||||
.word SWI_Handler @ Software Interrupt handler
|
||||
.word Trap @ Prefetch Abort handler
|
||||
.word Trap @ Data Abort handler
|
||||
.word IRQ_Handler @ IRQ handler
|
||||
.word Trap @ FIQ handler
|
||||
|
||||
Trap: B Trap @ Unused exception trap (infinite loop)
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ Reset Handler
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.section .text, "ax"
|
||||
.arm
|
||||
Reset_Handler:
|
||||
|
||||
@.extern TargetResetInit
|
||||
@ LDR SP, =Stack_Top @ Temporary stack for TargetResetInit()
|
||||
@ LDR R0, =TargetResetInit
|
||||
@ MOV LR, PC
|
||||
@ BX R0
|
||||
|
||||
@ Setup Stack for each mode
|
||||
LDR R0, =Stack_Top
|
||||
|
||||
@ Enter Undefined Instruction Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #M_UND | B_Irq | B_Fiq
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #UND_Stack_Size
|
||||
|
||||
@ Enter Abort Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #M_ABT | B_Irq | B_Fiq
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #ABT_Stack_Size
|
||||
|
||||
@ Enter FIQ Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #M_FIQ | B_Irq | B_Fiq
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #FIQ_Stack_Size
|
||||
|
||||
@ Enter IRQ Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #M_IRQ | B_Irq | B_Fiq
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #IRQ_Stack_Size
|
||||
|
||||
@ Enter Supervisor Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #M_SVC | B_Irq | B_Fiq
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #SVC_Stack_Size
|
||||
|
||||
@ Enter User Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #M_USR | B_Irq | B_Fiq
|
||||
MOV SP, R0
|
||||
SUB SL, SP, #USR_Stack_Size
|
||||
|
||||
@ Relocate .data section (Initialize with ROM data)
|
||||
LDR R1, =_etext
|
||||
LDR R2, =_data
|
||||
LDR R3, =_edata
|
||||
CMP R2, R3
|
||||
BEQ DataIsEmpty
|
||||
LoopRel:CMP R2, R3
|
||||
LDRLO R0, [R1], #4
|
||||
STRLO R0, [R2], #4
|
||||
BLO LoopRel
|
||||
DataIsEmpty:
|
||||
|
||||
@ Clear .bss section (Initialize with 0)
|
||||
MOV R0, #0
|
||||
LDR R1, =__bss_start__
|
||||
LDR R2, =__bss_end__
|
||||
CMP R1,R2
|
||||
BEQ BSSIsEmpty
|
||||
LoopZI: CMP R1, R2
|
||||
STRLO R0, [R1], #4
|
||||
BLO LoopZI
|
||||
BSSIsEmpty:
|
||||
|
||||
@ Start main()
|
||||
.extern main
|
||||
LDR R0, =main
|
||||
MOV LR, PC
|
||||
BX R0
|
||||
MTrap: B MTrap @ Trap if main() terminated
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ IRQ Handler
|
||||
@ Prologue and Epilog for all ISRs are handled here
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.equ LPC_BASE_VIC, 0xFFFFF000
|
||||
.equ VIC_IntSelect, 0x00C
|
||||
.equ VIC_IntEnable, 0x010
|
||||
.equ VIC_IntEnClear, 0x014
|
||||
.equ VIC_Protection, 0x020
|
||||
.equ VIC_SWPriorityMask,0x024
|
||||
.equ VIC_VectAddr0, 0x100
|
||||
.equ VIC_VectPriority0, 0x200
|
||||
.equ VIC_VectAddr, 0xF00
|
||||
|
||||
.arm
|
||||
IRQ_Handler:
|
||||
SUB LR, LR, #4 @ Adjust LR_irq and push it
|
||||
STMFD SP!, {LR}
|
||||
|
||||
MRS LR, SPSR @ Save SPSR need to be saved for nested interrupt
|
||||
STMFD SP!, {R0-R3,IP,LR} @ Push scratch/used registers and SPSR
|
||||
LDR R0, =LPC_BASE_VIC @ Get the ISR address pointed by VIC_VectAddr
|
||||
LDR R0, [R0, #VIC_VectAddr]
|
||||
MSR CPSR_c, #M_SVC @ Enter SVC mode and enable Irq and Fiq
|
||||
|
||||
STMFD SP!, {LR} @ Call the ISR
|
||||
MOV LR, PC
|
||||
BX R0
|
||||
LDMIA SP!, {LR}
|
||||
|
||||
MSR CPSR_c, #M_IRQ | B_Irq @ Enter IRQ mode and disable Irq
|
||||
LDMIA SP!, {R0-R3,IP,LR} @ Restore scratch/used registers and SPSR
|
||||
MSR SPSR_cxsf, LR @ Restore SPSR_irq
|
||||
|
||||
LDR LR, =LPC_BASE_VIC @ Issue EOI command to the VIC
|
||||
STR LR, [LR, #VIC_VectAddr]
|
||||
|
||||
LDMIA SP!, {PC}^ @ Reruen from the IRQ handler
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ SWI Service (declared in interrupt.h)
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.equ SWI_IRQ_DIS, 0
|
||||
.equ SWI_IRQ_EN, 1
|
||||
.equ SWI_FIQ_DIS, 2
|
||||
.equ SWI_FIQ_EN, 3
|
||||
.equ SWI_CLR_VECT, 4
|
||||
.equ SWI_REG_VECT, 5
|
||||
|
||||
.equ NUM_SWI, 6
|
||||
|
||||
.arm
|
||||
SWI_Handler:
|
||||
LDR IP, [LR, #-4] @ Get swi instruction code (assuming ARM state)
|
||||
AND IP, #0xFF @ Get swi comment field (lower 8 bit)
|
||||
CMP IP, #NUM_SWI @ Check range
|
||||
LDRLO PC, [PC, IP, LSL #2] @ Jump each service function when code is valid
|
||||
MOVS PC, LR @ Otherwise return
|
||||
.word IRQDisable
|
||||
.word IRQEnable
|
||||
.word FIQDisable
|
||||
.word FIQEnable
|
||||
.word ClearVect
|
||||
.word RegVect
|
||||
|
||||
IRQDisable:
|
||||
MRS R0, SPSR
|
||||
ORR R0, R0, #B_Irq
|
||||
MSR SPSR_c, R0
|
||||
MOVS PC, LR
|
||||
|
||||
IRQEnable:
|
||||
MRS R0, SPSR
|
||||
BIC R0, R0, #B_Irq
|
||||
MSR SPSR_c, R0
|
||||
MOVS PC, LR
|
||||
|
||||
FIQDisable:
|
||||
MRS R0, SPSR
|
||||
ORR R0, R0, #B_Fiq
|
||||
MSR SPSR_c, R0
|
||||
MOVS PC, LR
|
||||
|
||||
FIQEnable:
|
||||
MRS R0, SPSR
|
||||
BIC R0, R0, #B_Fiq
|
||||
MSR SPSR_c, R0
|
||||
MOVS PC, LR
|
||||
|
||||
ClearVect:
|
||||
LDR IP, =LPC_BASE_VIC
|
||||
MVN R0, #0 @ Disable all interrupts
|
||||
STR R0, [IP, #VIC_IntEnClear]
|
||||
MOV R0, R0, LSR #16 @ Unmask all interrupt levels
|
||||
STR R0, [IP, #VIC_SWPriorityMask]
|
||||
MOV R0, #1 @ Enable protection
|
||||
STR R0, [IP, #VIC_Protection]
|
||||
STR R0, [IP, #VIC_VectAddr] @ Issule EOI command
|
||||
MOVS PC, LR
|
||||
|
||||
RegVect:
|
||||
CMP R0, #32 @ Range check
|
||||
MOVCSS PC, LR
|
||||
LDR IP, =(LPC_BASE_VIC+VIC_VectAddr0)
|
||||
STR R1, [IP, R0, LSL #2] @ Set VICVectVectAddr<n>
|
||||
LDR IP, =(LPC_BASE_VIC+VIC_VectPriority0)
|
||||
STR R2, [IP, R0, LSL #2] @ Set VICVectPriority<n>
|
||||
MOV R1, #1
|
||||
MOV R1, R1, LSL R0
|
||||
LDR IP, =LPC_BASE_VIC
|
||||
LDR R2, [IP, #VIC_IntSelect] @ Set corresponding bit in the VICIntSelect
|
||||
BIC R2, R1
|
||||
CMP R3, #1
|
||||
ORREQ R2, R1
|
||||
STR R2, [IP, #VIC_IntSelect]
|
||||
STR R1, [IP, #VIC_IntEnable] @ Enable corresponding interrupt
|
||||
MOVS PC, LR
|
||||
|
||||
.global IrqDisable
|
||||
.arm
|
||||
IrqDisable:
|
||||
SWI SWI_IRQ_DIS
|
||||
BX LR
|
||||
|
||||
.global IrqEnable
|
||||
.arm
|
||||
IrqEnable:
|
||||
SWI SWI_IRQ_EN
|
||||
BX LR
|
||||
|
||||
.global FiqDisable
|
||||
.arm
|
||||
FiqDisable:
|
||||
SWI SWI_FIQ_DIS
|
||||
BX LR
|
||||
|
||||
.global FiqEnable
|
||||
.arm
|
||||
FiqEnable:
|
||||
SWI SWI_FIQ_EN
|
||||
BX LR
|
||||
|
||||
.global ClearVector
|
||||
.arm
|
||||
ClearVector:
|
||||
SWI SWI_CLR_VECT
|
||||
BX LR
|
||||
|
||||
.global RegisterVector
|
||||
.arm
|
||||
RegisterVector:
|
||||
SWI SWI_REG_VECT
|
||||
BX LR
|
||||
|
||||
|
||||
|
||||
@-----------------------------------------------------------@
|
||||
@ Fast Block Copy (declared in mci.c)
|
||||
@-----------------------------------------------------------@
|
||||
|
||||
.global Load_Block
|
||||
.arm
|
||||
Load_Block:
|
||||
STMFD SP!, {R4-R8}
|
||||
ANDS IP, R1, #3
|
||||
BEQ lb_align
|
||||
|
||||
BIC R1, #3
|
||||
MOV IP, IP, LSL #3
|
||||
RSB R8, IP, #32
|
||||
LDMIA R1!, {R7}
|
||||
lb_l1: MOV R3, R7
|
||||
LDMIA R1!, {R4-R7}
|
||||
MOV R3, R3, LSR IP
|
||||
ORR R3, R3, R4, LSL R8
|
||||
MOV R4, R4, LSR IP
|
||||
ORR R4, R4, R5, LSL R8
|
||||
MOV R5, R5, LSR IP
|
||||
ORR R5, R5, R6, LSL R8
|
||||
MOV R6, R6, LSR IP
|
||||
ORR R6, R6, R7, LSL R8
|
||||
SUBS R2, R2, #16
|
||||
STMIA R0!, {R3-R6}
|
||||
BNE lb_l1
|
||||
LDMFD SP!, {R4-R8}
|
||||
BX LR
|
||||
|
||||
lb_align:
|
||||
LDMIA R1!, {R3-R6}
|
||||
SUBS R2, R2, #16
|
||||
STMIA R0!, {R3-R6}
|
||||
BNE lb_align
|
||||
LDMFD SP!, {R4-R8}
|
||||
BX LR
|
||||
|
||||
|
||||
.global Store_Block
|
||||
.arm
|
||||
Store_Block:
|
||||
STMFD SP!, {R4-R8}
|
||||
ANDS IP, R0, #3
|
||||
BEQ sb_align
|
||||
|
||||
MOV IP, IP, LSL #3
|
||||
RSB R8, IP, #32
|
||||
|
||||
LDMIA R1!, {R4-R7}
|
||||
sb_p1: STRB R4, [R0], #1
|
||||
MOV R4, R4, LSR #8
|
||||
TST R0, #3
|
||||
BNE sb_p1
|
||||
ORR R4, R4, R5, LSL IP
|
||||
MOV R5, R5, LSR R8
|
||||
ORR R5, R5, R6, LSL IP
|
||||
MOV R6, R6, LSR R8
|
||||
ORR R6, R6, R7, LSL IP
|
||||
SUBS R2, R2, #16
|
||||
STMIA R0!, {R4-R6}
|
||||
|
||||
sb_l1: MOV R3, R7
|
||||
LDMIA R1!, {R4-R7}
|
||||
MOV R3, R3, LSR R8
|
||||
ORR R3, R3, R4, LSL IP
|
||||
MOV R4, R4, LSR R8
|
||||
ORR R4, R4, R5, LSL IP
|
||||
MOV R5, R5, LSR R8
|
||||
ORR R5, R5, R6, LSL IP
|
||||
MOV R6, R6, LSR R8
|
||||
ORR R6, R6, R7, LSL IP
|
||||
SUBS R2, R2, #16
|
||||
STMIA R0!, {R3-R6}
|
||||
BNE sb_l1
|
||||
|
||||
MOV R7, R7, LSR R8
|
||||
sb_p2: SUBS IP, IP, #8
|
||||
STRB R7, [R0], #1
|
||||
MOV R7, R7, LSR #8
|
||||
BNE sb_p2
|
||||
|
||||
LDMFD SP!, {R4-R8}
|
||||
BX LR
|
||||
|
||||
sb_align:
|
||||
LDMIA R1!, {R3-R6}
|
||||
SUBS R2, #16
|
||||
STMIA R0!, {R3-R6}
|
||||
BNE sb_align
|
||||
LDMFD SP!, {R4-R8}
|
||||
BX LR
|
||||
|
||||
.end
|
||||
|
||||
165
tools/ffsample/lpc2k/comm.c
Normal file
165
tools/ffsample/lpc2k/comm.c
Normal file
@@ -0,0 +1,165 @@
|
||||
#include <string.h>
|
||||
#include "LPC2300.h"
|
||||
#include "interrupt.h"
|
||||
#include "comm.h"
|
||||
|
||||
|
||||
#define BUFFER_SIZE 128
|
||||
|
||||
#define PCLK 18000000
|
||||
#define BPS 230400
|
||||
#define DIVADDVAL 5
|
||||
#define MULVAL 8
|
||||
#define DLVAL ((int)((double)PCLK / BPS / 16 / (1 + (double)DIVADDVAL / MULVAL)))
|
||||
|
||||
|
||||
static volatile struct
|
||||
{
|
||||
int rptr;
|
||||
int wptr;
|
||||
int count;
|
||||
BYTE buff[BUFFER_SIZE];
|
||||
} TxFifo0, RxFifo0;
|
||||
static volatile int TxRun0;
|
||||
|
||||
|
||||
|
||||
|
||||
void Isr_UART0 (void)
|
||||
{
|
||||
int d, idx, cnt, iir;
|
||||
|
||||
|
||||
for (;;) {
|
||||
iir = U0IIR; /* Get Interrupt ID*/
|
||||
if (iir & 1) break; /* Exit if there is no interrupt */
|
||||
switch (iir & 6) {
|
||||
case 4: /* Receive FIFO is half filled or timeout occured */
|
||||
idx = RxFifo0.wptr;
|
||||
cnt = RxFifo0.count;
|
||||
while (U0LSR & 0x01) { /* Receive all data in the FIFO */
|
||||
d = U0RBR;
|
||||
if (cnt < BUFFER_SIZE) { /* Store data if buffer is not full */
|
||||
RxFifo0.buff[idx] = d;
|
||||
cnt++;
|
||||
idx = (idx + 1) % BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
RxFifo0.wptr = idx;
|
||||
RxFifo0.count = cnt;
|
||||
break;
|
||||
|
||||
case 2: /* Transmisson FIFO empty */
|
||||
cnt = TxFifo0.count;
|
||||
if (cnt) {
|
||||
idx = TxFifo0.rptr;
|
||||
for (d = 12; d && cnt; d--, cnt--) { /* Store data into FIFO (max 12 chrs) */
|
||||
U0THR = TxFifo0.buff[idx];
|
||||
idx = (idx + 1) % BUFFER_SIZE;
|
||||
}
|
||||
TxFifo0.rptr = idx;
|
||||
TxFifo0.count = cnt;
|
||||
} else {
|
||||
TxRun0 = 0; /* When no data in the buffer, clear running flag */
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* Data error or break detected */
|
||||
d = U0LSR;
|
||||
d = U0RBR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int uart0_test (void)
|
||||
{
|
||||
return RxFifo0.count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BYTE uart0_get (void)
|
||||
{
|
||||
BYTE d;
|
||||
int idx;
|
||||
|
||||
/* Wait while Rx buffer is empty */
|
||||
while (!RxFifo0.count);
|
||||
|
||||
U0IER = 0; /* Disable interrupts */
|
||||
idx = RxFifo0.rptr;
|
||||
d = RxFifo0.buff[idx]; /* Get a byte from Rx buffer */
|
||||
RxFifo0.rptr = (idx + 1) % BUFFER_SIZE;
|
||||
RxFifo0.count--;
|
||||
U0IER = 0x07; /* Enable interrupt */
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void uart0_put (BYTE d)
|
||||
{
|
||||
#if 0
|
||||
while (!(U0LSR & 0x20));
|
||||
U0THR = d;
|
||||
#else
|
||||
int idx, cnt;
|
||||
|
||||
/* Wait for buffer ready */
|
||||
while (TxFifo0.count >= BUFFER_SIZE);
|
||||
|
||||
U0IER = 0x05; /* Disable Tx Interrupt */
|
||||
if (!TxRun0) { /* When not in runnig, trigger transmission */
|
||||
U0THR = d;
|
||||
TxRun0 = 1;
|
||||
} else { /* When transmission is runnig, store the data into the Tx buffer */
|
||||
cnt = TxFifo0.count;
|
||||
idx = TxFifo0.wptr;
|
||||
TxFifo0.buff[idx] = d;
|
||||
TxFifo0.wptr = (idx + 1) % BUFFER_SIZE;
|
||||
TxFifo0.count = ++cnt;
|
||||
}
|
||||
U0IER = 0x07; /* Enable Tx Interrupt */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void uart0_init (void)
|
||||
{
|
||||
U0IER = 0x00;
|
||||
RegisterVector(UART0_INT, Isr_UART0, PRI_LOWEST, CLASS_IRQ);
|
||||
|
||||
/* Attach UART0 unit to I/O pad */
|
||||
PINSEL0 = (PINSEL0 & 0xFFFFFF0F) | 0x50;
|
||||
|
||||
/* Initialize UART0 */
|
||||
U0LCR = 0x83; /* Select divisor latch */
|
||||
U0DLM = DLVAL / 256; /* Initialize BRG */
|
||||
U0DLL = DLVAL % 256;
|
||||
U0FDR = (MULVAL << 4) | DIVADDVAL;
|
||||
U0LCR = 0x03; /* Set serial format N81 and deselect divisor latch */
|
||||
U0FCR = 0x87; /* Enable FIFO */
|
||||
U0TER = 0x80; /* Enable Tansmission */
|
||||
|
||||
/* Clear Tx/Rx FIFOs */
|
||||
TxFifo0.rptr = 0;
|
||||
TxFifo0.wptr = 0;
|
||||
TxFifo0.count = 0;
|
||||
RxFifo0.rptr = 0;
|
||||
RxFifo0.wptr = 0;
|
||||
RxFifo0.count = 0;
|
||||
|
||||
/* Enable Tx/Rx/Error interrupts */
|
||||
U0IER = 0x07;
|
||||
}
|
||||
|
||||
|
||||
12
tools/ffsample/lpc2k/comm.h
Normal file
12
tools/ffsample/lpc2k/comm.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _COMMFUNC
|
||||
#define _COMMFUNC
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
void uart0_init (void);
|
||||
int uart0_test (void);
|
||||
void uart0_put (BYTE);
|
||||
BYTE uart0_get (void);
|
||||
|
||||
#endif
|
||||
|
||||
79
tools/ffsample/lpc2k/diskio.h
Normal file
79
tools/ffsample/lpc2k/diskio.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file R0.05 (C)ChaN, 2007
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Read-only mode */
|
||||
#define _USE_IOCTL 1
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
#endif
|
||||
DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||
void disk_timerproc (void);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl() */
|
||||
|
||||
/* Generic command */
|
||||
#define CTRL_SYNC 0 /* Mandatory for write functions */
|
||||
#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */
|
||||
#define GET_SECTOR_SIZE 2
|
||||
#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */
|
||||
#define CTRL_POWER 4
|
||||
#define CTRL_LOCK 5
|
||||
#define CTRL_EJECT 6
|
||||
/* MMC/SDC command */
|
||||
#define MMC_GET_TYPE 10
|
||||
#define MMC_GET_CSD 11
|
||||
#define MMC_GET_CID 12
|
||||
#define MMC_GET_OCR 13
|
||||
#define MMC_GET_SDSTAT 14
|
||||
/* ATA/CF command */
|
||||
#define ATA_GET_REV 20
|
||||
#define ATA_GET_MODEL 21
|
||||
#define ATA_GET_SN 22
|
||||
|
||||
|
||||
/* Card type flags (CardType) */
|
||||
#define CT_MMC 0x01
|
||||
#define CT_SD1 0x02
|
||||
#define CT_SD2 0x04
|
||||
#define CT_SDC (CT_SD1|CT_SD2)
|
||||
#define CT_BLOCK 0x08
|
||||
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
||||
2936
tools/ffsample/lpc2k/ff.c
Normal file
2936
tools/ffsample/lpc2k/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
547
tools/ffsample/lpc2k/ff.h
Normal file
547
tools/ffsample/lpc2k/ff.h
Normal file
@@ -0,0 +1,547 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.07a (C)ChaN, 2009
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is an open source software to implement FAT file system to
|
||||
/ small embedded systems. This is a free software and is opened for education,
|
||||
/ research and commercial developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Configuration Options
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FATFS
|
||||
#define _FATFS
|
||||
|
||||
#define _WORD_ACCESS 0
|
||||
/* The _WORD_ACCESS option defines which access method is used to the word
|
||||
/ data in the FAT structure.
|
||||
/
|
||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned
|
||||
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code efficiency. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||
/ 3: f_lseek is removed in addition to level 2. */
|
||||
|
||||
|
||||
#define _FS_TINY 0
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _DRIVES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512
|
||||
/* Maximum sector size to be handled. (512/1024/2048/4096) */
|
||||
/* 512 for memroy card and hard disk, 1024 for floppy disk, 2048 for MO disk */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
||||
/ drive number and can mount only first primaly partition. When it is set to 1,
|
||||
/ each volume is tied to the partitions listed in Drives[]. */
|
||||
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ When it is non LFN configuration, there is no difference between SBCS code
|
||||
/ pages. When LFN is enabled, the code page must always be set correctly.
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift-JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
/ 1258 - Vietnam
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 1
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (max:255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN.
|
||||
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
||||
/ 2: Enable LFN with dynamic working buffer on the caller's STACK.
|
||||
/
|
||||
/ The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
||||
/ a Unicode - OEM code conversion function ff_convert() must be added to
|
||||
/ the project. */
|
||||
|
||||
|
||||
#define _FS_REENTRANT 0
|
||||
#define _TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* Type of sync object used on the OS. */
|
||||
/* e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
|
||||
/ provided synchronization handlers, ff_req_grant, ff_rel_grant,
|
||||
/ ff_del_syncobj and ff_cre_syncobj function to the project. */
|
||||
|
||||
|
||||
|
||||
/* End of configuration options. Do not change followings without care. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multiple sector size */
|
||||
|
||||
#if _MAX_SS == 512
|
||||
#define SS(fs) 512
|
||||
#else
|
||||
#if _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
|
||||
#define SS(fs) ((fs)->s_size)
|
||||
#else
|
||||
#error Sector size must be 512, 1024, 2048 or 4096.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure */
|
||||
|
||||
typedef struct _FATFS {
|
||||
BYTE fs_type; /* FAT sub type */
|
||||
BYTE drive; /* Physical drive number */
|
||||
BYTE csize; /* Number of sectors per cluster */
|
||||
BYTE n_fats; /* Number of FAT copies */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE pad1;
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if _MAX_SS != 512U
|
||||
WORD s_size; /* Sector size */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
BYTE pad2;
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector */
|
||||
#endif
|
||||
DWORD sects_fat; /* Sectors per fat */
|
||||
DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure */
|
||||
|
||||
typedef struct _DIR {
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current index number */
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
DWORD sclust; /* Table start cluster (0:Static table) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File object structure */
|
||||
|
||||
typedef struct _FIL {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE csect; /* Sector address in the cluster */
|
||||
DWORD fptr; /* File R/W pointer */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS];/* File R/W buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* File status structure */
|
||||
|
||||
typedef struct _FILINFO {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
char fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
char *lfname; /* Pointer to the LFN buffer */
|
||||
int lfsize; /* Size of LFN buffer [bytes] */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* DBCS code ranges */
|
||||
|
||||
#if _CODE_PAGE == 932 /* CP932 (Japanese Shift-JIS) */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* CP936 (Simplified Chinese GBK) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* CP949 (Korean) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* CP950 (Traditional Chinese Big5) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#else /* SBCS code pages */
|
||||
#define _DF1S 0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Character code support macros */
|
||||
|
||||
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
||||
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
||||
#define IsDigit(c) (((c)>='0')&&((c)<='9'))
|
||||
|
||||
#if _DF1S /* DBCS configuration */
|
||||
|
||||
#if _DF2S /* Two 1st byte areas */
|
||||
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
||||
#else /* One 1st byte area */
|
||||
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
||||
#endif
|
||||
|
||||
#if _DS3S /* Three 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
||||
#else /* Two 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
||||
#endif
|
||||
|
||||
#else /* SBCS configuration */
|
||||
|
||||
#define IsDBCS1(c) 0
|
||||
#define IsDBCS2(c) 0
|
||||
|
||||
#endif /* _DF1S */
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multi partition */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
|
||||
typedef struct _PARTITION {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
|
||||
extern
|
||||
const PARTITION Drives[]; /* Logical drive# to physical location conversion table */
|
||||
#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */
|
||||
#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
|
||||
#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */
|
||||
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* 0 */
|
||||
FR_DISK_ERR, /* 1 */
|
||||
FR_INT_ERR, /* 2 */
|
||||
FR_NOT_READY, /* 3 */
|
||||
FR_NO_FILE, /* 4 */
|
||||
FR_NO_PATH, /* 5 */
|
||||
FR_INVALID_NAME, /* 6 */
|
||||
FR_DENIED, /* 7 */
|
||||
FR_EXIST, /* 8 */
|
||||
FR_INVALID_OBJECT, /* 9 */
|
||||
FR_WRITE_PROTECTED, /* 10 */
|
||||
FR_INVALID_DRIVE, /* 11 */
|
||||
FR_NOT_ENABLED, /* 12 */
|
||||
FR_NO_FILESYSTEM, /* 13 */
|
||||
FR_MKFS_ABORTED, /* 14 */
|
||||
FR_TIMEOUT /* 15 */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
|
||||
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const char*); /* Create a new directory */
|
||||
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const char*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||
|
||||
#if _USE_STRFUNC
|
||||
int f_putc (int, FIL*); /* Put a character to the file */
|
||||
int f_puts (const char*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */
|
||||
char* f_gets (char*, int, FIL*); /* Get a string from the file */
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#ifndef EOF
|
||||
#define EOF -1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* User defined functions */
|
||||
|
||||
/* Real time clock */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
|
||||
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
|
||||
#endif
|
||||
|
||||
/* Unicode - OEM code conversion */
|
||||
#if _USE_LFN
|
||||
WCHAR ff_convert (WCHAR, UINT);
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
|
||||
BOOL ff_del_syncobj(_SYNC_t);
|
||||
BOOL ff_req_grant(_SYNC_t);
|
||||
void ff_rel_grant(_SYNC_t);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#if _FS_READONLY == 0
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* FatFs refers the members in the FAT structures with byte offset instead
|
||||
/ of structure member because there are incompatibility of the packing option
|
||||
/ between various compilers. */
|
||||
|
||||
#define BS_jmpBoot 0
|
||||
#define BS_OEMName 3
|
||||
#define BPB_BytsPerSec 11
|
||||
#define BPB_SecPerClus 13
|
||||
#define BPB_RsvdSecCnt 14
|
||||
#define BPB_NumFATs 16
|
||||
#define BPB_RootEntCnt 17
|
||||
#define BPB_TotSec16 19
|
||||
#define BPB_Media 21
|
||||
#define BPB_FATSz16 22
|
||||
#define BPB_SecPerTrk 24
|
||||
#define BPB_NumHeads 26
|
||||
#define BPB_HiddSec 28
|
||||
#define BPB_TotSec32 32
|
||||
#define BS_55AA 510
|
||||
|
||||
#define BS_DrvNum 36
|
||||
#define BS_BootSig 38
|
||||
#define BS_VolID 39
|
||||
#define BS_VolLab 43
|
||||
#define BS_FilSysType 54
|
||||
|
||||
#define BPB_FATSz32 36
|
||||
#define BPB_ExtFlags 40
|
||||
#define BPB_FSVer 42
|
||||
#define BPB_RootClus 44
|
||||
#define BPB_FSInfo 48
|
||||
#define BPB_BkBootSec 50
|
||||
#define BS_DrvNum32 64
|
||||
#define BS_BootSig32 66
|
||||
#define BS_VolID32 67
|
||||
#define BS_VolLab32 71
|
||||
#define BS_FilSysType32 82
|
||||
|
||||
#define FSI_LeadSig 0
|
||||
#define FSI_StrucSig 484
|
||||
#define FSI_Free_Count 488
|
||||
#define FSI_Nxt_Free 492
|
||||
|
||||
#define MBR_Table 446
|
||||
|
||||
#define DIR_Name 0
|
||||
#define DIR_Attr 11
|
||||
#define DIR_NTres 12
|
||||
#define DIR_CrtTime 14
|
||||
#define DIR_CrtDate 16
|
||||
#define DIR_FstClusHI 20
|
||||
#define DIR_WrtTime 22
|
||||
#define DIR_WrtDate 24
|
||||
#define DIR_FstClusLO 26
|
||||
#define DIR_FileSize 28
|
||||
#define LDIR_Ord 0
|
||||
#define LDIR_Attr 11
|
||||
#define LDIR_Type 12
|
||||
#define LDIR_Chksum 13
|
||||
#define LDIR_FstClusLO 26
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _FATFS */
|
||||
37
tools/ffsample/lpc2k/integer.h
Normal file
37
tools/ffsample/lpc2k/integer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef signed char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* Boolean type */
|
||||
typedef enum { FALSE = 0, TRUE } BOOL;
|
||||
|
||||
#endif
|
||||
|
||||
#define _INTEGER
|
||||
#endif
|
||||
58
tools/ffsample/lpc2k/interrupt.h
Normal file
58
tools/ffsample/lpc2k/interrupt.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef __INTERRUPT_H
|
||||
#define __INTERRUPT_H
|
||||
|
||||
|
||||
/* Interrupt related service functions (These functions are defined in Startup.S) */
|
||||
|
||||
void RegisterVector (int IntNum, void(*Isr)(void), int Priority, int IntClass);
|
||||
void ClearVector (void);
|
||||
void FiqEnable (void);
|
||||
void FiqDisable (void);
|
||||
void IrqEnable (void);
|
||||
void IrqDisable (void);
|
||||
|
||||
|
||||
|
||||
/* LPC23xx interrupt number */
|
||||
|
||||
#define WDT_INT 0
|
||||
#define RES1_INT 1
|
||||
#define ARM_CORE0_INT 2
|
||||
#define ARM_CORE1_INT 3
|
||||
#define TIMER0_INT 4
|
||||
#define TIMER1_INT 5
|
||||
#define UART0_INT 6
|
||||
#define UART1_INT 7
|
||||
#define PWM0_1_INT 8
|
||||
#define I2C0_INT 9
|
||||
#define SPI0_INT 10
|
||||
#define SSP0_INT 10
|
||||
#define SSP1_INT 11
|
||||
#define PLL_INT 12
|
||||
#define RTC_INT 13
|
||||
#define EINT0_INT 14
|
||||
#define EINT1_INT 15
|
||||
#define EINT2_INT 16
|
||||
#define EINT3_INT 17
|
||||
#define ADC0_INT 18
|
||||
#define I2C1_INT 19
|
||||
#define BOD_INT 20
|
||||
#define EMAC_INT 21
|
||||
#define USB_INT 22
|
||||
#define CAN_INT 23
|
||||
#define MCI_INT 24
|
||||
#define GPDMA_INT 25
|
||||
#define TIMER2_INT 26
|
||||
#define TIMER3_INT 27
|
||||
#define UART2_INT 28
|
||||
#define UART3_INT 29
|
||||
#define I2C2_INT 30
|
||||
#define I2S_INT 31
|
||||
|
||||
#define CLASS_IRQ 0
|
||||
#define CLASS_FIQ 1
|
||||
#define PRI_LOWEST 15
|
||||
#define PRI_HIGHEST 0
|
||||
|
||||
|
||||
#endif /* __INTERRUPT_H */
|
||||
BIN
tools/ffsample/lpc2k/lpc_mmc.png
Normal file
BIN
tools/ffsample/lpc2k/lpc_mmc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
556
tools/ffsample/lpc2k/main.c
Normal file
556
tools/ffsample/lpc2k/main.c
Normal file
@@ -0,0 +1,556 @@
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* FAT file system sample project for FatFs R0.07 (C)ChaN, 2008 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "LPC2300.h"
|
||||
#include "integer.h"
|
||||
#include "interrupt.h"
|
||||
#include "comm.h"
|
||||
#include "monitor.h"
|
||||
#include "rtc.h"
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
|
||||
DWORD acc_size; /* Work register for fs command */
|
||||
WORD acc_files, acc_dirs;
|
||||
FILINFO Finfo;
|
||||
#if _USE_LFN
|
||||
char Lfname[512];
|
||||
#endif
|
||||
|
||||
char linebuf[120]; /* Console input buffer */
|
||||
|
||||
FATFS Fatfs[_DRIVES]; /* File system object for each logical drive */
|
||||
FIL File1, File2; /* File objects */
|
||||
DIR Dir; /* Directory object */
|
||||
BYTE Buff[16384] __attribute__ ((aligned (4))) ; /* Working buffer */
|
||||
|
||||
volatile UINT Timer; /* Performance timer (1kHz increment) */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* 1000Hz timer interrupt generated by TIMER0 */
|
||||
/*---------------------------------------------------------*/
|
||||
|
||||
void Isr_TIMER0 (void)
|
||||
{
|
||||
T0IR = 1; /* Clear irq flag */
|
||||
|
||||
Timer++;
|
||||
|
||||
disk_timerproc(); /* Disk timer process */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* User Provided Timer Function for FatFs module */
|
||||
/*---------------------------------------------------------*/
|
||||
/* This is a real time clock service to be called from */
|
||||
/* FatFs module. Any valid time must be returned even if */
|
||||
/* the system does not support a real time clock. */
|
||||
/* This is not required in read-only configuration. */
|
||||
|
||||
|
||||
DWORD get_fattime ()
|
||||
{
|
||||
RTC rtc;
|
||||
|
||||
|
||||
rtc_gettime(&rtc);
|
||||
|
||||
return ((DWORD)(rtc.year - 1980) << 25)
|
||||
| ((DWORD)rtc.month << 21)
|
||||
| ((DWORD)rtc.mday << 16)
|
||||
| ((DWORD)rtc.hour << 11)
|
||||
| ((DWORD)rtc.min << 5)
|
||||
| ((DWORD)rtc.sec >> 1);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Monitor */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
FRESULT scan_files (char* path)
|
||||
{
|
||||
DIR dirs;
|
||||
FRESULT res;
|
||||
BYTE i;
|
||||
char *fn;
|
||||
|
||||
|
||||
if ((res = f_opendir(&dirs, path)) == FR_OK) {
|
||||
i = strlen(path);
|
||||
while (((res = f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) {
|
||||
#if _USE_LFN
|
||||
fn = *Finfo.lfname ? Finfo.lfname : Finfo.fname;
|
||||
#else
|
||||
fn = Finfo.fname;
|
||||
#endif
|
||||
if (Finfo.fattrib & AM_DIR) {
|
||||
acc_dirs++;
|
||||
*(path+i) = '/'; strcpy(path+i+1, fn);
|
||||
res = scan_files(path);
|
||||
*(path+i) = '\0';
|
||||
if (res != FR_OK) break;
|
||||
} else {
|
||||
// xprintf("%s/%s\n", path, fn);
|
||||
acc_files++;
|
||||
acc_size += Finfo.fsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void put_rc (FRESULT rc)
|
||||
{
|
||||
const char *p;
|
||||
static const char str[] =
|
||||
"OK\0" "NOT_READY\0" "NO_FILE\0" "FR_NO_PATH\0" "INVALID_NAME\0" "INVALID_DRIVE\0"
|
||||
"DENIED\0" "EXIST\0" "RW_ERROR\0" "WRITE_PROTECTED\0" "NOT_ENABLED\0"
|
||||
"NO_FILESYSTEM\0" "INVALID_OBJECT\0" "MKFS_ABORTED\0";
|
||||
FRESULT i;
|
||||
|
||||
for (p = str, i = 0; i != rc && *p; i++) {
|
||||
while(*p++);
|
||||
}
|
||||
xprintf("rc=%u FR_%s\n", (UINT)rc, p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void IoInit (void)
|
||||
{
|
||||
#define PLL_N 2UL
|
||||
#define PLL_M 72UL
|
||||
#define CCLK_DIV 4
|
||||
|
||||
if ( PLLSTAT & (1 << 25) ) {
|
||||
PLLCON = 1; /* Disconnect PLL output if PLL is in use */
|
||||
PLLFEED = 0xAA; PLLFEED = 0x55;
|
||||
}
|
||||
PLLCON = 0; /* Disable PLL */
|
||||
PLLFEED = 0xAA; PLLFEED = 0x55;
|
||||
CLKSRCSEL = 0; /* Select IRC (4MHz) as the PLL clock source */
|
||||
|
||||
PLLCFG = ((PLL_N - 1) << 16) | (PLL_M - 1); /* Re-configure PLL */
|
||||
PLLFEED = 0xAA; PLLFEED = 0x55;
|
||||
PLLCON = 1; /* Enable PLL */
|
||||
PLLFEED = 0xAA; PLLFEED = 0x55;
|
||||
|
||||
while ((PLLSTAT & (1 << 26)) == 0); /* Wait for PLL locked */
|
||||
|
||||
CCLKCFG = CCLK_DIV-1; /* Select CCLK frequency (divide ratio of hclk) */
|
||||
PLLCON = 3; /* Connect PLL output to the sysclk */
|
||||
PLLFEED = 0xAA; PLLFEED = 0x55;
|
||||
|
||||
MAMCR = 0; /* Configure MAM for 72MHz operation */
|
||||
MAMTIM = 3;
|
||||
MAMCR = 2;
|
||||
|
||||
PCLKSEL0 = 0x00000000; /* Initialize peripheral clock to default */
|
||||
PCLKSEL1 = 0x00000000;
|
||||
|
||||
ClearVector(); /* Initialie VIC */
|
||||
|
||||
SCS |= 1; /* Enable FIO0 and FIO1 */
|
||||
|
||||
FIO1DIR0 = 0x10; /* -|-|-|LEDR|-|-|-|- */
|
||||
FIO1PIN0 = 0x00;
|
||||
|
||||
/* Initialize Timer0 as 1kHz interval timer */
|
||||
RegisterVector(TIMER0_INT, Isr_TIMER0, PRI_LOWEST, CLASS_IRQ);
|
||||
T0CTCR = 0;
|
||||
T0MR0 = 18000 - 1; /* 18M / 1k = 18000 */
|
||||
T0MCR = 0x3; /* Clear TC and Interrupt on MR0 match */
|
||||
T0TCR = 1;
|
||||
|
||||
uart0_init(); /* Initialize UART0 */
|
||||
|
||||
IrqEnable(); /* Enable Irq */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
char *ptr, *ptr2;
|
||||
long p1, p2, p3;
|
||||
BYTE res, b1;
|
||||
WORD w1;
|
||||
UINT s1, s2, cnt, blen = sizeof(Buff);
|
||||
DWORD ofs = 0, sect = 0;
|
||||
FATFS *fs; /* Pointer to file system object */
|
||||
RTC rtc;
|
||||
|
||||
|
||||
IoInit();
|
||||
|
||||
xputs("\nFatFs module test monitor for LPC2368\n");
|
||||
|
||||
for (;;) {
|
||||
xputc('>');
|
||||
ptr = linebuf;
|
||||
get_line(ptr, sizeof(linebuf));
|
||||
|
||||
switch (*ptr++) {
|
||||
|
||||
case 'm' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* md <address> [<count>] - Dump memory */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (!xatoi(&ptr, &p2)) p2 = 128;
|
||||
for (ptr=(char*)p1; p2 >= 16; ptr += 16, p2 -= 16)
|
||||
put_dump((BYTE*)ptr, (UINT)ptr, 16);
|
||||
if (p2) put_dump((BYTE*)ptr, (UINT)ptr, p2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* dd [<lba>] - Dump secrtor */
|
||||
if (!xatoi(&ptr, &p2)) p2 = sect;
|
||||
res = disk_read(0, Buff, p2, 1);
|
||||
if (res) { xprintf("rc=%d\n", (WORD)res); break; }
|
||||
sect = p2 + 1;
|
||||
xprintf("Sector:%lu\n", p2);
|
||||
for (ptr=(char*)Buff, ofs = 0; ofs < 0x200; ptr+=16, ofs+=16)
|
||||
put_dump((BYTE*)ptr, ofs, 16);
|
||||
break;
|
||||
|
||||
case 'i' : /* di - Initialize disk */
|
||||
xprintf("rc=%d\n", (WORD)disk_initialize(0));
|
||||
break;
|
||||
|
||||
case 's' : /* ds - Show disk status */
|
||||
if (disk_ioctl(0, GET_SECTOR_COUNT, &p2) == RES_OK)
|
||||
{ xprintf("Drive size: %lu sectors\n", p2); }
|
||||
if (disk_ioctl(0, GET_SECTOR_SIZE, &w1) == RES_OK)
|
||||
{ xprintf("Sector size: %u\n", w1); }
|
||||
if (disk_ioctl(0, GET_BLOCK_SIZE, &p2) == RES_OK)
|
||||
{ xprintf("Erase block size: %lu sectors\n", p2); }
|
||||
if (disk_ioctl(0, MMC_GET_TYPE, &b1) == RES_OK)
|
||||
{ xprintf("MMC/SDC type: %u\n", b1); }
|
||||
if (disk_ioctl(0, MMC_GET_CSD, Buff) == RES_OK)
|
||||
{ xputs("CSD:\n"); put_dump(Buff, 0, 16); }
|
||||
if (disk_ioctl(0, MMC_GET_CID, Buff) == RES_OK)
|
||||
{ xputs("CID:\n"); put_dump(Buff, 0, 16); }
|
||||
if (disk_ioctl(0, MMC_GET_OCR, Buff) == RES_OK)
|
||||
{ xputs("OCR:\n"); put_dump(Buff, 0, 4); }
|
||||
if (disk_ioctl(0, MMC_GET_SDSTAT, Buff) == RES_OK) {
|
||||
xputs("SD Status:\n");
|
||||
for (s1 = 0; s1 < 64; s1 += 16) put_dump(Buff+s1, s1, 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'b' :
|
||||
switch (*ptr++) {
|
||||
case 'd' : /* bd <addr> - Dump R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
for (ptr=(char*)&Buff[p1], ofs = p1, cnt = 32; cnt; cnt--, ptr+=16, ofs+=16)
|
||||
put_dump((BYTE*)ptr, ofs, 16);
|
||||
break;
|
||||
|
||||
case 'e' : /* be <addr> [<data>] ... - Edit R/W buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
if (xatoi(&ptr, &p2)) {
|
||||
do {
|
||||
Buff[p1++] = (BYTE)p2;
|
||||
} while (xatoi(&ptr, &p2));
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
xprintf("%04X %02X-", (WORD)(p1), (WORD)Buff[p1]);
|
||||
get_line(linebuf, sizeof(linebuf));
|
||||
ptr = linebuf;
|
||||
if (*ptr == '.') break;
|
||||
if (*ptr < ' ') { p1++; continue; }
|
||||
if (xatoi(&ptr, &p2))
|
||||
Buff[p1++] = (BYTE)p2;
|
||||
else
|
||||
xputs("???\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r' : /* br <lba> [<num>] - Read disk into R/W buffer */
|
||||
if (!xatoi(&ptr, &p2)) break;
|
||||
if (!xatoi(&ptr, &p3)) p3 = 1;
|
||||
xprintf("rc=%u\n", (WORD)disk_read(0, Buff, p2, p3));
|
||||
break;
|
||||
|
||||
case 'w' : /* bw <lba> [<num>] - Write R/W buffer into disk */
|
||||
if (!xatoi(&ptr, &p2)) break;
|
||||
if (!xatoi(&ptr, &p3)) p3 = 1;
|
||||
xprintf("rc=%u\n", (WORD)disk_write(0, Buff, p2, p3));
|
||||
break;
|
||||
|
||||
case 'f' : /* bf <val> - Fill working buffer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
memset(Buff, (BYTE)p1, sizeof(Buff));
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f' :
|
||||
switch (*ptr++) {
|
||||
|
||||
case 'i' : /* fi - Force initialized the logical drive */
|
||||
put_rc(f_mount(0, &Fatfs[0]));
|
||||
break;
|
||||
|
||||
case 's' : /* fs - Show logical drive status */
|
||||
res = f_getfree("", (DWORD*)&p2, &fs);
|
||||
if (res) { put_rc(res); break; }
|
||||
xprintf("FAT type = %u\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
|
||||
"Root DIR entries = %u\nSectors/FAT = %lu\nNumber of clusters = %lu\n"
|
||||
"FAT start (lba) = %lu\nDIR start (lba,clustor) = %lu\nData start (lba) = %lu\n\n",
|
||||
(WORD)fs->fs_type, (DWORD)fs->csize * 512, (WORD)fs->n_fats,
|
||||
fs->n_rootdir, fs->sects_fat, (DWORD)fs->max_clust - 2,
|
||||
fs->fatbase, fs->dirbase, fs->database
|
||||
);
|
||||
acc_size = acc_files = acc_dirs = 0;
|
||||
#if _USE_LFN
|
||||
Finfo.lfname = Lfname;
|
||||
Finfo.lfsize = sizeof(Lfname);
|
||||
#endif
|
||||
res = scan_files(ptr);
|
||||
if (res) { put_rc(res); break; }
|
||||
xprintf("%u files, %lu bytes.\n%u folders.\n"
|
||||
"%lu KB total disk space.\n%lu KB available.\n",
|
||||
acc_files, acc_size, acc_dirs,
|
||||
(fs->max_clust - 2) * (fs->csize / 2), p2 * (fs->csize / 2)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'l' : /* fl [<path>] - Directory listing */
|
||||
while (*ptr == ' ') ptr++;
|
||||
res = f_opendir(&Dir, ptr);
|
||||
if (res) { put_rc(res); break; }
|
||||
p1 = s1 = s2 = 0;
|
||||
for(;;) {
|
||||
#if _USE_LFN
|
||||
Finfo.lfname = Lfname;
|
||||
Finfo.lfsize = sizeof(Lfname);
|
||||
#endif
|
||||
res = f_readdir(&Dir, &Finfo);
|
||||
if ((res != FR_OK) || !Finfo.fname[0]) break;
|
||||
if (Finfo.fattrib & AM_DIR) {
|
||||
s2++;
|
||||
} else {
|
||||
s1++; p1 += Finfo.fsize;
|
||||
}
|
||||
xprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s",
|
||||
(Finfo.fattrib & AM_DIR) ? 'D' : '-',
|
||||
(Finfo.fattrib & AM_RDO) ? 'R' : '-',
|
||||
(Finfo.fattrib & AM_HID) ? 'H' : '-',
|
||||
(Finfo.fattrib & AM_SYS) ? 'S' : '-',
|
||||
(Finfo.fattrib & AM_ARC) ? 'A' : '-',
|
||||
(Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15, Finfo.fdate & 31,
|
||||
(Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63,
|
||||
Finfo.fsize, &(Finfo.fname[0]));
|
||||
#if _USE_LFN
|
||||
xprintf(" %s\n", Lfname);
|
||||
#else
|
||||
xputc('\n');
|
||||
#endif
|
||||
}
|
||||
xprintf("%4u File(s),%10lu bytes total\n%4u Dir(s)", s1, p1, s2);
|
||||
if (f_getfree(ptr, (DWORD*)&p1, &fs) == FR_OK)
|
||||
xprintf(", %10lu bytes free\n", p1 * fs->csize * 512);
|
||||
break;
|
||||
|
||||
case 'o' : /* fo <mode> <file> - Open a file */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_open(&File1, ptr, (BYTE)p1));
|
||||
break;
|
||||
|
||||
case 'c' : /* fc - Close a file */
|
||||
put_rc(f_close(&File1));
|
||||
break;
|
||||
|
||||
case 'e' : /* fe - Seek file pointer */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
res = f_lseek(&File1, p1);
|
||||
put_rc(res);
|
||||
if (res == FR_OK)
|
||||
xprintf("fptr=%lu(0x%lX)\n", File1.fptr, File1.fptr);
|
||||
break;
|
||||
|
||||
case 'd' : /* fd <len> - read and dump file from current fp */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
ofs = File1.fptr;
|
||||
while (p1) {
|
||||
if ((UINT)p1 >= 16) { cnt = 16; p1 -= 16; }
|
||||
else { cnt = p1; p1 = 0; }
|
||||
res = f_read(&File1, Buff, cnt, &cnt);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
if (!cnt) break;
|
||||
put_dump(Buff, ofs, cnt);
|
||||
ofs += 16;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r' : /* fr <len> - read file */
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
p2 = 0;
|
||||
Timer = 0;
|
||||
while (p1) {
|
||||
if ((UINT)p1 >= blen) {
|
||||
cnt = blen; p1 -= blen;
|
||||
} else {
|
||||
cnt = p1; p1 = 0;
|
||||
}
|
||||
res = f_read(&File1, Buff, cnt, &s2);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
p2 += s2;
|
||||
if (cnt != s2) break;
|
||||
}
|
||||
xprintf("%lu bytes read with %lu kB/sec.\n", p2, p2 / Timer);
|
||||
break;
|
||||
|
||||
case 'w' : /* fw <len> <val> - write file */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
|
||||
memset(Buff, (BYTE)p2, blen);
|
||||
p2 = 0;
|
||||
Timer = 0;
|
||||
while (p1) {
|
||||
if ((UINT)p1 >= blen) {
|
||||
cnt = blen; p1 -= blen;
|
||||
} else {
|
||||
cnt = p1; p1 = 0;
|
||||
}
|
||||
res = f_write(&File1, Buff, cnt, &s2);
|
||||
if (res != FR_OK) { put_rc(res); break; }
|
||||
p2 += s2;
|
||||
if (cnt != s2) break;
|
||||
}
|
||||
xprintf("%lu bytes written with %lu kB/sec.\n", p2, p2 / Timer);
|
||||
break;
|
||||
|
||||
case 'n' : /* fn <old_name> <new_name> - Change file/dir name */
|
||||
while (*ptr == ' ') ptr++;
|
||||
ptr2 = strchr(ptr, ' ');
|
||||
if (!ptr2) break;
|
||||
*ptr2++ = 0;
|
||||
while (*ptr2 == ' ') ptr2++;
|
||||
put_rc(f_rename(ptr, ptr2));
|
||||
break;
|
||||
|
||||
case 'u' : /* fu <name> - Unlink a file or dir */
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_unlink(ptr));
|
||||
break;
|
||||
|
||||
case 'v' : /* fv - Truncate file */
|
||||
put_rc(f_truncate(&File1));
|
||||
break;
|
||||
|
||||
case 'k' : /* fk <name> - Create a directory */
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_mkdir(ptr));
|
||||
break;
|
||||
|
||||
case 'a' : /* fa <atrr> <mask> <name> - Change file/dir attribute */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
|
||||
while (*ptr == ' ') ptr++;
|
||||
put_rc(f_chmod(ptr, p1, p2));
|
||||
break;
|
||||
|
||||
case 't' : /* ft <year> <month> <day> <hour> <min> <sec> <name> - Change timestamp */
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
Finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31);
|
||||
if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
Finfo.ftime = ((p1 & 31) << 11) | ((p1 & 63) << 5) | ((p1 >> 1) & 31);
|
||||
put_rc(f_utime(ptr, &Finfo));
|
||||
break;
|
||||
|
||||
case 'x' : /* fx <src_name> <dst_name> - Copy file */
|
||||
while (*ptr == ' ') ptr++;
|
||||
ptr2 = strchr(ptr, ' ');
|
||||
if (!ptr2) break;
|
||||
*ptr2++ = 0;
|
||||
while (*ptr2 == ' ') ptr2++;
|
||||
xprintf("Opening \"%s\"", ptr);
|
||||
res = f_open(&File1, ptr, FA_OPEN_EXISTING | FA_READ);
|
||||
xputc('\n');
|
||||
if (res) {
|
||||
put_rc(res);
|
||||
break;
|
||||
}
|
||||
xprintf("Creating \"%s\"", ptr2);
|
||||
res = f_open(&File2, ptr2, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
xputc('\n');
|
||||
if (res) {
|
||||
put_rc(res);
|
||||
f_close(&File1);
|
||||
break;
|
||||
}
|
||||
xprintf("Copying file...");
|
||||
Timer = 0;
|
||||
p1 = 0;
|
||||
for (;;) {
|
||||
res = f_read(&File1, Buff, blen, &s1);
|
||||
if (res || s1 == 0) break; /* error or eof */
|
||||
res = f_write(&File2, Buff, s1, &s2);
|
||||
p1 += s2;
|
||||
if (res || s2 < s1) break; /* error or disk full */
|
||||
}
|
||||
xprintf("%lu bytes copied with %lu kB/sec.\n", p1, p1 / Timer);
|
||||
f_close(&File1);
|
||||
f_close(&File2);
|
||||
break;
|
||||
#if _USE_MKFS
|
||||
case 'm' : /* fm <partition rule> <cluster size> - Create file system */
|
||||
if (!xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break;
|
||||
xprintf("The drive 0 will be formatted. Are you sure? (Y/n)=");
|
||||
get_line(ptr, sizeof(linebuf));
|
||||
if (*ptr == 'Y')
|
||||
put_rc(f_mkfs(0, (BYTE)p2, (WORD)p3));
|
||||
break;
|
||||
#endif
|
||||
case 'z' : /* fz [<rw size>] - Change R/W length for fr/fw/fx command */
|
||||
if (xatoi(&ptr, &p1) && p1 >= 1 && p1 <= sizeof(Buff))
|
||||
blen = p1;
|
||||
xprintf("blen=%u\n", blen);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't' : /* t [<year> <mon> <mday> <hour> <min> <sec>] */
|
||||
if (xatoi(&ptr, &p1)) {
|
||||
rtc.year = (WORD)p1;
|
||||
xatoi(&ptr, &p1); rtc.month = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); rtc.mday = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); rtc.hour = (BYTE)p1;
|
||||
xatoi(&ptr, &p1); rtc.min = (BYTE)p1;
|
||||
if (!xatoi(&ptr, &p1)) break;
|
||||
rtc.sec = (BYTE)p1;
|
||||
rtc_settime(&rtc);
|
||||
}
|
||||
rtc_gettime(&rtc);
|
||||
xprintf("%u/%u/%u %02u:%02u:%02u\n", rtc.year, rtc.month, rtc.mday, rtc.hour, rtc.min, rtc.sec);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
823
tools/ffsample/lpc2k/mci.c
Normal file
823
tools/ffsample/lpc2k/mci.c
Normal file
@@ -0,0 +1,823 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* MMC/SDSC/SDHC (in native mode via MCI) control module (C)ChaN, 2008 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "LPC2300.h"
|
||||
#include "interrupt.h"
|
||||
#include "diskio.h"
|
||||
|
||||
|
||||
/* ----- MMC/SDC command ----- */
|
||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (1) /* SEND_OP_COND (MMC) */
|
||||
#define CMD2 (2) /* ALL_SEND_CID */
|
||||
#define CMD3 (3) /* SEND_RELATIVE_ADDR */
|
||||
#define ACMD6 (6|0x80) /* SET_BUS_WIDTH (SDC) */
|
||||
#define CMD7 (7) /* SELECT_CARD */
|
||||
#define CMD8 (8) /* SEND_IF_COND */
|
||||
#define CMD9 (9) /* SEND_CSD */
|
||||
#define CMD10 (10) /* SEND_CID */
|
||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
||||
#define CMD13 (13) /* SEND_STATUS */
|
||||
#define ACMD13 (13|0x80) /* SD_STATUS (SDC) */
|
||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 (23) /* SET_BLK_COUNT (MMC) */
|
||||
#define ACMD23 (23|0x80) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
||||
#define CMD24 (24) /* WRITE_BLOCK */
|
||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
||||
#define ACMD41 (41|0x80) /* SEND_OP_COND (SDC) */
|
||||
#define CMD55 (55) /* APP_CMD */
|
||||
|
||||
|
||||
/* --- Driver configuration --- */
|
||||
#define N_BUF 4 /* Block transfer FIFO depth (>= 2) */
|
||||
#define USE_4BIT 1 /* Use wide bus mode on SDC */
|
||||
#define PCLK 36000000UL /* PCLK supplied to MCI module */
|
||||
#define MCLK_ID 400000UL /* MCICLK for ID state */
|
||||
#define MCLK_RW 18000000UL /* MCICLK for data transfer */
|
||||
|
||||
/* This MCI driver assumes that MCLK_RW is cclk/4 or slower. */
|
||||
/* If block buffer underrun/overrun is occured due to any interrupt */
|
||||
/* process during read/write operation, increasing N_BUF will solve it. */
|
||||
|
||||
|
||||
/* ----- Port definitions ----- */
|
||||
#define SOCKPORT FIO0PIN1 /* Socket contact port */
|
||||
#define SOCKINS 0x04 /* Card detect switch (bit2) */
|
||||
#define SOCKWP 0 /* Write protect switch (none) */
|
||||
#define LEDR_ON() FIO1SET0 = 0x10 /* Access indicator */
|
||||
#define LEDR_OFF() FIO1CLR0 = 0x10
|
||||
|
||||
|
||||
|
||||
/* These functions are defined in asmfunc.S */
|
||||
void Store_Block (void *sram, const void *uram, int count); /* Copy USB RAM to internal/external/ether RAM. uram must be double-word aligned. */
|
||||
void Load_Block (void *uram, const void *sram, int count); /* Copy interanl/external/ether RAM to USB RAM. uram must be double-word aligned. */
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
static volatile
|
||||
WORD Timer[2]; /* 1000Hz decrement timer for Transaction and Command */
|
||||
|
||||
static
|
||||
BYTE CardType, /* Card type flag */
|
||||
CardInfo[16+16+4]; /* CSD(16), CID(16), OCR(4) */
|
||||
|
||||
static
|
||||
WORD CardRCA; /* Assigned RCA */
|
||||
|
||||
static volatile
|
||||
BYTE XferStat, /* b3:MCI error, b2:Overrun, b1:Write, b0:Read */
|
||||
XferWc, /* Write block counter */
|
||||
XferWp, XferRp; /* R/W index of block FIFO */
|
||||
|
||||
|
||||
/* Block transfer buffer (located in USB RAM) */
|
||||
static
|
||||
DWORD DmaBuff[N_BUF][128] __attribute__ ((section(".usbram"))), /* Block transfer FIFO */
|
||||
LinkList[N_BUF][4] __attribute__ ((section(".usbram"))); /* DMA link list */
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Interrupt service routine for data transfer */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void Isr_MCI (void)
|
||||
{
|
||||
DWORD ms;
|
||||
BYTE n, xs;
|
||||
|
||||
|
||||
ms = MCI_STATUS & 0x073A; /* Clear MCI interrupt status */
|
||||
MCI_CLEAR = ms;
|
||||
|
||||
xs = XferStat;
|
||||
if (ms & 0x400) { /* A block transfer completed (DataBlockEnd) */
|
||||
if (xs & 1) { /* In card read operation */
|
||||
if (ms & 0x100) /* When last block is received (DataEnd), */
|
||||
GPDMA_SOFT_BREQ = 0x10; /* Pop off remaining data in the MCIFIFO */
|
||||
n = (XferWp + 1) % N_BUF; /* Next write buffer */
|
||||
XferWp = n;
|
||||
if (n == XferRp) xs |= 4; /* Check block overrun */
|
||||
}
|
||||
else { /* In card write operation */
|
||||
n = (XferRp + 1) % N_BUF; /* Next read buffer */
|
||||
XferRp = n;
|
||||
if (n == XferWp) xs |= 4; /* Check block underrun */
|
||||
}
|
||||
} else { /* An MCI error occured (not DataBlockEnd) */
|
||||
xs |= 8;
|
||||
}
|
||||
|
||||
XferStat = xs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void Isr_GPDMA (void)
|
||||
{
|
||||
GPDMA_INT_TCCLR = 0x01; /* Clear GPDMA interrupt flag */
|
||||
|
||||
if (XferStat & 2) { /* In write operation */
|
||||
if (--XferWc == N_BUF) /* Terminate LLI */
|
||||
LinkList[XferRp % N_BUF][2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Ready for data reception */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void ready_reception (
|
||||
UINT blks, /* Number of blocks to receive (1..127) */
|
||||
UINT bs /* Block size (64 or 512) */
|
||||
)
|
||||
{
|
||||
UINT n;
|
||||
DWORD dma_ctrl;
|
||||
|
||||
|
||||
/* ------ Setting up GPDMA Ch-0 ------ */
|
||||
|
||||
GPDMA_CH0_CFG &= 0xFFF80420; /* Disable ch-0 */
|
||||
GPDMA_INT_TCCLR = 0x01; /* Clear interrupt flag */
|
||||
dma_ctrl = 0x88492000 | (bs / 4); /* 1_000_1_0_00_010_010_010_010_************ */
|
||||
|
||||
/* Create link list */
|
||||
for (n = 0; n < N_BUF; n++) {
|
||||
LinkList[n][0] = (DWORD)&MCI_FIFO;
|
||||
LinkList[n][1] = (DWORD)DmaBuff[n];
|
||||
LinkList[n][2] = (DWORD)LinkList[(n + 1) % N_BUF];
|
||||
LinkList[n][3] = dma_ctrl;
|
||||
}
|
||||
|
||||
/* Load first LLI */
|
||||
GPDMA_CH0_SRC = LinkList[0][0];
|
||||
GPDMA_CH0_DEST = LinkList[0][1];
|
||||
GPDMA_CH0_LLI = LinkList[0][2];
|
||||
GPDMA_CH0_CTRL = LinkList[0][3];
|
||||
|
||||
/* Enable ch-0 */
|
||||
GPDMA_CH0_CFG |= 0x19009; /* *************_0_0_1_1_0_010_*_0000_*_0100_1 */
|
||||
|
||||
/* --------- Setting up MCI ---------- */
|
||||
|
||||
XferRp = 0; XferWp = 0; /* Block FIFO R/W index */
|
||||
XferStat = 1; /* Transfer status: MCI --> Memory */
|
||||
|
||||
MCI_DATA_LEN = bs * blks; /* Set total data length */
|
||||
MCI_DATA_TMR = (DWORD)(MCLK_RW * 0.1); /* Data timer: 0.1sec */
|
||||
MCI_CLEAR = 0x72A; /* Clear status flags */
|
||||
MCI_MASK0 = 0x72A; /* DataBlockEnd StartBitErr DataEnd RxOverrun DataTimeOut DataCrcFail */
|
||||
for (n = 0; bs > 1; bs >>= 1, n += 0x10);
|
||||
MCI_DATA_CTRL = n | 0xB; /* Start to receive data blocks */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Start to transmit a data block */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
static
|
||||
void start_transmission (
|
||||
BYTE blks /* Number of blocks to be transmitted (1..127) */
|
||||
)
|
||||
{
|
||||
UINT n;
|
||||
DWORD dma_ctrl;
|
||||
|
||||
|
||||
/* ------ Setting up GPDMA Ch-0 ------ */
|
||||
|
||||
GPDMA_CH0_CFG &= 0xFFF80420; /* Disable ch-0 */
|
||||
GPDMA_INT_TCCLR = 0x01; /* Clear interrupt flag */
|
||||
dma_ctrl = 0x84492080; /* 1_000_0_1_00_010_010_010_010_000010000000 */
|
||||
|
||||
/* Create link list */
|
||||
for (n = 0; n < N_BUF; n++) {
|
||||
LinkList[n][0] = (DWORD)DmaBuff[n];
|
||||
LinkList[n][1] = (DWORD)&MCI_FIFO;
|
||||
LinkList[n][2] = (n == blks - 1) ? 0 : (DWORD)LinkList[(n + 1) % N_BUF];
|
||||
LinkList[n][3] = dma_ctrl;
|
||||
}
|
||||
|
||||
/* Load first LLI */
|
||||
GPDMA_CH0_SRC = LinkList[0][0];
|
||||
GPDMA_CH0_DEST = LinkList[0][1];
|
||||
GPDMA_CH0_LLI = LinkList[0][2];
|
||||
GPDMA_CH0_CTRL = LinkList[0][3];
|
||||
|
||||
/* Enable ch-0 */
|
||||
GPDMA_CH0_CFG |= 0x18901; /* *************_0_0_1_1_0_001_*_0100_*_0000_1 */
|
||||
|
||||
/* --------- Setting up MCI ---------- */
|
||||
|
||||
XferRp = 0; /* Block FIFO read index */
|
||||
XferWc = blks;
|
||||
XferStat = 2; /* Transfer status: Memroy --> MCI */
|
||||
|
||||
MCI_DATA_LEN = 512 * (blks + 1); /* Set total data length */
|
||||
MCI_DATA_TMR = (DWORD)(MCLK_RW * 0.5); /* Data timer: 0.5sec */
|
||||
MCI_CLEAR = 0x51A; /* Clear status flags */
|
||||
MCI_MASK0 = 0x51A; /* DataBlockEnd DataEnd TxUnderrun DataTimeOut DataCrcFail */
|
||||
MCI_DATA_CTRL = (9 << 4) | 0x9; /* Start to transmit data blocks */
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Stop data transfer */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void stop_transfer (void)
|
||||
{
|
||||
MCI_MASK0 = 0; /* Disable MCI interrupt */
|
||||
MCI_DATA_CTRL = 0; /* Stop MCI data transfer */
|
||||
|
||||
GPDMA_CH0_CFG &= 0xFFF80420; /* Disable DMA ch-0 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Power Control */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void power_on (void)
|
||||
{
|
||||
/* Enable MCI and GPDMA clock */
|
||||
PCONP |= (3 << 28);
|
||||
|
||||
/* Enable GPDMA controller with little-endian */
|
||||
GPDMA_CH0_CFG &= 0xFFF80000; /* Disable DMA ch-0 */
|
||||
GPDMA_CONFIG = 0x01;
|
||||
|
||||
/* Select PCLK for MCI, CCLK/2 = 36MHz */
|
||||
PCLKSEL1 = (PCLKSEL1 & 0xFCFFFFFF) | 0x02000000;
|
||||
|
||||
/* Attach MCI unit to I/O pad */
|
||||
PINSEL1 = (PINSEL1 & 0xFFFFC03F) | 0x00002A80; /* MCICLK, MCICMD, MCIDATA0, MCIPWR */
|
||||
#if USE_4BIT
|
||||
PINSEL4 = (PINSEL4 & 0xF03FFFFF) | 0x0A800000; /* MCIDATA1-3 */
|
||||
#endif
|
||||
MCI_MASK0 = 0;
|
||||
MCI_COMMAND = 0;
|
||||
MCI_DATA_CTRL = 0;
|
||||
|
||||
/* Interrupt handler for MCI,DMA event */
|
||||
RegisterVector(MCI_INT, Isr_MCI, PRI_LOWEST-1, CLASS_IRQ);
|
||||
RegisterVector(GPDMA_INT, Isr_GPDMA, PRI_LOWEST-1, CLASS_IRQ);
|
||||
|
||||
/* Power-on (VCC is always tied to the socket in this board) */
|
||||
MCI_POWER = 0x01;
|
||||
for (Timer[0] = 10; Timer[0]; );
|
||||
MCI_POWER = 0x03;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void power_off (void)
|
||||
{
|
||||
MCI_MASK0 = 0;
|
||||
MCI_COMMAND = 0;
|
||||
MCI_DATA_CTRL = 0;
|
||||
|
||||
MCI_CLOCK = 0; /* Power-off */
|
||||
MCI_POWER = 0;
|
||||
LEDR_OFF();
|
||||
|
||||
Stat |= STA_NOINIT; /* Set STA_NOINIT */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to the card and receive a response */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BOOL send_cmd ( /* Returns TRUE when function succeeded otherwise returns FALSE */
|
||||
UINT idx, /* Command index (bit[5..0]), ACMD flag (bit7) */
|
||||
DWORD arg, /* Command argument */
|
||||
UINT rt, /* Expected response type. None(0), Short(1) or Long(2) */
|
||||
DWORD *buff /* Response return buffer */
|
||||
)
|
||||
{
|
||||
UINT s, mc;
|
||||
|
||||
|
||||
if (idx & 0x80) { /* Send a CMD55 prior to the specified command if it is ACMD class */
|
||||
if (!send_cmd(CMD55, (DWORD)CardRCA << 16, 1, buff) /* When CMD55 is faild, */
|
||||
|| !(buff[0] & 0x00000020)) return FALSE; /* exit with error */
|
||||
}
|
||||
idx &= 0x3F; /* Mask out ACMD flag */
|
||||
|
||||
do { /* Wait while CmdActive bit is set */
|
||||
MCI_COMMAND = 0; /* Cancel to transmit command */
|
||||
MCI_CLEAR = 0x0C5; /* Clear status flags */
|
||||
for (s = 0; s < 10; s++) MCI_STATUS; /* Skip lock out time of command reg. */
|
||||
} while (MCI_STATUS & 0x00800);
|
||||
|
||||
MCI_ARGUMENT = arg; /* Set the argument into argument register */
|
||||
mc = 0x400 | idx; /* Enable bit + index */
|
||||
if (rt == 1) mc |= 0x040; /* Set Response bit to reveice short resp */
|
||||
if (rt > 1) mc |= 0x0C0; /* Set Response and LongResp bit to receive long resp */
|
||||
MCI_COMMAND = mc; /* Initiate command transaction */
|
||||
|
||||
Timer[1] = 100;
|
||||
for (;;) { /* Wait for end of the cmd/resp transaction */
|
||||
if (!Timer[1]) return FALSE;
|
||||
s = MCI_STATUS; /* Get the transaction status */
|
||||
if (rt == 0) {
|
||||
if (s & 0x080) return TRUE; /* CmdSent */
|
||||
} else {
|
||||
if (s & 0x040) break; /* CmdRespEnd */
|
||||
if (s & 0x001) { /* CmdCrcFail */
|
||||
if (idx == 1 || idx == 12 || idx == 41) /* Ignore CRC error on CMD1/12/41 */
|
||||
break;
|
||||
return FALSE;
|
||||
}
|
||||
if (s & 0x004) return FALSE; /* CmdTimeOut */
|
||||
}
|
||||
}
|
||||
|
||||
buff[0] = MCI_RESP0; /* Read the response words */
|
||||
if (rt == 2) {
|
||||
buff[1] = MCI_RESP1;
|
||||
buff[2] = MCI_RESP2;
|
||||
buff[3] = MCI_RESP3;
|
||||
}
|
||||
|
||||
return TRUE; /* Return with success */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait card ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BOOL wait_ready (void) /* Returns TRUE when card is tran state, otherwise returns FALSE */
|
||||
{
|
||||
DWORD rc;
|
||||
|
||||
|
||||
Timer[0] = 500;
|
||||
while (Timer[0]) {
|
||||
if (send_cmd(CMD13, (DWORD)CardRCA << 16, 1, &rc)
|
||||
&& ((rc & 0x01E00) == 0x00800)) break;
|
||||
}
|
||||
return Timer[0] ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Swap byte order */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void bswap_cp (BYTE *dst, const DWORD *src)
|
||||
{
|
||||
DWORD d;
|
||||
|
||||
|
||||
d = *src;
|
||||
*dst++ = (BYTE)(d >> 24);
|
||||
*dst++ = (BYTE)(d >> 16);
|
||||
*dst++ = (BYTE)(d >> 8);
|
||||
*dst++ = (BYTE)(d >> 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
UINT cmd, n;
|
||||
DWORD resp[4];
|
||||
BYTE ty;
|
||||
|
||||
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
|
||||
|
||||
power_on(); /* Force socket power on */
|
||||
MCI_CLOCK = 0x100 | (PCLK/MCLK_ID/2-1); /* Set MCICLK = MCLK_ID */
|
||||
for (Timer[0] = 2; Timer[0]; );
|
||||
|
||||
LEDR_ON();
|
||||
send_cmd(CMD0, 0, 0, NULL); /* Enter idle state */
|
||||
CardRCA = 0;
|
||||
|
||||
/*---- Card is 'idle' state ----*/
|
||||
|
||||
Timer[0] = 1000; /* Initialization timeout of 1000 msec */
|
||||
if (send_cmd(CMD8, 0x1AA, 1, resp) /* SDC Ver2 */
|
||||
&& (resp[0] & 0xFFF) == 0x1AA) { /* The card can work at vdd range of 2.7-3.6V */
|
||||
do { /* Wait while card is busy state (use ACMD41 with HCS bit) */
|
||||
if (!Timer[0]) goto di_fail;
|
||||
} while (!send_cmd(ACMD41, 0x40FF8000, 1, resp) || !(resp[0] & 0x80000000));
|
||||
ty = (resp[0] & 0x40000000) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Check CCS bit in the OCR */
|
||||
}
|
||||
else { /* SDC Ver1 or MMC */
|
||||
if (send_cmd(ACMD41, 0x00FF8000, 1, resp)) {
|
||||
ty = CT_SD1; cmd = ACMD41; /* ACMD41 is accepted -> SDC Ver1 */
|
||||
} else {
|
||||
ty = CT_MMC; cmd = CMD1; /* ACMD41 is rejected -> MMC */
|
||||
}
|
||||
do { /* Wait while card is busy state (use ACMD41 or CMD1) */
|
||||
if (!Timer[0]) goto di_fail;
|
||||
} while (!send_cmd(cmd, 0x00FF8000, 1, resp) || !(resp[0] & 0x80000000));
|
||||
}
|
||||
|
||||
CardType = ty; /* Save card type */
|
||||
bswap_cp(&CardInfo[32], resp); /* Save OCR */
|
||||
|
||||
/*---- Card is 'ready' state ----*/
|
||||
|
||||
if (!send_cmd(CMD2, 0, 2, resp)) goto di_fail; /* Enter ident state */
|
||||
for (n = 0; n < 4; n++) bswap_cp(&CardInfo[n * 4 + 16], &resp[n]); /* Save CID */
|
||||
|
||||
/*---- Card is 'ident' state ----*/
|
||||
|
||||
if (ty & CT_SDC) { /* SDC: Get generated RCA and save it */
|
||||
if (!send_cmd(CMD3, 0, 1, resp)) goto di_fail;
|
||||
CardRCA = (WORD)(resp[0] >> 16);
|
||||
} else { /* MMC: Assign RCA to the card */
|
||||
if (!send_cmd(CMD3, 1 << 16, 1, resp)) goto di_fail;
|
||||
CardRCA = 1;
|
||||
}
|
||||
|
||||
/*---- Card is 'stby' state ----*/
|
||||
|
||||
if (!send_cmd(CMD9, (DWORD)CardRCA << 16, 2, resp)) /* Get CSD and save it */
|
||||
goto di_fail;
|
||||
for (n = 0; n < 4; n++) bswap_cp(&CardInfo[n * 4], &resp[n]);
|
||||
|
||||
if (!send_cmd(CMD7, (DWORD)CardRCA << 16, 1, resp)) /* Select card */
|
||||
goto di_fail;
|
||||
|
||||
/*---- Card is 'tran' state ----*/
|
||||
|
||||
if (!(ty & CT_BLOCK)) { /* Set data block length to 512 (for byte addressing cards) */
|
||||
if (!send_cmd(CMD16, 512, 1, resp) || (resp[0] & 0xFDF90000))
|
||||
goto di_fail;
|
||||
}
|
||||
|
||||
#if USE_4BIT
|
||||
if (ty & CT_SDC) { /* Set wide bus mode (for SDCs) */
|
||||
if (!send_cmd(ACMD6, 2, 1, resp) /* Set bus mode of SDC */
|
||||
|| (resp[0] & 0xFDF90000))
|
||||
goto di_fail;
|
||||
MCI_CLOCK |= 0x800; /* Set bus mode of MCI */
|
||||
}
|
||||
#endif
|
||||
|
||||
MCI_CLOCK = (MCI_CLOCK & 0xF00) | 0x200 | (PCLK/MCLK_RW/2-1); /* Set MCICLK = MCLK_RW, power-save mode */
|
||||
|
||||
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
|
||||
LEDR_OFF();
|
||||
return Stat;
|
||||
|
||||
di_fail:
|
||||
power_off();
|
||||
Stat |= STA_NOINIT; /* Set STA_NOINIT */
|
||||
LEDR_OFF();
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only single drive */
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
BYTE count /* Sector count (1..127) */
|
||||
)
|
||||
{
|
||||
DWORD resp;
|
||||
UINT cmd;
|
||||
BYTE rp;
|
||||
|
||||
|
||||
if (drv != 0 || count < 1 || count > 127) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert LBA to byte address if needed */
|
||||
if (!wait_ready()) return RES_ERROR; /* Make sure that card is tran state */
|
||||
|
||||
LEDR_ON();
|
||||
|
||||
ready_reception(count, 512); /* Ready to receive data blocks */
|
||||
cmd = (count > 1) ? CMD18 : CMD17; /* Transfer type: Single block or Multiple block */
|
||||
if (send_cmd(cmd, sector, 1, &resp) /* Start to read */
|
||||
&& !(resp & 0xC0580000)) {
|
||||
rp = 0;
|
||||
do {
|
||||
while ((rp == XferWp) && !(XferStat & 0xC)); /* Wait for block arrival */
|
||||
if (XferStat & 0xC) break; /* Abort if any error has occured */
|
||||
Store_Block(buff, DmaBuff[rp], 512);/* Pop an block */
|
||||
XferRp = rp = (rp + 1) % N_BUF; /* Next DMA buffer */
|
||||
if (XferStat & 0xC) break; /* Abort if overrun has occured */
|
||||
buff += 512; /* Next user buffer address */
|
||||
} while (--count);
|
||||
if (cmd == CMD18) /* Terminate to read (MB) */
|
||||
send_cmd(CMD12, 0, 1, &resp);
|
||||
}
|
||||
stop_transfer(); /* Close data path */
|
||||
|
||||
LEDR_OFF();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Pointer to the data to be written */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
BYTE count /* Sector count (1..127) */
|
||||
)
|
||||
{
|
||||
DWORD rc;
|
||||
UINT cmd;
|
||||
BYTE wp, xc;
|
||||
|
||||
if (drv != 0 || count < 1 || count > 127) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
|
||||
if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protection */
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert LBA to byte address if needed */
|
||||
if (!wait_ready()) return RES_ERROR; /* Make sure that card is tran state */
|
||||
|
||||
LEDR_ON();
|
||||
|
||||
if (count == 1) { /* Single block write */
|
||||
cmd = CMD24;
|
||||
} else { /* Multiple block write */
|
||||
cmd = (CardType & CT_SDC) ? ACMD23 : CMD23;
|
||||
if (!send_cmd(cmd, count, 1, &rc) /* Preset number of blocks to write */
|
||||
|| (rc & 0xC0580000)) {
|
||||
LEDR_OFF();
|
||||
return RES_ERROR;
|
||||
}
|
||||
cmd = CMD25;
|
||||
}
|
||||
|
||||
if (!send_cmd(cmd, sector, 1, &rc) /* Send a write command */
|
||||
|| (rc & 0xC0580000)) {
|
||||
LEDR_OFF();
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
wp = 0; xc = count;
|
||||
do { /* Fill block FIFO */
|
||||
Load_Block(DmaBuff[wp], (BYTE*)(UINT)buff, 512); /* Push a block */
|
||||
wp++; /* Next DMA buffer */
|
||||
count--; buff += 512; /* Next user buffer address */
|
||||
} while (count && wp < N_BUF);
|
||||
XferWp = wp = wp % N_BUF;
|
||||
start_transmission(xc); /* Start transmission */
|
||||
|
||||
while (count) {
|
||||
while((wp == XferRp) && !(XferStat & 0xC)); /* Wait for block FIFO not full */
|
||||
if (XferStat & 0xC) break; /* Abort if block underrun or any MCI error has occured */
|
||||
Load_Block(DmaBuff[wp], (BYTE*)(UINT)buff, 512); /* Push a block */
|
||||
XferWp = wp = (wp + 1) % N_BUF; /* Next DMA buffer */
|
||||
if (XferStat & 0xC) break; /* Abort if block underrun has occured */
|
||||
count--; buff += 512; /* Next user buffer address */
|
||||
}
|
||||
|
||||
while (!(XferStat & 0xC)); /* Wait for all blocks sent (block underrun) */
|
||||
if (XferStat & 0x8) count = 1; /* Abort if any MCI error has occured */
|
||||
|
||||
stop_transfer(); /* Close data path */
|
||||
if (cmd == CMD25 && (CardType & CT_SDC)) /* Terminate to write (SDC w/MB) */
|
||||
send_cmd(CMD12, 0, 1, &rc);
|
||||
|
||||
LEDR_OFF();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive data block */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
BYTE n, *p, *ptr = buff;
|
||||
DWORD csize, resp[4];
|
||||
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
res = RES_ERROR;
|
||||
|
||||
switch (ctrl) {
|
||||
case CTRL_SYNC : /* Make sure that all data has been written on the media */
|
||||
if (wait_ready()) /* Wait for card enters tarn state */
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
p = &CardInfo[0];
|
||||
if ((p[0] >> 6) == 1) { /* SDC ver 2.00 */
|
||||
csize = p[9] + ((WORD)p[8] << 8) + 1;
|
||||
*(DWORD*)buff = (DWORD)csize << 10;
|
||||
} else { /* MMC or SDC ver 1.XX */
|
||||
n = (p[5] & 15) + ((p[10] & 128) >> 7) + ((p[9] & 3) << 1) + 2;
|
||||
csize = (p[8] >> 6) + ((WORD)p[7] << 2) + ((WORD)(p[6] & 3) << 10) + 1;
|
||||
*(DWORD*)buff = (DWORD)csize << (n - 9);
|
||||
}
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
|
||||
*(WORD*)buff = 512;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sectors (DWORD) */
|
||||
if (CardType & CT_SD2) { /* SDC ver 2.00 */
|
||||
p = (BYTE*)DmaBuff[1];
|
||||
if (disk_ioctl(drv, MMC_GET_SDSTAT, p) == RES_OK) {
|
||||
*(DWORD*)buff = 16UL << (p[10] >> 4);
|
||||
res = RES_OK;
|
||||
}
|
||||
} else { /* SDC ver 1.XX or MMC */
|
||||
p = &CardInfo[0];
|
||||
if (CardType & CT_SD1) /* SDC v1 */
|
||||
*(DWORD*)buff = (((p[10] & 63) << 1) + ((WORD)(p[11] & 128) >> 7) + 1) << ((p[13] >> 6) - 1);
|
||||
else /* MMC */
|
||||
*(DWORD*)buff = ((WORD)((p[10] & 124) >> 2) + 1) * (((p[11] & 3) << 3) + ((p[11] & 224) >> 5) + 1);
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case MMC_GET_TYPE : /* Get card type flags (1 byte) */
|
||||
*ptr = CardType;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CSD : /* Get CSD as a data block (16 bytes) */
|
||||
memcpy(buff, &CardInfo[0], 16);
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CID : /* Get CID as a data block (16 bytes) */
|
||||
memcpy(buff, &CardInfo[16], 16);
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_OCR : /* Get OCR (4 bytes) */
|
||||
memcpy(buff, &CardInfo[32], 4);
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */
|
||||
if (CardType & CT_SDC) { /* SDC */
|
||||
if (wait_ready()) {
|
||||
ready_reception(1, 64); /* Ready to receive data blocks */
|
||||
if (send_cmd(ACMD13, 0, 1, resp) /* Start to read */
|
||||
&& !(resp[0] & 0xC0580000)) {
|
||||
while ((XferWp == 0) && !(XferStat & 0xC));
|
||||
if (!(XferStat & 0xC)) {
|
||||
Store_Block(buff, DmaBuff[0], 64);
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
stop_transfer(); /* Close data path */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Device Timer Interrupt Procedure (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This function must be called in period of 1ms */
|
||||
|
||||
void disk_timerproc (void)
|
||||
{
|
||||
static BYTE pv;
|
||||
BYTE s, p;
|
||||
WORD n;
|
||||
|
||||
|
||||
/* 1000Hz decrement timers */
|
||||
if ((n = Timer[0]) > 0) Timer[0] = --n;
|
||||
if ((n = Timer[1]) > 0) Timer[1] = --n;
|
||||
|
||||
p = pv;
|
||||
pv = SOCKPORT & (SOCKINS | SOCKWP); /* Sample socket switch */
|
||||
|
||||
if (p == pv) { /* Contact stabled? */
|
||||
s = Stat;
|
||||
|
||||
if (pv & SOCKWP) /* WP is H (write protected) */
|
||||
s |= STA_PROTECT;
|
||||
else /* WP is L (write enabled) */
|
||||
s &= ~STA_PROTECT;
|
||||
|
||||
if (p & SOCKINS) /* INS = H (Socket empty) */
|
||||
s |= (STA_NODISK | STA_NOINIT);
|
||||
else /* INS = L (Card inserted) */
|
||||
s &= ~STA_NODISK;
|
||||
|
||||
Stat = s;
|
||||
}
|
||||
}
|
||||
|
||||
214
tools/ffsample/lpc2k/monitor.c
Normal file
214
tools/ffsample/lpc2k/monitor.c
Normal file
@@ -0,0 +1,214 @@
|
||||
#include <stdarg.h>
|
||||
#include "monitor.h"
|
||||
|
||||
|
||||
|
||||
int xatoi (char **str, long *res)
|
||||
{
|
||||
DWORD val;
|
||||
BYTE c, radix, s = 0;
|
||||
|
||||
|
||||
while ((c = **str) == ' ') (*str)++;
|
||||
if (c == '-') {
|
||||
s = 1;
|
||||
c = *(++(*str));
|
||||
}
|
||||
if (c == '0') {
|
||||
c = *(++(*str));
|
||||
if (c <= ' ') {
|
||||
*res = 0; return 1;
|
||||
}
|
||||
if (c == 'x') {
|
||||
radix = 16;
|
||||
c = *(++(*str));
|
||||
} else {
|
||||
if (c == 'b') {
|
||||
radix = 2;
|
||||
c = *(++(*str));
|
||||
} else {
|
||||
if ((c >= '0')&&(c <= '9'))
|
||||
radix = 8;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((c < '1')||(c > '9'))
|
||||
return 0;
|
||||
radix = 10;
|
||||
}
|
||||
val = 0;
|
||||
while (c > ' ') {
|
||||
if (c >= 'a') c -= 0x20;
|
||||
c -= '0';
|
||||
if (c >= 17) {
|
||||
c -= 7;
|
||||
if (c <= 9) return 0;
|
||||
}
|
||||
if (c >= radix) return 0;
|
||||
val = val * radix + c;
|
||||
c = *(++(*str));
|
||||
}
|
||||
if (s) val = -val;
|
||||
*res = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void xputc (char c)
|
||||
{
|
||||
if (c == '\n') uart0_put('\r');
|
||||
uart0_put(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void xputs (const char* str)
|
||||
{
|
||||
while (*str)
|
||||
xputc(*str++);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void xitoa (long val, int radix, int len)
|
||||
{
|
||||
BYTE c, r, sgn = 0, pad = ' ';
|
||||
BYTE s[20], i = 0;
|
||||
DWORD v;
|
||||
|
||||
|
||||
if (radix < 0) {
|
||||
radix = -radix;
|
||||
if (val < 0) {
|
||||
val = -val;
|
||||
sgn = '-';
|
||||
}
|
||||
}
|
||||
v = val;
|
||||
r = radix;
|
||||
if (len < 0) {
|
||||
len = -len;
|
||||
pad = '0';
|
||||
}
|
||||
if (len > 20) return;
|
||||
do {
|
||||
c = (BYTE)(v % r);
|
||||
if (c >= 10) c += 7;
|
||||
c += '0';
|
||||
s[i++] = c;
|
||||
v /= r;
|
||||
} while (v);
|
||||
if (sgn) s[i++] = sgn;
|
||||
while (i < len)
|
||||
s[i++] = pad;
|
||||
do
|
||||
xputc(s[--i]);
|
||||
while (i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void xprintf (const char* str, ...)
|
||||
{
|
||||
va_list arp;
|
||||
int d, r, w, s, l;
|
||||
|
||||
|
||||
va_start(arp, str);
|
||||
|
||||
while ((d = *str++) != 0) {
|
||||
if (d != '%') {
|
||||
xputc(d); continue;
|
||||
}
|
||||
d = *str++; w = r = s = l = 0;
|
||||
if (d == '0') {
|
||||
d = *str++; s = 1;
|
||||
}
|
||||
while ((d >= '0')&&(d <= '9')) {
|
||||
w += w * 10 + (d - '0');
|
||||
d = *str++;
|
||||
}
|
||||
if (s) w = -w;
|
||||
if (d == 'l') {
|
||||
l = 1;
|
||||
d = *str++;
|
||||
}
|
||||
if (!d) break;
|
||||
if (d == 's') {
|
||||
xputs(va_arg(arp, char*));
|
||||
continue;
|
||||
}
|
||||
if (d == 'c') {
|
||||
xputc((char)va_arg(arp, int));
|
||||
continue;
|
||||
}
|
||||
if (d == 'u') r = 10;
|
||||
if (d == 'd') r = -10;
|
||||
if (d == 'X') r = 16;
|
||||
if (d == 'b') r = 2;
|
||||
if (!r) break;
|
||||
if (l) {
|
||||
xitoa((long)va_arg(arp, long), r, w);
|
||||
} else {
|
||||
if (r > 0)
|
||||
xitoa((unsigned long)va_arg(arp, int), r, w);
|
||||
else
|
||||
xitoa((long)va_arg(arp, int), r, w);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(arp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void put_dump (const BYTE *buff, DWORD ofs, int cnt)
|
||||
{
|
||||
BYTE n;
|
||||
|
||||
|
||||
xprintf("%08lX ", ofs);
|
||||
for(n = 0; n < cnt; n++)
|
||||
xprintf(" %02X", buff[n]);
|
||||
xputc(' ');
|
||||
for(n = 0; n < cnt; n++) {
|
||||
if ((buff[n] < 0x20)||(buff[n] >= 0x7F))
|
||||
xputc('.');
|
||||
else
|
||||
xputc(buff[n]);
|
||||
}
|
||||
xputc('\n');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void get_line (char *buff, int len)
|
||||
{
|
||||
char c;
|
||||
int idx = 0;
|
||||
|
||||
|
||||
for (;;) {
|
||||
c = xgetc();
|
||||
if (c == '\r') break;
|
||||
if ((c == '\b') && idx) {
|
||||
idx--; xputc(c);
|
||||
}
|
||||
if (((BYTE)c >= ' ') && (idx < len - 1)) {
|
||||
buff[idx++] = c; xputc(c);
|
||||
}
|
||||
}
|
||||
buff[idx] = 0;
|
||||
xputc('\n');
|
||||
}
|
||||
|
||||
|
||||
12
tools/ffsample/lpc2k/monitor.h
Normal file
12
tools/ffsample/lpc2k/monitor.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "integer.h"
|
||||
#include "comm.h"
|
||||
#define xgetc() (char)uart0_get()
|
||||
|
||||
int xatoi (char**, long*);
|
||||
void xputc (char);
|
||||
void xputs (const char*);
|
||||
void xitoa (long, int, int);
|
||||
void xprintf (const char*, ...);
|
||||
void put_dump (const BYTE*, DWORD ofs, int cnt);
|
||||
void get_line (char*, int len);
|
||||
|
||||
53
tools/ffsample/lpc2k/rtc.c
Normal file
53
tools/ffsample/lpc2k/rtc.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RTC controls */
|
||||
|
||||
#include "LPC2300.h"
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
|
||||
BOOL rtc_gettime (RTC *rtc)
|
||||
{
|
||||
DWORD d, t;
|
||||
|
||||
|
||||
do {
|
||||
t = RTC_CTIME0;
|
||||
d = RTC_CTIME1;
|
||||
} while (t != RTC_CTIME0 || d != RTC_CTIME1);
|
||||
|
||||
rtc->sec = t & 63;
|
||||
rtc->min = (t >> 8) & 63;
|
||||
rtc->hour = (t >> 16) & 31;
|
||||
rtc->wday = (t >> 24) & 7;
|
||||
rtc->mday = d & 31;
|
||||
rtc->month = (d >> 8) & 15;
|
||||
rtc->year = (d >> 16) & 4095;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL rtc_settime (const RTC *rtc)
|
||||
{
|
||||
/* Stop RTC */
|
||||
RTC_CCR = 0x12;
|
||||
|
||||
/* Update RTC registers */
|
||||
RTC_SEC = rtc->sec;
|
||||
RTC_MIN = rtc->min;
|
||||
RTC_HOUR = rtc->hour;
|
||||
RTC_DOW = rtc->wday;
|
||||
RTC_DOM = rtc->mday;
|
||||
RTC_MONTH = rtc->month;
|
||||
RTC_YEAR = rtc->year;
|
||||
|
||||
/* Start RTC with external XTAL */
|
||||
RTC_CCR = 0x11;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
15
tools/ffsample/lpc2k/rtc.h
Normal file
15
tools/ffsample/lpc2k/rtc.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "integer.h"
|
||||
|
||||
typedef struct {
|
||||
WORD year; /* 1..4095 */
|
||||
BYTE month; /* 1..12 */
|
||||
BYTE mday; /* 1.. 31 */
|
||||
BYTE wday; /* 1..7 */
|
||||
BYTE hour; /* 0..23 */
|
||||
BYTE min; /* 0..59 */
|
||||
BYTE sec; /* 0..59 */
|
||||
} RTC;
|
||||
|
||||
BOOL rtc_gettime (RTC*); /* Get time */
|
||||
BOOL rtc_settime (const RTC*); /* Set time */
|
||||
|
||||
3784
tools/ffsample/lpc2k/unicode/cc932.c
Normal file
3784
tools/ffsample/lpc2k/unicode/cc932.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user