parent
7a452442df
commit
95f37d7c77
|
@ -9,35 +9,143 @@
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
void SPIClass::begin() {
|
||||
DMA_Stream_TypeDef *_StreamTX;
|
||||
DMA_Stream_TypeDef *_StreamRX;
|
||||
uint32_t _ChannelTX;
|
||||
uint32_t _ChannelRX;
|
||||
|
||||
apb_freq = stm32GetClockFrequency((void*)spiHandle.Instance);
|
||||
|
||||
spiHandle.Init.Mode = SPI_MODE_MASTER;
|
||||
spiHandle.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
spiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
spiHandle.Init.NSS = SPI_NSS_SOFT;
|
||||
spiHandle.hdmatx = &hdma_spi_tx;
|
||||
spiHandle.hdmarx = &hdma_spi_rx;
|
||||
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||
|
||||
|
||||
#ifdef SPI1
|
||||
if (spiHandle.Instance == SPI1) __HAL_RCC_SPI1_CLK_ENABLE();
|
||||
if (spiHandle.Instance== SPI1) {
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
_StreamTX = SPIx_DMA(SPI1_StreamTX);
|
||||
_StreamRX = SPIx_DMA(SPI1_StreamRX);
|
||||
_ChannelTX = SPI1_ChannelTX;
|
||||
_ChannelRX = SPI1_ChannelRX;
|
||||
/*
|
||||
* Not used yet, still just polling
|
||||
*/
|
||||
//_SPISetDmaIRQ(SPI1);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI2
|
||||
if (spiHandle.Instance == SPI2) __HAL_RCC_SPI2_CLK_ENABLE();
|
||||
else if (spiHandle.Instance == SPI2) {
|
||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||
_StreamTX = SPIx_DMA(SPI2_StreamTX);
|
||||
_StreamRX = SPIx_DMA(SPI2_StreamRX);
|
||||
_ChannelTX = SPI2_ChannelTX;
|
||||
_ChannelRX = SPI2_ChannelRX;
|
||||
/*
|
||||
* Not used yet, still just polling
|
||||
*/
|
||||
//_SPISetDmaIRQ(SPI2);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI3
|
||||
if (spiHandle.Instance == SPI3) __HAL_RCC_SPI3_CLK_ENABLE();
|
||||
else if (spiHandle.Instance == SPI3) {
|
||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||
_StreamTX = SPIx_DMA(SPI3_StreamTX);
|
||||
_StreamRX = SPIx_DMA(SPI3_StreamRX);
|
||||
_ChannelTX = SPI3_ChannelTX;
|
||||
_ChannelRX = SPI3_ChannelRX;
|
||||
/*
|
||||
* Not used yet, still just polling
|
||||
*/
|
||||
//_SPISetDmaIRQ(SPI3);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI4
|
||||
if (spiHandle.Instance == SPI4) __HAL_RCC_SPI4_CLK_ENABLE();
|
||||
else if (spiHandle.Instance == SPI4) {
|
||||
__HAL_RCC_SPI4_CLK_ENABLE();
|
||||
_StreamTX = SPIx_DMA(SPI4_StreamTX);
|
||||
_StreamRX = SPIx_DMA(SPI4_StreamRX);
|
||||
_ChannelTX = SPI4_ChannelTX;
|
||||
_ChannelRX = SPI4_ChannelRX;
|
||||
/*
|
||||
* Not used yet, still just polling
|
||||
*/
|
||||
//_SPISetDmaIRQ(SPI4);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI5
|
||||
if (spiHandle.Instance == SPI5) __HAL_RCC_SPI5_CLK_ENABLE();
|
||||
else if (spiHandle.Instance == SPI5) {
|
||||
__HAL_RCC_SPI5_CLK_ENABLE();
|
||||
_StreamTX = SPIx_DMA(SPI5_StreamTX);
|
||||
_StreamRX = SPIx_DMA(SPI5_StreamRX);
|
||||
_ChannelTX = SPI5_ChannelTX;
|
||||
_ChannelRX = SPI5_ChannelRX;
|
||||
/*
|
||||
* Not used yet, still just polling
|
||||
*/
|
||||
//_SPISetDmaIRQ(SPI5);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI6
|
||||
if (spiHandle.Instance == SPI6) __HAL_RCC_SPI6_CLK_ENABLE();
|
||||
else if (spiHandle.Instance == SPI6) {
|
||||
__HAL_RCC_SPI6_CLK_ENABLE();
|
||||
_StreamTX = SPIx_DMA(SPI6_StreamTX);
|
||||
_StreamRX = SPIx_DMA(SPI6_StreamRX);
|
||||
_ChannelTX = SPI6_ChannelTX;
|
||||
_ChannelRX = SPI6_ChannelRX;
|
||||
/*
|
||||
* Not used yet, still just polling
|
||||
*/
|
||||
//_SPISetDmaIRQ(SPI6);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
hdma_spi_tx.Instance = _StreamTX;
|
||||
hdma_spi_tx.Parent = &spiHandle;
|
||||
hdma_spi_tx.Init.Channel = _ChannelTX;
|
||||
hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_spi_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_spi_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||
hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
|
||||
hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||
|
||||
|
||||
hdma_spi_rx.Instance = _StreamRX;
|
||||
hdma_spi_rx.Parent = &spiHandle;
|
||||
hdma_spi_rx.Init.Channel = _ChannelRX;
|
||||
hdma_spi_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_spi_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_spi_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_spi_rx.Init.Mode = DMA_NORMAL;
|
||||
hdma_spi_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
hdma_spi_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
hdma_spi_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||
hdma_spi_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_spi_rx.Init.MemBurst = DMA_MBURST_SINGLE;
|
||||
hdma_spi_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||
|
||||
|
||||
stm32AfSPIInit(spiHandle.Instance, mosiPort, mosiPin, misoPort, misoPin, sckPort, sckPin);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void SPIClass::beginTransaction(SPISettings settings) {
|
||||
if (this->settings.clock == settings.clock
|
||||
|
@ -122,3 +230,40 @@ void SPIClass::stm32SetSCK(uint8_t sck) {
|
|||
void SPIClass::stm32SetInstance(SPI_TypeDef *instance) {
|
||||
spiHandle.Instance = instance;
|
||||
}
|
||||
uint8_t SPIClass::dmaTransfer(uint8_t *transmitBuf, uint8_t *receiveBuf, uint16_t length) {
|
||||
//HAL_SPI_TransmitReceive(&spiHandle, transmitBuf, receiveBuf, length, 1000);
|
||||
// DMA handles configured in Begin. Need to change the MINC mode since dmaSend may have been called last
|
||||
hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
|
||||
HAL_DMA_Init(&hdma_spi_tx);
|
||||
HAL_DMA_Init(&hdma_spi_rx);
|
||||
|
||||
/*
|
||||
* We dont use interrupts here.
|
||||
*/
|
||||
|
||||
HAL_SPI_TransmitReceive_DMA(&spiHandle, transmitBuf, receiveBuf, length);
|
||||
HAL_DMA_PollForTransfer(&hdma_spi_tx, HAL_DMA_FULL_TRANSFER, 10000);
|
||||
HAL_DMA_PollForTransfer(&hdma_spi_rx, HAL_DMA_FULL_TRANSFER, 10000);
|
||||
HAL_DMA_IRQHandler(&hdma_spi_tx);
|
||||
HAL_DMA_IRQHandler(&hdma_spi_rx);
|
||||
spiHandle.State = HAL_SPI_STATE_READY;
|
||||
return 0;
|
||||
}
|
||||
uint8_t SPIClass::dmaSend(uint8_t *transmitBuf, uint16_t length, bool minc) {
|
||||
//HAL_SPI_TransmitReceive(&spiHandle, transmitBuf, buf, length, 1000);
|
||||
//Need to set TX DMA handle.
|
||||
if (minc == 1){
|
||||
hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
} else {
|
||||
hdma_spi_tx.Init.MemInc = DMA_MINC_DISABLE;
|
||||
}
|
||||
|
||||
HAL_DMA_Init(&hdma_spi_tx);
|
||||
|
||||
HAL_SPI_Transmit_DMA(&spiHandle, transmitBuf, length);
|
||||
HAL_DMA_PollForTransfer(&hdma_spi_tx, HAL_DMA_FULL_TRANSFER, 10000);
|
||||
HAL_DMA_IRQHandler(&hdma_spi_tx);
|
||||
spiHandle.State = HAL_SPI_STATE_READY;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,60 @@
|
|||
#define SPI_MODE2 0x02
|
||||
#define SPI_MODE3 0x03
|
||||
|
||||
#ifdef STM32F0
|
||||
#endif
|
||||
#ifdef STM32F1
|
||||
#define SPI1_StreamTX DMA1_Channel3
|
||||
#define SPI1_StreamRX DMA1_Channel2
|
||||
#define SPI1_ChannelTX
|
||||
#define SPI1_ChannelRX
|
||||
#define SPI2_StreamTX DMA1_Channel5
|
||||
#define SPI2_StreamRX DMA1_Channel4
|
||||
#define SPI2_ChannelTX
|
||||
#define SPI2_ChannelRX
|
||||
#define SPI3_StreamTX DMA2_Channel2
|
||||
#define SPI3_StreamRX DMA2_Channel1
|
||||
#define SPI3_ChannelTX
|
||||
#define SPI3_ChannelRX
|
||||
#endif
|
||||
#ifdef STM32F2
|
||||
#endif
|
||||
#ifdef STM32F3
|
||||
#endif
|
||||
#ifdef STM32F4
|
||||
#define SPI1_StreamTX 2_Stream3
|
||||
#define SPI1_StreamRX 2_Stream0
|
||||
#define SPI1_ChannelTX DMA_CHANNEL_3
|
||||
#define SPI1_ChannelRX DMA_CHANNEL_3
|
||||
#define SPI2_StreamTX 1_Stream4
|
||||
#define SPI2_StreamRX 1_Stream3
|
||||
#define SPI2_ChannelTX DMA_CHANNEL_0
|
||||
#define SPI2_ChannelRX DMA_CHANNEL_0
|
||||
#define SPI3_StreamTX 1_Stream5
|
||||
#define SPI3_StreamRX 1_Stream0
|
||||
#define SPI3_ChannelTX DMA_CHANNEL_0
|
||||
#define SPI3_ChannelRX DMA_CHANNEL_0
|
||||
|
||||
#define _SPIx_DMA(a) DMA##a
|
||||
#define SPIx_DMA(a) _SPIx_DMA(a)
|
||||
#define _SPIx_DMA_IRQn(a) DMA##a##_IRQn
|
||||
#define SPIx_DMA_IRQn(a) _SPIx_DMA_IRQn(a)
|
||||
|
||||
#define _SPISetDmaIRQ(a) HAL_NVIC_SetPriority(SPIx_DMA_IRQn(a##_StreamTX), 0, 0); \
|
||||
HAL_NVIC_SetPriority(SPIx_DMA_IRQn(a##_StreamRX), 0, 0); \
|
||||
HAL_NVIC_EnableIRQ(SPIx_DMA_IRQn(a##_StreamTX)); \
|
||||
HAL_NVIC_EnableIRQ(SPIx_DMA_IRQn(a##_StreamRX));
|
||||
#endif
|
||||
#ifdef STM32F7
|
||||
#endif
|
||||
#ifdef STM32L0
|
||||
#endif
|
||||
#ifdef STM32L1
|
||||
#endif
|
||||
#ifdef STM32L4
|
||||
#endif
|
||||
|
||||
|
||||
class SPISettings {
|
||||
public:
|
||||
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode): clock(clock), bitOrder(bitOrder), dataMode(dataMode) {};
|
||||
|
@ -82,6 +136,9 @@ class SPIClass {
|
|||
uint8_t transfer(uint8_t data);
|
||||
uint16_t transfer16(uint16_t data);
|
||||
void transfer(uint8_t *buf, size_t count);
|
||||
uint8_t dmaTransfer(uint8_t *transmitBuf, uint8_t *receiveBuf, uint16_t length);
|
||||
uint8_t dmaSend(uint8_t *transmitBuf, uint16_t length, bool minc = 1);
|
||||
|
||||
|
||||
private:
|
||||
uint32_t apb_freq = 0;
|
||||
|
@ -89,6 +146,8 @@ class SPIClass {
|
|||
SPISettings settings = {};
|
||||
|
||||
SPI_HandleTypeDef spiHandle = {};
|
||||
DMA_HandleTypeDef hdma_spi_rx = {};
|
||||
DMA_HandleTypeDef hdma_spi_tx = {};
|
||||
|
||||
GPIO_TypeDef *mosiPort = NULL;
|
||||
uint32_t mosiPin = 0;
|
||||
|
|
Loading…
Reference in New Issue