将SD SPI驱动添加到工程目录中
MounRiver Studio会自动添加文件路径到工程内
sdspi_port.c文件是移植的接口文件,里面需要根据实际使用情况实现接口函数,包含SPI初始化、SPI时钟速率变更及SPI数据收发函数
我这里使用的是SPI1
相关接口函数如下:
#include <stdio.h>
#include <stdint.h>
#include "sdspi.h"
#include "ch32v30x.h"
#define BOARD_SDSPI_TX_GPIO_PORT GPIOA
#define BOARD_SDSPI_TX_GPIO_PIN GPIO_Pin_7
#define BOARD_SDSPI_RX_GPIO_PORT GPIOA
#define BOARD_SDSPI_RX_GPIO_PIN GPIO_Pin_6
#define BOARD_SDSPI_CLK_GPIO_PORT GPIOA
#define BOARD_SDSPI_CLK_GPIO_PIN GPIO_Pin_5
#define BOARD_SDSPI_CS_GPIO_PORT GPIOA
#define BOARD_SDSPI_CS_GPIO_PIN GPIO_Pin_4
SDSPI_ApiRetStatus_Type sdspi_spi_init(void);
SDSPI_ApiRetStatus_Type sdspi_spi_freq(uint32_t hz);
SDSPI_ApiRetStatus_Type sdspi_spi_xfer(uint8_t *in, uint8_t *out, uint32_t len);
const SDSPI_Interface_Type board_sdspi_if =
{
.baudrate = 1000000u,
.spi_init = sdspi_spi_init,
.spi_freq = sdspi_spi_freq,
.spi_xfer = sdspi_spi_xfer
};
uint32_t board_sdspi_delay_count;
static void board_sdspi_delay(uint32_t count)
{
for (uint32_t i = count; i > 0u; i--)
{
__NOP();
}
}
SDSPI_ApiRetStatus_Type sdspi_spi_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
SPI_InitTypeDef SPI_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
GPIO_SetBits(BOARD_SDSPI_CS_GPIO_PORT, BOARD_SDSPI_CS_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
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_128;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
return SDSPI_ApiRetStatus_Success;
}
SDSPI_ApiRetStatus_Type sdspi_spi_freq(uint32_t hz)
{
SPI_InitTypeDef SPI_InitStructure = {0};
GPIO_SetBits(BOARD_SDSPI_CS_GPIO_PORT, BOARD_SDSPI_CS_GPIO_PIN);
SPI_Enable(SPI1, DISABLE);
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_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
switch (hz)
{
case SDMMC_CLOCK_400KHZ:
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
break;
default:
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
break;
}
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
return SDSPI_ApiRetStatus_Success;
}
void app_spi_putbyte(uint8_t tx_dat)
{
u8 i = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
{
i++;
if(i > 200)
return ;
}
SPI_I2S_SendData(SPI1, tx_dat);
}
uint8_t app_spi_getbyte(void)
{
u8 i = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
i++;
if(i > 200)
return 0;
}
return SPI_I2S_ReceiveData(SPI1);
}
uint8_t spi_xfer(uint8_t tx_dat)
{
u8 i = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
{
i++;
if(i > 200)
return 0;
}
SPI_I2S_SendData(SPI1, tx_dat);
i = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
i++;
if(i > 200)
return 0;
}
return SPI_I2S_ReceiveData(SPI1);
}
SDSPI_ApiRetStatus_Type sdspi_spi_xfer(uint8_t *in, uint8_t *out, uint32_t len)
{
uint8_t inbuf, outbuf;
GPIO_ResetBits(BOARD_SDSPI_CS_GPIO_PORT, BOARD_SDSPI_CS_GPIO_PIN);
for (uint32_t i = 0u; i < len; i++)
{
inbuf = (in == NULL) ? SDSPI_DUMMY_DATA: *in++;
outbuf = spi_xfer(inbuf);
if (out)
{
*out = outbuf;
out++;
}
}
GPIO_SetBits(BOARD_SDSPI_CS_GPIO_PORT, BOARD_SDSPI_CS_GPIO_PIN);
return SDSPI_ApiRetStatus_Success;
}
移植完这些,SD-SPI驱动就移植完了,为后续工作准好的驱动工作。
驱动文件:*附件:sdspi.zip
|