📄 ffsport_spi.c
字号:
/***********************************************************
* MMC/SD-interface to SPI-slot of STM32 *
* *
* by Frank Goetze - www.embedded-os.de *
************************************************************
* FFSPort_MMC.c *
* MMC/SD TO SPI PORT *
************************************************************
* - code generation Frank Goetze 01/2008 *
***********************************************************/
#include "../../../inc/MMC/STM32/FFSPort_SPI.h"
/****************** constant variables ********************/
#define CPU_CRISTAL_CLK 8000000UL // processor crystal-clock in Hz
OS_CONST U16 OS_ROMDATA SPI_c[] = {
SPI_BaudRatePrescaler_2,
SPI_BaudRatePrescaler_4,
SPI_BaudRatePrescaler_8,
SPI_BaudRatePrescaler_16,
SPI_BaudRatePrescaler_32,
SPI_BaudRatePrescaler_64,
SPI_BaudRatePrescaler_128,
SPI_BaudRatePrescaler_256
};
/*
************************************************************
* set max possible baudrate and return this
************************************************************
*/
U32 FFSPort_MMC_SetBR(U32 maxclk)
{
RCC_ClocksTypeDef rcc_clocks;
U32 s_clksrc;
U08 i;
i = 0;
RCC_GetClocksFreq(&rcc_clocks);
#if (!SPI_)
s_clksrc = (U32)rcc_clocks.PCLK2_Frequency;
#else
s_clksrc = (U32)rcc_clocks.PCLK1_Frequency;
#endif
while(((s_clksrc / (2 << i)) > maxclk) && (i < 7)) i++;
SPIx->CR1 = (SPIx->CR1 & ~SPI_BaudRatePrescaler_256) | SPI_c[i];
return(s_clksrc / (2 << i));
}
/*
************************************************************
* write a char and read one back
************************************************************
*/
U08 FFSPort_MMC_Send(U08 w)
{
while(!(SPI_GetFlagStatus(SPIx, SPI_FLAG_TXE))); // wait up to tx-empty
SPI_SendData(SPIx, (U16)w); // write char and send
while(!(SPI_GetFlagStatus(SPIx, SPI_FLAG_RXNE))); // wait up to rx-not_empty (char received)
return((U08)SPI_ReceiveData(SPIx)); // return received char
}
/*
************************************************************
* reinitialise the SPI-port
************************************************************
*/
U08 FFSPort_MMC_ReInit(void)
{
FFSPort_MMC_SetBR(400000); // set SPI-clk to max 400kHz as startup (should never be > 400kHz, says MMC)
return(0); // return actual alltimes ok.
}
/*
************************************************************
* initialise the SPI-port
************************************************************
*/
U08 FFSPort_MMC_Init(void)
{
SPI_InitTypeDef SPI_is;
GPIO_InitTypeDef GPIO_is;
#if (!SPI_)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // enable CLK for SPI1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // enable CLK for GPIOA (CS)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // enable CLK for GPIOC (WP & CD)
#else
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // enable CLK for SPI2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // enable CLK for GPIOB (CS)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // enable CLK for GPIOC (WP & CD)
#endif
SPI_is.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_is.SPI_Mode = SPI_Mode_Master; // init SPIx
SPI_is.SPI_DataSize = SPI_DataSize_8b;
SPI_is.SPI_CPOL = SPI_CPOL_High;
SPI_is.SPI_CPHA = SPI_CPHA_2Edge;
SPI_is.SPI_NSS = SPI_NSS_Soft;
SPI_is.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_is.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_is.SPI_CRCPolynomial = 7;
SPI_Init(SPIx, &SPI_is);
SPI_Cmd(SPIx, ENABLE);
GPIO_is.GPIO_Speed = GPIO_Speed_50MHz; // config SCK, MOSI, MISO
GPIO_is.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_is.GPIO_Pin = SPIx_bit;
GPIO_Init(SPIx_Gx, &GPIO_is);
GPIO_is.GPIO_Mode = GPIO_Mode_IPD; // config WP, CD as PIO in
GPIO_is.GPIO_Pin = WP_bit | CD_bit;
GPIO_Init(WPCD_Gx, &GPIO_is);
GPIO_is.GPIO_Mode = GPIO_Mode_Out_PP; // config NSS as PIO out
GPIO_is.GPIO_Pin = CS_bit;
GPIO_Init(CS_Gx, &GPIO_is);
return(FFSPort_MMC_ReInit()); // (re)init SPI-clock
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -