Wrote basic command funcs, acmd41 begun, cmd55, dmainit

This commit is contained in:
2015-10-13 18:39:29 +02:00
parent 9979813693
commit ae9679f10f
10 changed files with 993 additions and 14 deletions

View File

@@ -2,21 +2,56 @@
* shimatta_sdio-driver.c
*
* Created on: Apr 30, 2015
* Author: mari
* Mario Hüttel
*/
#include <shimatta_sdio-driver.h>
#define SETAF(PORT,PIN,AF) PORT->AFR[(PIN < 8 ? 0 : 1)] |= AF << ((PIN < 8 ? PIN : (PIN - 8)) * 4)
#define READCTRL ((BLOCKSIZE << 4) | SDIO_DCTRL_DMAEN)
#define DMAP2M (DMA_SxCR_CHSEL_2 | DMA_SxCR_PBURST_0 | DMA_SxCR_MBURST_0 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PSIZE_1 | DMA_SxCR_MINC | DMA_SxCR_PFCTRL)
#define DMAM2P (DMA_SxCR_CHSEL_2 | DMA_SxCR_PBURST_0 | DMA_SxCR_MBURST_0 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PSIZE_1 | DMA_SxCR_MINC | DMA_SxCR_PFCTRL | DMA_SxCR_DIR_0)
#define SHORT_ANS 1
#define LONG_ANS 3
#define NO_ANS 0
#define CCRCFAIL -1
#define CTIMEOUT -2
void SDIO_DMA_Init();
void SDIO_InitModule();
int SDIO_sendCmd(uint8_t CMD, uint32_t arg, uint8_t expectedAns);
int SDIO_getResp(uint8_t expectedCMD, uint8_t typeOfAns, uint32_t* responseBuffer);
int SDIO_parseR1Ans(uint32_t resp, StatusConv_t converter);
int SDIO_send_ACMD41();
int SDIO_send_CMD55();
//BYTE rxtxbuffer[1<<BLOCKSIZE]; //Data RX and TX Buffer not needed anymore. thanks to DMA
SDInfo_t cardInfo;
DSTATUS SDIO_status(){
return 0;
}
DSTATUS SDIO_initialize(){
cardInfo.rca = 0;
cardInfo.type = CARD_NONE;
SDIO_DMA_Init();
SDIO_InitModule();
return 0;
}
DRESULT SDIO_disk_read(BYTE *buff, DWORD sector, UINT count){
return RES_OK;
}
DRESULT SDIO_disk_write(BYTE *buff, DWORD sector, UINT count){
DRESULT SDIO_disk_write(const BYTE *buff, DWORD sector, UINT count){
return RES_OK;
}
DRESULT SDIO_disk_ioctl(BYTE cmd, void* buff){
@@ -25,3 +60,133 @@ DRESULT SDIO_disk_ioctl(BYTE cmd, void* buff){
DWORD __attribute__((weak)) get_fattime(){
return 0;
}
void SDIO_DMA_Init(){
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
DMASTREAM->CR = DMAM2P;
//Address Conffiguration
//Memory address is set by write and read block functions
//DMASTREAM->M0AR = (uint32_t)&rxtxbuffer;
DMASTREAM->PAR = (uint32_t)&SDIO->FIFO; //Not sure if this works
//DMASTREAM->CR |= DMA_SxCR_EN;
}
void SDIO_InitModule(){
//Init Clocks
RCC->AHB1ENR |= PORTCLKMASK;
RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;
//Init Alternate Functions
CLKPORT->MODER |= (2<<CLKPIN*2);
D0PORT->MODER |= (2<<D0PIN*2);
#if BUSWIDTH==1
D1PORT->MODER |= (2<<D1PIN*2);
D2PORT->MODER |= (2<<D2PIN*2);
D3PORT->MODER |= (2<<D3PIN*2);
#endif
//CLKPORT->AFR[(CLKPIN < 8 ? 0 : 1)] |= ALTFUNC << ((CLKPIN < 8 ? CLKPIN : (CLKPIN - 8)) * 4);
SETAF(CLKPORT, CLKPIN, ALTFUNC);
SETAF(D0PORT, D0PIN, ALTFUNC);
#if BUSWIDTH==1
SETAF(D1PORT, D1PIN, ALTFUNC);
SETAF(D2PORT, D2PIN, ALTFUNC);
SETAF(D3PORT, D3PIN, ALTFUNC);
#endif
//Init Module
//Set CLK Control Register
SDIO->CLKCR = (HW_FLOW<<14) | (BUSWIDTH<<11) | SDIO_CLKCR_CLKEN | (INITCLK & SDIO_CLKCR_CLKDIV);
//Set Data Timeout
SDIO->DTIMER = DTIMEOUT;
//Set Data Parameters
//SDIO->DCTRL = (BLOCKSIZE << 4) | SDIO_DCTRL_DMAEN;
//Set Power Register: Power up Card CLK
SDIO->POWER = SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1;
}
int SDIO_parseR1Ans(uint32_t resp, StatusConv_t converter){
statusConverter.value = resp;
return 0;
}
//Send Command
//Clear respone Flags
//->CRC Fail, complete response, Timeout
int SDIO_sendCmd(uint8_t CMD, uint32_t arg, uint8_t expectedAns){
//Clear Flags
SDIO->ICR = SDIO_ICR_CCRCFAILC | SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC;
//Send command
SDIO->ARG = arg;
SDIO->CMD = (CMD & SDIO_CMD_CMDINDEX) | SDIO_CMD_CPSMEN | SDIO_CMD_WAITPEND | ((expectedAns << 6) & SDIO_CMD_WAITRESP);
return 0;
}
int SDIO_getResp(uint8_t expectedCMD, uint8_t typeOfAns, uint32_t *responseBuffer) {
//Return with success because no data is needed
if (typeOfAns == NO_ANS) return 0;
//Wait for error or success
while (1) {
if (SDIO->STA & SDIO_STA_CMDREND) break; //Corrct Respone Received
//Exclude 41 from valid CRC check
if ((SDIO->STA & SDIO_STA_CCRCFAIL)) {
if(expectedCMD == 41) {
//This command does not have a CRC...Doushite....
break;//Hopefully the response is correct. Even without CRC....
}
}
if (SDIO->STA & SDIO_STA_CTIMEOUT)
return CTIMEOUT;
}
//Valid Respone Received
if ((SDIO->RESPCMD & SDIO_RESPCMD_RESPCMD) != expectedCMD) return -1; //Not the expected respose
//Correct Response
*(responseBuffer++) = SDIO->RESP1;
//Long response. Never needed with SD Cards
if (typeOfAns == LONG_ANS) {
*(responseBuffer++) = SDIO->RESP2;
*(responseBuffer++) = SDIO->RESP3;
*(responseBuffer++) = SDIO->RESP4;
}
}
int SDIO_send_CMD55(){
int retry = 0x20;
StatusConv_t converter;
uint32_t response;
do {
//Execute Command and check for valid response
SDIO_sendCmd(55, cardInfo.rca, SHORT_ANS);
if (!SDIO_getResp(55, SHORT_ANS, &response))
{
//Response valid. Check if Card has accepted switch to application command mode
converter.value = response;
if (converter.statusstruct.APP_CMD == 1)
return 0;
}
}while(--retry > 0);
return -1;
}
int SDIO_send_ACMD41(){
int retry = 0x200;
if (SDIO_send_CMD55()) return -1;
do {
SDIO_sendCmd(41, 1<<30, SHORT_ANS);
//TODO: Implement Response Check...
}while(--retry > 0);
}

View File

@@ -2,19 +2,114 @@
* shimatta_sdio-driver.h
*
* Created on: Apr 26, 2015
* Author: mari
* Mario Hüttel
*/
#ifndef FATFS_SHIMATTA_SDIO_DRIVER_SHIMATTA_SDIO_DRIVER_H_
#define FATFS_SHIMATTA_SDIO_DRIVER_SHIMATTA_SDIO_DRIVER_H_
#include <diskio.h>
#include <stm32f4xx.h>
DSTATUS SDIO_status();
DSTATUS SDIO_initialize();
DRESULT SDIO_disk_read(BYTE *buff, DWORD sector, UINT count);
DRESULT SDIO_disk_write(BYTE *buff, DWORD sector, UINT count);
DRESULT SDIO_disk_write(const BYTE *buff, DWORD sector, UINT count);
DRESULT SDIO_disk_ioctl(BYTE cmd, void* buff);
DWORD get_fattime();
#define CURRENT_STATE_IDLE 0
#define CURRENT_STATE_READY 1
#define CURRENT_STATE_IDENT 2
#define CURRENT_STATE_STBY 3
#define CURRENT_STATE_TRAN 4
#define CURRENT_STATE_DATA 5
#define CURRENT_STATE_RCV 6
#define CURRENT_STATE_PRG 7
#define CURRENT_STATE_DIS 8
typedef struct _CardStatus {
uint32_t reserved : 3;
uint32_t AKE_SEQ_ERROR : 1;
uint32_t reserved_2 : 1;
uint32_t APP_CMD : 1;
uint32_t reserved_3 : 2;
uint32_t READY_FOR_DATA : 1;
uint32_t CURRENT_STATE : 4;
uint32_t ERASE_RESET : 1;
uint32_t CARD_ECC_DIABLED : 1;
uint32_t WP_ERASE_SKIP : 1;
uint32_t CSD_OVERWRITE : 1;
uint32_t reserved17 : 1;
uint32_t reserved18 : 1;
uint32_t ERROR : 1;
uint32_t CC_ERROR : 1;
uint32_t CARD_ECC_FAILED : 1;
uint32_t ILLEGAL_COMMAND : 1;
uint32_t COM_CRC_ERROR : 1;
uint32_t LOCK_UNLOCK_FAILED : 1;
uint32_t CARD_IS_LOCKED : 1;
uint32_t WP_VIOLATION : 1;
uint32_t ERASE_PARAM : 1;
uint32_t ERASE_SEQ_ERROR : 1;
uint32_t BLOCK_LEN_ERROR : 1;
uint32_t ADDRESS_ERROR : 1;
uint32_t OUT_OF_RANGE : 1;
}CardStatus_t;
#define CARD_SD 1
#define CARD_MMC 2//Never use. MMC not supported
#define CARD_NONE 0
typedef struct _SDInfo {
uint32_t rca;
uint8_t type;
}SDInfo_t
typedef union _StatusConv {
CardStatus_t statusstruct;
uint32_t value;
}StatusConv_t;
//General Definitions
//Blocksize: 512 = 2^9 => 9
#define BLOCKSIZE 9 //9
//Hardware Flow: Prevents over- and underruns.
#define HW_FLOW 0 //0
//1 bit: 0
//4 bit: 1
#define BUSWIDTH 1 //1
//Initial Transfer CLK (ca. 400kHz)
#define INITCLK 120 //120
//Working CLK (Maximum)
#define WORKCLK 0 //0
//Data Timeout in CLK Cycles
#define DTIMEOUT 150 //150
//DMA Stream used for TX and RX DMA2 Stream 3 or 6 possible
#define DMASTREAM DMA2_Stream3
//Port Definitions
#define PORTCLKMASK (RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOCEN)
#define ALTFUNC 12
#define CLKPORT GPIOC
#define D0PORT GPIOC
#define D1PORT GPIOC
#define D2PORT GPIOC
#define D3PORT GPIOC
#define CMDPORT GPIOD
#define CLKPIN 12
#define D0PIN 8
#define D1PIN 9
#define D2PIN 10
#define D3PIN 11
#define CMDPIN 2
#endif /* FATFS_SHIMATTA_SDIO_DRIVER_SHIMATTA_SDIO_DRIVER_H_ */