18 #define SD_TIMEOUT_MS 1000
19 #define SD_BLOCK_SIZE 512
32 uint32_t sector_count;
34 volatile enum direction_e direction;
36 static struct sd_state_t sd_state;
38 #define DATATIMEOUT (0xFFFFFF) //I simply made this up. A method for computing a realistic values from CSD is described in the specs.
41 #define CMD0 ((uint8_t)0)
42 #define CMD8 ((uint8_t)8)
43 #define CMD55 ((uint8_t)55)
44 #define ACMD41 ((uint8_t)41)
45 #define CMD2 ((uint8_t)2)
46 #define CMD3 ((uint8_t)3)
47 #define CMD9 ((uint8_t)9)
48 #define CMD7 ((uint8_t)7)
49 #define ACMD6 ((uint8_t)6)
50 #define CMD24 ((uint8_t)24)
51 #define CMD25 ((uint8_t)25)
52 #define CMD12 ((uint8_t)12)
53 #define CMD13 ((uint8_t)13)
54 #define CMD17 ((uint8_t)17)
55 #define CMD18 ((uint8_t)18)
61 #define R3RESP (0xF40) //Note this is totaly out of standard. However, becouse of the masking in status = SD_Command it will be processed as SHRESP
65 #define RESP_R1 (0x01)
66 #define RESP_R1b (0x02)
67 #define RESP_R2 (0x03)
68 #define RESP_R3 (0x04)
69 #define RESP_R6 (0x05)
70 #define RESP_R7 (0x06)
72 static void SD_Panic(uint32_t code,
const char *message) {(void)code; (void)message;}
82 if (sd_state.direction != DIRECTION_NONE)
90 static status_e SD_Command(uint32_t cmd, uint32_t resp, uint32_t arg)
100 SDIO->ICR = (0x3<<22)|0x3ff;
112 sd_status = SDIO->STA;
136 sd_status = SDIO->STA;
138 if (sd_status & SDIO_STA_CTIMEOUT)
140 SD_Panic(cmd,
"SDIO: Command Timeout Error\n");
162 if (sd_status & SDIO_FLAG_CCRCFAIL)
173 SD_Panic(cmd,
"SDIO: Command CRC Error\n");
181 static status_e SD_Response(uint32_t *response, uint32_t type)
188 if ((type == RESP_R1) || (type == RESP_R1b))
190 *response = SDIO->RESP1;
191 if (*response & (uint32_t) 0xFDFFE008)
193 SD_Panic(SDIO->RESPCMD,
"SDIO:Response Error\n");
201 *response++ = SDIO->RESP1;
202 *response++ = SDIO->RESP2;
203 *response++ = SDIO->RESP3;
204 *response = SDIO->RESP4;
211 if (SDIO->RESPCMD != 0x3F)
213 SD_Panic(SDIO->RESPCMD,
"SDIO:Unexpected command index\n");
216 *response = SDIO->RESP1;
222 if (SDIO->RESPCMD != 0x03)
224 SD_Panic(SDIO->RESPCMD,
"SDIO:Unexpected command index\n");
227 *response = SDIO->RESP1;
233 if (SDIO->RESPCMD != 0x08)
235 SD_Panic(SDIO->RESPCMD,
"SDIO:Unexpected command index\n");
238 *response = SDIO->RESP1;
239 if ((*response & 0xFF) != 0xAA)
241 SD_Panic(CMD8,
"SDIO:Pattern did not match\n");
248 static uint32_t dmable_buffer[SD_BLOCK_SIZE/
sizeof(uint32_t)];
250 static void SD_StartBlockTransfer(uint8_t *buf, uint32_t cnt,
enum direction_e direction)
254 DMA_ClearFlag(DMA2_Stream3,
255 DMA_FLAG_FEIF3 | DMA_FLAG_DMEIF3 | DMA_FLAG_TEIF3 | DMA_FLAG_HTIF3
259 DMA_Cmd(DMA2_Stream3, DISABLE);
262 DMA_DeInit(DMA2_Stream3);
268 if (direction == DIRECTION_TX)
270 memcpy(dmable_buffer, buf, SD_BLOCK_SIZE);
271 SDDMA_InitStructure.
DMA_DIR = DMA_DIR_MemoryToPeripheral;
275 SDDMA_InitStructure.
DMA_DIR = DMA_DIR_PeripheralToMemory;
282 SDDMA_InitStructure.
DMA_Mode = DMA_Mode_Normal;
283 SDDMA_InitStructure.
DMA_Priority = DMA_Priority_VeryHigh;
288 DMA_Init(DMA2_Stream3, &SDDMA_InitStructure);
289 DMA_ITConfig(DMA2_Stream3, DMA_IT_TC, ENABLE);
290 DMA_FlowControllerConfig(DMA2_Stream3, DMA_FlowCtrl_Peripheral);
293 DMA_Cmd(DMA2_Stream3, ENABLE);
302 SDIO->DTIMER = (uint32_t) DATATIMEOUT;
308 tempreg |= (uint32_t) 9 << 4;
311 if (direction == DIRECTION_RX)
317 SDIO->DCTRL = tempreg;
321 sd_state.direction = direction;
333 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
336 GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_SDIO);
337 GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SDIO);
338 GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_SDIO);
341 GPIO_InitStructure.
GPIO_Pin = GPIO_Pin_8;
344 GPIO_InitStructure.
GPIO_OType = GPIO_OType_PP;
345 GPIO_InitStructure.
GPIO_PuPd = GPIO_PuPd_UP;
346 GPIO_Init(GPIOC, &GPIO_InitStructure);
349 GPIO_InitStructure.
GPIO_Pin = GPIO_Pin_2;
350 GPIO_Init(GPIOD, &GPIO_InitStructure);
353 GPIO_InitStructure.
GPIO_Pin = GPIO_Pin_12;
354 GPIO_InitStructure.
GPIO_PuPd = GPIO_PuPd_NOPULL;
355 GPIO_Init(GPIOC, &GPIO_InitStructure);
358 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);
361 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
366 tempreg |= (uint32_t) 0x76;
368 SDIO->CLKCR = tempreg;
376 static status_e compute_size(
struct sd_state_t *state, uint32_t *CSD_Tab)
380 uint32_t read_bl_len;
383 tmp = (uint8_t)((CSD_Tab[1] & 0x00FF0000) >> 16);
385 read_bl_len = tmp & 0x0F;
390 tmp = (uint8_t)((CSD_Tab[1] & 0x0000FF00) >> 8);
392 tmp32 = (tmp & 0x03) << 10;
395 tmp = (uint8_t)(CSD_Tab[1] & 0x000000FF);
399 tmp = (uint8_t)((CSD_Tab[2] & 0xFF000000) >> 24);
400 tmp32 |= (tmp & 0xC0) >> 6;
403 tmp = (uint8_t)((CSD_Tab[2] & 0x00FF0000) >> 16);
404 mul = (tmp & 0x03) << 1;
406 tmp = (uint8_t)((CSD_Tab[2] & 0x0000FF00) >> 8);
407 mul |= (tmp & 0x80) >> 7;
409 state->sector_count = (tmp32 + 1) ;
410 state->sector_count *= (1 << (mul + 2));
411 state->sector_count *= (1<<read_bl_len)/512;
418 tmp = (uint8_t)(CSD_Tab[1] & 0x000000FF);
419 tmp32 = (tmp & 0x3F) << 16;
422 tmp = (uint8_t)((CSD_Tab[2] & 0xFF000000) >> 24);
427 tmp = (uint8_t)((CSD_Tab[2] & 0x00FF0000) >> 16);
432 tmp = (uint8_t)((CSD_Tab[2] & 0x0000FF00) >> 8);
434 state->sector_count = tmp32 *1024;
449 status = SD_Command(CMD0, NORESP, 0);
456 status = SD_Command(CMD8, SHRESP, 0x000001AA);
461 status = SD_Response(&response, RESP_R7);
471 status = SD_Command(CMD55, SHRESP, 0);
472 status = SD_Response(&response, RESP_R1);
476 status = SD_Command(ACMD41, R3RESP, (uint32_t) 0x80100000 | (uint32_t) 0x40000000);
477 status = SD_Response(&response, RESP_R3);
480 if ((response >> 31) == 1)
483 sd_state.sdhc = (response & 0x40000000) >> 30;
489 SD_Panic(ACMD41,
"SDIO:ACMD41 Timeout\n");
496 status = SD_Command(CMD2, LNRESP, 0);
503 status = SD_Response(cid, RESP_R2);
510 status = SD_Command(CMD3, SHRESP, 0);
516 status = SD_Response(&response, RESP_R6);
522 sd_state.RCA = response >> 16;
528 status = SD_Command(CMD9, LNRESP, (sd_state.RCA << 16));
535 status = SD_Response(csd, RESP_R2);
541 status = compute_size(&sd_state, csd);
549 status = SD_Command(CMD7, SHRESP, (sd_state.RCA << 16));
554 status = SD_Response(&response, RESP_R1);
562 status = SD_Command(CMD55, SHRESP, (sd_state.RCA << 16));
568 status = SD_Response(&response, RESP_R1);
576 status = SD_Command(ACMD6, SHRESP, 0x00);
582 status = SD_Response(&response, RESP_R1);
593 tempreg |= (0x00) << 11;
597 SDIO->CLKCR = tempreg;
603 status_e SD_GetSectorCount(uint32_t *count)
605 *count = sd_state.sector_count;
609 status_e SD_WaitTransmissionEnd(
void)
620 if (!(DMA2_Stream3->CR & DMA_SxCR_EN))
632 if (sd_state.direction != DIRECTION_NONE)
635 & (DMA_LISR_TCIF3 | DMA_LISR_TEIF3 | DMA_LISR_DMEIF3
638 if (!(DMA2->LISR & DMA_LISR_TCIF3))
640 SD_Panic(DMA2->LISR,
"SDIO:DMA Error");
660 if (sd_state.direction != DIRECTION_NONE)
665 | SDIO_IT_STBITERR)))
670 SD_Panic(SDIO->STA,
"SDIO:Data Transmission Error\n");
676 if (sd_state.direction == DIRECTION_RX)
678 memcpy(sd_state.buf, dmable_buffer, SD_BLOCK_SIZE);
680 sd_state.direction = DIRECTION_NONE;
685 status_e SD_WriteSingleBlock(
const void *_buf, uint32_t blk)
688 const uint8_t *buf = _buf;
693 WriteAddr = blk * SD_BLOCK_SIZE;
694 if (sd_state.sdhc == 1)
700 status = SD_Command(CMD24, SHRESP, WriteAddr);
706 status = SD_Response(&response, RESP_R1);
713 SD_StartBlockTransfer((
void *)buf, SD_BLOCK_SIZE, DIRECTION_TX);
716 status = SD_WaitTransmissionEnd();
725 status_e SD_ReadSingleBlock(
void *_buf, uint32_t blk)
734 ReadAddr = blk * SD_BLOCK_SIZE;
735 if (sd_state.sdhc == 1)
741 status = SD_Command(CMD17, SHRESP, ReadAddr);
746 status = SD_Response(&response, RESP_R1);
753 SD_StartBlockTransfer(buf, SD_BLOCK_SIZE, DIRECTION_RX);
756 status = SD_WaitTransmissionEnd();
765 #ifdef SD_MULTIBLOCK_WRITE
766 #warning SD_MULTIBLOCK_WRITE is completely untested
768 static uint8_t DatBuf[SD_BLOCK_SIZE * 2];
769 static uint8_t *pDatBuf = DatBuf;
770 static uint32_t BufCnt = 0;
773 #ifdef SD_MULTIBLOCK_WRITE
774 status_e SD_StartMultipleBlockWrite(uint32_t blk)
782 WriteAddr = blk * SD_BLOCK_SIZE;
783 if (sd_state.sdhc == 1)
789 status = SD_Command(CMD25, SHRESP, WriteAddr);
794 status = SD_Response(&response, RESP_R1);
801 SDIO->ICR = (uint32_t) 0xA003FF;
806 status_e SD_StopMultipleBlockWrite(
void)
812 status = SD_WaitTransmissionEnd();
819 status = SD_Command(CMD12, SHRESP, 0);
820 status = SD_Response(&response, RESP_R1b);
825 while (((response & 0x100) >> 8) == 0)
832 status = SD_Command(CMD13, SHRESP, sd_state.RCA << 16);
833 status = SD_Response(&response, RESP_R1b);
838 status_e SD_WriteData(uint8_t *buf, uint32_t cnt)
851 if (BufCnt == SD_BLOCK_SIZE)
854 status = SD_WaitTransmissionEnd();
863 SD_StartBlockTransfer(pDatBuf - SD_BLOCK_SIZE, SD_BLOCK_SIZE, DIRECTION_TX);
866 if (pDatBuf == (DatBuf + (SD_BLOCK_SIZE * 2)))
This file contains all the functions prototypes for the RCC firmware library.
This file contains all the functions prototypes for the GPIO firmware library.
GPIOOType_TypeDef GPIO_OType
DMA Init structure definition.
#define SDIO_STA_TXUNDERR
void * memcpy(void *dest, const void *src, size_t n)
GPIOSpeed_TypeDef GPIO_Speed
uint32_t DMA_MemoryDataSize
CMSIS Cortex-M4 Device Peripheral Access Layer Header File. This file contains all the peripheral reg...
uint32_t DMA_PeripheralInc
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
uint32_t DMA_PeripheralDataSize
static uint32_t gpio_get(const struct gpio_t *gpio)
Get gpio level.
SD memory card access for STM32 boards.
GPIO Init structure definition.
uint32_t DMA_PeripheralBurst
This file contains all the functions prototypes for the DMA firmware library.
uint32_t DMA_PeripheralBaseAddr
uint32_t DMA_Memory0BaseAddr
#define SDIO_STA_STBITERR
This file contains all the functions prototypes for the SDIO firmware library.
uint32_t DMA_FIFOThreshold
GPIOMode_TypeDef GPIO_Mode
#define SDIO_STA_DTIMEOUT
#define DEF_GPIOC(__PIN, __MODE)
same as DEF_GPIOA for port C
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
#define SDIO_STA_DCRCFAIL
#define SDIO_CMD_WAITRESP
#define SDIO_CMD_CMDINDEX
status_e gpio_setup(const struct gpio_t *gpio)
Setup a gpio.
GPIOPuPd_TypeDef GPIO_PuPd
#define SDIO_STA_CTIMEOUT