/* * sd_fat.c * * Created on: 17 дек. 2016 г. * Author: PVV */ #include "rtl8195a.h" #ifdef CONFIG_SDIO_HOST_EN #include "rtl8195a_sdio_host.h" #include "hal_sdio_host.h" #include "sd.h" #include "sdio_host.h" #include "pinmap.h" #include "sdcard.h" //#include "ff.h" //#include "fatfs_ext/inc/ff_driver.h" #include "rtl8195a/os.h" #include "at_cmd/log_service.h" //extern ll_diskio_drv SD_disk_Driver; char *logical_drv = "0:/"; #define START_CHAR_DISK '0' typedef struct _msftm_td { unsigned short day :5; unsigned short month :4; unsigned short year :7; } msftm_d; typedef struct _msftm_tt { unsigned short sec :5; unsigned short min :6; unsigned short hour :5; } msftm_t; typedef union { unsigned short w; msftm_d d; } msftm_td; typedef union { unsigned short w; msftm_t t; } msftm_tt; uint8_t * month[12] = { "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; /* * MS files times */ int ms_ftime(unsigned short td, unsigned short tt, struct os_tm *tm) { msftm_td d; msftm_tt t; d.w = td; t.w = tt; tm->year = d.d.year + 1980; tm->month = d.d.month; tm->day = d.d.day; tm->hour = t.t.hour; tm->min = t.t.min; tm->sec = t.t.sec << 1; if (tm->month > 11 || tm->hour > 23 || tm->min > 59 || tm->sec > 59) { return 0; } return 1; } /* * MS files attr */ uint8_t * ms_fattr(uint8_t *s, uint8_t attr) { memset(s, '-', 7); if (attr & AM_ARC) s[0] = 'a'; if (attr & AM_DIR) s[1] = 'd'; if (attr & AM_LFN) s[2] = 'l'; if (attr & AM_VOL) s[3] = 'v'; if (attr & AM_SYS) s[4] = 's'; if (attr & AM_HID) s[5] = 'h'; if (attr & AM_RDO) s[6] = 'r'; s[7] = 0; return s; } /* * Linux files attr */ uint8_t * ux_fattr(uint8_t *s, uint8_t attr) { memset(s, '-', 10); if (attr & AM_DIR) { s[0] = 'd'; // s[3] = 'x'; // s[6] = 'x'; // s[9] = 'x'; } if (!(attr & AM_VOL)) { // { s[1] = 'r'; s[4] = 'r'; s[7] = 'r'; if (!(attr & AM_RDO)) { s[2] = 'w'; s[5] = 'w'; s[8] = 'w'; } } // if(attr & AM_VOL) s[3] = 'x'; if (!(attr & AM_SYS)) s[3] = 'x'; if (!(attr & AM_HID)) s[6] = 'x'; if (!(attr & AM_ARC)) s[9] = 'x'; s[10] = 0; return s; } FATFS * sd_mount(void) { FATFS * m_fs = NULL; // Инициализация I/O SDIOH if (HalGetChipId() != CHIP_ID_8195AM) { GPIOState[0] &= ~((1 << 8) - 1); HAL_GPIO_PullCtrl(PA_0, PullUp); // D2 HAL_GPIO_PullCtrl(PA_1, PullUp); // D3 HAL_GPIO_PullCtrl(PA_2, PullUp); // CMD HAL_GPIO_PullCtrl(PA_3, PullNone); // CLK HAL_GPIO_PullCtrl(PA_4, PullUp); // D0 HAL_GPIO_PullCtrl(PA_5, PullUp); // D1 HAL_GPIO_PullCtrl(PA_6, PullDown); // SD card removed HAL_GPIO_PullCtrl(PA_7, PullDown); // WP enable vTaskDelay(1); }; int8_t ret = SD_Init(); if (ret < SD_NODISK) { // sdio_sd_init(); if (sdio_sd_status() >= 0 && sdio_status == SDIO_SD_OK) { sdio_sd_getProtection(); #if CONFIG_DEBUG_LOG > 2 // чтение информации о SD карте printf("\nSD CSD: "); for (int i = 0; i < 16; i++) printf("%02x", SdioHostAdapter.Csd[i]); uint32_t i = sdio_sd_getCapacity(); printf("\nSD Capacity: %d sectors (%d GB | %d MB | %d KB)\n", i, i >> 21, i >> 11, i >> 1); #endif m_fs = (FATFS *) malloc(sizeof(FATFS)); if (m_fs != NULL) { memset(m_fs, 0, sizeof(FATFS)); int drv_num = FATFS_RegisterDiskDriver(&SD_disk_Driver); if (drv_num >= 0) { *logical_drv = (char) drv_num + START_CHAR_DISK; if (f_mount(m_fs, logical_drv, 1) == FR_OK) { m_fs->drv = (BYTE) drv_num; #if CONFIG_DEBUG_LOG > 3 printf("SD disk:%c mounted\n", logical_drv[0], m_fs); #endif } else { #if CONFIG_DEBUG_LOG > 2 printf("SD disk mount failed!\n"); #endif FATFS_UnRegisterDiskDriver(drv_num); free(m_fs); m_fs = NULL; } } else { #if CONFIG_DEBUG_LOG > 2 printf("SD Register Disk Driver failed!\n"); #endif free(m_fs); m_fs = NULL; } } else { #if CONFIG_DEBUG_LOG > 2 printf("Malloc failed!\n"); #endif } } else { #if CONFIG_DEBUG_LOG > 2 printf("SD Error (%d) get status!\n", sdio_status); #endif } } else { #if CONFIG_DEBUG_LOG > 2 printf("SD Init Error (%d)!\n", ret); #endif } return m_fs; } void sd_unmount(FATFS *m_fs) { if (m_fs != NULL) { #if CONFIG_DEBUG_LOG > 2 printf("unmount (%d)\n", f_mount(NULL, logical_drv, 1)); #else f_mount(NULL, logical_drv, 1); #endif FATFS_UnRegisterDiskDriver(m_fs->drv); free(m_fs); } pin_mode(PA_6, PullUp); // SD card removed pin_mode(PA_7, PullUp); // WP enable vTaskDelay(1); SD_DeInit(); // sdio_sd_deinit(); } void read_file_test(char* file_name) { FIL *f = malloc(sizeof(FIL)); if (f_open(f, file_name, FA_READ) == FR_OK) { char * buf = malloc(2048); unsigned int bytesread =0; unsigned int totalread=0; do { if (f_read(f, buf, 2048, &bytesread) != FR_OK) { totalread += bytesread; printf("Read error!"); break; } totalread += bytesread; } while (bytesread !=0); free(buf); f_close(f); } else { printf("No open file!"); } free(f); } static void fATHF(int argc, char *argv[]) { uint8 buf[512]; FATFS * fs = sd_mount(); if (fs != NULL) { uint8_t * pbuf = (uint8_t *) malloc(512); // char *lfn = malloc (_MAX_LFN + 1); if (pbuf != NULL) { DIR dir; FILINFO fno; fno.lfname = (TCHAR*) pbuf; fno.lfsize = 512; uint8_t * sdir; if(argc > 1 && argv[1] != NULL && (sdir = (uint8_t *) malloc(strlen(argv[1]) + 4)) != NULL ) strcpy(strcpy(sdir, logical_drv) + 3, argv[1]); else sdir = logical_drv; if (f_opendir(&dir, sdir) == FR_OK) { while (f_readdir(&dir, &fno) == FR_OK && fno.fname[0] != 0) { if ((fno.fattrib & AM_VOL)==0 && fno.fsize > 0) { if (*fno.lfname) { strcpy(strcpy(buf, logical_drv) + 3, fno.lfname); } else { strcpy(strcpy(buf, logical_drv) + 3, fno.fname); } TickType_t t1 = xTaskGetTickCount(); read_file_test(buf); t1 = xTaskGetTickCount() - t1; if(t1 == 0) t1 = 1; printf("%u kbytes/sec\t%s\n", t1, buf); } } } else printf("FATFS: Open dir fail!\n"); free(pbuf); if((void *)sdir != (void *)logical_drv) free(sdir); } } sd_unmount(fs); } /* Test SD */ static void fATHS(int argc, char *argv[]) { // HalPinCtrlRtl8195A(UART0,0,0); // HalPinCtrlRtl8195A(UART1,0,0); #if CONFIG_DEBUG_LOG > 4 ConfigDebugErr = -1; ConfigDebugInfo = -1; ConfigDebugWarn = -1; CfgSysDebugErr = -1; CfgSysDebugInfo = -1; CfgSysDebugWarn = -1; #endif #if DEBUG_AT_USER_LEVEL > 3 printf("ATHS: dir\n"); #endif FATFS * fs = sd_mount(); if (fs != NULL) { uint8_t * pbuf = (uint8_t *) malloc(512); // char *lfn = malloc (_MAX_LFN + 1); if (pbuf != NULL) { DIR dir; FILINFO fno; struct os_tm tm; fno.lfname = (TCHAR*) pbuf; fno.lfsize = 512; uint8_t * sdir; if(argc > 1 && argv[1] != NULL && (sdir = (uint8_t *) malloc(strlen(argv[1]) + 4)) != NULL ) strcpy(strcpy(sdir, logical_drv) + 3, argv[1]); else sdir = logical_drv; printf("\ndir %s\n", sdir); if (f_opendir(&dir, sdir) == FR_OK) { while (f_readdir(&dir, &fno) == FR_OK && fno.fname[0] != 0) { int srtlen = 0; { uint8_t buf[12]; srtlen += printf(ux_fattr(buf, fno.fattrib)); } srtlen += printf(" 0"); if (fno.fattrib & AM_VOL) printf(" volume"); else if (fno.fattrib & AM_SYS) printf(" system"); else printf(" none "); srtlen += 7; if (fno.fattrib & AM_HID) printf(" hidden"); else printf(" none "); srtlen += 7; srtlen += printf(" %d", fno.fsize); while (srtlen < 37) srtlen += printf(" "); ms_ftime(fno.fdate, fno.ftime, &tm); srtlen += printf(" %04d-%02d-%02d %02d:%02d:%02d ", tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec); if (*fno.lfname) { srtlen += printf(fno.lfname); //fnlen = fno.lfsize; } else { srtlen += printf(fno.fname); //fnlen = fno.fsize; } printf("\n"); }; printf("\n"); f_closedir(&dir); } else printf("FATFS: Open dir fail!\n"); free(pbuf); if((void *)sdir != (void *)logical_drv) free(sdir); } } sd_unmount(fs); /* } else printf("FATFS: Malloc fail!\n"); f_mount(NULL, logical_drv, 1); } else printf("FATFS mount logical drive fail!\n"); FATFS_UnRegisterDiskDriver(drv_num); } else printf("Register disk driver to FATFS fail.\n"); free(m_fs); } else printf("FATFS: Malloc fail!\n"); } else printf("SD Init fail!\n"); pin_mode(PA_6, PullUp); // SD card removed pin_mode(PA_7, PullUp); // WP enable vTaskDelay(5); SD_DeInit(); // sdio_sd_deinit(); */ } MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_dscard[] = { {"ATHS", 0, fATHS, "=[dir]: SD test"}, {"ATHF", 0, fATHF, "=[dir]: SD file read"} }; #endif // CONFIG_SDIO_HOST_EN