Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMA SPI support for STM32 devices #162

Merged
merged 21 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9a62406
Start on STM32 DMA SPI
multiplemonomials May 20, 2023
2b5c014
Update all objects.hs, add interrupt function
multiplemonomials May 20, 2023
8c8f03f
Initial DMA code should be ready to test out...
multiplemonomials May 20, 2023
8eff3e5
Fix SPI interrupt-mode IRQ handlers, add SPI::transfer_and_wait
multiplemonomials May 22, 2023
77770ac
Fix CMake error when building for STM32WL processors
multiplemonomials May 23, 2023
2d4f3de
Now builds on all STM devices!
multiplemonomials May 23, 2023
8a276b0
Properly support STM32U5 / DMA IP v3
multiplemonomials May 24, 2023
6c54c2e
Start on STM32F4 support, fix hardfault on IP v1 and v3 due to incorr…
multiplemonomials May 28, 2023
b5f12fe
Fix Rx-only transfers, add abort code, fix incorrect channel assignme…
multiplemonomials May 29, 2023
f150a62
Start on STM32H7 SPI DMA
multiplemonomials May 29, 2023
7af59fb
Fixes for H7: Correctly manage data cache, keep SPI ISR enabled
multiplemonomials May 30, 2023
8fdd9f0
Implement DMA SPI header constants for all remaining STM32 families. …
multiplemonomials Jun 6, 2023
e863b22
Try and fix build on STM32G0
multiplemonomials Jun 6, 2023
92a686d
Fix build on STM32G0
multiplemonomials Jun 9, 2023
c93d2fe
Add SPI_32BIT_WORDS label, start on fixing SPI docs
multiplemonomials Jun 19, 2023
1ee9d67
SPI: Implement reference counting so that DMA channels get freed prop…
multiplemonomials Aug 22, 2023
ed4adc7
Fix issue where SPI data could get corrupted (by TI mode turning on) …
multiplemonomials Aug 23, 2023
3184faa
Mark DMA channels as unallocated when SPI bus is freed
multiplemonomials Aug 24, 2023
fc4bd87
Simplify spi_abort_asynch()
multiplemonomials Aug 24, 2023
d8be1ff
Fix some rebase issues, fix failing to allocate DMA channel on STM32U5
multiplemonomials Aug 30, 2023
dd9989c
Fix DMA getting stuck on STM32F4, F7, and F2
multiplemonomials Nov 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/source/I2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void I2C::abort_transfer(void)
I2C::Result I2C::transfer_and_wait(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout, bool repeated)
{
// Use EventFlags to suspend the thread until the transfer finishes
rtos::EventFlags transferResultFlags("I2C::Result EvFlags");
rtos::EventFlags transferResultFlags("I2C::transfer_and_wait EvFlags");

// Simple callback from the transfer that sets the EventFlags using the I2C result event
event_callback_t transferCallback([&](int event) {
Expand Down
3 changes: 3 additions & 0 deletions hal/include/hal/spi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ int spi_master_write(spi_t *obj, int value);
* tx_length and rx_length. The bytes written will be padded with the
* value 0xff.
*
* Note: Even if the word size / bits per frame is not 8, \c rx_length and \c tx_length
* still give lengths in bytes of input data, not numbers of words.
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] tx_buffer Pointer to the byte-array of data to write to the device
* @param[in] tx_length Number of bytes to write, may be zero
Expand Down
1 change: 1 addition & 0 deletions targets/TARGET_STM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ target_sources(mbed-stm
trng_api.c
us_ticker.c
watchdog_api.c
stm_dma_utils.c
)

target_link_libraries(mbed-stm INTERFACE mbed-cmsis-cortex-m)
14 changes: 0 additions & 14 deletions targets/TARGET_STM/TARGET_STM32F0/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,6 @@ struct pwmout_s {
uint8_t inverted;
};

struct spi_s {
SPI_HandleTypeDef handle;
IRQn_Type spiIRQ;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
#if DEVICE_SPI_ASYNCH
uint32_t event;
uint8_t transfer_type;
#endif
};

struct serial_s {
UARTName uart;
int index; // Used by irq
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F0/spi_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@
// Defines the word length capability of the device where Nth bit allows for N window size
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)

// We have DMA support
#define STM32_SPI_CAPABILITY_DMA 1

#endif
38 changes: 38 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F0/stm_dma_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* mbed Microcontroller Library
* Copyright (c) 2016-2023 STMicroelectronics
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef MBED_OS_STM_DMA_INFO_H
#define MBED_OS_STM_DMA_INFO_H

#include "cmsis.h"
#include "stm_dma_utils.h"

// See STM32F0 reference manual Table 26.

/// Mapping from SPI index to DMA link info for Tx
static const DMALinkInfo SPITxDMALinks[] = {
{1, 3}, // SPI1 Tx is DMA1 Channel 3
{1, 5}, // SPI2 Tx is DMA1 Channel 5
};

/// Mapping from SPI index to DMA link info for Rx
static const DMALinkInfo SPIRxDMALinks[] = {
{1, 2}, // SPI1 Rx is DMA1 Channel 2
{1, 4}, // SPI2 Rx is DMA1 Channel 4
};

#endif //MBED_OS_STM_DMA_INFO_H
14 changes: 0 additions & 14 deletions targets/TARGET_STM/TARGET_STM32F1/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,6 @@ struct serial_s {
#endif
};

struct spi_s {
SPI_HandleTypeDef handle;
IRQn_Type spiIRQ;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
#if DEVICE_SPI_ASYNCH
uint32_t event;
uint8_t transfer_type;
#endif
};

struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F1/spi_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@
// Defines the word length capability of the device where Nth bit allows for N window size
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)

// We have DMA support
#define STM32_SPI_CAPABILITY_DMA 1

#endif
40 changes: 40 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F1/stm_dma_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* mbed Microcontroller Library
* Copyright (c) 2016-2023 STMicroelectronics
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef MBED_OS_STM_DMA_INFO_H
#define MBED_OS_STM_DMA_INFO_H

#include "cmsis.h"
#include "stm_dma_utils.h"

// See STM32F1 reference manual Tables 78 and 79.

/// Mapping from SPI index to DMA link info for Tx
static const DMALinkInfo SPITxDMALinks[] = {
{1, 3}, // SPI1 Tx is DMA1 Channel 3
{1, 5}, // SPI2 Tx is DMA1 Channel 5
{2, 2}, // SPI3 Tx is DMA2 Channel 2
};

/// Mapping from SPI index to DMA link info for Rx
static const DMALinkInfo SPIRxDMALinks[] = {
{1, 2}, // SPI1 Rx is DMA1 Channel 2
{1, 4}, // SPI2 Rx is DMA1 Channel 4
{2, 1}, // SPI3 Rx is DMA2 Channel 1
};

#endif //MBED_OS_STM_DMA_INFO_H
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,18 @@ HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_

/* Enable Common interrupts*/
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
hdma->Instance->FCR |= DMA_IT_FE;

/* Mbed CE mod: Only enable the FIFO Error interrupt if the FIFO is actually enabled.
* If it's not enabled, then this interrupt can trigger spuriously from memory bus
* stalls that the DMA engine encounters, and this creates random DMA failures.
* Reference forum thread here:
* https://community.st.com/t5/stm32-mcus-products/spi-dma-fifo-error-issue-feifx/td-p/537074
* also: https://community.st.com/t5/stm32-mcus-touch-gfx-and-gui/spi-dma-error-is-occurred-when-the-other-dma-memory-to-memory-is/td-p/191590
*/
if(hdma->Instance->FCR & DMA_SxFCR_DMDIS)
{
hdma->Instance->FCR |= DMA_IT_FE;
}

if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
{
Expand Down
14 changes: 0 additions & 14 deletions targets/TARGET_STM/TARGET_STM32F2/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,6 @@ struct serial_s {
#endif
};

struct spi_s {
SPI_HandleTypeDef handle;
IRQn_Type spiIRQ;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
#if DEVICE_SPI_ASYNCH
uint32_t event;
uint8_t transfer_type;
#endif
};

struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F2/spi_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@
// Defines the word legnth capability of the device where Nth bit allows for N window size
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)

// We have DMA support
#define STM32_SPI_CAPABILITY_DMA 1

#endif
40 changes: 40 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F2/stm_dma_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* mbed Microcontroller Library
* Copyright (c) 2016-2023 STMicroelectronics
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef MBED_OS_STM_DMA_INFO_H
#define MBED_OS_STM_DMA_INFO_H

#include "cmsis.h"
#include "stm_dma_utils.h"

// See STM32F2 reference manual Tables 22 and 23

/// Mapping from SPI index to DMA link info for Tx
static const DMALinkInfo SPITxDMALinks[] = {
{2, 3, 3}, // SPI1 Tx is DMA2 Stream 3 Channel 3
{1, 4, 0}, // SPI2 Tx is DMA1 Stream 4 Channel 0
{1, 5, 0} // SPI3 Tx is DMA1 Stream 5 Channel 0
};

/// Mapping from SPI index to DMA link info for Rx
static const DMALinkInfo SPIRxDMALinks[] = {
{2, 0, 3}, // SPI1 Rx is DMA2 Stream 0 Channel 3
{1, 3, 0}, // SPI2 Rx is DMA1 Stream 3 Channel 0
{1, 0, 0} // SPI3 Rx is DMA2 Stream 0 Channel 0
};

#endif //MBED_OS_STM_DMA_INFO_H
14 changes: 0 additions & 14 deletions targets/TARGET_STM/TARGET_STM32F3/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,6 @@ struct pwmout_s {
uint8_t inverted;
};

struct spi_s {
SPI_HandleTypeDef handle;
IRQn_Type spiIRQ;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
#if DEVICE_SPI_ASYNCH
uint32_t event;
uint8_t transfer_type;
#endif
};

struct serial_s {
UARTName uart;
int index; // Used by irq
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F3/spi_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@
// Defines the word legnth capability of the device where Nth bit allows for N window size
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)

// We have DMA support
#define STM32_SPI_CAPABILITY_DMA 1

#endif
42 changes: 42 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F3/stm_dma_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* mbed Microcontroller Library
* Copyright (c) 2016-2023 STMicroelectronics
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef MBED_OS_STM_DMA_INFO_H
#define MBED_OS_STM_DMA_INFO_H

#include "cmsis.h"
#include "stm_dma_utils.h"

// See STM32F3 reference manual Tables 78 and 79.

/// Mapping from SPI index to DMA link info for Tx
static const DMALinkInfo SPITxDMALinks[] = {
{1, 3}, // SPI1 Tx is DMA1 Channel 3
{1, 5}, // SPI2 Tx is DMA1 Channel 5
{2, 2}, // SPI3 Tx is DMA2 Channel 2
{2, 5}, // SPI4 Tx is DMA2 Channel 5
};

/// Mapping from SPI index to DMA link info for Rx
static const DMALinkInfo SPIRxDMALinks[] = {
{1, 2}, // SPI1 Rx is DMA1 Channel 2
{1, 4}, // SPI2 Rx is DMA1 Channel 4
{2, 1}, // SPI3 Rx is DMA2 Channel 1
{2, 4}, // SPI4 Rx is DMA2 Channel 4
};

#endif //MBED_OS_STM_DMA_INFO_H
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,18 @@ HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_

/* Enable Common interrupts*/
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
hdma->Instance->FCR |= DMA_IT_FE;

/* Mbed CE mod: Only enable the FIFO Error interrupt if the FIFO is actually enabled.
* If it's not enabled, then this interrupt can trigger spuriously from memory bus
* stalls that the DMA engine encounters, and this creates random DMA failures.
* Reference forum thread here:
* https://community.st.com/t5/stm32-mcus-products/spi-dma-fifo-error-issue-feifx/td-p/537074
* also: https://community.st.com/t5/stm32-mcus-touch-gfx-and-gui/spi-dma-error-is-occurred-when-the-other-dma-memory-to-memory-is/td-p/191590
*/
if(hdma->Instance->FCR & DMA_SxFCR_DMDIS)
{
hdma->Instance->FCR |= DMA_IT_FE;
}

if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
{
Expand Down
14 changes: 0 additions & 14 deletions targets/TARGET_STM/TARGET_STM32F4/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,6 @@ struct serial_s {
#endif
};

struct spi_s {
SPI_HandleTypeDef handle;
IRQn_Type spiIRQ;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
#if DEVICE_SPI_ASYNCH
uint32_t event;
uint8_t transfer_type;
#endif
};

struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
Expand Down
3 changes: 3 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F4/spi_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@
// Defines the word legnth capability of the device where Nth bit allows for N window size
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)

// We have DMA support
#define STM32_SPI_CAPABILITY_DMA 1

#endif
Loading