📄 stm32f10x_spi.c
字号:
SPIx->CR1 |= CR1_CRCEN_Set;
}
else
{
/* Disable the selected SPI CRC calculation */
SPIx->CR1 &= CR1_CRCEN_Reset;
}
}
/*******************************************************************************
* Function Name : SPI_GetCRC
* Description : Returns the transmit or the receive CRC register value for
* the specified SPI.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* - SPI_CRC: specifies the CRC register to be read.
* This parameter can be one of the following values:
* - SPI_CRC_Tx: Selects Tx CRC register
* - SPI_CRC_Rx: Selects Rx CRC register
* Output : None
* Return : The selected CRC register value..
*******************************************************************************/
u16 SPI_GetCRC(SPI_TypeDef* SPIx, u8 SPI_CRC)
{
u16 crcreg = 0;
/* Check the parameters */
assert_param(IS_SPI_CRC(SPI_CRC));
if (SPI_CRC != SPI_CRC_Rx)
{
/* Get the Tx CRC register */
crcreg = SPIx->TXCRCR;
}
else
{
/* Get the Rx CRC register */
crcreg = SPIx->RXCRCR;
}
/* Return the selected CRC register */
return crcreg;
}
/*******************************************************************************
* Function Name : SPI_GetCRCPolynomial
* Description : Returns the CRC Polynomial register value for the specified SPI.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* Output : None
* Return : The CRC Polynomial register value.
*******************************************************************************/
u16 SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
{
/* Return the CRC polynomial register */
return SPIx->CRCPR;
}
/*******************************************************************************
* Function Name : SPI_BiDirectionalLineConfig
* Description : Selects the data transfer direction in bi-directional mode
* for the specified SPI.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* - SPI_Direction: specifies the data transfer direction in
* bi-directional mode.
* This parameter can be one of the following values:
* - SPI_Direction_Tx: Selects Tx transmission direction
* - SPI_Direction_Rx: Selects Rx receive direction
* Output : None
* Return : None
*******************************************************************************/
void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, u16 SPI_Direction)
{
/* Check the parameters */
assert_param(IS_SPI_DIRECTION(SPI_Direction));
if (SPI_Direction == SPI_Direction_Tx)
{
/* Set the Tx only mode */
SPIx->CR1 |= SPI_Direction_Tx;
}
else
{
/* Set the Rx only mode */
SPIx->CR1 &= SPI_Direction_Rx;
}
}
/*******************************************************************************
* Function Name : SPI_GetFlagStatus
* Description : Checks whether the specified SPI flag is set or not.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* - SPI_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* - SPI_FLAG_BSY: Busy flag.
* - SPI_FLAG_OVR: Overrun flag.
* - SPI_FLAG_MODF: Mode Fault flag.
* - SPI_FLAG_CRCERR: CRC Error flag.
* - SPI_FLAG_TXE: Transmit buffer empty flag.
* - SPI_FLAG_RXNE: Receive buffer not empty flag.
* Output : None
* Return : The new state of SPI_FLAG (SET or RESET).
*******************************************************************************/
FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, u16 SPI_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_SPI_GET_FLAG(SPI_FLAG));
/* Check the status of the specified SPI flag */
if ((SPIx->SR & SPI_FLAG) != (u16)RESET)
{
/* SPI_FLAG is set */
bitstatus = SET;
}
else
{
/* SPI_FLAG is reset */
bitstatus = RESET;
}
/* Return the SPI_FLAG status */
return bitstatus;
}
/*******************************************************************************
* Function Name : SPI_ClearFlag
* Description : Clears the SPIx's pending flags.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* - SPI_FLAG: specifies the flag to clear.
* This parameter can be any combination of the following values:
* - SPI_FLAG_OVR: Overrun flag.
* - SPI_FLAG_MODF: Mode Fault flag.
* - SPI_FLAG_CRCERR: CRC Error flag.
* Output : None
* Return : None
*******************************************************************************/
void SPI_ClearFlag(SPI_TypeDef* SPIx, u16 SPI_FLAG)
{
/* Check the parameters */
assert_param(IS_SPI_CLEAR_FLAG(SPI_FLAG));
/* SPI_FLAG_MODF flag clear */
if(SPI_FLAG == SPI_FLAG_MODF)
{
/* Read SR register */
(void)SPIx->SR;
/* Write on CR1 register */
SPIx->CR1 |= CR1_SPE_Set;
}
/* SPI_FLAG_OVR flag clear */
else if(SPI_FLAG == SPI_FLAG_OVR)
{
/* Read SR register */
(void)SPIx->SR;
}
else /* SPI_FLAG_CRCERR flag clear */
{
/* Clear the selected SPI flag */
SPIx->SR &= (u16)~SPI_FLAG;
}
}
/*******************************************************************************
* Function Name : SPI_GetITStatus
* Description : Checks whether the specified SPI interrupt has occurred or not.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* - SPI_IT: specifies the SPI interrupt source to check.
* This parameter can be one of the following values:
* - SPI_IT_OVR: Overrun interrupt.
* - SPI_IT_MODF: Mode Fault interrupt.
* - SPI_IT_CRCERR: CRC Error interrupt.
* - SPI_IT_TXE: Transmit buffer empty interrupt.
* - SPI_IT_RXNE: Receive buffer not empty interrupt.
* Output : None
* Return : The new state of SPI_IT (SET or RESET).
*******************************************************************************/
ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, u8 SPI_IT)
{
ITStatus bitstatus = RESET;
u16 itpos = 0, itmask = 0, enablestatus = 0;
/* Check the parameters */
assert_param(IS_SPI_GET_IT(SPI_IT));
/* Get the SPI IT index */
itpos = (u16)((u16)0x01 << (SPI_IT & (u8)0x0F));
/* Get the SPI IT index */
itmask = SPI_IT >> 4;
/* Set the IT mask */
itmask = (u16)((u16)0x01 << itmask);
/* Get the SPI_IT enable bit status */
enablestatus = (SPIx->CR2 & itmask) ;
/* Check the status of the specified SPI interrupt */
if (((SPIx->SR & itpos) != (u16)RESET) && enablestatus)
{
/* SPI_IT is set */
bitstatus = SET;
}
else
{
/* SPI_IT is reset */
bitstatus = RESET;
}
/* Return the SPI_IT status */
return bitstatus;
}
/*******************************************************************************
* Function Name : SPI_ClearITPendingBit
* Description : Clears the SPIx抯 interrupt pending bits.
* Input : - SPIx: where x can be 1 or 2 to select the SPI peripheral.
* - SPI_IT: specifies the SPI interrupt pending bit to clear.
* This parameter can be one of the following values:
* - SPI_IT_OVR: Overrun interrupt.
* - SPI_IT_MODF: Mode Fault interrupt.
* - SPI_IT_CRCERR: CRC Error interrupt.
* Output : None
* Return : None
*******************************************************************************/
void SPI_ClearITPendingBit(SPI_TypeDef* SPIx, u8 SPI_IT)
{
u16 itpos = 0;
/* Check the parameters */
assert_param(IS_SPI_CLEAR_IT(SPI_IT));
/* SPI_IT_MODF pending bit clear */
if(SPI_IT == SPI_IT_MODF)
{
/* Read SR register */
(void)SPIx->SR;
/* Write on CR1 register */
SPIx->CR1 |= CR1_SPE_Set;
}
else if(SPI_IT == SPI_IT_OVR) /* SPI_IT_OVR pending bit clear */
{
/* Read SR register */
(void)(SPIx->SR);
}
else /* SPI_IT_CRCERR pending bit clear */
{
/* Get the SPI IT index */
itpos = (u16)((u16)0x01 << (SPI_IT & (u8)0x0F));
/* Clear the selected SPI interrupt pending bits */
SPIx->SR &= (u16)~itpos;
}
}
/*******************************************************************************
* Function Name : SPI_Config
* Description : Initializes the SPI1 and CS pins.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* GPIOA and GPIOC Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
/* SPI1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* Configure SPI1 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 PC12 pin: CS pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* SPI1 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(SPI1, &SPI_InitStructure);
/* SPI1 enable */
SPI_Cmd(SPI1, ENABLE);
}
/*****************************************************************************/
esint8 if_readBuf(hwInterface* file,euint32 address,euint8* buf)
{
return(sd_readSector(file,address,buf,512));
}
/*****************************************************************************/
esint8 if_writeBuf(hwInterface* file,euint32 address,euint8* buf)
{
return(sd_writeSector(file,address, buf));
}
/*****************************************************************************/
esint8 if_setPos(hwInterface* file,euint32 address)
{
return(0);
}
/*****************************************************************************/
// Utility-functions which does not toogle CS.
// Only needed during card-init. During init
// the automatic chip-select is disabled for SSP
static euint8 my_if_spiSend(hwInterface *iface, euint8 outgoing)
{
euint8 incoming;
SPI_SendData(SPI1, outgoing);
while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
incoming = SPI_ReceiveData(SPI1);
return(incoming);
}
/*****************************************************************************/
void if_spiInit(hwInterface *iface)
{
euint8 i;
SPI_Config();
MSD_CS_HIGH();
// low speed during init
if_spiSetSpeed(3);
/* Send 20 spi commands with card not selected */
for(i=0;i<21;i++)
my_if_spiSend(iface,0xff);
}
/*****************************************************************************/
void if_spiSetSpeed(euint8 speed)
{
/*speed &= 0xFE;
if ( speed < SPI_PRESCALE_MIN ) speed = SPI_PRESCALE_MIN ;
SPI_PRESCALE_REG = speed;*/
}
/*****************************************************************************/
euint8 if_spiSend(hwInterface *iface, euint8 outgoing)
{
euint8 incoming;
MSD_CS_LOW();
SPI_SendData(SPI1, outgoing);
while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
incoming = SPI_ReceiveData(SPI1);
MSD_CS_HIGH();
return(incoming);
}
esint8 if_initInterface(hwInterface* file, eint8* opts)
{
euint32 sc;
if_spiInit(file);
if(sd_Init(file)<0) {
return(-1);
}
if(sd_State(file)<0){
return(-2);
}
sd_getDriveSize(file, &sc);
file->sectorCount = sc/512;
if( (sc%512) != 0) {
file->sectorCount--;
}
return(0);
}
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -