diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2007-11-04 12:43:01 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2007-11-04 12:43:01 +0000 |
commit | 48cdf91217fd6460628315a63ccc9e87de21c193 (patch) | |
tree | 2f51c9191795ee2032695aa0d9bd9242235f48c8 /demos/ARM7-LPC214x-GCC/mmcsd.c | |
parent | 8b1e399085a166ba91f012d5b057ee4cd1f8bfc0 (diff) | |
download | ChibiOS-48cdf91217fd6460628315a63ccc9e87de21c193.tar.gz ChibiOS-48cdf91217fd6460628315a63ccc9e87de21c193.tar.bz2 ChibiOS-48cdf91217fd6460628315a63ccc9e87de21c193.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@85 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'demos/ARM7-LPC214x-GCC/mmcsd.c')
-rw-r--r-- | demos/ARM7-LPC214x-GCC/mmcsd.c | 119 |
1 files changed, 107 insertions, 12 deletions
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);
@@ -245,6 +267,39 @@ BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf) { }
/*
+ * 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
* @param buf the pointer to the write buffer
@@ -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;
}
|