diff options
Diffstat (limited to 'testhal/STM32F4xx/SDC/main.c')
-rw-r--r-- | testhal/STM32F4xx/SDC/main.c | 471 |
1 files changed, 156 insertions, 315 deletions
diff --git a/testhal/STM32F4xx/SDC/main.c b/testhal/STM32F4xx/SDC/main.c index 721eac66b..264f31133 100644 --- a/testhal/STM32F4xx/SDC/main.c +++ b/testhal/STM32F4xx/SDC/main.c @@ -15,341 +15,160 @@ */
#include <string.h>
+
#include "ch.h"
#include "hal.h"
-#include "shell.h"
#include "chprintf.h"
+#include "shell.h"
-#include "ff.h"
-
-#define SDC_DATA_DESTRUCTIVE_TEST FALSE
-
-#define SDC_BURST_SIZE 8 /* how many sectors reads at once */
-static uint8_t outbuf[MMCSD_BLOCK_SIZE * SDC_BURST_SIZE + 1];
-static uint8_t inbuf[MMCSD_BLOCK_SIZE * SDC_BURST_SIZE + 1];
-
-/* FS object.*/
-static FATFS SDC_FS;
-
-/* FS mounted and ready.*/
-static bool_t fs_ready = FALSE;
+/*
+ * SDIO configuration.
+ */
+static const SDCConfig sdccfg = {
+ 0
+};
-/**
- * @brief Parody of UNIX badblocks program.
- *
- * @param[in] start first block to check
- * @param[in] end last block to check
- * @param[in] blockatonce number of blocks to check at once
- * @param[in] pattern check pattern
- *
- * @return The operation status.
- * @retval SDC_SUCCESS operation succeeded, the requested blocks have been
- * read.
- * @retval SDC_FAILED operation failed, the state of the buffer is uncertain.
+/*
+ * LED blinker thread, times are in milliseconds.
*/
-bool_t badblocks(uint32_t start, uint32_t end, uint32_t blockatonce, uint8_t pattern){
- uint32_t position = 0;
- uint32_t i = 0;
-
- chDbgCheck(blockatonce <= SDC_BURST_SIZE, "badblocks");
-
- /* fill control buffer */
- for (i=0; i < MMCSD_BLOCK_SIZE * blockatonce; i++)
- outbuf[i] = pattern;
-
- /* fill SD card with pattern. */
- position = start;
- while (position < end){
- if (sdcWrite(&SDCD1, position, outbuf, blockatonce))
- goto ERROR;
- position += blockatonce;
- }
+static THD_WORKING_AREA(waThread1, 128);
+static msg_t Thread1(void *arg) {
- /* read and compare. */
- position = start;
- while (position < end){
- if (sdcRead(&SDCD1, position, inbuf, blockatonce))
- goto ERROR;
- if (memcmp(inbuf, outbuf, blockatonce * MMCSD_BLOCK_SIZE) != 0)
- goto ERROR;
- position += blockatonce;
+ (void)arg;
+ chRegSetThreadName("blinker");
+ while (TRUE) {
+ palSetPad(GPIOC, GPIOC_LED);
+ chThdSleepMilliseconds(500);
+ palClearPad(GPIOC, GPIOC_LED);
+ chThdSleepMilliseconds(500);
}
- return FALSE;
-
-ERROR:
- return TRUE;
}
-/**
- *
- */
-void fillbuffer(uint8_t pattern, uint8_t *b){
- uint32_t i = 0;
- for (i=0; i < MMCSD_BLOCK_SIZE * SDC_BURST_SIZE; i++)
- b[i] = pattern;
-}
+/*===========================================================================*/
+/* Command line related. */
+/*===========================================================================*/
-/**
- *
- */
-void fillbuffers(uint8_t pattern){
- fillbuffer(pattern, inbuf);
- fillbuffer(pattern, outbuf);
-}
+#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(2048)
-/**
- *
- */
-void cmd_sdiotest(BaseSequentialStream *chp, int argc, char *argv[]){
- (void)argc;
- (void)argv;
- uint32_t i = 0;
-
- chprintf(chp, "Trying to connect SDIO... ");
- chThdSleepMilliseconds(100);
-
- if (!sdcConnect(&SDCD1)) {
-
- chprintf(chp, "OK\r\n");
- chprintf(chp, "*** Card CSD content is: ");
- chprintf(chp, "%X %X %X %X \r\n", (&SDCD1)->csd[3], (&SDCD1)->csd[2],
- (&SDCD1)->csd[1], (&SDCD1)->csd[0]);
-
- chprintf(chp, "Single aligned read...");
- chThdSleepMilliseconds(100);
- if (sdcRead(&SDCD1, 0, inbuf, 1))
- chSysHalt();
- chprintf(chp, " OK\r\n");
- chThdSleepMilliseconds(100);
-
-
- chprintf(chp, "Single unaligned read...");
- chThdSleepMilliseconds(100);
- if (sdcRead(&SDCD1, 0, inbuf + 1, 1))
- chSysHalt();
- if (sdcRead(&SDCD1, 0, inbuf + 2, 1))
- chSysHalt();
- if (sdcRead(&SDCD1, 0, inbuf + 3, 1))
- chSysHalt();
- chprintf(chp, " OK\r\n");
- chThdSleepMilliseconds(100);
-
-
- chprintf(chp, "Multiple aligned reads...");
- chThdSleepMilliseconds(100);
- fillbuffers(0x55);
- /* fill reference buffer from SD card */
- if (sdcRead(&SDCD1, 0, inbuf, SDC_BURST_SIZE))
- chSysHalt();
- for (i=0; i<1000; i++){
- if (sdcRead(&SDCD1, 0, outbuf, SDC_BURST_SIZE))
- chSysHalt();
- if (memcmp(inbuf, outbuf, SDC_BURST_SIZE * MMCSD_BLOCK_SIZE) != 0)
- chSysHalt();
- }
- chprintf(chp, " OK\r\n");
- chThdSleepMilliseconds(100);
-
-
- chprintf(chp, "Multiple unaligned reads...");
- chThdSleepMilliseconds(100);
- fillbuffers(0x55);
- /* fill reference buffer from SD card */
- if (sdcRead(&SDCD1, 0, inbuf + 1, SDC_BURST_SIZE))
- chSysHalt();
- for (i=0; i<1000; i++){
- if (sdcRead(&SDCD1, 0, outbuf + 1, SDC_BURST_SIZE))
- chSysHalt();
- if (memcmp(inbuf, outbuf, SDC_BURST_SIZE * MMCSD_BLOCK_SIZE) != 0)
- chSysHalt();
- }
- chprintf(chp, " OK\r\n");
- chThdSleepMilliseconds(100);
-
-#if SDC_DATA_DESTRUCTIVE_TEST
-
- chprintf(chp, "Single aligned write...");
- chThdSleepMilliseconds(100);
- fillbuffer(0xAA, inbuf);
- if (sdcWrite(&SDCD1, 0, inbuf, 1))
- chSysHalt();
- fillbuffer(0, outbuf);
- if (sdcRead(&SDCD1, 0, outbuf, 1))
- chSysHalt();
- if (memcmp(inbuf, outbuf, MMCSD_BLOCK_SIZE) != 0)
- chSysHalt();
- chprintf(chp, " OK\r\n");
-
- chprintf(chp, "Single unaligned write...");
- chThdSleepMilliseconds(100);
- fillbuffer(0xFF, inbuf);
- if (sdcWrite(&SDCD1, 0, inbuf+1, 1))
- chSysHalt();
- fillbuffer(0, outbuf);
- if (sdcRead(&SDCD1, 0, outbuf+1, 1))
- chSysHalt();
- if (memcmp(inbuf+1, outbuf+1, MMCSD_BLOCK_SIZE) != 0)
- chSysHalt();
- chprintf(chp, " OK\r\n");
-
- chprintf(chp, "Running badblocks at 0x10000 offset...");
- chThdSleepMilliseconds(100);
- if(badblocks(0x10000, 0x11000, SDC_BURST_SIZE, 0xAA))
- chSysHalt();
- chprintf(chp, " OK\r\n");
-#endif /* !SDC_DATA_DESTRUCTIVE_TEST */
-
-
- /**
- * Now perform some FS tests.
- */
-
- FRESULT err;
- uint32_t clusters;
- FATFS *fsp;
- FIL FileObject;
- uint32_t bytes_written;
- uint32_t bytes_read;
- FILINFO filinfo;
- uint8_t teststring[] = {"This is test file\r\n"};
-
- chprintf(chp, "Register working area for filesystem... ");
- chThdSleepMilliseconds(100);
- err = f_mount(0, &SDC_FS);
- if (err != FR_OK){
- chSysHalt();
- }
- else{
- fs_ready = TRUE;
- chprintf(chp, "OK\r\n");
- }
+#define SDC_BURST_SIZE 16
+/* Buffer for block read/write operations, note that an extra byte is
+ allocated in order to support unaligned operations.*/
+static uint8_t buf[MMCSD_BLOCK_SIZE * SDC_BURST_SIZE + 1];
-#if SDC_DATA_DESTRUCTIVE_TEST
- chprintf(chp, "Formatting... ");
- chThdSleepMilliseconds(100);
- err = f_mkfs (0,0,0);
- if (err != FR_OK){
- chSysHalt();
- }
- else{
- chprintf(chp, "OK\r\n");
- }
-#endif /* SDC_DATA_DESTRUCTIVE_TEST */
-
+void cmd_sdc(BaseSequentialStream *chp, int argc, char *argv[]) {
+ static const char *mode[] = {"SDV11", "SDV20", "MMC", NULL};
+ systime_t start, end;
+ uint32_t n, startblk;
- chprintf(chp, "Mount filesystem... ");
- chThdSleepMilliseconds(100);
- err = f_getfree("/", &clusters, &fsp);
- if (err != FR_OK) {
- chSysHalt();
- }
- chprintf(chp, "OK\r\n");
- chprintf(chp,
- "FS: %lu free clusters, %lu sectors per cluster, %lu bytes free\r\n",
- clusters, (uint32_t)SDC_FS.csize,
- clusters * (uint32_t)SDC_FS.csize * (uint32_t)MMCSD_BLOCK_SIZE);
-
-
- chprintf(chp, "Create file \"chtest.txt\"... ");
- chThdSleepMilliseconds(100);
- err = f_open(&FileObject, "0:chtest.txt", FA_WRITE | FA_OPEN_ALWAYS);
- if (err != FR_OK) {
- chSysHalt();
- }
- chprintf(chp, "OK\r\n");
- chprintf(chp, "Write some data in it... ");
- chThdSleepMilliseconds(100);
- err = f_write(&FileObject, teststring, sizeof(teststring), (void *)&bytes_written);
- if (err != FR_OK) {
- chSysHalt();
- }
- else
- chprintf(chp, "OK\r\n");
+ if (argc != 1) {
+ chprintf(chp, "Usage: sdiotest read|write|all\r\n");
+ return;
+ }
- chprintf(chp, "Close file \"chtest.txt\"... ");
- err = f_close(&FileObject);
- if (err != FR_OK) {
- chSysHalt();
- }
- else
- chprintf(chp, "OK\r\n");
-
- chprintf(chp, "Check file size \"chtest.txt\"... ");
- err = f_stat("0:chtest.txt", &filinfo);
- chThdSleepMilliseconds(100);
- if (err != FR_OK) {
- chSysHalt();
- }
- else{
- if (filinfo.fsize == sizeof(teststring))
- chprintf(chp, "OK\r\n");
- else
- chSysHalt();
- }
+ /* Card presence check.*/
+ if (!blkIsInserted(&SDCD1)) {
+ chprintf(chp, "Card not inserted, aborting.\r\n");
+ return;
+ }
- chprintf(chp, "Check file content \"chtest.txt\"... ");
- err = f_open(&FileObject, "0:chtest.txt", FA_READ | FA_OPEN_EXISTING);
- chThdSleepMilliseconds(100);
- if (err != FR_OK) {
- chSysHalt();
- }
- uint8_t buf[sizeof(teststring)];
- err = f_read(&FileObject, buf, sizeof(teststring), (void *)&bytes_read);
- if (err != FR_OK) {
- chSysHalt();
- }
- else{
- if (memcmp(teststring, buf, sizeof(teststring)) != 0){
- chSysHalt();
+ /* Connection to the card.*/
+ chprintf(chp, "Connecting... ");
+ if (sdcConnect(&SDCD1)) {
+ chprintf(chp, "failed\r\n");
+ return;
+ }
+ chprintf(chp, "OK\r\n\r\nCard Info\r\n");
+ chprintf(chp, "CSD : %08X %8X %08X %08X \r\n",
+ SDCD1.csd[3], SDCD1.csd[2], SDCD1.csd[1], SDCD1.csd[0]);
+ chprintf(chp, "CID : %08X %8X %08X %08X \r\n",
+ SDCD1.cid[3], SDCD1.cid[2], SDCD1.cid[1], SDCD1.cid[0]);
+ chprintf(chp, "Mode : %s\r\n", mode[SDCD1.cardmode]);
+ chprintf(chp, "Capacity : %DMB\r\n", SDCD1.capacity / 2048);
+
+ /* The test is performed in the middle of the flash area.*/
+ startblk = (SDCD1.capacity / MMCSD_BLOCK_SIZE) / 2;
+
+ if ((strcmp(argv[0], "read") == 0) ||
+ (strcmp(argv[0], "all") == 0)) {
+
+ /* Single block read performance, aligned.*/
+ chprintf(chp, "Single block aligned read performance: ");
+ start = chVTGetSystemTime();
+ end = start + MS2ST(1000);
+ n = 0;
+ do {
+ if (blkRead(&SDCD1, startblk, buf, 1)) {
+ chprintf(chp, "failed\r\n");
+ goto exittest;
}
- else{
- chprintf(chp, "OK\r\n");
+ n++;
+ } while (chVTIsSystemTimeWithin(start, end));
+ chprintf(chp, "%D blocks/S, %D bytes/S\r\n", n, n * MMCSD_BLOCK_SIZE);
+
+ /* Multiple sequential blocks read performance, aligned.*/
+ chprintf(chp, "16 sequential blocks aligned read performance: ");
+ start = chVTGetSystemTime();
+ end = start + MS2ST(1000);
+ n = 0;
+ do {
+ if (blkRead(&SDCD1, startblk, buf, SDC_BURST_SIZE)) {
+ chprintf(chp, "failed\r\n");
+ goto exittest;
}
- }
-
- chprintf(chp, "Umount filesystem... ");
- f_mount(0, NULL);
- chprintf(chp, "OK\r\n");
-
- chprintf(chp, "Disconnecting from SDIO...");
- chThdSleepMilliseconds(100);
- if (sdcDisconnect(&SDCD1))
- chSysHalt();
- chprintf(chp, " OK\r\n");
- chprintf(chp, "------------------------------------------------------\r\n");
- chprintf(chp, "All tests passed successfully.\r\n");
- chThdSleepMilliseconds(100);
- }
- else{
- chSysHalt();
+ n += SDC_BURST_SIZE;
+ } while (chVTIsSystemTimeWithin(start, end));
+ chprintf(chp, "%D blocks/S, %D bytes/S\r\n", n, n * MMCSD_BLOCK_SIZE);
+
+#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
+ /* Single block read performance, unaligned.*/
+ chprintf(chp, "Single block unaligned read performance: ");
+ start = chVTGetSystemTime();
+ end = start + MS2ST(1000);
+ n = 0;
+ do {
+ if (blkRead(&SDCD1, startblk, buf + 1, 1)) {
+ chprintf(chp, "failed\r\n");
+ goto exittest;
+ }
+ n++;
+ } while (chVTIsSystemTimeWithin(start, end));
+ chprintf(chp, "%D blocks/S, %D bytes/S\r\n", n, n * MMCSD_BLOCK_SIZE);
+
+ /* Multiple sequential blocks read performance, unaligned.*/
+ chprintf(chp, "16 sequential blocks unaligned read performance: ");
+ start = chVTGetSystemTime();
+ end = start + MS2ST(1000);
+ n = 0;
+ do {
+ if (blkRead(&SDCD1, startblk, buf + 1, SDC_BURST_SIZE)) {
+ chprintf(chp, "failed\r\n");
+ goto exittest;
+ }
+ n += SDC_BURST_SIZE;
+ } while (chVTIsSystemTimeWithin(start, end));
+ chprintf(chp, "%D blocks/S, %D bytes/S\r\n", n, n * MMCSD_BLOCK_SIZE);
+#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */
}
-}
+ if ((strcmp(argv[0], "write") == 0) ||
+ (strcmp(argv[0], "all") == 0)) {
-/*
- * SDIO configuration.
- */
-static const SDCConfig sdccfg = {
- 0
-};
+ }
+
+ /* Card disconnect and command end.*/
+exittest:
+ sdcDisconnect(&SDCD1);
+}
-/**
- *
- */
-static SerialConfig ser_cfg = {
- 115200,
- 0,
- 0,
- 0,
-};
static const ShellCommand commands[] = {
- {"sdiotest", cmd_sdiotest},
+ {"sdc", cmd_sdc},
{NULL, NULL}
};
+
static const ShellConfig shell_cfg1 = {
- (BaseSequentialStream *)&SD2,
+ (BaseSequentialStream *)&SD6,
commands
};
@@ -357,14 +176,27 @@ static const ShellConfig shell_cfg1 = { * Application entry point.
*/
int main(void) {
+ thread_t *shelltp = NULL;
+
+ /*
+ * System initializations.
+ * - HAL initialization, this also initializes the configured device drivers
+ * and performs the board-specific initializations.
+ * - Kernel initialization, the main() function becomes a thread and the
+ * RTOS is active.
+ */
halInit();
chSysInit();
- /* start debugging serial link */
- sdStart(&SD2, &ser_cfg);
+ /*
+ * Shell manager initialization.
+ */
shellInit();
- static WORKING_AREA(waShell, 2048);
- shellCreateStatic(&shell_cfg1, waShell, sizeof(waShell), NORMALPRIO);
+
+ /*
+ * Activates the serial driver 6 using the driver default configuration.
+ */
+ sdStart(&SD6, NULL);
/*
* Initializes the SDIO drivers.
@@ -372,11 +204,20 @@ int main(void) { sdcStart(&SDCD1, &sdccfg);
/*
- * Normal main() thread activity.
- * Blinking signaling about successful passing.
+ * Creates the blinker thread.
+ */
+ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
+
+ /*
+ * Normal main() thread activity, in this demo it does nothing.
*/
while (TRUE) {
- palTogglePad(GPIOB, GPIOB_LED_R);
- chThdSleepMilliseconds(100);
+ if (!shelltp)
+ shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
+ else if (chThdTerminatedX(shelltp)) {
+ chThdRelease(shelltp); /* Recovers memory of the previous shell. */
+ shelltp = NULL; /* Triggers spawning of a new shell. */
+ }
+ chThdSleepMilliseconds(1000);
}
}
|