From 48cdf91217fd6460628315a63ccc9e87de21c193 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 4 Nov 2007 12:43:01 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@85 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARM7-LPC214x-GCC/main.c | 3 +- demos/ARM7-LPC214x-GCC/mmcsd.c | 119 ++++++++++++++++++++++++++++++++++++----- demos/ARM7-LPC214x-GCC/mmcsd.h | 12 +++-- 3 files changed, 116 insertions(+), 18 deletions(-) (limited to 'demos/ARM7-LPC214x-GCC') diff --git a/demos/ARM7-LPC214x-GCC/main.c b/demos/ARM7-LPC214x-GCC/main.c index 9677918fd..fbd4f2726 100644 --- a/demos/ARM7-LPC214x-GCC/main.c +++ b/demos/ARM7-LPC214x-GCC/main.c @@ -83,8 +83,9 @@ static void InsertHandler(t_eventid id) { /* Card ready, do stuff.*/ if (mmcGetSize(&data)) return; - if (mmcBlockRead(0x200000, rwbuf)) + if (mmcRead(rwbuf, 0)) return; + PlaySound(440, 200); } static void RemoveHandler(t_eventid id) { diff --git a/demos/ARM7-LPC214x-GCC/mmcsd.c b/demos/ARM7-LPC214x-GCC/mmcsd.c index fb1c5c650..8723d8d96 100644 --- a/demos/ARM7-LPC214x-GCC/mmcsd.c +++ b/demos/ARM7-LPC214x-GCC/mmcsd.c @@ -58,6 +58,9 @@ void tmrfunc(void *par) { chVTSetI(&vt, 10, tmrfunc, NULL); } +/* + * Starts the card polling service. + */ void mmcStartPolling(void) { chSysLock(); @@ -70,6 +73,9 @@ void mmcStartPolling(void) { chSysUnlock(); } +/* + * Stops the card polling service. + */ void mmcStopPolling(void) { chSysLock(); @@ -82,17 +88,24 @@ void mmcStopPolling(void) { chSysUnlock(); } +/* + * Returns TRUE if the card is safely inserted in the reader. + */ BOOL mmcCardInserted (void) { return cnt == 0; } -static void sendhdr(BYTE8 cmd, ULONG32 arg) { - BYTE8 buf[6]; +static void wait(void) { + int i; + BYTE8 buf[4]; - /* - * Wait for the bus to become idle if a write operation was in progress. - */ + for (i = 0; i < 16; i++) { + sspRW(buf, NULL, 1); + if (buf[0] == 0xFF) + break; + } + /* Looks like it is a loooong wait.*/ while (TRUE) { sspRW(buf, NULL, 1); if (buf[0] == 0xFF) @@ -101,6 +114,15 @@ static void sendhdr(BYTE8 cmd, ULONG32 arg) { chThdSleep(1); /* Trying to be nice with the other threads.*/ #endif } +} + +static void sendhdr(BYTE8 cmd, ULONG32 arg) { + BYTE8 buf[6]; + + /* + * Wait for the bus to become idle if a write operation was in progress. + */ + wait(); buf[0] = 0x40 | cmd; buf[1] = arg >> 24; @@ -228,7 +250,7 @@ BOOL mmcGetSize(MMCCSD *data) { * @param buf the pointer to the read buffer * @return \p TRUE if an error happened */ -BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf) { +BOOL mmcRead(BYTE8 *buf, ULONG32 blknum) { sspAcquireBus(); sendhdr(CMDREAD, blknum << 8); @@ -244,6 +266,39 @@ BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf) { return FALSE; } +/* + * Reads multiple blocks. + * @param blknum the initial block + * @param n the number of blocks + * @param buf the pointer to the read buffer + * @return \p TRUE if an error happened + */ +BOOL mmcReadMultiple(BYTE8 *buf, ULONG32 blknum, ULONG32 n) { + static const BYTE8 stopcmd[] = {0x40 | CMDSTOP, 0, 0, 0, 0, 1, 0xFF}; + + sspAcquireBus(); + sendhdr(CMDREADMULTIPLE, blknum << 8); + if (recvr1() != 0x00) { + sspReleaseBus(); + return TRUE; + } + while (n) { + if (getdata(buf, 512)) { + sspReleaseBus(); + return TRUE; + } + buf += 512; + n--; + } + sspRW(NULL, (BYTE8 *)stopcmd, sizeof(stopcmd)); + if (recvr1() != 0x00) { + sspReleaseBus(); + return TRUE; + } + sspReleaseBus(); + return FALSE; +} + /* * Writes a block. * @param blknum the block number @@ -254,8 +309,8 @@ BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf) { * the card, this allows to not make useless busy waiting. The invoking * thread can do other things while the data is being written. */ -BOOL mmcBlockWrite(ULONG32 blknum, BYTE8 *buf) { - static BYTE8 start[] = {0xFF, 0xFE}; +BOOL mmcWrite(BYTE8 *buf, ULONG32 blknum) { + static const BYTE8 start[] = {0xFF, 0xFE}; BYTE8 b[4]; sspAcquireBus(); @@ -264,13 +319,53 @@ BOOL mmcBlockWrite(ULONG32 blknum, BYTE8 *buf) { sspReleaseBus(); return TRUE; } - sspRW(NULL, start, 2); /* Data prologue.*/ - sspRW(NULL, buf, 512); /* Data.*/ - sspRW(NULL, NULL, 2); /* CRC ignored in this version.*/ + sspRW(NULL, (BYTE8 *)start, 2); /* Data prologue.*/ + sspRW(NULL, buf, 512); /* Data.*/ + sspRW(NULL, NULL, 2); /* CRC ignored in this version.*/ sspRW(b, NULL, 1); sspReleaseBus(); - if ((b[0] & 0x1E) != 0x05) + if ((b[0] & 0x1F) != 0x05) + return TRUE; + return FALSE; +} + +/* + * Writes multiple blocks. + * @param blknum the initial block + * @param n the number of blocks + * @param buf the pointer to the write buffer + * @return \p TRUE if an error happened + * @note The function DOES NOT wait for the SPI bus to become free after + * sending the data, the bus check is done before sending commands to + * the card, this allows to not make useless busy waiting. The invoking + * thread can do other things while the data is being written. + */ +BOOL mmcWriteMultiple(BYTE8 *buf, ULONG32 blknum, ULONG32 n) { + static const BYTE8 start[] = {0xFF, 0xFC}, + stop[] = {0xFD, 0xFF}; + BYTE8 b[4]; + + sspAcquireBus(); + sendhdr(CMDWRITEMULTIPLE, blknum << 8); + if (recvr1() != 0x00) { + sspReleaseBus(); return TRUE; + } + while (n) { + sspRW(NULL, (BYTE8 *)start, sizeof(start)); /* Data prologue.*/ + sspRW(NULL, buf, 512); /* Data.*/ + sspRW(NULL, NULL, 2); /* CRC ignored in this version.*/ + sspRW(b, NULL, 1); + if ((b[0] & 0x1F) != 0x05) { + sspReleaseBus(); + return TRUE; + } + wait(); + buf += 512; + n--; + } + sspRW(NULL, (BYTE8 *)stop, sizeof(stop)); /* Stops the transfer.*/ + sspReleaseBus(); return FALSE; } diff --git a/demos/ARM7-LPC214x-GCC/mmcsd.h b/demos/ARM7-LPC214x-GCC/mmcsd.h index a071075bb..823a76a3d 100644 --- a/demos/ARM7-LPC214x-GCC/mmcsd.h +++ b/demos/ARM7-LPC214x-GCC/mmcsd.h @@ -22,19 +22,19 @@ #define NICE_WAITING -/* Following times are 10mS units.*/ #define CMD0_RETRY 10 #define CMD1_RETRY 100 #define POLLING_INTERVAL 10 - -/* Byte transfer time units.*/ #define MMC_WAIT_DATA 10000 #define CMDGOIDLE 0 #define CMDINIT 1 #define CMDREADCSD 9 +#define CMDSTOP 12 #define CMDREAD 17 +#define CMDREADMULTIPLE 18 #define CMDWRITE 24 +#define CMDWRITEMULTIPLE 25 typedef struct { ULONG32 csize; @@ -51,8 +51,10 @@ void mmcStopPolling(void); BOOL mmcCardInserted (void); BYTE8 mmcSendCommand(BYTE8 cmd, ULONG32 arg); BOOL mmcGetSize(MMCCSD *data); -BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf); -BOOL mmcBlockWrite(ULONG32 blknum, BYTE8 *buf); +BOOL mmcRead(BYTE8 *buf, ULONG32 blknum); +BOOL mmcReadMultiple(BYTE8 *buf, ULONG32 blknum, ULONG32 n); +BOOL mmcWrite(BYTE8 *buf, ULONG32 blknum); +BOOL mmcWriteMultiple(BYTE8 *buf, ULONG32 blknum, ULONG32 n); void mmcSynch(void); #endif /* _MMCSD_H_*/ -- cgit v1.2.3