MXC-A36-Demo/MCU/components/drivers/peripheral/Src/driver_spi_master.c

1054 lines
28 KiB
C
Raw Blame History

/*
******************************************************************************
* @file driver_spi_master.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief SPI module driver.
* This file provides firmware functions to manage the
* Serial Peripheral Interface (SPI) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
static void spi_master_tx_u8(SPI_HandleTypeDef *hspi)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u8[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
break;
}
}
}
static void spi_master_tx_u16(SPI_HandleTypeDef *hspi)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u16[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
break;
}
}
}
static void spi_master_tx_u32(SPI_HandleTypeDef *hspi)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u32[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
break;
}
}
}
static void spi_master_rx_u8(SPI_HandleTypeDef *hspi)
{
while (!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
hspi->u_RxData.p_u8[hspi->u32_RxCount++] = hspi->SPIx->DR;
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
break;
}
}
}
static void spi_master_rx_u16(SPI_HandleTypeDef *hspi)
{
while (!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
hspi->u_RxData.p_u16[hspi->u32_RxCount++] = hspi->SPIx->DR;
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
break;
}
}
}
static void spi_master_rx_u32(SPI_HandleTypeDef *hspi)
{
while (!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
hspi->u_RxData.p_u32[hspi->u32_RxCount++] = hspi->SPIx->DR;
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
break;
}
}
}
/************************************************************************************
* @fn spi_master_IRQHandler
*
* @brief Handle SPI interrupt request.
*
* @param hspi: SPI handle.
*/
void spi_master_IRQHandler(SPI_HandleTypeDef *hspi)
{
uint8_t frame_size;
/* Tx FIFO Threshold EMPTY */
if (__SPI_TxFIFO_EMPTY_INT_STATUS(hspi->SPIx))
{
frame_size = __SPI_DATA_FRAME_SIZE_GET(hspi->SPIx);
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
spi_master_tx_u8(hspi);
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
spi_master_tx_u16(hspi);
}
else
{
spi_master_tx_u32(hspi);
}
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
__SPI_TxFIFO_EMPTY_INT_DISABLE(hspi->SPIx);
hspi->b_TxBusy = false;
if (hspi->TxCpltCallback != NULL)
{
hspi->TxCpltCallback(hspi);
}
}
}
/* Rx FIFO Threshold FULL */
else if (__SPI_RxFIFO_FULL_INT_STATUS(hspi->SPIx))
{
frame_size = hspi->SPIx->CTRL0.DFS_32;
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
spi_master_rx_u8(hspi);
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
spi_master_rx_u16(hspi);
}
else
{
spi_master_rx_u32(hspi);
}
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
__SPI_RxFIFO_FULL_INT_DISABLE(hspi->SPIx);
hspi->b_RxBusy = false;
if (hspi->RxCpltCallback != NULL)
{
hspi->RxCpltCallback(hspi);
}
}
}
}
/************************************************************************************
* @fn spi_master_init
*
* @brief Initialize the SPI according to the specified parameters in the struct_SPIInit_t
*
* @param hspi: SPI handle.
*/
void spi_master_init(SPI_HandleTypeDef *hspi)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Work mode */
hspi->SPIx->CTRL0.SCPOL = hspi->Init.Work_Mode & 0x2 ? 1 : 0;
hspi->SPIx->CTRL0.SCPH = hspi->Init.Work_Mode & 0x1 ? 1 : 0;
/* Frame Size */
hspi->SPIx->CTRL0.DFS_32 = hspi->Init.Frame_Size;
/* BaudRate Prescaler */
hspi->SPIx->BAUDR = hspi->Init.BaudRate_Prescaler;
/* FIFO Threshold */
hspi->SPIx->TXFTLR = hspi->Init.TxFIFOEmpty_Threshold;
hspi->SPIx->RXFTLR = hspi->Init.RxFIFOFull_Threshold;
/* Disable all interrupt */
hspi->SPIx->IMR.MSTIM = 0;
hspi->SPIx->IMR.TXEIM = 0;
hspi->SPIx->IMR.TXOIM = 0;
hspi->SPIx->IMR.RXUIM = 0;
hspi->SPIx->IMR.RXOIM = 0;
hspi->SPIx->IMR.RXFIM = 0;
__SPI_CS_TOGGLE_DISABLE(hspi->SPIx);
/* CS Set */
hspi->SPIx->SER = 1;
}
/************************************************************************************
* @fn spi_master_transmit_X1
*
* @brief Send an amount of data in blocking mode.(Standard mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be sent
*/
void spi_master_transmit_X1(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
uint8_t frame_size;
union {
void *data;
uint8_t *p_u8;
uint16_t *p_u16;
uint32_t *p_u32;
} p_data;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Select RxTx mode */
__SPI_TMODE_RxTx(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* Get current frame size */
frame_size = __SPI_DATA_FRAME_SIZE_GET(hspi->SPIx);
p_data.data = fp_Data;
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u8++;
}
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u16++;
}
}
else
{
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u32++;
}
}
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while(__SPI_IS_BUSY(hspi->SPIx));
}
/************************************************************************************
* @fn spi_master_transmit_X1_IT
*
* @brief Send an amount of data in interrupt mode.(Standard mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be sent
*/
void spi_master_transmit_X1_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
if (hspi->b_TxBusy)
return;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Select RxTx mode */
__SPI_TMODE_RxTx(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
hspi->u32_TxSize = fu32_Size;
hspi->u32_TxCount = 0;
hspi->u_TxData.p_data = fp_Data;
hspi->b_TxBusy = true;
/* TxFIFO empty interrupt enable */
__SPI_TxFIFO_EMPTY_INT_ENABLE(hspi->SPIx);
}
/************************************************************************************
* @fn spi_master_transmit_X1_DMA
*
* @brief Send an amount of data in DMA mode.(Standard mode)
*
* @param hspi: SPI handle.
*/
void spi_master_transmit_X1_DMA(SPI_HandleTypeDef *hspi)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Clear DMA signals */
__SPI_DMA_TX_DISABLE(hspi->SPIx);
/* Select RxTx mode */
__SPI_TMODE_RxTx(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* DMA Config */
__SPI_DMA_TX_ENABLE(hspi->SPIx);
__SPI_DMA_TX_LEVEL(hspi->SPIx, hspi->Init.TxFIFOEmpty_Threshold);
}
/************************************************************************************
* @fn spi_master_receive_X1
*
* @brief Receive an amount of data in blocking mode.(Standard mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be Receive
*/
void spi_master_receive_X1(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
uint8_t frame_size;
union {
void *data;
uint8_t *p_u8;
uint16_t *p_u16;
uint32_t *p_u32;
} p_data;
uint32_t RxCount = fu32_Size;
uint32_t TxCount = fu32_Size;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Select RxTx mode */
__SPI_TMODE_RxTx(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* Get current frame size */
frame_size = __SPI_DATA_FRAME_SIZE_GET(hspi->SPIx);
p_data.data = fp_Data;
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
while (RxCount)
{
/* write data to tx FIFO */
if (!__SPI_IS_TxFIFO_FULL(hspi->SPIx) && TxCount)
{
hspi->SPIx->DR = 0x00;
TxCount--;
}
while(!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
*p_data.p_u8++ = hspi->SPIx->DR;
RxCount--;
}
}
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
while (RxCount)
{
/* write data to tx FIFO */
if (!__SPI_IS_TxFIFO_FULL(hspi->SPIx) && TxCount)
{
hspi->SPIx->DR = 0x00;
TxCount--;
}
while(!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
*p_data.p_u16++ = hspi->SPIx->DR;
RxCount--;
}
}
}
else
{
while (RxCount)
{
/* write data to tx FIFO */
if (!__SPI_IS_TxFIFO_FULL(hspi->SPIx) && TxCount)
{
hspi->SPIx->DR = 0x00;
TxCount--;
}
while(!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
*p_data.p_u32++ = hspi->SPIx->DR;
RxCount--;
}
}
}
while(__SPI_IS_BUSY(hspi->SPIx));
}
/************************************************************************************
* @fn spi_master_readflash_X1
*
* @brief ReadFlash mode. First send the command address, And then receive the data
*
* @param hspi: SPI handle.
* fp_CMD_ADDR: Command and Address.
* fu32_CMDLegnth: Command and Address Length.
* fp_Data : pointer to data buffer.
* fu16_Size : amount of data to be Receive.
*/
void spi_master_readflash_X1(SPI_HandleTypeDef *hspi, uint16_t *fp_CMD_ADDR, uint32_t fu32_CMDLegnth, uint8_t *fp_Data, uint16_t fu16_Size)
{
uint8_t *lp8_Data;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Select flash read mode */
__SPI_TMODE_FLASH_READ(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
/* Config receive data size */
hspi->SPIx->CTRL1.NDF = fu16_Size - 1;
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* Frame Size <= 8 */
if (hspi->SPIx->CTRL0.DFS_32 <= SPI_FRAME_SIZE_8BIT)
{
lp8_Data = (uint8_t *)fp_CMD_ADDR;
while (fu32_CMDLegnth--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *lp8_Data++;
}
lp8_Data = (uint8_t *)fp_Data;
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while (__SPI_IS_BUSY(hspi->SPIx))
{
if (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*lp8_Data++ = hspi->SPIx->DR;
}
}
while (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*lp8_Data++ = hspi->SPIx->DR;
}
}
else
{
while (fu32_CMDLegnth--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *fp_CMD_ADDR++;
}
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while (__SPI_IS_BUSY(hspi->SPIx))
{
if (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*fp_Data++ = hspi->SPIx->DR;
}
}
while (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*fp_Data++ = hspi->SPIx->DR;
}
}
}
/************************************************************************************
* @fn spi_master_readflash_X1_IT
*
* @brief ReadFlash mode. First send the command address, And then receive the data
*
* @param hspi: SPI handle.
* fp_CMD_ADDR: Command and Address.
* fu32_CMDLegnth: Command and Address Length.
* fp_RxData : pointer to data buffer.
* fu16_Size : amount of data to be Receive.
*/
void spi_master_readflash_X1_IT(SPI_HandleTypeDef *hspi, uint8_t *fp_CMD_ADDR, uint32_t fu32_CMDLegnth, uint8_t *fp_Data, uint16_t fu16_Size)
{
uint8_t *lp8_Data;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Select flash read mode */
__SPI_TMODE_FLASH_READ(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
/* Config receive data size */
hspi->SPIx->CTRL1.NDF = fu16_Size - 1;
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
hspi->u32_RxSize = fu16_Size;
hspi->u32_RxCount = 0;
hspi->b_RxBusy = true;
hspi->u_RxData.p_data = (uint8_t *)fp_Data;
/* Frame Size <= 8 */
if (hspi->SPIx->CTRL0.DFS_32 <= SPI_FRAME_SIZE_8BIT)
{
while (fu32_CMDLegnth--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *fp_CMD_ADDR++;
}
}
/* RxFIFO full interrupt enable */
__SPI_RxFIFO_FULL_INT_ENABLE(hspi->SPIx);
}
/************************************************************************************
* @fn spi_master_readflash_X1_DMA
*
* @brief ReadFlash mode. First send the command address, And then receive the data
*
* @param hspi: SPI handle.
* fp_CMD_ADDR: Command and Address.
* fu32_CMDLegnth: Command and Address Length.
* fu16_Size : amount of data to be Receive.
*/
void spi_master_readflash_X1_DMA(SPI_HandleTypeDef *hspi, uint8_t *fp_CMD_ADDR, uint32_t fu32_CMDLegnth, uint16_t fu16_Size)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Clear DMA signals */
__SPI_DMA_RX_DISABLE(hspi->SPIx);
/* Select flash read mode */
__SPI_TMODE_FLASH_READ(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
/* DMA Config */
__SPI_DMA_RX_ENABLE(hspi->SPIx);
__SPI_DMA_RX_LEVEL(hspi->SPIx, hspi->Init.RxFIFOFull_Threshold);
/* Config receive data size */
hspi->SPIx->CTRL1.NDF = fu16_Size - 1;
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
while (fu32_CMDLegnth--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *fp_CMD_ADDR++;
}
}
/************************************************************************************
* @fn spi_master_transmit_X2X4X8
*
* @brief Send an amount of data in blocking mode.(Dual<61><6C>Quad and Octal mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be sent
*/
void spi_master_transmit_X2X4X8(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
uint8_t frame_size;
union {
void *data;
uint8_t *p_u8;
uint16_t *p_u16;
uint32_t *p_u32;
} p_data;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* config Mult Wire Transfer parameters */
spi_master_MultWireConfig(hspi, Wire_Write);
/* Select Only Tx mode */
__SPI_TMODE_Tx_ONLY(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* Get current frame size */
frame_size = __SPI_DATA_FRAME_SIZE_GET(hspi->SPIx);
p_data.data = fp_Data;
//#define SPI_FIFO_DEPTH 128
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
#ifdef SPI_FIFO_DEPTH
while(fu32_Size >= SPI_FIFO_DEPTH)
{
uint32_t u32_l = SPI_FIFO_DEPTH;
while (u32_l--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u8++;
}
fu32_Size -= SPI_FIFO_DEPTH;
while(__SPI_IS_TxFIFO_EMPTY(hspi->SPIx) == 0);
}
while (fu32_Size--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u8++;
}
#else
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u8++;
}
#endif
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
#ifdef SPI_FIFO_DEPTH
while(fu32_Size >= SPI_FIFO_DEPTH)
{
uint32_t u32_l = SPI_FIFO_DEPTH;
while (u32_l--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u16++;
}
fu32_Size -= SPI_FIFO_DEPTH;
while(__SPI_IS_TxFIFO_EMPTY(hspi->SPIx) == 0);
}
while (fu32_Size--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u16++;
}
#else
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u16++;
}
#endif
}
else
{
#ifdef SPI_FIFO_DEPTH
while(fu32_Size >= SPI_FIFO_DEPTH)
{
uint32_t u32_l = SPI_FIFO_DEPTH;
while (u32_l--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u32++;
}
fu32_Size -= SPI_FIFO_DEPTH;
while(__SPI_IS_TxFIFO_EMPTY(hspi->SPIx) == 0);
}
while (fu32_Size--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u32++;
}
#else
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u32++;
}
#endif
}
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while(__SPI_IS_BUSY(hspi->SPIx));
}
/************************************************************************************
* @fn spi_master_transmit_X2X4X8_IT
*
* @brief Send an amount of data in interrupt mode.(Dual<61><6C>Quad and Octal mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be sent
*/
void spi_master_transmit_X2X4X8_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
uint8_t *lp8_Data;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* config Mult Wire Transfer parameters */
spi_master_MultWireConfig(hspi, Wire_Write);
/* Select Only Tx mode */
__SPI_TMODE_Tx_ONLY(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
hspi->u32_TxSize = fu32_Size;
hspi->u32_TxCount = 0;
hspi->b_TxBusy = true;
hspi->u_TxData.p_data = (uint8_t *)fp_Data;
/* TxFIFO empty interrupt enable */
__SPI_TxFIFO_EMPTY_INT_ENABLE(hspi->SPIx);
}
/************************************************************************************
* @fn spi_master_transmit_X2X4X8_IT
*
* @brief Send an amount of data in DMA mode.(Dual<61><6C>Quad and Octal mode)
*
* @param hspi: SPI handle.
*/
void spi_master_transmit_X2X4X8_DMA(SPI_HandleTypeDef *hspi)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Clear DMA signals */
__SPI_DMA_TX_DISABLE(hspi->SPIx);
/* config Mult Wire Transfer parameters */
spi_master_MultWireConfig(hspi, Wire_Write);
/* Select Only Tx mode */
__SPI_TMODE_Tx_ONLY(hspi->SPIx);
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* DMA Config */
__SPI_DMA_TX_ENABLE(hspi->SPIx);
__SPI_DMA_TX_LEVEL(hspi->SPIx, hspi->Init.TxFIFOEmpty_Threshold);
}
/************************************************************************************
* @fn spi_master_receive_X2X4X8
*
* @brief Receive an amount of data in blocking mode.(Dual<61><6C>Quad and Octal mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu16_Size: amount of data to be Receive
*/
void spi_master_receive_X2X4X8(SPI_HandleTypeDef *hspi, void *fp_Data, uint16_t fu16_Size)
{
uint8_t frame_size;
union {
void *data;
uint8_t *p_u8;
uint16_t *p_u16;
uint32_t *p_u32;
} p_data;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Config receive data size */
hspi->u32_RxSize = fu16_Size - 1;
/* config Mult Wire Transfer parameters */
spi_master_MultWireConfig(hspi, Wire_Read);
/* Get current frame size */
frame_size = __SPI_DATA_FRAME_SIZE_GET(hspi->SPIx);
p_data.data = fp_Data;
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while (__SPI_IS_BUSY(hspi->SPIx))
{
if (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*p_data.p_u8++ = hspi->SPIx->DR;
}
}
while (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*p_data.p_u8++ = hspi->SPIx->DR;
}
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while (__SPI_IS_BUSY(hspi->SPIx))
{
if (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*p_data.p_u16++ = hspi->SPIx->DR;
}
}
while (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*p_data.p_u16++ = hspi->SPIx->DR;
}
}
else
{
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while (__SPI_IS_BUSY(hspi->SPIx))
{
if (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*p_data.p_u32++ = hspi->SPIx->DR;
}
}
while (__SPI_IS_RxFIFO_NOT_EMPTY(hspi->SPIx))
{
*p_data.p_u32++ = hspi->SPIx->DR;
}
}
}
/************************************************************************************
* @fn spi_master_receive_X2X4X8_IT
*
* @brief Receive an amount of data in interrupt mode.(Dual<61><6C>Quad and Octal mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu16_Size: amount of data to be Receive
*/
void spi_master_receive_X2X4X8_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint16_t fu16_Size)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Config receive data size */
hspi->u32_RxSize = fu16_Size - 1;
/* config Mult Wire Transfer parameters */
spi_master_MultWireConfig(hspi, Wire_Read);
hspi->u32_RxSize = fu16_Size;
hspi->u32_RxCount = 0;
hspi->u_RxData.p_data = fp_Data;
hspi->b_RxBusy = true;
/* RxFIFO full interrupt enable */
__SPI_RxFIFO_FULL_INT_ENABLE(hspi->SPIx);
}
/************************************************************************************
* @fn spi_master_receive_X2X4X8_DMA
*
* @brief Receive an amount of data in DMA mode.(Dual<61><6C>Quad and Octal mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu16_Size: amount of data to be Receive
*/
void spi_master_receive_X2X4X8_DMA(SPI_HandleTypeDef *hspi, uint16_t fu16_Size)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Clear DMA signals */
__SPI_DMA_RX_DISABLE(hspi->SPIx);
/* DMA Config */
__SPI_DMA_RX_LEVEL(hspi->SPIx, hspi->Init.RxFIFOFull_Threshold);
__SPI_DMA_RX_ENABLE(hspi->SPIx);
/* Config receive data size */
hspi->u32_RxSize = fu16_Size - 1;
/* config Mult Wire Transfer parameters */
spi_master_MultWireConfig(hspi, Wire_Read);
}
/************************************************************************************
* @fn spi_master_MultWireConfig
*
* @brief config Mult Wire Transfer parameters.(DualbQuad mode)
*
* @param hspi: SPI handle.
*/
void spi_master_MultWireConfig(SPI_HandleTypeDef *hspi, enum_Wire_Type_t fe_type)
{
uint8_t lu8_Buffer[8];
uint8_t lu8_Count = 0, i = 0;
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
if (fe_type == Wire_Write)
{
/* Frame Size */
__SPI_DATA_FRAME_SIZE(hspi->SPIx, SPI_FRAME_SIZE_8BIT);
/* Select RxTx mode */
__SPI_TMODE_RxTx(hspi->SPIx);
/* Select Standard mode */
__SPI_SET_MODE_X1(hspi->SPIx);
__SPI_ENABLE(hspi->SPIx);
if (hspi->MultWireParam.InstructLength == INST_16BIT)
{
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Instruct >> 8 & 0xFF;
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Instruct & 0xFF;
}
else if (hspi->MultWireParam.InstructLength == INST_8BIT)
{
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Instruct & 0xFF;
}
if (hspi->MultWireParam.AddressLength >= ADDR_32BIT)
{
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Address >> 24 & 0xFF;
}
if (hspi->MultWireParam.AddressLength >= ADDR_24BIT)
{
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Address >> 16 & 0xFF;
}
if (hspi->MultWireParam.AddressLength >= ADDR_16BIT)
{
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Address >> 8 & 0xFF;
}
if (hspi->MultWireParam.AddressLength >= ADDR_8BIT)
{
lu8_Buffer[lu8_Count++] = hspi->MultWireParam.Address & 0xFF;
}
while (lu8_Count--)
{
/* write data to tx FIFO */
hspi->SPIx->DR = lu8_Buffer[i++];
}
while(!__SPI_IS_TxFIFO_EMPTY(hspi->SPIx));
while(__SPI_IS_BUSY(hspi->SPIx));
__SPI_DISABLE(hspi->SPIx);
/* Frame Size */
__SPI_DATA_FRAME_SIZE(hspi->SPIx, hspi->Init.Frame_Size);
/* Select Dual, Quad and Octal mode*/
__SPI_SET_MODE_X2X4X8(hspi->SPIx, hspi->MultWireParam.Wire_X2X4X8);
hspi->SPIx->CTRL2.INST_L = 0;
hspi->SPIx->CTRL2.WAIT_CYCLES = 0;
hspi->SPIx->CTRL2.TRANS_TYPE = INST_ADDR_XX;
hspi->SPIx->CTRL2.ADDR_L = 0;
}
else
{
/* Select Dual, Quad and Octal mode*/
__SPI_SET_MODE_X2X4X8(hspi->SPIx, hspi->MultWireParam.Wire_X2X4X8);
/* Select Only Rx mode */
__SPI_TMODE_Rx_ONLY(hspi->SPIx);
/* config Transfer TypebInstruct LengthbAddress Length */
hspi->SPIx->CTRL2.TRANS_TYPE = INST_ADDR_X1;
hspi->SPIx->CTRL2.INST_L = hspi->MultWireParam.InstructLength;
hspi->SPIx->CTRL2.ADDR_L = hspi->MultWireParam.AddressLength;
hspi->SPIx->CTRL2.WAIT_CYCLES = hspi->MultWireParam.ReceiveWaitCycles;
hspi->SPIx->CTRL1.NDF = hspi->u32_RxSize;
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
/* write Instruct */
if (hspi->MultWireParam.InstructLength > INST_0BIT)
{
hspi->SPIx->DR = hspi->MultWireParam.Instruct;
}
/* write address */
if(hspi->SPIx == SPIMX8_0 || hspi->SPIx == SPIMX8_1)
{
hspi->SPIx->DR = hspi->MultWireParam.Address;
}
else
{
if (hspi->MultWireParam.AddressLength > ADDR_24BIT)
{
hspi->SPIx->DR = (hspi->MultWireParam.Address >> 16) & 0xFFFF;
hspi->SPIx->DR = hspi->MultWireParam.Address & 0xFFFF;
}
else if (hspi->MultWireParam.AddressLength > ADDR_16BIT)
{
hspi->SPIx->DR = (hspi->MultWireParam.Address >> 8) & 0xFFFF;
hspi->SPIx->DR = hspi->MultWireParam.Address & 0xFF;
}
else if (hspi->MultWireParam.AddressLength > ADDR_0BIT)
{
hspi->SPIx->DR = hspi->MultWireParam.Address & 0xFFFF;
}
}
}
}