Sergey
5 years ago
11 changed files with 917 additions and 112 deletions
@ -0,0 +1,291 @@ |
|||||
|
#include "sdio_driver.h" |
||||
|
|
||||
|
volatile SDCard_TypeDef SDCard; |
||||
|
volatile SD_Status_TypeDef SDStatus; |
||||
|
volatile uint32_t response[4]; //Для хранения ответа от карты
|
||||
|
volatile uint8_t transmit; //Флаг запущенной передачи данных в SDIO
|
||||
|
volatile uint8_t state=0; //Для хранения состояния карты
|
||||
|
volatile uint8_t multiblock=0; //Используется в прерывании SDIO, чтоб слать команду STOP
|
||||
|
volatile uint32_t error_flag=0; |
||||
|
|
||||
|
volatile uint8_t __attribute__ ((aligned (4))) buf_copy[8*1024]; |
||||
|
|
||||
|
|
||||
|
void SD_check_status(SD_Status_TypeDef* SDStatus,uint32_t* reg){ |
||||
|
SDStatus->ake_seq_error = (*reg & (1 << 3)) ? 1 : 0; |
||||
|
SDStatus->app_cmd = (*reg & (1 << 5)) ? 1 : 0; |
||||
|
SDStatus->ready_for_data = (*reg & (1 << 8)) ? 1 : 0; |
||||
|
SDStatus->current_state = (uint8_t)((*reg & (0x0F << 9)) >> 9); |
||||
|
SDStatus->erase_reset = (*reg & (1 << 13)) ? 1 : 0; |
||||
|
SDStatus->card_ecc_disabled = (*reg & (1 << 14)) ? 1 : 0; |
||||
|
SDStatus->wp_erase_skip = (*reg & (1 << 15)) ? 1 : 0; |
||||
|
SDStatus->csd_overwrite = (*reg & (1 << 16)) ? 1 : 0; |
||||
|
SDStatus->error = (*reg & (1 << 19)) ? 1 : 0; |
||||
|
SDStatus->cc_error = (*reg & (1 << 20)) ? 1 : 0; |
||||
|
SDStatus->card_ecc_failed = (*reg & (1 << 21)) ? 1 : 0; |
||||
|
SDStatus->illegal_command = (*reg & (1 << 22)) ? 1 : 0; |
||||
|
SDStatus->com_crc_error = (*reg & (1 << 23)) ? 1 : 0; |
||||
|
SDStatus->lock_unlock_failed= (*reg & (1 << 24)) ? 1 : 0; |
||||
|
SDStatus->card_is_locked = (*reg & (1 << 25)) ? 1 : 0; |
||||
|
SDStatus->wp_violation = (*reg & (1 << 26)) ? 1 : 0; |
||||
|
SDStatus->erase_param = (*reg & (1 << 27)) ? 1 : 0; |
||||
|
SDStatus->erase_seq_error = (*reg & (1 << 28)) ? 1 : 0; |
||||
|
SDStatus->block_len_error = (*reg & (1 << 29)) ? 1 : 0; |
||||
|
SDStatus->address_error = (*reg & (1 << 30)) ? 1 : 0; |
||||
|
SDStatus->out_of_range = (*reg & (1U << 31)) ? 1 : 0; |
||||
|
}; |
||||
|
|
||||
|
uint8_t SD_Cmd(uint8_t cmd, uint32_t arg, uint16_t response_type, uint32_t *response){ |
||||
|
SDIO->ICR = SDIO_ICR_CMD_FLAGS; |
||||
|
SDIO->ARG = arg; |
||||
|
SDIO->CMD = (uint32_t)(response_type | cmd); |
||||
|
SDIO->CMD |= SDIO_CMD_CPSMEN; |
||||
|
|
||||
|
while( (SDIO->STA & SDIO_STA_CMD_FLAGS) == 0){asm("nop");}; |
||||
|
|
||||
|
if (response_type != SDIO_RESP_NONE) { |
||||
|
response[0] = SDIO->RESP1; |
||||
|
response[1] = SDIO->RESP2; |
||||
|
response[2] = SDIO->RESP3; |
||||
|
response[3] = SDIO->RESP4; |
||||
|
} |
||||
|
|
||||
|
if (SDIO->STA & SDIO_STA_CTIMEOUT) { |
||||
|
return 2; |
||||
|
} |
||||
|
if (SDIO->STA & SDIO_STA_CCRCFAIL) { |
||||
|
return 3; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
//#pragma GCC push_options
|
||||
|
//#pragma GCC optimize ("O0")
|
||||
|
uint32_t SD_transfer(uint8_t *buf, uint32_t blk, uint32_t cnt, uint32_t dir){ |
||||
|
uint32_t trials; |
||||
|
uint8_t cmd=0; |
||||
|
uint8_t *ptr = buf; |
||||
|
|
||||
|
trials=SDIO_DATA_TIMEOUT; |
||||
|
while (transmit && trials--) {}; |
||||
|
if(!trials) { |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
state=0; |
||||
|
while(state != 4){ //Дождаться когда карта будет в режиме tran (4)
|
||||
|
SD_Cmd(SD_CMD13, SDCard.RCA ,SDIO_RESP_SHORT,(uint32_t*)response); |
||||
|
SD_check_status((SD_Status_TypeDef*)&SDStatus,(uint32_t*)&response[0]); |
||||
|
state=SDStatus.current_state; |
||||
|
|
||||
|
if((state == 5) || (state == 6)) SD_Cmd(SD_CMD12, 0, SDIO_RESP_SHORT,(uint32_t*)response); |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
//Выключить DMA
|
||||
|
DMA2->IFCR=DMA_S4_CLEAR; |
||||
|
DMA2_Channel4->CCR=0; |
||||
|
DMA2->IFCR=DMA_S4_CLEAR; |
||||
|
DMA2_Channel4->CCR=DMA_SDIO_CR; |
||||
|
|
||||
|
multiblock = (cnt == 1) ? 0 : 1; |
||||
|
if (dir==UM2SD){ //Запись
|
||||
|
if(((uint32_t)buf % 4) != 0){ |
||||
|
DEBUG("Buffer not aligned"); |
||||
|
memcpy((uint8_t*)buf_copy,buf,cnt*512); |
||||
|
ptr=(uint8_t*)buf_copy; |
||||
|
}; |
||||
|
DMA2_Channel4->CCR|=(0x01 << DMA_CCR_DIR_Pos); |
||||
|
cmd=(cnt == 1)? SD_CMD24 : SD_CMD25; |
||||
|
} |
||||
|
else if (dir==SD2UM){ //Чтение
|
||||
|
cmd=(cnt == 1)? SD_CMD17 : SD_CMD18; |
||||
|
if(((uint32_t)buf % 4) != 0){ |
||||
|
ptr=(uint8_t*)buf_copy; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
DMA2_Channel4->CMAR=(uint32_t)ptr; //Memory address
|
||||
|
DMA2_Channel4->CPAR=(uint32_t)&(SDIO->FIFO); //SDIO FIFO Address
|
||||
|
DMA2_Channel4->CNDTR=cnt*512/4; |
||||
|
|
||||
|
transmit=1; |
||||
|
error_flag=0; |
||||
|
|
||||
|
DISABLE_IRQ; |
||||
|
SD_Cmd(cmd, blk, SDIO_RESP_SHORT, (uint32_t*)response); |
||||
|
|
||||
|
SDIO->ICR=SDIO_ICR_DATA_FLAGS; |
||||
|
SDIO->DTIMER=(uint32_t)0x6BDD00; |
||||
|
SDIO->DLEN=cnt*512; //Количество байт (блок 512 байт)
|
||||
|
SDIO->DCTRL= SDIO_DCTRL | (dir & SDIO_DCTRL_DTDIR); //Direction. 0=Controller to card, 1=Card to Controller
|
||||
|
|
||||
|
DMA2_Channel4->CCR |= DMA_CCR_EN; |
||||
|
SDIO->DCTRL|=1; //DPSM is enabled
|
||||
|
ENABLE_IRQ; |
||||
|
|
||||
|
while((SDIO->STA & (SDIO_STA_DATAEND|SDIO_STA_ERRORS)) == 0){__asm volatile ("nop");}; |
||||
|
|
||||
|
if(SDIO->STA & SDIO_STA_ERRORS){ |
||||
|
error_flag=SDIO->STA; |
||||
|
transmit=0; |
||||
|
SDIO->ICR = SDIO_ICR_STATIC; |
||||
|
DMA2_Channel4->CCR = 0; |
||||
|
DMA2->IFCR = DMA_S4_CLEAR; |
||||
|
return error_flag; |
||||
|
} |
||||
|
|
||||
|
if(dir==SD2UM) { //Read
|
||||
|
while (DMA2_Channel4->CCR & DMA_CCR_EN) { |
||||
|
if(SDIO->STA & SDIO_STA_ERRORS) { |
||||
|
transmit=0; |
||||
|
return 99; |
||||
|
} |
||||
|
DMA2_Channel4->CCR = 0; |
||||
|
DMA2->IFCR = DMA_S4_CLEAR; |
||||
|
}; |
||||
|
|
||||
|
if(((uint32_t)buf % 4) != 0){ |
||||
|
memcpy(buf,(uint8_t*)buf_copy,cnt*512); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
if(multiblock > 0) SD_Cmd(SD_CMD12, 0, SDIO_RESP_SHORT, (uint32_t*)response); |
||||
|
transmit=0; |
||||
|
DMA2->IFCR = DMA_S4_CLEAR; |
||||
|
SDIO->ICR=SDIO_ICR_STATIC; |
||||
|
return 0; |
||||
|
}; |
||||
|
//#pragma GCC pop_options
|
||||
|
|
||||
|
uint8_t SD_Init(void) { |
||||
|
volatile uint32_t trials = 0x0000FFFF; |
||||
|
uint32_t tempreg; //Для временного хранения регистров
|
||||
|
uint8_t result = 0; |
||||
|
|
||||
|
RCC->AHBENR |= RCC_AHBENR_SDIOEN | RCC_AHBENR_DMA2EN; |
||||
|
|
||||
|
SDIO->CLKCR = SDIO_CLKCR_CLKEN | (58 << SDIO_CLKCR_CLKDIV_Pos); |
||||
|
SDIO->POWER |= SDIO_POWER_PWRCTRL; |
||||
|
|
||||
|
|
||||
|
result = SD_Cmd(SD_CMD0,0x00,SDIO_RESP_NONE,(uint32_t*)response); //NORESP
|
||||
|
if (result != 0){ |
||||
|
ERROR("CMD0: %d",result); |
||||
|
return 1; |
||||
|
}; |
||||
|
|
||||
|
result = SD_Cmd(SD_CMD8,SD_CHECK_PATTERN,SDIO_RESP_SHORT,(uint32_t*)response); //R7
|
||||
|
if (result != 0) { |
||||
|
ERROR("CMD8: %d",result); |
||||
|
return 8; |
||||
|
}; |
||||
|
if (response[0] != SD_CHECK_PATTERN) { |
||||
|
ERROR("CMD8 check"); |
||||
|
return 8; |
||||
|
}; |
||||
|
|
||||
|
trials = 0x0000FFFF; |
||||
|
while (--trials) { |
||||
|
SD_Cmd(SD_CMD55, 0 ,SDIO_RESP_SHORT,(uint32_t*)response); // CMD55 with RCA 0 R1
|
||||
|
SD_check_status((SD_Status_TypeDef*)&SDStatus,(uint32_t*)&response[0]); |
||||
|
SD_Cmd(SD_ACMD41,(1<<20|1<<30),SDIO_RESP_SHORT,(uint32_t*)response); |
||||
|
if (response[0] & SDIO_ACMD41_CHECK) break; |
||||
|
} |
||||
|
if (!trials) { |
||||
|
ERROR("CMD41 check"); |
||||
|
return 41; |
||||
|
}; |
||||
|
|
||||
|
result = SD_Cmd(SD_CMD2,0x00,SDIO_RESP_LONG,(uint32_t*)response); //CMD2 CID R2
|
||||
|
if (result != 0) { |
||||
|
ERROR("CMD2: %d",result); |
||||
|
return 2; |
||||
|
}; |
||||
|
|
||||
|
SDCard.CID[0]=response[0]; |
||||
|
SDCard.CID[1]=response[1]; |
||||
|
SDCard.CID[2]=response[2]; |
||||
|
SDCard.CID[3]=response[3]; |
||||
|
|
||||
|
result = SD_Cmd(SD_CMD3,0x00,SDIO_RESP_SHORT,(uint32_t*)response); //CMD3 RCA R6
|
||||
|
if (result != 0){ |
||||
|
ERROR("CMD3: %d",result); |
||||
|
return 3; |
||||
|
}; |
||||
|
|
||||
|
SDCard.RCA=( response[0] & (0xFFFF0000) ); |
||||
|
|
||||
|
result = SD_Cmd(SD_CMD9,SDCard.RCA,SDIO_RESP_LONG,(uint32_t*)response); //CMD9 СSD R2
|
||||
|
if (result != 0) { |
||||
|
ERROR("CMD9: %d",result); |
||||
|
return 9; |
||||
|
} |
||||
|
|
||||
|
SDCard.CSD[0]=response[0]; |
||||
|
SDCard.CSD[1]=response[1]; |
||||
|
SDCard.CSD[2]=response[2]; |
||||
|
SDCard.CSD[3]=response[3]; |
||||
|
|
||||
|
SD_parse_CSD((uint32_t*)SDCard.CSD); |
||||
|
|
||||
|
result = SD_Cmd(SD_CMD7,SDCard.RCA,SDIO_RESP_SHORT,(uint32_t*)response); //CMD7 tran R1b
|
||||
|
SD_check_status((SD_Status_TypeDef*)&SDStatus,(uint32_t*)&response[0]); |
||||
|
if (result != 0) { |
||||
|
ERROR("CMD7: %d",result); |
||||
|
return 7; |
||||
|
} |
||||
|
|
||||
|
state=0; |
||||
|
//Дождаться когда карта будет в режиме tran (4)
|
||||
|
while(state != 4){ |
||||
|
SD_Cmd(SD_CMD13, SDCard.RCA ,SDIO_RESP_SHORT,(uint32_t*)response); |
||||
|
SD_check_status((SD_Status_TypeDef*)&SDStatus,(uint32_t*)&response[0]); |
||||
|
state=SDStatus.current_state; |
||||
|
}; |
||||
|
|
||||
|
#if(SDIO_4BIT_Mode == 1) |
||||
|
result = SD_Cmd(SD_CMD55, SDCard.RCA ,SDIO_RESP_SHORT,(uint32_t*)response); //CMD55 with RCA
|
||||
|
SD_check_status((SD_Status_TypeDef*)&SDStatus,(uint32_t*)&response[0]); |
||||
|
if (result != 0)return 55; |
||||
|
|
||||
|
result = SD_Cmd(6, 0x02, SDIO_RESP_SHORT,(uint32_t*)response); //Шлем ACMD6 c аргументом 0x02, установив 4-битный режим
|
||||
|
if (result != 0) {return 6;}; |
||||
|
if (response[0] != 0x920) {return 5;}; //Убеждаемся, что карта находится в готовности работать с трансфером
|
||||
|
|
||||
|
tempreg=((0x01)<<SDIO_CLKCR_WIDBUS_Pos)| SDIO_CLKCR_CLKEN |( 2 << SDIO_CLKCR_CLKDIV_Pos); |
||||
|
//tempreg=((0x01)<<SDIO_CLKCR_WIDBUS_Pos)| SDIO_CLKCR_CLKEN;
|
||||
|
SDIO->CLKCR=tempreg; |
||||
|
|
||||
|
#if (SDIO_HIGH_SPEED != 0) |
||||
|
SD_HighSpeed(); |
||||
|
tempreg=((0x01)<<SDIO_CLKCR_WIDBUS_Pos)| SDIO_CLKCR_BYPASS | SDIO_CLKCR_CLKEN; |
||||
|
SDIO->CLKCR=tempreg; |
||||
|
#endif |
||||
|
#else |
||||
|
tempreg=0; |
||||
|
tempreg=SDIO_CLKCR_CLKEN; |
||||
|
SDIO->CLKCR=tempreg; |
||||
|
#endif |
||||
|
|
||||
|
DEBUG("SDINIT: ok"); |
||||
|
return 0; |
||||
|
}; |
||||
|
|
||||
|
void SD_parse_CSD(uint32_t* reg){ |
||||
|
uint32_t tmp; |
||||
|
//Версия CSD регистра
|
||||
|
if(reg[0] & (11U << 30)){ |
||||
|
SDCard.CSDVer=2; |
||||
|
}else{ |
||||
|
SDCard.CSDVer=1; |
||||
|
}; |
||||
|
//Размер карты и количество блоков
|
||||
|
tmp= (reg[2] >> 16) & 0xFFFF; |
||||
|
tmp |= (reg[1] & 0x3F) << 16; |
||||
|
SDCard.BlockCount=tmp*1000; |
||||
|
SDCard.Capacity=(tmp+1)*512; |
||||
|
}; |
||||
|
|
@ -0,0 +1,144 @@ |
|||||
|
#ifndef SDIO_DRIVER_H |
||||
|
#define SDIO_DRIVER_H |
||||
|
|
||||
|
#include "../../module/mks_wifi/small_cmsis.h" |
||||
|
#include "../../module/mks_wifi/mks_wifi_sd_low_lev.h" |
||||
|
|
||||
|
// SD card description
|
||||
|
typedef struct { |
||||
|
uint32_t Capacity; // Card capacity (MBytes for SDHC/SDXC, bytes otherwise)
|
||||
|
uint32_t BlockCount; // SD card blocks count
|
||||
|
uint32_t BlockSize; // SD card block size (bytes), determined in SD_ReadCSD()
|
||||
|
uint32_t MaxBusClkFreq; // Maximum card bus frequency (MHz)
|
||||
|
uint32_t RCA; // SD card RCA address (only for SDIO)
|
||||
|
uint32_t PSN; // SD card serial number
|
||||
|
uint32_t CSD[4]; // SD card CSD register (card structure data)
|
||||
|
uint32_t CID[4]; // SD card CID register (card identification number)
|
||||
|
uint16_t OID; // SD card OEM/Application ID
|
||||
|
uint16_t MDT; // SD card manufacturing date
|
||||
|
uint8_t Type; // Card type (detected by SD_Init())
|
||||
|
uint8_t CSDVer; // SD card CSD register version
|
||||
|
uint8_t MID; // SD card manufacturer ID
|
||||
|
uint8_t PNM[5]; // SD card product name (5-character ASCII string)
|
||||
|
uint8_t PRV; // SD card product revision (two BCD digits: '6.2' will be 01100010b)
|
||||
|
uint8_t SCR[8]; // SD card SCR register (SD card configuration)
|
||||
|
} SDCard_TypeDef; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t out_of_range; //Аргумент команды вышел за пределы допустимого диапазона для этой карты.
|
||||
|
uint8_t address_error; //Ошибочно выровненный адрес, который не соответствует длине блока, который использовался в команде.
|
||||
|
uint8_t block_len_error; //Длина передаваемого блока не допустима для этой карты, или количество передаваемых байт не соответствует длине блока.
|
||||
|
uint8_t erase_seq_error; //Произошла ошибка в последовательности команд стирания.
|
||||
|
uint8_t erase_param; //Произошел недопустимый выбор записываемых блоков для стирания.
|
||||
|
uint8_t wp_violation; //Устанавливается, когда хост попытался выполнить запись в защищенный блок либо на временно защищенную от записи, либо на постоянно защищенную от записи карту.
|
||||
|
uint8_t card_is_locked; //Если установлен, то сигнализирует, что карта заблокирована хостом.
|
||||
|
uint8_t lock_unlock_failed; //Устанавливается, когда была детектирована ошибка пароля в команде блокировки/разблокировки карты.
|
||||
|
uint8_t com_crc_error; //Ошибка CRC предыдущей команды.
|
||||
|
uint8_t illegal_command; //Команда недопустима для текущего состояния карты.
|
||||
|
uint8_t card_ecc_failed; //Была применена внутренняя ECC, но произошла ошибка для корректных данных.
|
||||
|
uint8_t cc_error; //Ошибка внутреннего контроллера карты.
|
||||
|
uint8_t error; //Во время выполнения операции произошла общая или неизвестная ошибка.
|
||||
|
uint8_t csd_overwrite; //Произошла одна из следующих ошибок: - Секция только для чтения CSD не соответствует содержимому карты. - Попытка реверса копирования (копирование в место источника), или ошибка защиты от записи.
|
||||
|
uint8_t wp_erase_skip; //Устанавливается, когда была очищена только часть адресного пространства - из-за наличия защищенных от записи блоков, или очищалась карта, временно или постоянно защищенная от записи.
|
||||
|
uint8_t card_ecc_disabled;//Была выполнена команда без внутреннего ECC.
|
||||
|
uint8_t erase_reset; //Была очищена последовательность стирания перед выполнением, потому что была принята команда выхода из последовательности стирания.
|
||||
|
uint8_t current_state; //Состояние карты, когда принимается команда. Если выполнение команды приводит к изменению состояния карты, это увидит хост в ответ на следующую команду. Эти 4 бита интерпретируются как двоичное число со значением в диапазоне от 0 до 15.
|
||||
|
/*
|
||||
|
0: idle |
||||
|
1: ready |
||||
|
2: ident |
||||
|
3: stby |
||||
|
4: tran |
||||
|
5: data |
||||
|
6: rcv |
||||
|
7: prg |
||||
|
8: dis |
||||
|
9..14:зарезервировано |
||||
|
15: зарезервировано для режима I/O |
||||
|
*/ |
||||
|
uint8_t ready_for_data; //Соответствует сигнализации по шине, что буфер пуст.
|
||||
|
uint8_t app_cmd; //Карта ожидает ACMD, или показывается, что команда была интерпретирована как ACMD.
|
||||
|
uint8_t ake_seq_error; //Ошибка в последовательности аутентификации.
|
||||
|
} SD_Status_TypeDef; |
||||
|
|
||||
|
|
||||
|
#define SDIO_4BIT_Mode 1 |
||||
|
//#define SDIO_HIGH_SPEED 1
|
||||
|
|
||||
|
#define SDIO_DATA_TIMEOUT ((uint32_t)0x01000000) |
||||
|
|
||||
|
// SDIO CMD response type
|
||||
|
#define SDIO_RESP_NONE 0x00 // No response
|
||||
|
#define SDIO_RESP_SHORT SDIO_CMD_WAITRESP_0 // Short response
|
||||
|
#define SDIO_RESP_LONG SDIO_CMD_WAITRESP // Long response
|
||||
|
|
||||
|
// SD commands index
|
||||
|
#define SD_CMD0 ((uint8_t)0) |
||||
|
#define SD_CMD8 ((uint8_t)8) |
||||
|
#define SD_CMD55 ((uint8_t)55) |
||||
|
#define SD_ACMD41 ((uint8_t)41) |
||||
|
#define SD_CMD2 ((uint8_t)2) |
||||
|
#define SD_CMD3 ((uint8_t)3) |
||||
|
#define SD_CMD6 ((uint8_t)6) |
||||
|
#define SD_CMD7 ((uint8_t)7) |
||||
|
#define SD_CMD9 ((uint8_t)9) |
||||
|
|
||||
|
#define SD_CMD12 ((uint8_t)12) |
||||
|
#define SD_CMD13 ((uint8_t)13) |
||||
|
|
||||
|
#define SD_CMD_SET_BLOCKLEN ((uint8_t)16) |
||||
|
#define SD_CMD_SWITCH_FUNC ((uint8_t)6U) |
||||
|
|
||||
|
#define SD_CMD17 ((uint8_t)17) |
||||
|
#define SD_CMD18 ((uint8_t)18) |
||||
|
|
||||
|
#define SD_CMD24 ((uint8_t)24) |
||||
|
#define SD_CMD25 ((uint8_t)25) |
||||
|
|
||||
|
#define SDIO_ACMD41_CHECK ((uint32_t)0x80000000) |
||||
|
// Pattern for R6 response
|
||||
|
#define SD_CHECK_PATTERN ((uint32_t)0x000001AA) |
||||
|
|
||||
|
#define UM2SD (0x00) //Transfer Direction
|
||||
|
#define SD2UM (0x02) |
||||
|
|
||||
|
|
||||
|
|
||||
|
#define DMA_S4_CLEAR ((uint32_t) DMA_IFCR_CTCIF4 | DMA_IFCR_CTEIF4 | DMA_IFCR_CGIF4 | DMA_IFCR_CHTIF4) |
||||
|
#define DMA_SDIO_CR ((uint32_t)( (0x03 << DMA_CCR_PL_Pos) | \ |
||||
|
(0x02 << DMA_CCR_MSIZE_Pos) | \ |
||||
|
(0x02 << DMA_CCR_PSIZE_Pos) | \ |
||||
|
(0x01 << DMA_CCR_MINC_Pos) | \ |
||||
|
(0x00 << DMA_CCR_PINC_Pos) | \ |
||||
|
(0x00 << DMA_CCR_CIRC_Pos)) ) |
||||
|
|
||||
|
#define SDIO_DATA_R_TIMEOUT (uint32_t)9000000 |
||||
|
#define SDIO_DCTRL (uint32_t)((uint32_t) 9 << SDIO_DCTRL_DBLOCKSIZE_Pos ) | ((uint32_t) 1 << SDIO_DCTRL_DMAEN_Pos) | SDIO_DCTRL_DTEN |
||||
|
#define SDIO_ICR_STATIC ((uint32_t)(SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | SDIO_ICR_CTIMEOUTC | \ |
||||
|
SDIO_ICR_DTIMEOUTC | SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \ |
||||
|
SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | SDIO_ICR_DATAENDC | \ |
||||
|
SDIO_ICR_DBCKENDC | SDIO_ICR_STBITERRC )) |
||||
|
|
||||
|
#define SDIO_ICR_DATA_FLAGS (SDIO_ICR_DBCKENDC | SDIO_ICR_STBITERRC | SDIO_ICR_DATAENDC | SDIO_ICR_RXOVERRC | SDIO_ICR_TXUNDERRC | SDIO_ICR_DTIMEOUTC | SDIO_ICR_DCRCFAILC) |
||||
|
#define SDIO_ICR_CMD_FLAGS (SDIO_ICR_CEATAENDC | SDIO_ICR_SDIOITC | SDIO_ICR_CMDSENTC | SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC) |
||||
|
#define SDIO_STA_ERRORS (uint32_t)(SDIO_STA_STBITERR | SDIO_STA_RXOVERR | SDIO_STA_TXUNDERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL ) |
||||
|
|
||||
|
#define SDIO_STA_TRX_ERROR_FLAGS (SDIO_STA_STBITERR | SDIO_STA_RXOVERR | SDIO_STA_TXUNDERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL) |
||||
|
#define SDIO_STA_CMD_ERROR_FLAGS (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL) |
||||
|
#define SDIO_STA_TRX_ACT_FLAGS (SDIO_STA_RXACT|SDIO_STA_TXACT) |
||||
|
#define SDIO_STA_CMD_FLAGS (uint32_t)(SDIO_STA_CCRCFAIL|SDIO_STA_CTIMEOUT|SDIO_STA_CMDSENT|SDIO_STA_CMDREND) |
||||
|
|
||||
|
|
||||
|
#define DISABLE_IRQ { __asm volatile ("cpsid i" : : : "memory");} |
||||
|
#define ENABLE_IRQ { __asm volatile ("cpsie i" : : : "memory");} |
||||
|
|
||||
|
//uint8_t SD_Init(void);
|
||||
|
void SD_parse_CSD(uint32_t* reg); |
||||
|
void SD_check_status(SD_Status_TypeDef* SDStatus,uint32_t* reg); |
||||
|
uint32_t SD_get_block_count(void); |
||||
|
uint8_t SD_Cmd(uint8_t cmd, uint32_t arg, uint16_t response_type, uint32_t *response); |
||||
|
uint32_t SD_transfer(uint8_t *buf, uint32_t blk, uint32_t cnt, uint32_t dir); |
||||
|
uint8_t SD_Init(void); |
||||
|
//void SDIO_Config(void);
|
||||
|
|
||||
|
#endif |
Loading…
Reference in new issue