You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

999 lines
30KB

  1. // adapted for Arduino SD library by Paul Stoffregen
  2. // following code is modified by Walter Zimmer from
  3. // from version provided by
  4. // Petr Gargulak (NXP Employee)
  5. //https://community.nxp.com/servlet/JiveServlet/download/339474-1-263510/SDHC_K60_Baremetal.ZIP
  6. //see also
  7. //https://community.nxp.com/thread/99202
  8. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  9. #include "kinetis.h"
  10. //#include "core_pins.h" // testing only
  11. //#include "HardwareSerial.h" // testing only
  12. // Missing in Teensyduino 1.30
  13. #ifndef MPU_CESR_VLD_MASK
  14. #define MPU_CESR_VLD_MASK 0x1u
  15. #endif
  16. /******************************************************************************
  17. * Constants
  18. ******************************************************************************/
  19. enum {
  20. SDHC_RESULT_OK = 0, /* 0: Successful */
  21. SDHC_RESULT_ERROR, /* 1: R/W Error */
  22. SDHC_RESULT_WRPRT, /* 2: Write Protected */
  23. SDHC_RESULT_NOT_READY, /* 3: Not Ready */
  24. SDHC_RESULT_PARERR, /* 4: Invalid Parameter */
  25. SDHC_RESULT_NO_RESPONSE /* 5: No Response */ // from old diskio.h
  26. };
  27. /*void print_result(int n)
  28. {
  29. switch (n) {
  30. case SDHC_RESULT_OK: serial_print("OK\n"); break;
  31. case SDHC_RESULT_ERROR: serial_print("R/W Error\n"); break;
  32. case SDHC_RESULT_WRPRT: serial_print("Write Protect\n"); break;
  33. case SDHC_RESULT_NOT_READY: serial_print("Not Ready\n"); break;
  34. case SDHC_RESULT_PARERR: serial_print("Invalid Param\n"); break;
  35. case SDHC_RESULT_NO_RESPONSE: serial_print("No Response\n"); break;
  36. default: serial_print("Unknown result\n");
  37. }
  38. }*/
  39. #define SDHC_STATUS_NOINIT 0x01 /* Drive not initialized */
  40. #define SDHC_STATUS_NODISK 0x02 /* No medium in the drive */
  41. #define SDHC_STATUS_PROTECT 0x04 /* Write protected */
  42. #define IO_SDHC_ATTRIBS (IO_DEV_ATTR_READ | IO_DEV_ATTR_REMOVE | IO_DEV_ATTR_SEEK | IO_DEV_ATTR_WRITE | IO_DEV_ATTR_BLOCK_MODE)
  43. #define SDHC_XFERTYP_RSPTYP_NO (0x00)
  44. #define SDHC_XFERTYP_RSPTYP_136 (0x01)
  45. #define SDHC_XFERTYP_RSPTYP_48 (0x02)
  46. #define SDHC_XFERTYP_RSPTYP_48BUSY (0x03)
  47. #define SDHC_XFERTYP_CMDTYP_ABORT (0x03)
  48. #define SDHC_PROCTL_EMODE_INVARIANT (0x02)
  49. #define SDHC_PROCTL_DTW_1BIT (0x00)
  50. #define SDHC_PROCTL_DTW_4BIT (0x01)
  51. #define SDHC_PROCTL_DTW_8BIT (0x10)
  52. #define SDHC_INITIALIZATION_MAX_CNT 100000
  53. /* SDHC commands */
  54. #define SDHC_CMD0 (0)
  55. #define SDHC_CMD1 (1)
  56. #define SDHC_CMD2 (2)
  57. #define SDHC_CMD3 (3)
  58. #define SDHC_CMD4 (4)
  59. #define SDHC_CMD5 (5)
  60. #define SDHC_CMD6 (6)
  61. #define SDHC_CMD7 (7)
  62. #define SDHC_CMD8 (8)
  63. #define SDHC_CMD9 (9)
  64. #define SDHC_CMD10 (10)
  65. #define SDHC_CMD11 (11)
  66. #define SDHC_CMD12 (12)
  67. #define SDHC_CMD13 (13)
  68. #define SDHC_CMD15 (15)
  69. #define SDHC_CMD16 (16)
  70. #define SDHC_CMD17 (17)
  71. #define SDHC_CMD18 (18)
  72. #define SDHC_CMD20 (20)
  73. #define SDHC_CMD24 (24)
  74. #define SDHC_CMD25 (25)
  75. #define SDHC_CMD26 (26)
  76. #define SDHC_CMD27 (27)
  77. #define SDHC_CMD28 (28)
  78. #define SDHC_CMD29 (29)
  79. #define SDHC_CMD30 (30)
  80. #define SDHC_CMD32 (32)
  81. #define SDHC_CMD33 (33)
  82. #define SDHC_CMD34 (34)
  83. #define SDHC_CMD35 (35)
  84. #define SDHC_CMD36 (36)
  85. #define SDHC_CMD37 (37)
  86. #define SDHC_CMD38 (38)
  87. #define SDHC_CMD39 (39)
  88. #define SDHC_CMD40 (40)
  89. #define SDHC_CMD42 (42)
  90. #define SDHC_CMD52 (52)
  91. #define SDHC_CMD53 (53)
  92. #define SDHC_CMD55 (55)
  93. #define SDHC_CMD56 (56)
  94. #define SDHC_CMD60 (60)
  95. #define SDHC_CMD61 (61)
  96. #define SDHC_ACMD6 (0x40 + 6)
  97. #define SDHC_ACMD13 (0x40 + 13)
  98. #define SDHC_ACMD22 (0x40 + 22)
  99. #define SDHC_ACMD23 (0x40 + 23)
  100. #define SDHC_ACMD41 (0x40 + 41)
  101. #define SDHC_ACMD42 (0x40 + 42)
  102. #define SDHC_ACMD51 (0x40 + 51)
  103. #define SDHC_FIFO_BUFFER_SIZE 16
  104. #define SDHC_BLOCK_SIZE 512
  105. /******************************************************************************
  106. * Macros
  107. ******************************************************************************/
  108. // prescale can be 2, 4, 8, 16, 32, 64, 128, 256
  109. // divisor can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
  110. #define SDHC_SYSCTL_DIVISOR(prescale, divisor) \
  111. (SDHC_SYSCTL_SDCLKFS((prescale)>>1)|SDHC_SYSCTL_DVS((divisor)-1))
  112. #if (F_CPU == 240000000)
  113. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(64, 10) // 375 kHz
  114. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 5) // 24 MHz
  115. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 3) // 40 MHz
  116. #elif (F_CPU == 216000000)
  117. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(64, 9) // 375 kHz
  118. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 5) // 21.6 MHz
  119. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 3) // 36 MHz
  120. #elif (F_CPU == 192000000)
  121. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(32, 15) // 400 kHz
  122. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 4) // 24 MHz
  123. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 48 MHz
  124. #elif (F_CPU == 180000000)
  125. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(32, 15) // 351 kHz
  126. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 4) // 22.5 MHz
  127. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 45 MHz
  128. #elif (F_CPU == 168000000)
  129. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(32, 14) // 375 kHz
  130. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 4) // 21 MHz
  131. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 42 MHz
  132. #elif (F_CPU == 144000000)
  133. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(32, 12) // 375 kHz
  134. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 3) // 24 MHz
  135. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 36 MHz
  136. #elif (F_CPU == 120000000)
  137. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(32, 10) // 375 kHz
  138. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 3) // 20 MHz
  139. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 30 MHz
  140. #elif (F_CPU == 96000000)
  141. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(16, 15) // 400 kHz
  142. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 24 MHz
  143. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 48 MHz
  144. #elif (F_CPU == 72000000)
  145. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(16, 12) // 375 kHz
  146. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 2) // 18 MHz
  147. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 36 MHz
  148. #elif (F_CPU == 48000000)
  149. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(8, 15) // 400 kHz
  150. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 24 MHz
  151. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 24 MHz
  152. #elif (F_CPU == 24000000)
  153. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(4, 15) // 500 kHz
  154. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 12 MHz
  155. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 12 MHz
  156. #elif (F_CPU == 16000000)
  157. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(4, 10) // 400 kHz
  158. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 8 MHz
  159. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 8 MHz
  160. #elif (F_CPU == 8000000)
  161. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(2, 10) // 400 kHz
  162. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 4 MHz
  163. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 4 MHz
  164. #elif (F_CPU == 4000000)
  165. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(2, 5) // 400 kHz
  166. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 2 MHz
  167. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 2 MHz
  168. #elif (F_CPU == 2000000)
  169. #define SDHC_SYSCTL_400KHZ SDHC_SYSCTL_DIVISOR(2, 3) // 333 kHz
  170. #define SDHC_SYSCTL_25MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 1 MHz
  171. #define SDHC_SYSCTL_50MHZ SDHC_SYSCTL_DIVISOR(2, 1) // 1 MHz
  172. #endif
  173. /******************************************************************************
  174. * Types
  175. ******************************************************************************/
  176. typedef struct {
  177. uint8_t status;
  178. uint8_t highCapacity;
  179. uint8_t version2;
  180. uint8_t tranSpeed;
  181. uint32_t address;
  182. uint32_t numBlocks;
  183. uint32_t lastCardStatus;
  184. } SD_CARD_DESCRIPTOR;
  185. /******************************************************************************
  186. * Global functions
  187. ******************************************************************************/
  188. uint8_t SDHC_InitCard(void);
  189. uint8_t SDHC_GetStatus(void);
  190. uint32_t SDHC_GetBlockCnt(void);
  191. int SDHC_ReadBlocks(void * buff, uint32_t sector);
  192. int SDHC_WriteBlocks(const void * buff, uint32_t sector);
  193. /******************************************************************************
  194. * Private variables
  195. ******************************************************************************/
  196. static SD_CARD_DESCRIPTOR sdCardDesc;
  197. /******************************************************************************
  198. * Private functions
  199. ******************************************************************************/
  200. static uint8_t SDHC_Init(void);
  201. static void SDHC_InitGPIO(void);
  202. static void SDHC_ReleaseGPIO(void);
  203. static void SDHC_SetClock(uint32_t sysctl);
  204. static uint32_t SDHC_WaitStatus(uint32_t mask);
  205. static int SDHC_ReadBlock(uint32_t* pData);
  206. static int SDHC_WriteBlock(const uint32_t* pData);
  207. static int SDHC_CMD_Do(uint32_t xfertyp);
  208. static int SDHC_CMD0_GoToIdle(void);
  209. static int SDHC_CMD2_Identify(void);
  210. static int SDHC_CMD3_GetAddress(void);
  211. static int SDHC_ACMD6_SetBusWidth(uint32_t address, uint32_t width);
  212. static int SDHC_CMD7_SelectCard(uint32_t address);
  213. static int SDHC_CMD8_SetInterface(uint32_t cond);
  214. static int SDHC_CMD9_GetParameters(uint32_t address);
  215. static int SDHC_CMD12_StopTransfer(void);
  216. static int SDHC_CMD12_StopTransferWaitForBusy(void);
  217. static int SDHC_CMD16_SetBlockSize(uint32_t block_size);
  218. static int SDHC_CMD17_ReadBlock(uint32_t sector);
  219. static int SDHC_CMD24_WriteBlock(uint32_t sector);
  220. static int SDHC_ACMD41_SendOperationCond(uint32_t cond);
  221. /******************************************************************************
  222. *
  223. * Public functions
  224. *
  225. ******************************************************************************/
  226. // initialize the SDHC Controller
  227. // returns status of initialization(OK, nonInit, noCard, CardProtected)
  228. static uint8_t SDHC_Init(void)
  229. {
  230. int i;
  231. // Enable clock to SDHC peripheral
  232. SIM_SCGC3 |= SIM_SCGC3_SDHC;
  233. // Enable clock to PORT E peripheral (all SDHC BUS signals)
  234. SIM_SCGC5 |= SIM_SCGC5_PORTE;
  235. SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
  236. SIM_SCGC7 |= SIM_SCGC7_DMA;
  237. // Enable DMA access via MPU (not currently used)
  238. MPU_CESR &= ~MPU_CESR_VLD_MASK;
  239. // De-init GPIO - to prevent unwanted clocks on bus
  240. SDHC_ReleaseGPIO();
  241. /* Reset SDHC */
  242. SDHC_SYSCTL = SDHC_SYSCTL_RSTA | SDHC_SYSCTL_SDCLKFS(0x80);
  243. while (SDHC_SYSCTL & SDHC_SYSCTL_RSTA) ; // wait
  244. /* Initial values */ // to do - Check values
  245. SDHC_VENDOR = 0;
  246. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(SDHC_BLOCK_SIZE);
  247. SDHC_PROCTL = SDHC_PROCTL_EMODE(SDHC_PROCTL_EMODE_INVARIANT) | SDHC_PROCTL_D3CD;
  248. SDHC_WML = SDHC_WML_RDWML(SDHC_FIFO_BUFFER_SIZE) | SDHC_WML_WRWML(SDHC_FIFO_BUFFER_SIZE);
  249. /* Set the SDHC initial baud rate divider and start */
  250. //SDHC_SetBaudrate(400);
  251. SDHC_SetClock(SDHC_SYSCTL_400KHZ);
  252. /* Poll inhibit bits */
  253. while (SDHC_PRSSTAT & (SDHC_PRSSTAT_CIHB | SDHC_PRSSTAT_CDIHB)) { };
  254. /* Init GPIO again */
  255. SDHC_InitGPIO();
  256. /* Enable requests */
  257. SDHC_IRQSTAT = 0xFFFF;
  258. SDHC_IRQSTATEN = SDHC_IRQSTATEN_DMAESEN | SDHC_IRQSTATEN_AC12ESEN | SDHC_IRQSTATEN_DEBESEN |
  259. SDHC_IRQSTATEN_DCESEN | SDHC_IRQSTATEN_DTOESEN | SDHC_IRQSTATEN_CIESEN |
  260. SDHC_IRQSTATEN_CEBESEN | SDHC_IRQSTATEN_CCESEN | SDHC_IRQSTATEN_CTOESEN |
  261. SDHC_IRQSTATEN_BRRSEN | SDHC_IRQSTATEN_BWRSEN | SDHC_IRQSTATEN_DINTSEN |
  262. SDHC_IRQSTATEN_CRMSEN | SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN;
  263. // initial clocks... SD spec says only 74 clocks are needed, but if Teensy rebooted
  264. // while the card was in middle of an operation, thousands of clock cycles can be
  265. // needed to get the card to complete a prior command and return to a usable state.
  266. for (i=0; i < 500; i++) {
  267. SDHC_SYSCTL |= SDHC_SYSCTL_INITA;
  268. while (SDHC_SYSCTL & SDHC_SYSCTL_INITA) { };
  269. }
  270. // to do - check if this needed
  271. SDHC_IRQSTAT |= SDHC_IRQSTAT_CRM;
  272. // Check card
  273. if (SDHC_PRSSTAT & SDHC_PRSSTAT_CINS) {
  274. return 0;
  275. } else {
  276. return SDHC_STATUS_NODISK;
  277. }
  278. }
  279. uint8_t KinetisSDHC_GetCardType(void)
  280. {
  281. if (sdCardDesc.status) return 0;
  282. if (sdCardDesc.version2 == 0) return 1; // SD_CARD_TYPE_SD1
  283. if (sdCardDesc.highCapacity == 0) return 2; // SD_CARD_TYPE_SD2
  284. return 3; // SD_CARD_TYPE_SDHC
  285. }
  286. // initialize the SDHC Controller and SD Card
  287. // returns status of initialization(OK, nonInit, noCard, CardProtected)
  288. uint8_t KinetisSDHC_InitCard(void)
  289. {
  290. uint8_t resS;
  291. int resR;
  292. uint32_t i;
  293. resS = SDHC_Init();
  294. sdCardDesc.status = resS;
  295. sdCardDesc.address = 0;
  296. sdCardDesc.highCapacity = 0;
  297. sdCardDesc.version2 = 0;
  298. sdCardDesc.numBlocks = 0;
  299. if (resS)
  300. return resS;
  301. resR = SDHC_CMD0_GoToIdle();
  302. if (resR) {
  303. sdCardDesc.status = SDHC_STATUS_NOINIT;
  304. return SDHC_STATUS_NOINIT;
  305. }
  306. resR = SDHC_CMD8_SetInterface(0x000001AA); // 3.3V and AA check pattern
  307. if (resR == SDHC_RESULT_OK) {
  308. if (SDHC_CMDRSP0 != 0x000001AA) {
  309. sdCardDesc.status = SDHC_STATUS_NOINIT;
  310. return SDHC_STATUS_NOINIT;
  311. }
  312. sdCardDesc.highCapacity = 1;
  313. } else if (resR == SDHC_RESULT_NO_RESPONSE) {
  314. // version 1 cards do not respond to CMD8
  315. } else {
  316. sdCardDesc.status = SDHC_STATUS_NOINIT;
  317. return SDHC_STATUS_NOINIT;
  318. }
  319. if (SDHC_ACMD41_SendOperationCond(0)) {
  320. sdCardDesc.status = SDHC_STATUS_NOINIT;
  321. return SDHC_STATUS_NOINIT;
  322. }
  323. if (SDHC_CMDRSP0 & 0x300000) {
  324. uint32_t condition = 0x00300000;
  325. if (sdCardDesc.highCapacity)
  326. condition |= 0x40000000;
  327. i = 0;
  328. do {
  329. i++;
  330. if (SDHC_ACMD41_SendOperationCond(condition)) {
  331. resS = SDHC_STATUS_NOINIT;
  332. break;
  333. }
  334. } while ((!(SDHC_CMDRSP0 & 0x80000000)) && (i < SDHC_INITIALIZATION_MAX_CNT));
  335. if (resS)
  336. return resS;
  337. if ((i >= SDHC_INITIALIZATION_MAX_CNT) || (!(SDHC_CMDRSP0 & 0x40000000)))
  338. sdCardDesc.highCapacity = 0;
  339. }
  340. // Card identify
  341. if(SDHC_CMD2_Identify()) {
  342. sdCardDesc.status = SDHC_STATUS_NOINIT;
  343. return SDHC_STATUS_NOINIT;
  344. }
  345. // Get card address
  346. if(SDHC_CMD3_GetAddress()) {
  347. sdCardDesc.status = SDHC_STATUS_NOINIT;
  348. return SDHC_STATUS_NOINIT;
  349. }
  350. sdCardDesc.address = SDHC_CMDRSP0 & 0xFFFF0000;
  351. // Get card parameters
  352. if(SDHC_CMD9_GetParameters(sdCardDesc.address)) {
  353. sdCardDesc.status = SDHC_STATUS_NOINIT;
  354. return SDHC_STATUS_NOINIT;
  355. }
  356. if (!(SDHC_CMDRSP3 & 0x00C00000)) {
  357. uint32_t read_bl_len, c_size, c_size_mult;
  358. read_bl_len = (SDHC_CMDRSP2 >> 8) & 0x0F;
  359. c_size = SDHC_CMDRSP2 & 0x03;
  360. c_size = (c_size << 10) | (SDHC_CMDRSP1 >> 22);
  361. c_size_mult = (SDHC_CMDRSP1 >> 7) & 0x07;
  362. sdCardDesc.numBlocks = (c_size + 1) * (1 << (c_size_mult + 2)) * (1 << (read_bl_len - 9));
  363. } else {
  364. uint32_t c_size;
  365. sdCardDesc.version2 = 1;
  366. c_size = (SDHC_CMDRSP1 >> 8) & 0x003FFFFF;
  367. sdCardDesc.numBlocks = (c_size + 1) << 10;
  368. }
  369. // Select card
  370. if (SDHC_CMD7_SelectCard(sdCardDesc.address)) {
  371. sdCardDesc.status = SDHC_STATUS_NOINIT;
  372. return SDHC_STATUS_NOINIT;
  373. }
  374. // Set Block Size to 512
  375. // Block Size in SDHC Controller is already set to 512 by SDHC_Init();
  376. // Set 512 Block size in SD card
  377. if (SDHC_CMD16_SetBlockSize(SDHC_BLOCK_SIZE)) {
  378. sdCardDesc.status = SDHC_STATUS_NOINIT;
  379. return SDHC_STATUS_NOINIT;
  380. }
  381. // Set 4 bit data bus width
  382. if (SDHC_ACMD6_SetBusWidth(sdCardDesc.address, 2)) {
  383. sdCardDesc.status = SDHC_STATUS_NOINIT;
  384. return SDHC_STATUS_NOINIT;
  385. }
  386. // Set Data bus width also in SDHC controller
  387. SDHC_PROCTL &= (~ SDHC_PROCTL_DTW_MASK);
  388. SDHC_PROCTL |= SDHC_PROCTL_DTW(SDHC_PROCTL_DTW_4BIT);
  389. // De-Init GPIO
  390. SDHC_ReleaseGPIO();
  391. // Set the SDHC default baud rate
  392. SDHC_SetClock(SDHC_SYSCTL_25MHZ);
  393. // TODO: use CMD6 and CMD9 to detect if card supports 50 MHz
  394. // then use CMD4 to configure card to high speed mode,
  395. // and SDHC_SetClock() for 50 MHz config
  396. // Init GPIO
  397. SDHC_InitGPIO();
  398. return sdCardDesc.status;
  399. }
  400. // read a block from disk
  401. // buff - pointer on buffer where read data should be stored
  402. // sector - index of start sector
  403. int KinetisSDHC_ReadBlock(void * buff, uint32_t sector)
  404. {
  405. int result;
  406. uint32_t* pData = (uint32_t*)buff;
  407. // Check if this is ready
  408. if (sdCardDesc.status != 0)
  409. return SDHC_RESULT_NOT_READY;
  410. // Convert LBA to uint8_t address if needed
  411. if (!sdCardDesc.highCapacity)
  412. sector *= 512;
  413. SDHC_IRQSTAT = 0xffff;
  414. // Just single block mode is needed
  415. result = SDHC_CMD17_ReadBlock(sector);
  416. if(result != SDHC_RESULT_OK) return result;
  417. result = SDHC_ReadBlock(pData);
  418. // finish up
  419. while (!(SDHC_IRQSTAT & SDHC_IRQSTAT_TC)) { } // wait for transfer to complete
  420. SDHC_IRQSTAT = (SDHC_IRQSTAT_TC | SDHC_IRQSTAT_BRR | SDHC_IRQSTAT_AC12E);
  421. return result;
  422. }
  423. //-----------------------------------------------------------------------------
  424. // FUNCTION: disk_write
  425. // SCOPE: SDHC public related function
  426. // DESCRIPTION: Function write block/blocks to disk
  427. //
  428. // PARAMETERS: buff - pointer on buffer where is stored data
  429. // sector - index of start sector
  430. // count - count of sector to write
  431. //
  432. // RETURNS: result of operation
  433. //-----------------------------------------------------------------------------
  434. int KinetisSDHC_WriteBlock(const void * buff, uint32_t sector)
  435. {
  436. int result;
  437. const uint32_t *pData = (const uint32_t *)buff;
  438. // Check if this is ready
  439. if (sdCardDesc.status != 0) return SDHC_RESULT_NOT_READY;
  440. // Convert LBA to uint8_t address if needed
  441. if(!sdCardDesc.highCapacity)
  442. sector *= 512;
  443. SDHC_IRQSTAT = 0xffff;
  444. // Just single block mode is needed
  445. result = SDHC_CMD24_WriteBlock(sector);
  446. if (result != SDHC_RESULT_OK) return result;
  447. result = SDHC_WriteBlock(pData);
  448. // finish up
  449. while (!(SDHC_IRQSTAT & SDHC_IRQSTAT_TC)) { } // wait for transfer to complete
  450. SDHC_IRQSTAT = (SDHC_IRQSTAT_TC | SDHC_IRQSTAT_BWR | SDHC_IRQSTAT_AC12E);
  451. return result;
  452. }
  453. /******************************************************************************
  454. *
  455. * Private functions
  456. *
  457. ******************************************************************************/
  458. // initialize the SDHC Controller signals
  459. static void SDHC_InitGPIO(void)
  460. {
  461. PORTE_PCR0 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D1 */
  462. PORTE_PCR1 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D0 */
  463. PORTE_PCR2 = PORT_PCR_MUX(4) | PORT_PCR_DSE; /* SDHC.CLK */
  464. PORTE_PCR3 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.CMD */
  465. PORTE_PCR4 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D3 */
  466. PORTE_PCR5 = PORT_PCR_MUX(4) | PORT_PCR_PS | PORT_PCR_PE | PORT_PCR_DSE; /* SDHC.D2 */
  467. }
  468. // release the SDHC Controller signals
  469. static void SDHC_ReleaseGPIO(void)
  470. {
  471. PORTE_PCR0 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D1 */
  472. PORTE_PCR1 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D0 */
  473. PORTE_PCR2 = 0; /* SDHC.CLK */
  474. PORTE_PCR3 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* SDHC.CMD */
  475. PORTE_PCR4 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D3 */
  476. PORTE_PCR5 = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; /* PULLUP SDHC.D1 */
  477. }
  478. static void SDHC_SetClock(uint32_t sysctl)
  479. {
  480. uint32_t n, timeout;
  481. n = SDHC_SYSCTL;
  482. // Disable SDHC clocks
  483. n &= ~SDHC_SYSCTL_SDCLKEN;
  484. SDHC_SYSCTL = n;
  485. // Change dividers
  486. n &= ~(SDHC_SYSCTL_DTOCV_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK);
  487. n |= sysctl | SDHC_SYSCTL_DTOCV(0x0E);
  488. SDHC_SYSCTL = n;
  489. /* Wait for stable clock */
  490. timeout = 0xFFFFF;
  491. while ((!(SDHC_PRSSTAT & SDHC_PRSSTAT_SDSTB)) && timeout) {
  492. timeout--;
  493. }
  494. /* Enable SDHC clocks */
  495. SDHC_SYSCTL = n | SDHC_SYSCTL_SDCLKEN;
  496. SDHC_IRQSTAT |= SDHC_IRQSTAT_DTOE;
  497. }
  498. // waits for status bits sets
  499. static uint32_t SDHC_WaitStatus(uint32_t mask)
  500. {
  501. uint32_t result;
  502. uint32_t timeout = 1<<24;
  503. do {
  504. result = SDHC_IRQSTAT & mask;
  505. timeout--;
  506. }
  507. while(!result && (timeout));
  508. if (timeout)
  509. return result;
  510. return 0;
  511. }
  512. // reads one block
  513. static int SDHC_ReadBlock(uint32_t* pData)
  514. {
  515. uint32_t i, irqstat;
  516. const uint32_t i_max = ((SDHC_BLOCK_SIZE) / (4 * SDHC_FIFO_BUFFER_SIZE));
  517. for (i = 0; i < i_max; i++) {
  518. irqstat = SDHC_IRQSTAT;
  519. SDHC_IRQSTAT = irqstat | SDHC_IRQSTAT_BRR;
  520. if (irqstat & (SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE | SDHC_IRQSTAT_DTOE)) {
  521. SDHC_IRQSTAT = irqstat | SDHC_IRQSTAT_BRR |
  522. SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE | SDHC_IRQSTAT_DTOE;
  523. SDHC_CMD12_StopTransferWaitForBusy();
  524. return SDHC_RESULT_ERROR;
  525. }
  526. while (!(SDHC_PRSSTAT & SDHC_PRSSTAT_BREN)) { };
  527. *pData++ = SDHC_DATPORT;
  528. *pData++ = SDHC_DATPORT;
  529. *pData++ = SDHC_DATPORT;
  530. *pData++ = SDHC_DATPORT;
  531. *pData++ = SDHC_DATPORT;
  532. *pData++ = SDHC_DATPORT;
  533. *pData++ = SDHC_DATPORT;
  534. *pData++ = SDHC_DATPORT;
  535. *pData++ = SDHC_DATPORT;
  536. *pData++ = SDHC_DATPORT;
  537. *pData++ = SDHC_DATPORT;
  538. *pData++ = SDHC_DATPORT;
  539. *pData++ = SDHC_DATPORT;
  540. *pData++ = SDHC_DATPORT;
  541. *pData++ = SDHC_DATPORT;
  542. *pData++ = SDHC_DATPORT;
  543. }
  544. return SDHC_RESULT_OK;
  545. }
  546. // writes one block
  547. static int SDHC_WriteBlock(const uint32_t* pData)
  548. {
  549. uint32_t i, i_max, j;
  550. i_max = ((SDHC_BLOCK_SIZE) / (4 * SDHC_FIFO_BUFFER_SIZE));
  551. for(i = 0; i < i_max; i++) {
  552. while (!(SDHC_IRQSTAT & SDHC_IRQSTAT_BWR)) ; // wait
  553. if (SDHC_IRQSTAT & (SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE | SDHC_IRQSTAT_DTOE)) {
  554. SDHC_IRQSTAT |= SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE |
  555. SDHC_IRQSTAT_DTOE | SDHC_IRQSTAT_BWR;
  556. (void)SDHC_CMD12_StopTransferWaitForBusy();
  557. return SDHC_RESULT_ERROR;
  558. }
  559. for(j=0; j<SDHC_FIFO_BUFFER_SIZE; j++) {
  560. SDHC_DATPORT = *pData++;
  561. }
  562. SDHC_IRQSTAT |= SDHC_IRQSTAT_BWR;
  563. if (SDHC_IRQSTAT & (SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE | SDHC_IRQSTAT_DTOE)) {
  564. SDHC_IRQSTAT |= SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE |
  565. SDHC_IRQSTAT_DTOE | SDHC_IRQSTAT_BWR;
  566. (void)SDHC_CMD12_StopTransferWaitForBusy();
  567. return SDHC_RESULT_ERROR;
  568. }
  569. }
  570. return SDHC_RESULT_OK;
  571. }
  572. // sends the command to SDcard
  573. static int SDHC_CMD_Do(uint32_t xfertyp)
  574. {
  575. // Card removal check preparation
  576. SDHC_IRQSTAT |= SDHC_IRQSTAT_CRM;
  577. // Wait for cmd line idle // to do timeout PRSSTAT[CDIHB] and the PRSSTAT[CIHB]
  578. while ((SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB) || (SDHC_PRSSTAT & SDHC_PRSSTAT_CDIHB))
  579. { };
  580. SDHC_XFERTYP = xfertyp;
  581. /* Wait for response */
  582. if (SDHC_WaitStatus(SDHC_IRQSTAT_CIE | SDHC_IRQSTAT_CEBE | SDHC_IRQSTAT_CCE | SDHC_IRQSTAT_CC) != SDHC_IRQSTAT_CC) {
  583. SDHC_IRQSTAT |= SDHC_IRQSTAT_CTOE | SDHC_IRQSTAT_CIE | SDHC_IRQSTAT_CEBE |
  584. SDHC_IRQSTAT_CCE | SDHC_IRQSTAT_CC;
  585. return SDHC_RESULT_ERROR;
  586. }
  587. /* Check card removal */
  588. if (SDHC_IRQSTAT & SDHC_IRQSTAT_CRM) {
  589. SDHC_IRQSTAT |= SDHC_IRQSTAT_CTOE | SDHC_IRQSTAT_CC;
  590. return SDHC_RESULT_NOT_READY;
  591. }
  592. /* Get response, if available */
  593. if (SDHC_IRQSTAT & SDHC_IRQSTAT_CTOE) {
  594. SDHC_IRQSTAT |= SDHC_IRQSTAT_CTOE | SDHC_IRQSTAT_CC;
  595. return SDHC_RESULT_NO_RESPONSE;
  596. }
  597. SDHC_IRQSTAT |= SDHC_IRQSTAT_CC;
  598. return SDHC_RESULT_OK;
  599. }
  600. // sends CMD0 to put SDCARD to idle
  601. static int SDHC_CMD0_GoToIdle(void)
  602. {
  603. uint32_t xfertyp;
  604. int result;
  605. SDHC_CMDARG = 0;
  606. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD0) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_NO));
  607. result = SDHC_CMD_Do(xfertyp);
  608. if(result == SDHC_RESULT_OK) {
  609. (void)SDHC_CMDRSP0;
  610. }
  611. return result;
  612. }
  613. // sends CMD2 to identify card
  614. static int SDHC_CMD2_Identify(void)
  615. {
  616. uint32_t xfertyp;
  617. int result;
  618. SDHC_CMDARG = 0;
  619. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD2) | SDHC_XFERTYP_CCCEN |
  620. SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_136));
  621. result = SDHC_CMD_Do(xfertyp);
  622. if(result == SDHC_RESULT_OK) {
  623. (void)SDHC_CMDRSP0;
  624. }
  625. return result;
  626. }
  627. // sends CMD 3 to get address
  628. static int SDHC_CMD3_GetAddress(void)
  629. {
  630. uint32_t xfertyp;
  631. int result;
  632. SDHC_CMDARG = 0;
  633. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD3) | SDHC_XFERTYP_CICEN |
  634. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  635. result = SDHC_CMD_Do(xfertyp);
  636. if (result == SDHC_RESULT_OK) {
  637. (void)SDHC_CMDRSP0;
  638. }
  639. return result;
  640. }
  641. // sends ACMD6 to set bus width
  642. static int SDHC_ACMD6_SetBusWidth(uint32_t address, uint32_t width)
  643. {
  644. uint32_t xfertyp;
  645. int result;
  646. SDHC_CMDARG = address;
  647. // first send CMD 55 Application specific command
  648. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD55) | SDHC_XFERTYP_CICEN |
  649. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  650. result = SDHC_CMD_Do(xfertyp);
  651. if(result == SDHC_RESULT_OK) {
  652. (void)SDHC_CMDRSP0;
  653. } else {
  654. return result;
  655. }
  656. SDHC_CMDARG = width;
  657. // Send 6CMD
  658. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD6) | SDHC_XFERTYP_CICEN |
  659. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  660. result = SDHC_CMD_Do(xfertyp);
  661. if(result == SDHC_RESULT_OK) {
  662. (void)SDHC_CMDRSP0;
  663. }
  664. return result;
  665. }
  666. // sends CMD 7 to select card
  667. static int SDHC_CMD7_SelectCard(uint32_t address)
  668. {
  669. uint32_t xfertyp;
  670. int result;
  671. SDHC_CMDARG = address;
  672. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD7) | SDHC_XFERTYP_CICEN |
  673. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48BUSY));
  674. result = SDHC_CMD_Do(xfertyp);
  675. if(result == SDHC_RESULT_OK) {
  676. (void)SDHC_CMDRSP0;
  677. }
  678. return result;
  679. }
  680. // CMD8 to send interface condition
  681. static int SDHC_CMD8_SetInterface(uint32_t cond)
  682. {
  683. uint32_t xfertyp;
  684. int result;
  685. SDHC_CMDARG = cond;
  686. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD8) | SDHC_XFERTYP_CICEN |
  687. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  688. result = SDHC_CMD_Do(xfertyp);
  689. if(result == SDHC_RESULT_OK) {
  690. (void)SDHC_CMDRSP0;
  691. }
  692. return result;
  693. }
  694. // sends CMD 8 to send interface condition
  695. static int SDHC_CMD9_GetParameters(uint32_t address)
  696. {
  697. uint32_t xfertyp;
  698. int result;
  699. SDHC_CMDARG = address;
  700. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD9) | SDHC_XFERTYP_CCCEN |
  701. SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_136));
  702. result = SDHC_CMD_Do(xfertyp);
  703. if (result == SDHC_RESULT_OK) {
  704. //(void)SDHC_CMDRSP0;
  705. sdCardDesc.tranSpeed = SDHC_CMDRSP2 >> 24;
  706. }
  707. return result;
  708. }
  709. // sends CMD12 to stop transfer
  710. static int SDHC_CMD12_StopTransfer(void)
  711. {
  712. uint32_t xfertyp;
  713. int result;
  714. SDHC_CMDARG = 0;
  715. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD12) | SDHC_XFERTYP_CMDTYP(SDHC_XFERTYP_CMDTYP_ABORT) |
  716. SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48BUSY));
  717. result = SDHC_CMD_Do(xfertyp);
  718. if (result == SDHC_RESULT_OK) {
  719. }
  720. return result;
  721. }
  722. // sends CMD12 to stop transfer and first waits to ready SDCArd
  723. static int SDHC_CMD12_StopTransferWaitForBusy(void)
  724. {
  725. uint32_t timeOut = 100;
  726. int result;
  727. do {
  728. result = SDHC_CMD12_StopTransfer();
  729. timeOut--;
  730. } while(timeOut && (SDHC_PRSSTAT & SDHC_PRSSTAT_DLA) && result == SDHC_RESULT_OK);
  731. if (result != SDHC_RESULT_OK)
  732. return result;
  733. if(!timeOut)
  734. return SDHC_RESULT_NO_RESPONSE;
  735. return SDHC_RESULT_OK;
  736. }
  737. // sends CMD8 to set block size
  738. static int SDHC_CMD16_SetBlockSize(uint32_t block_size)
  739. {
  740. uint32_t xfertyp;
  741. int result;
  742. SDHC_CMDARG = block_size;
  743. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD16) | SDHC_XFERTYP_CICEN |
  744. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  745. result = SDHC_CMD_Do(xfertyp);
  746. if (result == SDHC_RESULT_OK) {
  747. (void)SDHC_CMDRSP0;
  748. }
  749. return result;
  750. }
  751. // sends CMD17 to read one block
  752. static int SDHC_CMD17_ReadBlock(uint32_t sector)
  753. {
  754. uint32_t xfertyp;
  755. int result;
  756. SDHC_CMDARG = sector;
  757. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | 512;
  758. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD17) | SDHC_XFERTYP_CICEN |
  759. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48) |
  760. SDHC_XFERTYP_DTDSEL | SDHC_XFERTYP_DPSEL);
  761. result = SDHC_CMD_Do(xfertyp);
  762. if (result == SDHC_RESULT_OK) {
  763. (void)SDHC_CMDRSP0;
  764. }
  765. return result;
  766. }
  767. // sends CMD24 to write one block
  768. static int SDHC_CMD24_WriteBlock(uint32_t sector)
  769. {
  770. uint32_t xfertyp;
  771. int result;
  772. SDHC_CMDARG = sector;
  773. SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | 512;
  774. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD24) | SDHC_XFERTYP_CICEN |
  775. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48) |
  776. SDHC_XFERTYP_DPSEL);
  777. result = SDHC_CMD_Do(xfertyp);
  778. if (result == SDHC_RESULT_OK) {
  779. (void)SDHC_CMDRSP0;
  780. }
  781. return result;
  782. }
  783. // ACMD 41 to send operation condition
  784. static int SDHC_ACMD41_SendOperationCond(uint32_t cond)
  785. {
  786. uint32_t xfertyp;
  787. int result;
  788. SDHC_CMDARG = 0;
  789. // first send CMD 55 Application specific command
  790. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_CMD55) | SDHC_XFERTYP_CICEN |
  791. SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  792. result = SDHC_CMD_Do(xfertyp);
  793. if (result == SDHC_RESULT_OK) {
  794. (void)SDHC_CMDRSP0;
  795. } else {
  796. return result;
  797. }
  798. SDHC_CMDARG = cond;
  799. // Send 41CMD
  800. xfertyp = (SDHC_XFERTYP_CMDINX(SDHC_ACMD41) | SDHC_XFERTYP_RSPTYP(SDHC_XFERTYP_RSPTYP_48));
  801. result = SDHC_CMD_Do(xfertyp);
  802. if (result == SDHC_RESULT_OK) {
  803. (void)SDHC_CMDRSP0;
  804. }
  805. return result;
  806. }
  807. #endif // __MK64FX512__ or __MK66FX1M0__