11 static uint8_t sd_mmc_slot_sel;
13 static uint32_t hsmci_transfert_pos;
15 static uint16_t hsmci_block_size;
17 static uint16_t hsmci_nb_block;
24 uint32_t mr = HSMCI->HSMCI_MR;
25 uint32_t dtor = HSMCI->HSMCI_DTOR;
26 uint32_t sdcr = HSMCI->HSMCI_SDCR;
27 uint32_t cstor = HSMCI->HSMCI_CSTOR;
28 uint32_t cfg = HSMCI->HSMCI_CFG;
29 HSMCI->HSMCI_CR = HSMCI_CR_SWRST;
31 HSMCI->HSMCI_DTOR = dtor;
32 HSMCI->HSMCI_SDCR = sdcr;
33 HSMCI->HSMCI_CSTOR = cstor;
34 HSMCI->HSMCI_CFG = cfg;
37 HSMCI->HSMCI_CR = HSMCI_CR_PWSEN | HSMCI_CR_MCIEN;
54 clkdiv = mck / (2 * speed);
55 rest = mck % (2 * speed);
70 printf(
"CLKDIV is : %d\n\r",clkdiv);
71 HSMCI->HSMCI_MR &= ~HSMCI_MR_CLKDIV_Msk;
72 HSMCI->HSMCI_MR |= HSMCI_MR_CLKDIV(clkdiv);
81 uint32_t busy_wait = 1000000;
92 }
while (!((sr & HSMCI_SR_NOTBUSY) && ((sr & HSMCI_SR_DTIP) == 0)));
109 cmdr |= HSMCI_CMDR_CMDNB(cmd) | HSMCI_CMDR_SPCMD_STD;
112 cmdr |= HSMCI_CMDR_MAXLAT;
115 cmdr |= HSMCI_CMDR_RSPTYP_136_BIT;
119 cmdr |= HSMCI_CMDR_RSPTYP_R1B;
123 cmdr |= HSMCI_CMDR_RSPTYP_48_BIT;
128 cmdr |= HSMCI_CMDR_OPDCMD_OPENDRAIN;
132 HSMCI->HSMCI_ARGR = arg;
134 HSMCI->HSMCI_CMDR = cmdr;
139 sr = HSMCI->HSMCI_SR;
142 if (sr & (HSMCI_SR_CSTOE | HSMCI_SR_RTOE | HSMCI_SR_RENDE | HSMCI_SR_RCRCE | HSMCI_SR_RDIRE | HSMCI_SR_RINDE))
150 if (sr & (HSMCI_SR_CSTOE | HSMCI_SR_RTOE | HSMCI_SR_RENDE | HSMCI_SR_RDIRE | HSMCI_SR_RINDE))
156 }
while (!(sr & HSMCI_SR_CMDRDY));
175 PMC->PMC_PCER0 = PMC_PCER0_PID11;
181 PMC->PMC_PCER0 = PMC_PCER0_PID18;
190 HSMCI->HSMCI_CR = HSMCI_CR_SWRST;
191 HSMCI->HSMCI_CR = HSMCI_CR_MCIDIS | HSMCI_CR_PWSDIS;
193 HSMCI->HSMCI_IDR = 0xFFFFFFFF;
195 HSMCI->HSMCI_DTOR = HSMCI_DTOR_DTOCYC_Msk | HSMCI_DTOR_DTOMUL_Msk ;
197 HSMCI->HSMCI_CSTOR = HSMCI_CSTOR_CSTOCYC_Msk | HSMCI_CSTOR_CSTOMUL_Msk ;
199 HSMCI->HSMCI_CFG = HSMCI_CFG_FIFOMODE | HSMCI_CFG_FERRCTRL;
200 const uint8_t CLKDIV = 0x95;
203 HSMCI->HSMCI_MR = CLKDIV | HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_PWSDIV_Msk;
205 HSMCI->HSMCI_SDCR = HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_1 ;
207 HSMCI->HSMCI_CR = HSMCI_CR_MCIEN | HSMCI_CR_PWSEN;
228 uint32_t hsmci_slot = HSMCI_SDCR_SDCSEL_SLOTA;
229 uint32_t hsmci_bus_width = HSMCI_SDCR_SDCBUS_1;
233 HSMCI->HSMCI_CFG |= HSMCI_CFG_HSMODE;
237 HSMCI->HSMCI_CFG &= ~HSMCI_CFG_HSMODE;
245 hsmci_slot = HSMCI_SDCR_SDCSEL_SLOTA;
254 hsmci_bus_width = HSMCI_SDCR_SDCBUS_1;
258 hsmci_bus_width = HSMCI_SDCR_SDCBUS_4;
262 hsmci_bus_width = HSMCI_SDCR_SDCBUS_8;
268 HSMCI->HSMCI_SDCR = hsmci_slot | hsmci_bus_width;
280 HSMCI->HSMCI_MR &= ~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF | HSMCI_MR_FBYTE);
282 HSMCI->HSMCI_ARGR = 0;
284 HSMCI->HSMCI_CMDR = HSMCI_CMDR_RSPTYP_NORESP | HSMCI_CMDR_SPCMD_INIT | HSMCI_CMDR_OPDCMD_OPENDRAIN;
286 while (!(HSMCI->HSMCI_SR & HSMCI_SR_CMDRDY));
292 HSMCI->HSMCI_MR &= ~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF | HSMCI_MR_FBYTE);
293 #ifdef HSMCI_MR_PDCMODE
295 HSMCI->HSMCI_MR &= ~HSMCI_MR_PDCMODE;
297 HSMCI->HSMCI_BLKR = 0;
303 return HSMCI->HSMCI_RSPR[0];
308 uint32_t response_32;
310 for (uint8_t i = 0; i < 4; i++)
312 response_32 = HSMCI->HSMCI_RSPR[0];
313 *response = (response_32 >> 24) & 0xFF;
315 *response = (response_32 >> 16) & 0xFF;
317 *response = (response_32 >> 8) & 0xFF;
319 *response = (response_32 >> 0) & 0xFF;
324 uint32_t
hsmci_adtc_start(uint32_t cmd, uint32_t arg, uint16_t block_size, uint16_t nb_block, uint32_t access_block)
328 #ifdef HSMCI_MR_PDCMODE
332 HSMCI->HSMCI_MR |= HSMCI_MR_PDCMODE;
337 HSMCI->HSMCI_MR &= ~HSMCI_MR_PDCMODE;
344 HSMCI->HSMCI_MR |= HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF;
346 if (block_size & 0x3)
348 HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE;
352 HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE;
357 cmdr = HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_WRITE;
361 cmdr = HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ;
366 cmdr |= HSMCI_CMDR_TRTYP_BYTE;
368 HSMCI->HSMCI_BLKR = ((block_size % 512) << HSMCI_BLKR_BCNT_Pos);
372 HSMCI->HSMCI_BLKR = (block_size << HSMCI_BLKR_BLKLEN_Pos) | (nb_block << HSMCI_BLKR_BCNT_Pos);
375 cmdr |= HSMCI_CMDR_TRTYP_BLOCK;
379 cmdr |= HSMCI_CMDR_TRTYP_STREAM;
383 cmdr |= HSMCI_CMDR_TRTYP_SINGLE;
387 cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE;
392 printf(
"Incorrect flags in adtc command\n\r");
395 hsmci_transfert_pos = 0;
396 hsmci_block_size = block_size;
397 hsmci_nb_block = nb_block;
398 printf(
"HSMCI block size is : %d\n\r",hsmci_block_size);
399 printf(
"HSMCI number of blocks are : %d\n\r",nb_block);
417 sr = HSMCI->HSMCI_SR;
418 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
423 }
while (!(sr & HSMCI_SR_RXRDY));
426 *value = HSMCI->HSMCI_RDR;
427 hsmci_transfert_pos += 4;
428 if (((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos)
437 sr = HSMCI->HSMCI_SR;
438 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
443 }
while (!(sr & HSMCI_SR_XFRDONE));
456 sr = HSMCI->HSMCI_SR;
457 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
462 }
while (!(sr & HSMCI_SR_TXRDY));
465 HSMCI->HSMCI_TDR = value;
466 hsmci_transfert_pos += 4;
467 if (((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos)
476 sr = HSMCI->HSMCI_SR;
477 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
482 }
while (!(sr & HSMCI_SR_NOTBUSY));
487 #ifdef HSMCI_MR_PDCMODE
492 nb_data = nb_block * hsmci_block_size;
497 if (((uint32_t)dest & 0x3) || (hsmci_block_size & 0x3))
499 HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE;
503 HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE;
507 HSMCI->HSMCI_RPR = (uint32_t)dest;
508 HSMCI->HSMCI_RCR = (HSMCI->HSMCI_MR & HSMCI_MR_FBYTE) ? nb_data : nb_data / 4;
509 HSMCI->HSMCI_RNCR = 0;
511 HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTEN;
512 hsmci_transfert_pos += nb_data;
523 sr = HSMCI->HSMCI_SR;
524 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
526 HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS;
531 }
while (!(sr & HSMCI_SR_RXBUFF));
533 if (hsmci_transfert_pos < ((uint32_t)hsmci_block_size * hsmci_nb_block))
541 sr = HSMCI->HSMCI_SR;
542 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
547 }
while (!(sr & HSMCI_SR_XFRDONE));
555 nb_data = nb_block * hsmci_block_size;
560 if (((uint32_t)src & 0x3) || (hsmci_block_size & 0x3))
562 HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE;
566 HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE;
570 HSMCI->HSMCI_TPR = (uint32_t)src;
571 HSMCI->HSMCI_TCR = (HSMCI->HSMCI_MR & HSMCI_MR_FBYTE) ? nb_data : nb_data / 4;
572 HSMCI->HSMCI_TNCR = 0;
574 HSMCI->HSMCI_PTCR = HSMCI_PTCR_TXTEN;
575 hsmci_transfert_pos += nb_data;
587 sr = HSMCI->HSMCI_SR;
588 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
591 HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS;
594 }
while (!(sr & HSMCI_SR_TXBUFE));
597 if (hsmci_transfert_pos < ((uint32_t)hsmci_block_size * hsmci_nb_block))
605 sr = HSMCI->HSMCI_SR;
606 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE))
611 }
while (!(sr & HSMCI_SR_NOTBUSY));
615 #endif // HSMCI_MR_PDCMODE
uint32_t hsmci_adtc_start(uint32_t cmd, uint32_t arg, uint16_t block_size, uint16_t nb_block, uint32_t access_block)
Send an ADTC command on the selected slot An ADTC (Addressed Data Transfer Commands) command is used ...
uint32_t hsmci_send_cmd_execute(uint32_t cmdr, uint32_t cmd, uint32_t arg)
Send a command.
uint32_t hsmci_wait_end_of_read_blocks(void)
Wait the end of transfer initiated by mci_start_read_blocks()
SD/MMC protocol definitions.
uint32_t hsmci_write_word(uint32_t value)
Write a word on the line.
uint32_t hsmci_is_high_speed_capable(void)
Return the high speed capability of the driver.
void hsmci_set_speed(uint32_t speed, uint32_t mck)
Set speed of the HSMCI clock.
int printf(const char *format,...)
#define SDMMC_CMD_SINGLE_BLOCK
To signal a data transfer in single block mode.
#define SDMMC_CMD_OPENDRAIN
void hsmci_select_device(uint8_t slot, uint32_t clock, uint8_t bus_width, uint32_t high_speed)
Select a slot and initialize it.
void hsmci_reset(void)
Reset the HSMCI interface.
#define SDMMC_RESP_BUSY
Card may send busy.
uint32_t hsmci_init(void)
Initializes the low level driver.
#define SDMMC_RESP_CRC
Expect valid crc (MCI only)
uint8_t hsmci_get_bus_width(uint8_t slot)
Return the maximum bus width of a slot.
uint32_t hsmci_start_write_blocks(const void *src, uint16_t nb_block)
Start a write blocks transfer on the line Note: The driver will use the DMA available to speed up the...
uint32_t hsmci_adtc_stop(uint32_t cmd, uint32_t arg)
Send a command to stop an ADTC command on the selected slot.
#define SDMMC_CMD_STREAM
To signal a data transfer in stream mode.
void hsmci_deselect_device(uint8_t slot)
Deselect a slot.
uint32_t hsmci_start_read_blocks(void *dest, uint16_t nb_block)
Start a read blocks transfer on the line Note: The driver will use the DMA available to speed up the ...
#define SDMMC_CMD_WRITE
To signal a data write operation.
uint32_t hsmci_read_word(uint32_t *value)
Read a word on the line.
uint32_t hsmci_get_response(void)
Return the 32 bits response of the last command.
#define SDMMC_RESP_PRESENT
Have response (MCI only)
#define SDMMC_CMD_SDIO_BLOCK
To signal a SDIO tranfer in block mode.
void hsmci_get_response_128(uint8_t *response)
Return the 128 bits response of the last command.
uint32_t hsmci_wait_end_of_write_blocks(void)
Wait the end of transfer initiated by mci_start_write_blocks()
#define SDMMC_CMD_SDIO_BYTE
To signal a SDIO tranfer in multi byte mode.
#define SDMMC_RESP_136
136 bit response (MCI only)
void hsmci_send_clock(void)
Send 74 clock cycles on the line of selected slot Note: It is required after card plug and before car...
uint32_t hsmci_wait_busy(void)
Wait the end of busy signal on data line.
#define SDMMC_CMD_MULTI_BLOCK
To signal a data transfer in multi block mode.
uint32_t hsmci_send_cmd(uint32_t cmd, uint32_t arg)
Send a command on the selected slot.