1st version

SPI DMA for F4. Blocking.
This commit is contained in:
victorpv 2017-04-29 22:08:02 -05:00
parent 7a452442df
commit 95f37d7c77
2 changed files with 211 additions and 7 deletions

View File

@ -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;
}

View File

@ -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;