【MM32F5270开发板试用】依靠SPI_SD,移植FatFs文件系统(优化版本)
上三篇文章: 【MM32F5270开发板试用】一、依靠SPI_SD,移植FatFs文件系统 【MM32F5270开发板试用】SysTick+Scheduler轮询 【MM32F5270开发板试用】如何将数据存放在DTCM 本次所有代码按照以前习惯全部开源:我的Github地址是:https://github.com/kings669/MM32F5
可能关注我的朋友发现,我最近没有更新文章,那是因为我前段时间去参加今年的智能车竞赛。现在,已经比完,可以有时间完成我后续的计划😄。
一、优化背景 在测试的过程中,发现播放音频卡顿十分卡顿,经过排除后发现,在官方适配的SPI是软件SPI。想到我们的整体流程是从SD卡开始,源头就卡了,何来最大吞吐率😄。
二、优化过程 1、开启时钟,在clock_init.c中
/* SPI3. */ RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_SPI3, true); RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_SPI3);
2、引脚设置,在pin_init.c中
/* PC12 - GPIO output: SPI3_MOSI. */ gpio_init.Pins = GPIO_PIN_12; gpio_init.PinMode = GPIO_PinMode_AF_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &gpio_init); GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_6);
/* PC11 - GPIO input: SPI3_MISO. */ gpio_init.Pins = GPIO_PIN_11; gpio_init.PinMode = GPIO_PinMode_In_Floating; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &gpio_init); GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_6);
/* PC10 - GPIO output: SPI3_SCK. */ gpio_init.Pins = GPIO_PIN_10; gpio_init.PinMode = GPIO_PinMode_AF_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &gpio_init); GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_6);
/* PA15 - GPIO output: SPI3_CS. */ gpio_init.Pins = GPIO_PIN_15; gpio_init.PinMode = GPIO_PinMode_AF_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio_init); GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_6);
3、修改sdspi_port.c文件
#include "board_init.h"
#include "sdspi.h"
#include "hal_spi.h"
#define BOARD_SDSPI_TX_GPIO_PORT GPIOC
#define BOARD_SDSPI_TX_GPIO_PIN GPIO_PIN_12
#define BOARD_SDSPI_RX_GPIO_PORT GPIOC
#define BOARD_SDSPI_RX_GPIO_PIN GPIO_PIN_11
#define BOARD_SDSPI_CLK_GPIO_PORT GPIOC
#define BOARD_SDSPI_CLK_GPIO_PIN GPIO_PIN_10
#define BOARD_SDSPI_CS_GPIO_PORT GPIOA
#define BOARD_SDSPI_CS_GPIO_PIN GPIO_PIN_15
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_WriteBit(BOARD_SDSPI_CS_GPIO_PORT , BOARD_SDSPI_CS_GPIO_PIN , 1u);
SPI_Master_Init_Type spi_init;
spi_init.ClockFreqHz = CLOCK_APB1_FREQ;
spi_init.BaudRate = SDMMC_CLOCK_400KHZ;
spi_init.XferMode = SPI_XferMode_TxRx;
spi_init.PolPha = SPI_PolPha_Alt2;
spi_init.DataWidth = SPI_DataWidth_8b;
spi_init.LSB = false;
spi_init.AutoCS = true;
SPI_InitMaster(SPI3, &spi_init);
SPI_Enable(SPI3, true);
return SDSPI_ApiRetStatus_Success;
}
void SPI_SetBaudRate(SPI_Type * SPIx, uint32_t src_clk, uint32_t baudrate)
{
uint32_t div = src_clk / baudrate;
if (div < 2u)
{
div = 2u;
}
SPIx->SPBRG = div;
if (div <= 4)
{
SPIx->CCTL |= (SPI_I2S_CCTL_TXEDGE_MASK | SPI_I2S_CCTL_RXEDGE_MASK);
}
else
{
SPIx->CCTL &= ~(SPI_I2S_CCTL_TXEDGE_MASK | SPI_I2S_CCTL_RXEDGE_MASK);
}
}
SDSPI_ApiRetStatus_Type sdspi_spi_freq(uint32_t hz)
{
switch (hz)
{
case SDMMC_CLOCK_400KHZ:
SPI_Enable(SPI3, false);
SPI_SetBaudRate(SPI3,CLOCK_APB1_FREQ,SDMMC_CLOCK_400KHZ);
SPI_Enable(SPI3, true);
break;
default:
SPI_Enable(SPI3, false);
SPI_SetBaudRate(SPI3,CLOCK_APB1_FREQ,SD_CLOCK_25MHZ);
SPI_Enable(SPI3, true);
break;
}
return SDSPI_ApiRetStatus_Success;
}
void app_spi_putbyte(uint8_t c)
{
while ( SPI_STATUS_TX_FULL & SPI_GetStatus(SPI3) )
{}
SPI_PutData(SPI3, c);
}
uint8_t app_spi_getbyte(void)
{
while (0u == (SPI_STATUS_RX_DONE & SPI_GetStatus(SPI3)) )
{}
return SPI_GetData(SPI3);
}
uint8_t spi_xfer(uint8_t tx_dat)
{
uint8_t rx_dat = 0u;
app_spi_putbyte(tx_dat);
rx_dat=app_spi_getbyte();
return rx_dat;
}
void spi_assert_cs(bool enable)
{
GPIO_WriteBit(BOARD_SDSPI_CS_GPIO_PORT, BOARD_SDSPI_CS_GPIO_PIN, (enable ? 0u: 1u) );
}
SDSPI_ApiRetStatus_Type sdspi_spi_xfer(uint8_t *in, uint8_t *out, uint32_t len)
{
uint8_t inbuf, outbuf;
for (uint32_t i = 0u; i < len; i++)
{
inbuf = (in == NULL) ? SDSPI_DUMMY_DATA: *in++;
outbuf = spi_xfer(inbuf);
if (out)
{
*out = outbuf;
out++;
}
}
return SDSPI_ApiRetStatus_Success;
}
|