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

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

上级 5c17c2e6
......@@ -4,6 +4,15 @@ from building import *
cwd = os.path.join(str(Dir('#')), 'drivers')
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]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
......
......@@ -14,7 +14,6 @@
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
/**
......@@ -45,15 +44,15 @@ void NVIC_Configuration(void)
* This is the timer interrupt service routine.
*
*/
void rt_hw_timer_handler(void)
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
/* leave interrupt */
rt_interrupt_leave();
}
/**
......
......@@ -40,6 +40,9 @@
#define STM32_SRAM_SIZE 64
#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_usart_init(void);
......
此差异已折叠。
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : msd.h
* Author : MCD Application Team
* Version : V2.1
* Date : 05/30/2008
* Description : Header for msd.c file.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH 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.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MSD_H
#define __MSD_H
/* Includes ------------------------------------------------------------------*/
#include <stm32f10x.h>
/* Private define ------------------------------------------------------------*/
/* Block Size */
#define BLOCK_SIZE 512
/* Dummy byte */
#define DUMMY 0xFF
/*
* File : msd.h
* SPI mode SD Card Driver
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-04-17 Bernard first version.
*/
#ifndef MSD_H_INCLUDED
#define MSD_H_INCLUDED
#include <stdint.h>
#include <drivers/spi.h>
/* SD command (SPI mode) */
#define GO_IDLE_STATE 0 /* CMD0 R1 */
#define SEND_OP_COND 1 /* CMD1 R1 */
#define SWITCH_FUNC 6 /* CMD6 R1 */
#define SEND_IF_COND 8 /* CMD8 R7 */
#define SEND_CSD 9 /* CMD9 R1 */
#define SEND_CID 10 /* CMD10 R1 */
#define STOP_TRANSMISSION 12 /* CMD12 R1B */
#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 */
/* 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_START_DATA_MULTIPLE_BLOCK_READ 0xFE /* Data token start byte, Start Multiple Block Read */
#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 */
#define MSD_TOKEN_READ_START 0xFE /* Data token start byte, Start Single Block Read */
#define MSD_TOKEN_WRITE_SINGLE_START 0xFE /* Data token start byte, Start Single Block Write */
/* MSD functions return */
#define MSD_SUCCESS 0x00
#define MSD_FAIL 0xFF
#define MSD_TOKEN_WRITE_MULTIPLE_START 0xFC /* Data token start byte, Start Multiple Block Write */
#define MSD_TOKEN_WRITE_MULTIPLE_STOP 0xFD /* Data toke stop byte, Stop Multiple Block Write */
/* MSD reponses and error flags */
#define MSD_RESPONSE_NO_ERROR 0x00
#define MSD_IN_IDLE_STATE 0x01
#define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04
#define MSD_COM_CRC_ERROR 0x08
#define MSD_ERASE_SEQUENCE_ERROR 0x10
#define MSD_ADDRESS_ERROR 0x20
#define MSD_PARAMETER_ERROR 0x40
#define MSD_RESPONSE_FAILURE 0xFF
#define MSD_RESPONSE_NO_ERROR 0x00
#define MSD_IN_IDLE_STATE 0x01
#define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04
#define MSD_COM_CRC_ERROR 0x08
#define MSD_ERASE_SEQUENCE_ERROR 0x10
#define MSD_ADDRESS_ERROR 0x20
#define MSD_PARAMETER_ERROR 0x40
#define MSD_RESPONSE_FAILURE 0xFF
/* Data response error */
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
/* Commands: CMDxx = CMD-number | 0x40 */
#define MSD_GO_IDLE_STATE 0 /* CMD0=0x40 */
#define MSD_SEND_OP_COND 1 /* CMD1=0x41 */
#define MSD_SEND_CSD 9 /* CMD9=0x49 */
#define MSD_SEND_CID 10 /* CMD10=0x4A */
#define MSD_STOP_TRANSMISSION 12 /* CMD12=0x4C */
#define MSD_SEND_STATUS 13 /* CMD13=0x4D */
#define MSD_SET_BLOCKLEN 16 /* CMD16=0x50 */
#define MSD_READ_SINGLE_BLOCK 17 /* CMD17=0x51 */
#define MSD_READ_MULTIPLE_BLOCK 18 /* CMD18=0x52 */
#define MSD_SET_BLOCK_COUNT 23 /* CMD23=0x57 */
#define MSD_WRITE_BLOCK 24 /* CMD24=0x58 */
#define MSD_WRITE_MULTIPLE_BLOCK 25 /* CMD25=0x59 */
#define MSD_PROGRAM_CSD 27 /* CMD27=0x5B */
#define MSD_SET_WRITE_PROT 28 /* CMD28=0x5C */
#define MSD_CLR_WRITE_PROT 29 /* CMD29=0x5D */
#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*/
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
#define MSD_DATA_RESPONSE_MASK 0x1F
#define MSD_GET_DATA_RESPONSE(res) (res & MSD_DATA_RESPONSE_MASK)
#define MSD_CMD_LEN 6 /**< command, arg and crc. */
#define MSD_RESPONSE_MAX_LEN 5 /**< response max len */
#define MSD_CSD_LEN 16 /**< SD crad CSD register len */
#define SECTOR_SIZE 512 /**< sector size, default 512byte */
/* card try timeout, unit: ms */
#define CARD_TRY_TIMES 3000
#define CARD_TRY_TIMES_ACMD41 800
#define CARD_WAIT_TOKEN_TIMES 800
#define MSD_USE_PRE_ERASED /**< id define MSD_USE_PRE_ERASED, before CMD25, send ACMD23 */
/**
* SD/MMC card type
*/
typedef enum
{
vu8 CSDStruct; /* CSD structure */
vu8 SysSpecVersion; /* System specification version */
vu8 Reserved1; /* Reserved */
vu8 TAAC; /* Data read access-time 1 */
vu8 NSAC; /* Data read access-time 2 in CLK cycles */
vu8 MaxBusClkFrec; /* Max. bus clock frequency */
vu16 CardComdClasses; /* Card command classes */
vu8 RdBlockLen; /* Max. read data block length */
vu8 PartBlockRead; /* Partial blocks for read allowed */
vu8 WrBlockMisalign; /* Write block misalignment */
vu8 RdBlockMisalign; /* Read block misalignment */
vu8 DSRImpl; /* DSR implemented */
vu8 Reserved2; /* Reserved */
vu16 DeviceSize; /* Device Size */
vu8 MaxRdCurrentVDDMin; /* Max. read current @ VDD min */
vu8 MaxRdCurrentVDDMax; /* Max. read current @ VDD max */
vu8 MaxWrCurrentVDDMin; /* Max. write current @ VDD min */
vu8 MaxWrCurrentVDDMax; /* Max. write current @ VDD max */
vu8 DeviceSizeMul; /* Device size multiplier */
vu8 EraseGrSize; /* Erase group size */
vu8 EraseGrMul; /* Erase group size multiplier */
vu8 WrProtectGrSize; /* Write protect group size */
vu8 WrProtectGrEnable; /* Write protect group enable */
vu8 ManDeflECC; /* Manufacturer default ECC */
vu8 WrSpeedFact; /* Write speed factor */
vu8 MaxWrBlockLen; /* Max. write data block length */
vu8 WriteBlockPaPartial; /* Partial blocks for write allowed */
vu8 Reserved3; /* Reserded */
vu8 ContentProtectAppli; /* Content protection application */
vu8 FileFormatGrouop; /* File format group */
vu8 CopyFlag; /* Copy flag (OTP) */
vu8 PermWrProtect; /* Permanent write protection */
vu8 TempWrProtect; /* Temporary write protection */
vu8 FileFormat; /* File Format */
vu8 ECC; /* ECC code */
vu8 msd_CRC; /* CRC */
vu8 Reserved4; /* always 1*/
}
sMSD_CSD;
typedef struct _MSD_CID /*Card Identification Data*/
MSD_CARD_TYPE_UNKNOWN = 0, /**< unknown */
MSD_CARD_TYPE_MMC, /**< MultiMedia Card */
MSD_CARD_TYPE_SD_V1_X, /**< Ver 1.X Standard Capacity SD Memory Card */
MSD_CARD_TYPE_SD_V2_X, /**< Ver 2.00 or later Standard Capacity SD Memory Card */
MSD_CARD_TYPE_SD_SDHC, /**< High Capacity SD Memory Card */
MSD_CARD_TYPE_SD_SDXC, /**< later Extended Capacity SD Memory Card */
}msd_card_type;
typedef enum
{
vu8 ManufacturerID; /* ManufacturerID */
vu16 OEM_AppliID; /* OEM/Application ID */
vu32 ProdName1; /* Product Name part1 */
vu8 ProdName2; /* Product Name part2*/
vu8 ProdRev; /* Product Revision */
vu32 ProdSN; /* Product Serial Number */
vu8 Reserved1; /* Reserved1 */
vu16 ManufactDate; /* Manufacturing Date */
vu8 msd_CRC; /* CRC */
vu8 Reserved2; /* always 1*/
}
sMSD_CID;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/*----- High layer function -----*/
u8 MSD_Init(void);
u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite);
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****/
response_type_unknown = 0,
response_r1,
response_r1b,
response_r2,
response_r3,
response_r4,
response_r5,
response_r7,
}response_type;
struct msd_device
{
struct rt_device parent; /**< RT-Thread device struct */
struct rt_device_blk_geometry geometry; /**< sector size, sector count */
struct rt_spi_device * spi_device; /**< SPI interface */
msd_card_type card_type; /**< card type: MMC SD1.x SD2.0 SDHC SDXC */
uint32_t max_clock; /**< MAX SPI clock */
};
extern rt_err_t msd_init(const char * sd_device_name, const char * spi_device_name);
#endif // MSD_H_INCLUDED
......@@ -5,18 +5,98 @@
#include "stm32_eth.h"
#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)
{
#ifdef RT_USING_LWIP
/* initialize eth interface */
rt_hw_stm32_eth_init();
#endif /* RT_USING_LWIP */
#ifdef RT_USING_SPI
rt_hw_spi_init();
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
/* init sdcard driver */
{
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_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
......@@ -5,7 +5,7 @@
* @version V3.5.0
* @date 08-April-2011
* @brief Main Interrupt Service Routines.
* This file provides template for all exceptions handler and
* This file provides template for all exceptions handler and
* peripherals interrupt service routine.
******************************************************************************
* @attention
......@@ -19,7 +19,7 @@
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
......@@ -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 */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
......@@ -132,7 +126,7 @@ void USART1_IRQHandler(void)
#ifdef RT_USING_UART1
extern struct rt_device uart1_device;
extern void rt_hw_serial_isr(struct rt_device *device);
/* enter interrupt */
rt_interrupt_enter();
......@@ -191,7 +185,7 @@ void USART3_IRQHandler(void)
/**
* @}
*/
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
......@@ -13,6 +13,7 @@
* 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode
*/
#include <board.h>
#include "usart.h"
#include <serial.h>
#include <stm32f10x_dma.h>
......
此差异已折叠。
......@@ -2,4 +2,4 @@
# GoldBull debug board
- 10M/100M ethernet
- SPI SD Card
- LCD
SPI: SPI1 (PA5,PA6,PA7). CS:PA4
......@@ -58,7 +58,7 @@
/* SECTION: Device System */
/* Using Device System */
#define RT_USING_DEVICE
#define RT_USING_UART1
#define RT_USING_SPI
/* SECTION: Console options */
#define RT_USING_CONSOLE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册