| 48 | }; // namespace |
| 49 | |
| 50 | bool SDCard_begin(uint8_t slaveSelect, uint32_t freqLimit) |
| 51 | { |
| 52 | chipSelect = slaveSelect; |
| 53 | digitalWrite(chipSelect, HIGH); |
| 54 | pinMode(chipSelect, OUTPUT); |
| 55 | digitalWrite(chipSelect, HIGH); |
| 56 | |
| 57 | if(SDCardSPI == nullptr) { |
| 58 | debug_e("SDCard SPI object not created."); |
| 59 | return false; |
| 60 | } |
| 61 | |
| 62 | auto& settings = SDCardSPI->SPIDefaultSettings; |
| 63 | |
| 64 | settings.dataMode = SPI_MODE0; |
| 65 | |
| 66 | spiInitFreq = 1000000U; |
| 67 | if(freqLimit > 0 && freqLimit < spiInitFreq) { |
| 68 | spiInitFreq = freqLimit; |
| 69 | } |
| 70 | |
| 71 | // Note: Some SD cards struggle at 40MHz |
| 72 | settings.speed = std::min(freqLimit, uint32_t(40000000)); |
| 73 | |
| 74 | if(!SDCardSPI->begin()) { |
| 75 | debug_e("SDCard SPI init failed"); |
| 76 | return false; |
| 77 | } |
| 78 | |
| 79 | /* This must be allocated for the whole program life ~512Bytes*/ |
| 80 | pFatFs = new FATFS; |
| 81 | if(pFatFs == nullptr) { |
| 82 | debug_e("No heap for pFatFs"); |
| 83 | return false; |
| 84 | } |
| 85 | |
| 86 | /* Give a work area to the default drive */ |
| 87 | FRESULT mountRes = f_mount(pFatFs, "", 0); |
| 88 | if(FR_OK != mountRes) { |
| 89 | debug_e("f_mount: FAIL %d", mountRes); |
| 90 | return false; |
| 91 | } |
| 92 | |
| 93 | /* open dummy file to force card init */ |
| 94 | FIL file; |
| 95 | if(FR_OK == f_open(&file, "dummy", FA_READ)) { |
| 96 | f_close(&file); |
| 97 | } |
| 98 | |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | namespace |
| 103 | { |