提交 8421ecfa 编写于 作者: wuyangyong's avatar wuyangyong

update SD card driver: use RT-Thread SPI driver.

上级 5c17c2e6
...@@ -4,6 +4,15 @@ from building import * ...@@ -4,6 +4,15 @@ from building import *
cwd = os.path.join(str(Dir('#')), 'drivers') cwd = os.path.join(str(Dir('#')), 'drivers')
src = Glob('*.c') src = Glob('*.c')
# remove no need file.
if GetDepend('RT_USING_LWIP') == False:
SrcRemove(src, 'stm32_eth.c')
if GetDepend('RT_USING_SPI') == False:
SrcRemove(src, 'rt_stm32f10x_spi.c')
SrcRemove(src, 'msd.c')
CPPPATH = [cwd] CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <rthw.h> #include <rthw.h>
#include <rtthread.h> #include <rtthread.h>
#include "board.h" #include "board.h"
/** /**
...@@ -45,7 +44,7 @@ void NVIC_Configuration(void) ...@@ -45,7 +44,7 @@ void NVIC_Configuration(void)
* This is the timer interrupt service routine. * This is the timer interrupt service routine.
* *
*/ */
void rt_hw_timer_handler(void) void SysTick_Handler(void)
{ {
/* enter interrupt */ /* enter interrupt */
rt_interrupt_enter(); rt_interrupt_enter();
......
...@@ -40,6 +40,9 @@ ...@@ -40,6 +40,9 @@
#define STM32_SRAM_SIZE 64 #define STM32_SRAM_SIZE 64
#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024) #define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024)
#define RT_USING_UART1
#define RT_USING_SPI1
void rt_hw_board_init(void); void rt_hw_board_init(void);
void rt_hw_usart_init(void); void rt_hw_usart_init(void);
......
/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** /*
* File Name : msd.c * File : msd.c
* Author : MCD Application Team * SPI mode SD Card Driver
* Version : V2.1 * This file is part of RT-Thread RTOS
* Date : 05/30/2008 * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
* Description : MSD card driver source file. *
* Pin assignment: * The license and distribution terms for this file may be
* ---------------------------------------------- * found in the file LICENSE in this distribution or at
* | STM32F10x | MSD Pin | * http://www.rt-thread.org/license/LICENSE
* ---------------------------------------------- *
* | P0.4 | ChipSelect 1 | * Change Logs:
* | P0.1 / MOSI | DataIn 2 | * Date Author Notes
* | | GND 3 (0 V) | * 2009-04-17 Bernard first version.
* | | VDD 4 (3.3 V) | * 2010-07-15 aozima Modify read/write according new block driver interface.
* | P0.2 / SCLK | Clock 5 | * 2012-02-01 aozima use new RT-Thread SPI drivers.
* | | GND 6 (0 V) | * 2012-04-11 aozima get max. data transfer rate from CSD[TRAN_SPEED].
* | P0.0 / MISO | DataOut 7 | * 2012-05-21 aozima update MMC card support.
* ----------------------------------------------- */
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS #include <string.h>
* 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 SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "msd.h" #include "msd.h"
#include <stm32f10x_spi.h>
#include <rtthread.h> //#define MSD_TRACE
/* Private typedef -----------------------------------------------------------*/ #ifdef MSD_TRACE
/* Private define ------------------------------------------------------------*/ #define MSD_DEBUG(...) rt_kprintf("[MSD] %d ", rt_tick_get()); rt_kprintf(__VA_ARGS__);
/* Private macro -------------------------------------------------------------*/ #else
/* Select MSD Card: ChipSelect pin low */ #define MSD_DEBUG(...)
#define MSD_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4) #endif /* #ifdef MSD_TRACE */
/* Deselect MSD Card: ChipSelect pin high */
#define MSD_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4) #define DUMMY 0xFF
#define MSD_SPI SPI1
#define MSD_RCC_SPI RCC_APB2Periph_SPI1 #define CARD_NCR_MAX 8
/* Private function prototypes -----------------------------------------------*/ #define CARD_NRC 1
static void SPI_Config(void); #define CARD_NCR 1
/* Private functions ---------------------------------------------------------*/
static struct msd_device _msd_device;
/*******************************************************************************
* Function Name : MSD_Init /* function define */
* Description : Initializes the MSD/SD communication. static rt_bool_t rt_tick_timeout(rt_tick_t tick_start, rt_tick_t tick_long);
* Input : None
* Output : None static rt_err_t MSD_take_owner(struct rt_spi_device* spi_device);
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed static void MSD_take_cs(struct rt_spi_device* device);
* - MSD_RESPONSE_NO_ERROR: Sequence succeed static void MSD_release_cs(struct rt_spi_device* device);
*******************************************************************************/
u8 MSD_Init(void) static rt_err_t _wait_token(struct rt_spi_device* device, uint8_t token);
static rt_err_t _wait_ready(struct rt_spi_device* device);
static rt_size_t rt_msd_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size);
static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size);
static rt_size_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size);
static rt_size_t rt_msd_sdhc_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size);
static rt_err_t MSD_take_owner(struct rt_spi_device* spi_device)
{
rt_err_t result;
result = rt_mutex_take(&(spi_device->bus->lock), RT_WAITING_FOREVER);
if(result == RT_EOK)
{
if (spi_device->bus->owner != spi_device)
{
/* not the same owner as current, re-configure SPI bus */
result = spi_device->bus->ops->configure(spi_device, &spi_device->config);
if (result == RT_EOK)
{
/* set SPI bus owner */
spi_device->bus->owner = spi_device;
}
}
}
return result;
}
static void MSD_take_cs(struct rt_spi_device* device)
{ {
u32 i = 0; struct rt_spi_message message;
/* Initialize SPI */ /* initial message */
SPI_Config(); message.send_buf = RT_NULL;
/* MSD chip select high */ message.recv_buf = RT_NULL;
MSD_CS_HIGH(); message.length = 0;
/* Send dummy byte 0xFF, 10 times with CS high*/ message.cs_take = 1;
/* rise CS and MOSI for 80 clocks cycles */ message.cs_release = 0;
for (i = 0; i < 10; i++)
{ /* transfer message */
/* Send dummy byte 0xFF */ device->bus->ops->xfer(device, &message);
MSD_WriteByte(DUMMY);
}
/*------------Put MSD in SPI mode--------------*/
/* MSD initialized and set to SPI mode properly */
return (MSD_GoIdleState());
} }
/******************************************************************************* static void MSD_release_cs(struct rt_spi_device* device)
* Function Name : MSD_WriteBlock
* Description : Writes a block on the MSD
* Input : - pBuffer : pointer to the buffer containing the data to be
* written on the MSD.
* - WriteAddr : address to write on.
* - NumByteToWrite: number of data to write
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{ {
u32 i = 0; struct rt_spi_message message;
u8 rvalue = MSD_RESPONSE_FAILURE;
/* initial message */
message.send_buf = RT_NULL;
message.recv_buf = RT_NULL;
message.length = 0;
message.cs_take = 0;
message.cs_release = 1;
/* transfer message */
device->bus->ops->xfer(device, &message);
}
/* MSD chip select low */ static rt_bool_t rt_tick_timeout(rt_tick_t tick_start, rt_tick_t tick_long)
MSD_CS_LOW(); {
/* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */ rt_tick_t tick_end = tick_start + tick_long;
MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF); rt_tick_t tick_now = rt_tick_get();
rt_bool_t result = RT_FALSE;
/* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */ if(tick_end >= tick_start)
if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
{ {
/* Send a dummy byte */ if (tick_now >= tick_end)
MSD_WriteByte(DUMMY);
/* Send the data token to signify the start of the data */
MSD_WriteByte(0xFE);
/* Write the block data to MSD : write count data by block */
for (i = 0; i < NumByteToWrite; i++)
{ {
/* Send the pointed byte */ result = RT_TRUE;
MSD_WriteByte(*pBuffer);
/* Point to the next location where the byte read will be saved */
pBuffer++;
} }
/* Put CRC bytes (not really needed by us, but required by MSD) */ else
MSD_ReadByte();
MSD_ReadByte();
/* Read data response */
if (MSD_GetDataResponse() == MSD_DATA_OK)
{ {
rvalue = MSD_RESPONSE_NO_ERROR; result = RT_FALSE;
}
}
else
{
if ((tick_now < tick_start ) && (tick_now >= tick_end) )
{
result = RT_TRUE;
}
else
{
result = RT_FALSE;
} }
} }
/* MSD chip select high */ return result;
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Returns the reponse */
return rvalue;
} }
/******************************************************************************* static uint8_t crc7(const uint8_t *buf, int len)
* Function Name : MSD_ReadBlock
* Description : Reads a block of data from the MSD.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the MSD.
* - ReadAddr : MSD's internal address to read from.
* - NumByteToRead : number of bytes to read from the MSD.
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{ {
u32 i = 0; unsigned char i, j, crc, ch, ch2, ch3;
u8 rvalue = MSD_RESPONSE_FAILURE;
crc = 0;
/* MSD chip select low */ for (i = 0; i < len; i ++)
MSD_CS_LOW(); {
/* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */ ch = buf[i];
MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);
/* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */ for (j = 0; j < 8; j ++, ch <<= 1)
if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
{ {
/* Now look for the data token to signify the start of the data */ ch2 = (crc & 0x40) ? 1 : 0;
if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ)) ch3 = (ch & 0x80) ? 1 : 0;
if (ch2 ^ ch3)
{ {
/* Read the MSD block data : read NumByteToRead data */ crc ^= 0x04;
for (i = 0; i < NumByteToRead; i++) crc <<= 1;
crc |= 0x01;
}
else
{ {
/* Save the received data */ crc <<= 1;
*pBuffer = MSD_ReadByte();
/* Point to the next location where the byte read will be saved */
pBuffer++;
} }
/* Get CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte();
MSD_ReadByte();
/* Set response value to success */
rvalue = MSD_RESPONSE_NO_ERROR;
} }
} }
/* MSD chip select high */ return crc;
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Returns the reponse */
return rvalue;
} }
/******************************************************************************* static rt_err_t _send_cmd(
* Function Name : MSD_WriteBuffer struct rt_spi_device* device,
* Description : Writes many blocks on the MSD uint8_t cmd,
* Input : - pBuffer : pointer to the buffer containing the data to be uint32_t arg,
* written on the MSD. uint8_t crc,
* - WriteAddr : address to write on. response_type type,
* - NumByteToWrite: number of data to write uint8_t * response
* Output : None )
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite)
{ {
u32 i = 0, NbrOfBlock = 0, Offset = 0; struct rt_spi_message message;
u8 rvalue = MSD_RESPONSE_FAILURE; uint8_t cmd_buffer[8];
uint8_t recv_buffer[sizeof(cmd_buffer)];
uint32_t i;
cmd_buffer[0] = DUMMY;
cmd_buffer[1] = (cmd | 0x40);
cmd_buffer[2] = (uint8_t)(arg >> 24);
cmd_buffer[3] = (uint8_t)(arg >> 16);
cmd_buffer[4] = (uint8_t)(arg >> 8);
cmd_buffer[5] = (uint8_t)(arg);
if(crc == 0x00)
{
crc = crc7(&cmd_buffer[1], 5);
crc = (crc<<1) | 0x01;
}
cmd_buffer[6] = (crc);
cmd_buffer[7] = DUMMY;
/* initial message */
message.send_buf = cmd_buffer;
message.recv_buf = recv_buffer;
message.length = sizeof(cmd_buffer);
message.cs_take = message.cs_release = 0;
/* Calculate number of blocks to write */ _wait_ready(device);
NbrOfBlock = NumByteToWrite / BLOCK_SIZE;
/* MSD chip select low */
MSD_CS_LOW();
/* Data transfer */ /* transfer message */
while (NbrOfBlock --) device->bus->ops->xfer(device, &message);
for(i=CARD_NCR; i<(CARD_NCR_MAX+1); i++)
{ {
/* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */ uint8_t send = DUMMY;
MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr + Offset, 0xFF);
/* initial message */
message.send_buf = &send;
message.recv_buf = response;
message.length = 1;
message.cs_take = message.cs_release = 0;
/* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */ /* transfer message */
if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) device->bus->ops->xfer(device, &message);
if(0 == (response[0] & 0x80))
{ {
return MSD_RESPONSE_FAILURE; break;
} }
/* Send dummy byte */ } /* wait response */
MSD_WriteByte(DUMMY);
/* Send the data token to signify the start of the data */ if((CARD_NCR_MAX+1) == i)
MSD_WriteByte(MSD_START_DATA_SINGLE_BLOCK_WRITE);
/* Write the block data to MSD : write count data by block */
for (i = 0; i < BLOCK_SIZE; i++)
{ {
/* Send the pointed byte */ return RT_ERROR;//fail
MSD_WriteByte(*pBuffer);
/* Point to the next location where the byte read will be saved */
pBuffer++;
} }
/* Set next write address */
Offset += 512; //recieve other byte
/* Put CRC bytes (not really needed by us, but required by MSD) */ if(type == response_r1)
MSD_ReadByte();
MSD_ReadByte();
/* Read data response */
if (MSD_GetDataResponse() == MSD_DATA_OK)
{ {
/* Set response value to success */ return RT_EOK;
rvalue = MSD_RESPONSE_NO_ERROR;
} }
else else if(type == response_r1b)
{ {
/* Set response value to failure */ rt_tick_t tick_start = rt_tick_get();
rvalue = MSD_RESPONSE_FAILURE; uint8_t recv;
while(1)
{
/* initial message */
message.send_buf = RT_NULL;
message.recv_buf = &recv;
message.length = 1;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
if(recv == DUMMY)
{
return RT_EOK;
} }
if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(2000)))
{
return RT_ETIMEOUT;
}
}
}
else if(type == response_r2)
{
/* initial message */
message.send_buf = RT_NULL;
message.recv_buf = response+1;
message.length = 1;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
}
else if((type == response_r3) || (type == response_r7))
{
/* initial message */
message.send_buf = RT_NULL;
message.recv_buf = response+1;
message.length = 4;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
}
else
{
return RT_ERROR; // unknow type?
} }
/* MSD chip select high */ return RT_EOK;
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Returns the reponse */
return rvalue;
} }
/******************************************************************************* static rt_err_t _wait_token(struct rt_spi_device* device, uint8_t token)
* Function Name : MSD_ReadBuffer
* Description : Reads multiple block of data from the MSD.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the MSD.
* - ReadAddr : MSD's internal address to read from.
* - NumByteToRead : number of bytes to read from the MSD.
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead)
{ {
u32 i = 0, NbrOfBlock = 0, Offset = 0; struct rt_spi_message message;
u8 rvalue = MSD_RESPONSE_FAILURE; rt_tick_t tick_start;
uint8_t send, recv;
tick_start = rt_tick_get();
/* Calculate number of blocks to read */ /* wati token */
NbrOfBlock = NumByteToRead / BLOCK_SIZE; /* initial message */
/* MSD chip select low */ send = DUMMY;
MSD_CS_LOW(); message.send_buf = &send;
message.recv_buf = &recv;
message.length = 1;
message.cs_take = message.cs_release = 0;
/* Data transfer */ while(1)
while (NbrOfBlock --)
{ {
/* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */ /* transfer message */
MSD_SendCmd (MSD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF); device->bus->ops->xfer(device, &message);
/* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) if(recv == token)
{ {
return MSD_RESPONSE_FAILURE; return RT_EOK;
} }
/* Now look for the data token to signify the start of the data */
if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ)) if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_WAIT_TOKEN_TIMES)))
{
/* Read the MSD block data : read NumByteToRead data */
for (i = 0; i < BLOCK_SIZE; i++)
{ {
/* Read the pointed data */ MSD_DEBUG("[err] wait data start token timeout!\r\n");
*pBuffer = MSD_ReadByte(); return RT_ETIMEOUT;
/* Point to the next location where the byte read will be saved */
pBuffer++;
} }
/* Set next read address*/ } /* wati token */
Offset += 512; }
/* get CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte(); static rt_err_t _wait_ready(struct rt_spi_device* device)
MSD_ReadByte(); {
/* Set response value to success */ struct rt_spi_message message;
rvalue = MSD_RESPONSE_NO_ERROR; rt_tick_t tick_start;
uint8_t send, recv;
tick_start = rt_tick_get();
send = DUMMY;
/* initial message */
message.send_buf = &send;
message.recv_buf = &recv;
message.length = 1;
message.cs_take = message.cs_release = 0;
while(1)
{
/* transfer message */
device->bus->ops->xfer(device, &message);
if(recv == DUMMY)
{
return RT_EOK;
} }
else
if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(1000)))
{ {
/* Set response value to failure */ MSD_DEBUG("[err] wait ready timeout!\r\n");
rvalue = MSD_RESPONSE_FAILURE; return RT_ETIMEOUT;
} }
} }
/* MSD chip select high */
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Returns the reponse */
return rvalue;
} }
/******************************************************************************* static rt_err_t _read_block(struct rt_spi_device* device, void * buffer, uint32_t block_size)
* Function Name : MSD_GetCSDRegister
* Description : Read the CSD card register.
* Reading the contents of the CSD register in SPI mode
* is a simple read-block transaction.
* Input : - MSD_csd: pointer on an SCD register structure
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8 MSD_GetCSDRegister(sMSD_CSD* MSD_csd)
{ {
u32 i = 0; struct rt_spi_message message;
u8 rvalue = MSD_RESPONSE_FAILURE; rt_err_t result;
u8 CSD_Tab[16];
/* MSD chip select low */
MSD_CS_LOW();
/* Send CMD9 (CSD register) or CMD10(CSD register) */
MSD_SendCmd(MSD_SEND_CSD, 0, 0xFF);
/* Wait for response in the R1 format (0x00 is no errors) */
if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
{
if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
{
for (i = 0; i < 16; i++)
{
/* Store CSD register value on CSD_Tab */
CSD_Tab[i] = MSD_ReadByte();
}
}
/* Get CRC bytes (not really needed by us, but required by MSD) */
MSD_WriteByte(DUMMY);
MSD_WriteByte(DUMMY);
/* Set response value to success */
rvalue = MSD_RESPONSE_NO_ERROR;
}
/* MSD chip select high */
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Byte 0 */
MSD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
MSD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
MSD_csd->Reserved1 = CSD_Tab[0] & 0x03;
/* Byte 1 */
MSD_csd->TAAC = CSD_Tab[1] ;
/* Byte 2 */
MSD_csd->NSAC = CSD_Tab[2];
/* Byte 3 */
MSD_csd->MaxBusClkFrec = CSD_Tab[3];
/* Byte 4 */
MSD_csd->CardComdClasses = CSD_Tab[4] << 4;
/* Byte 5 */
MSD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
MSD_csd->RdBlockLen = CSD_Tab[5] & 0x0F;
/* Byte 6 */
MSD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
MSD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
MSD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
MSD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
MSD_csd->Reserved2 = 0; /* Reserved */
MSD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10;
/* Byte 7 */
MSD_csd->DeviceSize |= (CSD_Tab[7]) << 2;
/* Byte 8 */
MSD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;
MSD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
MSD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
/* Byte 9 */
MSD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
MSD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
MSD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
/* Byte 10 */
MSD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
MSD_csd->EraseGrSize = (CSD_Tab[10] & 0x7C) >> 2;
MSD_csd->EraseGrMul = (CSD_Tab[10] & 0x03) << 3;
/* Byte 11 */
MSD_csd->EraseGrMul |= (CSD_Tab[11] & 0xE0) >> 5;
MSD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x1F);
/* Byte 12 */
MSD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
MSD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
MSD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
MSD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;
/* Byte 13 */
MSD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xc0) >> 6;
MSD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
MSD_csd->Reserved3 = 0;
MSD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01);
/* Byte 14 */
MSD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
MSD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
MSD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
MSD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
MSD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
MSD_csd->ECC = (CSD_Tab[14] & 0x03);
/* Byte 15 */
MSD_csd->msd_CRC = (CSD_Tab[15] & 0xFE) >> 1;
MSD_csd->Reserved4 = 1;
/* Return the reponse */
return rvalue;
}
/******************************************************************************* /* wati token */
* Function Name : MSD_GetCIDRegister result = _wait_token(device, MSD_TOKEN_READ_START);
* Description : Read the CID card register. if(result != RT_EOK)
* Reading the contents of the CID register in SPI mode {
* is a simple read-block transaction. return result;
* Input : - MSD_cid: pointer on an CID register structure }
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed /* read data */
* - MSD_RESPONSE_NO_ERROR: Sequence succeed {
*******************************************************************************/ /* initial message */
u8 MSD_GetCIDRegister(sMSD_CID* MSD_cid) message.send_buf = RT_NULL;
{ message.recv_buf = buffer;
u32 i = 0; message.length = block_size;
u8 rvalue = MSD_RESPONSE_FAILURE; message.cs_take = message.cs_release = 0;
u8 CID_Tab[16];
/* transfer message */
/* MSD chip select low */ device->bus->ops->xfer(device, &message);
MSD_CS_LOW(); } /* read data */
/* Send CMD10 (CID register) */
MSD_SendCmd(MSD_SEND_CID, 0, 0xFF); /* get crc */
{
/* Wait for response in the R1 format (0x00 is no errors) */ uint8_t recv_buffer[2];
if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
{ /* initial message */
if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ)) message.send_buf = RT_NULL;
{ message.recv_buf = recv_buffer;
/* Store CID register value on CID_Tab */ message.length = 2;
for (i = 0; i < 16; i++) message.cs_take = message.cs_release = 0;
{
CID_Tab[i] = MSD_ReadByte(); /* transfer message */
} device->bus->ops->xfer(device, &message);
} } /* get crc */
/* Get CRC bytes (not really needed by us, but required by MSD) */
MSD_WriteByte(DUMMY); return RT_EOK;
MSD_WriteByte(DUMMY);
/* Set response value to success */
rvalue = MSD_RESPONSE_NO_ERROR;
}
/* MSD chip select high */
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Byte 0 */
MSD_cid->ManufacturerID = CID_Tab[0];
/* Byte 1 */
MSD_cid->OEM_AppliID = CID_Tab[1] << 8;
/* Byte 2 */
MSD_cid->OEM_AppliID |= CID_Tab[2];
/* Byte 3 */
MSD_cid->ProdName1 = CID_Tab[3] << 24;
/* Byte 4 */
MSD_cid->ProdName1 |= CID_Tab[4] << 16;
/* Byte 5 */
MSD_cid->ProdName1 |= CID_Tab[5] << 8;
/* Byte 6 */
MSD_cid->ProdName1 |= CID_Tab[6];
/* Byte 7 */
MSD_cid->ProdName2 = CID_Tab[7];
/* Byte 8 */
MSD_cid->ProdRev = CID_Tab[8];
/* Byte 9 */
MSD_cid->ProdSN = CID_Tab[9] << 24;
/* Byte 10 */
MSD_cid->ProdSN |= CID_Tab[10] << 16;
/* Byte 11 */
MSD_cid->ProdSN |= CID_Tab[11] << 8;
/* Byte 12 */
MSD_cid->ProdSN |= CID_Tab[12];
/* Byte 13 */
MSD_cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
/* Byte 14 */
MSD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
/* Byte 15 */
MSD_cid->ManufactDate |= CID_Tab[14];
/* Byte 16 */
MSD_cid->msd_CRC = (CID_Tab[15] & 0xFE) >> 1;
MSD_cid->Reserved2 = 1;
/* Return the reponse */
return rvalue;
} }
/******************************************************************************* static rt_err_t _write_block(struct rt_spi_device* device, const void * buffer, uint32_t block_size, uint8_t token)
* Function Name : MSD_SendCmd
* Description : Send 5 bytes command to the MSD card.
* Input : - Cmd: the user expected command to send to MSD card
* - Arg: the command argument
* - Crc: the CRC
* Output : None
* Return : None
*******************************************************************************/
void MSD_SendCmd(u8 Cmd, u32 Arg, u8 Crc)
{ {
u32 i = 0x00; struct rt_spi_message message;
u8 Frame[6]; uint8_t send_buffer[16];
/* Construct byte1 */ rt_memset(send_buffer, DUMMY, sizeof(send_buffer));
Frame[0] = (Cmd | 0x40); send_buffer[sizeof(send_buffer) - 1] = token;
/* Construct byte2 */
Frame[1] = (u8)(Arg >> 24); /* send start block token */
/* Construct byte3 */ {
Frame[2] = (u8)(Arg >> 16); /* initial message */
/* Construct byte4 */ message.send_buf = send_buffer;
Frame[3] = (u8)(Arg >> 8); message.recv_buf = RT_NULL;
/* Construct byte5 */ message.length = sizeof(send_buffer);
Frame[4] = (u8)(Arg); message.cs_take = message.cs_release = 0;
/* Construct CRC: byte6 */
Frame[5] = (Crc); /* transfer message */
device->bus->ops->xfer(device, &message);
/* Send the Cmd bytes */
for (i = 0; i < 6; i++)
{
MSD_WriteByte(Frame[i]);
} }
/* send data */
{
/* initial message */
message.send_buf = buffer;
message.recv_buf = RT_NULL;
message.length = block_size;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
}
/* put crc and get data response */
{
uint8_t recv_buffer[3];
uint8_t response;
/* initial message */
message.send_buf = send_buffer;
message.recv_buf = recv_buffer;
message.length = sizeof(recv_buffer);
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
// response = 0x0E & recv_buffer[2];
response = MSD_GET_DATA_RESPONSE(recv_buffer[2]);
if(response != MSD_DATA_OK)
{
MSD_DEBUG("[err] write block fail! data response : 0x%02X\r\n", response);
return RT_ERROR;
}
}
/* wati ready */
return _wait_ready(device);
} }
/******************************************************************************* /* RT-Thread Device Driver Interface */
* Function Name : MSD_GetDataResponse static rt_err_t rt_msd_init(rt_device_t dev)
* Description : Get MSD card data response.
* Input : None
* Output : None
* Return : The MSD status: Read data response xxx0<status>1
* - status 010: Data accecpted
* - status 101: Data rejected due to a crc error
* - status 110: Data rejected due to a Write error.
* - status 111: Data rejected due to other error.
*******************************************************************************/
u8 MSD_GetDataResponse(void)
{ {
u32 i = 0; struct msd_device * msd = (struct msd_device *)dev;
u8 response, rvalue; uint8_t response[MSD_RESPONSE_MAX_LEN];
rt_err_t result = RT_EOK;
rt_tick_t tick_start;
uint32_t OCR;
if(msd->spi_device == RT_NULL)
{
MSD_DEBUG("[err] the SPI SD device has no SPI!\r\n");
return RT_EIO;
}
while (i <= 64) /* config spi */
{ {
/* Read resonse */ struct rt_spi_configuration cfg;
response = MSD_ReadByte(); cfg.data_width = 8;
/* Mask unused bits */ cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */
response &= 0x1F; cfg.max_hz = 1000*400; /* 400kbit/s */
rt_spi_configure(msd->spi_device, &cfg);
} /* config spi */
/* init SD card */
{
struct rt_spi_message message;
result = MSD_take_owner(msd->spi_device);
if (result != RT_EOK)
{
goto _exit;
}
MSD_release_cs(msd->spi_device);
/* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
start to supply at least 74 SD clocks to the SD card with keeping CMD line to high.
In case of SPI mode, CS shall be held to high during 74 clock cycles. */
{
uint8_t send_buffer[100]; /* 100byte > 74 clock */
switch (response) /* initial message */
memset(send_buffer, DUMMY, sizeof(send_buffer));
message.send_buf = send_buffer;
message.recv_buf = RT_NULL;
message.length = sizeof(send_buffer);
message.cs_take = message.cs_release = 0;
/* transfer message */
msd->spi_device->bus->ops->xfer(msd->spi_device, &message);
} /* send 74 clock */
/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
{
tick_start = rt_tick_get();
while(1)
{ {
case MSD_DATA_OK: MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, GO_IDLE_STATE, 0x00, 0x95, response_r1, response);
MSD_release_cs(msd->spi_device);
if((result == RT_EOK) && (response[0] == MSD_IN_IDLE_STATE))
{ {
rvalue = MSD_DATA_OK;
break; break;
} }
case MSD_DATA_CRC_ERROR: if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES)))
return MSD_DATA_CRC_ERROR; {
MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n");
result = RT_ETIMEOUT;
goto _exit;
}
}
MSD_DEBUG("[info] SD card goto IDLE mode OK!\r\n");
} /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
/* CMD8 */
{
tick_start = rt_tick_get();
do
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, SEND_IF_COND, 0x01AA, 0x87, response_r7, response);
MSD_release_cs(msd->spi_device);
case MSD_DATA_WRITE_ERROR: if(result == RT_EOK)
return MSD_DATA_WRITE_ERROR; {
MSD_DEBUG("[info] CMD8 response : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\r\n",
response[0], response[1], response[2], response[3], response[4]);
default: if(response[0] & (1<<2))
{ {
rvalue = MSD_DATA_OTHER_ERROR; /* illegal command, SD V1.x or MMC card */
MSD_DEBUG("[info] CMD8 is illegal command.\r\n");
MSD_DEBUG("[info] maybe Ver1.X SD Memory Card or MMC card!\r\n");
msd->card_type = MSD_CARD_TYPE_SD_V1_X;
break; break;
} }
else
{
/* SD V2.0 or later or SDHC or SDXC memory card! */
MSD_DEBUG("[info] Ver2.00 or later or SDHC or SDXC memory card!\r\n");
msd->card_type = MSD_CARD_TYPE_SD_V2_X;
}
if((0xAA == response[4]) && (0x00 == response[3]))
{
/* SD2.0 not support current voltage */
MSD_DEBUG("[err] VCA = 0, SD2.0 not surpport current operation voltage range\r\n");
result = RT_ERROR;
goto _exit;
}
} }
/* Exit loop in case of data ok */ else
if (rvalue == MSD_DATA_OK) {
if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(200)))
{
MSD_DEBUG("[err] CMD8 SEND_IF_COND timeout!\r\n");
result = RT_ETIMEOUT;
goto _exit;
}
}
}
while(0xAA != response[4]);
} /* CMD8 */
/* Ver1.X SD Memory Card or MMC card */
if(msd->card_type == MSD_CARD_TYPE_SD_V1_X)
{
rt_bool_t is_sd_v1_x = RT_FALSE;
rt_tick_t tick_start;
/* try SD Ver1.x */
while(1)
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response);
if(result != RT_EOK)
{
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[info] It maybe SD1.x or MMC But it is Not response to CMD58!\r\n");
goto _exit;
}
if(0 != (response[0]&0xFE))
{
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[info] It look CMD58 as illegal command so it is not SD card!\r\n");
break; break;
/* Increment loop counter */
i++;
} }
/* Wait null data */ MSD_release_cs(msd->spi_device);
while (MSD_ReadByte() == 0);
/* Return response */
return response;
}
/******************************************************************************* OCR = response[1];
* Function Name : MSD_GetResponse OCR = (OCR<<8) + response[2];
* Description : Returns the MSD response. OCR = (OCR<<8) + response[3];
* Input : None OCR = (OCR<<8) + response[4];
* Output : None MSD_DEBUG("[info] OCR is 0x%08X\r\n", OCR);
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8 MSD_GetResponse(u8 Response)
{
u32 Count = 0xFFF;
/* Check if response is got or a timeout is happen */ if( 0 == (OCR & (0x1 << 15)))
while ((MSD_ReadByte() != Response) && Count)
{ {
Count--; MSD_DEBUG(("[err] SD 1.x But not surpport current voltage\r\n"));
result = RT_ERROR;
goto _exit;
} }
if (Count == 0) /* --Send ACMD41 to make card ready */
tick_start = rt_tick_get();
/* try CMD55 + ACMD41 */
while(1)
{ {
/* After time out */ if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES_ACMD41)))
return MSD_RESPONSE_FAILURE; {
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[info] try CMD55 + ACMD41 timeout! mabey MMC card!\r\n");
break;
} }
else
MSD_take_cs(msd->spi_device);
/* CMD55 APP_CMD */
result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response);
if(result != RT_EOK)
{ {
/* Right response got */ MSD_release_cs(msd->spi_device);
return MSD_RESPONSE_NO_ERROR; continue;
} }
}
/******************************************************************************* if(0 != (response[0]&0xFE))
* Function Name : MSD_GetStatus {
* Description : Returns the MSD status. MSD_release_cs(msd->spi_device);
* Input : None MSD_DEBUG("[info] Not SD card2 , may be MMC\r\n");
* Output : None break;
* Return : The MSD status. }
*******************************************************************************/
u16 MSD_GetStatus(void)
{
u16 Status = 0;
/* MSD chip select low */ /* ACMD41 SD_SEND_OP_COND */
MSD_CS_LOW(); result = _send_cmd(msd->spi_device, SD_SEND_OP_COND, 0x00, 0x00, response_r1, response);
/* Send CMD13 (MSD_SEND_STATUS) to get MSD status */ if(result != RT_EOK)
MSD_SendCmd(MSD_SEND_STATUS, 0, 0xFF); {
MSD_release_cs(msd->spi_device);
continue;
}
Status = MSD_ReadByte(); if(0 != (response[0]&0xFE))
Status |= (u16)(MSD_ReadByte() << 8); {
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[info] Not SD card4 , may be MMC\r\n");
break;
}
/* MSD chip select high */ if(0 == (response[0]&0xFF))
MSD_CS_HIGH(); {
/* Send dummy byte 0xFF */ MSD_release_cs(msd->spi_device);
MSD_WriteByte(DUMMY); is_sd_v1_x = RT_TRUE;
MSD_DEBUG("[info] It is Ver1.X SD Memory Card!!!\r\n");
break;
}
} /* try CMD55 + ACMD41 */
return Status; break;
} } /* try SD Ver1.x */
/******************************************************************************* /* try MMC */
* Function Name : MSD_GoIdleState if(is_sd_v1_x != RT_TRUE)
* Description : Put MSD in Idle state. {
* Input : None uint32_t i;
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed MSD_DEBUG("[info] try MMC card!\r\n");
* - MSD_RESPONSE_NO_ERROR: Sequence succeed MSD_release_cs(msd->spi_device);
*******************************************************************************/
u8 MSD_GoIdleState(void) /* send dummy clock */
{ {
int i; uint8_t send_buffer[100];
/* MSD chip select low */
MSD_CS_LOW(); /* initial message */
/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */ memset(send_buffer, DUMMY, sizeof(send_buffer));
MSD_SendCmd(MSD_GO_IDLE_STATE, 0, 0x95); message.send_buf = send_buffer;
message.recv_buf = RT_NULL;
message.length = sizeof(send_buffer);
message.cs_take = message.cs_release = 0;
for(i=0; i<10; i++)
{
/* transfer message */
msd->spi_device->bus->ops->xfer(msd->spi_device, &message);
}
} /* send dummy clock */
/* send CMD0 goto IDLE state */
tick_start = rt_tick_get();
while(1)
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, GO_IDLE_STATE, 0x00, 0x95, response_r1, response);
MSD_release_cs(msd->spi_device);
if((result == RT_EOK) && (response[0] == MSD_IN_IDLE_STATE))
{
break;
}
if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES)))
{
MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n");
result = RT_ETIMEOUT;
goto _exit;
}
} /* send CMD0 goto IDLE stat */
/* send CMD1 */
tick_start = rt_tick_get();
while(1)
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, SEND_OP_COND, 0x00, 0x00, response_r1, response);
MSD_release_cs(msd->spi_device);
if((result == RT_EOK) && (response[0] == MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[info] It is MMC card!!!\r\n");
msd->card_type = MSD_CARD_TYPE_MMC;
break;
}
if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES)))
{
MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n");
result = RT_ETIMEOUT;
goto _exit;
}
} /* send CMD1 */
} /* try MMC */
}
else if(msd->card_type == MSD_CARD_TYPE_SD_V2_X)
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response);
if(result != RT_EOK)
{
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[err] It maybe SD2.0 But it is Not response to CMD58!\r\n");
goto _exit;
}
if((response[0] & 0xFE) != 0)
{
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[err] It look CMD58 as illegal command so it is not SD card!\r\n");
result = RT_ERROR;
goto _exit;
}
MSD_release_cs(msd->spi_device);
OCR = response[1];
OCR = (OCR<<8) + response[2];
OCR = (OCR<<8) + response[3];
OCR = (OCR<<8) + response[4];
MSD_DEBUG("[info] OCR is 0x%08X\r\n", OCR);
/* Wait for In Idle State Response (R1 Format) equal to 0x01 */ if( 0 == (OCR & (0x1 << 15)))
if (MSD_GetResponse(MSD_IN_IDLE_STATE))
{ {
/* No Idle State Response: return response failue */ MSD_DEBUG(("[err] SD 1.x But not surpport current voltage\r\n"));
return MSD_RESPONSE_FAILURE; result = RT_ERROR;
goto _exit;
} }
/*----------Activates the card initialization process-----------*/
/* --Send ACMD41 to make card ready */
tick_start = rt_tick_get();
/* try CMD55 + ACMD41 */
do do
{ {
/* MSD chip select high */ MSD_take_cs(msd->spi_device);
MSD_CS_HIGH(); if(rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES_ACMD41)))
/* Send Dummy byte 0xFF */ {
MSD_WriteByte(DUMMY); MSD_release_cs(msd->spi_device);
for (i = 0; i < 0xfff; i++); MSD_DEBUG("[err] SD Ver2.x or later try CMD55 + ACMD41 timeout!\r\n");
result = RT_ERROR;
goto _exit;
}
/* MSD chip select low */ /* CMD55 APP_CMD */
MSD_CS_LOW(); result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x65, response_r1, response);
for (i = 0; i < 0xfff; i++); // if((result != RT_EOK) || (response[0] == 0x01))
if(result != RT_EOK)
{
MSD_release_cs(msd->spi_device);
continue;
}
/* Send CMD1 (Activates the card process) until response equal to 0x0 */ if((response[0] & 0xFE) != 0)
MSD_SendCmd(MSD_SEND_OP_COND, 0, 0xFF); {
/* Wait for no error Response (R1 Format) equal to 0x00 */ MSD_release_cs(msd->spi_device);
MSD_DEBUG("[err] Not SD ready!\r\n");
result = RT_ERROR;
goto _exit;
} }
while (MSD_GetResponse(MSD_RESPONSE_NO_ERROR));
/* MSD chip select high */ /* ACMD41 SD_SEND_OP_COND */
MSD_CS_HIGH(); result = _send_cmd(msd->spi_device, SD_SEND_OP_COND, 0x40000000, 0x77, response_r1, response);
/* Send dummy byte 0xFF */ if(result != RT_EOK)
MSD_WriteByte(DUMMY); {
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[err] ACMD41 fail!\r\n");
result = RT_ERROR;
goto _exit;
}
return MSD_RESPONSE_NO_ERROR; if((response[0] & 0xFE) != 0)
} {
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[info] Not SD card4 , response : 0x%02X\r\n", response[0]);
// break;
}
}
while(response[0] != MSD_RESPONSE_NO_ERROR);
MSD_release_cs(msd->spi_device);
/* try CMD55 + ACMD41 */
/* --Read OCR again */
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response);
if(result != RT_EOK)
{
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[err] It maybe SD2.0 But it is Not response to 2nd CMD58!\r\n");
goto _exit;
}
/******************************************************************************* if((response[0] & 0xFE) != 0)
* Function Name : MSD_WriteByte {
* Description : Write a byte on the MSD. MSD_release_cs(msd->spi_device);
* Input : Data: byte to send. MSD_DEBUG("[err] It look 2nd CMD58 as illegal command so it is not SD card!\r\n");
* Output : None result = RT_ERROR;
* Return : None. goto _exit;
*******************************************************************************/ }
u8 MSD_WriteByte(u8 Data) MSD_release_cs(msd->spi_device);
{
/* Wait until the transmit buffer is empty */
while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_TXE) == RESET);
/* Send the byte */
SPI_I2S_SendData(MSD_SPI, Data);
/* Get the received data */ OCR = response[1];
Data = SPI_I2S_ReceiveData(MSD_SPI); OCR = (OCR<<8) + response[2];
OCR = (OCR<<8) + response[3];
OCR = (OCR<<8) + response[4];
MSD_DEBUG("[info] OCR 2nd read is 0x%08X\r\n", OCR);
return Data; if((OCR & 0x40000000) != 0)
} {
MSD_DEBUG("[info] It is SD2.0 SDHC Card!!!\r\n");
msd->card_type = MSD_CARD_TYPE_SD_SDHC;
}
else
{
MSD_DEBUG("[info] It is SD2.0 standard capacity Card!!!\r\n");
}
} /* MSD_CARD_TYPE_SD_V2_X */
else
{
MSD_DEBUG("[err] SD card type unkonw!\r\n");
result = RT_ERROR;
goto _exit;
}
} /* init SD card */
/******************************************************************************* if(msd->card_type == MSD_CARD_TYPE_SD_SDHC)
* Function Name : MSD_ReadByte {
* Description : Read a byte from the MSD. dev->read = rt_msd_sdhc_read;
* Input : None. dev->write = rt_msd_sdhc_write;
* Output : None }
* Return : The received byte. else
*******************************************************************************/ {
u8 MSD_ReadByte(void) dev->read = rt_msd_read;
{ dev->write = rt_msd_write;
u8 Data = 0; }
/* Wait until the transmit buffer is empty */ /* set CRC */
while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_TXE) == RESET); {
/* Send the byte */ MSD_release_cs(msd->spi_device);
SPI_I2S_SendData(MSD_SPI, DUMMY); MSD_take_cs(msd->spi_device);
#ifdef MSD_USE_CRC
result = _send_cmd(msd->spi_device, CRC_ON_OFF, 0x01, 0x83, response_r1, response);
#else
result = _send_cmd(msd->spi_device, CRC_ON_OFF, 0x00, 0x91, response_r1, response);
#endif
MSD_release_cs(msd->spi_device);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD59 CRC_ON_OFF fail! response : 0x%02X\r\n", response[0]);
result = RT_ERROR;
goto _exit;
}
} /* set CRC */
/* Wait until a data is received */ /* CMD16 SET_BLOCKLEN */
while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_RXNE) == RESET); {
/* Get the received data */ MSD_release_cs(msd->spi_device);
Data = SPI_I2S_ReceiveData(MSD_SPI); MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, SET_BLOCKLEN, SECTOR_SIZE, 0x00, response_r1, response);
MSD_release_cs(msd->spi_device);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD16 SET_BLOCKLEN fail! response : 0x%02X\r\n", response[0]);
result = RT_ERROR;
goto _exit;
}
msd->geometry.block_size = SECTOR_SIZE;
msd->geometry.bytes_per_sector = SECTOR_SIZE;
}
/* Return the shifted data */ /* read CSD */
return Data; {
} uint8_t CSD_buffer[MSD_CSD_LEN];
/******************************************************************************* MSD_take_cs(msd->spi_device);
* Function Name : SPI_Config // result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0xAF, response_r1, response);
* Description : Initializes the SPI and CS pins. result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0x00, response_r1, response);
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_Config(void)
{
uint32_t delay;
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* GPIOA and GPIOC Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
/* SPI Periph clock enable */
RCC_APB2PeriphClockCmd(MSD_RCC_SPI, ENABLE);
/* Configure SPI pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PA4 pin: CS pin, PC4 : SD Power */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* SPI Config */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(MSD_SPI, &SPI_InitStructure);
/* SPI enable */
SPI_Cmd(MSD_SPI, ENABLE);
/* active SD card */
GPIO_ResetBits(GPIOC, GPIO_Pin_4);
for (delay = 0; delay < 0xfffff; delay ++);
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ if(result != RT_EOK)
{
MSD_release_cs(msd->spi_device);
MSD_DEBUG("[err] CMD9 SEND_CSD timeout!\r\n");
goto _exit;
}
/* if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
* RT-Thread SD Card Driver {
* 2009-04-17 Bernard first version MSD_release_cs(msd->spi_device);
* 2010-07-15 Modify read/write according new block driver interface MSD_DEBUG("[err] CMD9 SEND_CSD fail! response : 0x%02X\r\n", response[0]);
*/ result = RT_ERROR;
#include <rtthread.h> goto _exit;
#include <dfs_fs.h> }
static struct rt_device sdcard_device; result = _read_block(msd->spi_device, CSD_buffer, MSD_CSD_LEN);
static struct dfs_partition part; MSD_release_cs(msd->spi_device);
if(result != RT_EOK)
{
MSD_DEBUG("[err] read CSD fail!\r\n");
goto _exit;
}
#define SECTOR_SIZE 512 /* Analyze CSD */
{
uint8_t CSD_STRUCTURE;
uint32_t C_SIZE;
uint32_t card_capacity;
/* RT-Thread Device Driver Interface */ uint8_t tmp8;
static rt_err_t rt_msd_init(rt_device_t dev) uint16_t tmp16;
{ uint32_t tmp32;
sMSD_CSD MSD_csd;
MSD_GetCSDRegister(&MSD_csd);
return RT_EOK; /* get CSD_STRUCTURE */
tmp8 = CSD_buffer[0] & 0xC0; /* 0b11000000 */
CSD_STRUCTURE = tmp8 >> 6;
/* MMC CSD Analyze. */
if(msd->card_type == MSD_CARD_TYPE_MMC)
{
uint8_t C_SIZE_MULT;
uint8_t READ_BL_LEN;
if(CSD_STRUCTURE > 2)
{
MSD_DEBUG("[err] bad CSD Version : %d\r\n", CSD_STRUCTURE);
result = RT_ERROR;
goto _exit;
}
if(CSD_STRUCTURE == 0)
{
MSD_DEBUG("[info] CSD version No. 1.0\r\n");
}
else if(CSD_STRUCTURE == 1)
{
MSD_DEBUG("[info] CSD version No. 1.1\r\n");
}
else if(CSD_STRUCTURE == 2)
{
MSD_DEBUG("[info] CSD version No. 1.2\r\n");
}
/* get TRAN_SPEED 8bit [103:96] */
tmp8 = CSD_buffer[3];
tmp8 &= 0x03; /* [2:0] transfer rate unit.*/
if(tmp8 == 0)
{
msd->max_clock = 100 * 1000; /* 0=100kbit/s. */
}
else if(tmp8 == 1)
{
msd->max_clock = 1 * 1000 * 1000; /* 1=1Mbit/s. */
}
else if(tmp8 == 2)
{
msd->max_clock = 10 * 1000 * 1000; /* 2=10Mbit/s. */
}
else if(tmp8 == 3)
{
msd->max_clock = 100 * 1000 * 1000; /* 3=100Mbit/s. */
}
if(tmp8 == 0)
{
MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dkbit/s.\r\n", tmp8, msd->max_clock/1000);
}
else
{
MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock/1000/1000);
}
/* get READ_BL_LEN 4bit [83:80] */
tmp8 = CSD_buffer[5] & 0x0F; /* 0b00001111; */
READ_BL_LEN = tmp8; /* 4 bit */
MSD_DEBUG("[info] CSD : READ_BL_LEN : %d %dbyte\r\n", READ_BL_LEN, (1 << READ_BL_LEN));
/* get C_SIZE 12bit [73:62] */
tmp16 = CSD_buffer[6] & 0x03; /* get [73:72] 0b00000011 */
tmp16 = tmp16<<8;
tmp16 += CSD_buffer[7]; /* get [71:64] */
tmp16 = tmp16<<2;
tmp8 = CSD_buffer[8] & 0xC0; /* get [63:62] 0b11000000 */
tmp8 = tmp8>>6;
tmp16 = tmp16 + tmp8;
C_SIZE = tmp16; //12 bit
MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE);
/* get C_SIZE_MULT 3bit [49:47] */
tmp8 = CSD_buffer[9] & 0x03;//0b00000011;
tmp8 = tmp8<<1;
tmp8 = tmp8 + ((CSD_buffer[10] & 0x80/*0b10000000*/)>>7);
C_SIZE_MULT = tmp8; // 3 bit
MSD_DEBUG("[info] CSD : C_SIZE_MULT : %d\r\n", C_SIZE_MULT);
/* memory capacity = BLOCKNR * BLOCK_LEN */
/* BLOCKNR = (C_SIZE+1) * MULT */
/* MULT = 2^(C_SIZE_MULT+2) */
/* BLOCK_LEN = 2^READ_BL_LEN */
card_capacity = (1 << READ_BL_LEN) * ((C_SIZE + 1) * (1 << (C_SIZE_MULT+2)));
msd->geometry.sector_count = card_capacity / msd->geometry.bytes_per_sector;
MSD_DEBUG("[info] card capacity : %d Mbyte\r\n", card_capacity/(1024*1024));
}
else /* SD CSD Analyze. */
{
if(CSD_STRUCTURE == 0)
{
uint8_t C_SIZE_MULT;
uint8_t READ_BL_LEN;
MSD_DEBUG("[info] CSD Version 1.0\r\n");
/* get TRAN_SPEED 8bit [103:96] */
tmp8 = CSD_buffer[3];
if(tmp8 == 0x32)
{
msd->max_clock = 1000 * 1000 * 10; /* 10Mbit/s. */
}
else if(tmp8 == 0x5A)
{
msd->max_clock = 1000 * 1000 * 50; /* 50Mbit/s. */
}
else
{
msd->max_clock = 1000 * 1000 * 1; /* 1Mbit/s default. */
}
MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock/1000/1000);
/* get READ_BL_LEN 4bit [83:80] */
tmp8 = CSD_buffer[5] & 0x0F; /* 0b00001111; */
READ_BL_LEN = tmp8; /* 4 bit */
MSD_DEBUG("[info] CSD : READ_BL_LEN : %d %dbyte\r\n", READ_BL_LEN, (1 << READ_BL_LEN));
/* get C_SIZE 12bit [73:62] */
tmp16 = CSD_buffer[6] & 0x03; /* get [73:72] 0b00000011 */
tmp16 = tmp16<<8;
tmp16 += CSD_buffer[7]; /* get [71:64] */
tmp16 = tmp16<<2;
tmp8 = CSD_buffer[8] & 0xC0; /* get [63:62] 0b11000000 */
tmp8 = tmp8>>6;
tmp16 = tmp16 + tmp8;
C_SIZE = tmp16; //12 bit
MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE);
/* get C_SIZE_MULT 3bit [49:47] */
tmp8 = CSD_buffer[9] & 0x03;//0b00000011;
tmp8 = tmp8<<1;
tmp8 = tmp8 + ((CSD_buffer[10] & 0x80/*0b10000000*/)>>7);
C_SIZE_MULT = tmp8; // 3 bit
MSD_DEBUG("[info] CSD : C_SIZE_MULT : %d\r\n", C_SIZE_MULT);
/* memory capacity = BLOCKNR * BLOCK_LEN */
/* BLOCKNR = (C_SIZE+1) * MULT */
/* MULT = 2^(C_SIZE_MULT+2) */
/* BLOCK_LEN = 2^READ_BL_LEN */
card_capacity = (1 << READ_BL_LEN) * ((C_SIZE + 1) * (1 << (C_SIZE_MULT+2)));
msd->geometry.sector_count = card_capacity / msd->geometry.bytes_per_sector;
MSD_DEBUG("[info] card capacity : %d Mbyte\r\n", card_capacity/(1024*1024));
}
else if(CSD_STRUCTURE == 1)
{
MSD_DEBUG("[info] CSD Version 2.0\r\n");
/* get TRAN_SPEED 8bit [103:96] */
tmp8 = CSD_buffer[3];
if(tmp8 == 0x32)
{
msd->max_clock = 1000 * 1000 * 10; /* 10Mbit/s. */
}
else if(tmp8 == 0x5A)
{
msd->max_clock = 1000 * 1000 * 50; /* 50Mbit/s. */
}
else if(tmp8 == 0x0B)
{
msd->max_clock = 1000 * 1000 * 100; /* 100Mbit/s. */
/* UHS50 Card sets TRAN_SPEED to 0Bh (100Mbit/sec), */
/* for both SDR50 and DDR50 modes. */
}
else if(tmp8 == 0x2B)
{
msd->max_clock = 1000 * 1000 * 200; /* 200Mbit/s. */
/* UHS104 Card sets TRAN_SPEED to 2Bh (200Mbit/sec). */
}
else
{
msd->max_clock = 1000 * 1000 * 1; /* 1Mbit/s default. */
}
MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock/1000/1000);
/* get C_SIZE 22bit [69:48] */
tmp32 = CSD_buffer[7] & 0x3F; /* 0b00111111 */
tmp32 = tmp32<<8;
tmp32 += CSD_buffer[8];
tmp32 = tmp32<<8;
tmp32 += CSD_buffer[9];
C_SIZE = tmp32;
MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE);
/* memory capacity = (C_SIZE+1) * 512K byte */
card_capacity = (C_SIZE + 1) / 2; /* unit : Mbyte */
msd->geometry.sector_count = card_capacity * 1024; /* 1 Mbyte = 512 byte X 2048 */
MSD_DEBUG("[info] card capacity : %d.%d Gbyte\r\n", card_capacity/1024, (card_capacity%1024)*100/1024);
}
else
{
MSD_DEBUG("[err] bad CSD Version : %d\r\n", CSD_STRUCTURE);
result = RT_ERROR;
goto _exit;
}
} /* SD CSD Analyze. */
} /* Analyze CSD */
} /* read CSD */
/* config spi to high speed */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */
cfg.max_hz = msd->max_clock;
rt_spi_configure(msd->spi_device, &cfg);
} /* config spi */
_exit:
MSD_release_cs(msd->spi_device);
rt_mutex_release(&(msd->spi_device->bus->lock));
return result;
} }
static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag) static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag)
{ {
// struct msd_device * msd = (struct msd_device *)dev;
return RT_EOK; return RT_EOK;
} }
static rt_err_t rt_msd_close(rt_device_t dev) static rt_err_t rt_msd_close(rt_device_t dev)
{ {
// struct msd_device * msd = (struct msd_device *)dev;
return RT_EOK; return RT_EOK;
} }
static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{ {
rt_uint8_t status; struct msd_device * msd = (struct msd_device *)dev;
rt_uint32_t i; uint8_t response[MSD_RESPONSE_MAX_LEN];
rt_err_t result = RT_EOK;
result = MSD_take_owner(msd->spi_device);
if (result != RT_EOK)
{
goto _exit;
}
status = MSD_RESPONSE_NO_ERROR; /* config spi to high speed */
// rt_kprintf("read: 0x%x, size %d\n", pos, size); {
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */
cfg.max_hz = msd->max_clock;
rt_spi_configure(msd->spi_device, &cfg);
} /* config spi */
/* SINGLE_BLOCK? */
if(size == 1)
{
MSD_take_cs(msd->spi_device);
/* read all sectors */ result = _send_cmd(msd->spi_device, READ_SINGLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response);
for (i = 0; i < size; i ++) if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{ {
status = MSD_ReadBlock((rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE), MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos);
(part.offset + pos + i)* SECTOR_SIZE, SECTOR_SIZE); size = 0;
if (status != MSD_RESPONSE_NO_ERROR) goto _exit;
}
result = _read_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector);
if(result != RT_EOK)
{ {
rt_kprintf("sd card read failed\n"); MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos);
return 0; size = 0;
} }
} }
else if(size > 1)
{
uint32_t i;
if (status == MSD_RESPONSE_NO_ERROR) return size; MSD_take_cs(msd->spi_device);
rt_kprintf("read failed: %d\n", status); result = _send_cmd(msd->spi_device, READ_MULTIPLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response);
return 0; if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos);
size = 0;
goto _exit;
}
for(i=0; i<size; i++)
{
result = _read_block(msd->spi_device,
(uint8_t *)buffer + msd->geometry.bytes_per_sector * i,
msd->geometry.bytes_per_sector);
if(result != RT_EOK)
{
MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos);
size = i;
break;
}
}
/* send CMD12 stop transfer */
result = _send_cmd(msd->spi_device, STOP_TRANSMISSION, 0x00, 0x00, response_r1b, response);
if(result != RT_EOK)
{
MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK, send stop token fail!\r\n");
}
} /* READ_MULTIPLE_BLOCK */
_exit:
/* release and exit */
MSD_release_cs(msd->spi_device);
rt_mutex_release(&(msd->spi_device->bus->lock));
return size;
} }
static rt_size_t rt_msd_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) static rt_size_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{ {
rt_uint8_t status; struct msd_device * msd = (struct msd_device *)dev;
rt_uint32_t i; uint8_t response[MSD_RESPONSE_MAX_LEN];
rt_err_t result = RT_EOK;
result = MSD_take_owner(msd->spi_device);
if (result != RT_EOK)
{
goto _exit;
}
/* config spi to high speed */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */
cfg.max_hz = msd->max_clock;
rt_spi_configure(msd->spi_device, &cfg);
} /* config spi */
/* SINGLE_BLOCK? */
if(size == 1)
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, READ_SINGLE_BLOCK, pos, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos);
size = 0;
goto _exit;
}
result = _read_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector);
if(result != RT_EOK)
{
MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos);
size = 0;
}
}
else if(size > 1)
{
uint32_t i;
MSD_take_cs(msd->spi_device);
status = MSD_RESPONSE_NO_ERROR; result = _send_cmd(msd->spi_device, READ_MULTIPLE_BLOCK, pos, 0x00, response_r1, response);
// rt_kprintf("write: 0x%x, size %d\n", pos, size); if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos);
size = 0;
goto _exit;
}
/* write all sectors */ for(i=0; i<size; i++)
for (i = 0; i < size; i ++)
{ {
status = MSD_WriteBuffer((rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE), result = _read_block(msd->spi_device,
(part.offset + pos + i)* SECTOR_SIZE, SECTOR_SIZE); (uint8_t *)buffer + msd->geometry.bytes_per_sector * i,
if (status != MSD_RESPONSE_NO_ERROR) msd->geometry.bytes_per_sector);
if(result != RT_EOK)
{ {
rt_kprintf("sd card write failed\n"); MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos);
return 0; size = i;
break;
}
} }
/* send CMD12 stop transfer */
result = _send_cmd(msd->spi_device, STOP_TRANSMISSION, 0x00, 0x00, response_r1b, response);
if(result != RT_EOK)
{
MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK, send stop token fail!\r\n");
} }
} /* READ_MULTIPLE_BLOCK */
if (status == MSD_RESPONSE_NO_ERROR) return size; _exit:
/* release and exit */
MSD_release_cs(msd->spi_device);
rt_mutex_release(&(msd->spi_device->bus->lock));
rt_kprintf("write failed: %d\n", status); return size;
return 0;
} }
static rt_err_t rt_msd_control(rt_device_t dev, rt_uint8_t cmd, void *args) static rt_size_t rt_msd_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{ {
RT_ASSERT(dev != RT_NULL); struct msd_device * msd = (struct msd_device *)dev;
uint8_t response[MSD_RESPONSE_MAX_LEN];
rt_err_t result;
return RT_EOK; result = MSD_take_owner(msd->spi_device);
if (result != RT_EOK)
{
MSD_DEBUG("[err] get SPI owner fail!\r\n");
goto _exit;
}
/* config spi to high speed */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */
cfg.max_hz = msd->max_clock;
rt_spi_configure(msd->spi_device, &cfg);
} /* config spi */
/* SINGLE_BLOCK? */
if(size == 1)
{
MSD_take_cs(msd->spi_device);
result = _send_cmd(msd->spi_device, WRITE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD WRITE_BLOCK fail!\r\n");
size = 0;
goto _exit;
}
result = _write_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector, MSD_TOKEN_WRITE_SINGLE_START);
if(result != RT_EOK)
{
MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos);
size = 0;
}
}
else if(size > 1)
{
struct rt_spi_message message;
uint32_t i;
MSD_take_cs(msd->spi_device);
#ifdef MSD_USE_PRE_ERASED
if(msd->card_type != MSD_CARD_TYPE_MMC)
{
/* CMD55 APP_CMD */
result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD55 APP_CMD fail!\r\n");
size = 0;
goto _exit;
}
/* ACMD23 Pre-erased */
result = _send_cmd(msd->spi_device, SET_WR_BLK_ERASE_COUNT, size, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] ACMD23 SET_BLOCK_COUNT fail!\r\n");
size = 0;
goto _exit;
}
}
#endif
result = _send_cmd(msd->spi_device, WRITE_MULTIPLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD WRITE_MULTIPLE_BLOCK fail!\r\n");
size = 0;
goto _exit;
}
/* write all block */
for(i=0; i<size; i++)
{
result = _write_block(msd->spi_device,
(const uint8_t *)buffer + msd->geometry.bytes_per_sector * i,
msd->geometry.bytes_per_sector,
MSD_TOKEN_WRITE_MULTIPLE_START);
if(result != RT_EOK)
{
MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos);
size = i;
break;
}
} /* write all block */
/* send stop token */
{
uint8_t send_buffer[18];
rt_memset(send_buffer, DUMMY, sizeof(send_buffer));
send_buffer[sizeof(send_buffer) - 1] = MSD_TOKEN_WRITE_MULTIPLE_STOP;
/* initial message */
message.send_buf = send_buffer;
message.recv_buf = RT_NULL;
message.length = sizeof(send_buffer);
message.cs_take = message.cs_release = 0;
/* transfer message */
msd->spi_device->bus->ops->xfer(msd->spi_device, &message);
}
/* wait ready */
result = _wait_ready(msd->spi_device);
if(result != RT_EOK)
{
MSD_DEBUG("[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!\r\n");
}
} /* size > 1 */
_exit:
/* release and exit */
MSD_release_cs(msd->spi_device);
rt_mutex_release(&(msd->spi_device->bus->lock));
return size;
} }
void rt_hw_msd_init() static rt_size_t rt_msd_sdhc_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{ {
if (MSD_Init() == MSD_RESPONSE_NO_ERROR) struct msd_device * msd = (struct msd_device *)dev;
uint8_t response[MSD_RESPONSE_MAX_LEN];
rt_err_t result;
result = MSD_take_owner(msd->spi_device);
if (result != RT_EOK)
{ {
rt_uint8_t status; goto _exit;
rt_uint8_t *sector; }
/* register sdcard device */ /* config spi to high speed */
sdcard_device.init = rt_msd_init; {
sdcard_device.open = rt_msd_open; struct rt_spi_configuration cfg;
sdcard_device.close = rt_msd_close; cfg.data_width = 8;
sdcard_device.read = rt_msd_read; cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */
sdcard_device.write = rt_msd_write; cfg.max_hz = msd->max_clock;
sdcard_device.control = rt_msd_control;
rt_spi_configure(msd->spi_device, &cfg);
} /* config spi */
/* no private */ /* SINGLE_BLOCK? */
sdcard_device.user_data = RT_NULL; if(size == 1)
/* get the first sector to read partition table */
sector = (rt_uint8_t*) rt_malloc (512);
if (sector == RT_NULL)
{ {
rt_kprintf("allocate partition sector buffer failed\n"); MSD_take_cs(msd->spi_device);
return; result = _send_cmd(msd->spi_device, WRITE_BLOCK, pos, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD WRITE_BLOCK fail!\r\n");
size = 0;
goto _exit;
} }
status = MSD_ReadBlock(sector, 0, 512); result = _write_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector, MSD_TOKEN_WRITE_SINGLE_START);
if (status == MSD_RESPONSE_NO_ERROR) if(result != RT_EOK)
{ {
/* get the first partition */ MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos);
status = dfs_filesystem_get_partition(&part, sector, 0); size = 0;
if (status != RT_EOK) }
}
else if(size > 1)
{ {
/* there is no partition table */ struct rt_spi_message message;
part.offset = 0; uint32_t i;
part.size = 0;
MSD_take_cs(msd->spi_device);
#ifdef MSD_USE_PRE_ERASED
/* CMD55 APP_CMD */
result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] CMD55 APP_CMD fail!\r\n");
size = 0;
goto _exit;
} }
/* ACMD23 Pre-erased */
result = _send_cmd(msd->spi_device, SET_WR_BLK_ERASE_COUNT, size, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{
MSD_DEBUG("[err] ACMD23 SET_BLOCK_COUNT fail!\r\n");
size = 0;
goto _exit;
} }
else #endif
result = _send_cmd(msd->spi_device, WRITE_MULTIPLE_BLOCK, pos, 0x00, response_r1, response);
if((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR))
{ {
/* there is no partition table */ MSD_DEBUG("[err] CMD WRITE_MULTIPLE_BLOCK fail!\r\n");
part.offset = 0; size = 0;
part.size = 0; goto _exit;
} }
/* release sector buffer */ /* write all block */
rt_free(sector); for(i=0; i<size; i++)
{
result = _write_block(msd->spi_device,
(const uint8_t *)buffer + msd->geometry.bytes_per_sector * i,
msd->geometry.bytes_per_sector,
MSD_TOKEN_WRITE_MULTIPLE_START);
if(result != RT_EOK)
{
MSD_DEBUG("[err] write MULTIPLE_BLOCK #%d fail!\r\n", pos);
size = i;
break;
}
} /* write all block */
rt_device_register(&sdcard_device, "sd0", /* send stop token */
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); {
uint8_t send_buffer[18];
rt_memset(send_buffer, DUMMY, sizeof(send_buffer));
send_buffer[sizeof(send_buffer) - 1] = MSD_TOKEN_WRITE_MULTIPLE_STOP;
/* initial message */
message.send_buf = send_buffer;
message.recv_buf = RT_NULL;
message.length = sizeof(send_buffer);
message.cs_take = message.cs_release = 0;
/* transfer message */
msd->spi_device->bus->ops->xfer(msd->spi_device, &message);
} }
else
result = _wait_ready(msd->spi_device);
if(result != RT_EOK)
{
MSD_DEBUG("[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!\r\n");
}
} /* size > 1 */
_exit:
/* release and exit */
MSD_release_cs(msd->spi_device);
rt_mutex_release(&(msd->spi_device->bus->lock));
return size;
}
static rt_err_t rt_msd_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
struct msd_device * msd = (struct msd_device *)dev;
RT_ASSERT(dev != RT_NULL);
if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
{ {
rt_kprintf("sdcard init failed\n"); struct rt_device_blk_geometry *geometry;
geometry = (struct rt_device_blk_geometry *)args;
if (geometry == RT_NULL) return -RT_ERROR;
geometry->bytes_per_sector = msd->geometry.bytes_per_sector;
geometry->block_size = msd->geometry.block_size;
geometry->sector_count = msd->geometry.sector_count;
} }
return RT_EOK;
}
rt_err_t msd_init(const char * sd_device_name, const char * spi_device_name)
{
rt_err_t result = RT_EOK;
struct rt_spi_device * spi_device;
spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
if(spi_device == RT_NULL)
{
MSD_DEBUG("spi device %s not found!\r\n", spi_device_name);
return -RT_ENOSYS;
}
rt_memset(&_msd_device, 0, sizeof(_msd_device));
_msd_device.spi_device = spi_device;
/* register sdcard device */
_msd_device.parent.type = RT_Device_Class_Block;
_msd_device.geometry.bytes_per_sector = 0;
_msd_device.geometry.sector_count = 0;
_msd_device.geometry.block_size = 0;
_msd_device.parent.init = rt_msd_init;
_msd_device.parent.open = rt_msd_open;
_msd_device.parent.close = rt_msd_close;
_msd_device.parent.read = RT_NULL;
_msd_device.parent.write = RT_NULL;
_msd_device.parent.control = rt_msd_control;
/* no private, no callback */
_msd_device.parent.user_data = RT_NULL;
_msd_device.parent.rx_indicate = RT_NULL;
_msd_device.parent.tx_complete = RT_NULL;
result = rt_device_register(&_msd_device.parent, sd_device_name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
return result;
} }
/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** /*
* File Name : msd.h * File : msd.h
* Author : MCD Application Team * SPI mode SD Card Driver
* Version : V2.1 * This file is part of RT-Thread RTOS
* Date : 05/30/2008 * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
* Description : Header for msd.c file. *
******************************************************************************** * The license and distribution terms for this file may be
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * found in the file LICENSE in this distribution or at
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. * http://www.rt-thread.org/license/LICENSE
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, *
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * Change Logs:
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * Date Author Notes
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * 2009-04-17 Bernard first version.
* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED */
* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*******************************************************************************/ #ifndef MSD_H_INCLUDED
#define MSD_H_INCLUDED
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MSD_H #include <stdint.h>
#define __MSD_H #include <drivers/spi.h>
/* Includes ------------------------------------------------------------------*/ /* SD command (SPI mode) */
#include <stm32f10x.h> #define GO_IDLE_STATE 0 /* CMD0 R1 */
#define SEND_OP_COND 1 /* CMD1 R1 */
/* Private define ------------------------------------------------------------*/ #define SWITCH_FUNC 6 /* CMD6 R1 */
/* Block Size */ #define SEND_IF_COND 8 /* CMD8 R7 */
#define BLOCK_SIZE 512 #define SEND_CSD 9 /* CMD9 R1 */
#define SEND_CID 10 /* CMD10 R1 */
/* Dummy byte */ #define STOP_TRANSMISSION 12 /* CMD12 R1B */
#define DUMMY 0xFF #define SEND_STATUS 13 /* CMD13 R2 */
#define SET_BLOCKLEN 16 /* CMD16 R1 */
#define READ_SINGLE_BLOCK 17 /* CMD17 R1 */
#define READ_MULTIPLE_BLOCK 18 /* CMD18 R1 */
#define WRITE_BLOCK 24 /* CMD24 R1 */
#define WRITE_MULTIPLE_BLOCK 25 /* CMD25 R1 */
#define PROGRAM_CSD 27 /* CMD27 R1 */
#define SET_WRITE_PROT 28 /* CMD28 R1B */
#define CLR_WRITE_PROT 29 /* CMD29 R1B */
#define SEND_WRITE_PROT 30 /* CMD30 R1 */
#define ERASE_WR_BLK_START_ADDR 32 /* CMD32 R1 */
#define ERASE_WR_BLK_END_ADDR 33 /* CMD33 R1 */
#define ERASE 38 /* CMD38 R1B */
#define LOCK_UNLOCK 42 /* CMD42 R1 */
#define APP_CMD 55 /* CMD55 R1 */
#define GEN_CMD 56 /* CMD56 R1 */
#define READ_OCR 58 /* CMD58 R3 */
#define CRC_ON_OFF 59 /* CMD59 R1 */
/* Application-Specific Command */
#define SD_STATUS 13 /* ACMD13 R2 */
#define SEND_NUM_WR_BLOCKS 22 /* ACMD22 R1 */
#define SET_WR_BLK_ERASE_COUNT 23 /* ACMD23 R1 */
#define SD_SEND_OP_COND 41 /* ACMD41 R1 */
#define SET_CLR_CARD_DETECT 42 /* ACMD42 R1 */
#define SEND_SCR 51 /* ACMD51 R1 */
/* Start Data tokens */ /* Start Data tokens */
/* Tokens (necessary because at nop/idle (and CS active) only 0xff is on the data/command line) */ /* Tokens (necessary because at nop/idle (and CS active) only 0xff is on the data/command line) */
#define MSD_START_DATA_SINGLE_BLOCK_READ 0xFE /* Data token start byte, Start Single Block Read */ #define MSD_TOKEN_READ_START 0xFE /* Data token start byte, Start Single Block Read */
#define MSD_START_DATA_MULTIPLE_BLOCK_READ 0xFE /* Data token start byte, Start Multiple Block Read */ #define MSD_TOKEN_WRITE_SINGLE_START 0xFE /* Data token start byte, Start Single Block Write */
#define MSD_START_DATA_SINGLE_BLOCK_WRITE 0xFE /* Data token start byte, Start Single Block Write */
#define MSD_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD /* Data token start byte, Start Multiple Block Write */
#define MSD_STOP_DATA_MULTIPLE_BLOCK_WRITE 0xFD /* Data toke stop byte, Stop Multiple Block Write */
/* MSD functions return */ #define MSD_TOKEN_WRITE_MULTIPLE_START 0xFC /* Data token start byte, Start Multiple Block Write */
#define MSD_SUCCESS 0x00 #define MSD_TOKEN_WRITE_MULTIPLE_STOP 0xFD /* Data toke stop byte, Stop Multiple Block Write */
#define MSD_FAIL 0xFF
/* MSD reponses and error flags */ /* MSD reponses and error flags */
#define MSD_RESPONSE_NO_ERROR 0x00 #define MSD_RESPONSE_NO_ERROR 0x00
...@@ -57,117 +78,55 @@ ...@@ -57,117 +78,55 @@
#define MSD_DATA_CRC_ERROR 0x0B #define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D #define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF #define MSD_DATA_OTHER_ERROR 0xFF
#define MSD_DATA_RESPONSE_MASK 0x1F
#define MSD_GET_DATA_RESPONSE(res) (res & MSD_DATA_RESPONSE_MASK)
/* Commands: CMDxx = CMD-number | 0x40 */ #define MSD_CMD_LEN 6 /**< command, arg and crc. */
#define MSD_GO_IDLE_STATE 0 /* CMD0=0x40 */ #define MSD_RESPONSE_MAX_LEN 5 /**< response max len */
#define MSD_SEND_OP_COND 1 /* CMD1=0x41 */ #define MSD_CSD_LEN 16 /**< SD crad CSD register len */
#define MSD_SEND_CSD 9 /* CMD9=0x49 */ #define SECTOR_SIZE 512 /**< sector size, default 512byte */
#define MSD_SEND_CID 10 /* CMD10=0x4A */
#define MSD_STOP_TRANSMISSION 12 /* CMD12=0x4C */ /* card try timeout, unit: ms */
#define MSD_SEND_STATUS 13 /* CMD13=0x4D */ #define CARD_TRY_TIMES 3000
#define MSD_SET_BLOCKLEN 16 /* CMD16=0x50 */ #define CARD_TRY_TIMES_ACMD41 800
#define MSD_READ_SINGLE_BLOCK 17 /* CMD17=0x51 */ #define CARD_WAIT_TOKEN_TIMES 800
#define MSD_READ_MULTIPLE_BLOCK 18 /* CMD18=0x52 */
#define MSD_SET_BLOCK_COUNT 23 /* CMD23=0x57 */ #define MSD_USE_PRE_ERASED /**< id define MSD_USE_PRE_ERASED, before CMD25, send ACMD23 */
#define MSD_WRITE_BLOCK 24 /* CMD24=0x58 */
#define MSD_WRITE_MULTIPLE_BLOCK 25 /* CMD25=0x59 */ /**
#define MSD_PROGRAM_CSD 27 /* CMD27=0x5B */ * SD/MMC card type
#define MSD_SET_WRITE_PROT 28 /* CMD28=0x5C */ */
#define MSD_CLR_WRITE_PROT 29 /* CMD29=0x5D */ typedef enum
#define MSD_SEND_WRITE_PROT 30 /* CMD30=0x5E */
#define MSD_TAG_SECTOR_START 32 /* CMD32=0x60 */
#define MSD_TAG_SECTOR_END 33 /* CMD33=0x61 */
#define MSD_UNTAG_SECTOR 34 /* CMD34=0x62 */
#define MSD_TAG_ERASE_GROUP_START 35 /* CMD35=0x63 */
#define MSD_TAG_ERASE_GROUP_END 36 /* CMD36=0x64 */
#define MSD_UNTAG_ERASE_GROUP 37 /* CMD37=0x65 */
#define MSD_ERASE 38 /* CMD38=0x66 */
#define MSD_READ_OCR 39 /* CMD39=0x67 */
#define MSD_CRC_ON_OFF 40 /* CMD40=0x68 */
/* Exported types ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
typedef struct _MSD_CSD /*Card Specific Data*/
{ {
vu8 CSDStruct; /* CSD structure */ MSD_CARD_TYPE_UNKNOWN = 0, /**< unknown */
vu8 SysSpecVersion; /* System specification version */ MSD_CARD_TYPE_MMC, /**< MultiMedia Card */
vu8 Reserved1; /* Reserved */ MSD_CARD_TYPE_SD_V1_X, /**< Ver 1.X Standard Capacity SD Memory Card */
vu8 TAAC; /* Data read access-time 1 */ MSD_CARD_TYPE_SD_V2_X, /**< Ver 2.00 or later Standard Capacity SD Memory Card */
vu8 NSAC; /* Data read access-time 2 in CLK cycles */ MSD_CARD_TYPE_SD_SDHC, /**< High Capacity SD Memory Card */
vu8 MaxBusClkFrec; /* Max. bus clock frequency */ MSD_CARD_TYPE_SD_SDXC, /**< later Extended Capacity SD Memory Card */
vu16 CardComdClasses; /* Card command classes */ }msd_card_type;
vu8 RdBlockLen; /* Max. read data block length */
vu8 PartBlockRead; /* Partial blocks for read allowed */ typedef enum
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 msd_CRC; /* CRC */
vu8 Reserved4; /* always 1*/
}
sMSD_CSD;
typedef struct _MSD_CID /*Card Identification Data*/
{ {
vu8 ManufacturerID; /* ManufacturerID */ response_type_unknown = 0,
vu16 OEM_AppliID; /* OEM/Application ID */ response_r1,
vu32 ProdName1; /* Product Name part1 */ response_r1b,
vu8 ProdName2; /* Product Name part2*/ response_r2,
vu8 ProdRev; /* Product Revision */ response_r3,
vu32 ProdSN; /* Product Serial Number */ response_r4,
vu8 Reserved1; /* Reserved1 */ response_r5,
vu16 ManufactDate; /* Manufacturing Date */ response_r7,
vu8 msd_CRC; /* CRC */ }response_type;
vu8 Reserved2; /* always 1*/
} struct msd_device
sMSD_CID; {
struct rt_device parent; /**< RT-Thread device struct */
/* Exported constants --------------------------------------------------------*/ struct rt_device_blk_geometry geometry; /**< sector size, sector count */
/* Exported macro ------------------------------------------------------------*/ struct rt_spi_device * spi_device; /**< SPI interface */
/* Exported functions ------------------------------------------------------- */ msd_card_type card_type; /**< card type: MMC SD1.x SD2.0 SDHC SDXC */
uint32_t max_clock; /**< MAX SPI clock */
/*----- High layer function -----*/ };
u8 MSD_Init(void);
u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite); extern rt_err_t msd_init(const char * sd_device_name, const char * spi_device_name);
u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite); #endif // MSD_H_INCLUDED
u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead);
u8 MSD_GetCSDRegister(sMSD_CSD* MSD_csd);
u8 MSD_GetCIDRegister(sMSD_CID* MSD_cid);
/*----- Medium layer function -----*/
void MSD_SendCmd(u8 Cmd, u32 Arg, u8 Crc);
u8 MSD_GetResponse(u8 Response);
u8 MSD_GetDataResponse(void);
u8 MSD_GoIdleState(void);
u16 MSD_GetStatus(void);
/*----- Low layer function -----*/
u8 MSD_WriteByte(u8 byte);
u8 MSD_ReadByte(void);
#endif /* __MSD_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
...@@ -5,18 +5,98 @@ ...@@ -5,18 +5,98 @@
#include "stm32_eth.h" #include "stm32_eth.h"
#endif /* RT_USING_LWIP */ #endif /* RT_USING_LWIP */
#ifdef RT_USING_SPI
#include "rt_stm32f10x_spi.h"
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
#include "msd.h"
#endif /* RT_USING_DFS */
/*
* SPI1_MOSI: PA7
* SPI1_MISO: PA6
* SPI1_SCK : PA5
*
* CS0: PA4 SD card.
*/
static void rt_hw_spi_init(void)
{
#ifdef RT_USING_SPI1
/* register spi bus */
{
static struct stm32_spi_bus stm32_spi;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,
ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
stm32_spi_register(SPI1, &stm32_spi, "spi1");
}
/* attach cs */
{
static struct rt_spi_device spi_device;
static struct stm32_spi_cs spi_cs;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/* spi21: PG10 */
spi_cs.GPIOx = GPIOA;
spi_cs.GPIO_Pin = GPIO_Pin_4;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = spi_cs.GPIO_Pin;
GPIO_SetBits(spi_cs.GPIOx, spi_cs.GPIO_Pin);
GPIO_Init(spi_cs.GPIOx, &GPIO_InitStructure);
rt_spi_bus_attach_device(&spi_device, "spi10", "spi1", (void*)&spi_cs);
}
#endif /* RT_USING_SPI1 */
}
#endif /* RT_USING_SPI */
void rt_platform_init(void) void rt_platform_init(void)
{ {
#ifdef RT_USING_LWIP #ifdef RT_USING_SPI
/* initialize eth interface */ rt_hw_spi_init();
rt_hw_stm32_eth_init();
#endif /* RT_USING_LWIP */
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT) #if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
/* init sdcard driver */ /* init sdcard driver */
{ {
extern void rt_hw_msd_init(void); extern void rt_hw_msd_init(void);
rt_hw_msd_init(); GPIO_InitTypeDef GPIO_InitStructure;
/* PC4 : SD Power */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* SD card power on. */
GPIO_ResetBits(GPIOC, GPIO_Pin_4);
rt_thread_delay(2);
msd_init("sd0", "spi10");
} }
#endif /* RT_USING_DFS && RT_USING_DFS_ELMFAT */ #endif /* RT_USING_DFS && RT_USING_DFS_ELMFAT */
#endif // RT_USING_SPI
#ifdef RT_USING_LWIP
/* initialize eth interface */
rt_hw_stm32_eth_init();
#endif /* RT_USING_LWIP */
} }
#include "rt_stm32f10x_spi.h"
static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message);
static struct rt_spi_ops stm32_spi_ops =
{
configure,
xfer
};
#ifdef USING_SPI1
static struct stm32_spi_bus stm32_spi_bus_1;
#endif /* #ifdef USING_SPI1 */
#ifdef USING_SPI2
static struct stm32_spi_bus stm32_spi_bus_2;
#endif /* #ifdef USING_SPI2 */
#ifdef USING_SPI3
static struct stm32_spi_bus stm32_spi_bus_3;
#endif /* #ifdef USING_SPI3 */
//------------------ DMA ------------------
#ifdef SPI_USE_DMA
static uint8_t dummy = 0xFF;
#endif
#ifdef SPI_USE_DMA
static void DMA_Configuration(struct stm32_spi_bus * stm32_spi_bus, const void * send_addr, void * recv_addr, rt_size_t size)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_ClearFlag(stm32_spi_bus->DMA_Channel_RX_FLAG_TC
| stm32_spi_bus->DMA_Channel_RX_FLAG_TE
| stm32_spi_bus->DMA_Channel_TX_FLAG_TC
| stm32_spi_bus->DMA_Channel_TX_FLAG_TE);
/* RX channel configuration */
DMA_Cmd(stm32_spi_bus->DMA_Channel_RX, DISABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(stm32_spi_bus->SPI->DR));
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_BufferSize = size;
if(recv_addr != RT_NULL)
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) recv_addr;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
}
else
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) (&dummy);
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
}
DMA_Init(stm32_spi_bus->DMA_Channel_RX, &DMA_InitStructure);
DMA_Cmd(stm32_spi_bus->DMA_Channel_RX, ENABLE);
/* TX channel configuration */
DMA_Cmd(stm32_spi_bus->DMA_Channel_TX, DISABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(stm32_spi_bus->SPI->DR));
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_BufferSize = size;
if(send_addr != RT_NULL)
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)send_addr;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
}
else
{
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(&dummy);;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
}
DMA_Init(stm32_spi_bus->DMA_Channel_TX, &DMA_InitStructure);
DMA_Cmd(stm32_spi_bus->DMA_Channel_TX, ENABLE);
}
#endif
rt_inline uint16_t get_spi_BaudRatePrescaler(rt_uint32_t max_hz)
{
uint16_t SPI_BaudRatePrescaler;
/* STM32F10x SPI MAX 18Mhz */
if(max_hz >= SystemCoreClock/2 && SystemCoreClock/2 <= 18000000)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
}
else if(max_hz >= SystemCoreClock/4)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
}
else if(max_hz >= SystemCoreClock/8)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
}
else if(max_hz >= SystemCoreClock/16)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
}
else if(max_hz >= SystemCoreClock/32)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
}
else if(max_hz >= SystemCoreClock/64)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
}
else if(max_hz >= SystemCoreClock/128)
{
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
}
else
{
/* min prescaler 256 */
SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
}
return SPI_BaudRatePrescaler;
}
static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration)
{
struct stm32_spi_bus * stm32_spi_bus = (struct stm32_spi_bus *)device->bus;
SPI_InitTypeDef SPI_InitStructure;
SPI_StructInit(&SPI_InitStructure);
/* data_width */
if(configuration->data_width <= 8)
{
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
}
else if(configuration->data_width <= 16)
{
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
}
else
{
return RT_EIO;
}
/* baudrate */
SPI_InitStructure.SPI_BaudRatePrescaler = get_spi_BaudRatePrescaler(configuration->max_hz);
/* CPOL */
if(configuration->mode & RT_SPI_CPOL)
{
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
}
else
{
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
}
/* CPHA */
if(configuration->mode & RT_SPI_CPHA)
{
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
}
else
{
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
}
/* MSB or LSB */
if(configuration->mode & RT_SPI_MSB)
{
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
}
else
{
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
}
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
/* init SPI */
SPI_I2S_DeInit(stm32_spi_bus->SPI);
SPI_Init(stm32_spi_bus->SPI, &SPI_InitStructure);
/* Enable SPI_MASTER */
SPI_Cmd(stm32_spi_bus->SPI, ENABLE);
SPI_CalculateCRC(stm32_spi_bus->SPI, DISABLE);
return RT_EOK;
};
static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message)
{
struct stm32_spi_bus * stm32_spi_bus = (struct stm32_spi_bus *)device->bus;
struct rt_spi_configuration * config = &device->config;
SPI_TypeDef * SPI = stm32_spi_bus->SPI;
struct stm32_spi_cs * stm32_spi_cs = device->parent.user_data;
rt_uint32_t size = message->length;
/* take CS */
if(message->cs_take)
{
GPIO_ResetBits(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin);
}
#ifdef SPI_USE_DMA
if(message->length > 32)
{
if(config->data_width <= 8)
{
DMA_Configuration(stm32_spi_bus, message->send_buf, message->recv_buf, message->length);
SPI_I2S_DMACmd(SPI, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);
while (DMA_GetFlagStatus(stm32_spi_bus->DMA_Channel_RX_FLAG_TC) == RESET
|| DMA_GetFlagStatus(stm32_spi_bus->DMA_Channel_TX_FLAG_TC) == RESET);
SPI_I2S_DMACmd(SPI, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE);
}
// rt_memcpy(buffer,_spi_flash_buffer,DMA_BUFFER_SIZE);
// buffer += DMA_BUFFER_SIZE;
}
else
#endif
{
if(config->data_width <= 8)
{
const rt_uint8_t * send_ptr = message->send_buf;
rt_uint8_t * recv_ptr = message->recv_buf;
while(size--)
{
rt_uint8_t data = 0xFF;
if(send_ptr != RT_NULL)
{
data = *send_ptr++;
}
//Wait until the transmit buffer is empty
while (SPI_I2S_GetFlagStatus(SPI, SPI_I2S_FLAG_TXE) == RESET);
// Send the byte
SPI_I2S_SendData(SPI, data);
//Wait until a data is received
while (SPI_I2S_GetFlagStatus(SPI, SPI_I2S_FLAG_RXNE) == RESET);
// Get the received data
data = SPI_I2S_ReceiveData(SPI);
if(recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
}
else if(config->data_width <= 16)
{
const rt_uint16_t * send_ptr = message->send_buf;
rt_uint16_t * recv_ptr = message->recv_buf;
while(size--)
{
rt_uint16_t data = 0xFF;
if(send_ptr != RT_NULL)
{
data = *send_ptr++;
}
//Wait until the transmit buffer is empty
while (SPI_I2S_GetFlagStatus(SPI, SPI_I2S_FLAG_TXE) == RESET);
// Send the byte
SPI_I2S_SendData(SPI, data);
//Wait until a data is received
while (SPI_I2S_GetFlagStatus(SPI, SPI_I2S_FLAG_RXNE) == RESET);
// Get the received data
data = SPI_I2S_ReceiveData(SPI);
if(recv_ptr != RT_NULL)
{
*recv_ptr++ = data;
}
}
}
}
/* release CS */
if(message->cs_release)
{
GPIO_SetBits(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin);
}
return message->length;
};
/** \brief init and register stm32 spi bus.
*
* \param SPI: STM32 SPI, e.g: SPI1,SPI2,SPI3.
* \param stm32_spi: stm32 spi bus struct.
* \param spi_bus_name: spi bus name, e.g: "spi1"
* \return
*
*/
rt_err_t stm32_spi_register(SPI_TypeDef * SPI,
struct stm32_spi_bus * stm32_spi,
const char * spi_bus_name)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
if(SPI == SPI1)
{
stm32_spi->SPI = SPI1;
#ifdef SPI_USE_DMA
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
stm32_spi->DMA_Channel_RX = DMA1_Channel2;
stm32_spi->DMA_Channel_TX = DMA1_Channel3;
stm32_spi->DMA_Channel_RX_FLAG_TC = DMA1_FLAG_TC2;
stm32_spi->DMA_Channel_RX_FLAG_TE = DMA1_FLAG_TE2;
stm32_spi->DMA_Channel_TX_FLAG_TC = DMA1_FLAG_TC3;
stm32_spi->DMA_Channel_TX_FLAG_TE = DMA1_FLAG_TE3;
#endif
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
}
else if(SPI == SPI2)
{
stm32_spi->SPI = SPI2;
#ifdef SPI_USE_DMA
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
stm32_spi->DMA_Channel_RX = DMA1_Channel4;
stm32_spi->DMA_Channel_TX = DMA1_Channel5;
stm32_spi->DMA_Channel_RX_FLAG_TC = DMA1_FLAG_TC4;
stm32_spi->DMA_Channel_RX_FLAG_TE = DMA1_FLAG_TE4;
stm32_spi->DMA_Channel_TX_FLAG_TC = DMA1_FLAG_TC5;
stm32_spi->DMA_Channel_TX_FLAG_TE = DMA1_FLAG_TE5;
#endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
}
else if(SPI == SPI3)
{
stm32_spi->SPI = SPI3;
#ifdef SPI_USE_DMA
/* Enable the DMA2 Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
stm32_spi->DMA_Channel_RX = DMA2_Channel1;
stm32_spi->DMA_Channel_TX = DMA2_Channel2;
stm32_spi->DMA_Channel_RX_FLAG_TC = DMA2_FLAG_TC1;
stm32_spi->DMA_Channel_RX_FLAG_TE = DMA2_FLAG_TE1;
stm32_spi->DMA_Channel_TX_FLAG_TC = DMA2_FLAG_TC2;
stm32_spi->DMA_Channel_TX_FLAG_TE = DMA2_FLAG_TE2;
#endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
}
else
{
return RT_ENOSYS;
}
return rt_spi_bus_register(&stm32_spi->parent, spi_bus_name, &stm32_spi_ops);
}
#ifndef STM32_SPI_H_INCLUDED
#define STM32_SPI_H_INCLUDED
#include <rtdevice.h>
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
#include "board.h"
//#define SPI_USE_DMA
struct stm32_spi_bus
{
struct rt_spi_bus parent;
SPI_TypeDef * SPI;
#ifdef SPI_USE_DMA
DMA_Channel_TypeDef * DMA_Channel_TX;
DMA_Channel_TypeDef * DMA_Channel_RX;
uint32_t DMA_Channel_TX_FLAG_TC;
uint32_t DMA_Channel_TX_FLAG_TE;
uint32_t DMA_Channel_RX_FLAG_TC;
uint32_t DMA_Channel_RX_FLAG_TE;
#endif /* SPI_USE_DMA */
};
struct stm32_spi_cs
{
GPIO_TypeDef * GPIOx;
uint16_t GPIO_Pin;
};
/* public function list */
rt_err_t stm32_spi_register(SPI_TypeDef * SPI,
struct stm32_spi_bus * stm32_spi,
const char * spi_bus_name);
#endif // STM32_SPI_H_INCLUDED
...@@ -107,12 +107,6 @@ void DebugMon_Handler(void) ...@@ -107,12 +107,6 @@ void DebugMon_Handler(void)
{ {
} }
void SysTick_Handler(void)
{
extern void rt_hw_timer_handler(void);
rt_hw_timer_handler();
}
/******************************************************************************/ /******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */ /* STM32F10x Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode * 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode
*/ */
#include <board.h>
#include "usart.h" #include "usart.h"
#include <serial.h> #include <serial.h>
#include <stm32f10x_dma.h> #include <stm32f10x_dma.h>
......
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd"> <Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
<SchemaVersion>1.1</SchemaVersion> <SchemaVersion>1.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header> <Header>### uVision Project, (C) Keil Software</Header>
<Targets> <Targets>
<Target> <Target>
<TargetName>RT-Thread STM32</TargetName> <TargetName>RT-Thread STM32</TargetName>
...@@ -12,25 +15,25 @@ ...@@ -12,25 +15,25 @@
<Device>STM32F107VC</Device> <Device>STM32F107VC</Device>
<Vendor>STMicroelectronics</Vendor> <Vendor>STMicroelectronics</Vendor>
<Cpu>IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x803FFFF) CLOCK(25000000) CPUTYPE("Cortex-M3")</Cpu> <Cpu>IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x803FFFF) CLOCK(25000000) CPUTYPE("Cortex-M3")</Cpu>
<FlashUtilSpec /> <FlashUtilSpec></FlashUtilSpec>
<StartupFile>"STARTUP\ST\STM32F10x.s" ("STM32 Startup Code")</StartupFile> <StartupFile>"STARTUP\ST\STM32F10x.s" ("STM32 Startup Code")</StartupFile>
<FlashDriverDll>UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_CL -FS08000000 -FL040000)</FlashDriverDll> <FlashDriverDll>UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_CL -FS08000000 -FL040000)</FlashDriverDll>
<DeviceId>4889</DeviceId> <DeviceId>4889</DeviceId>
<RegisterFile>stm32f10x_lib.h</RegisterFile> <RegisterFile>stm32f10x_lib.h</RegisterFile>
<MemoryEnv /> <MemoryEnv></MemoryEnv>
<Cmp /> <Cmp></Cmp>
<Asm /> <Asm></Asm>
<Linker /> <Linker></Linker>
<OHString /> <OHString></OHString>
<InfinionOptionDll /> <InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc /> <SLE66CMisc></SLE66CMisc>
<SLE66AMisc /> <SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc /> <SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>SFD\ST\STM32F107x\STM32F107.sfr</SFDFile> <SFDFile>SFD\ST\STM32F107x\STM32F107.sfr</SFDFile>
<UseEnv>0</UseEnv> <UseEnv>0</UseEnv>
<BinPath /> <BinPath></BinPath>
<IncludePath /> <IncludePath></IncludePath>
<LibPath /> <LibPath></LibPath>
<RegisterFilePath>ST\STM32F10x\</RegisterFilePath> <RegisterFilePath>ST\STM32F10x\</RegisterFilePath>
<DBRegisterFilePath>ST\STM32F10x\</DBRegisterFilePath> <DBRegisterFilePath>ST\STM32F10x\</DBRegisterFilePath>
<TargetStatus> <TargetStatus>
...@@ -54,16 +57,18 @@ ...@@ -54,16 +57,18 @@
<BeforeCompile> <BeforeCompile>
<RunUserProg1>0</RunUserProg1> <RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2> <RunUserProg2>0</RunUserProg2>
<UserProg1Name /> <UserProg1Name></UserProg1Name>
<UserProg2Name /> <UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode> <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode> <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile> </BeforeCompile>
<BeforeMake> <BeforeMake>
<RunUserProg1>0</RunUserProg1> <RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2> <RunUserProg2>0</RunUserProg2>
<UserProg1Name /> <UserProg1Name></UserProg1Name>
<UserProg2Name /> <UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode> <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode> <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
</BeforeMake> </BeforeMake>
...@@ -71,12 +76,12 @@ ...@@ -71,12 +76,12 @@
<RunUserProg1>1</RunUserProg1> <RunUserProg1>1</RunUserProg1>
<RunUserProg2>0</RunUserProg2> <RunUserProg2>0</RunUserProg2>
<UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name> <UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
<UserProg2Name /> <UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode> <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode> <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
</AfterMake> </AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild> <SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString /> <SVCSIdString></SVCSIdString>
</TargetCommonOption> </TargetCommonOption>
<CommonProperty> <CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler> <UseCPPCompiler>0</UseCPPCompiler>
...@@ -90,16 +95,16 @@ ...@@ -90,16 +95,16 @@
<AssembleAssemblyFile>0</AssembleAssemblyFile> <AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly> <PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode> <StopOnExitCode>3</StopOnExitCode>
<CustomArgument /> <CustomArgument></CustomArgument>
<IncludeLibraryModules /> <IncludeLibraryModules></IncludeLibraryModules>
</CommonProperty> </CommonProperty>
<DllOption> <DllOption>
<SimDllName>SARMCM3.DLL</SimDllName> <SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments /> <SimDllArguments></SimDllArguments>
<SimDlgDll>DARMSTM.DLL</SimDlgDll> <SimDlgDll>DARMSTM.DLL</SimDlgDll>
<SimDlgDllArguments>-pSTM32F107VC</SimDlgDllArguments> <SimDlgDllArguments>-pSTM32F107VC</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName> <TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments /> <TargetDllArguments></TargetDllArguments>
<TargetDlgDll>TARMSTM.DLL</TargetDlgDll> <TargetDlgDll>TARMSTM.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pSTM32F107VC</TargetDlgDllArguments> <TargetDlgDllArguments>-pSTM32F107VC</TargetDlgDllArguments>
</DllOption> </DllOption>
...@@ -131,22 +136,23 @@ ...@@ -131,22 +136,23 @@
<RestoreMemoryDisplay>1</RestoreMemoryDisplay> <RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions> <RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox> <RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
</Target> </Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild> <RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>7</TargetSelection> <TargetSelection>7</TargetSelection>
<SimDlls> <SimDlls>
<CpuDll /> <CpuDll></CpuDll>
<CpuDllArguments /> <CpuDllArguments></CpuDllArguments>
<PeripheralDll /> <PeripheralDll></PeripheralDll>
<PeripheralDllArguments /> <PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile /> <InitializationFile></InitializationFile>
</SimDlls> </SimDlls>
<TargetDlls> <TargetDlls>
<CpuDll /> <CpuDll></CpuDll>
<CpuDllArguments /> <CpuDllArguments></CpuDllArguments>
<PeripheralDll /> <PeripheralDll></PeripheralDll>
<PeripheralDllArguments /> <PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile /> <InitializationFile></InitializationFile>
<Driver>Segger\JL2CM3.dll</Driver> <Driver>Segger\JL2CM3.dll</Driver>
</TargetDlls> </TargetDlls>
</DebugOption> </DebugOption>
...@@ -160,8 +166,8 @@ ...@@ -160,8 +166,8 @@
<DriverSelection>4099</DriverSelection> <DriverSelection>4099</DriverSelection>
</Flash1> </Flash1>
<Flash2>Segger\JL2CM3.dll</Flash2> <Flash2>Segger\JL2CM3.dll</Flash2>
<Flash3 /> <Flash3>"" ()</Flash3>
<Flash4 /> <Flash4></Flash4>
</Utilities> </Utilities>
<TargetArmAds> <TargetArmAds>
<ArmAdsMisc> <ArmAdsMisc>
...@@ -193,7 +199,7 @@ ...@@ -193,7 +199,7 @@
<RvctClst>0</RvctClst> <RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst> <GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M3"</AdsCpuType> <AdsCpuType>"Cortex-M3"</AdsCpuType>
<RvctDeviceName /> <RvctDeviceName></RvctDeviceName>
<mOS>0</mOS> <mOS>0</mOS>
<uocRom>0</uocRom> <uocRom>0</uocRom>
<uocRam>0</uocRam> <uocRam>0</uocRam>
...@@ -324,7 +330,7 @@ ...@@ -324,7 +330,7 @@
<Size>0x0</Size> <Size>0x0</Size>
</OCR_RVCT10> </OCR_RVCT10>
</OnChipMemories> </OnChipMemories>
<RvctStartVector /> <RvctStartVector></RvctStartVector>
</ArmAdsMisc> </ArmAdsMisc>
<Cads> <Cads>
<interw>1</interw> <interw>1</interw>
...@@ -339,11 +345,12 @@ ...@@ -339,11 +345,12 @@
<Rwpi>0</Rwpi> <Rwpi>0</Rwpi>
<wLevel>0</wLevel> <wLevel>0</wLevel>
<uThumb>0</uThumb> <uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<VariousControls> <VariousControls>
<MiscControls /> <MiscControls></MiscControls>
<Define>STM32F10X_CL, USE_STDPERIPH_DRIVER</Define> <Define>STM32F10X_CL, USE_STDPERIPH_DRIVER</Define>
<Undefine /> <Undefine></Undefine>
<IncludePath>.;..\..\components\CMSIS\Include;..\..\components\dfs;..\..\components\dfs\include;..\..\components\finsh;..\..\components\init;..\..\components\net\lwip\src;..\..\components\net\lwip\src\arch\include;..\..\components\net\lwip\src\include;..\..\components\net\lwip\src\include\ipv4;..\..\components\net\lwip\src\include\netif;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m3;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;Libraries\STM32F10x_StdPeriph_Driver\inc;applications;drivers</IncludePath> <IncludePath>.;..\..\components\CMSIS\Include;..\..\components\dfs;..\..\components\dfs\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\init;..\..\components\net\lwip\src;..\..\components\net\lwip\src\arch\include;..\..\components\net\lwip\src\include;..\..\components\net\lwip\src\include\ipv4;..\..\components\net\lwip\src\include\netif;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m3;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;Libraries\STM32F10x_StdPeriph_Driver\inc;applications;drivers</IncludePath>
</VariousControls> </VariousControls>
</Cads> </Cads>
<Aads> <Aads>
...@@ -354,11 +361,12 @@ ...@@ -354,11 +361,12 @@
<SplitLS>0</SplitLS> <SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk> <SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn> <NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<VariousControls> <VariousControls>
<MiscControls /> <MiscControls></MiscControls>
<Define /> <Define></Define>
<Undefine /> <Undefine></Undefine>
<IncludePath /> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
</Aads> </Aads>
<LDads> <LDads>
...@@ -370,12 +378,12 @@ ...@@ -370,12 +378,12 @@
<useFile>0</useFile> <useFile>0</useFile>
<TextAddressRange>0x08000000</TextAddressRange> <TextAddressRange>0x08000000</TextAddressRange>
<DataAddressRange>0x20000000</DataAddressRange> <DataAddressRange>0x20000000</DataAddressRange>
<ScatterFile /> <ScatterFile></ScatterFile>
<IncludeLibs /> <IncludeLibs></IncludeLibs>
<IncludeLibsPath /> <IncludeLibsPath></IncludeLibsPath>
<Misc> --keep __fsym_* --keep __vsym_* </Misc> <Misc> --keep __fsym_* --keep __vsym_* </Misc>
<LinkerInputFile /> <LinkerInputFile></LinkerInputFile>
<DisabledWarnings /> <DisabledWarnings></DisabledWarnings>
</LDads> </LDads>
</TargetArmAds> </TargetArmAds>
</TargetOption> </TargetOption>
...@@ -388,8 +396,6 @@ ...@@ -388,8 +396,6 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>applications\application.c</FilePath> <FilePath>applications\application.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>startup.c</FileName> <FileName>startup.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -405,43 +411,36 @@ ...@@ -405,43 +411,36 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>drivers\board.c</FilePath> <FilePath>drivers\board.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>msd.c</FileName> <FileName>msd.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>drivers\msd.c</FilePath> <FilePath>drivers\msd.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>platform.c</FileName> <FileName>platform.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>drivers\platform.c</FilePath> <FilePath>drivers\platform.c</FilePath>
</File> </File>
</Files> <File>
<Files> <FileName>rt_stm32f10x_spi.c</FileName>
<FileType>1</FileType>
<FilePath>drivers\rt_stm32f10x_spi.c</FilePath>
</File>
<File> <File>
<FileName>serial.c</FileName> <FileName>serial.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>drivers\serial.c</FilePath> <FilePath>drivers\serial.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32_eth.c</FileName> <FileName>stm32_eth.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>drivers\stm32_eth.c</FilePath> <FilePath>drivers\stm32_eth.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_it.c</FileName> <FileName>stm32f10x_it.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>drivers\stm32f10x_it.c</FilePath> <FilePath>drivers\stm32f10x_it.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>usart.c</FileName> <FileName>usart.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -457,169 +456,121 @@ ...@@ -457,169 +456,121 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c</FilePath> <FilePath>Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_crc.c</FileName> <FileName>stm32f10x_crc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_crc.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_crc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_rcc.c</FileName> <FileName>stm32f10x_rcc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_wwdg.c</FileName> <FileName>stm32f10x_wwdg.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_wwdg.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_wwdg.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_pwr.c</FileName> <FileName>stm32f10x_pwr.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_pwr.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_pwr.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_exti.c</FileName> <FileName>stm32f10x_exti.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_exti.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_exti.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_bkp.c</FileName> <FileName>stm32f10x_bkp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_bkp.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_bkp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_i2c.c</FileName> <FileName>stm32f10x_i2c.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_i2c.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_i2c.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_adc.c</FileName> <FileName>stm32f10x_adc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_adc.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_adc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_dac.c</FileName> <FileName>stm32f10x_dac.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dac.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dac.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_rtc.c</FileName> <FileName>stm32f10x_rtc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rtc.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rtc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_fsmc.c</FileName> <FileName>stm32f10x_fsmc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_fsmc.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_fsmc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_tim.c</FileName> <FileName>stm32f10x_tim.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_tim.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_tim.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_iwdg.c</FileName> <FileName>stm32f10x_iwdg.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_iwdg.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_iwdg.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_spi.c</FileName> <FileName>stm32f10x_spi.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_spi.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_spi.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_flash.c</FileName> <FileName>stm32f10x_flash.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_flash.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_flash.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_sdio.c</FileName> <FileName>stm32f10x_sdio.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_sdio.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_sdio.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_gpio.c</FileName> <FileName>stm32f10x_gpio.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_usart.c</FileName> <FileName>stm32f10x_usart.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_dbgmcu.c</FileName> <FileName>stm32f10x_dbgmcu.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dbgmcu.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dbgmcu.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_dma.c</FileName> <FileName>stm32f10x_dma.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dma.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dma.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_can.c</FileName> <FileName>stm32f10x_can.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_can.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_can.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stm32f10x_cec.c</FileName> <FileName>stm32f10x_cec.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_cec.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_cec.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>misc.c</FileName> <FileName>misc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\misc.c</FilePath> <FilePath>Libraries\STM32F10x_StdPeriph_Driver\src\misc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>startup_stm32f10x_cl.s</FileName> <FileName>startup_stm32f10x_cl.s</FileName>
<FileType>2</FileType> <FileType>2</FileType>
...@@ -635,78 +586,56 @@ ...@@ -635,78 +586,56 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\clock.c</FilePath> <FilePath>..\..\src\clock.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>device.c</FileName> <FileName>device.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\device.c</FilePath> <FilePath>..\..\src\device.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>idle.c</FileName> <FileName>idle.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\idle.c</FilePath> <FilePath>..\..\src\idle.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>ipc.c</FileName> <FileName>ipc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\ipc.c</FilePath> <FilePath>..\..\src\ipc.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>irq.c</FileName> <FileName>irq.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\irq.c</FilePath> <FilePath>..\..\src\irq.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>kservice.c</FileName> <FileName>kservice.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\kservice.c</FilePath> <FilePath>..\..\src\kservice.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>mem.c</FileName> <FileName>mem.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\mem.c</FilePath> <FilePath>..\..\src\mem.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>mempool.c</FileName> <FileName>mempool.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\mempool.c</FilePath> <FilePath>..\..\src\mempool.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>object.c</FileName> <FileName>object.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\object.c</FilePath> <FilePath>..\..\src\object.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>scheduler.c</FileName> <FileName>scheduler.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\scheduler.c</FilePath> <FilePath>..\..\src\scheduler.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>thread.c</FileName> <FileName>thread.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\src\thread.c</FilePath> <FilePath>..\..\src\thread.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>timer.c</FileName> <FileName>timer.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -722,29 +651,21 @@ ...@@ -722,29 +651,21 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\libcpu\arm\cortex-m3\cpuport.c</FilePath> <FilePath>..\..\libcpu\arm\cortex-m3\cpuport.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>context_rvds.S</FileName> <FileName>context_rvds.S</FileName>
<FileType>2</FileType> <FileType>2</FileType>
<FilePath>..\..\libcpu\arm\cortex-m3\context_rvds.S</FilePath> <FilePath>..\..\libcpu\arm\cortex-m3\context_rvds.S</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>backtrace.c</FileName> <FileName>backtrace.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\backtrace.c</FilePath> <FilePath>..\..\libcpu\arm\common\backtrace.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>div0.c</FileName> <FileName>div0.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\div0.c</FilePath> <FilePath>..\..\libcpu\arm\common\div0.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>showmem.c</FileName> <FileName>showmem.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -760,36 +681,26 @@ ...@@ -760,36 +681,26 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\dfs\src\dfs.c</FilePath> <FilePath>..\..\components\dfs\src\dfs.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>dfs_fs.c</FileName> <FileName>dfs_fs.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\dfs\src\dfs_fs.c</FilePath> <FilePath>..\..\components\dfs\src\dfs_fs.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>dfs_file.c</FileName> <FileName>dfs_file.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\dfs\src\dfs_file.c</FilePath> <FilePath>..\..\components\dfs\src\dfs_file.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>dfs_posix.c</FileName> <FileName>dfs_posix.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\dfs\src\dfs_posix.c</FilePath> <FilePath>..\..\components\dfs\src\dfs_posix.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>dfs_elm.c</FileName> <FileName>dfs_elm.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\dfs\filesystems\elmfat\dfs_elm.c</FilePath> <FilePath>..\..\components\dfs\filesystems\elmfat\dfs_elm.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>ff.c</FileName> <FileName>ff.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -797,6 +708,21 @@ ...@@ -797,6 +708,21 @@
</File> </File>
</Files> </Files>
</Group> </Group>
<Group>
<GroupName>DeviceDrivers</GroupName>
<Files>
<File>
<FileName>spi_core.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\spi\spi_core.c</FilePath>
</File>
<File>
<FileName>spi_dev.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\spi\spi_dev.c</FilePath>
</File>
</Files>
</Group>
<Group> <Group>
<GroupName>finsh</GroupName> <GroupName>finsh</GroupName>
<Files> <Files>
...@@ -805,85 +731,61 @@ ...@@ -805,85 +731,61 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\cmd.c</FilePath> <FilePath>..\..\components\finsh\cmd.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_compiler.c</FileName> <FileName>finsh_compiler.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_compiler.c</FilePath> <FilePath>..\..\components\finsh\finsh_compiler.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_error.c</FileName> <FileName>finsh_error.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_error.c</FilePath> <FilePath>..\..\components\finsh\finsh_error.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_heap.c</FileName> <FileName>finsh_heap.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_heap.c</FilePath> <FilePath>..\..\components\finsh\finsh_heap.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_init.c</FileName> <FileName>finsh_init.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_init.c</FilePath> <FilePath>..\..\components\finsh\finsh_init.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_node.c</FileName> <FileName>finsh_node.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_node.c</FilePath> <FilePath>..\..\components\finsh\finsh_node.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_ops.c</FileName> <FileName>finsh_ops.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_ops.c</FilePath> <FilePath>..\..\components\finsh\finsh_ops.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_parser.c</FileName> <FileName>finsh_parser.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_parser.c</FilePath> <FilePath>..\..\components\finsh\finsh_parser.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_token.c</FileName> <FileName>finsh_token.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_token.c</FilePath> <FilePath>..\..\components\finsh\finsh_token.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_var.c</FileName> <FileName>finsh_var.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_var.c</FilePath> <FilePath>..\..\components\finsh\finsh_var.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>finsh_vm.c</FileName> <FileName>finsh_vm.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_vm.c</FilePath> <FilePath>..\..\components\finsh\finsh_vm.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>shell.c</FileName> <FileName>shell.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\finsh\shell.c</FilePath> <FilePath>..\..\components\finsh\shell.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>symbol.c</FileName> <FileName>symbol.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -909,239 +811,171 @@ ...@@ -909,239 +811,171 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\api_lib.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\api_lib.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>api_msg.c</FileName> <FileName>api_msg.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\api_msg.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\api_msg.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>err.c</FileName> <FileName>err.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\err.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\err.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>netbuf.c</FileName> <FileName>netbuf.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\netbuf.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\netbuf.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>netdb.c</FileName> <FileName>netdb.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\netdb.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\netdb.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>netifapi.c</FileName> <FileName>netifapi.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\netifapi.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\netifapi.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>sockets.c</FileName> <FileName>sockets.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\sockets.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\sockets.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>tcpip.c</FileName> <FileName>tcpip.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\api\tcpip.c</FilePath> <FilePath>..\..\components\net\lwip\src\api\tcpip.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>sys_arch.c</FileName> <FileName>sys_arch.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\arch\sys_arch.c</FilePath> <FilePath>..\..\components\net\lwip\src\arch\sys_arch.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>def.c</FileName> <FileName>def.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\def.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\def.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>dhcp.c</FileName> <FileName>dhcp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\dhcp.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\dhcp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>dns.c</FileName> <FileName>dns.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\dns.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\dns.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>init.c</FileName> <FileName>init.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\init.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\init.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>memp.c</FileName> <FileName>memp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\memp.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\memp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>netif.c</FileName> <FileName>netif.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\netif.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\netif.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>pbuf.c</FileName> <FileName>pbuf.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\pbuf.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\pbuf.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>raw.c</FileName> <FileName>raw.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\raw.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\raw.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>stats.c</FileName> <FileName>stats.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\stats.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\stats.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>sys.c</FileName> <FileName>sys.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\sys.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\sys.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>tcp.c</FileName> <FileName>tcp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\tcp.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\tcp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>tcp_in.c</FileName> <FileName>tcp_in.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\tcp_in.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\tcp_in.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>tcp_out.c</FileName> <FileName>tcp_out.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\tcp_out.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\tcp_out.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>timers.c</FileName> <FileName>timers.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\timers.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\timers.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>udp.c</FileName> <FileName>udp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\udp.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\udp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>autoip.c</FileName> <FileName>autoip.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\autoip.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\autoip.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>icmp.c</FileName> <FileName>icmp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\icmp.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\icmp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>igmp.c</FileName> <FileName>igmp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\igmp.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\igmp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>inet.c</FileName> <FileName>inet.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\inet.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\inet.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>inet_chksum.c</FileName> <FileName>inet_chksum.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\inet_chksum.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\inet_chksum.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>ip.c</FileName> <FileName>ip.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\ip.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\ip.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>ip_addr.c</FileName> <FileName>ip_addr.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\ip_addr.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\ip_addr.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>ip_frag.c</FileName> <FileName>ip_frag.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\core\ipv4\ip_frag.c</FilePath> <FilePath>..\..\components\net\lwip\src\core\ipv4\ip_frag.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>etharp.c</FileName> <FileName>etharp.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\netif\etharp.c</FilePath> <FilePath>..\..\components\net\lwip\src\netif\etharp.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>ethernetif.c</FileName> <FileName>ethernetif.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\components\net\lwip\src\netif\ethernetif.c</FilePath> <FilePath>..\..\components\net\lwip\src\netif\ethernetif.c</FilePath>
</File> </File>
</Files>
<Files>
<File> <File>
<FileName>slipif.c</FileName> <FileName>slipif.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
...@@ -1152,4 +986,5 @@ ...@@ -1152,4 +986,5 @@
</Groups> </Groups>
</Target> </Target>
</Targets> </Targets>
</Project> </Project>
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
# GoldBull debug board # GoldBull debug board
- 10M/100M ethernet - 10M/100M ethernet
- SPI SD Card - SPI SD Card
- LCD SPI: SPI1 (PA5,PA6,PA7). CS:PA4
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
/* SECTION: Device System */ /* SECTION: Device System */
/* Using Device System */ /* Using Device System */
#define RT_USING_DEVICE #define RT_USING_DEVICE
#define RT_USING_UART1 #define RT_USING_SPI
/* SECTION: Console options */ /* SECTION: Console options */
#define RT_USING_CONSOLE #define RT_USING_CONSOLE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册