/*! * \brief Card insertion event. * * Also use at power up to see if card was or remained * inserted while power unavailable. */ void sdc_insert_handler(eventid_t id) { FRESULT err; (void)id; /*! \todo generate a mailbox event here */ /*! \todo test event message system */ /*! * On insertion SDC initialization and FS mount. */ if (sdcConnect(&SDCD1)) { if(sdcConnect(&SDCD1)) { // why does it often fail the first time but not the second? return; } } err = f_mount(0, &SDC_FS); if (err != FR_OK) { err = f_mount(0, &SDC_FS); if (err != FR_OK) { sdcDisconnect(&SDCD1); return; } } sdc_reset_fp_index(); fs_ready = TRUE; chEvtBroadcast(&sdc_start_event); }
void sd_t::Init() { IsReady = FALSE; // Bus pins PinSetupAlterFunc(GPIOC, 8, omPushPull, pudPullUp, AF12, ps50MHz); PinSetupAlterFunc(GPIOC, 9, omPushPull, pudPullUp, AF12, ps50MHz); PinSetupAlterFunc(GPIOC, 10, omPushPull, pudPullUp, AF12, ps50MHz); PinSetupAlterFunc(GPIOC, 11, omPushPull, pudPullUp, AF12, ps50MHz); PinSetupAlterFunc(GPIOC, 12, omPushPull, pudNone, AF12, ps50MHz); PinSetupAlterFunc(GPIOD, 2, omPushPull, pudPullUp, AF12, ps50MHz); // Power pin PinSetupOut(GPIOC, 4, omPushPull, pudNone); PinClear(GPIOC, 4); // Power on Delay_ms(450); FRESULT err; sdcInit(); sdcStart(&SDCD1, NULL); if (sdcConnect(&SDCD1)) { Uart.Printf("SD connect error\r"); return; } else { Uart.Printf("SD capacity: %u\r", SDCD1.capacity); } err = f_mount(0, &SDC_FS); if (err != FR_OK) { Uart.Printf("SD mount error\r"); sdcDisconnect(&SDCD1); return; } IsReady = TRUE; }
/* * SD card removal event. */ static void RemoveHandler(eventid_t id) { (void)id; if (sdcGetDriverState(&SDCD1) == SDC_ACTIVE) sdcDisconnect(&SDCD1); fs_ready = FALSE; }
void poll_inserted() { const auto card_present_now = sdcIsCardInserted(&SDCD1); if( card_present_now != card_present ) { card_present = card_present_now; Status new_status { card_present ? Status::Present : Status::NotPresent }; if( card_present ) { if( sdcConnect(&SDCD1) == CH_SUCCESS ) { if( mount() == FR_OK ) { new_status = Status::Mounted; } else { new_status = Status::MountError; } } else { new_status = Status::ConnectError; } } else { sdcDisconnect(&SDCD1); } status_ = new_status; status_signal.emit(status_); } }
// Card removal event. static void RemoveHandler( eventid_t id ) { (void)id; sdcDisconnect( &SDCD1 ); DPRINT( 2, KYEL "[ FatFS ] Card removed\r\n" ); fs_ready = FALSE; }
//----------------------------------------------------------------------------- // usually alreay too late to actually disconnect, but it's good to have // things in a known state static void on_remove(void) { sdcDisconnect(&SDCD1); kbs_setSDCFree(0); kbs_setFName(KUROBOX_BLANK_FNAME); kbs_err_setSD(0); fs_ready = FALSE; }
bool sdioDisconnect (void) { if (cnxState == STOP) return true; if (sdcDisconnect(&SDCD1)) { return false; } sdcStop (&SDCD1); cnxState = STOP; return true; }
/* SD Card Disconnect */ static void microsd_card_deinit() { /* Unmount File System */ f_mount(0, "A", 0); /* Disconnect from card */ sdcDisconnect(&SDCD1); /* Disable SDC peripheral */ sdcStop(&SDCD1); }
void sdc_haltnow(void) { bool b_ret; chEvtBroadcast(&sdc_halt_event); chThdSleepMilliseconds(20); b_ret = sdcDisconnect(&SDCD1); if(b_ret) { SDCDEBUG("sdcDiscon fail\r\n"); // this happens a lot! b_ret = sdcDisconnect(&SDCD1); if(b_ret) { SDCDEBUG("sdcDiscon fail2\r\n"); } } sdc_reset_fp_index(); fs_ready = FALSE; SDCDEBUG("SDC card halted.\r\n"); }
bool_t sdioDisconnect (void) { if (cnxState == STOP) return TRUE; if (sdcDisconnect(&SDCD1)) { return FALSE; } sdcStop (&SDCD1); cnxState = STOP; return TRUE; }
/*! * \brief Card removal event. */ void sdc_remove_handler(eventid_t id) { (void)id; bool_t ret; chEvtBroadcast(&sdc_halt_event); chThdSleepMilliseconds(5); /*! \todo generate a mailbox event here */ /*! \todo test event message system */ ret = sdcDisconnect(&SDCD1); if(ret) { SDCDEBUG("sdcDiscon fail\r\n"); // this happens a lot! ret = sdcDisconnect(&SDCD1); if(ret) { SDCDEBUG("sdcDiscon fail2\r\n"); } } sdc_reset_fp_index(); fs_ready = FALSE; }
/* * SD card removal event. */ static void remove_handler(void) { if (fs_ready == TRUE){ f_mount(0, NULL); fs_ready = FALSE; } if ((&SDCD1)->state == BLK_ACTIVE){ sdcDisconnect(&SDCD1); sdcStop(&SDCD1); } fs_ready = FALSE; }
/* * Card insertion event. */ static void InsertHandler(eventid_t id) { FRESULT err; (void)id; /* * On insertion SDC initialization and FS mount. */ if (fs_ready) { sdcDisconnect(&SDCD1); fs_ready = FALSE; } if (sdcConnect(&SDCD1)) return; err = f_mount(0, &SDC_FS); if (err != FR_OK) { sdcDisconnect(&SDCD1); return; } fs_ready = TRUE; }
/* * SD card insertion event. */ static void insert_handler(void) { FRESULT err; sdcStart(&SDCD1, &sdccfg); /* * On insertion SDC initialization and FS mount. */ if (sdcConnect(&SDCD1)) return; err = f_mount(0, &SDC_FS); if (err != FR_OK) { sdcDisconnect(&SDCD1); sdcStop(&SDCD1); return; } fs_ready = TRUE; }
// Card insertion event. static void InsertHandler( eventid_t id ) { FRESULT err; (void)id; // On insertion SDC initialization and FS mount. if( sdcConnect( &SDCD1 ) ) return; err = f_mount( &SDC_FS, "/", 1 ); if( FR_OK != err ) { sdcDisconnect( &SDCD1 ); return; } DPRINT( 2, KYEL "[ FatFS ] Card inserted\r\n" ); fs_ready = TRUE; }
void cmd_sdiotest(BaseSequentialStream *chp, int argc, char *argv[]){ (void)argc; (void)argv; FRESULT err; uint32_t clusters; FATFS *fsp; FIL FileObject; //FILINFO FileInfo; size_t bytes_written; struct tm timp; #if !HAL_USE_RTC chprintf(chp, "ERROR! Chibios compiled without RTC support."); chprintf(chp, "Enable HAL_USE_RCT in you halconf.h"); chThdSleepMilliseconds(100); return; #endif chprintf(chp, "Trying to connect SDIO... "); chThdSleepMilliseconds(100); if (!sdcConnect(&SDCD1)) { chprintf(chp, "OK\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"); } chprintf(chp, "Mounting 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); rtcGetTimeTm(&RTCD1, &timp); chprintf(chp, "Current RTC time is: "); chprintf(chp, "%u-%u-%u %u:%u:%u\r\n", timp.tm_year+1900, timp.tm_mon+1, timp.tm_mday, timp.tm_hour, timp.tm_min, timp.tm_sec); chprintf(chp, "Creating empty file 'tmstmp.tst'... "); chThdSleepMilliseconds(100); err = f_open(&FileObject, "0:tmstmp.tst", 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, "tst", sizeof("tst"), (void *)&bytes_written); if (err != FR_OK) { chSysHalt(); } else chprintf(chp, "OK\r\n"); chprintf(chp, "Closing file 'tmstmp.tst'... "); chThdSleepMilliseconds(100); err = f_close(&FileObject); if (err != FR_OK) { chSysHalt(); } else chprintf(chp, "OK\r\n"); // chprintf(chp, "Obtaining file info ... "); // chThdSleepMilliseconds(100); // err = f_stat("0:tmstmp.tst", &FileInfo); // if (err != FR_OK) { // chSysHalt(); // } // else{ // chprintf(chp, "OK\r\n"); // chprintf(chp, " Timestamp: %u-%u-%u %u:%u:%u\r\n", // ((FileInfo.fdate >> 9) & 127) + 1980, // (FileInfo.fdate >> 5) & 15, // FileInfo.fdate & 31, // (FileInfo.ftime >> 11) & 31, // (FileInfo.ftime >> 5) & 63, // (FileInfo.ftime & 31) * 2); // } chprintf(chp, "Umounting 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, "Now you can remove memory card and check timestamp on PC.\r\n"); chThdSleepMilliseconds(100); } else{ chSysHalt(); } }
/* * Card removal event. */ static void RemoveHandler(eventid_t id) { (void)id; sdcDisconnect(&SDCD1); fs_ready = FALSE; }
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; if (argc != 1) { chprintf(chp, "Usage: sdiotest read|write|erase|all\r\n"); return; } /* Card presence check.*/ if (!blkIsInserted(&SDCD1)) { chprintf(chp, "Card not inserted, aborting.\r\n"); return; } /* 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 & 3U]); 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; } 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; } 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)) { unsigned i; memset(buf, 0xAA, MMCSD_BLOCK_SIZE * 2); chprintf(chp, "Writing..."); if(sdcWrite(&SDCD1, startblk, buf, 2)) { chprintf(chp, "failed\r\n"); goto exittest; } chprintf(chp, "OK\r\n"); memset(buf, 0x55, MMCSD_BLOCK_SIZE * 2); chprintf(chp, "Reading..."); if (blkRead(&SDCD1, startblk, buf, 1)) { chprintf(chp, "failed\r\n"); goto exittest; } chprintf(chp, "OK\r\n"); for (i = 0; i < MMCSD_BLOCK_SIZE; i++) buf[i] = i + 8; chprintf(chp, "Writing..."); if(sdcWrite(&SDCD1, startblk, buf, 2)) { chprintf(chp, "failed\r\n"); goto exittest; } chprintf(chp, "OK\r\n"); memset(buf, 0, MMCSD_BLOCK_SIZE * 2); chprintf(chp, "Reading..."); if (blkRead(&SDCD1, startblk, buf, 1)) { chprintf(chp, "failed\r\n"); goto exittest; } chprintf(chp, "OK\r\n"); } if ((strcmp(argv[0], "erase") == 0) || (strcmp(argv[0], "all") == 0)) { /** * Test sdcErase() * Strategy: * 1. Fill two blocks with non-constant data * 2. Write two blocks starting at startblk * 3. Erase the second of the two blocks * 3.1. First block should be equal to the data written * 3.2. Second block should NOT be equal too the data written (i.e. erased). * 4. Erase both first and second block * 4.1 Both blocks should not be equal to the data initially written * Precondition: SDC_BURST_SIZE >= 2 */ memset(buf, 0, MMCSD_BLOCK_SIZE * 2); memset(buf2, 0, MMCSD_BLOCK_SIZE * 2); /* 1. */ unsigned int i = 0; for (; i < MMCSD_BLOCK_SIZE * 2; ++i) { buf[i] = (i + 7) % 'T'; //Ensure block 1/2 are not equal } /* 2. */ if(sdcWrite(&SDCD1, startblk, buf, 2)) { chprintf(chp, "sdcErase() test write failed\r\n"); goto exittest; } /* 3. (erase) */ if(sdcErase(&SDCD1, startblk + 1, startblk + 2)) { chprintf(chp, "sdcErase() failed\r\n"); goto exittest; } sdcflags_t errflags = sdcGetAndClearErrors(&SDCD1); if(errflags) { chprintf(chp, "sdcErase() yielded error flags: %d\r\n", errflags); goto exittest; } if(sdcRead(&SDCD1, startblk, buf2, 2)) { chprintf(chp, "single-block sdcErase() failed\r\n"); goto exittest; } /* 3.1. */ if(memcmp(buf, buf2, MMCSD_BLOCK_SIZE) != 0) { chprintf(chp, "sdcErase() non-erased block compare failed\r\n"); goto exittest; } /* 3.2. */ if(memcmp(buf + MMCSD_BLOCK_SIZE, buf2 + MMCSD_BLOCK_SIZE, MMCSD_BLOCK_SIZE) == 0) { chprintf(chp, "sdcErase() erased block compare failed\r\n"); goto exittest; } /* 4. */ if(sdcErase(&SDCD1, startblk, startblk + 2)) { chprintf(chp, "multi-block sdcErase() failed\r\n"); goto exittest; } if(sdcRead(&SDCD1, startblk, buf2, 2)) { chprintf(chp, "single-block sdcErase() failed\r\n"); goto exittest; } /* 4.1 */ if(memcmp(buf, buf2, MMCSD_BLOCK_SIZE) == 0) { chprintf(chp, "multi-block sdcErase() erased block compare failed\r\n"); goto exittest; } if(memcmp(buf + MMCSD_BLOCK_SIZE, buf2 + MMCSD_BLOCK_SIZE, MMCSD_BLOCK_SIZE) == 0) { chprintf(chp, "multi-block sdcErase() erased block compare failed\r\n"); goto exittest; } /* END of sdcErase() test */ } /* Card disconnect and command end.*/ exittest: sdcDisconnect(&SDCD1); }
//----------------------------------------------------------------------------- // the SD card has been inserted, do the necessary steps to get a sane system static int on_insert(void) { FRESULT stat; kbs_setFName(KUROBOX_LOADING_NAME); if (!sdcConnect(&SDCD1)) { kbs_setFName(KUROBOX_ERR1); return KB_NOT_OK; } stat = f_mount(&SDC_FS, "/", 1); if (stat != FR_OK) { kbs_setFName(KUROBOX_ERR2); sdcDisconnect(&SDCD1); return KB_NOT_OK; } chThdSleepMilliseconds(100); uint32_t clusters; FATFS * fsp = NULL; stat = f_getfree("/", &clusters, &fsp); if (stat != FR_OK) { kbs_setFName(KUROBOX_ERR3); sdcDisconnect(&SDCD1); return KB_NOT_OK; } uint64_t cardsize = clusters * (((uint32_t)fsp->csize * (uint32_t)MMCSD_BLOCK_SIZE) / 1024); cardsize_MB = cardsize / 1024; // @TODO: this can be moved to above the check for free space fs_write_protected = sdc_lld_is_write_protected(&SDCD1); if ( fs_write_protected ) { // -1 means that it's write protected, display that kbs_setSDCFree(-1); kbs_setFName(KUROBOX_WP_NAME); return KB_NOT_OK; } kbs_setSDCFree(cardsize_MB); stat = make_dirs(); if (stat != FR_OK) { kbs_setFName(KUROBOX_ERR4); sdcDisconnect(&SDCD1); return KB_NOT_OK; } stat = new_file(); if (stat != FR_OK) { kbs_setFName(KUROBOX_ERR5); sdcDisconnect(&SDCD1); return KB_NOT_OK; } fs_ready = TRUE; logger_state = LS_RUNNING; kbs_err_setSD(1); return KB_OK; }
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(); } }
/* * Application entry point. */ int main(void) { /* * 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(); /* * Initializes the SDIO drivers. */ sdcStart(&SDCD1, &sdccfg); if (!sdcConnect(&SDCD1)) { int i; /* Single aligned read.*/ if (sdcRead(&SDCD1, 0, blkbuf, 1)) chSysHalt(); /* Single unaligned read.*/ if (sdcRead(&SDCD1, 0, blkbuf + 1, 1)) chSysHalt(); /* Multiple aligned read.*/ if (sdcRead(&SDCD1, 0, blkbuf, 4)) chSysHalt(); /* Multiple unaligned read.*/ if (sdcRead(&SDCD1, 0, blkbuf + 1, 4)) chSysHalt(); /* Repeated multiple aligned reads.*/ for (i = 0; i < 1000; i++) { if (sdcRead(&SDCD1, 0, blkbuf, 4)) chSysHalt(); } /* Repeated multiple unaligned reads.*/ for (i = 0; i < 1000; i++) { if (sdcRead(&SDCD1, 0, blkbuf + 1, 4)) chSysHalt(); } /* Repeated multiple aligned writes.*/ for (i = 0; i < 100; i++) { if (sdcRead(&SDCD1, 0x10000, blkbuf, 4)) chSysHalt(); if (sdcWrite(&SDCD1, 0x10000, blkbuf, 4)) chSysHalt(); if (sdcWrite(&SDCD1, 0x10000, blkbuf, 4)) chSysHalt(); } /* Repeated multiple unaligned writes.*/ for (i = 0; i < 100; i++) { if (sdcRead(&SDCD1, 0x10000, blkbuf + 1, 4)) chSysHalt(); if (sdcWrite(&SDCD1, 0x10000, blkbuf + 1, 4)) chSysHalt(); if (sdcWrite(&SDCD1, 0x10000, blkbuf + 1, 4)) chSysHalt(); } if (sdcDisconnect(&SDCD1)) chSysHalt(); } /* * Normal main() thread activity. */ while (TRUE) { chThdSleepMilliseconds(500); } }
//----------------------------------------------------------------------------- // main writer thread function - is called when SD card is ready and we're just // going to keep writing until SD card is ejected. // @TODO: when file exceeds 1GB, start a new file static uint8_t writing_run(void) { uint8_t ret = 1; uint32_t writer_buffers_written = 0; while(LS_RUNNING == logger_state) { if (chThdShouldTerminateX()) { logger_state = LS_EXITING; f_sync(&kbfile); f_close(&kbfile); sdcDisconnect(&SDCD1); break; } int8_t idx = new_write_buffer_idx_to_write(); if ( idx == -1 ) { // no more buffers to write, go to sleep, wait to be notified chSysLock(); writerThreadForSleep = chThdGetSelfX(); chSchGoSleepS(CH_STATE_SUSPENDED); chSysUnlock(); // we can get woken up by either a buffer ready to be written // or a request to terminate, either way, back to the start // of the loop to check. continue; } //---------------------------------------------------------------------- // start of write kbg_setLED1(1); // here we have a full buffer ready to write write_buffer_t * buf = &write_buffers[idx]; UINT bytes_written = 0; FRESULT stat = FR_OK; DEBG_WRITER_TIME_WRITES_TIMER(0); stat = f_write(&kbfile, buf->buffer, sizeof(buf->buffer), &bytes_written); DEBG_WRITER_TIME_WRITES_TIMER(1); kbg_setLED1(0); // end of write //---------------------------------------------------------------------- if (bytes_written != sizeof(buf->buffer) || stat != FR_OK) current_msg.write_errors++; //---------------------------------------------------------------------- // start of flush //kbg_setLED2(1); DEBG_WRITER_TIME_WRITES_TIMER(2); stat = f_sync(&kbfile); DEBG_WRITER_TIME_WRITES_TIMER(3); if (stat != FR_OK) current_msg.write_errors++; // we're done, return it return_write_buffer_idx_after_writing(idx); //kbg_setLED2(0); // end of flush //---------------------------------------------------------------------- #ifdef DEBG_WRITER_TIME_WRITES chprintf(DEBG, "%12f, %12f, %12f, %d, %6d, 0x%.8d\n", (t1-t0) / 168000.0f, (t3-t2) / 168000.0f, (t3-t0) / 168000.0f, idx, bytes_written, buf->buffer); #endif // DEBG_WRITER_TIME_WRITES kbs_setWriteCount(current_msg.msg_num); kbs_setWriteErrors(current_msg.write_errors); // after X buffers, start a new file. this has to be in sync with // the logger thread, so that you both do roll over at the same time writer_buffers_written++; if ( writer_buffers_written > MAX_BUFFERS_PER_FILE ) { writer_buffers_written = 0; // we've hit the file size limit, close the old, open a new file if ( new_file() != FR_OK ) { // no new file? that's bad!! logger_state = LS_WAIT_FOR_SD; break; } } sd_card_status(); if (LS_RUNNING != logger_state) break; } return ret; }
static int sdc_done(const fstab_entry_t *dev) { (void) dev; return (sdcDisconnect(&SDCD1) == CH_FAILED) ? -1 : 0; }