mirror of https://github.com/ARMmbed/mbed-os.git
DMA SPI support for STM32 devices (#162)
* Start on STM32 DMA SPI * Update all objects.hs, add interrupt function * Initial DMA code should be ready to test out... * Fix SPI interrupt-mode IRQ handlers, add SPI::transfer_and_wait * Fix CMake error when building for STM32WL processors * Now builds on all STM devices! * Properly support STM32U5 / DMA IP v3 * Start on STM32F4 support, fix hardfault on IP v1 and v3 due to incorrect indexing * Fix Rx-only transfers, add abort code, fix incorrect channel assignments for DMA IP v1 devices * Start on STM32H7 SPI DMA * Fixes for H7: Correctly manage data cache, keep SPI ISR enabled * Implement DMA SPI header constants for all remaining STM32 families. Also add support for freeing DMA channels * Try and fix build on STM32G0 * Fix build on STM32G0 * Add SPI_32BIT_WORDS label, start on fixing SPI docs * SPI: Implement reference counting so that DMA channels get freed properly * Fix issue where SPI data could get corrupted (by TI mode turning on) depending on memory layout (if your spis pointer & 0x10 was nonzero) * Mark DMA channels as unallocated when SPI bus is freed * Simplify spi_abort_asynch() * Fix some rebase issues, fix failing to allocate DMA channel on STM32U5 * Fix DMA getting stuck on STM32F4, F7, and F2pull/15494/head
parent
7e9d658ae9
commit
28815b13d3
|
|
@ -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)
|
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
|
// 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
|
// Simple callback from the transfer that sets the EventFlags using the I2C result event
|
||||||
event_callback_t transferCallback([&](int event) {
|
event_callback_t transferCallback([&](int event) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
* tx_length and rx_length. The bytes written will be padded with the
|
||||||
* value 0xff.
|
* 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] 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_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
|
* @param[in] tx_length Number of bytes to write, may be zero
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ target_sources(mbed-stm
|
||||||
trng_api.c
|
trng_api.c
|
||||||
us_ticker.c
|
us_ticker.c
|
||||||
watchdog_api.c
|
watchdog_api.c
|
||||||
|
stm_dma_utils.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(mbed-stm INTERFACE mbed-cmsis-cortex-m)
|
target_link_libraries(mbed-stm INTERFACE mbed-cmsis-cortex-m)
|
||||||
|
|
|
||||||
|
|
@ -44,20 +44,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@
|
||||||
// Defines the word length capability of the device where Nth bit allows for N window size
|
// Defines the word length capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -89,20 +89,6 @@ struct serial_s {
|
||||||
#endif
|
#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 {
|
struct i2c_s {
|
||||||
/* The 1st 2 members I2CName i2c
|
/* The 1st 2 members I2CName i2c
|
||||||
* and I2C_HandleTypeDef handle should
|
* and I2C_HandleTypeDef handle should
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,7 @@
|
||||||
// Defines the word length capability of the device where Nth bit allows for N window size
|
// Defines the word length capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -202,7 +202,18 @@ HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_
|
||||||
|
|
||||||
/* Enable Common interrupts*/
|
/* Enable Common interrupts*/
|
||||||
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
||||||
|
|
||||||
|
/* 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;
|
hdma->Instance->FCR |= DMA_IT_FE;
|
||||||
|
}
|
||||||
|
|
||||||
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
|
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -95,20 +95,6 @@ struct serial_s {
|
||||||
#endif
|
#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 {
|
struct i2c_s {
|
||||||
/* The 1st 2 members I2CName i2c
|
/* The 1st 2 members I2CName i2c
|
||||||
* and I2C_HandleTypeDef handle should
|
* and I2C_HandleTypeDef handle should
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -57,20 +57,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -202,7 +202,18 @@ HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_
|
||||||
|
|
||||||
/* Enable Common interrupts*/
|
/* Enable Common interrupts*/
|
||||||
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
||||||
|
|
||||||
|
/* 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;
|
hdma->Instance->FCR |= DMA_IT_FE;
|
||||||
|
}
|
||||||
|
|
||||||
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
|
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -76,20 +76,6 @@ struct serial_s {
|
||||||
#endif
|
#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 {
|
struct i2c_s {
|
||||||
/* The 1st 2 members I2CName i2c
|
/* The 1st 2 members I2CName i2c
|
||||||
* and I2C_HandleTypeDef handle should
|
* and I2C_HandleTypeDef handle should
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* 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 STM32F4 reference manual Tables 42 and 43.
|
||||||
|
// Note: For each SPI and each direction, there are two possible assignments to a DMA channel.
|
||||||
|
// We need to assign them here so that no combination would ever conflict and use the same DMA channel.
|
||||||
|
|
||||||
|
// Exception: SPI5 and SPI6 use the same DMA channels in hardware and there's no way to deconflict them.
|
||||||
|
// So, SPI5 and SPI6 cannot be used with DMA at the same time.
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
{2, 1, 4}, // SPI4 Tx is DMA2 Stream 1 Channel 4
|
||||||
|
{2, 6, 7}, // SPI5 Tx is DMA2 Stream 6 Channel 7
|
||||||
|
{2, 5, 1}, // SPI6 Tx is DMA2 Stream 5 Channel 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{2, 2, 3}, // SPI1 Rx is DMA2 Stream 2 Channel 3
|
||||||
|
{1, 3, 0}, // SPI2 Rx is DMA1 Stream 3 Channel 0
|
||||||
|
{1, 0, 0}, // SPI3 Rx is DMA1 Stream 0 Channel 0
|
||||||
|
{2, 0, 4}, // SPI4 Rx is DMA2 Stream 0 Channel 4
|
||||||
|
{2, 5, 7}, // SPI5 Rx is DMA2 Stream 5 Channel 7
|
||||||
|
{2, 6, 1}, // SPI6 Rx is DMA2 Stream 6 Channel 1
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -479,7 +479,18 @@ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress,
|
||||||
|
|
||||||
/* Enable Common interrupts*/
|
/* Enable Common interrupts*/
|
||||||
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
||||||
|
|
||||||
|
/* 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;
|
hdma->Instance->FCR |= DMA_IT_FE;
|
||||||
|
}
|
||||||
|
|
||||||
if(hdma->XferHalfCpltCallback != NULL)
|
if(hdma->XferHalfCpltCallback != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,18 @@ HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_
|
||||||
|
|
||||||
/* Enable Common interrupts*/
|
/* Enable Common interrupts*/
|
||||||
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
|
||||||
|
|
||||||
|
/* 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;
|
hdma->Instance->FCR |= DMA_IT_FE;
|
||||||
|
}
|
||||||
|
|
||||||
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
|
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -75,20 +75,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* 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 STM32F7 reference manual Tables 27 and 28.
|
||||||
|
// Note: For each SPI and each direction, there are two possible assignments to a DMA channel.
|
||||||
|
// We need to assign them here so that no combination would ever conflict and use the same DMA channel.
|
||||||
|
|
||||||
|
// Exception: SPI5 and SPI6 use the same DMA channels in hardware and there's no way to deconflict them.
|
||||||
|
// So, SPI5 and SPI6 cannot be used with DMA at the same time.
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
{2, 1, 4}, // SPI4 Tx is DMA2 Stream 1 Channel 4
|
||||||
|
{2, 6, 7}, // SPI5 Tx is DMA2 Stream 6 Channel 7
|
||||||
|
{2, 5, 1}, // SPI6 Tx is DMA2 Stream 5 Channel 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{2, 2, 3}, // SPI1 Rx is DMA2 Stream 2 Channel 3
|
||||||
|
{1, 3, 0}, // SPI2 Rx is DMA1 Stream 3 Channel 0
|
||||||
|
{1, 0, 0}, // SPI3 Rx is DMA1 Stream 0 Channel 0
|
||||||
|
{2, 0, 4}, // SPI4 Rx is DMA2 Stream 0 Channel 4
|
||||||
|
{2, 5, 7}, // SPI5 Rx is DMA2 Stream 5 Channel 7
|
||||||
|
{2, 6, 1}, // SPI6 Rx is DMA2 Stream 6 Channel 1
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -56,20 +56,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/* 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"
|
||||||
|
|
||||||
|
// STM32G0 devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX},
|
||||||
|
#ifdef DMA2
|
||||||
|
// For better performance, on devices with DMA2 (STM32G0Bxx/Cxx), put SPI3 on DMA2
|
||||||
|
{2, 1, DMA_REQUEST_SPI3_TX}
|
||||||
|
#else
|
||||||
|
{1, 5, DMA_REQUEST_SPI3_TX}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, DMA_REQUEST_SPI1_RX},
|
||||||
|
{1, 4, DMA_REQUEST_SPI2_RX},
|
||||||
|
#ifdef DMA2
|
||||||
|
// For better performance, on devices with DMA2 (STM32G0Bxx/Cxx), put SPI3 on DMA2
|
||||||
|
{2, 2, DMA_REQUEST_SPI3_RX}
|
||||||
|
#else
|
||||||
|
{1, 6, DMA_REQUEST_SPI3_RX}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -55,20 +55,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* 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"
|
||||||
|
|
||||||
|
// STM32G4 devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX},
|
||||||
|
{1, 5, DMA_REQUEST_SPI3_TX},
|
||||||
|
#ifdef SPI4
|
||||||
|
{2, 1, DMA_REQUEST_SPI4_TX}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, DMA_REQUEST_SPI1_RX},
|
||||||
|
{1, 4, DMA_REQUEST_SPI2_RX},
|
||||||
|
{1, 6, DMA_REQUEST_SPI3_RX},
|
||||||
|
#ifdef SPI4
|
||||||
|
{2, 2, DMA_REQUEST_SPI4_RX}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -64,20 +64,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0xFFFFFFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0xFFFFFFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* 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"
|
||||||
|
|
||||||
|
// STM32H7 devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX},
|
||||||
|
{1, 5, DMA_REQUEST_SPI3_TX},
|
||||||
|
{1, 7, DMA_REQUEST_SPI4_TX},
|
||||||
|
{2, 1, DMA_REQUEST_SPI5_TX},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 0, DMA_REQUEST_SPI1_RX},
|
||||||
|
{1, 2, DMA_REQUEST_SPI2_RX},
|
||||||
|
{1, 4, DMA_REQUEST_SPI3_RX},
|
||||||
|
{1, 6, DMA_REQUEST_SPI4_RX},
|
||||||
|
{2, 0, DMA_REQUEST_SPI5_RX},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -58,20 +58,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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 STM32L0 reference manual Table 51
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 3, 1}, // SPI1 Tx is DMA1 Channel 3 Request 1
|
||||||
|
{1, 5, 2}, // SPI2 Tx is DMA1 Channel 5 Request 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, 1}, // SPI1 Rx is DMA1 Channel 2 Request 1
|
||||||
|
{1, 4, 2}, // SPI2 Tx is DMA1 Channel 4 Request 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -76,20 +76,6 @@ struct serial_s {
|
||||||
#endif
|
#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 {
|
struct i2c_s {
|
||||||
/* The 1st 2 members I2CName i2c
|
/* The 1st 2 members I2CName i2c
|
||||||
* and I2C_HandleTypeDef handle should
|
* and I2C_HandleTypeDef handle should
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x00008080)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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 STM32L1 reference manual Tables 55 and 56
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
|
@ -54,20 +54,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* 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"
|
||||||
|
|
||||||
|
#ifdef DMAMUX1
|
||||||
|
|
||||||
|
// STM32L4+ devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX},
|
||||||
|
{1, 5, DMA_REQUEST_SPI3_TX}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, DMA_REQUEST_SPI1_RX},
|
||||||
|
{1, 4, DMA_REQUEST_SPI2_RX},
|
||||||
|
{1, 6, DMA_REQUEST_SPI3_RX}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
// Base model STM32L4 devices, with fixed DMA line mapping
|
||||||
|
// See STM32L4 reference manual Tables 41 and 42.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 3, 1}, // SPI1 Tx is DMA1 Ch3 Request 1
|
||||||
|
{1, 5, 1}, // SPI2 Tx is DMA1 Ch5 Request 1
|
||||||
|
{2, 2, 3} // SPI3 Tx is DMA2 Ch2 Request 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, 1}, // SPI1 Rx is DMA1 Ch2 Request 1
|
||||||
|
{1, 4, 1}, // SPI2 Rx is DMA1 Ch4 Request 1
|
||||||
|
{2, 1, 3} // SPI3 Rx is DMA2 Ch1 Request 3
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -64,20 +64,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
// STM32L5 devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX},
|
||||||
|
{1, 5, DMA_REQUEST_SPI3_TX},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, DMA_REQUEST_SPI1_RX},
|
||||||
|
{1, 4, DMA_REQUEST_SPI2_RX},
|
||||||
|
{1, 6, DMA_REQUEST_SPI3_RX},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -64,20 +64,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
// STM32U5+ devices.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 0, GPDMA1_REQUEST_SPI1_TX},
|
||||||
|
{1, 2, GPDMA1_REQUEST_SPI2_TX},
|
||||||
|
{1, 4, GPDMA1_REQUEST_SPI3_TX}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 1, GPDMA1_REQUEST_SPI1_RX},
|
||||||
|
{1, 3, GPDMA1_REQUEST_SPI2_RX},
|
||||||
|
{1, 5, GPDMA1_REQUEST_SPI3_TX}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -47,20 +47,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* 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"
|
||||||
|
|
||||||
|
// STM32WB devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
#ifdef SPI2
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, DMA_REQUEST_SPI1_RX},
|
||||||
|
#ifdef SPI4
|
||||||
|
{1, 4, DMA_REQUEST_SPI2_RX}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -50,20 +50,6 @@ struct pwmout_s {
|
||||||
uint8_t inverted;
|
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 {
|
struct serial_s {
|
||||||
UARTName uart;
|
UARTName uart;
|
||||||
int index; // Used by irq
|
int index; // Used by irq
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,7 @@
|
||||||
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
// We have DMA support
|
||||||
|
#define STM32_SPI_CAPABILITY_DMA 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
// STM32WB devices, with DMAMUX feature.
|
||||||
|
// On this device, the DMA channels may be chosen arbitrarily.
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Tx
|
||||||
|
static const DMALinkInfo SPITxDMALinks[] = {
|
||||||
|
{1, 1, DMA_REQUEST_SPI1_TX},
|
||||||
|
{1, 3, DMA_REQUEST_SPI2_TX}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Mapping from SPI index to DMA link info for Rx
|
||||||
|
static const DMALinkInfo SPIRxDMALinks[] = {
|
||||||
|
{1, 2, DMA_REQUEST_SPI1_RX},
|
||||||
|
{1, 4, DMA_REQUEST_SPI2_RX}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_INFO_H
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "stm_i2c_api.h"
|
#include "stm_i2c_api.h"
|
||||||
|
#include "stm_spi_api.h"
|
||||||
|
|
||||||
#if DEVICE_USTICKER
|
#if DEVICE_USTICKER
|
||||||
#include "us_ticker_defines.h"
|
#include "us_ticker_defines.h"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header contains constants and defines specific to processors with the v1 DMA IP.
|
||||||
|
* The v1 IP has DMA controllers with multiple streams, where each "stream" has a "channel selection"
|
||||||
|
* to determine what triggers DMA requests.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBED_OS_STM_DMA_IP_V1_H
|
||||||
|
#define MBED_OS_STM_DMA_IP_V1_H
|
||||||
|
|
||||||
|
// Devices with DMA IP v1 have at most 8 channels per controller.
|
||||||
|
#define MAX_DMA_CHANNELS_PER_CONTROLLER 8
|
||||||
|
|
||||||
|
// Count DMA controllers
|
||||||
|
#ifdef DMA1
|
||||||
|
#ifdef DMA2
|
||||||
|
#define NUM_DMA_CONTROLLERS 2
|
||||||
|
#else
|
||||||
|
#define NUM_DMA_CONTROLLERS 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NUM_DMA_CONTROLLERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Provide an alias so that code can always use the v2 name for this structure
|
||||||
|
#define DMA_Channel_TypeDef DMA_Stream_TypeDef
|
||||||
|
|
||||||
|
// On some smaller devices, e.g. STM32L1 family, DMA channels are simply logically ORed rather than
|
||||||
|
// muxed, so we don't need the "sourceNumber" field.
|
||||||
|
// We can check if this is the case by the absence of specific peripherals/registers.
|
||||||
|
#if defined(DMAMUX1_BASE) || defined(DMA_SxCR_CHSEL_Msk)
|
||||||
|
#define STM_DEVICE_HAS_DMA_SOURCE_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define STM_DEVICE_HAS_DMA_SOURCE_SELECTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_IP_V1_H
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header contains constants and defines specific to processors with the v2 DMA IP.
|
||||||
|
*
|
||||||
|
* The v2 DMA IP has DMA controllers with multiple channels, where each channel has a request source
|
||||||
|
* that determines what triggers DMA transactions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBED_OS_STM_DMA_IP_V2_H
|
||||||
|
#define MBED_OS_STM_DMA_IP_V2_H
|
||||||
|
|
||||||
|
#ifdef TARGET_MCU_STM32F0
|
||||||
|
|
||||||
|
// STM32F0 is weird and does its own thing.
|
||||||
|
// Only 5 channels usable, the other 2 lack interrupts
|
||||||
|
#define MAX_DMA_CHANNELS_PER_CONTROLLER 5
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Devices with DMA IP v2 have at most 7 channels per controller.
|
||||||
|
#define MAX_DMA_CHANNELS_PER_CONTROLLER 7
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Count DMA controllers
|
||||||
|
#ifdef DMA1
|
||||||
|
#ifdef DMA2
|
||||||
|
#define NUM_DMA_CONTROLLERS 2
|
||||||
|
#else
|
||||||
|
#define NUM_DMA_CONTROLLERS 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NUM_DMA_CONTROLLERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// On some smaller devices, e.g. STM32L1 family, DMA channels are simply logically ORed rather than
|
||||||
|
// muxed, so we don't need the "sourceNumber" field.
|
||||||
|
// We can check if this is the case by the absence of specific peripherals/registers.
|
||||||
|
#if defined(DMA1_CSELR) || defined(DMAMUX1_BASE)
|
||||||
|
#define STM_DEVICE_HAS_DMA_SOURCE_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define STM_DEVICE_HAS_DMA_SOURCE_SELECTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_IP_V2_H
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header contains constants and defines specific to processors with the v3 DMA IP.
|
||||||
|
*
|
||||||
|
* The v3 DMA IP has one DMA controller with multiple channels, where each channel has a request source
|
||||||
|
* that determines what triggers DMA transactions. Any DMA channel can connect to any request source,
|
||||||
|
* unlike many other STM32 chips.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MBED_OS_STM_DMA_IP_V3_H
|
||||||
|
#define MBED_OS_STM_DMA_IP_V3_H
|
||||||
|
|
||||||
|
// Devices with DMA IP v3 have at most 16 channels per controller.
|
||||||
|
#define MAX_DMA_CHANNELS_PER_CONTROLLER 16
|
||||||
|
|
||||||
|
#define NUM_DMA_CONTROLLERS 1
|
||||||
|
|
||||||
|
// Currently all known IPv3 devices have source selection
|
||||||
|
#define STM_DEVICE_HAS_DMA_SOURCE_SELECTION 1
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_IP_V3_H
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* 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_UTILS_H
|
||||||
|
#define MBED_OS_STM_DMA_UTILS_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
|
||||||
|
// determine DMA IP version using the available constants in the chip header
|
||||||
|
#if defined(GPDMA1)
|
||||||
|
#define DMA_IP_VERSION_V3 1
|
||||||
|
#elif defined(DMA1_Channel1)
|
||||||
|
#define DMA_IP_VERSION_V2 1
|
||||||
|
#else
|
||||||
|
#define DMA_IP_VERSION_V1 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Include correct header for the IP version
|
||||||
|
#ifdef DMA_IP_VERSION_V3
|
||||||
|
#include "stm_dma_ip_v3.h"
|
||||||
|
#elif defined(DMA_IP_VERSION_V2)
|
||||||
|
#include "stm_dma_ip_v2.h"
|
||||||
|
#else
|
||||||
|
#include "stm_dma_ip_v1.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure containing info about a peripheral's link to the DMA controller.
|
||||||
|
*/
|
||||||
|
typedef struct DMALinkInfo {
|
||||||
|
|
||||||
|
/// Index of the DMA module that the DMA link uses.
|
||||||
|
/// Note: 1-indexed.
|
||||||
|
uint8_t dmaIdx;
|
||||||
|
|
||||||
|
/// Index of the channel on the DMA module.
|
||||||
|
/// Note that some STMicro chips have a DMA mux allowing any DMA peripheral to be used with
|
||||||
|
/// any channel, and others have a semi-fixed architecture with just some basic multiplexing.
|
||||||
|
/// Note: May be 1 or 0 indexed depending on processor
|
||||||
|
uint8_t channelIdx;
|
||||||
|
|
||||||
|
#if STM_DEVICE_HAS_DMA_SOURCE_SELECTION
|
||||||
|
/// Request source number. This is either a DMA mux input number, or a mux selection number
|
||||||
|
/// on devices without a DMA mux.
|
||||||
|
/// Note: 0-indexed.
|
||||||
|
uint8_t sourceNumber;
|
||||||
|
#endif
|
||||||
|
} DMALinkInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the DMA channel instance for a DMA link
|
||||||
|
*
|
||||||
|
* @param dmaLink DMA link instance
|
||||||
|
*/
|
||||||
|
DMA_Channel_TypeDef * stm_get_dma_channel(DMALinkInfo const * dmaLink);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the interrupt number for a DMA link
|
||||||
|
*
|
||||||
|
* @param dmaLink DMA link instance
|
||||||
|
*/
|
||||||
|
IRQn_Type stm_get_dma_irqn(const DMALinkInfo *dmaLink);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a DMA link for use.
|
||||||
|
*
|
||||||
|
* This enables and sets up the interrupt, allocates a DMA handle, and returns the handle pointer.
|
||||||
|
* Arguments are based on the parameters used for the DMA_InitTypeDef structure.
|
||||||
|
*
|
||||||
|
* @param dmaLink DMA link instance
|
||||||
|
* @param direction \c DMA_PERIPH_TO_MEMORY, \c DMA_MEMORY_TO_PERIPH, or \c DMA_MEMORY_TO_MEMORY
|
||||||
|
* @param periphInc Whether the Peripheral address register should be incremented or not.
|
||||||
|
* @param memInc Whether the Memory address register should be incremented or not.
|
||||||
|
* @param periphDataAlignment Alignment value of the peripheral data. 1, 2, or 4.
|
||||||
|
* @param memDataAlignment \c DMA_MDATAALIGN_BYTE, \c DMA_MDATAALIGN_HALFWORD, or \c DMA_MDATAALIGN_WORD
|
||||||
|
*
|
||||||
|
* @return Pointer to DMA handle allocated by this module.
|
||||||
|
* @return NULL if the DMA channel used by the link has already been allocated by something else.
|
||||||
|
*/
|
||||||
|
DMA_HandleTypeDef * stm_init_dma_link(DMALinkInfo const * dmaLink, uint32_t direction, bool periphInc, bool memInc, uint8_t periphDataAlignment, uint8_t memDataAlignment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free a DMA link.
|
||||||
|
*
|
||||||
|
* This frees memory associated with it and unlocks the hardware DMA channel so that it can be used by somebody else.
|
||||||
|
*
|
||||||
|
* @param dmaLink DMA link ponter to free.
|
||||||
|
*/
|
||||||
|
void stm_free_dma_link(DMALinkInfo const * dmaLink);
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_DMA_UTILS_H
|
||||||
|
|
@ -42,6 +42,11 @@
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
#include "PeripheralPins.h"
|
#include "PeripheralPins.h"
|
||||||
#include "spi_device.h"
|
#include "spi_device.h"
|
||||||
|
#include "stm_spi_api.h"
|
||||||
|
|
||||||
|
#ifdef STM32_SPI_CAPABILITY_DMA
|
||||||
|
#include "stm_dma_info.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DEVICE_SPI_ASYNCH
|
#if DEVICE_SPI_ASYNCH
|
||||||
#define SPI_INST(obj) ((SPI_TypeDef *)(obj->spi.spi))
|
#define SPI_INST(obj) ((SPI_TypeDef *)(obj->spi.spi))
|
||||||
|
|
@ -85,6 +90,55 @@ extern HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(SPI_HandleTypeDef *hspi);
|
||||||
#define HAS_32BIT_SPI_TRANSFERS 1
|
#define HAS_32BIT_SPI_TRANSFERS 1
|
||||||
#endif // SPI_DATASIZE_X
|
#endif // SPI_DATASIZE_X
|
||||||
|
|
||||||
|
// SPI IRQ handlers
|
||||||
|
#if defined SPI1_BASE
|
||||||
|
static SPI_HandleTypeDef * spi1Handle; // Handle of whatever SPI structure is used for SPI1
|
||||||
|
void SPI1_IRQHandler()
|
||||||
|
{
|
||||||
|
HAL_SPI_IRQHandler(spi1Handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined SPI2_BASE
|
||||||
|
static SPI_HandleTypeDef * spi2Handle; // Handle of whatever SPI structure is used for SPI2
|
||||||
|
void SPI2_IRQHandler()
|
||||||
|
{
|
||||||
|
HAL_SPI_IRQHandler(spi2Handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined SPI3_BASE
|
||||||
|
static SPI_HandleTypeDef * spi3Handle; // Handle of whatever SPI structure is used for SPI3
|
||||||
|
void SPI3_IRQHandler()
|
||||||
|
{
|
||||||
|
HAL_SPI_IRQHandler(spi3Handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined SPI4_BASE
|
||||||
|
static SPI_HandleTypeDef * spi4Handle; // Handle of whatever SPI structure is used for SPI4
|
||||||
|
void SPI4_IRQHandler()
|
||||||
|
{
|
||||||
|
HAL_SPI_IRQHandler(spi4Handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined SPI5_BASE
|
||||||
|
static SPI_HandleTypeDef * spi5Handle; // Handle of whatever SPI structure is used for SPI5
|
||||||
|
void SPI5_IRQHandler()
|
||||||
|
{
|
||||||
|
HAL_SPI_IRQHandler(spi5Handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined SPI6_BASE
|
||||||
|
static SPI_HandleTypeDef * spi6Handle; // Handle of whatever SPI structure is used for SPI6
|
||||||
|
void SPI6_IRQHandler()
|
||||||
|
{
|
||||||
|
HAL_SPI_IRQHandler(spi6Handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush RX FIFO/input register of SPI interface and clear overrun flag.
|
* Flush RX FIFO/input register of SPI interface and clear overrun flag.
|
||||||
*/
|
*/
|
||||||
|
|
@ -96,6 +150,20 @@ static inline void spi_flush_rx(spi_t *obj)
|
||||||
LL_SPI_ClearFlag_OVR(SPI_INST(obj));
|
LL_SPI_ClearFlag_OVR(SPI_INST(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store the spi_s * inside an SPI handle, for later retrieval in callbacks
|
||||||
|
static inline void store_spis_pointer(SPI_HandleTypeDef * spiHandle, struct spi_s * spis) {
|
||||||
|
// Annoyingly, STM neglected to provide any sort of "user data" pointer inside SPI_HandleTypeDef for use
|
||||||
|
// in callbacks. However, there are some variables in the Init struct that are never accessed after HAL_SPI_Init().
|
||||||
|
// So, we can reuse those to store our pointer.
|
||||||
|
spiHandle->Init.TIMode = (uint32_t)spis;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get spi_s * from SPI_HandleTypeDef
|
||||||
|
static inline struct spi_s * get_spis_pointer(SPI_HandleTypeDef * spiHandle) {
|
||||||
|
return (struct spi_s *) spiHandle->Init.TIMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap)
|
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap)
|
||||||
{
|
{
|
||||||
if (slave) {
|
if (slave) {
|
||||||
|
|
@ -149,10 +217,16 @@ void init_spi(spi_t *obj)
|
||||||
|
|
||||||
__HAL_SPI_DISABLE(handle);
|
__HAL_SPI_DISABLE(handle);
|
||||||
|
|
||||||
|
// Reset flag used by store_spis_pointer()
|
||||||
|
handle->Init.TIMode = SPI_TIMODE_DISABLE;
|
||||||
|
|
||||||
DEBUG_PRINTF("init_spi: instance=0x%8X\r\n", (int)handle->Instance);
|
DEBUG_PRINTF("init_spi: instance=0x%8X\r\n", (int)handle->Instance);
|
||||||
if (HAL_SPI_Init(handle) != HAL_OK) {
|
if (HAL_SPI_Init(handle) != HAL_OK) {
|
||||||
error("Cannot initialize SPI");
|
error("Cannot initialize SPI");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
store_spis_pointer(handle, spiobj);
|
||||||
|
|
||||||
/* In some cases after SPI object re-creation SPI overrun flag may not
|
/* In some cases after SPI object re-creation SPI overrun flag may not
|
||||||
* be cleared, so clear RX data explicitly to prevent any transmissions errors */
|
* be cleared, so clear RX data explicitly to prevent any transmissions errors */
|
||||||
spi_flush_rx(obj);
|
spi_flush_rx(obj);
|
||||||
|
|
@ -205,6 +279,10 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||||
#endif /* SPI_IP_VERSION_V2 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
#ifdef DEVICE_SPI_ASYNCH
|
||||||
|
spiobj->driverCallback = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined SPI1_BASE
|
#if defined SPI1_BASE
|
||||||
// Enable SPI clock
|
// Enable SPI clock
|
||||||
if (spiobj->spi == SPI_1) {
|
if (spiobj->spi == SPI_1) {
|
||||||
|
|
@ -224,6 +302,8 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
__HAL_RCC_SPI1_RELEASE_RESET();
|
__HAL_RCC_SPI1_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI1_IRQn;
|
spiobj->spiIRQ = SPI1_IRQn;
|
||||||
|
spiobj->spiIndex = 1;
|
||||||
|
spi1Handle = &spiobj->handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -245,6 +325,8 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
__HAL_RCC_SPI2_RELEASE_RESET();
|
__HAL_RCC_SPI2_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI2_IRQn;
|
spiobj->spiIRQ = SPI2_IRQn;
|
||||||
|
spiobj->spiIndex = 2;
|
||||||
|
spi2Handle = &spiobj->handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -266,6 +348,8 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
__HAL_RCC_SPI3_RELEASE_RESET();
|
__HAL_RCC_SPI3_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI3_IRQn;
|
spiobj->spiIRQ = SPI3_IRQn;
|
||||||
|
spiobj->spiIndex = 3;
|
||||||
|
spi3Handle = &spiobj->handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -283,6 +367,8 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
__HAL_RCC_SPI4_RELEASE_RESET();
|
__HAL_RCC_SPI4_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI4_CLK_ENABLE();
|
__HAL_RCC_SPI4_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI4_IRQn;
|
spiobj->spiIRQ = SPI4_IRQn;
|
||||||
|
spiobj->spiIndex = 4;
|
||||||
|
spi4Handle = &spiobj->handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -300,6 +386,8 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
__HAL_RCC_SPI5_RELEASE_RESET();
|
__HAL_RCC_SPI5_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI5_CLK_ENABLE();
|
__HAL_RCC_SPI5_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI5_IRQn;
|
spiobj->spiIRQ = SPI5_IRQn;
|
||||||
|
spiobj->spiIndex = 5;
|
||||||
|
spi5Handle = &spiobj->handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -317,6 +405,8 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
__HAL_RCC_SPI6_RELEASE_RESET();
|
__HAL_RCC_SPI6_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI6_CLK_ENABLE();
|
__HAL_RCC_SPI6_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI6_IRQn;
|
spiobj->spiIRQ = SPI6_IRQn;
|
||||||
|
spiobj->spiIndex = 6;
|
||||||
|
spi6Handle = &spiobj->handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -368,7 +458,6 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
#endif
|
#endif
|
||||||
handle->Init.DataSize = SPI_DATASIZE_8BIT;
|
handle->Init.DataSize = SPI_DATASIZE_8BIT;
|
||||||
handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
|
handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||||
handle->Init.TIMode = SPI_TIMODE_DISABLE;
|
|
||||||
|
|
||||||
#if defined (SPI_IP_VERSION_V2)
|
#if defined (SPI_IP_VERSION_V2)
|
||||||
handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
|
handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
|
||||||
|
|
@ -418,6 +507,76 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
||||||
SPI_INIT_DIRECT(obj, &explicit_spi_pinmap);
|
SPI_INIT_DIRECT(obj, &explicit_spi_pinmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STM32_SPI_CAPABILITY_DMA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the DMA for an SPI object in the Tx direction.
|
||||||
|
* Does nothing if DMA is already initialized.
|
||||||
|
*/
|
||||||
|
static void spi_init_tx_dma(struct spi_s * obj)
|
||||||
|
{
|
||||||
|
if(!obj->txDMAInitialized)
|
||||||
|
{
|
||||||
|
#ifdef TARGET_MCU_STM32H7
|
||||||
|
// For STM32H7, SPI6 does not support DMA through the normal mechanism -- it would require use of the BDMA
|
||||||
|
// controller, which we don't currently support, and which can only access data in SRAM4.
|
||||||
|
if(obj->spiIndex == 6)
|
||||||
|
{
|
||||||
|
mbed_error(MBED_ERROR_UNSUPPORTED, "DMA not supported on SPI6!", 0, MBED_FILENAME, __LINE__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get DMA handle
|
||||||
|
DMALinkInfo const *dmaLink = &SPITxDMALinks[obj->spiIndex - 1];
|
||||||
|
|
||||||
|
// Initialize DMA channel
|
||||||
|
DMA_HandleTypeDef *dmaHandle = stm_init_dma_link(dmaLink, DMA_MEMORY_TO_PERIPH, false, true, 1, 1);
|
||||||
|
|
||||||
|
if(dmaHandle == NULL)
|
||||||
|
{
|
||||||
|
mbed_error(MBED_ERROR_ALREADY_IN_USE, "Tx DMA channel already used by something else!", 0, MBED_FILENAME, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
__HAL_LINKDMA(&obj->handle, hdmatx, *dmaHandle);
|
||||||
|
obj->txDMAInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the DMA for an SPI object in the Rx direction.
|
||||||
|
* Does nothing if DMA is already initialized.
|
||||||
|
*/
|
||||||
|
static void spi_init_rx_dma(struct spi_s * obj)
|
||||||
|
{
|
||||||
|
if(!obj->rxDMAInitialized)
|
||||||
|
{
|
||||||
|
#ifdef TARGET_MCU_STM32H7
|
||||||
|
// For STM32H7, SPI6 does not support DMA through the normal mechanism -- it would require use of the BDMA
|
||||||
|
// controller, which we don't currently support, and which can only access data in SRAM4.
|
||||||
|
if(obj->spiIndex == 6)
|
||||||
|
{
|
||||||
|
mbed_error(MBED_ERROR_UNSUPPORTED, "DMA not supported on SPI6!", 0, MBED_FILENAME, __LINE__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get DMA handle
|
||||||
|
DMALinkInfo const *dmaLink = &SPIRxDMALinks[obj->spiIndex - 1];
|
||||||
|
|
||||||
|
// Initialize DMA channel
|
||||||
|
DMA_HandleTypeDef *dmaHandle = stm_init_dma_link(dmaLink, DMA_PERIPH_TO_MEMORY, false, true, 1, 1);
|
||||||
|
|
||||||
|
if(dmaHandle == NULL)
|
||||||
|
{
|
||||||
|
mbed_error(MBED_ERROR_ALREADY_IN_USE, "Rx DMA channel already used by something else!", 0, MBED_FILENAME, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
__HAL_LINKDMA(&obj->handle, hdmarx, *dmaHandle);
|
||||||
|
obj->rxDMAInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void spi_free(spi_t *obj)
|
void spi_free(spi_t *obj)
|
||||||
{
|
{
|
||||||
struct spi_s *spiobj = SPI_S(obj);
|
struct spi_s *spiobj = SPI_S(obj);
|
||||||
|
|
@ -425,6 +584,20 @@ void spi_free(spi_t *obj)
|
||||||
|
|
||||||
DEBUG_PRINTF("spi_free\r\n");
|
DEBUG_PRINTF("spi_free\r\n");
|
||||||
|
|
||||||
|
#if STM32_SPI_CAPABILITY_DMA
|
||||||
|
// Free DMA channels if allocated
|
||||||
|
if(spiobj->txDMAInitialized)
|
||||||
|
{
|
||||||
|
stm_free_dma_link(&SPITxDMALinks[spiobj->spiIndex - 1]);
|
||||||
|
spiobj->txDMAInitialized = false;
|
||||||
|
}
|
||||||
|
if(spiobj->rxDMAInitialized)
|
||||||
|
{
|
||||||
|
stm_free_dma_link(&SPIRxDMALinks[spiobj->spiIndex - 1]);
|
||||||
|
spiobj->rxDMAInitialized = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__HAL_SPI_DISABLE(handle);
|
__HAL_SPI_DISABLE(handle);
|
||||||
HAL_SPI_DeInit(handle);
|
HAL_SPI_DeInit(handle);
|
||||||
|
|
||||||
|
|
@ -1362,7 +1535,7 @@ typedef enum {
|
||||||
|
|
||||||
|
|
||||||
/// @returns the number of bytes transferred, or `0` if nothing transferred
|
/// @returns the number of bytes transferred, or `0` if nothing transferred
|
||||||
static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer_type, const void *tx, void *rx, size_t length)
|
static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer_type, const void *tx, void *rx, size_t length, DMAUsage hint)
|
||||||
{
|
{
|
||||||
struct spi_s *spiobj = SPI_S(obj);
|
struct spi_s *spiobj = SPI_S(obj);
|
||||||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||||
|
|
@ -1373,19 +1546,59 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
||||||
// so the number of transfers depends on the container size
|
// so the number of transfers depends on the container size
|
||||||
size_t words;
|
size_t words;
|
||||||
|
|
||||||
DEBUG_PRINTF("SPI inst=0x%8X Start: %u, %u\r\n", (int)handle->Instance, transfer_type, length);
|
|
||||||
|
|
||||||
obj->spi.transfer_type = transfer_type;
|
obj->spi.transfer_type = transfer_type;
|
||||||
|
|
||||||
words = length >> bitshift;
|
words = length >> bitshift;
|
||||||
|
|
||||||
// enable the interrupt
|
bool useDMA = false;
|
||||||
|
|
||||||
|
#if STM32_SPI_CAPABILITY_DMA
|
||||||
|
if (hint != DMA_USAGE_NEVER)
|
||||||
|
{
|
||||||
|
// Initialize DMA channel(s) needed
|
||||||
|
switch (transfer_type)
|
||||||
|
{
|
||||||
|
case SPI_TRANSFER_TYPE_TXRX:
|
||||||
|
spi_init_rx_dma(&obj->spi);
|
||||||
|
spi_init_tx_dma(&obj->spi);
|
||||||
|
break;
|
||||||
|
case SPI_TRANSFER_TYPE_TX:
|
||||||
|
spi_init_tx_dma(&obj->spi);
|
||||||
|
break;
|
||||||
|
case SPI_TRANSFER_TYPE_RX:
|
||||||
|
spi_init_rx_dma(&obj->spi);
|
||||||
|
if(handle->Init.Direction == SPI_DIRECTION_2LINES) {
|
||||||
|
// For 2 line SPI, doing an Rx-only transfer still requires a second DMA channel to send the fill
|
||||||
|
// bytes.
|
||||||
|
spi_init_tx_dma(&obj->spi);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
useDMA = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEBUG_PRINTF("SPI inst=0x%8X Start: type=%u, length=%u, DMA=%d\r\n", (int) handle->Instance, transfer_type, length, !!useDMA);
|
||||||
|
|
||||||
|
// Enable the interrupt. This might be needed even for DMA -- some HAL implementations (e.g. H7) have
|
||||||
|
// the DMA interrupt handler trigger the SPI interrupt.
|
||||||
IRQn_Type irq_n = spiobj->spiIRQ;
|
IRQn_Type irq_n = spiobj->spiIRQ;
|
||||||
NVIC_DisableIRQ(irq_n);
|
|
||||||
NVIC_ClearPendingIRQ(irq_n);
|
NVIC_ClearPendingIRQ(irq_n);
|
||||||
NVIC_SetPriority(irq_n, 1);
|
NVIC_SetPriority(irq_n, 1);
|
||||||
NVIC_EnableIRQ(irq_n);
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
|
#if defined(STM32_SPI_CAPABILITY_DMA) && defined(__DCACHE_PRESENT)
|
||||||
|
if (useDMA && transfer_type != SPI_TRANSFER_TYPE_RX)
|
||||||
|
{
|
||||||
|
// For chips with a cache (e.g. Cortex-M7), we need to evict the Tx data from cache to main memory.
|
||||||
|
// This ensures that the DMA controller can see the most up-to-date copy of the data.
|
||||||
|
SCB_CleanDCache_by_Addr((volatile void*)tx, length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// flush FIFO
|
// flush FIFO
|
||||||
#if defined(SPI_FLAG_FRLVL)
|
#if defined(SPI_FLAG_FRLVL)
|
||||||
HAL_SPIEx_FlushRxFifo(handle);
|
HAL_SPIEx_FlushRxFifo(handle);
|
||||||
|
|
@ -1400,21 +1613,52 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
||||||
#endif
|
#endif
|
||||||
switch (transfer_type) {
|
switch (transfer_type) {
|
||||||
case SPI_TRANSFER_TYPE_TXRX:
|
case SPI_TRANSFER_TYPE_TXRX:
|
||||||
rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t *)tx, (uint8_t *)rx, words);
|
if(useDMA) {
|
||||||
|
rc = HAL_SPI_TransmitReceive_DMA(handle, (uint8_t *)tx, (uint8_t *)rx, words);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t *) tx, (uint8_t *) rx, words);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SPI_TRANSFER_TYPE_TX:
|
case SPI_TRANSFER_TYPE_TX:
|
||||||
rc = HAL_SPI_Transmit_IT(handle, (uint8_t *)tx, words);
|
if (useDMA) {
|
||||||
|
rc = HAL_SPI_Transmit_DMA(handle, (uint8_t *)tx, words);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = HAL_SPI_Transmit_IT(handle, (uint8_t *) tx, words);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SPI_TRANSFER_TYPE_RX:
|
case SPI_TRANSFER_TYPE_RX:
|
||||||
// the receive function also "transmits" the receive buffer so in order
|
// the receive function also "transmits" the receive buffer so in order
|
||||||
// to guarantee that 0xff is on the line, we explicitly memset it here
|
// to guarantee that 0xff is on the line, we explicitly memset it here
|
||||||
memset(rx, SPI_FILL_CHAR, length);
|
memset(rx, SPI_FILL_CHAR, length);
|
||||||
|
|
||||||
|
if (useDMA) {
|
||||||
|
#if defined(STM32_SPI_CAPABILITY_DMA) && defined(__DCACHE_PRESENT)
|
||||||
|
// For chips with a cache (e.g. Cortex-M7), we need to evict the Tx data from cache to main memory.
|
||||||
|
// This ensures that the DMA controller can see the most up-to-date copy of the data.
|
||||||
|
SCB_CleanDCache_by_Addr(rx, length);
|
||||||
|
#endif
|
||||||
|
rc = HAL_SPI_Receive_DMA(handle, (uint8_t *)rx, words);
|
||||||
|
}
|
||||||
|
else {
|
||||||
rc = HAL_SPI_Receive_IT(handle, (uint8_t *)rx, words);
|
rc = HAL_SPI_Receive_IT(handle, (uint8_t *)rx, words);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
length = 0;
|
length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(STM32_SPI_CAPABILITY_DMA) && defined(__DCACHE_PRESENT)
|
||||||
|
if (useDMA && transfer_type != SPI_TRANSFER_TYPE_TX)
|
||||||
|
{
|
||||||
|
// For chips with a cache (e.g. Cortex-M7), we need to invalidate the Rx data in cache.
|
||||||
|
// This ensures that the CPU will fetch the data from SRAM instead of using its cache.
|
||||||
|
SCB_InvalidateDCache_by_Addr(rx, length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
#if defined(SPI_IP_VERSION_V2)
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
// enable SPI back in case of error
|
// enable SPI back in case of error
|
||||||
|
|
@ -1430,15 +1674,11 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
||||||
}
|
}
|
||||||
|
|
||||||
// asynchronous API
|
// asynchronous API
|
||||||
// DMA support for SPI is currently not supported, hence asynchronous SPI does not support high speeds(MHZ range)
|
|
||||||
void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
|
void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
|
||||||
{
|
{
|
||||||
struct spi_s *spiobj = SPI_S(obj);
|
struct spi_s *spiobj = SPI_S(obj);
|
||||||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||||
|
|
||||||
// TODO: DMA usage is currently ignored
|
|
||||||
(void) hint;
|
|
||||||
|
|
||||||
// check which use-case we have
|
// check which use-case we have
|
||||||
bool use_tx = (tx != NULL && tx_length > 0);
|
bool use_tx = (tx != NULL && tx_length > 0);
|
||||||
bool use_rx = (rx != NULL && rx_length > 0);
|
bool use_rx = (rx != NULL && rx_length > 0);
|
||||||
|
|
@ -1463,10 +1703,10 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
|
||||||
|
|
||||||
obj->spi.event = event;
|
obj->spi.event = event;
|
||||||
|
|
||||||
// register the thunking handler
|
// Register the callback.
|
||||||
IRQn_Type irq_n = spiobj->spiIRQ;
|
// It's a function pointer, but it's passed as a uint32_t because of reasons.
|
||||||
NVIC_SetVector(irq_n, (uint32_t)handler);
|
spiobj->driverCallback = (void (*)(void))handler;
|
||||||
DEBUG_PRINTF("SPI: Transfer: tx %u (%u), rx %u (%u), IRQ %u\n", use_tx, tx_length, use_rx, rx_length, irq_n);
|
DEBUG_PRINTF("SPI: Transfer: tx %u (%u), rx %u (%u)\n", use_tx, tx_length, use_rx, rx_length);
|
||||||
|
|
||||||
// enable the right hal transfer
|
// enable the right hal transfer
|
||||||
if (use_tx && use_rx) {
|
if (use_tx && use_rx) {
|
||||||
|
|
@ -1477,22 +1717,19 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
|
||||||
obj->tx_buff.length = size;
|
obj->tx_buff.length = size;
|
||||||
obj->rx_buff.length = size;
|
obj->rx_buff.length = size;
|
||||||
}
|
}
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size);
|
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size, hint);
|
||||||
} else if (use_tx) {
|
} else if (use_tx) {
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, tx, NULL, tx_length);
|
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, tx, NULL, tx_length, hint);
|
||||||
} else if (use_rx) {
|
} else if (use_rx) {
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX, NULL, rx, rx_length);
|
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX, NULL, rx, rx_length, hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t spi_irq_handler_asynch(spi_t *obj)
|
uint32_t spi_irq_handler_asynch(spi_t *obj)
|
||||||
{
|
{
|
||||||
int event = 0;
|
int event = 0;
|
||||||
SPI_HandleTypeDef *handle = &(SPI_S(obj)->handle);
|
SPI_HandleTypeDef *handle = &(SPI_S(obj)->handle);
|
||||||
|
|
||||||
// call the CubeF4 handler, this will update the handle
|
|
||||||
HAL_SPI_IRQHandler(handle);
|
|
||||||
|
|
||||||
if (handle->State == HAL_SPI_STATE_READY) {
|
if (handle->State == HAL_SPI_STATE_READY) {
|
||||||
// When HAL SPI is back to READY state, check if there was an error
|
// When HAL SPI is back to READY state, check if there was an error
|
||||||
int error = obj->spi.handle.ErrorCode;
|
int error = obj->spi.handle.ErrorCode;
|
||||||
|
|
@ -1537,6 +1774,36 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
|
||||||
return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE));
|
return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback from STM32 HAL when a bidirectional SPI transfer completes (interrupt based or DMA)
|
||||||
|
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||||
|
{
|
||||||
|
struct spi_s * spis = get_spis_pointer(hspi);
|
||||||
|
if(spis != NULL)
|
||||||
|
{
|
||||||
|
spis->driverCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback from STM32 HAL when a Rx-only SPI transfer completes (interrupt based or DMA)
|
||||||
|
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||||
|
{
|
||||||
|
struct spi_s * spis = get_spis_pointer(hspi);
|
||||||
|
if(spis != NULL)
|
||||||
|
{
|
||||||
|
spis->driverCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback from STM32 HAL when a Tx-only SPI transfer completes (interrupt based or DMA)
|
||||||
|
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||||
|
{
|
||||||
|
struct spi_s * spis = get_spis_pointer(hspi);
|
||||||
|
if(spis != NULL)
|
||||||
|
{
|
||||||
|
spis->driverCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t spi_active(spi_t *obj)
|
uint8_t spi_active(spi_t *obj)
|
||||||
{
|
{
|
||||||
struct spi_s *spiobj = SPI_S(obj);
|
struct spi_s *spiobj = SPI_S(obj);
|
||||||
|
|
@ -1558,21 +1825,26 @@ void spi_abort_asynch(spi_t *obj)
|
||||||
struct spi_s *spiobj = SPI_S(obj);
|
struct spi_s *spiobj = SPI_S(obj);
|
||||||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||||
|
|
||||||
// disable interrupt
|
// disable interrupt if it was enabled
|
||||||
IRQn_Type irq_n = spiobj->spiIRQ;
|
IRQn_Type irq_n = spiobj->spiIRQ;
|
||||||
NVIC_ClearPendingIRQ(irq_n);
|
NVIC_ClearPendingIRQ(irq_n);
|
||||||
NVIC_DisableIRQ(irq_n);
|
NVIC_DisableIRQ(irq_n);
|
||||||
|
|
||||||
|
#ifdef STM32_SPI_CAPABILITY_DMA
|
||||||
|
// Abort DMA transfers if DMA channels have been allocated
|
||||||
|
if(spiobj->txDMAInitialized) {
|
||||||
|
HAL_DMA_Abort_IT(spiobj->handle.hdmatx);
|
||||||
|
}
|
||||||
|
if(spiobj->rxDMAInitialized) {
|
||||||
|
HAL_DMA_Abort_IT(spiobj->handle.hdmarx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// clean-up
|
// clean-up
|
||||||
LL_SPI_Disable(SPI_INST(obj));
|
LL_SPI_Disable(SPI_INST(obj));
|
||||||
HAL_SPI_DeInit(handle);
|
HAL_SPI_DeInit(handle);
|
||||||
HAL_SPI_Init(handle);
|
|
||||||
// cleanup input buffer
|
init_spi(obj);
|
||||||
spi_flush_rx(obj);
|
|
||||||
// enable SPI back if it isn't 3-wire mode
|
|
||||||
if (handle->Init.Direction != SPI_DIRECTION_1LINE) {
|
|
||||||
LL_SPI_Enable(SPI_INST(obj));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //DEVICE_SPI_ASYNCH
|
#endif //DEVICE_SPI_ASYNCH
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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_SPI_API_H
|
||||||
|
#define MBED_OS_STM_SPI_API_H
|
||||||
|
|
||||||
|
#include "spi_device.h"
|
||||||
|
|
||||||
|
#if STM32_SPI_CAPABILITY_DMA
|
||||||
|
#include "stm_dma_utils.h"
|
||||||
|
#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;
|
||||||
|
|
||||||
|
// Callback function for when we get an interrupt on an async transfer.
|
||||||
|
// This will point, through a bit of indirection, to SPI::irq_handler_asynch()
|
||||||
|
// for the correct SPI instance.
|
||||||
|
void (*driverCallback)(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
uint8_t spiIndex; // Index of the SPI peripheral, from 1-6
|
||||||
|
#if STM32_SPI_CAPABILITY_DMA
|
||||||
|
bool txDMAInitialized;
|
||||||
|
bool rxDMAInitialized;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MBED_OS_STM_SPI_API_H
|
||||||
|
|
@ -3224,7 +3224,8 @@
|
||||||
"CRC",
|
"CRC",
|
||||||
"TRNG",
|
"TRNG",
|
||||||
"FLASH",
|
"FLASH",
|
||||||
"MPU"
|
"MPU",
|
||||||
|
"SPI_32BIT_WORDS"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"MCU_STM32H723xG": {
|
"MCU_STM32H723xG": {
|
||||||
|
|
@ -4849,7 +4850,8 @@
|
||||||
"FLASH",
|
"FLASH",
|
||||||
"MPU",
|
"MPU",
|
||||||
"TRNG",
|
"TRNG",
|
||||||
"SERIAL_ASYNCH"
|
"SERIAL_ASYNCH",
|
||||||
|
"SPI_32BIT_WORDS"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"MCU_STM32U575xI": {
|
"MCU_STM32U575xI": {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ set(MBEDHTRUN_ARGS --skip-flashing @MBED_HTRUN_ARGUMENTS@) # filled in by config
|
||||||
|
|
||||||
# Print out command
|
# Print out command
|
||||||
string(REPLACE ";" " " MBEDHTRUN_ARGS_FOR_DISPLAY "${MBEDHTRUN_ARGS}")
|
string(REPLACE ";" " " MBEDHTRUN_ARGS_FOR_DISPLAY "${MBEDHTRUN_ARGS}")
|
||||||
message("Executing: mbedhtrun ${MBEDHTRUN_ARGS_FOR_DISPLAY}")
|
message("Executing: @Python3_EXECUTABLE@ -m mbed_host_tests.mbedhtrun ${MBEDHTRUN_ARGS_FOR_DISPLAY}")
|
||||||
|
|
||||||
# Note: For this command, we need to survive mbedhtrun not being on the PATH, so we import the package and call the main function using "python -c"
|
# Note: For this command, we need to survive mbedhtrun not being on the PATH, so we import the package and call the main function using "python -c"
|
||||||
execute_process(
|
execute_process(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue