649 lines
26 KiB
C
649 lines
26 KiB
C
////////////////////////////////////////////////////////////////////////////////
|
|
/// @file hal_spi.c
|
|
/// @author AE TEAM
|
|
/// @brief THIS FILE PROVIDES ALL THE SPI FIRMWARE FUNCTIONS.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @attention
|
|
///
|
|
/// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
|
|
/// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
|
|
/// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
|
|
/// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
|
|
/// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
|
|
/// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
|
|
///
|
|
/// <H2><CENTER>© COPYRIGHT MINDMOTION </CENTER></H2>
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Define to prevent recursive inclusion
|
|
#define _HAL_SPI_C_
|
|
#include <math.h>
|
|
// Files includes
|
|
#include "hal_spi.h"
|
|
#include "hal_rcc.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @addtogroup MM32_Hardware_Abstract_Layer
|
|
/// @{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @addtogroup SPI_HAL
|
|
/// @{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
///@addtogroup SPI_Exported_Functions
|
|
///@{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Deinitializes the spi peripheral registers to their
|
|
/// default reset values.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_DeInit(SPI_TypeDef* spi)
|
|
{
|
|
switch (*(vu32*)&spi) {
|
|
case (u32)SPI2: // SPI2_BASE:
|
|
RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI2, ENABLE);
|
|
RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI2, DISABLE);
|
|
break;
|
|
case (u32)SPI3: // SPI3_BASE:
|
|
RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI3, ENABLE);
|
|
RCC_APB1PeriphResetCmd(RCC_APB1ENR_SPI3, DISABLE);
|
|
break;
|
|
case (u32)SPI1: // SPI1_BASE:
|
|
RCC_APB2PeriphResetCmd(RCC_APB2ENR_SPI1, ENABLE);
|
|
RCC_APB2PeriphResetCmd(RCC_APB2ENR_SPI1, DISABLE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Initializes the spi peripheral according to the specified
|
|
/// parameters in the init_struct .
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param init_struct: pointer to a SPI_InitTypeDef structure
|
|
/// that contains the configuration information for the
|
|
/// specified SPI peripheral.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_Init(SPI_TypeDef* spi, SPI_InitTypeDef* init_struct)
|
|
{
|
|
if (init_struct->SPI_DataSize == SPI_DataSize_32b) {
|
|
SET_BIT(spi->GCR, SPI_GCR_DWSEL);
|
|
}
|
|
else {
|
|
CLEAR_BIT(spi->GCR, SPI_GCR_DWSEL);
|
|
}
|
|
MODIFY_REG(spi->GCR, SPI_GCR_NSS, init_struct->SPI_NSS);
|
|
MODIFY_REG(spi->GCR, SPI_GCR_MODE, init_struct->SPI_Mode);
|
|
MODIFY_REG(spi->CCR, SPI_CCR_LSBFE, init_struct->SPI_FirstBit);
|
|
MODIFY_REG(spi->CCR, SPI_CCR_CPOL, init_struct->SPI_CPOL);
|
|
MODIFY_REG(spi->CCR, SPI_CCR_CPHA, init_struct->SPI_CPHA);
|
|
|
|
SET_BIT(spi->CCR, SPI_CCR_SPILEN);
|
|
|
|
MODIFY_REG(spi->BRR, BRR_Mask, init_struct->SPI_BaudRatePrescaler);
|
|
|
|
if (init_struct->SPI_DataWidth >= 32) {
|
|
MODIFY_REG(spi->ECR, ECR_Mask, 0);
|
|
}
|
|
else {
|
|
MODIFY_REG(spi->ECR, ECR_Mask, init_struct->SPI_DataWidth);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Fills each init_struct member with its default value.
|
|
/// @param init_struct: pointer to a SPI_InitTypeDef structure
|
|
/// which will be initialized.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_StructInit(SPI_InitTypeDef* init_struct)
|
|
{
|
|
init_struct->SPI_Mode = SPI_Mode_Slave;
|
|
init_struct->SPI_DataSize = SPI_DataSize_8b;
|
|
init_struct->SPI_DataWidth = 8;
|
|
init_struct->SPI_CPOL = SPI_CPOL_Low;
|
|
init_struct->SPI_CPHA = SPI_CPHA_1Edge;
|
|
init_struct->SPI_NSS = SPI_NSS_Soft;
|
|
init_struct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
|
|
init_struct->SPI_FirstBit = SPI_FirstBit_MSB;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Enables or disables the specified SPI peripheral.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param state: new state of the spi peripheral.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_Cmd(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->GCR, SPI_GCR_SPIEN) : CLEAR_BIT(spi->GCR, SPI_GCR_SPIEN);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Enables or disables the specified SPI interrupts.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:SPI1, SPI2.
|
|
/// @param interrupt: specifies the SPI interrupt sources to be
|
|
/// enabled or disabled.
|
|
/// This parameter can be one of the following values:
|
|
/// @arg SPI_IT_TXEPT: Transmitter empty interrupt
|
|
/// @arg SPI_IT_RXFULL: RX FIFO full interrupt
|
|
/// @arg SPI_IT_RXMATCH: Receive data match the RXDNR number interrupt
|
|
/// @arg SPI_IT_RXOERR: Receive overrun error interrupt
|
|
/// @arg SPI_IT_UNDERRUN: underrun interrupt
|
|
/// @arg SPI_IT_RX: Receive data available interrupt
|
|
/// @arg SPI_IT_TX: Transmit FIFO available interrupt
|
|
/// @param state: new state of the specified spi interrupts.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_ITConfig(SPI_TypeDef* spi, u8 interrupt, FunctionalState state)
|
|
{
|
|
if (state) {
|
|
SET_BIT(spi->GCR, (u32)SPI_GCR_IEN);
|
|
SET_BIT(spi->IER, (u32)interrupt);
|
|
}
|
|
else {
|
|
CLEAR_BIT(spi->IER, interrupt);
|
|
CLEAR_BIT(spi->GCR, SPI_GCR_IEN);
|
|
}
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Enables or disables the SPI DMA interface.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param state: new state of the DMA Request sources.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_DMACmd(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->GCR, SPI_GCR_DMAEN) : CLEAR_BIT(spi->GCR, SPI_GCR_DMAEN);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief configure tn Fifo trigger level bit.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param fifo_trigger_value: specifies the Fifo trigger level
|
|
/// This parameter can be any combination of the following values:
|
|
/// SPI_TXTLF : SPI TX FIFO Trigger value set
|
|
/// SPI_RXTLF : SPI RX FIFO Trigger value set
|
|
/// @param state: new state of the selected SPI transfer request.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_FifoTrigger(SPI_TypeDef* spi, SPI_TLF_TypeDef fifo_trigger_value, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->GCR, (u32)fifo_trigger_value) : CLEAR_BIT(spi->GCR, (u32)fifo_trigger_value);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Transmits a Data through the spi peripheral.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param data : Data to be transmitted.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_SendData(SPI_TypeDef* spi, u32 data)
|
|
{
|
|
u16 templen;
|
|
__asm volatile("cpsid i");
|
|
|
|
WRITE_REG(spi->TDR, data);
|
|
|
|
templen = READ_REG(spi->ECR);
|
|
if(templen == 0)
|
|
templen = 32;
|
|
if (templen > 8)
|
|
WRITE_REG(spi->TDR, data >> 8);
|
|
if (templen > 16)
|
|
WRITE_REG(spi->TDR, data >> 16);
|
|
if (templen > 24)
|
|
WRITE_REG(spi->TDR, data >> 24);
|
|
__asm volatile("cpsie i");
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Returns the most recent received data by the spi peripheral.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @retval The value of the received data.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
u32 SPI_ReceiveData(SPI_TypeDef* spi)
|
|
{
|
|
u32 temp;
|
|
u8 templen;
|
|
__asm volatile("cpsid i");
|
|
|
|
temp = READ_REG(spi->RDR);
|
|
|
|
templen = READ_REG(spi->ECR);
|
|
if(templen == 0)
|
|
templen = 32;
|
|
if (templen > 8)
|
|
temp |= (u32)(READ_REG(spi->RDR) << 8);
|
|
if (templen > 16)
|
|
temp |= (u32)(READ_REG(spi->RDR) << 16);
|
|
if (templen > 24)
|
|
temp |= (u32)(READ_REG(spi->RDR) << 24);
|
|
|
|
__asm volatile("cpsie i");
|
|
|
|
return temp;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Slave chip csn single by selected
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param state: new state of the selected SPI CS pin
|
|
/// request.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_CSInternalSelected(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? CLEAR_BIT(spi->NSSR, SPI_NSSR_NSS) : SET_BIT(spi->NSSR, SPI_NSSR_NSS); // illogical
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Configures the NSS pin control mode for the selected SPI.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param nss: specifies the SPI NSS internal state.
|
|
/// This parameter can be one of the following values:
|
|
/// @arg SPI_NSS_Soft: NSS pin control by software
|
|
/// @arg SPI_NSS_Hard: NSS pin control by hardware
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* spi, SPI_NSS_TypeDef nss)
|
|
{
|
|
(nss != SPI_NSS_Soft) ? SET_BIT(spi->GCR, SPI_NSS_Hard) : CLEAR_BIT(spi->GCR, SPI_NSS_Hard);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Configures the data size for the selected SPI.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param data_size: specifies the SPI data size.
|
|
/// This parameter can be one of the following values:
|
|
/// 0 to 31, 0 = 32b, 1 = 1b, 2 = 2b
|
|
/// @arg DataSize : 0 to 31
|
|
/// @retval None.
|
|
/// @retval None.
|
|
bool SPI_DataSizeConfig(SPI_TypeDef* spi, u8 data_size)
|
|
{
|
|
if (data_size > 32)
|
|
return false;
|
|
data_size &= 0x1F;
|
|
WRITE_REG(spi->ECR, data_size);
|
|
return true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_DataSizeTypeConfig(SPI_TypeDef* spi, SPI_DataSize_TypeDef SPI_DataSize)
|
|
{
|
|
CLEAR_BIT(spi->GCR, (u32)SPI_DataSize_32b);
|
|
SET_BIT(spi->GCR, (u32)SPI_DataSize);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Selects the data transfer direction in bi-directional mode
|
|
/// for the specified SPI.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param direction: specifies the data transfer direction in
|
|
/// bi-directional mode.
|
|
/// This parameter can be one of the following values:
|
|
/// @arg SPI_Direction_Tx: Selects Tx transmission direction
|
|
/// @arg SPI_Direction_Rx: Selects Rx receive direction
|
|
/// @arg SPI_Disable_Tx: Selects Rx receive direction
|
|
/// @arg SPI_Disable_Rx: Selects Rx receive direction
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_BiDirectionalLineConfig(SPI_TypeDef* spi, SPI_Direction_TypeDef direction)
|
|
{
|
|
switch (direction) {
|
|
case SPI_Direction_Rx:
|
|
SET_BIT(spi->GCR, SPI_GCR_RXEN);
|
|
break;
|
|
case SPI_Direction_Tx:
|
|
SET_BIT(spi->GCR, SPI_GCR_TXEN);
|
|
break;
|
|
case SPI_Disable_Rx:
|
|
CLEAR_BIT(spi->GCR, SPI_GCR_RXEN);
|
|
break;
|
|
case SPI_Disable_Tx:
|
|
CLEAR_BIT(spi->GCR, SPI_GCR_TXEN);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Checks whether the specified SPI flag is set or not.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param flag: specifies the SPI flag to check.
|
|
/// This parameter can be one of the following values:
|
|
/// @arg SPI_FLAG_RXAVL: Rx buffer has bytes flag
|
|
/// @arg SPI_FLAG_TXEPT: Tx buffer and tx shifter empty flag
|
|
/// @arg SPI_FLAG_TXFULL: Tx buffer full flag
|
|
/// @arg SPI_FLAG_RXAVL_4BYTE: Receive available 4 byte data message flag.
|
|
/// @retval The new state of SPI_FLAG (SET or RESET).
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
FlagStatus SPI_GetFlagStatus(SPI_TypeDef* spi, SPI_FLAG_TypeDef flag)
|
|
{
|
|
// u8 number;
|
|
return (spi->SR & flag) ? SET : RESET;
|
|
// if (spi->ECR == 8 || spi->ECR == 0)
|
|
// return (spi->SR & SPI_FLAG) ? SET : RESET;
|
|
// else {
|
|
// if ((spi->ECR > 0) && (spi->ECR <= 8))
|
|
// number = 1;
|
|
// else if ((spi->ECR) <= 16)
|
|
// number = 2;
|
|
// else if ((spi->ECR) <= 24)
|
|
// number = 3;
|
|
// else if (((spi->ECR) <= 31) || (spi->ECR == 0))
|
|
// number = 4;
|
|
// return (((spi->SR & 0xf00) >> 8) >= number) ? SET : RESET;
|
|
// }
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Checks whether the specified SPI interrupt has occurred or not.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param interrupt: specifies the SPI interrupt source to check.
|
|
/// This parameter can be one of the following values:
|
|
/// @arg SPI_IT_TX: Tx buffer empty interrupt
|
|
/// @arg SPI_IT_RX: Rx buffer interrupt
|
|
/// @arg SPI_IT_UNDERRUN: under Error interrupt in slave mode
|
|
/// @arg SPI_IT_RXOVER: RX OVER Error interrupt
|
|
/// @arg SPI_IT_RXMATCH: spectials rx data numbers interrupt
|
|
/// @arg SPI_IT_RXFULL: Rx buffer full interrupt
|
|
/// @arg SPI_IT_TXEPT: Tx buffer and tx shifter empty interrupt
|
|
/// @retval The new state of SPI_IT (SET or RESET).
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
ITStatus SPI_GetITStatus(SPI_TypeDef* spi, SPI_IT_TypeDef interrupt)
|
|
{
|
|
return (spi->ISR & interrupt) ? SET : RESET;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Clears the spi interrupt pending bit.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param interrupt: specifies the SPI interrupt pending bit to clear.
|
|
/// @arg SPI_IT_TX: Tx buffer empty interrupt
|
|
/// @arg SPI_IT_RX: Rx buffer interrupt
|
|
/// @arg SPI_IT_UNDERRUN: under Error interrupt in slave mode
|
|
/// @arg SPI_IT_RXOVER: RX OVER Error interrupt
|
|
/// @arg SPI_IT_RXMATCH: spectials rx data numbers interrupt
|
|
/// @arg SPI_IT_RXFULL: Rx buffer full interrupt
|
|
/// @arg SPI_IT_TXEPT: Tx buffer and tx shifter empty interrupt
|
|
/// This function clears only ERR intetrrupt pending bit.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_ClearITPendingBit(SPI_TypeDef* spi, SPI_IT_TypeDef interrupt)
|
|
{
|
|
SET_BIT(spi->ICR, interrupt);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief SPI Hole a count Received bytes in next receive process.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param number: specifies the SPI receive Number.
|
|
/// This parament can be 1-65535.
|
|
/// This function can use only in SPI master single receive mode.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_RxBytes(SPI_TypeDef* spi, u16 number)
|
|
{
|
|
WRITE_REG(spi->RDNR, number);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief slave mode tx data transmit phase adjust set.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param adjust_value: slave mode tx data transmit phase adjust enum.
|
|
/// This parament can be :
|
|
/// SPI_SlaveAdjust_FAST: fast speed use
|
|
/// SPI_SlaveAdjust_LOW: low speed use
|
|
/// This function can use only in SPI master single receive mode.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SPI_SlaveAdjust(SPI_TypeDef* spi, SPI_SlaveAdjust_TypeDef adjust_value)
|
|
{
|
|
(adjust_value) ? SET_BIT(spi->CCR, SPI_CCR_RXEDGE) : CLEAR_BIT(spi->CCR, SPI_CCR_RXEDGE);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Enables or disables all SPI interrupts.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param state: new state of all spi interrupts.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void exSPI_ITCmd(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->IER, (u32)SPI_GCR_IEN) : CLEAR_BIT(spi->IER, (u32)SPI_GCR_IEN);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Enables or disables the specified SPI interrupts.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param interrupt: specifies the SPI interrupt sources to be enabled or disabled.
|
|
/// This parameter can be one of the following values:
|
|
/// @arg SPI_IT_TXEPT: Transmitter empty interrupt
|
|
/// @arg SPI_IT_RXFULL: RX FIFO full interrupt
|
|
/// @arg SPI_IT_RXMATCH: Receive data match the RXDNR number interrupt
|
|
/// @arg SPI_IT_RXOERR: Receive overrun error interrupt
|
|
/// @arg SPI_IT_UNDERRUN: underrun interrupt
|
|
/// @arg SPI_IT_RX: Receive data available interrupt
|
|
/// @arg SPI_IT_TX: Transmit FIFO available interrupt
|
|
/// @param state: new state of the specified spi interrupts.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void exSPI_ITConfig(SPI_TypeDef* spi, SPI_IT_TypeDef interrupt, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->IER, (u32)interrupt) : CLEAR_BIT(spi->IER, (u32)interrupt);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Enables or disables the SPI DMA request.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param state: new state of the DMA Request.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void exSPI_DMACmd(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->GCR, SPI_GCR_DMAEN) : CLEAR_BIT(spi->GCR, SPI_GCR_DMAEN);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Set or reset Slave chip csn signal output
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param state: new state of Slave chip csn signal output.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void exSPI_CSInternalSelected(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? CLEAR_BIT(spi->NSSR, SPI_NSSR_NSS) : SET_BIT(spi->NSSR, SPI_NSSR_NSS); // illogical
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tx data and rx data phase adjust.
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2.
|
|
/// @param adjust_value: choose adjust mode.
|
|
/// This parament can be :
|
|
/// SPI_DataEdgeAdjust_LOW,
|
|
/// SPI_DataEdgeAdjust_FAST
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void exSPI_DataEdgeAdjust(SPI_TypeDef* spi, SPI_DataEdgeAdjust_TypeDef adjust_value)
|
|
{
|
|
// master mode
|
|
if (spi->GCR & SPI_GCR_MODE) {
|
|
adjust_value ? SET_BIT(spi->CCR, SPI_CCR_RXEDGE) : CLEAR_BIT(spi->CCR, SPI_CCR_RXEDGE);
|
|
}
|
|
// slave mode
|
|
else {
|
|
adjust_value ? SET_BIT(spi->CCR, SPI_CCR_TXEDGE) : CLEAR_BIT(spi->CCR, SPI_CCR_TXEDGE);
|
|
}
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Set or reset i2s
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2, SPI3.
|
|
/// @param state: new state of Slave chip csn signal output.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void I2S_Cmd(SPI_TypeDef* spi, FunctionalState state)
|
|
{
|
|
(state) ? SET_BIT(spi->CFGR, I2S_CFGR_SPI_I2S) : CLEAR_BIT(spi->CFGR, I2S_CFGR_SPI_I2S);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief i2s Config
|
|
/// @param spi: Select the SPI peripheral.
|
|
/// This parameter can be one of the following values:
|
|
/// SPI1, SPI2, SPI3.
|
|
/// @param state: new state of Slave chip csn signal output.
|
|
/// This parameter can be: ENABLE or DISABLE.
|
|
/// @retval None.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void I2S_Init(SPI_TypeDef* spi, I2S_InitTypeDef* I2S_InitStruct)
|
|
{
|
|
u32 i2sdiv = 2;
|
|
u32 tmpreg = 0;
|
|
u32 packetlength = 1;
|
|
u32 result = 0, yushu = 0;
|
|
u32 sourceclock = 0;
|
|
RCC_ClocksTypeDef RCC_Clocks;
|
|
|
|
if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) {
|
|
i2sdiv = 2;
|
|
}
|
|
else {
|
|
if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) {
|
|
packetlength = 1;
|
|
}
|
|
else {
|
|
packetlength = 2;
|
|
}
|
|
RCC_GetClocksFreq(&RCC_Clocks);
|
|
|
|
if((SPI2 == spi) || (SPI3 == spi)) {
|
|
sourceclock = RCC_Clocks.PCLK1_Frequency;
|
|
}
|
|
else {
|
|
sourceclock = RCC_Clocks.PCLK2_Frequency;
|
|
}
|
|
if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) {
|
|
result = (sourceclock) / (256 * (I2S_InitStruct->I2S_AudioFreq));
|
|
yushu = (sourceclock) % (256 * (I2S_InitStruct->I2S_AudioFreq));
|
|
if(yushu > (128 * (I2S_InitStruct->I2S_AudioFreq))) {
|
|
result = result + 1;
|
|
}
|
|
i2sdiv = result;
|
|
if ((i2sdiv < 2) || (i2sdiv > 0x1FF)) {
|
|
i2sdiv = 2;
|
|
}
|
|
}
|
|
else {
|
|
result = (sourceclock) / (16 * 2 * packetlength * (I2S_InitStruct->I2S_AudioFreq));
|
|
yushu = (sourceclock) % (16 * 2 * packetlength * (I2S_InitStruct->I2S_AudioFreq));
|
|
if(yushu > ((16 * packetlength * (I2S_InitStruct->I2S_AudioFreq)))) {
|
|
result = result + 1;
|
|
}
|
|
if ((i2sdiv < 1) || (i2sdiv > 0x1FF)) {
|
|
i2sdiv = 1;
|
|
}
|
|
}
|
|
}
|
|
if(I2S_CPOL_High == I2S_InitStruct->I2S_CPOL) {
|
|
spi->CCTL |= SPI_CCR_CPOL;
|
|
}
|
|
else {
|
|
spi->CCTL &= ~SPI_CCR_CPOL;
|
|
}
|
|
|
|
spi->CFGR = 0x2 << I2S_CFGR_I2SDIV_Pos;
|
|
|
|
if((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_MasterRx)) {
|
|
spi->GCTL |= SPI_GCR_MODE;
|
|
}
|
|
else {
|
|
spi->GCTL &= ~SPI_GCR_MODE;
|
|
}
|
|
if((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveTx)) {
|
|
spi->GCTL |= SPI_GCR_TXEN;
|
|
spi->GCTL &= ~SPI_GCR_RXEN;
|
|
}
|
|
else {
|
|
spi->GCTL &= ~SPI_GCR_TXEN;
|
|
spi->GCTL |= SPI_GCR_RXEN;
|
|
}
|
|
// tmpreg = spi->GCTL;
|
|
// tmpreg &= ~(1 << 2);
|
|
// tmpreg |= (u16)(I2S_InitStruct->I2S_Mode);
|
|
// spi->GCTL = tmpreg;
|
|
//
|
|
tmpreg = 0;
|
|
tmpreg |= (i2sdiv << I2S_CFGR_I2SDIV_Pos) | \
|
|
(I2S_InitStruct->I2S_MCLKOutput) | \
|
|
(I2S_CFGR_SPI_I2S) | \
|
|
(I2S_InitStruct->I2S_Standard) | \
|
|
(I2S_InitStruct->I2S_DataFormat);
|
|
spi->CFGR &= ~I2S_CFGR_I2SDIV;
|
|
spi->CFGR |= tmpreg;
|
|
|
|
}
|
|
/// @}
|
|
|
|
/// @}
|
|
|
|
/// @}
|