Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

977 lines
29KB

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