]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
Integrate fatfs. Add some sd card test commands.
authorLeo C <erbl259-lmu@yahoo.de>
Sat, 22 Nov 2014 12:07:04 +0000 (13:07 +0100)
committerLeo C <erbl259-lmu@yahoo.de>
Sat, 22 Nov 2014 12:07:04 +0000 (13:07 +0100)
12 files changed:
avr/cmd_sd.c [new file with mode: 0644]
avr/command_tbl.c
avr/main.c
avr/mmc.c [new file with mode: 0644]
avr/timer.c
fatfs/src/diskio.h [deleted file]
fatfs/src/ffconf.h
include/avr/ffconf.h [new file with mode: 0644]
include/diskio.h [new file with mode: 0644]
include/ff.h [new file with mode: 0644]
include/integer.h [moved from fatfs/src/integer.h with 51% similarity]
include/spi.h [new file with mode: 0644]

diff --git a/avr/cmd_sd.c b/avr/cmd_sd.c
new file mode 100644 (file)
index 0000000..55acf2f
--- /dev/null
@@ -0,0 +1,289 @@
+#include "common.h"
+#include <stdlib.h>
+
+#include "diskio.h"
+#include "ff.h"
+#include "command.h"
+#include "print-utils.h"
+
+
+static const FLASH char * const FLASH rc_names[] = {
+                       FSTR("OK"),
+                       FSTR("DISK_ERR"),
+                       FSTR("INT_ERR"),
+                       FSTR("NOT_READY"),
+                       FSTR("NO_FILE"),
+                       FSTR("NO_PATH"),
+                       FSTR("INVALID_NAME"),
+                       FSTR("DENIED"),
+                       FSTR("EXIST"),
+                       FSTR("INVALID_OBJECT"),
+                       FSTR("WRITE_PROTECTED"),
+                       FSTR("INVALID_DRIVE"),
+                       FSTR("NOT_ENABLED"),
+                       FSTR("NO_FILE_SYSTEM"),
+                       FSTR("MKFS_ABORTED"),
+                       FSTR("TIMEOUT"),
+                       FSTR("LOCKED"),
+                       FSTR("NOT_ENOUGH_CORE"),
+                       FSTR("TOO_MANY_OPEN_FILES")
+               };
+
+static
+void put_rc (FRESULT rc)
+{
+#if 0
+       printf_P(PSTR("rc=%u FR_%S\n"), rc, rc_names[rc]);
+#else
+       printf_P(PSTR("rc=%u FR_"), rc);
+       my_puts_P(rc_names[rc]);
+       printf_P(PSTR("\n"));
+
+#endif
+
+}
+
+#define BUFF_SIZE      1024
+BYTE Buff[BUFF_SIZE];                  /* Working buffer */
+
+static         DWORD last_sect;
+
+
+/*
+ * dd <pd#> [<sector>] - Dump sector
+ *
+ */
+command_ret_t do_dd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       FRESULT res;
+       BYTE dev;
+       unsigned long sec;
+
+       (void) cmdtp; (void) flag;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       dev = (BYTE) strtoul(argv[1], 0, 10);
+
+       if (argc > 2)
+               sec = strtoul(argv[2], 0, 10);
+       else
+               sec = last_sect;
+
+       res = disk_read(dev, Buff, sec, 1);
+
+       if (res) {
+               printf_P(PSTR("rc=%.2x\n"), res);
+               return CMD_RET_FAILURE;
+       }
+
+       last_sect = sec + 1;
+       printf_P(PSTR("Sector:%lu\n"), sec);
+       dump_ram((uint32_t) (size_t) Buff, 0, 0x200, NULL);
+
+       return CMD_RET_SUCCESS;
+}
+
+/*
+ * di <pd#> - Initialize disk
+ *
+ */
+command_ret_t do_di(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       FRESULT res;
+       BYTE dev;
+
+       (void) cmdtp; (void) flag;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       dev = (BYTE) strtoul(argv[1], 0, 10);
+       res = disk_status(dev);
+       printf_P(PSTR("disk_status=%.2x\n"), res);
+
+       if ((res & STA_NODISK) == 0) {
+               res = disk_initialize(dev);
+       }
+       printf_P(PSTR("rc=%.2x\n"), res);
+       if (res) {
+               return CMD_RET_FAILURE;
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+/*
+ * ds <pd#> - Show disk status
+ *
+ */
+command_ret_t do_ds(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       BYTE dev;
+
+       union {
+               unsigned long lval;
+               unsigned char cval;
+       } dat;
+
+       (void) cmdtp; (void) flag;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       dev = (BYTE) strtoul(argv[1], 0, 10);
+
+
+       if (disk_ioctl(dev, GET_SECTOR_COUNT, &dat.lval) == RES_OK)
+               printf_P(PSTR("Drive size: %lu sectors\n"), dat.lval);
+
+       if (disk_ioctl(dev, GET_BLOCK_SIZE, &dat.lval) == RES_OK)
+               printf_P(PSTR("Erase block: %lu sectors\n"), dat.lval);
+
+       if (disk_ioctl(dev, MMC_GET_TYPE, &dat.cval) == RES_OK)
+               printf_P(PSTR("Card type: %u\n"), dat.cval);
+
+       if (disk_ioctl(dev, MMC_GET_CSD, Buff) == RES_OK)
+               dump_ram((uint32_t) (size_t) Buff, 0, 16, "CSD:");
+
+       if (disk_ioctl(dev, MMC_GET_CID, Buff) == RES_OK)
+               dump_ram((uint32_t) (size_t) Buff, 0, 16, "CID:");
+
+       if (disk_ioctl(dev, MMC_GET_OCR, Buff) == RES_OK)
+               dump_ram((uint32_t) (size_t) Buff, 0, 4, "OCR:");
+
+       if (disk_ioctl(dev, MMC_GET_SDSTAT, Buff) == RES_OK)
+               dump_ram((uint32_t) (size_t) Buff, 0, 64, "SD Status:");
+
+       if (disk_ioctl(dev, ATA_GET_MODEL, Buff) == RES_OK) {
+               Buff[40] = '\0';
+               printf_P(PSTR("Model: %s\n"), Buff);
+       }
+       if (disk_ioctl(dev, ATA_GET_SN, Buff) == RES_OK) {
+               Buff[20] = '\0'; printf_P(PSTR("S/N: %s\n"), Buff);
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+
+
+/*
+ * Disk ioctl
+ * dcs <pd#> - CTRL_SYNC
+ *
+ */
+command_ret_t do_dcs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       BYTE dev;
+
+       (void) cmdtp; (void) flag;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       dev = (BYTE) strtoul(argv[1], 0, 10);
+       printf_P(PSTR("rc=%.2x\n"), disk_ioctl(dev, CTRL_SYNC, 0));
+
+       return CMD_RET_SUCCESS;
+}
+
+
+
+command_ret_t do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       (void) cmdtp; (void) flag;
+       (void) argc; (void) argv;
+
+       printf_P(_USE_LFN ? PSTR("LFN Enabled") : PSTR("LFN Disabled"));
+       printf_P(PSTR(", Code page: %u\n"), _CODE_PAGE);
+
+       for (FRESULT i=0; i<19; i++)
+               put_rc(i);
+
+
+       return CMD_RET_SUCCESS;
+}
+
+extern command_ret_t do_echo(cmd_tbl_t *, int, int, char * const []);
+
+
+static
+command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+cmd_tbl_t cmd_sd_sub[] = {
+CMD_TBL_ITEM(
+       dd,     CONFIG_SYS_MAXARGS,     1,      do_dd,
+       "Dump sector",
+       ""
+),
+CMD_TBL_ITEM(
+       di,     2,                      1,      do_di,
+       "Initialize disk",
+       ""
+),
+CMD_TBL_ITEM(
+       ds,     2,                      1,      do_ds,
+       "Disk status",
+       ""
+),
+CMD_TBL_ITEM(
+       dcs,    2,                      1,      do_dcs,
+       "Device control: SYNC",
+       ""
+),
+CMD_TBL_ITEM(
+       echo,   CONFIG_SYS_MAXARGS,     1,      do_echo,
+       "sane as echo (simple test)", ""
+),
+CMD_TBL_ITEM(
+       test,   CONFIG_SYS_MAXARGS,     1,      do_test,
+       "print some compiled in parameters", ""
+),
+CMD_TBL_ITEM(
+       help,   CONFIG_SYS_MAXARGS,     1,      do_help,
+       "print sub command description/usage",
+       "\n"
+       "       - print brief description of all sub commands\n"
+       "sd help command ...\n"
+       "       - print detailed usage of sub cmd 'command'"
+),
+
+/* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
+       {FSTR("?"),   CONFIG_SYS_MAXARGS, 1, do_help,
+        FSTR("alias for 'help'"),
+#ifdef  CONFIG_SYS_LONGHELP
+       FSTR(""),
+#endif /* CONFIG_SYS_LONGHELP */
+#ifdef CONFIG_AUTO_COMPLETE
+       0,
+#endif
+},
+};
+
+static
+command_ret_t do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       return _do_help(cmd_sd_sub, ARRAY_SIZE(cmd_sd_sub), cmdtp, flag, argc, argv);
+}
+
+
+command_ret_t do_sd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       cmd_tbl_t *cp;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       /* drop initial "sd" arg */
+       argc--;
+       argv++;
+
+       cp = find_cmd_tbl(argv[0], cmd_sd_sub, ARRAY_SIZE(cmd_sd_sub));
+
+       if (cp)
+               return cp->cmd(cmdtp, flag, argc, argv);
+
+       return CMD_RET_USAGE;
+}
index 97110fd4f4649f6f651734a4524cb8cae026114b..6b53fad26353361d08d787d0ae13e780fca2c903 100644 (file)
@@ -231,6 +231,13 @@ CMD_TBL_ITEM(
 ),
 #endif /* CONFIG_MX_CYCLIC */
 
+CMD_TBL_ITEM(
+       sd,   CONFIG_SYS_MAXARGS, 1, do_sd,
+       "SD/MMC card handling commands",
+       "<subcommand> args ...\n"
+       "sd help\n"
+       "    - print help on subcommands"
+),
 
 CMD_TBL_ITEM(
        help,   CONFIG_SYS_MAXARGS,     1,      do_help,
@@ -241,17 +248,6 @@ CMD_TBL_ITEM(
        "       - print detailed usage of 'command'"
 ),
 
-/* TODO: make macro CMD_TBL_ITEM work with this */
-       {FSTR("sd"),   CONFIG_SYS_MAXARGS, 1, do_sd,
-        FSTR("SD/MMC card handling commands"),
-#ifdef  CONFIG_SYS_LONGHELP
-       sd_help_text,
-#endif /* CONFIG_SYS_LONGHELP */
-#ifdef CONFIG_AUTO_COMPLETE
-       0,
-#endif
-},
-
 /* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
        {FSTR("?"),   CONFIG_SYS_MAXARGS, 1, do_help,
         FSTR("alias for 'help'"),
index 2f9a62f284094ac87e76d74db8dda13c0891f508..af082a3d9c8cb8a6d3d4ede5d3c602e4f00afa68 100644 (file)
@@ -18,6 +18,7 @@
 #include "cli.h"
 #include "env.h"
 #include "z180-serv.h"
+#include "spi.h"
 
 static uint8_t mcusr;
 
@@ -108,8 +109,15 @@ void setup_avr(void)
        TCCR3B = (0b01<<WGM32)|(0b001<<CS30); /* CTC Mode, Prescaler 1 */
        TIMSK3 = _BV(OCIE3A);           /* Enable TC2.oca interrupt */
 
+       /* SPI as master */
+       PRR0 &= ~_BV(PRSPI);
+       SPI_DDR = (SPI_DDR & ~_BV(SPI_MISO))
+                       | _BV(SPI_MOSI) | _BV(SPI_SCK) | _BV(SPI_SS);
+       SPI_PORT = (SPI_PORT & ~(_BV(SPI_MOSI) | _BV(SPI_SCK)))
+                       | _BV(SPI_SS);
+
        /* INT5, INT6: falling edge */
-       EICRB = (EICRB & ~((0b11 << ISC50) | (0b11 << ISC60))) | 
+       EICRB = (EICRB & ~((0b11 << ISC50) | (0b11 << ISC60))) |
                (0b10 << ISC50) | (0b10 << ISC60);
        /* Reset pending ints */
        EIFR |= _BV(INTF5) | _BV(INTF6);
@@ -219,7 +227,6 @@ void main_loop(void)
 
 int main(void)
 {
-
        setup_avr();
        z80_setup_bus();
 
diff --git a/avr/mmc.c b/avr/mmc.c
new file mode 100644 (file)
index 0000000..eb10ea6
--- /dev/null
+++ b/avr/mmc.c
@@ -0,0 +1,637 @@
+/*-----------------------------------------------------------------------*/
+/* MMCv3/SDv1/SDv2 (in SPI mode) control module  (C)ChaN, 2007             */
+/*-----------------------------------------------------------------------*/
+/* Only spi_rcvr(), spi_xmit(), disk_timerproc() and some macros         */
+/* are platform dependent.                                               */
+/*-----------------------------------------------------------------------*/
+
+#include <avr/io.h>
+#include <stdbool.h>
+#include "timer.h"
+#include "spi.h"
+#include "diskio.h"
+#include "debug.h"
+#include "print-utils.h"
+
+
+/* Definitions for MMC/SDC command */
+#define CMD0   (0)                     /* GO_IDLE_STATE */
+#define CMD1   (1)                     /* SEND_OP_COND (MMC) */
+#define        ACMD41  (0x80+41)       /* SEND_OP_COND (SDC) */
+#define CMD8   (8)                     /* SEND_IF_COND */
+#define CMD9   (9)                     /* SEND_CSD */
+#define CMD10  (10)            /* SEND_CID */
+#define CMD12  (12)            /* STOP_TRANSMISSION */
+#define ACMD13 (0x80+13)       /* SD_STATUS (SDC) */
+#define CMD16  (16)            /* SET_BLOCKLEN */
+#define CMD17  (17)            /* READ_SINGLE_BLOCK */
+#define CMD18  (18)            /* READ_MULTIPLE_BLOCK */
+#define CMD23  (23)            /* SET_BLOCK_COUNT (MMC) */
+#define        ACMD23  (0x80+23)       /* SET_WR_BLK_ERASE_COUNT (SDC) */
+#define CMD24  (24)            /* WRITE_BLOCK */
+#define CMD25  (25)            /* WRITE_MULTIPLE_BLOCK */
+#define CMD55  (55)            /* APP_CMD */
+#define CMD58  (58)            /* READ_OCR */
+
+
+/* SD card socket connections */
+#if 0
+//#define MMC_PORT             PORTG           /* Socket contact port */
+//#define MMC_INPORT           PING
+//#define SD_WP_PIN            5                       /* Write protect switch */
+#endif
+
+/* SD card SPI access */
+#define SD_CD_PORT             PORTG
+#define SD_CD_DDR              DDRG
+#define SD_CD_INPORT           PING
+#define SD_CD_PIN              3                       /* Card detect switch */
+
+#define SD_WP_PORT             PORTG
+#define SD_WP_DDR              DDRG
+#define SD_WP_INPORT           PING
+//#define SD_WP_PIN            5                       /* Write protect switch */
+
+#define SD_CS_PORT             PORTG
+#define SD_CS_DDR              DDRG
+#define SD_CS_PIN              4                       /* Chip select pin */
+
+
+/* Port Controls  (Platform dependent) */
+
+#ifdef SD_CD_PIN
+static inline
+bool sd_cd(void)
+{
+       return (SD_CD_INPORT & _BV(SD_CD_PIN)) == 0;
+}
+#endif
+
+#ifdef SD_WP_PIN
+static inline
+bool sd_wp(void)
+{
+       return (SD_WP_INPORT & _BV(SD_WP_PIN)) == 0;
+}
+#endif
+
+#define CS_LOW()       SD_CS_PORT &= ~(1<<SD_CS_PIN)   /* MMC CS = L */
+#define CS_HIGH()      SD_CS_PORT |=  (1<<SD_CS_PIN)   /* MMC CS = H */
+
+#define        FCLK_SLOW()     SPISetMMCInitClock() /* Set slow clock (100k-400k) */
+#define        FCLK_FAST()     SPISetFastClock()        /* Set fast clock (depends on the CSD) */
+
+/*--------------------------------------------------------------------------
+
+ Module Private Functions
+
+ ---------------------------------------------------------------------------*/
+
+static volatile
+DSTATUS disk_stat = STA_NOINIT;        /* Disk status */
+
+static
+BYTE CardType;                         /* Card type flags */
+
+/*-----------------------------------------------------------------------*/
+/* Wait for card ready                                                   */
+/*-----------------------------------------------------------------------*/
+
+static
+int wait_ready (void)  /* 1:OK, 0:Timeout */
+{
+       uint32_t to = get_timer(0);
+
+       /* Wait for ready in timeout of 500ms */
+       do {
+               if (spi_rcvr() == 0xFF) {
+                       return 1;
+               }
+       } while (get_timer(to) < 500);
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Deselect the card and release SPI bus                                 */
+/*-----------------------------------------------------------------------*/
+
+static
+void deselect (void)
+{
+//     debug("*** enter deselect()\n");
+       CS_HIGH();
+       /* Dummy clock (TODO: force DO hi-z for multiple slave SPI) */
+       spi_rcvr();
+//     debug("***  exit deselect()\n");
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Select the card and wait for ready                                    */
+/*-----------------------------------------------------------------------*/
+
+static
+int select (void)      /* 1:Successful, 0:Timeout */
+{
+//     debug("*** enter select()\n");
+       CS_LOW();
+       /* Dummy clock (force DO enabled) */
+       spi_rcvr();
+
+       if (wait_ready()) {
+//             debug("***  exit select() == 1\n");
+               return 1;       /* OK */
+       }
+       deselect();
+//     debug("***  exit select() == 0\n");
+
+       return 0;       /* Timeout */
+}
+
+/*-----------------------------------------------------------------------*/
+/* 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)
+{
+//     debug("*** enter power_on()\n");
+
+#ifdef SD_PWR_PIN
+       SD_PWR_DDR |= _BV(SD_PWR_PIN); // Turns on PWR pin as output
+       SD_PWR_PORT &= ~_BV(SD_PWR_PIN); // Drives PWR pin high
+
+       for (uint32_t to = get_timer(0); get_timer(to) < 30;)
+               ; /* Wait for 30ms */
+#endif
+
+#ifdef SD_CD_PIN
+       /* Card detect, input with pullup */
+       SD_CD_DDR &= ~_BV(SD_CD_PIN);
+       SD_CD_PORT |= _BV(SD_CD_PIN);
+#endif
+#ifdef SD_WP_PIN
+       SD_WP_DDR &= ~_BV(SD_WP_PIN);
+       SD_WP_PORT |= _BV(SD_WP_PIN);
+#endif
+       SD_CS_PORT |= _BV(SD_CS_PIN);
+       SD_CS_DDR |= _BV(SD_CS_PIN); // Turns on CS pin as output
+
+//     debug("***  exit power_on()\n");
+}
+
+static
+void power_off (void)
+{
+//     debug("*** enter power_off()\n");
+       select();                               /* Wait for card ready */
+       deselect();
+
+#ifdef SD_PWR_PIN
+       SD_PWR_PORT |= (1 << SD_PWR_PIN); /* Socket power OFF */
+#endif
+       disk_stat |= STA_NOINIT; /* Set STA_NOINIT */
+//     debug("***  exit power_off()\n");
+}
+
+#if 0
+static
+int chk_power(void) /* Socket power state: 0=off, 1=on */
+{
+#ifdef SD_PWR_PIN
+       return (SD_PWR_PORT & (1 << SD_PWR_PIN)) ? 0 : 1;
+#else
+       return 1;
+#endif /* SD_PWR_PIN */
+}
+#endif
+
+/*-----------------------------------------------------------------------*/
+/* Receive a data packet from MMC                                        */
+/*-----------------------------------------------------------------------*/
+
+static
+int rcvr_datablock (
+       BYTE *buff,                     /* Data buffer to store received data */
+UINT btr /* Byte count (must be multiple of 4) */
+) {
+       BYTE token, tmp;
+       uint32_t to = get_timer(0);
+
+       /* Wait for data packet in timeout of 200ms */
+       do {
+               token = spi_rcvr();
+       } while ((token == 0xFF) && get_timer(to) < 200);
+       if(token != 0xFE) return 0;             /* If not valid data token, retutn with error */
+
+       tmp = spi_rcvr(); /* shift in first byte */
+       spi_write(0xff); /* start shift in next byte */
+       while (--btr) {
+               *buff++ = tmp;
+               asm volatile (""::"r"(buff), "r"(btr));
+               spi_wait();
+               tmp = SPDR;
+               spi_write(0xff);
+       }
+       *buff = tmp; /* store last byte in buffer while SPI module shifts in crc part1 */
+       spi_wait();
+       spi_rcvr(); /* second crc */
+
+       return 1; /* Return with success */
+}
+
+/*-----------------------------------------------------------------------*/
+/* Send a data packet to MMC                                             */
+/*-----------------------------------------------------------------------*/
+
+#if    _USE_WRITE
+static
+int xmit_datablock (
+               const BYTE *buff, /* 512 byte data block to be transmitted */
+               BYTE token /* Data/Stop token */
+)
+{
+       BYTE resp, tmp;
+       UINT btr;
+
+       if (!wait_ready()) return 0;
+
+       spi_write(token); /* Xmit data token */
+       if (token != 0xFD) { /* Is data token */
+               btr = 512;
+               do {
+                       tmp = *buff++;
+                       spi_wait();
+                       spi_write(tmp);
+               }while (--btr);
+               spi_wait();
+               spi_xmit(0xff); /* CRC (Dummy) */
+               spi_xmit(0xff);
+               resp = spi_rcvr(); /* Reveive data response */
+               return ((resp & 0x1F) != 0x05) ? 0 : 1; /* If not accepted, return with error */
+       }
+
+       spi_wait();
+       return 1;
+}
+#endif /* _USE_WRITE */
+
+/*-----------------------------------------------------------------------*/
+/* Send a command packet to MMC                                          */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE send_cmd (                /* Returns R1 resp (bit7==1:Send failed) */
+       BYTE cmd,               /* Command index */
+                                        DWORD arg /* Argument */
+) {
+       union {
+               DWORD as32;
+               BYTE as8[4];
+       } argtmp;
+       BYTE n, res;
+
+//     debug("*** send_cmd( %.2x )\n", cmd);
+
+       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 except to stop multiple block read */
+       if (cmd != CMD12) {
+               deselect();
+               if (!select())
+                       return 0xFF;
+       }
+
+       /* Send command packet */
+       spi_xmit(0x40 | cmd); /* Start + Command index */
+       argtmp.as32 = arg;
+       spi_xmit(argtmp.as8[3]); /* Argument[31..24] */
+       spi_xmit(argtmp.as8[2]); /* Argument[23..16] */
+       spi_xmit(argtmp.as8[1]); /* Argument[15..8] */
+       spi_xmit(argtmp.as8[0]); /* 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) */
+       spi_xmit(n);
+
+       /* Receive command response */
+       if (cmd == CMD12)
+               spi_rcvr(); /* Skip a stuff byte when stop reading */
+       n = 10; /* Wait for a valid response in timeout of 10 attempts */
+       do
+               res = spi_rcvr();
+       while ((res & 0x80) && --n);
+
+       return res; /* Return with the response value */
+}
+
+/*--------------------------------------------------------------------------
+
+ Public Functions
+
+ ---------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------*/
+/* Initialize Disk Drive                                                 */
+/*-----------------------------------------------------------------------*/
+
+#define MMC_INIT_TO 1000       /* 1s */
+
+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 (disk_stat & STA_NODISK)
+               return disk_stat; /* No card in the socket */
+
+       power_on(); /* Force socket power on */
+       FCLK_SLOW();
+       for (n = 10; n; n--)
+               spi_rcvr(); /* 80 dummy clocks */
+
+       ty = 0;
+       if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
+               /* Init timeout timer */
+               uint32_t timer = get_timer(0);
+
+               if (send_cmd(CMD8, 0x1AA) == 1) {       /* SDv2? */
+                       for (n = 0; n < 4; n++) ocr[n] = spi_rcvr();            /* 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 (get_timer(timer) < MMC_INIT_TO && send_cmd(ACMD41, 1UL << 30));  /* Wait for leaving idle state (ACMD41 with HCS bit) */
+                               if (get_timer(timer) < MMC_INIT_TO && send_cmd(CMD58, 0) == 0) {                /* Check CCS bit in the OCR */
+                                       for (n = 0; n < 4; n++) ocr[n] = spi_rcvr();
+                                       ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;      /* SDv2 */
+                               }
+                       }
+               } else {                                                        /* SDv1 or MMCv3 */
+                       if (send_cmd(ACMD41, 0) <= 1) {
+                               ty = CT_SD1; cmd = ACMD41;      /* SDv1 */
+                       } else {
+                               ty = CT_MMC; cmd = CMD1;        /* MMCv3 */
+                       }
+
+                       /* Wait for leaving idle state */
+                       while (get_timer(timer) < MMC_INIT_TO && send_cmd(cmd, 0));
+
+                       /* Set R/W block length to 512 */
+                       if (!(get_timer(timer) < MMC_INIT_TO) || send_cmd(CMD16, 512) != 0)
+                               ty = 0;
+               }
+       }
+       CardType = ty;
+       deselect();
+
+       if (ty) { /* Initialization succeded */
+               disk_stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
+               FCLK_FAST();
+       } else { /* Initialization failed */
+               power_off();
+       }
+
+       return disk_stat;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Get Disk Status                                                       */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_status (
+       BYTE drv                /* Physical drive nmuber (0) */
+)
+{
+       if (drv) return STA_NOINIT;             /* Supports only single drive */
+       return disk_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) */
+       UINT count /* Sector count (1..255) */
+)
+{
+       BYTE cmd;
+
+       if (drv || !count) return RES_PARERR;
+       if (disk_stat & STA_NOINIT) return RES_NOTRDY;
+
+       if (!(CardType & CT_BLOCK)) sector *= 512;      /* Convert to byte address if needed */
+
+       cmd = count > 1 ? CMD18 : CMD17;                        /*  READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
+       if (send_cmd(cmd, sector) == 0) {
+               do {
+                       if (!rcvr_datablock(buff, 512))
+                               break;
+                       buff += 512;
+               } while (--count);
+               if (cmd == CMD18)
+                       send_cmd(CMD12, 0);     /* STOP_TRANSMISSION */
+       }
+       deselect();
+
+       return count ? RES_ERROR : RES_OK;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s)                                                       */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_WRITE
+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) */
+               UINT count /* Sector count (1..255) */
+)
+{
+       if (drv || !count) return RES_PARERR;
+       if (disk_stat & STA_NOINIT) return RES_NOTRDY;
+       if (disk_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;
+               }
+       }
+       deselect();
+
+       return count ? RES_ERROR : RES_OK;
+}
+#endif /* _USE_WRITE */
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions                                               */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_IOCTL
+DRESULT disk_ioctl (
+       BYTE drv,               /* Physical drive nmuber (0) */
+       BYTE cmd,               /* Control code */
+       void *buff              /* Buffer to send/receive control data */
+)
+{
+       DRESULT res;
+       BYTE n, csd[16], *ptr = buff;
+       DWORD csize;
+
+       if (drv)
+               return RES_PARERR;
+
+       res = RES_ERROR;
+
+       if (disk_stat & STA_NOINIT) return RES_NOTRDY;
+
+       switch (cmd) {
+       case CTRL_SYNC :                /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
+               if (select())
+                       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) + ((DWORD)(csd[7] & 63) << 16) + 1;
+                               *(DWORD*)buff = 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 = csize << (n - 9);
+                       }
+                       res = RES_OK;
+               }
+               break;
+
+       case GET_BLOCK_SIZE:    /* Get erase block size in unit of sector (DWORD) */
+               if (CardType & CT_SD2) {        /* SDv2? */
+                       if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
+                               spi_rcvr();
+                               if (rcvr_datablock(csd, 16)) { /* Read partial block */
+                                       for (n = 64 - 16; n; n--)
+                                               spi_rcvr(); /* Purge trailing data */
+                                       *(DWORD*) buff = 16UL << (csd[10] >> 4);
+                                       res = RES_OK;
+                               }
+                       }
+               } else {                                        /* SDv1 or MMCv3 */
+                       if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
+                               if (CardType & CT_SD1) {        /* SDv1 */
+                                       *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
+                               } else {                                        /* MMCv3 */
+                                       *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
+                               }
+                               res = RES_OK;
+                       }
+               }
+               break;
+
+       /* Following commands are never used by FatFs module */
+
+       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++ = spi_rcvr();
+                       res = RES_OK;
+               }
+               break;
+
+       case MMC_GET_SDSTAT: /* Receive SD status as a data block (64 bytes) */
+               if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
+                       spi_rcvr();
+                       if (rcvr_datablock(ptr, 64))
+                               res = RES_OK;
+               }
+               break;
+
+       case CTRL_POWER_OFF :   /* Power off */
+               power_off();
+               disk_stat |= STA_NOINIT;
+               res = RES_OK;
+               break;
+
+       default:
+               res = RES_PARERR;
+       }
+
+       deselect();
+
+       return res;
+}
+#endif /* _USE_IOCTL */
+
+/*-----------------------------------------------------------------------*/
+/* Device Timer Interrupt Procedure  (Platform dependent)                */
+/*-----------------------------------------------------------------------*/
+/* This function must be called in period of 10ms                        */
+
+void disk_timerproc (void)
+{
+       BYTE s;
+
+       s = disk_stat;
+
+#ifdef SD_WP_PIN
+       if (sd_wp())                            /* Write protected */
+               s |= STA_PROTECT;
+       else                                    /* Write enabled */
+               s &= ~STA_PROTECT;
+#endif
+
+#ifdef SD_CD_PIN
+       if (sd_cd())                            /* Card inserted */
+               s &= ~STA_NODISK;
+       else                                    /* Socket empty */
+               s |= (STA_NODISK | STA_NOINIT);
+#endif
+
+       disk_stat = s;                          /* Update MMC status */
+}
index 67b4a491018ee2d02507956f57274d8eec93dcf7..6fb19a81b9fa308b18796a001e50c4d8875b7c9d 100644 (file)
@@ -25,6 +25,7 @@ ISR(TIMER3_COMPA_vect)
        static int_fast8_t tick_10ms;
        int_fast8_t i;
 
+       extern void disk_timerproc(void);
 
        timestamp++;
 
@@ -34,7 +35,7 @@ ISR(TIMER3_COMPA_vect)
                Stat |= S_10MS_TO;
 
                /* Drive timer procedure of low level disk I/O module */
-               //disk_timerproc();
+               disk_timerproc();
        }
        tick_10ms = i;
 
@@ -83,4 +84,3 @@ uint32_t get_timer(uint32_t base)
        }
        return ret - base;
 }
-
diff --git a/fatfs/src/diskio.h b/fatfs/src/diskio.h
deleted file mode 100644 (file)
index 9650f68..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-----------------------------------------------------------------------/\r
-/  Low level disk interface modlue include file   (C)ChaN, 2014          /\r
-/-----------------------------------------------------------------------*/\r
-\r
-#ifndef _DISKIO_DEFINED\r
-#define _DISKIO_DEFINED\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#define _USE_WRITE     1       /* 1: Enable disk_write function */\r
-#define _USE_IOCTL     1       /* 1: Enable disk_ioctl fucntion */\r
-\r
-#include "integer.h"\r
-\r
-\r
-/* Status of Disk Functions */\r
-typedef BYTE   DSTATUS;\r
-\r
-/* Results of Disk Functions */\r
-typedef enum {\r
-       RES_OK = 0,             /* 0: Successful */\r
-       RES_ERROR,              /* 1: R/W Error */\r
-       RES_WRPRT,              /* 2: Write Protected */\r
-       RES_NOTRDY,             /* 3: Not Ready */\r
-       RES_PARERR              /* 4: Invalid Parameter */\r
-} DRESULT;\r
-\r
-\r
-/*---------------------------------------*/\r
-/* Prototypes for disk control functions */\r
-\r
-\r
-DSTATUS disk_initialize (BYTE pdrv);\r
-DSTATUS disk_status (BYTE pdrv);\r
-DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);\r
-DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);\r
-DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);\r
-\r
-\r
-/* Disk Status Bits (DSTATUS) */\r
-\r
-#define STA_NOINIT             0x01    /* Drive not initialized */\r
-#define STA_NODISK             0x02    /* No medium in the drive */\r
-#define STA_PROTECT            0x04    /* Write protected */\r
-\r
-\r
-/* Command code for disk_ioctrl fucntion */\r
-\r
-/* Generic command (Used by FatFs) */\r
-#define CTRL_SYNC                      0       /* Complete pending write process (needed at _FS_READONLY == 0) */\r
-#define GET_SECTOR_COUNT       1       /* Get media size (needed at _USE_MKFS == 1) */\r
-#define GET_SECTOR_SIZE                2       /* Get sector size (needed at _MAX_SS != _MIN_SS) */\r
-#define GET_BLOCK_SIZE         3       /* Get erase block size (needed at _USE_MKFS == 1) */\r
-#define CTRL_TRIM                      4       /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */\r
-\r
-/* Generic command (Not used by FatFs) */\r
-#define CTRL_POWER                     5       /* Get/Set power status */\r
-#define CTRL_LOCK                      6       /* Lock/Unlock media removal */\r
-#define CTRL_EJECT                     7       /* Eject media */\r
-#define CTRL_FORMAT                    8       /* Create physical format on the media */\r
-\r
-/* MMC/SDC specific ioctl command */\r
-#define MMC_GET_TYPE           10      /* Get card type */\r
-#define MMC_GET_CSD                    11      /* Get CSD */\r
-#define MMC_GET_CID                    12      /* Get CID */\r
-#define MMC_GET_OCR                    13      /* Get OCR */\r
-#define MMC_GET_SDSTAT         14      /* Get SD status */\r
-\r
-/* ATA/CF specific ioctl command */\r
-#define ATA_GET_REV                    20      /* Get F/W revision */\r
-#define ATA_GET_MODEL          21      /* Get model name */\r
-#define ATA_GET_SN                     22      /* Get serial number */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
index 04429453f7e91a7fd7291878caeff4a1887fd3f1..adc4b87462a4183ccf3e56fd4965629a784bb51f 100644 (file)
@@ -51,7 +51,7 @@
 /* This option switches fast seek feature. (0:Disable or 1:Enable) */
 
 
-#define _USE_LABEL             0
+#define _USE_LABEL             1
 /* This option switches volume label functions, f_getlabel() and f_setlabel().
 /  (0:Disable or 1:Enable) */
 
@@ -65,7 +65,7 @@
 / Locale and Namespace Configurations
 /---------------------------------------------------------------------------*/
 
-#define _CODE_PAGE     932
+#define _CODE_PAGE     858
 /* This option specifies the OEM code page to be used on the target system.
 /  Incorrect setting of the code page can cause a file open failure.
 /
@@ -97,8 +97,8 @@
 /   1    - ASCII (No extended character. Valid for only non-LFN configuration.) */
 
 
-#define        _USE_LFN        0
-#define        _MAX_LFN        255
+#define        _USE_LFN        1
+#define        _MAX_LFN        128
 /* The _USE_LFN option switches the LFN feature.
 /
 /   0: Disable LFN feature. _MAX_LFN has no effect.
 /  When _LFN_UNICODE is 0, this option has no effect. */
 
 
-#define _FS_RPATH      0
+#define _FS_RPATH      2
 /* This option configures relative path feature.
 /
 /   0: Disable relative path feature and remove related functions.
 /  defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
 /  When timestamp feature is enabled (_FS_NORTC        == 0), get_fattime() function need
 /  to be added to the project to read current time form RTC. _NORTC_MON,
-/  _NORTC_MDAY and _NORTC_YEAR have no effect. 
+/  _NORTC_MDAY and _NORTC_YEAR have no effect.
 /  These options have no effect at read-only configuration (_FS_READONLY == 1). */
 
 
 /   PIC24       0           H8S         0           MSP430      0
 /   PIC32       0           H8/300H     0           8051        0/1
 */
-
diff --git a/include/avr/ffconf.h b/include/avr/ffconf.h
new file mode 100644 (file)
index 0000000..88c53d1
--- /dev/null
@@ -0,0 +1,25 @@
+
+#undef _WORD_ACCESS
+
+#define _WORD_ACCESS   0       /* 0 or 1 */
+/* The _WORD_ACCESS option is an only platform dependent option. It defines
+/  which access method is used to the word data on the FAT volume.
+/
+/   0: Byte-by-byte access. Always compatible with all platforms.
+/   1: Word access. Do not choose this unless under both the following conditions.
+/
+/  * Address misaligned memory access is always allowed to ALL instructions.
+/  * Byte order on the memory is little-endian.
+/
+/  If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
+/  Following table shows allowable settings of some processor types.
+/
+/   ARM7TDMI    0           ColdFire    0           V850E       0
+/   Cortex-M3   0           Z80         0/1         V850ES      0/1
+/   Cortex-M0   0           x86         0/1         TLCS-870    0/1
+/   AVR         0/1         RX600(LE)   0/1         TLCS-900    0/1
+/   AVR32       0           RL78        0           R32C        0
+/   PIC18       0/1         SH-2        0           M16C        0/1
+/   PIC24       0           H8S         0           MSP430      0
+/   PIC32       0           H8/300H     0           8051        0/1
+*/
diff --git a/include/diskio.h b/include/diskio.h
new file mode 100644 (file)
index 0000000..f5ba3e0
--- /dev/null
@@ -0,0 +1,86 @@
+/*-----------------------------------------------------------------------
+/  Low level disk interface modlue include file  R0.07   (C)ChaN, 2009
+/-----------------------------------------------------------------------*/
+
+#ifndef _DISKIO_H
+#define _DISKIO_H
+
+#define _USE_WRITE     1       /* 1: Enable disk_write function */
+#define _USE_IOCTL     1       /* 1: Enable disk_ioctl fucntion */
+
+#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 drv);
+DSTATUS disk_status (BYTE drv);
+DRESULT disk_read (BYTE drv, BYTE* buff, DWORD sector, UINT count);
+#if    _USE_WRITE
+DRESULT disk_write (BYTE drv, const BYTE* buff, DWORD sector, UINT count);
+#endif
+#if    _USE_IOCTL
+DRESULT disk_ioctl (BYTE drv, BYTE cmd, void* buff);
+#endif
+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 (Used by FatFs) */
+#define CTRL_SYNC                      0       /* Complete pending write process (needed at _FS_READONLY == 0) */
+#define GET_SECTOR_COUNT       1       /* Get media size (needed at _USE_MKFS == 1) */
+#define GET_SECTOR_SIZE                2       /* Get sector size (needed at _MAX_SS != _MIN_SS) */
+#define GET_BLOCK_SIZE         3       /* Get erase block size (needed at _USE_MKFS == 1) */
+#define CTRL_TRIM                      4       /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
+
+/* Generic command (Not used by FatFs) */
+#define CTRL_FORMAT                    5       /* Create physical format on the media */
+#define CTRL_POWER_IDLE                6       /* Put the device idle state */
+#define CTRL_POWER_OFF         7       /* Put the device off state */
+#define CTRL_LOCK                      8       /* Lock media removal */
+#define CTRL_UNLOCK                    9       /* Unlock media removal */
+#define CTRL_EJECT                     10      /* Eject media */
+
+/* MMC/SDC specific command (Not used by FatFs) */
+#define MMC_GET_TYPE           50      /* Get card type */
+#define MMC_GET_CSD                    51      /* Get CSD */
+#define MMC_GET_CID                    52      /* Get CID */
+#define MMC_GET_OCR                    53      /* Get OCR */
+#define MMC_GET_SDSTAT         54      /* Get SD status */
+
+/* ATA/CF specific command (Not used by FatFs) */
+#define ATA_GET_REV                    60      /* Get F/W revision */
+#define ATA_GET_MODEL          61      /* Get model name */
+#define ATA_GET_SN                     62      /* Get serial number */
+
+/* MMC card type flags (MMC_GET_TYPE) */
+#define CT_MMC         0x01            /* MMC ver 3 */
+#define CT_SD1         0x02            /* SD ver 1 */
+#define CT_SD2         0x04            /* SD ver 2 */
+#define CT_SDC         (CT_SD1|CT_SD2) /* SD */
+#define CT_BLOCK       0x08            /* Block addressing */
+
+#endif /* _DISKIO_H */
diff --git a/include/ff.h b/include/ff.h
new file mode 100644 (file)
index 0000000..c19b7b5
--- /dev/null
@@ -0,0 +1,2 @@
+#include "../fatfs/src/ff.h"
+#include "avr/ffconf.h"
similarity index 51%
rename from fatfs/src/integer.h
rename to include/integer.h
index 074a46bd5bbe54df12d05b2362b8f19db83c4c09..a263f7c914af655884476ebd634c1a27d4fd44e6 100644 (file)
@@ -5,29 +5,22 @@
 #ifndef _FF_INTEGER\r
 #define _FF_INTEGER\r
 \r
-#ifdef _WIN32  /* FatFs development platform */\r
-\r
-#include <windows.h>\r
-#include <tchar.h>\r
-\r
-#else                  /* Embedded platform */\r
+#include <stdint.h>\r
 \r
 /* This type MUST be 8 bit */\r
-typedef unsigned char  BYTE;\r
+typedef uint8_t                BYTE;\r
 \r
 /* These types MUST be 16 bit */\r
-typedef short                  SHORT;\r
-typedef unsigned short WORD;\r
-typedef unsigned short WCHAR;\r
+typedef int16_t                SHORT;\r
+typedef uint16_t       WORD;\r
+typedef uint16_t       WCHAR;\r
 \r
 /* These types MUST be 16 bit or 32 bit */\r
-typedef int                            INT;\r
+typedef int            INT;\r
 typedef unsigned int   UINT;\r
 \r
 /* These types MUST be 32 bit */\r
-typedef long                   LONG;\r
-typedef unsigned long  DWORD;\r
-\r
-#endif\r
+typedef int32_t                LONG;\r
+typedef uint32_t       DWORD;\r
 \r
 #endif\r
diff --git a/include/spi.h b/include/spi.h
new file mode 100644 (file)
index 0000000..04ea726
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * spi.h
+ *
+ *  Created on: 17.04.2009
+ *      Author: leo
+ */
+
+#ifndef SPI_H_
+#define SPI_H_
+
+#define SPI_PORT       PORTB           /* SPI Connection port */
+#define SPI_DDR        DDRB            /* SPI Direction port */
+#define SPI_SS         0
+#define SPI_SCK                1
+#define SPI_MOSI       2
+#define SPI_MISO       3
+
+
+/* SPI macros */
+
+#define SPI_SET_SPEED_F_2              do {SPCR = (1<<SPE) | (1<<MSTR) | (0<<SPR1) | (0<<SPR0); SPSR = (1<<SPI2X); } while(0)
+#define SPI_SET_SPEED_F_4              do {SPCR = (1<<SPE) | (1<<MSTR) | (0<<SPR1) | (0<<SPR0); SPSR = (0<<SPI2X); } while(0)
+#define SPI_SET_SPEED_F_8              do {SPCR = (1<<SPE) | (1<<MSTR) | (0<<SPR1) | (1<<SPR0); SPSR = (1<<SPI2X); } while(0)
+#define SPI_SET_SPEED_F_16             do {SPCR = (1<<SPE) | (1<<MSTR) | (0<<SPR1) | (1<<SPR0); SPSR = (0<<SPI2X); } while(0)
+#define SPI_SET_SPEED_F_32             do {SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (0<<SPR0); SPSR = (1<<SPI2X); } while(0)
+#define SPI_SET_SPEED_F_64             do {SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (0<<SPR0); SPSR = (0<<SPI2X); } while(0)
+#define SPI_SET_SPEED_F_128            do {SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0); SPSR = (0<<SPI2X); } while(0)
+
+/** switch to fast SPI Clock */
+#define SPISetFastClock()       SPI_SET_SPEED_F_2
+#define SPISetSlowClock()       SPI_SET_SPEED_F_8
+#define SPISetMMCInitClock() SPI_SET_SPEED_F_64
+
+
+static inline void spi_wait() {
+       loop_until_bit_is_set(SPSR,SPIF);
+}
+
+static inline void spi_write(uint8_t a) {
+       SPDR = a;
+}
+
+static inline void spi_xmit(uint8_t a){
+       spi_write(a);
+       spi_wait();
+}
+
+static inline uint8_t spi_rcvr(void) {
+       SPDR = 0xFF;
+       spi_wait();
+       return SPDR;
+}
+
+#endif /* SPI_H_ */