Wrote basic command funcs, acmd41 begun, cmd55, dmainit
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
#include <shimatta_sdio-driver.h>
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define SDIO 0 /* Example: Map ATA harddisk to physical drive 0 */
|
||||
#define SDCARD 0 /* Example: Map ATA harddisk to physical drive 0 */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
@@ -22,7 +22,7 @@ DSTATUS disk_status(BYTE pdrv /* Physical drive number to identify the drive */
|
||||
) {
|
||||
|
||||
switch (pdrv) {
|
||||
case SDIO:
|
||||
case SDCARD:
|
||||
return SDIO_status();
|
||||
break;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ DSTATUS disk_initialize(BYTE pdrv /* Physical drive number to identify the drive
|
||||
|
||||
|
||||
switch (pdrv) {
|
||||
case SDIO:
|
||||
case SDCARD:
|
||||
return SDIO_initialize();
|
||||
break;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ UINT count /* Number of sectors to read */
|
||||
) {
|
||||
|
||||
switch (pdrv) {
|
||||
case SDIO:
|
||||
case SDCARD:
|
||||
return SDIO_disk_read(buff, sector, count);
|
||||
break;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
) {
|
||||
switch (pdrv) {
|
||||
case SDIO:
|
||||
case SDCARD:
|
||||
return SDIO_disk_write(buff, sector, count);
|
||||
break;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ void *buff /* Buffer to send/receive control data */
|
||||
) {
|
||||
|
||||
switch (pdrv) {
|
||||
case SDIO:
|
||||
case SDCARD:
|
||||
return SDIO_disk_ioctl(cmd, buff);
|
||||
break;
|
||||
}
|
||||
|
@@ -2654,7 +2654,6 @@ FRESULT f_write (
|
||||
const BYTE *wbuff = (const BYTE*)buff;
|
||||
BYTE csect;
|
||||
|
||||
|
||||
*bw = 0; /* Clear write byte counter */
|
||||
|
||||
res = validate(fp); /* Check validity */
|
||||
|
@@ -33,7 +33,7 @@
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
#define _USE_STRFUNC 1
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
@@ -145,8 +145,8 @@
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
#define _STR_VOLUME_ID 1
|
||||
#define _VOLUME_STRS "SD"
|
||||
/* _STR_VOLUME_ID option switches string volume ID feature.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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_ */
|
||||
|
Reference in New Issue
Block a user