From 32e57dac2e61e79b029593eb4d34d727bcc10678 Mon Sep 17 00:00:00 2001 From: iperry Date: Thu, 17 Dec 2009 02:37:07 +0000 Subject: Initial commit of library code, moved from leaftest repo git-svn-id: https://leaflabs.googlecode.com/svn/trunk/library@69 749a229e-a60e-11de-b98f-4500b42dc123 --- src/stm32lib/examples/SDIO/main.c | 329 +++ src/stm32lib/examples/SDIO/readme.txt | 79 + src/stm32lib/examples/SDIO/sdcard.c | 2895 +++++++++++++++++++++++++++ src/stm32lib/examples/SDIO/sdcard.h | 252 +++ src/stm32lib/examples/SDIO/stm32f10x_conf.h | 169 ++ src/stm32lib/examples/SDIO/stm32f10x_it.c | 745 +++++++ src/stm32lib/examples/SDIO/stm32f10x_it.h | 100 + 7 files changed, 4569 insertions(+) create mode 100755 src/stm32lib/examples/SDIO/main.c create mode 100755 src/stm32lib/examples/SDIO/readme.txt create mode 100755 src/stm32lib/examples/SDIO/sdcard.c create mode 100755 src/stm32lib/examples/SDIO/sdcard.h create mode 100755 src/stm32lib/examples/SDIO/stm32f10x_conf.h create mode 100755 src/stm32lib/examples/SDIO/stm32f10x_it.c create mode 100755 src/stm32lib/examples/SDIO/stm32f10x_it.h (limited to 'src/stm32lib/examples/SDIO') diff --git a/src/stm32lib/examples/SDIO/main.c b/src/stm32lib/examples/SDIO/main.c new file mode 100755 index 0000000..73259d0 --- /dev/null +++ b/src/stm32lib/examples/SDIO/main.c @@ -0,0 +1,329 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : main.c +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : Main program body +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" +#include "sdcard.h" + +/* Private typedef -----------------------------------------------------------*/ +typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus; + +/* Private define ------------------------------------------------------------*/ +#define BlockSize 512 /* Block Size in Bytes */ +#define BufferWordsSize (BlockSize >> 2) + +#define NumberOfBlocks 2 /* For Multi Blocks operation (Read/Write) */ +#define MultiBufferWordsSize ((BlockSize * NumberOfBlocks) >> 2) + + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +SD_CardInfo SDCardInfo; +u32 Buffer_Block_Tx[BufferWordsSize], Buffer_Block_Rx[BufferWordsSize]; +u32 Buffer_MultiBlock_Tx[MultiBufferWordsSize], Buffer_MultiBlock_Rx[MultiBufferWordsSize]; +volatile TestStatus EraseStatus = FAILED, TransferStatus1 = FAILED, TransferStatus2 = FAILED; +SD_Error Status = SD_OK; +ErrorStatus HSEStartUpStatus; + +/* Private function prototypes -----------------------------------------------*/ +void RCC_Configuration(void); +void NVIC_Configuration(void); +void Fill_Buffer(u32 *pBuffer, u16 BufferLenght, u32 Offset); +TestStatus Buffercmp(u32* pBuffer1, u32* pBuffer2, u16 BufferLength); +TestStatus eBuffercmp(u32* pBuffer, u16 BufferLength); + +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : main +* Description : Main program. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +int main(void) +{ +#ifdef DEBUG + debug(); +#endif + + /* Clock Config */ + RCC_Configuration(); + + /* Interrupt Config */ + NVIC_Configuration(); + + /*-------------------------- SD Init ----------------------------- */ + Status = SD_Init(); + + if (Status == SD_OK) + { + /*----------------- Read CSD/CID MSD registers ------------------*/ + Status = SD_GetCardInfo(&SDCardInfo); + } + + if (Status == SD_OK) + { + /*----------------- Select Card --------------------------------*/ + Status = SD_SelectDeselect((u32) (SDCardInfo.RCA << 16)); + } + + if (Status == SD_OK) + { + Status = SD_EnableWideBusOperation(SDIO_BusWide_4b); + } + + /*------------------- Block Erase -------------------------------*/ + if (Status == SD_OK) + { + /* Erase NumberOfBlocks Blocks of WRITE_BL_LEN(512 Bytes) */ + Status = SD_Erase(0x00, (BlockSize * NumberOfBlocks)); + } + + /* Set Device Transfer Mode to DMA */ + if (Status == SD_OK) + { + Status = SD_SetDeviceMode(SD_DMA_MODE); + } + + if (Status == SD_OK) + { + Status = SD_ReadMultiBlocks(0x00, Buffer_MultiBlock_Rx, BlockSize, NumberOfBlocks); + } + + if (Status == SD_OK) + { + EraseStatus = eBuffercmp(Buffer_MultiBlock_Rx, MultiBufferWordsSize); + } + + /*------------------- Block Read/Write --------------------------*/ + /* Fill the buffer to send */ + Fill_Buffer(Buffer_Block_Tx, BufferWordsSize, 0xFFFF); + + + if (Status == SD_OK) + { + /* Write block of 512 bytes on address 0 */ + Status = SD_WriteBlock(0x00, Buffer_Block_Tx, BlockSize); + } + + if (Status == SD_OK) + { + /* Read block of 512 bytes from address 0 */ + Status = SD_ReadBlock(0x00, Buffer_Block_Rx, BlockSize); + } + + if (Status == SD_OK) + { + /* Check the corectness of written dada */ + TransferStatus1 = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BufferWordsSize); + } + + /*--------------- Multiple Block Read/Write ---------------------*/ + /* Fill the buffer to send */ + Fill_Buffer(Buffer_MultiBlock_Tx, MultiBufferWordsSize, 0x0); + + if (Status == SD_OK) + { + /* Write multiple block of many bytes on address 0 */ + Status = SD_WriteMultiBlocks(0x00, Buffer_MultiBlock_Tx, BlockSize, NumberOfBlocks); + } + + if (Status == SD_OK) + { + /* Read block of many bytes from address 0 */ + Status = SD_ReadMultiBlocks(0x00, Buffer_MultiBlock_Rx, BlockSize, NumberOfBlocks); + } + + if (Status == SD_OK) + { + /* Check the corectness of written dada */ + TransferStatus2 = Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MultiBufferWordsSize); + } + + /* Infinite loop */ + while (1) + {} +} + +/******************************************************************************* +* Function Name : RCC_Configuration +* Description : Configures the different system clocks. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RCC_Configuration(void) +{ + /* RCC system reset(for debug purpose) */ + RCC_DeInit(); + + /* Enable HSE */ + RCC_HSEConfig(RCC_HSE_ON); + + /* Wait till HSE is ready */ + HSEStartUpStatus = RCC_WaitForHSEStartUp(); + + if(HSEStartUpStatus == SUCCESS) + { + /* Enable Prefetch Buffer */ + FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); + + /* Flash 2 wait state */ + FLASH_SetLatency(FLASH_Latency_2); + + /* HCLK = SYSCLK */ + RCC_HCLKConfig(RCC_SYSCLK_Div1); + + /* PCLK2 = HCLK */ + RCC_PCLK2Config(RCC_HCLK_Div1); + + /* PCLK1 = HCLK/2 */ + RCC_PCLK1Config(RCC_HCLK_Div2); + + /* PLLCLK = 8MHz * 9 = 72 MHz */ + RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); + + /* Enable PLL */ + RCC_PLLCmd(ENABLE); + + /* Wait till PLL is ready */ + while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) + { + } + + /* Select PLL as system clock source */ + RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); + + /* Wait till PLL is used as system clock source */ + while(RCC_GetSYSCLKSource() != 0x08) + { + } + } +} + +/******************************************************************************* +* Function Name : NVIC_Config +* Description : Configures SDIO IRQ channel. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + /* Configure the NVIC Preemption Priority Bits */ + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + + NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQChannel; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +/******************************************************************************* +* Function Name : Buffercmp +* Description : Compares two buffers. +* Input : - pBuffer1, pBuffer2: buffers to be compared. +* : - BufferLength: buffer's length +* Output : None +* Return : PASSED: pBuffer1 identical to pBuffer2 +* FAILED: pBuffer1 differs from pBuffer2 +*******************************************************************************/ +TestStatus Buffercmp(u32* pBuffer1, u32* pBuffer2, u16 BufferLength) +{ + while (BufferLength--) + { + if (*pBuffer1 != *pBuffer2) + { + return FAILED; + } + + pBuffer1++; + pBuffer2++; + } + + return PASSED; +} + +/******************************************************************************* +* Function name : Fill_Buffer +* Description : Fills buffer with user predefined data. +* Input : - pBuffer: pointer on the Buffer to fill +* - BufferLenght: size of the buffer to fill +* - Offset: first value to fill on the Buffer +* Output : None +* Return : None +*******************************************************************************/ +void Fill_Buffer(u32 *pBuffer, u16 BufferLenght, u32 Offset) +{ + u16 index = 0; + + /* Put in global buffer same values */ + for (index = 0; index < BufferLenght; index++ ) + { + pBuffer[index] = index + Offset; + } +} + +/******************************************************************************* +* Function name : eBuffercmp +* Description : Checks if a buffer has all its values are equal to zero. +* Input : - pBuffer: buffer to be compared. +* : - BufferLength: buffer's length +* Output : None +* Return : PASSED: pBuffer values are zero +* FAILED: At least one value from pBuffer buffer is diffrent +* from zero. +*******************************************************************************/ +TestStatus eBuffercmp(u32* pBuffer, u16 BufferLength) +{ + while (BufferLength--) + { + if (*pBuffer != 0x00) + { + return FAILED; + } + + pBuffer++; + } + + return PASSED; +} + +#ifdef DEBUG +/******************************************************************************* +* Function Name : assert_failed +* Description : Reports the name of the source file and the source line number +* where the assert_param error has occurred. +* Input : - file: pointer to the source file name +* - line: assert_param error line source number +* Output : None +* Return : None +*******************************************************************************/ +void assert_failed(u8* file, u32 line) +{ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + + /* Infinite loop */ + while (1) + {} +} +#endif + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/src/stm32lib/examples/SDIO/readme.txt b/src/stm32lib/examples/SDIO/readme.txt new file mode 100755 index 0000000..54d6cd1 --- /dev/null +++ b/src/stm32lib/examples/SDIO/readme.txt @@ -0,0 +1,79 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : readme.txt +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : Description of the SDIO Example. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +Example description +=================== +This example provides a basic example of how to use the SDIO firmware library and +an associate driver to perform read/write operations on the SD Card memory +mounted on the STM3210E-EVAL board. +Below is a description of the different example steps: + - Configure the SDIO according to the desired SDIO_CK clock frequency. + - Reset the SD Card + - Identify the SD Card + - Initializes the SD Card + - Get the SD Card Info + - Select the SD Card + - Enable the Wide Bus mode (4-bit data) + - Erase the correponding blocks + - Read the Erased blocks + - Test if the corresponding Blocks are well erased: check if the EraseStatus + variable is equal to PASSED. + - Set the Data Transfer Mode to DMA + - Write a single Block + - Read a single Block + - Comapare the written Block and the read one: check if the TransferStatus1 + variable is equal to PASSED. + - Write multiple Blocks (2) + - Read multiple Blocks (2) + - Comapare the written Blocks and the read one: check if the TransferStatus2 + variable is equal to PASSED. + + +Directory contents +================== +stm32f10x_conf.h Library Configuration file +stm32f10x_it.c Interrupt handlers +stm32f10x_it.h Header for stm32f10x_it.c +sdcard.c SD Card Driver file +sdcard.h Header for sdcard.c +main.c Main program + + +Hardware environment +==================== +This example runs on STMicroelectronics STM3210E-EVAL evaluation board and can be +easily tailored to any other hardware. + +Note: make sure that the Jumper 17 (JP17) is closed and Jumper 20 (JP20) is open + in STM3210E-EVAL + + +How to use it +============= +In order to make the program work, you must do the following: +- Create a project and setup all your toolchain's start-up files +- Compile the directory content files and required Library files: + + stm32f10x_lib.c + + stm32f10x_gpio.c + + stm32f10x_rcc.c + + stm32f10x_nvic.c + + stm32f10x_flash.c + + stm32f10x_sdio.c + + stm32f10x_dma.c + +- Link all compiled files and load your image into either RAM or Flash +- Run the example + +******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****** diff --git a/src/stm32lib/examples/SDIO/sdcard.c b/src/stm32lib/examples/SDIO/sdcard.c new file mode 100755 index 0000000..c837e79 --- /dev/null +++ b/src/stm32lib/examples/SDIO/sdcard.c @@ -0,0 +1,2895 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : sdcard.c +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : This file provides all the SD Card driver firmware +* functions. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "sdcard.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define NULL 0 +#define SDIO_STATIC_FLAGS ((u32)0x000005FF) +#define SDIO_CMD0TIMEOUT ((u32)0x00002710) +#define SDIO_FIFO_Address ((u32)0x40018080) + +/* Mask for errors Card Status R1 (OCR Register) */ +#define SD_OCR_ADDR_OUT_OF_RANGE ((u32)0x80000000) +#define SD_OCR_ADDR_MISALIGNED ((u32)0x40000000) +#define SD_OCR_BLOCK_LEN_ERR ((u32)0x20000000) +#define SD_OCR_ERASE_SEQ_ERR ((u32)0x10000000) +#define SD_OCR_BAD_ERASE_PARAM ((u32)0x08000000) +#define SD_OCR_WRITE_PROT_VIOLATION ((u32)0x04000000) +#define SD_OCR_LOCK_UNLOCK_FAILED ((u32)0x01000000) +#define SD_OCR_COM_CRC_FAILED ((u32)0x00800000) +#define SD_OCR_ILLEGAL_CMD ((u32)0x00400000) +#define SD_OCR_CARD_ECC_FAILED ((u32)0x00200000) +#define SD_OCR_CC_ERROR ((u32)0x00100000) +#define SD_OCR_GENERAL_UNKNOWN_ERROR ((u32)0x00080000) +#define SD_OCR_STREAM_READ_UNDERRUN ((u32)0x00040000) +#define SD_OCR_STREAM_WRITE_OVERRUN ((u32)0x00020000) +#define SD_OCR_CID_CSD_OVERWRIETE ((u32)0x00010000) +#define SD_OCR_WP_ERASE_SKIP ((u32)0x00008000) +#define SD_OCR_CARD_ECC_DISABLED ((u32)0x00004000) +#define SD_OCR_ERASE_RESET ((u32)0x00002000) +#define SD_OCR_AKE_SEQ_ERROR ((u32)0x00000008) +#define SD_OCR_ERRORBITS ((u32)0xFDFFE008) + +/* Masks for R6 Response */ +#define SD_R6_GENERAL_UNKNOWN_ERROR ((u32)0x00002000) +#define SD_R6_ILLEGAL_CMD ((u32)0x00004000) +#define SD_R6_COM_CRC_FAILED ((u32)0x00008000) + +#define SD_VOLTAGE_WINDOW_SD ((u32)0x80100000) +#define SD_HIGH_CAPACITY ((u32)0x40000000) +#define SD_STD_CAPACITY ((u32)0x00000000) +#define SD_CHECK_PATTERN ((u32)0x000001AA) + +#define SD_MAX_VOLT_TRIAL ((u32)0x0000FFFF) +#define SD_ALLZERO ((u32)0x00000000) + +#define SD_WIDE_BUS_SUPPORT ((u32)0x00040000) +#define SD_SINGLE_BUS_SUPPORT ((u32)0x00010000) +#define SD_CARD_LOCKED ((u32)0x02000000) +#define SD_CARD_PROGRAMMING ((u32)0x00000007) +#define SD_CARD_RECEIVING ((u32)0x00000006) +#define SD_DATATIMEOUT ((u32)0x000FFFFF) +#define SD_0TO7BITS ((u32)0x000000FF) +#define SD_8TO15BITS ((u32)0x0000FF00) +#define SD_16TO23BITS ((u32)0x00FF0000) +#define SD_24TO31BITS ((u32)0xFF000000) +#define SD_MAX_DATA_LENGTH ((u32)0x01FFFFFF) + +#define SD_HALFFIFO ((u32)0x00000008) +#define SD_HALFFIFOBYTES ((u32)0x00000020) + +/* Command Class Supported */ +#define SD_CCCC_LOCK_UNLOCK ((u32)0x00000080) +#define SD_CCCC_WRITE_PROT ((u32)0x00000040) +#define SD_CCCC_ERASE ((u32)0x00000020) + +/* Following commands are SD Card Specific commands. + SDIO_APP_CMD should be sent before sending these commands. */ +#define SDIO_SEND_IF_COND ((u32)0x00000008) + +#define SDIO_MULTIMEDIA_CARD ((u32)0x0) +#define SDIO_SECURE_DIGITAL_CARD ((u32)0x1) +#define SDIO_SECURE_DIGITAL_IO_CARD ((u32)0x2) +#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD ((u32)0x3) +#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD ((u32)0x4) +#define SDIO_HIGH_CAPACITY_SD_CARD ((u32)0x5) +#define SDIO_HIGH_CAPACITY_MMC_CARD ((u32)0x6) + +#define SDIO_INIT_CLK_DIV ((u8)0xB2) +#define SDIO_TRANSFER_CLK_DIV ((u8)0x1) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static u32 CardType = SDIO_SECURE_DIGITAL_CARD; +static u32 CSD_Tab[4], CID_Tab[4], RCA = 0; +static u32 DeviceMode = SD_POLLING_MODE; +static u32 TotalNumberOfBytes = 0, StopCondition = 0; +u32 *SrcBuffer, *DestBuffer; +volatile SD_Error TransferError = SD_OK; +vu32 TransferEnd = 0; +vu32 NumberOfBytes = 0; +SDIO_InitTypeDef SDIO_InitStructure; +SDIO_CmdInitTypeDef SDIO_CmdInitStructure; +SDIO_DataInitTypeDef SDIO_DataInitStructure; + +/* Private function prototypes -----------------------------------------------*/ +static SD_Error CmdError(void); +static SD_Error CmdResp1Error(u8 cmd); +static SD_Error CmdResp7Error(void); +static SD_Error CmdResp3Error(void); +static SD_Error CmdResp2Error(void); +static SD_Error CmdResp6Error(u8 cmd, u16 *prca); +static SD_Error SDEnWideBus(FunctionalState NewState); +static SD_Error IsCardProgramming(u8 *pstatus); +static SD_Error FindSCR(u16 rca, u32 *pscr); +static u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes); +static void GPIO_Configuration(void); +static void DMA_TxConfiguration(u32 *BufferSRC, u32 BufferSize); +static void DMA_RxConfiguration(u32 *BufferDST, u32 BufferSize); + +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : SD_Init +* Description : Initializes the SD Card and put it into StandBy State (Ready +* for data transfer). +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_Init(void) +{ + SD_Error errorstatus = SD_OK; + + /* Configure SDIO interface GPIO */ + GPIO_Configuration(); + + /* Enable the SDIO AHB Clock */ + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, ENABLE); + + /* Enable the DMA2 Clock */ + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); + + SDIO_DeInit(); + + errorstatus = SD_PowerON(); + + if (errorstatus != SD_OK) + { + /* CMD Response TimeOut (wait for CMDSENT flag) */ + return(errorstatus); + } + + errorstatus = SD_InitializeCards(); + + if (errorstatus != SD_OK) + { + /* CMD Response TimeOut (wait for CMDSENT flag) */ + return(errorstatus); + } + + /* Configure the SDIO peripheral */ + /* HCLK = 72 MHz, SDIOCLK = 72 MHz, SDIO_CK = HCLK/(2 + 1) = 24 MHz */ + SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; + SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; + SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; + SDIO_Init(&SDIO_InitStructure); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_PowerON +* Description : Enquires cards about their operating voltage and configures +* clock controls. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_PowerON(void) +{ + SD_Error errorstatus = SD_OK; + u32 response = 0, count = 0; + bool validvoltage = FALSE; + u32 SDType = SD_STD_CAPACITY; + + /* Power ON Sequence -------------------------------------------------------*/ + /* Configure the SDIO peripheral */ + SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV; /* HCLK = 72MHz, SDIOCLK = 72MHz, SDIO_CK = HCLK/(178 + 2) = 400 KHz */ + SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; + SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; + SDIO_Init(&SDIO_InitStructure); + + /* Set Power State to ON */ + SDIO_SetPowerState(SDIO_PowerState_ON); + + /* Enable SDIO Clock */ + SDIO_ClockCmd(ENABLE); + + /* CMD0: GO_IDLE_STATE -------------------------------------------------------*/ + /* No CMD response required */ + SDIO_CmdInitStructure.SDIO_Argument = 0x0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_GO_IDLE_STATE; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdError(); + + if (errorstatus != SD_OK) + { + /* CMD Response TimeOut (wait for CMDSENT flag) */ + return(errorstatus); + } + + /* CMD8: SEND_IF_COND --------------------------------------------------------*/ + /* Send CMD8 to verify SD card interface operating condition */ + /* Argument: - [31:12]: Reserved (shall be set to '0') + - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) + - [7:0]: Check Pattern (recommended 0xAA) */ + /* CMD Response: R7 */ + SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_IF_COND; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp7Error(); + + if (errorstatus == SD_OK) + { + SDType = SD_HIGH_CAPACITY; /* SD Card 2.0 */ + } + else + { + /* CMD55 */ + SDIO_CmdInitStructure.SDIO_Argument = 0x00; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + errorstatus = CmdResp1Error(SDIO_APP_CMD); + } + /* CMD55 */ + SDIO_CmdInitStructure.SDIO_Argument = 0x00; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + /* If errorstatus is Command TimeOut, it is a MMC card */ + /* If errorstatus is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch) + or SD card 1.x */ + if (errorstatus == SD_OK) + { + /* SD CARD */ + /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ + while ((!validvoltage) && (count < SD_MAX_VOLT_TRIAL)) + { + + /* SEND CMD55 APP_CMD with RCA as 0 */ + SDIO_CmdInitStructure.SDIO_Argument = 0x00; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_SD | SDType; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_APP_OP_COND; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp3Error(); + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + response = SDIO_GetResponse(SDIO_RESP1); + validvoltage = (bool) (((response >> 31) == 1) ? 1 : 0); + count++; + } + if (count >= SD_MAX_VOLT_TRIAL) + { + errorstatus = SD_INVALID_VOLTRANGE; + return(errorstatus); + } + + if (SDType == SD_HIGH_CAPACITY) + { + CardType = SDIO_HIGH_CAPACITY_SD_CARD; + } + else + { + CardType = SDIO_SECURE_DIGITAL_CARD; + } + }/* else MMC Card */ + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_PowerOFF +* Description : Turns the SDIO output signals off. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_PowerOFF(void) +{ + SD_Error errorstatus = SD_OK; + + /* Set Power State to OFF */ + SDIO_SetPowerState(SDIO_PowerState_OFF); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_InitializeCards +* Description : Intialises all cards or single card as the case may be. +* Card(s) come into standby state. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_InitializeCards(void) +{ + SD_Error errorstatus = SD_OK; + u16 rca = 0x01; + + if (SDIO_GetPowerState() == SDIO_PowerState_OFF) + { + errorstatus = SD_REQUEST_NOT_APPLICABLE; + return(errorstatus); + } + + if (SDIO_SECURE_DIGITAL_IO_CARD != CardType) + { + /* Send CMD2 ALL_SEND_CID */ + SDIO_CmdInitStructure.SDIO_Argument = 0x0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_ALL_SEND_CID; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp2Error(); + + if (SD_OK != errorstatus) + { + return(errorstatus); + } + + CID_Tab[0] = SDIO_GetResponse(SDIO_RESP1); + CID_Tab[1] = SDIO_GetResponse(SDIO_RESP2); + CID_Tab[2] = SDIO_GetResponse(SDIO_RESP3); + CID_Tab[3] = SDIO_GetResponse(SDIO_RESP4); + } + if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_SECURE_DIGITAL_IO_CARD == CardType) || (SDIO_SECURE_DIGITAL_IO_COMBO_CARD == CardType) + || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) + { + /* Send CMD3 SET_REL_ADDR with argument 0 */ + /* SD Card publishes its RCA. */ + SDIO_CmdInitStructure.SDIO_Argument = 0x00; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_REL_ADDR; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp6Error(SDIO_SET_REL_ADDR, &rca); + + if (SD_OK != errorstatus) + { + return(errorstatus); + } + } + + if (SDIO_SECURE_DIGITAL_IO_CARD != CardType) + { + RCA = rca; + + /* Send CMD9 SEND_CSD with argument as card's RCA */ + SDIO_CmdInitStructure.SDIO_Argument = (u32)(rca << 16); + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_CSD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp2Error(); + + if (SD_OK != errorstatus) + { + return(errorstatus); + } + + CSD_Tab[0] = SDIO_GetResponse(SDIO_RESP1); + CSD_Tab[1] = SDIO_GetResponse(SDIO_RESP2); + CSD_Tab[2] = SDIO_GetResponse(SDIO_RESP3); + CSD_Tab[3] = SDIO_GetResponse(SDIO_RESP4); + } + + errorstatus = SD_OK; /* All cards get intialized */ + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_GetCardInfo +* Description : Returns information about specific card. +* Input : cardinfo : pointer to a SD_CardInfo structure +* that contains all SD card information. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo) +{ + SD_Error errorstatus = SD_OK; + u8 tmp = 0; + + cardinfo->CardType = (u8)CardType; + cardinfo->RCA = (u16)RCA; + + /* Byte 0 */ + tmp = (u8)((CSD_Tab[0] & 0xFF000000) >> 24); + cardinfo->SD_csd.CSDStruct = (tmp & 0xC0) >> 6; + cardinfo->SD_csd.SysSpecVersion = (tmp & 0x3C) >> 2; + cardinfo->SD_csd.Reserved1 = tmp & 0x03; + + /* Byte 1 */ + tmp = (u8)((CSD_Tab[0] & 0x00FF0000) >> 16); + cardinfo->SD_csd.TAAC = tmp; + + /* Byte 2 */ + tmp = (u8)((CSD_Tab[0] & 0x0000FF00) >> 8); + cardinfo->SD_csd.NSAC = tmp; + + /* Byte 3 */ + tmp = (u8)(CSD_Tab[0] & 0x000000FF); + cardinfo->SD_csd.MaxBusClkFrec = tmp; + + /* Byte 4 */ + tmp = (u8)((CSD_Tab[1] & 0xFF000000) >> 24); + cardinfo->SD_csd.CardComdClasses = tmp << 4; + + /* Byte 5 */ + tmp = (u8)((CSD_Tab[1] & 0x00FF0000) >> 16); + cardinfo->SD_csd.CardComdClasses |= (tmp & 0xF0) >> 4; + cardinfo->SD_csd.RdBlockLen = tmp & 0x0F; + + /* Byte 6 */ + tmp = (u8)((CSD_Tab[1] & 0x0000FF00) >> 8); + cardinfo->SD_csd.PartBlockRead = (tmp & 0x80) >> 7; + cardinfo->SD_csd.WrBlockMisalign = (tmp & 0x40) >> 6; + cardinfo->SD_csd.RdBlockMisalign = (tmp & 0x20) >> 5; + cardinfo->SD_csd.DSRImpl = (tmp & 0x10) >> 4; + cardinfo->SD_csd.Reserved2 = 0; /* Reserved */ + cardinfo->SD_csd.DeviceSize = (tmp & 0x03) << 10; + + /* Byte 7 */ + tmp = (u8)(CSD_Tab[1] & 0x000000FF); + cardinfo->SD_csd.DeviceSize |= (tmp) << 2; + + /* Byte 8 */ + tmp = (u8)((CSD_Tab[2] & 0xFF000000) >> 24); + + cardinfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6; + cardinfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3; + cardinfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07); + + /* Byte 9 */ + tmp = (u8)((CSD_Tab[2] & 0x00FF0000) >> 16); + cardinfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5; + cardinfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2; + cardinfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1; + + /* Byte 10 */ + tmp = (u8)((CSD_Tab[2] & 0x0000FF00) >> 8); + cardinfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7; + cardinfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6; + cardinfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1; + + /* Byte 11 */ + tmp = (u8)(CSD_Tab[2] & 0x000000FF); + cardinfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7; + cardinfo->SD_csd.WrProtectGrSize = (tmp & 0x7F); + + /* Byte 12 */ + tmp = (u8)((CSD_Tab[3] & 0xFF000000) >> 24); + cardinfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7; + cardinfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5; + cardinfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2; + cardinfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2; + + /* Byte 13 */ + tmp = (u8)((CSD_Tab[3] & 0x00FF0000) >> 16); + cardinfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6; + cardinfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5; + cardinfo->SD_csd.Reserved3 = 0; + cardinfo->SD_csd.ContentProtectAppli = (tmp & 0x01); + + /* Byte 14 */ + tmp = (u8)((CSD_Tab[3] & 0x0000FF00) >> 8); + cardinfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7; + cardinfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6; + cardinfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5; + cardinfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4; + cardinfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2; + cardinfo->SD_csd.ECC = (tmp & 0x03); + + /* Byte 15 */ + tmp = (u8)(CSD_Tab[3] & 0x000000FF); + cardinfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1; + cardinfo->SD_csd.Reserved4 = 1; + + + /* Byte 0 */ + tmp = (u8)((CID_Tab[0] & 0xFF000000) >> 24); + cardinfo->SD_cid.ManufacturerID = tmp; + + /* Byte 1 */ + tmp = (u8)((CID_Tab[0] & 0x00FF0000) >> 16); + cardinfo->SD_cid.OEM_AppliID = tmp << 8; + + /* Byte 2 */ + tmp = (u8)((CID_Tab[0] & 0x000000FF00) >> 8); + cardinfo->SD_cid.OEM_AppliID |= tmp; + + /* Byte 3 */ + tmp = (u8)(CID_Tab[0] & 0x000000FF); + cardinfo->SD_cid.ProdName1 = tmp << 24; + + /* Byte 4 */ + tmp = (u8)((CID_Tab[1] & 0xFF000000) >> 24); + cardinfo->SD_cid.ProdName1 |= tmp << 16; + + /* Byte 5 */ + tmp = (u8)((CID_Tab[1] & 0x00FF0000) >> 16); + cardinfo->SD_cid.ProdName1 |= tmp << 8; + + /* Byte 6 */ + tmp = (u8)((CID_Tab[1] & 0x0000FF00) >> 8); + cardinfo->SD_cid.ProdName1 |= tmp; + + /* Byte 7 */ + tmp = (u8)(CID_Tab[1] & 0x000000FF); + cardinfo->SD_cid.ProdName2 = tmp; + + /* Byte 8 */ + tmp = (u8)((CID_Tab[2] & 0xFF000000) >> 24); + cardinfo->SD_cid.ProdRev = tmp; + + /* Byte 9 */ + tmp = (u8)((CID_Tab[2] & 0x00FF0000) >> 16); + cardinfo->SD_cid.ProdSN = tmp << 24; + + /* Byte 10 */ + tmp = (u8)((CID_Tab[2] & 0x0000FF00) >> 8); + cardinfo->SD_cid.ProdSN |= tmp << 16; + + /* Byte 11 */ + tmp = (u8)(CID_Tab[2] & 0x000000FF); + cardinfo->SD_cid.ProdSN |= tmp << 8; + + /* Byte 12 */ + tmp = (u8)((CID_Tab[3] & 0xFF000000) >> 24); + cardinfo->SD_cid.ProdSN |= tmp; + + /* Byte 13 */ + tmp = (u8)((CID_Tab[3] & 0x00FF0000) >> 16); + cardinfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4; + cardinfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8; + + /* Byte 14 */ + tmp = (u8)((CID_Tab[3] & 0x0000FF00) >> 8); + cardinfo->SD_cid.ManufactDate |= tmp; + + /* Byte 15 */ + tmp = (u8)(CID_Tab[3] & 0x000000FF); + cardinfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1; + cardinfo->SD_cid.Reserved2 = 1; + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_EnableWideBusOperation +* Description : Enables wide bus opeartion for the requeseted card if +* supported by card. +* Input : WideMode: Specifies the SD card wide bus mode. +* This parameter can be one of the following values: +* - SDIO_BusWide_8b: 8-bit data transfer (Only for MMC) +* - SDIO_BusWide_4b: 4-bit data transfer +* - SDIO_BusWide_1b: 1-bit data transfer +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_EnableWideBusOperation(u32 WideMode) +{ + SD_Error errorstatus = SD_OK; + + /* MMC Card doesn't support this feature */ + if (SDIO_MULTIMEDIA_CARD == CardType) + { + errorstatus = SD_UNSUPPORTED_FEATURE; + return(errorstatus); + } + else if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) + { + if (SDIO_BusWide_8b == WideMode) + { + errorstatus = SD_UNSUPPORTED_FEATURE; + return(errorstatus); + } + else if (SDIO_BusWide_4b == WideMode) + { + errorstatus = SDEnWideBus(ENABLE); + + if (SD_OK == errorstatus) + { + /* Configure the SDIO peripheral */ + SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; + SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_4b; + SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; + SDIO_Init(&SDIO_InitStructure); + } + } + else + { + errorstatus = SDEnWideBus(DISABLE); + + if (SD_OK == errorstatus) + { + /* Configure the SDIO peripheral */ + SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; + SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; + SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; + SDIO_Init(&SDIO_InitStructure); + } + } + } + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_SetDeviceMode +* Description : Sets device mode whether to operate in Polling, Interrupt or +* DMA mode. +* Input : Mode: Specifies the Data Transfer mode. +* This parameter can be one of the following values: +* - SD_DMA_MODE: Data transfer using DMA. +* - SD_INTERRUPT_MODE: Data transfer using interrupts. +* - SD_POLLING_MODE: Data transfer using flags. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_SetDeviceMode(u32 Mode) +{ + SD_Error errorstatus = SD_OK; + + if ((Mode == SD_DMA_MODE) || (Mode == SD_INTERRUPT_MODE) || (Mode == SD_POLLING_MODE)) + { + DeviceMode = Mode; + } + else + { + errorstatus = SD_INVALID_PARAMETER; + } + return(errorstatus); + +} + +/******************************************************************************* +* Function Name : SD_SelectDeselect +* Description : Selects od Deselects the corresponding card. +* Input : addr: Address of the Card to be selected. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_SelectDeselect(u32 addr) +{ + SD_Error errorstatus = SD_OK; + + /* Send CMD7 SDIO_SEL_DESEL_CARD */ + SDIO_CmdInitStructure.SDIO_Argument = addr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEL_DESEL_CARD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SEL_DESEL_CARD); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_ReadBlock +* Description : Allows to read one block from a specified address in a card. +* Input : - addr: Address from where data are to be read. +* - readbuff: pointer to the buffer that will contain the +* received data +* - blocksize: the SD card Data block size. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_ReadBlock(u32 addr, u32 *readbuff, u16 BlockSize) +{ + SD_Error errorstatus = SD_OK; + u32 count = 0, *tempbuff = readbuff; + u8 power = 0; + + if (NULL == readbuff) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + TransferError = SD_OK; + TransferEnd = 0; + TotalNumberOfBytes = 0; + + /* Clear all DPSM configuration */ + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 0; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable; + SDIO_DataConfig(&SDIO_DataInitStructure); + SDIO_DMACmd(DISABLE); + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0)) + { + power = convert_from_bytes_to_power_of_two(BlockSize); + + /* Set Block Size for Card */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN); + + if (SD_OK != errorstatus) + { + return(errorstatus); + } + } + else + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = BlockSize; + SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; + SDIO_DataConfig(&SDIO_DataInitStructure); + + TotalNumberOfBytes = BlockSize; + StopCondition = 0; + DestBuffer = readbuff; + + /* Send CMD17 READ_SINGLE_BLOCK */ + SDIO_CmdInitStructure.SDIO_Argument = (u32)addr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_READ_SINGLE_BLOCK; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_READ_SINGLE_BLOCK); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + /* In case of single block transfer, no need of stop transfer at all.*/ + if (DeviceMode == SD_POLLING_MODE) + { + /* Polling mode */ + while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))) + { + if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET) + { + for (count = 0; count < 8; count++) + { + *(tempbuff + count) = SDIO_ReadData(); + } + tempbuff += 8; + } + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); + errorstatus = SD_DATA_TIMEOUT; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); + errorstatus = SD_DATA_CRC_FAIL; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_RXOVERR); + errorstatus = SD_RX_OVERRUN; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_STBITERR); + errorstatus = SD_START_BIT_ERR; + return(errorstatus); + } + while (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) + { + *tempbuff = SDIO_ReadData(); + tempbuff++; + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + } + else if (DeviceMode == SD_INTERRUPT_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_RXFIFOHF | SDIO_IT_STBITERR, ENABLE); + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + else if (DeviceMode == SD_DMA_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE); + SDIO_DMACmd(ENABLE); + DMA_RxConfiguration(readbuff, BlockSize); + while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET) + {} + } + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_ReadMultiBlocks +* Description : Allows to read blocks from a specified address in a card. +* Input : - addr: Address from where data are to be read. +* - readbuff: pointer to the buffer that will contain the +* received data. +* - BlockSize: the SD card Data block size. +* - NumberOfBlocks: number of blocks to be read. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_ReadMultiBlocks(u32 addr, u32 *readbuff, u16 BlockSize, u32 NumberOfBlocks) +{ + SD_Error errorstatus = SD_OK; + u32 count = 0, *tempbuff = readbuff; + u8 power = 0; + + if (NULL == readbuff) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + TransferError = SD_OK; + TransferEnd = 0; + TotalNumberOfBytes = 0; + + /* Clear all DPSM configuration */ + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 0; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable; + SDIO_DataConfig(&SDIO_DataInitStructure); + SDIO_DMACmd(DISABLE); + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + if ((BlockSize > 0) && (BlockSize <= 2048) && (0 == (BlockSize & (BlockSize - 1)))) + { + power = convert_from_bytes_to_power_of_two(BlockSize); + + /* Set Block Size for Card */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN); + + if (SD_OK != errorstatus) + { + return(errorstatus); + } + } + else + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + if (NumberOfBlocks > 1) + { + /* Common to all modes */ + if (NumberOfBlocks * BlockSize > SD_MAX_DATA_LENGTH) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + TotalNumberOfBytes = NumberOfBlocks * BlockSize; + StopCondition = 1; + DestBuffer = readbuff; + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize; + SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; + SDIO_DataConfig(&SDIO_DataInitStructure); + + /* Send CMD18 READ_MULT_BLOCK with argument data address */ + SDIO_CmdInitStructure.SDIO_Argument = (u32)addr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_READ_MULT_BLOCK; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_READ_MULT_BLOCK); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + if (DeviceMode == SD_POLLING_MODE) + { + /* Polling mode */ + while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DATAEND | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR))) + { + if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET) + { + for (count = 0; count < SD_HALFFIFO; count++) + { + *(tempbuff + count) = SDIO_ReadData(); + } + tempbuff += SD_HALFFIFO; + } + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); + errorstatus = SD_DATA_TIMEOUT; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); + errorstatus = SD_DATA_CRC_FAIL; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_RXOVERR); + errorstatus = SD_RX_OVERRUN; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_STBITERR); + errorstatus = SD_START_BIT_ERR; + return(errorstatus); + } + while (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) + { + *tempbuff = SDIO_ReadData(); + tempbuff++; + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET) + { + /* In Case Of SD-CARD Send Command STOP_TRANSMISSION */ + if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) + { + /* Send CMD12 STOP_TRANSMISSION */ + SDIO_CmdInitStructure.SDIO_Argument = 0x0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_STOP_TRANSMISSION; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_STOP_TRANSMISSION); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + } + } + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + } + else if (DeviceMode == SD_INTERRUPT_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_RXFIFOHF | SDIO_IT_STBITERR, ENABLE); + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + else if (DeviceMode == SD_DMA_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE); + SDIO_DMACmd(ENABLE); + DMA_RxConfiguration(readbuff, (NumberOfBlocks * BlockSize)); + while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET) + {} + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + } + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_WriteBlock +* Description : Allows to write one block starting from a specified address +* in a card. +* Input : - addr: Address from where data are to be read. +* - writebuff: pointer to the buffer that contain the data to be +* transferred. +* - BlockSize: the SD card Data block size. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_WriteBlock(u32 addr, u32 *writebuff, u16 BlockSize) +{ + SD_Error errorstatus = SD_OK; + u8 power = 0, cardstate = 0; + u32 timeout = 0, bytestransferred = 0; + u32 cardstatus = 0, count = 0, restwords = 0; + u32 *tempbuff = writebuff; + + if (writebuff == NULL) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + TransferError = SD_OK; + TransferEnd = 0; + TotalNumberOfBytes = 0; + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 0; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable; + SDIO_DataConfig(&SDIO_DataInitStructure); + SDIO_DMACmd(DISABLE); + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + /* Set the block size, both on controller and card */ + if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0)) + { + power = convert_from_bytes_to_power_of_two(BlockSize); + + SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + } + else + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + /* Wait till card is ready for data Added */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16); + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SEND_STATUS); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + cardstatus = SDIO_GetResponse(SDIO_RESP1); + + timeout = SD_DATATIMEOUT; + + while (((cardstatus & 0x00000100) == 0) && (timeout > 0)) + { + timeout--; + SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16); + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SEND_STATUS); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + cardstatus = SDIO_GetResponse(SDIO_RESP1); + } + + if (timeout == 0) + { + return(SD_ERROR); + } + + /* Send CMD24 WRITE_SINGLE_BLOCK */ + SDIO_CmdInitStructure.SDIO_Argument = addr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_WRITE_SINGLE_BLOCK; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_WRITE_SINGLE_BLOCK); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + TotalNumberOfBytes = BlockSize; + StopCondition = 0; + SrcBuffer = writebuff; + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = BlockSize; + SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; + SDIO_DataConfig(&SDIO_DataInitStructure); + + /* In case of single data block transfer no need of stop command at all */ + if (DeviceMode == SD_POLLING_MODE) + { + while (!(SDIO->STA & (SDIO_FLAG_DBCKEND | SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR))) + { + if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET) + { + if ((TotalNumberOfBytes - bytestransferred) < 32) + { + restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) : (( TotalNumberOfBytes - bytestransferred) / 4 + 1); + + for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4) + { + SDIO_WriteData(*tempbuff); + } + } + else + { + for (count = 0; count < 8; count++) + { + SDIO_WriteData(*(tempbuff + count)); + } + tempbuff += 8; + bytestransferred += 32; + } + } + } + if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); + errorstatus = SD_DATA_TIMEOUT; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); + errorstatus = SD_DATA_CRC_FAIL; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_TXUNDERR); + errorstatus = SD_TX_UNDERRUN; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_STBITERR); + errorstatus = SD_START_BIT_ERR; + return(errorstatus); + } + } + else if (DeviceMode == SD_INTERRUPT_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE); + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + else if (DeviceMode == SD_DMA_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE); + DMA_TxConfiguration(writebuff, BlockSize); + SDIO_DMACmd(ENABLE); + while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET) + {} + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + /* Wait till the card is in programming state */ + errorstatus = IsCardProgramming(&cardstate); + + while ((errorstatus == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))) + { + errorstatus = IsCardProgramming(&cardstate); + } + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_WriteMultiBlocks +* Description : Allows to write blocks starting from a specified address in +* a card. +* Input : - addr: Address from where data are to be read. +* - writebuff: pointer to the buffer that contain the data to be +* transferred. +* - BlockSize: the SD card Data block size. +* - NumberOfBlocks: number of blocks to be written. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_WriteMultiBlocks(u32 addr, u32 *writebuff, u16 BlockSize, u32 NumberOfBlocks) +{ + SD_Error errorstatus = SD_OK; + u8 power = 0, cardstate = 0; + u32 bytestransferred = 0; + u32 count = 0, restwords = 0; + u32 *tempbuff = writebuff; + + if (writebuff == NULL) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + TransferError = SD_OK; + TransferEnd = 0; + TotalNumberOfBytes = 0; + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 0; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable; + SDIO_DataConfig(&SDIO_DataInitStructure); + SDIO_DMACmd(DISABLE); + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + /* Set the block size, both on controller and card */ + if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0)) + { + power = convert_from_bytes_to_power_of_two(BlockSize); + + SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + } + else + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + /* Wait till card is ready for data Added */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16); + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SEND_STATUS); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + if (NumberOfBlocks > 1) + { + /* Common to all modes */ + if (NumberOfBlocks * BlockSize > SD_MAX_DATA_LENGTH) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) + { + /* To improve performance */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16); + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + /* To improve performance */ + SDIO_CmdInitStructure.SDIO_Argument = (u32)NumberOfBlocks; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCK_COUNT; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCK_COUNT); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + } + + /* Send CMD25 WRITE_MULT_BLOCK with argument data address */ + SDIO_CmdInitStructure.SDIO_Argument = (u32)addr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_WRITE_MULT_BLOCK; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_WRITE_MULT_BLOCK); + + if (SD_OK != errorstatus) + { + return(errorstatus); + } + + TotalNumberOfBytes = NumberOfBlocks * BlockSize; + StopCondition = 1; + SrcBuffer = writebuff; + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize; + SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; + SDIO_DataConfig(&SDIO_DataInitStructure); + + if (DeviceMode == SD_POLLING_MODE) + { + while (!(SDIO->STA & (SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DATAEND | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR))) + { + if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET) + { + if (!((TotalNumberOfBytes - bytestransferred) < SD_HALFFIFOBYTES)) + { + for (count = 0; count < SD_HALFFIFO; count++) + { + SDIO_WriteData(*(tempbuff + count)); + } + tempbuff += SD_HALFFIFO; + bytestransferred += SD_HALFFIFOBYTES; + } + else + { + restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) : + ((TotalNumberOfBytes - bytestransferred) / 4 + 1); + + for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4) + { + SDIO_WriteData(*tempbuff); + } + } + } + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); + errorstatus = SD_DATA_TIMEOUT; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); + errorstatus = SD_DATA_CRC_FAIL; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_TXUNDERR); + errorstatus = SD_TX_UNDERRUN; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_STBITERR); + errorstatus = SD_START_BIT_ERR; + return(errorstatus); + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET) + { + if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) + { + /* Send CMD12 STOP_TRANSMISSION */ + SDIO_CmdInitStructure.SDIO_Argument = 0x0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_STOP_TRANSMISSION; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + + errorstatus = CmdResp1Error(SDIO_STOP_TRANSMISSION); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + } + } + } + else if (DeviceMode == SD_INTERRUPT_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXFIFOHE | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE); + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + else if (DeviceMode == SD_DMA_MODE) + { + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE); + SDIO_DMACmd(ENABLE); + DMA_TxConfiguration(writebuff, (NumberOfBlocks * BlockSize)); + while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET) + {} + while ((TransferEnd == 0) && (TransferError == SD_OK)) + {} + if (TransferError != SD_OK) + { + return(TransferError); + } + } + } + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + /* Wait till the card is in programming state */ + errorstatus = IsCardProgramming(&cardstate); + + while ((errorstatus == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))) + { + errorstatus = IsCardProgramming(&cardstate); + } + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_GetTransferState +* Description : Gets the cuurent data transfer state. +* Input : None +* Output : None +* Return : SDTransferState: Data Transfer state. +* This value can be: +* - SD_NO_TRANSFER: No data transfer is acting +* - SD_TRANSFER_IN_PROGRESS: Data transfer is acting +*******************************************************************************/ +SDTransferState SD_GetTransferState(void) +{ + if (SDIO->STA & (SDIO_FLAG_TXACT | SDIO_FLAG_RXACT)) + { + return(SD_TRANSFER_IN_PROGRESS); + } + else + { + return(SD_NO_TRANSFER); + } +} + +/******************************************************************************* +* Function Name : SD_StopTransfer +* Description : Aborts an ongoing data transfer. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_StopTransfer(void) +{ + SD_Error errorstatus = SD_OK; + + /* Send CMD12 STOP_TRANSMISSION */ + SDIO_CmdInitStructure.SDIO_Argument = 0x0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_STOP_TRANSMISSION; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_STOP_TRANSMISSION); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_Erase +* Description : Allows to erase memory area specified for the given card. +* Input : - startaddr: the start address. +* - endaddr: the end address. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_Erase(u32 startaddr, u32 endaddr) +{ + SD_Error errorstatus = SD_OK; + u32 delay = 0; + vu32 maxdelay = 0; + u8 cardstate = 0; + + /* Check if the card coomnd class supports erase command */ + if (((CSD_Tab[1] >> 20) & SD_CCCC_ERASE) == 0) + { + errorstatus = SD_REQUEST_NOT_APPLICABLE; + return(errorstatus); + } + + maxdelay = 72000 / ((SDIO->CLKCR & 0xFF) + 2); + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */ + if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)) + { + /* Send CMD32 SD_ERASE_GRP_START with argument as addr */ + SDIO_CmdInitStructure.SDIO_Argument = startaddr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_ERASE_GRP_START; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SD_ERASE_GRP_START); + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + /* Send CMD33 SD_ERASE_GRP_END with argument as addr */ + SDIO_CmdInitStructure.SDIO_Argument = endaddr; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_ERASE_GRP_END; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SD_ERASE_GRP_END); + if (errorstatus != SD_OK) + { + return(errorstatus); + } + } + + /* Send CMD38 ERASE */ + SDIO_CmdInitStructure.SDIO_Argument = 0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_ERASE; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_ERASE); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + for (delay = 0; delay < maxdelay; delay++) + {} + + /* Wait till the card is in programming state */ + errorstatus = IsCardProgramming(&cardstate); + + while ((errorstatus == SD_OK) && ((SD_CARD_PROGRAMMING == cardstate) || (SD_CARD_RECEIVING == cardstate))) + { + errorstatus = IsCardProgramming(&cardstate); + } + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_SendStatus +* Description : Returns the current card's status. +* Input : pcardstatus: pointer to the buffer that will contain the SD +* card status (Card Status register). +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_SendStatus(u32 *pcardstatus) +{ + SD_Error errorstatus = SD_OK; + + if (pcardstatus == NULL) + { + errorstatus = SD_INVALID_PARAMETER; + return(errorstatus); + } + + SDIO_CmdInitStructure.SDIO_Argument = (u32) RCA << 16; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + + errorstatus = CmdResp1Error(SDIO_SEND_STATUS); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + *pcardstatus = SDIO_GetResponse(SDIO_RESP1); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_SendSDStatus +* Description : Returns the current SD card's status. +* Input : psdstatus: pointer to the buffer that will contain the SD +* card status (SD Status register). +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_SendSDStatus(u32 *psdstatus) +{ + SD_Error errorstatus = SD_OK; + u32 count = 0; + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + /* Set block size for card if it is not equal to current block size for card. */ + SDIO_CmdInitStructure.SDIO_Argument = 64; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + /* CMD55 */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) RCA << 16; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 64; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_64b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; + SDIO_DataConfig(&SDIO_DataInitStructure); + + + /* Send ACMD13 SD_APP_STAUS with argument as card's RCA.*/ + SDIO_CmdInitStructure.SDIO_Argument = 0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_APP_STAUS; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + errorstatus = CmdResp1Error(SDIO_SD_APP_STAUS); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))) + { + if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET) + { + for (count = 0; count < 8; count++) + { + *(psdstatus + count) = SDIO_ReadData(); + } + psdstatus += 8; + } + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); + errorstatus = SD_DATA_TIMEOUT; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); + errorstatus = SD_DATA_CRC_FAIL; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_RXOVERR); + errorstatus = SD_RX_OVERRUN; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_STBITERR); + errorstatus = SD_START_BIT_ERR; + return(errorstatus); + } + + while (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) + { + *psdstatus = SDIO_ReadData(); + psdstatus++; + } + + /* Clear all the static status flags*/ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + psdstatus -= 16; + for (count = 0; count < 16; count++) + { + psdstatus[count] = ((psdstatus[count] & SD_0TO7BITS) << 24) |((psdstatus[count] & SD_8TO15BITS) << 8) | + ((psdstatus[count] & SD_16TO23BITS) >> 8) |((psdstatus[count] & SD_24TO31BITS) >> 24); + } + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SD_ProcessIRQSrc +* Description : Allows to process all the interrupts that are high. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +SD_Error SD_ProcessIRQSrc(void) +{ + u32 count = 0, restwords = 0; + + if (DeviceMode == SD_INTERRUPT_MODE) + { + if (SDIO_GetITStatus(SDIO_IT_RXFIFOHF) != RESET) + { + for (count = 0; count < SD_HALFFIFO; count++) + { + *(DestBuffer + count) = SDIO_ReadData(); + } + DestBuffer += SD_HALFFIFO; + NumberOfBytes += SD_HALFFIFOBYTES; + } + else if (SDIO_GetITStatus(SDIO_IT_TXFIFOHE) != RESET) + { + if ((TotalNumberOfBytes - NumberOfBytes) < SD_HALFFIFOBYTES) + { + restwords = ((TotalNumberOfBytes - NumberOfBytes) % 4 == 0) ? + ((TotalNumberOfBytes - NumberOfBytes) / 4) : + ((TotalNumberOfBytes - NumberOfBytes) / 4 + 1); + + for (count = 0; count < restwords; count++, SrcBuffer++, NumberOfBytes += 4) + { + SDIO_WriteData(*SrcBuffer); + } + } + else + { + for (count = 0; count < SD_HALFFIFO; count++) + { + SDIO_WriteData(*(SrcBuffer + count)); + } + + SrcBuffer += SD_HALFFIFO; + NumberOfBytes += SD_HALFFIFOBYTES; + } + } + } + + if (SDIO_GetITStatus(SDIO_IT_DATAEND) != RESET) + { + if (DeviceMode != SD_DMA_MODE) + { + while ((SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) && (NumberOfBytes < TotalNumberOfBytes)) + { + *DestBuffer = SDIO_ReadData(); + DestBuffer++; + NumberOfBytes += 4; + } + } + + if (StopCondition == 1) + { + TransferError = SD_StopTransfer(); + } + else + { + TransferError = SD_OK; + } + SDIO_ClearITPendingBit(SDIO_IT_DATAEND); + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR | + SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE); + TransferEnd = 1; + NumberOfBytes = 0; + return(TransferError); + } + + if (SDIO_GetITStatus(SDIO_IT_DCRCFAIL) != RESET) + { + SDIO_ClearITPendingBit(SDIO_IT_DCRCFAIL); + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR | + SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE); + NumberOfBytes = 0; + TransferError = SD_DATA_CRC_FAIL; + return(SD_DATA_CRC_FAIL); + } + + if (SDIO_GetITStatus(SDIO_IT_DTIMEOUT) != RESET) + { + SDIO_ClearITPendingBit(SDIO_IT_DTIMEOUT); + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR | + SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE); + NumberOfBytes = 0; + TransferError = SD_DATA_TIMEOUT; + return(SD_DATA_TIMEOUT); + } + + if (SDIO_GetITStatus(SDIO_IT_RXOVERR) != RESET) + { + SDIO_ClearITPendingBit(SDIO_IT_RXOVERR); + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR | + SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE); + NumberOfBytes = 0; + TransferError = SD_RX_OVERRUN; + return(SD_RX_OVERRUN); + } + + if (SDIO_GetITStatus(SDIO_IT_TXUNDERR) != RESET) + { + SDIO_ClearITPendingBit(SDIO_IT_TXUNDERR); + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR | + SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE); + NumberOfBytes = 0; + TransferError = SD_TX_UNDERRUN; + return(SD_TX_UNDERRUN); + } + + if (SDIO_GetITStatus(SDIO_IT_STBITERR) != RESET) + { + SDIO_ClearITPendingBit(SDIO_IT_STBITERR); + SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR | + SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE); + NumberOfBytes = 0; + TransferError = SD_START_BIT_ERR; + return(SD_START_BIT_ERR); + } + + return(SD_OK); +} + +/******************************************************************************* +* Function Name : CmdError +* Description : Checks for error conditions for CMD0. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error CmdError(void) +{ + SD_Error errorstatus = SD_OK; + u32 timeout; + + timeout = SDIO_CMD0TIMEOUT; /* 10000 */ + + while ((timeout > 0) && (SDIO_GetFlagStatus(SDIO_FLAG_CMDSENT) == RESET)) + { + timeout--; + } + + if (timeout == 0) + { + errorstatus = SD_CMD_RSP_TIMEOUT; + return(errorstatus); + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : CmdResp7Error +* Description : Checks for error conditions for R7. +* response. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error CmdResp7Error(void) +{ + SD_Error errorstatus = SD_OK; + u32 status; + u32 timeout = SDIO_CMD0TIMEOUT; + + status = SDIO->STA; + + while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) && (timeout > 0)) + { + timeout--; + status = SDIO->STA; + } + + if ((timeout == 0) || (status & SDIO_FLAG_CTIMEOUT)) + { + /* Card is not V2.0 complient or card does not support the set voltage range */ + errorstatus = SD_CMD_RSP_TIMEOUT; + SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT); + return(errorstatus); + } + + if (status & SDIO_FLAG_CMDREND) + { + /* Card is SD V2.0 compliant */ + errorstatus = SD_OK; + return(errorstatus); + } + return(errorstatus); +} + +/******************************************************************************* +* Function Name : CmdResp1Error +* Description : Checks for error conditions for R1. +* response +* Input : cmd: The sent command index. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error CmdResp1Error(u8 cmd) +{ + SD_Error errorstatus = SD_OK; + u32 status; + u32 response_r1; + + status = SDIO->STA; + + while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))) + { + status = SDIO->STA; + } + + if (status & SDIO_FLAG_CTIMEOUT) + { + errorstatus = SD_CMD_RSP_TIMEOUT; + SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT); + return(errorstatus); + } + else if (status & SDIO_FLAG_CCRCFAIL) + { + errorstatus = SD_CMD_CRC_FAIL; + SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL); + return(errorstatus); + } + + /* Check response received is of desired command */ + if (SDIO_GetCommandResponse() != cmd) + { + errorstatus = SD_ILLEGAL_CMD; + return(errorstatus); + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + /* We have received response, retrieve it for analysis */ + response_r1 = SDIO_GetResponse(SDIO_RESP1); + + if ((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO) + { + return(errorstatus); + } + + if (response_r1 & SD_OCR_ADDR_OUT_OF_RANGE) + { + return(SD_ADDR_OUT_OF_RANGE); + } + + if (response_r1 & SD_OCR_ADDR_MISALIGNED) + { + return(SD_ADDR_MISALIGNED); + } + + if (response_r1 & SD_OCR_BLOCK_LEN_ERR) + { + return(SD_BLOCK_LEN_ERR); + } + + if (response_r1 & SD_OCR_ERASE_SEQ_ERR) + { + return(SD_ERASE_SEQ_ERR); + } + + if (response_r1 & SD_OCR_BAD_ERASE_PARAM) + { + return(SD_BAD_ERASE_PARAM); + } + + if (response_r1 & SD_OCR_WRITE_PROT_VIOLATION) + { + return(SD_WRITE_PROT_VIOLATION); + } + + if (response_r1 & SD_OCR_LOCK_UNLOCK_FAILED) + { + return(SD_LOCK_UNLOCK_FAILED); + } + + if (response_r1 & SD_OCR_COM_CRC_FAILED) + { + return(SD_COM_CRC_FAILED); + } + + if (response_r1 & SD_OCR_ILLEGAL_CMD) + { + return(SD_ILLEGAL_CMD); + } + + if (response_r1 & SD_OCR_CARD_ECC_FAILED) + { + return(SD_CARD_ECC_FAILED); + } + + if (response_r1 & SD_OCR_CC_ERROR) + { + return(SD_CC_ERROR); + } + + if (response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR) + { + return(SD_GENERAL_UNKNOWN_ERROR); + } + + if (response_r1 & SD_OCR_STREAM_READ_UNDERRUN) + { + return(SD_STREAM_READ_UNDERRUN); + } + + if (response_r1 & SD_OCR_STREAM_WRITE_OVERRUN) + { + return(SD_STREAM_WRITE_OVERRUN); + } + + if (response_r1 & SD_OCR_CID_CSD_OVERWRIETE) + { + return(SD_CID_CSD_OVERWRITE); + } + + if (response_r1 & SD_OCR_WP_ERASE_SKIP) + { + return(SD_WP_ERASE_SKIP); + } + + if (response_r1 & SD_OCR_CARD_ECC_DISABLED) + { + return(SD_CARD_ECC_DISABLED); + } + + if (response_r1 & SD_OCR_ERASE_RESET) + { + return(SD_ERASE_RESET); + } + + if (response_r1 & SD_OCR_AKE_SEQ_ERROR) + { + return(SD_AKE_SEQ_ERROR); + } + return(errorstatus); +} + +/******************************************************************************* +* Function Name : CmdResp3Error +* Description : Checks for error conditions for R3 (OCR). +* response. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error CmdResp3Error(void) +{ + SD_Error errorstatus = SD_OK; + u32 status; + + status = SDIO->STA; + + while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))) + { + status = SDIO->STA; + } + + if (status & SDIO_FLAG_CTIMEOUT) + { + errorstatus = SD_CMD_RSP_TIMEOUT; + SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT); + return(errorstatus); + } + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + return(errorstatus); +} + +/******************************************************************************* +* Function Name : CmdResp2Error +* Description : Checks for error conditions for R2 (CID or CSD). +* response. +* Input : None +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error CmdResp2Error(void) +{ + SD_Error errorstatus = SD_OK; + u32 status; + + status = SDIO->STA; + + while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CTIMEOUT | SDIO_FLAG_CMDREND))) + { + status = SDIO->STA; + } + + if (status & SDIO_FLAG_CTIMEOUT) + { + errorstatus = SD_CMD_RSP_TIMEOUT; + SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT); + return(errorstatus); + } + else if (status & SDIO_FLAG_CCRCFAIL) + { + errorstatus = SD_CMD_CRC_FAIL; + SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL); + return(errorstatus); + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : CmdResp6Error +* Description : Checks for error conditions for R6 (RCA). +* response. +* Input : - cmd: The sent command index. +* - prca: pointer to the variable that will contain the SD +* card relative address RCA. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error CmdResp6Error(u8 cmd, u16 *prca) +{ + SD_Error errorstatus = SD_OK; + u32 status; + u32 response_r1; + + status = SDIO->STA; + + while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CTIMEOUT | SDIO_FLAG_CMDREND))) + { + status = SDIO->STA; + } + + if (status & SDIO_FLAG_CTIMEOUT) + { + errorstatus = SD_CMD_RSP_TIMEOUT; + SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT); + return(errorstatus); + } + else if (status & SDIO_FLAG_CCRCFAIL) + { + errorstatus = SD_CMD_CRC_FAIL; + SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL); + return(errorstatus); + } + + /* Check response received is of desired command */ + if (SDIO_GetCommandResponse() != cmd) + { + errorstatus = SD_ILLEGAL_CMD; + return(errorstatus); + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + /* We have received response, retrieve it. */ + response_r1 = SDIO_GetResponse(SDIO_RESP1); + + if (SD_ALLZERO == (response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED))) + { + *prca = (u16) (response_r1 >> 16); + return(errorstatus); + } + + if (response_r1 & SD_R6_GENERAL_UNKNOWN_ERROR) + { + return(SD_GENERAL_UNKNOWN_ERROR); + } + + if (response_r1 & SD_R6_ILLEGAL_CMD) + { + return(SD_ILLEGAL_CMD); + } + + if (response_r1 & SD_R6_COM_CRC_FAILED) + { + return(SD_COM_CRC_FAILED); + } + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : SDEnWideBus +* Description : Enables or disables the SDIO wide bus mode. +* Input : NewState: new state of the SDIO wide bus mode. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error SDEnWideBus(FunctionalState NewState) +{ + SD_Error errorstatus = SD_OK; + + u32 scr[2] = {0, 0}; + + if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) + { + errorstatus = SD_LOCK_UNLOCK_FAILED; + return(errorstatus); + } + + /* Get SCR Register */ + errorstatus = FindSCR(RCA, scr); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + /* If wide bus operation to be enabled */ + if (NewState == ENABLE) + { + /* If requested card supports wide bus operation */ + if ((scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO) + { + /* Send CMD55 APP_CMD with argument as card's RCA.*/ + SDIO_CmdInitStructure.SDIO_Argument = (u32) RCA << 16; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */ + SDIO_CmdInitStructure.SDIO_Argument = 0x2; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_SD_SET_BUSWIDTH; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_APP_SD_SET_BUSWIDTH); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + return(errorstatus); + } + else + { + errorstatus = SD_REQUEST_NOT_APPLICABLE; + return(errorstatus); + } + } /* If wide bus operation to be disabled */ + else + { + /* If requested card supports 1 bit mode operation */ + if ((scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO) + { + /* Send CMD55 APP_CMD with argument as card's RCA.*/ + SDIO_CmdInitStructure.SDIO_Argument = (u32) RCA << 16; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */ + SDIO_CmdInitStructure.SDIO_Argument = 0x00; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_SD_SET_BUSWIDTH; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_APP_SD_SET_BUSWIDTH); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + return(errorstatus); + } + else + { + errorstatus = SD_REQUEST_NOT_APPLICABLE; + return(errorstatus); + } + } +} + +/******************************************************************************* +* Function Name : IsCardProgramming +* Description : Checks if the SD card is in programming state. +* Input : pstatus: pointer to the variable that will contain the SD +* card state. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error IsCardProgramming(u8 *pstatus) +{ + SD_Error errorstatus = SD_OK; + vu32 respR1 = 0, status = 0; + + SDIO_CmdInitStructure.SDIO_Argument = (u32) RCA << 16; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + status = SDIO->STA; + while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))) + { + status = SDIO->STA; + } + + if (status & SDIO_FLAG_CTIMEOUT) + { + errorstatus = SD_CMD_RSP_TIMEOUT; + SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT); + return(errorstatus); + } + else if (status & SDIO_FLAG_CCRCFAIL) + { + errorstatus = SD_CMD_CRC_FAIL; + SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL); + return(errorstatus); + } + + status = (u32)SDIO_GetCommandResponse(); + + /* Check response received is of desired command */ + if (status != SDIO_SEND_STATUS) + { + errorstatus = SD_ILLEGAL_CMD; + return(errorstatus); + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + + /* We have received response, retrieve it for analysis */ + respR1 = SDIO_GetResponse(SDIO_RESP1); + + /* Find out card status */ + *pstatus = (u8) ((respR1 >> 9) & 0x0000000F); + + if ((respR1 & SD_OCR_ERRORBITS) == SD_ALLZERO) + { + return(errorstatus); + } + + if (respR1 & SD_OCR_ADDR_OUT_OF_RANGE) + { + return(SD_ADDR_OUT_OF_RANGE); + } + + if (respR1 & SD_OCR_ADDR_MISALIGNED) + { + return(SD_ADDR_MISALIGNED); + } + + if (respR1 & SD_OCR_BLOCK_LEN_ERR) + { + return(SD_BLOCK_LEN_ERR); + } + + if (respR1 & SD_OCR_ERASE_SEQ_ERR) + { + return(SD_ERASE_SEQ_ERR); + } + + if (respR1 & SD_OCR_BAD_ERASE_PARAM) + { + return(SD_BAD_ERASE_PARAM); + } + + if (respR1 & SD_OCR_WRITE_PROT_VIOLATION) + { + return(SD_WRITE_PROT_VIOLATION); + } + + if (respR1 & SD_OCR_LOCK_UNLOCK_FAILED) + { + return(SD_LOCK_UNLOCK_FAILED); + } + + if (respR1 & SD_OCR_COM_CRC_FAILED) + { + return(SD_COM_CRC_FAILED); + } + + if (respR1 & SD_OCR_ILLEGAL_CMD) + { + return(SD_ILLEGAL_CMD); + } + + if (respR1 & SD_OCR_CARD_ECC_FAILED) + { + return(SD_CARD_ECC_FAILED); + } + + if (respR1 & SD_OCR_CC_ERROR) + { + return(SD_CC_ERROR); + } + + if (respR1 & SD_OCR_GENERAL_UNKNOWN_ERROR) + { + return(SD_GENERAL_UNKNOWN_ERROR); + } + + if (respR1 & SD_OCR_STREAM_READ_UNDERRUN) + { + return(SD_STREAM_READ_UNDERRUN); + } + + if (respR1 & SD_OCR_STREAM_WRITE_OVERRUN) + { + return(SD_STREAM_WRITE_OVERRUN); + } + + if (respR1 & SD_OCR_CID_CSD_OVERWRIETE) + { + return(SD_CID_CSD_OVERWRITE); + } + + if (respR1 & SD_OCR_WP_ERASE_SKIP) + { + return(SD_WP_ERASE_SKIP); + } + + if (respR1 & SD_OCR_CARD_ECC_DISABLED) + { + return(SD_CARD_ECC_DISABLED); + } + + if (respR1 & SD_OCR_ERASE_RESET) + { + return(SD_ERASE_RESET); + } + + if (respR1 & SD_OCR_AKE_SEQ_ERROR) + { + return(SD_AKE_SEQ_ERROR); + } + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : FindSCR +* Description : Find the SD card SCR register value. +* Input : - rca: selected card address. +* - pscr: pointer to the buffer that will contain the SCR value. +* Output : None +* Return : SD_Error: SD Card Error code. +*******************************************************************************/ +static SD_Error FindSCR(u16 rca, u32 *pscr) +{ + u32 index = 0; + SD_Error errorstatus = SD_OK; + u32 tempscr[2] = {0, 0}; + + /* Set Block Size To 8 Bytes */ + /* Send CMD55 APP_CMD with argument as card's RCA */ + SDIO_CmdInitStructure.SDIO_Argument = (u32)8; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + /* Send CMD55 APP_CMD with argument as card's RCA */ + SDIO_CmdInitStructure.SDIO_Argument = (u32) RCA << 16; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_APP_CMD); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; + SDIO_DataInitStructure.SDIO_DataLength = 8; + SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_8b; + SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO; + SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; + SDIO_DataConfig(&SDIO_DataInitStructure); + + + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ + SDIO_CmdInitStructure.SDIO_Argument = 0x0; + SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_APP_SEND_SCR; + SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; + SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; + SDIO_SendCommand(&SDIO_CmdInitStructure); + + errorstatus = CmdResp1Error(SDIO_SD_APP_SEND_SCR); + + if (errorstatus != SD_OK) + { + return(errorstatus); + } + + while (!(SDIO->STA & (SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))) + { + if (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) + { + *(tempscr + index) = SDIO_ReadData(); + index++; + } + } + + if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); + errorstatus = SD_DATA_TIMEOUT; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); + errorstatus = SD_DATA_CRC_FAIL; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_RXOVERR); + errorstatus = SD_RX_OVERRUN; + return(errorstatus); + } + else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) + { + SDIO_ClearFlag(SDIO_FLAG_STBITERR); + errorstatus = SD_START_BIT_ERR; + return(errorstatus); + } + + /* Clear all the static flags */ + SDIO_ClearFlag(SDIO_STATIC_FLAGS); + + *(pscr + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) | ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24); + + *(pscr) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) | ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24); + + return(errorstatus); +} + +/******************************************************************************* +* Function Name : convert_from_bytes_to_power_of_two +* Description : Converts the number of bytes in power of two and returns the +* power. +* Input : NumberOfBytes: number of bytes. +* Output : None +* Return : None +*******************************************************************************/ +static u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes) +{ + u8 count = 0; + + while (NumberOfBytes != 1) + { + NumberOfBytes >>= 1; + count++; + } + return(count); +} + +/******************************************************************************* +* Function Name : GPIO_Configuration +* Description : Configures the SDIO Corresponding GPIO Ports +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +static void GPIO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* GPIOC and GPIOD Periph clock enable */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); + + /* Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + /* Configure PD.02 CMD line */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_Init(GPIOD, &GPIO_InitStructure); +} + +/******************************************************************************* +* Function Name : DMA_TxConfiguration +* Description : Configures the DMA2 Channel4 for SDIO Tx request. +* Input : - BufferSRC: pointer to the source buffer +* - BufferSize: buffer size +* Output : None +* Return : None +*******************************************************************************/ +static void DMA_TxConfiguration(u32 *BufferSRC, u32 BufferSize) +{ + DMA_InitTypeDef DMA_InitStructure; + + DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4); + + /* DMA2 Channel4 disable */ + DMA_Cmd(DMA2_Channel4, DISABLE); + + /* DMA2 Channel4 Config */ + DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SDIO_FIFO_Address; + DMA_InitStructure.DMA_MemoryBaseAddr = (u32)BufferSRC; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_BufferSize = BufferSize / 4; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA2_Channel4, &DMA_InitStructure); + + /* DMA2 Channel4 enable */ + DMA_Cmd(DMA2_Channel4, ENABLE); +} + +/******************************************************************************* +* Function Name : DMA_RxConfiguration +* Description : Configures the DMA2 Channel4 for SDIO Rx request. +* Input : - BufferDST: pointer to the destination buffer +* - BufferSize: buffer size +* Output : None +* Return : None +*******************************************************************************/ +static void DMA_RxConfiguration(u32 *BufferDST, u32 BufferSize) +{ + DMA_InitTypeDef DMA_InitStructure; + + DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4); + + /* DMA2 Channel4 disable */ + DMA_Cmd(DMA2_Channel4, DISABLE); + + /* DMA2 Channel4 Config */ + DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SDIO_FIFO_Address; + DMA_InitStructure.DMA_MemoryBaseAddr = (u32)BufferDST; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + DMA_InitStructure.DMA_BufferSize = BufferSize / 4; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA2_Channel4, &DMA_InitStructure); + + /* DMA2 Channel4 enable */ + DMA_Cmd(DMA2_Channel4, ENABLE); +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/src/stm32lib/examples/SDIO/sdcard.h b/src/stm32lib/examples/SDIO/sdcard.h new file mode 100755 index 0000000..8289dda --- /dev/null +++ b/src/stm32lib/examples/SDIO/sdcard.h @@ -0,0 +1,252 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : sdcard.h +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : This file contains all the functions prototypes for the +* SD Card driver firmware library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SDCARD_H +#define __SDCARD_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + /* SDIO specific error defines */ + SD_CMD_CRC_FAIL = (1), /* Command response received (but CRC check failed) */ + SD_DATA_CRC_FAIL = (2), /* Data bock sent/received (CRC check Failed) */ + SD_CMD_RSP_TIMEOUT = (3), /* Command response timeout */ + SD_DATA_TIMEOUT = (4), /* Data time out */ + SD_TX_UNDERRUN = (5), /* Transmit FIFO under-run */ + SD_RX_OVERRUN = (6), /* Receive FIFO over-run */ + SD_START_BIT_ERR = (7), /* Start bit not detected on all data signals in widE bus mode */ + SD_CMD_OUT_OF_RANGE = (8), /* CMD's argument was out of range.*/ + SD_ADDR_MISALIGNED = (9), /* Misaligned address */ + SD_BLOCK_LEN_ERR = (10), /* Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */ + SD_ERASE_SEQ_ERR = (11), /* An error in the sequence of erase command occurs.*/ + SD_BAD_ERASE_PARAM = (12), /* An Invalid selection for erase groups */ + SD_WRITE_PROT_VIOLATION = (13), /* Attempt to program a write protect block */ + SD_LOCK_UNLOCK_FAILED = (14), /* Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */ + SD_COM_CRC_FAILED = (15), /* CRC check of the previous command failed */ + SD_ILLEGAL_CMD = (16), /* Command is not legal for the card state */ + SD_CARD_ECC_FAILED = (17), /* Card internal ECC was applied but failed to correct the data */ + SD_CC_ERROR = (18), /* Internal card controller error */ + SD_GENERAL_UNKNOWN_ERROR = (19), /* General or Unknown error */ + SD_STREAM_READ_UNDERRUN = (20), /* The card could not sustain data transfer in stream read operation. */ + SD_STREAM_WRITE_OVERRUN = (21), /* The card could not sustain data programming in stream mode */ + SD_CID_CSD_OVERWRITE = (22), /* CID/CSD overwrite error */ + SD_WP_ERASE_SKIP = (23), /* only partial address space was erased */ + SD_CARD_ECC_DISABLED = (24), /* Command has been executed without using internal ECC */ + SD_ERASE_RESET = (25), /* Erase sequence was cleared before executing because an out of erase sequence command was received */ + SD_AKE_SEQ_ERROR = (26), /* Error in sequence of authentication. */ + SD_INVALID_VOLTRANGE = (27), + SD_ADDR_OUT_OF_RANGE = (28), + SD_SWITCH_ERROR = (29), + SD_SDIO_DISABLED = (30), + SD_SDIO_FUNCTION_BUSY = (31), + SD_SDIO_FUNCTION_FAILED = (32), + SD_SDIO_UNKNOWN_FUNCTION = (33), + + /* Standard error defines */ + SD_INTERNAL_ERROR, + SD_NOT_CONFIGURED, + SD_REQUEST_PENDING, + SD_REQUEST_NOT_APPLICABLE, + SD_INVALID_PARAMETER, + SD_UNSUPPORTED_FEATURE, + SD_UNSUPPORTED_HW, + SD_ERROR, + SD_OK, +} SD_Error; + +/* SDIO Commands Index */ +#define SDIO_GO_IDLE_STATE ((u8)0) +#define SDIO_SEND_OP_COND ((u8)1) +#define SDIO_ALL_SEND_CID ((u8)2) +#define SDIO_SET_REL_ADDR ((u8)3) /* SDIO_SEND_REL_ADDR for SD Card */ +#define SDIO_SET_DSR ((u8)4) +#define SDIO_SDIO_SEN_OP_COND ((u8)5) +#define SDIO_HS_SWITCH ((u8)6) +#define SDIO_SEL_DESEL_CARD ((u8)7) +#define SDIO_HS_SEND_EXT_CSD ((u8)8) +#define SDIO_SEND_CSD ((u8)9) +#define SDIO_SEND_CID ((u8)10) +#define SDIO_READ_DAT_UNTIL_STOP ((u8)11) /* SD Card doesn't support it */ +#define SDIO_STOP_TRANSMISSION ((u8)12) +#define SDIO_SEND_STATUS ((u8)13) +#define SDIO_HS_BUSTEST_READ ((u8)14) +#define SDIO_GO_INACTIVE_STATE ((u8)15) +#define SDIO_SET_BLOCKLEN ((u8)16) +#define SDIO_READ_SINGLE_BLOCK ((u8)17) +#define SDIO_READ_MULT_BLOCK ((u8)18) +#define SDIO_HS_BUSTEST_WRITE ((u8)19) +#define SDIO_WRITE_DAT_UNTIL_STOP ((u8)20) /* SD Card doesn't support it */ +#define SDIO_SET_BLOCK_COUNT ((u8)23) /* SD Card doesn't support it */ +#define SDIO_WRITE_SINGLE_BLOCK ((u8)24) +#define SDIO_WRITE_MULT_BLOCK ((u8)25) +#define SDIO_PROG_CID ((u8)26) /* reserved for manufacturers */ +#define SDIO_PROG_CSD ((u8)27) +#define SDIO_SET_WRITE_PROT ((u8)28) +#define SDIO_CLR_WRITE_PROT ((u8)29) +#define SDIO_SEND_WRITE_PROT ((u8)30) +#define SDIO_SD_ERASE_GRP_START ((u8)32) /* To set the address of the first write + block to be erased. (For SD card only) */ +#define SDIO_SD_ERASE_GRP_END ((u8)33) /* To set the address of the last write block of the + continuous range to be erased. (For SD card only) */ +#define SDIO_ERASE_GRP_START ((u8)35) /* To set the address of the first write block to be erased. + (For MMC card only spec 3.31) */ + +#define SDIO_ERASE_GRP_END ((u8)36) /* To set the address of the last write block of the + continuous range to be erased. (For MMC card only spec 3.31) */ + +#define SDIO_ERASE ((u8)38) +#define SDIO_FAST_IO ((u8)39) /* SD Card doesn't support it */ +#define SDIO_GO_IRQ_STATE ((u8)40) /* SD Card doesn't support it */ +#define SDIO_LOCK_UNLOCK ((u8)42) +#define SDIO_APP_CMD ((u8)55) +#define SDIO_GEN_CMD ((u8)56) +#define SDIO_NO_CMD ((u8)64) + +/* Following commands are SD Card Specific commands. + SDIO_APP_CMD should be sent before sending these + commands. */ +#define SDIO_APP_SD_SET_BUSWIDTH ((u8)6) /* For SD Card only */ +#define SDIO_SD_APP_STAUS ((u8)13) /* For SD Card only */ +#define SDIO_SD_APP_SEND_NUM_WRITE_BLOCKS ((u8)22) /* For SD Card only */ +#define SDIO_SD_APP_OP_COND ((u8)41) /* For SD Card only */ +#define SDIO_SD_APP_SET_CLR_CARD_DETECT ((u8)42) /* For SD Card only */ +#define SDIO_SD_APP_SEND_SCR ((u8)51) /* For SD Card only */ +#define SDIO_SDIO_RW_DIRECT ((u8)52) /* For SD I/O Card only */ +#define SDIO_SDIO_RW_EXTENDED ((u8)53) /* For SD I/O Card only */ + +/* Following commands are SD Card Specific security commands. + SDIO_APP_CMD should be sent before sending these commands. */ +#define SDIO_SD_APP_GET_MKB ((u8)43) /* For SD Card only */ +#define SDIO_SD_APP_GET_MID ((u8)44) /* For SD Card only */ +#define SDIO_SD_APP_SET_CER_RN1 ((u8)45) /* For SD Card only */ +#define SDIO_SD_APP_GET_CER_RN2 ((u8)46) /* For SD Card only */ +#define SDIO_SD_APP_SET_CER_RES2 ((u8)47) /* For SD Card only */ +#define SDIO_SD_APP_GET_CER_RES1 ((u8)48) /* For SD Card only */ +#define SDIO_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((u8)18) /* For SD Card only */ +#define SDIO_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((u8)25) /* For SD Card only */ +#define SDIO_SD_APP_SECURE_ERASE ((u8)38) /* For SD Card only */ +#define SDIO_SD_APP_CHANGE_SECURE_AREA ((u8)49) /* For SD Card only */ +#define SDIO_SD_APP_SECURE_WRITE_MKB ((u8)48) /* For SD Card only */ + +typedef enum +{ + SD_NO_TRANSFER = 0, + SD_TRANSFER_IN_PROGRESS +} SDTransferState; + +typedef struct +{ + u16 TransferredBytes; + SD_Error TransferError; + u8 padding; +} SDLastTransferInfo; + +typedef struct /* Card Specific Data */ +{ + vu8 CSDStruct; /* CSD structure */ + vu8 SysSpecVersion; /* System specification version */ + vu8 Reserved1; /* Reserved */ + vu8 TAAC; /* Data read access-time 1 */ + vu8 NSAC; /* Data read access-time 2 in CLK cycles */ + vu8 MaxBusClkFrec; /* Max. bus clock frequency */ + vu16 CardComdClasses; /* Card command classes */ + vu8 RdBlockLen; /* Max. read data block length */ + vu8 PartBlockRead; /* Partial blocks for read allowed */ + vu8 WrBlockMisalign; /* Write block misalignment */ + vu8 RdBlockMisalign; /* Read block misalignment */ + vu8 DSRImpl; /* DSR implemented */ + vu8 Reserved2; /* Reserved */ + vu16 DeviceSize; /* Device Size */ + vu8 MaxRdCurrentVDDMin; /* Max. read current @ VDD min */ + vu8 MaxRdCurrentVDDMax; /* Max. read current @ VDD max */ + vu8 MaxWrCurrentVDDMin; /* Max. write current @ VDD min */ + vu8 MaxWrCurrentVDDMax; /* Max. write current @ VDD max */ + vu8 DeviceSizeMul; /* Device size multiplier */ + vu8 EraseGrSize; /* Erase group size */ + vu8 EraseGrMul; /* Erase group size multiplier */ + vu8 WrProtectGrSize; /* Write protect group size */ + vu8 WrProtectGrEnable; /* Write protect group enable */ + vu8 ManDeflECC; /* Manufacturer default ECC */ + vu8 WrSpeedFact; /* Write speed factor */ + vu8 MaxWrBlockLen; /* Max. write data block length */ + vu8 WriteBlockPaPartial; /* Partial blocks for write allowed */ + vu8 Reserved3; /* Reserded */ + vu8 ContentProtectAppli; /* Content protection application */ + vu8 FileFormatGrouop; /* File format group */ + vu8 CopyFlag; /* Copy flag (OTP) */ + vu8 PermWrProtect; /* Permanent write protection */ + vu8 TempWrProtect; /* Temporary write protection */ + vu8 FileFormat; /* File Format */ + vu8 ECC; /* ECC code */ + vu8 CSD_CRC; /* CSD CRC */ + vu8 Reserved4; /* always 1*/ +} SD_CSD; + +typedef struct /*Card Identification Data*/ +{ + vu8 ManufacturerID; /* ManufacturerID */ + vu16 OEM_AppliID; /* OEM/Application ID */ + vu32 ProdName1; /* Product Name part1 */ + vu8 ProdName2; /* Product Name part2*/ + vu8 ProdRev; /* Product Revision */ + vu32 ProdSN; /* Product Serial Number */ + vu8 Reserved1; /* Reserved1 */ + vu16 ManufactDate; /* Manufacturing Date */ + vu8 CID_CRC; /* CID CRC */ + vu8 Reserved2; /* always 1 */ +} SD_CID; + +typedef struct +{ + SD_CSD SD_csd; + SD_CID SD_cid; + u8 CardType; + u16 RCA; +} SD_CardInfo; + +/* Exported constants --------------------------------------------------------*/ +#define SD_DMA_MODE ((u32)0x00000000) +#define SD_INTERRUPT_MODE ((u32)0x00000001) +#define SD_POLLING_MODE ((u32)0x00000002) + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +SD_Error SD_Init(void); +SD_Error SD_PowerON(void); +SD_Error SD_PowerOFF(void); +SD_Error SD_InitializeCards(void); +SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo); +SD_Error SD_EnableWideBusOperation(u32 WideMode); +SD_Error SD_SetDeviceMode(u32 Mode); +SD_Error SD_SelectDeselect(u32 addr); +SD_Error SD_ReadBlock(u32 addr, u32 *readbuff, u16 BlockSize); +SD_Error SD_ReadMultiBlocks(u32 addr, u32 *readbuff, u16 BlockSize, u32 NumberOfBlocks); +SD_Error SD_WriteBlock(u32 addr, u32 *writebuff, u16 BlockSize); +SD_Error SD_WriteMultiBlocks(u32 addr, u32 *writebuff, u16 BlockSize, u32 NumberOfBlocks); +SDTransferState SD_GetTransferState(void); +SD_Error SD_StopTransfer(void); +SD_Error SD_Erase(u32 startaddr, u32 endaddr); +SD_Error SD_SendStatus(u32 *pcardstatus); +SD_Error SD_SendSDStatus(u32 *psdstatus); +SD_Error SD_ProcessIRQSrc(void); + +#endif /* __SDCARD_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/src/stm32lib/examples/SDIO/stm32f10x_conf.h b/src/stm32lib/examples/SDIO/stm32f10x_conf.h new file mode 100755 index 0000000..f487d13 --- /dev/null +++ b/src/stm32lib/examples/SDIO/stm32f10x_conf.h @@ -0,0 +1,169 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : stm32f10x_conf.h +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : Library configuration file. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_CONF_H +#define __STM32F10x_CONF_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_type.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Uncomment the line below to compile the library in DEBUG mode, this will expanse + the "assert_param" macro in the firmware library code (see "Exported macro" + section below) */ +/*#define DEBUG 1*/ + +/* Comment the line below to disable the specific peripheral inclusion */ +/************************************* ADC ************************************/ +//#define _ADC +//#define _ADC1 +//#define _ADC2 +//#define _ADC3 + +/************************************* BKP ************************************/ +//#define _BKP + +/************************************* CAN ************************************/ +//#define _CAN + +/************************************* CRC ************************************/ +//#define _CRC + +/************************************* DAC ************************************/ +//#define _DAC + +/************************************* DBGMCU *********************************/ +//#define _DBGMCU +/************************************* DMA ************************************/ +#define _DMA +//#define _DMA1_Channel1 +//#define _DMA1_Channel2 +//#define _DMA1_Channel3 +//#define _DMA1_Channel4 +//#define _DMA1_Channel5 +//#define _DMA1_Channel6 +//#define _DMA1_Channel7 +//#define _DMA2_Channel1 +//#define _DMA2_Channel2 +//#define _DMA2_Channel3 +#define _DMA2_Channel4 +//#define _DMA2_Channel5 + +/************************************* EXTI ***********************************/ +//#define _EXTI + +/************************************* FLASH and Option Bytes *****************/ +#define _FLASH +/* Uncomment the line below to enable FLASH program/erase/protections functions, + otherwise only FLASH configuration (latency, prefetch, half cycle) functions + are enabled */ +/* #define _FLASH_PROG */ + +/************************************* FSMC ***********************************/ +//#define _FSMC + +/************************************* GPIO ***********************************/ +#define _GPIO +//#define _GPIOA +//#define _GPIOB +#define _GPIOC +#define _GPIOD +//#define _GPIOE +//#define _GPIOF +//#define _GPIOG +#define _AFIO + +/************************************* I2C ************************************/ +//#define _I2C +//#define _I2C1 +//#define _I2C2 + +/************************************* IWDG ***********************************/ +//#define _IWDG + +/************************************* NVIC ***********************************/ +#define _NVIC + +/************************************* PWR ************************************/ +//#define _PWR + +/************************************* RCC ************************************/ +#define _RCC + +/************************************* RTC ************************************/ +//#define _RTC + +/************************************* SDIO ***********************************/ +#define _SDIO + +/************************************* SPI ************************************/ +//#define _SPI +//#define _SPI1 +//#define _SPI2 +//#define _SPI3 + +/************************************* SysTick ********************************/ +//#define _SysTick + +/************************************* TIM ************************************/ +//#define _TIM +//#define _TIM1 +//#define _TIM2 +//#define _TIM3 +//#define _TIM4 +//#define _TIM5 +//#define _TIM6 +//#define _TIM7 +//#define _TIM8 + +/************************************* USART **********************************/ +//#define _USART +//#define _USART1 +//#define _USART2 +//#define _USART3 +//#define _UART4 +//#define _UART5 + +/************************************* WWDG ***********************************/ +//#define _WWDG + +/* In the following line adjust the value of External High Speed oscillator (HSE) + used in your application */ +#define HSE_Value ((u32)8000000) /* Value of the External oscillator in Hz*/ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef DEBUG +/******************************************************************************* +* Macro Name : assert_param +* Description : The assert_param macro is used for function's parameters check. +* It is used only if the library is compiled in DEBUG mode. +* Input : - expr: If expr is false, it calls assert_failed function +* which reports the name of the source file and the source +* line number of the call that failed. +* If expr is true, it returns no value. +* Return : None +*******************************************************************************/ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((u8 *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(u8* file, u32 line); +#else + #define assert_param(expr) ((void)0) +#endif /* DEBUG */ + +#endif /* __STM32F10x_CONF_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/src/stm32lib/examples/SDIO/stm32f10x_it.c b/src/stm32lib/examples/SDIO/stm32f10x_it.c new file mode 100755 index 0000000..bf3e5b4 --- /dev/null +++ b/src/stm32lib/examples/SDIO/stm32f10x_it.c @@ -0,0 +1,745 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : stm32f10x_it.c +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : Main Interrupt Service Routines. +* This file provides template for all exceptions handler +* and peripherals interrupt service routine. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_it.h" +#include "sdcard.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : NMIException +* Description : This function handles NMI exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void NMIException(void) +{} + +/******************************************************************************* +* Function Name : HardFaultException +* Description : This function handles Hard Fault exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void HardFaultException(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + {} +} + +/******************************************************************************* +* Function Name : MemManageException +* Description : This function handles Memory Manage exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void MemManageException(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + {} +} + +/******************************************************************************* +* Function Name : BusFaultException +* Description : This function handles Bus Fault exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void BusFaultException(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + {} +} + +/******************************************************************************* +* Function Name : UsageFaultException +* Description : This function handles Usage Fault exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void UsageFaultException(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + {} +} + +/******************************************************************************* +* Function Name : DebugMonitor +* Description : This function handles Debug Monitor exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DebugMonitor(void) +{} + +/******************************************************************************* +* Function Name : SVCHandler +* Description : This function handles SVCall exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SVCHandler(void) +{} + +/******************************************************************************* +* Function Name : PendSVC +* Description : This function handles PendSVC exception. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void PendSVC(void) +{} + +/******************************************************************************* +* Function Name : SysTickHandler +* Description : This function handles SysTick Handler. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SysTickHandler(void) +{} + +/******************************************************************************* +* Function Name : WWDG_IRQHandler +* Description : This function handles WWDG interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void WWDG_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : PVD_IRQHandler +* Description : This function handles PVD interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void PVD_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TAMPER_IRQHandler +* Description : This function handles Tamper interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TAMPER_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : RTC_IRQHandler +* Description : This function handles RTC global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RTC_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : FLASH_IRQHandler +* Description : This function handles Flash interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void FLASH_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : RCC_IRQHandler +* Description : This function handles RCC interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RCC_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI0_IRQHandler +* Description : This function handles External interrupt Line 0 request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI0_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI1_IRQHandler +* Description : This function handles External interrupt Line 1 request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI1_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI2_IRQHandler +* Description : This function handles External interrupt Line 2 request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI3_IRQHandler +* Description : This function handles External interrupt Line 3 request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI4_IRQHandler +* Description : This function handles External interrupt Line 4 request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI4_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel1_IRQHandler +* Description : This function handles DMA1 Channel 1 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel1_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel2_IRQHandler +* Description : This function handles DMA1 Channel 2 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel3_IRQHandler +* Description : This function handles DMA1 Channel 3 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel4_IRQHandler +* Description : This function handles DMA1 Channel 4 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel4_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel5_IRQHandler +* Description : This function handles DMA1 Channel 5 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel5_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel6_IRQHandler +* Description : This function handles DMA1 Channel 6 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel6_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA1_Channel7_IRQHandler +* Description : This function handles DMA1 Channel 7 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel7_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : ADC1_2_IRQHandler +* Description : This function handles ADC1 and ADC2 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void ADC1_2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : USB_HP_CAN_TX_IRQHandler +* Description : This function handles USB High Priority or CAN TX interrupts +* requests. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void USB_HP_CAN_TX_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : USB_LP_CAN_RX0_IRQHandler +* Description : This function handles USB Low Priority or CAN RX0 interrupts +* requests. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void USB_LP_CAN_RX0_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : CAN_RX1_IRQHandler +* Description : This function handles CAN RX1 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void CAN_RX1_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : CAN_SCE_IRQHandler +* Description : This function handles CAN SCE interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void CAN_SCE_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI9_5_IRQHandler +* Description : This function handles External lines 9 to 5 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI9_5_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM1_BRK_IRQHandler +* Description : This function handles TIM1 Break interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM1_BRK_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM1_UP_IRQHandler +* Description : This function handles TIM1 overflow and update interrupt +* request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM1_UP_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM1_TRG_COM_IRQHandler +* Description : This function handles TIM1 Trigger and commutation interrupts +* requests. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM1_TRG_COM_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM1_CC_IRQHandler +* Description : This function handles TIM1 capture compare interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM1_CC_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM2_IRQHandler +* Description : This function handles TIM2 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM3_IRQHandler +* Description : This function handles TIM3 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM4_IRQHandler +* Description : This function handles TIM4 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM4_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : I2C1_EV_IRQHandler +* Description : This function handles I2C1 Event interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void I2C1_EV_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : I2C1_ER_IRQHandler +* Description : This function handles I2C1 Error interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void I2C1_ER_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : I2C2_EV_IRQHandler +* Description : This function handles I2C2 Event interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void I2C2_EV_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : I2C2_ER_IRQHandler +* Description : This function handles I2C2 Error interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void I2C2_ER_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : SPI1_IRQHandler +* Description : This function handles SPI1 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI1_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : SPI2_IRQHandler +* Description : This function handles SPI2 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : USART1_IRQHandler +* Description : This function handles USART1 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void USART1_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : USART2_IRQHandler +* Description : This function handles USART2 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void USART2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : USART3_IRQHandler +* Description : This function handles USART3 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void USART3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : EXTI15_10_IRQHandler +* Description : This function handles External lines 15 to 10 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void EXTI15_10_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : RTCAlarm_IRQHandler +* Description : This function handles RTC Alarm interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RTCAlarm_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : USBWakeUp_IRQHandler +* Description : This function handles USB WakeUp interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void USBWakeUp_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM8_BRK_IRQHandler +* Description : This function handles TIM8 Break interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM8_BRK_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM8_UP_IRQHandler +* Description : This function handles TIM8 overflow and update interrupt +* request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM8_UP_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM8_TRG_COM_IRQHandler +* Description : This function handles TIM8 Trigger and commutation interrupts +* requests. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM8_TRG_COM_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM8_CC_IRQHandler +* Description : This function handles TIM8 capture compare interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM8_CC_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : ADC3_IRQHandler +* Description : This function handles ADC3 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void ADC3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : FSMC_IRQHandler +* Description : This function handles FSMC global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void FSMC_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : SDIO_IRQHandler +* Description : This function handles SDIO global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SDIO_IRQHandler(void) +{ + /* Process All SDIO Interrupt Sources */ + SD_ProcessIRQSrc(); +} + +/******************************************************************************* +* Function Name : TIM5_IRQHandler +* Description : This function handles TIM5 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM5_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : SPI3_IRQHandler +* Description : This function handles SPI3 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SPI3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : UART4_IRQHandler +* Description : This function handles UART4 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void UART4_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : UART5_IRQHandler +* Description : This function handles UART5 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void UART5_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM6_IRQHandler +* Description : This function handles TIM6 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM6_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : TIM7_IRQHandler +* Description : This function handles TIM7 global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void TIM7_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA2_Channel1_IRQHandler +* Description : This function handles DMA2 Channel 1 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA2_Channel1_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA2_Channel2_IRQHandler +* Description : This function handles DMA2 Channel 2 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA2_Channel2_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA2_Channel3_IRQHandler +* Description : This function handles DMA2 Channel 3 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA2_Channel3_IRQHandler(void) +{} + +/******************************************************************************* +* Function Name : DMA2_Channel4_5_IRQHandler +* Description : This function handles DMA2 Channel 4 and DMA2 Channel 5 +* interrupts requests. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA2_Channel4_5_IRQHandler(void) +{} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/src/stm32lib/examples/SDIO/stm32f10x_it.h b/src/stm32lib/examples/SDIO/stm32f10x_it.h new file mode 100755 index 0000000..e74b6cc --- /dev/null +++ b/src/stm32lib/examples/SDIO/stm32f10x_it.h @@ -0,0 +1,100 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : stm32f10x_it.h +* Author : MCD Application Team +* Version : V2.0.1 +* Date : 06/13/2008 +* Description : This file contains the headers of the interrupt handlers. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_IT_H +#define __STM32F10x_IT_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NMIException(void); +void HardFaultException(void); +void MemManageException(void); +void BusFaultException(void); +void UsageFaultException(void); +void DebugMonitor(void); +void SVCHandler(void); +void PendSVC(void); +void SysTickHandler(void); +void WWDG_IRQHandler(void); +void PVD_IRQHandler(void); +void TAMPER_IRQHandler(void); +void RTC_IRQHandler(void); +void FLASH_IRQHandler(void); +void RCC_IRQHandler(void); +void EXTI0_IRQHandler(void); +void EXTI1_IRQHandler(void); +void EXTI2_IRQHandler(void); +void EXTI3_IRQHandler(void); +void EXTI4_IRQHandler(void); +void DMA1_Channel1_IRQHandler(void); +void DMA1_Channel2_IRQHandler(void); +void DMA1_Channel3_IRQHandler(void); +void DMA1_Channel4_IRQHandler(void); +void DMA1_Channel5_IRQHandler(void); +void DMA1_Channel6_IRQHandler(void); +void DMA1_Channel7_IRQHandler(void); +void ADC1_2_IRQHandler(void); +void USB_HP_CAN_TX_IRQHandler(void); +void USB_LP_CAN_RX0_IRQHandler(void); +void CAN_RX1_IRQHandler(void); +void CAN_SCE_IRQHandler(void); +void EXTI9_5_IRQHandler(void); +void TIM1_BRK_IRQHandler(void); +void TIM1_UP_IRQHandler(void); +void TIM1_TRG_COM_IRQHandler(void); +void TIM1_CC_IRQHandler(void); +void TIM2_IRQHandler(void); +void TIM3_IRQHandler(void); +void TIM4_IRQHandler(void); +void I2C1_EV_IRQHandler(void); +void I2C1_ER_IRQHandler(void); +void I2C2_EV_IRQHandler(void); +void I2C2_ER_IRQHandler(void); +void SPI1_IRQHandler(void); +void SPI2_IRQHandler(void); +void USART1_IRQHandler(void); +void USART2_IRQHandler(void); +void USART3_IRQHandler(void); +void EXTI15_10_IRQHandler(void); +void RTCAlarm_IRQHandler(void); +void USBWakeUp_IRQHandler(void); +void TIM8_BRK_IRQHandler(void); +void TIM8_UP_IRQHandler(void); +void TIM8_TRG_COM_IRQHandler(void); +void TIM8_CC_IRQHandler(void); +void ADC3_IRQHandler(void); +void FSMC_IRQHandler(void); +void SDIO_IRQHandler(void); +void TIM5_IRQHandler(void); +void SPI3_IRQHandler(void); +void UART4_IRQHandler(void); +void UART5_IRQHandler(void); +void TIM6_IRQHandler(void); +void TIM7_IRQHandler(void); +void DMA2_Channel1_IRQHandler(void); +void DMA2_Channel2_IRQHandler(void); +void DMA2_Channel3_IRQHandler(void); +void DMA2_Channel4_5_IRQHandler(void); + +#endif /* __STM32F10x_IT_H */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ -- cgit v1.2.3