From 16f10822864c01278a4f8d450136f8d88f29f87e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 15 Jun 2013 16:38:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5856 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- testhal/STM32F4xx/SDC/main.c | 382 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 testhal/STM32F4xx/SDC/main.c (limited to 'testhal/STM32F4xx/SDC/main.c') diff --git a/testhal/STM32F4xx/SDC/main.c b/testhal/STM32F4xx/SDC/main.c new file mode 100644 index 000000000..721eac66b --- /dev/null +++ b/testhal/STM32F4xx/SDC/main.c @@ -0,0 +1,382 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include "ch.h" +#include "hal.h" + +#include "shell.h" +#include "chprintf.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; + +/** + * @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. + */ +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; + } + + /* 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; + } + 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; +} + +/** + * + */ +void fillbuffers(uint8_t pattern){ + fillbuffer(pattern, inbuf); + fillbuffer(pattern, outbuf); +} + +/** + * + */ +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"); + } + + +#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 */ + + + 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"); + + 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(); + } + + 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(); + } + else{ + chprintf(chp, "OK\r\n"); + } + } + + 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(); + } +} + + +/* + * SDIO configuration. + */ +static const SDCConfig sdccfg = { + 0 +}; + +/** + * + */ +static SerialConfig ser_cfg = { + 115200, + 0, + 0, + 0, +}; +static const ShellCommand commands[] = { + {"sdiotest", cmd_sdiotest}, + {NULL, NULL} +}; +static const ShellConfig shell_cfg1 = { + (BaseSequentialStream *)&SD2, + commands +}; + +/* + * Application entry point. + */ +int main(void) { + halInit(); + chSysInit(); + + /* start debugging serial link */ + sdStart(&SD2, &ser_cfg); + shellInit(); + static WORKING_AREA(waShell, 2048); + shellCreateStatic(&shell_cfg1, waShell, sizeof(waShell), NORMALPRIO); + + /* + * Initializes the SDIO drivers. + */ + sdcStart(&SDCD1, &sdccfg); + + /* + * Normal main() thread activity. + * Blinking signaling about successful passing. + */ + while (TRUE) { + palTogglePad(GPIOB, GPIOB_LED_R); + chThdSleepMilliseconds(100); + } +} -- cgit v1.2.3