aboutsummaryrefslogtreecommitdiffstats
path: root/demos/ARM7-LPC214x-GCC
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2007-11-02 15:34:52 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2007-11-02 15:34:52 +0000
commit50cd4e00ef4614552dba01b865688c66629e1958 (patch)
tree7198ace94816ee6894e7169df468935003ad536b /demos/ARM7-LPC214x-GCC
parentd0cc4f2406f3932312de7908afeb33daf0acc720 (diff)
downloadChibiOS-50cd4e00ef4614552dba01b865688c66629e1958.tar.gz
ChibiOS-50cd4e00ef4614552dba01b865688c66629e1958.tar.bz2
ChibiOS-50cd4e00ef4614552dba01b865688c66629e1958.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@82 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'demos/ARM7-LPC214x-GCC')
-rw-r--r--demos/ARM7-LPC214x-GCC/main.c19
-rw-r--r--demos/ARM7-LPC214x-GCC/mmcsd.c180
-rw-r--r--demos/ARM7-LPC214x-GCC/mmcsd.h21
3 files changed, 185 insertions, 35 deletions
diff --git a/demos/ARM7-LPC214x-GCC/main.c b/demos/ARM7-LPC214x-GCC/main.c
index 9e0a4222c..614020271 100644
--- a/demos/ARM7-LPC214x-GCC/main.c
+++ b/demos/ARM7-LPC214x-GCC/main.c
@@ -21,7 +21,6 @@
#include "lpc214x.h"
#include "lpc214x_serial.h"
-//#include "lpc214x_ssp.h"
#include "mmcsd.h"
#include "buzzer.h"
#include "evtimer.h"
@@ -56,8 +55,9 @@ static t_msg Thread2(void *arg) {
return 0;
}
+static BYTE8 rwbuf[512];
+
static void TimerHandler(t_eventid id) {
-// static BYTE8 sspbuf[16];
t_msg TestThread(void *p);
if (!(IO0PIN & 0x00018000)) { // Both buttons
@@ -68,16 +68,21 @@ static void TimerHandler(t_eventid id) {
if (!(IO0PIN & 0x00008000)) // Button 1
PlaySound(1000, 100);
if (!(IO0PIN & 0x00010000)) { // Button 2
-// sspRW(sspbuf, (BYTE8 *)"Hello World!\r\n", 14);
-// chFDDWrite(&COM1, sspbuf, 14);
+ MMCCSD data;
+
chFDDWrite(&COM1, (BYTE8 *)"Hello World!\r\n", 14);
- if (!mmcInit())
- PlaySound(2000, 500);
+ if (mmcInit())
+ return;
+ if (mmcGetSize(&data))
+ return;
+ if (mmcBlockRead(0x200000, rwbuf))
+ return;
+ PlaySound(2000, 100);
}
}
}
-static BYTE8 waThread3[UserStackSize(64)];
+static BYTE8 waThread3[UserStackSize(128)];
static EvTimer evt;
static t_evhandler evhndl[1] = {
TimerHandler
diff --git a/demos/ARM7-LPC214x-GCC/mmcsd.c b/demos/ARM7-LPC214x-GCC/mmcsd.c
index 1c0d5c7d8..7867782c9 100644
--- a/demos/ARM7-LPC214x-GCC/mmcsd.c
+++ b/demos/ARM7-LPC214x-GCC/mmcsd.c
@@ -26,11 +26,64 @@
static EventSource MMCInsertEventSource;
+/*
+ * Subsystem initialization.
+ */
void InitMMC(void) {
chEvtInit(&MMCInsertEventSource);
}
+static void sendhdr(BYTE8 cmd, ULONG32 arg) {
+ BYTE8 buf[6];
+
+ /*
+ * Wait for the bus to become idle if a write operation was in progress.
+ */
+ while (TRUE) {
+ sspRW(buf, NULL, 1);
+ if (buf[0] == 0xFF)
+ break;
+#ifdef NICE_WAITING
+ chThdSleep(1); /* Trying to be nice with the other threads.*/
+#endif
+ }
+
+ buf[0] = 0x40 | cmd;
+ buf[1] = arg >> 24;
+ buf[2] = arg >> 16;
+ buf[3] = arg >> 8;
+ buf[4] = arg;
+ buf[5] = 0x95; /* Valid for CMD0 ingnored by other commands. */
+ sspRW(NULL, buf, 6);
+}
+
+static BYTE8 recvr1(void) {
+ int i;
+ BYTE8 r1[1];
+
+ for (i = 0; i < 9; i++) {
+ sspRW(r1, NULL, 1);
+ if (r1[0] != 0xFF)
+ return r1[0];
+ }
+ return 0xFF; /* Timeout.*/
+}
+
+static BOOL getdata(BYTE8 *buf, ULONG32 n) {
+ int i;
+
+ for (i = 0; i < MMC_WAIT_DATA; i++) {
+ sspRW(buf, NULL, 1);
+ if (buf[0] == 0xFE) {
+ sspRW(buf, NULL, n);
+ sspRW(NULL, NULL, 2); /* CRC ignored.*/
+ return FALSE;
+ }
+ }
+ return TRUE; /* Timeout.*/
+}
+
/*
* Initializes a card after the power up by selecting the SPI mode.
*/
@@ -47,7 +100,7 @@ BOOL mmcInit(void) {
sspRW(NULL, NULL, 16); /* 128 clock pulses without ~CS asserted. */
int i = 0;
while (TRUE) {
- if (mmcSendCommand(0, 0) == 0x01)
+ if (mmcSendCommand(CMDGOIDLE, 0) == 0x01)
break;
if (++i >= CMD0_RETRY)
return TRUE;
@@ -59,7 +112,7 @@ BOOL mmcInit(void) {
*/
i = 0;
while (TRUE) {
- BYTE8 b = mmcSendCommand(1, 0);
+ BYTE8 b = mmcSendCommand(CMDINIT, 0);
if (b == 0x00)
break;
if (b != 0x01)
@@ -76,32 +129,6 @@ BOOL mmcInit(void) {
return FALSE;
}
-static void sendhdr(BYTE8 cmd, ULONG32 arg) {
- BYTE8 buf[8];
-
- buf[0] = 0xFF;
- buf[1] = 0x40 | cmd;
- buf[2] = arg >> 24;
- buf[3] = arg >> 16;
- buf[4] = arg >> 8;
- buf[5] = arg;
- buf[6] = 0x95; /* Valid for CMD0 ingnored by other commands. */
- buf[7] = 0xFF;
- sspRW(NULL, buf, 8);
-}
-
-static BYTE8 recvr1(void) {
- int i;
- BYTE8 r1[1];
-
- for (i = 0; i < 8; i++) {
- sspRW(r1, NULL, 1);
- if (r1[0] != 0xFF)
- return r1[0];
- }
- return 0xFF;
-}
-
/*
* Sends a simple command and returns a R1-type response.
*/
@@ -114,3 +141,100 @@ BYTE8 mmcSendCommand(BYTE8 cmd, ULONG32 arg) {
sspReleaseBus();
return r1;
}
+
+/*
+ * Reads the card info record.
+ * @param data the pointer to a \p MMCCSD structure
+ * @return \p TRUE if an error happened
+ */
+BOOL mmcGetSize(MMCCSD *data) {
+ BYTE8 buf[16];
+
+ sspAcquireBus();
+ sendhdr(CMDREADCSD, 0);
+ if (recvr1() != 0x00) {
+ sspReleaseBus();
+ return TRUE;
+ }
+ if (getdata(buf, 16)) {
+ sspReleaseBus();
+ return TRUE;
+ }
+ sspReleaseBus();
+
+ /* csize * multiplier */
+ data->csize = (((buf[6] & 3) << 10) | (buf[7] << 2) | (buf[8] >> 6)) *
+ (1 << (2 + (((buf[9] & 3) << 1) | (buf[10] >> 7))));
+ data->rdblklen = 1 << (buf[5] & 15);
+ return FALSE;
+}
+
+/*
+ * Reads a block.
+ * @param blknum the block number
+ * @param buf the pointer to the read buffer
+ * @return \p TRUE if an error happened
+ */
+BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf) {
+
+ sspAcquireBus();
+ sendhdr(CMDREAD, blknum << 8);
+ if (recvr1() != 0x00) {
+ sspReleaseBus();
+ return TRUE;
+ }
+ if (getdata(buf, 512)) {
+ sspReleaseBus();
+ return TRUE;
+ }
+ sspReleaseBus();
+ return FALSE;
+}
+
+/*
+ * Writes a block.
+ * @param blknum the block number
+ * @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 mmcBlockWrite(ULONG32 blknum, BYTE8 *buf) {
+ static BYTE8 start[] = {0xFF, 0xFE};
+ BYTE8 b[4];
+
+ sspAcquireBus();
+ sendhdr(CMDWRITE, blknum << 8);
+ if (recvr1() != 0x00) {
+ sspReleaseBus();
+ return TRUE;
+ }
+ sspRW(NULL, 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)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Makes sure that pending operations are completed before returning.
+ */
+void mmcSynch(void) {
+ BYTE8 buf[4];
+
+ sspAcquireBus();
+ while (TRUE) {
+ sspRW(buf, NULL, 1);
+ if (buf[0] == 0xFF)
+ break;
+#ifdef NICE_WAITING
+ chThdSleep(1); /* Trying to be nice with the other threads.*/
+#endif
+ }
+ sspReleaseBus();
+}
diff --git a/demos/ARM7-LPC214x-GCC/mmcsd.h b/demos/ARM7-LPC214x-GCC/mmcsd.h
index 4c9f1d643..047fd0fb2 100644
--- a/demos/ARM7-LPC214x-GCC/mmcsd.h
+++ b/demos/ARM7-LPC214x-GCC/mmcsd.h
@@ -20,12 +20,33 @@
#ifndef _MMCSD_H_
#define _MMCSD_H_
+#define NICE_WAITING
+
+/* Following times are 10mS units.*/
#define CMD0_RETRY 10
#define CMD1_RETRY 100
+/* Byte transfer time units.*/
+#define MMC_WAIT_DATA 10000
+
+#define CMDGOIDLE 0
+#define CMDINIT 1
+#define CMDREADCSD 9
+#define CMDREAD 17
+#define CMDWRITE 24
+
+typedef struct {
+ ULONG32 csize;
+ ULONG32 rdblklen;
+} MMCCSD;
+
void InitMMC(void);
BOOL mmcInit(void);
BYTE8 mmcSendCommand(BYTE8 cmd, ULONG32 arg);
+BOOL mmcGetSize(MMCCSD *data);
+BOOL mmcBlockRead(ULONG32 blknum, BYTE8 *buf);
+BOOL mmcBlockWrite(ULONG32 blknum, BYTE8 *buf);
+void mmcSynch(void);
#endif /* _MMCSD_H_*/