mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #15028 from jeromecoutant/PR_SPI_V2
STM32 SPI: Update and improvementpull/15061/head
commit
3eae29b01d
|
@ -19,6 +19,8 @@
|
||||||
#include "stm32h7xx_ll_rcc.h"
|
#include "stm32h7xx_ll_rcc.h"
|
||||||
#include "stm32h7xx_ll_spi.h"
|
#include "stm32h7xx_ll_spi.h"
|
||||||
|
|
||||||
|
#define SPI_IP_VERSION_V2
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
||||||
|
|
|
@ -197,9 +197,27 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
spiobj->spi = (SPIName)pinmap->peripheral;
|
spiobj->spi = (SPIName)pinmap->peripheral;
|
||||||
MBED_ASSERT(spiobj->spi != (SPIName)NC);
|
MBED_ASSERT(spiobj->spi != (SPIName)NC);
|
||||||
|
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
#if defined SPI1_BASE
|
#if defined SPI1_BASE
|
||||||
// Enable SPI clock
|
// Enable SPI clock
|
||||||
if (spiobj->spi == SPI_1) {
|
if (spiobj->spi == SPI_1) {
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
|
||||||
|
#if defined (RCC_SPI123CLKSOURCE_PLL)
|
||||||
|
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
|
||||||
|
#else
|
||||||
|
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK;
|
||||||
|
#endif
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
__HAL_RCC_SPI1_FORCE_RESET();
|
||||||
|
__HAL_RCC_SPI1_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI1_IRQn;
|
spiobj->spiIRQ = SPI1_IRQn;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +225,20 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
|
|
||||||
#if defined SPI2_BASE
|
#if defined SPI2_BASE
|
||||||
if (spiobj->spi == SPI_2) {
|
if (spiobj->spi == SPI_2) {
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
|
||||||
|
#if defined (RCC_SPI123CLKSOURCE_PLL)
|
||||||
|
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
|
||||||
|
#else
|
||||||
|
PeriphClkInit.Spi2ClockSelection = RCC_SPI2CLKSOURCE_SYSCLK;
|
||||||
|
#endif
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
__HAL_RCC_SPI2_FORCE_RESET();
|
||||||
|
__HAL_RCC_SPI2_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI2_IRQn;
|
spiobj->spiIRQ = SPI2_IRQn;
|
||||||
}
|
}
|
||||||
|
@ -214,6 +246,20 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
|
|
||||||
#if defined SPI3_BASE
|
#if defined SPI3_BASE
|
||||||
if (spiobj->spi == SPI_3) {
|
if (spiobj->spi == SPI_3) {
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
|
||||||
|
#if defined (RCC_SPI123CLKSOURCE_PLL)
|
||||||
|
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
|
||||||
|
#else
|
||||||
|
PeriphClkInit.Spi3ClockSelection = RCC_SPI3CLKSOURCE_SYSCLK;
|
||||||
|
#endif
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
__HAL_RCC_SPI3_FORCE_RESET();
|
||||||
|
__HAL_RCC_SPI3_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI3_IRQn;
|
spiobj->spiIRQ = SPI3_IRQn;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +267,16 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
|
|
||||||
#if defined SPI4_BASE
|
#if defined SPI4_BASE
|
||||||
if (spiobj->spi == SPI_4) {
|
if (spiobj->spi == SPI_4) {
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI4;
|
||||||
|
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
__HAL_RCC_SPI4_FORCE_RESET();
|
||||||
|
__HAL_RCC_SPI4_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI4_CLK_ENABLE();
|
__HAL_RCC_SPI4_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI4_IRQn;
|
spiobj->spiIRQ = SPI4_IRQn;
|
||||||
}
|
}
|
||||||
|
@ -228,6 +284,16 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
|
|
||||||
#if defined SPI5_BASE
|
#if defined SPI5_BASE
|
||||||
if (spiobj->spi == SPI_5) {
|
if (spiobj->spi == SPI_5) {
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI5;
|
||||||
|
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
__HAL_RCC_SPI5_FORCE_RESET();
|
||||||
|
__HAL_RCC_SPI5_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI5_CLK_ENABLE();
|
__HAL_RCC_SPI5_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI5_IRQn;
|
spiobj->spiIRQ = SPI5_IRQn;
|
||||||
}
|
}
|
||||||
|
@ -235,6 +301,16 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
|
|
||||||
#if defined SPI6_BASE
|
#if defined SPI6_BASE
|
||||||
if (spiobj->spi == SPI_6) {
|
if (spiobj->spi == SPI_6) {
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
|
||||||
|
PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PCLK4;
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
|
__HAL_RCC_SPI6_FORCE_RESET();
|
||||||
|
__HAL_RCC_SPI6_RELEASE_RESET();
|
||||||
__HAL_RCC_SPI6_CLK_ENABLE();
|
__HAL_RCC_SPI6_CLK_ENABLE();
|
||||||
spiobj->spiIRQ = SPI6_IRQn;
|
spiobj->spiIRQ = SPI6_IRQn;
|
||||||
}
|
}
|
||||||
|
@ -242,13 +318,14 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
|
|
||||||
// Configure the SPI pins
|
// Configure the SPI pins
|
||||||
pin_function(pinmap->mosi_pin, pinmap->mosi_function);
|
pin_function(pinmap->mosi_pin, pinmap->mosi_function);
|
||||||
pin_mode(pinmap->mosi_pin, PullNone);
|
pin_mode(pinmap->mosi_pin, PullDown); // Pull Down is set for output line
|
||||||
|
|
||||||
pin_function(pinmap->miso_pin, pinmap->miso_function);
|
pin_function(pinmap->miso_pin, pinmap->miso_function);
|
||||||
pin_mode(pinmap->miso_pin, PullNone);
|
pin_mode(pinmap->miso_pin, PullNone);
|
||||||
|
|
||||||
pin_function(pinmap->sclk_pin, pinmap->sclk_function);
|
pin_function(pinmap->sclk_pin, pinmap->sclk_function);
|
||||||
pin_mode(pinmap->sclk_pin, PullNone);
|
pin_mode(pinmap->sclk_pin, PullNone);
|
||||||
|
|
||||||
spiobj->pin_miso = pinmap->miso_pin;
|
spiobj->pin_miso = pinmap->miso_pin;
|
||||||
spiobj->pin_mosi = pinmap->mosi_pin;
|
spiobj->pin_mosi = pinmap->mosi_pin;
|
||||||
spiobj->pin_sclk = pinmap->sclk_pin;
|
spiobj->pin_sclk = pinmap->sclk_pin;
|
||||||
|
@ -289,10 +366,21 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
||||||
handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
|
handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||||
handle->Init.TIMode = SPI_TIMODE_DISABLE;
|
handle->Init.TIMode = SPI_TIMODE_DISABLE;
|
||||||
|
|
||||||
#if TARGET_STM32H7
|
#if defined (SPI_IP_VERSION_V2)
|
||||||
|
handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
|
||||||
handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
|
handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
|
||||||
handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
|
handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
|
||||||
|
handle->Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
|
||||||
|
handle->Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
|
||||||
|
handle->Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
|
||||||
|
handle->Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
|
||||||
|
handle->Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
|
||||||
|
handle->Init.IOSwap = SPI_IO_SWAP_DISABLE;
|
||||||
|
#if defined(SPI_RDY_MASTER_MANAGEMENT_INTERNALLY)
|
||||||
|
handle->Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
|
||||||
|
handle->Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According the STM32 Datasheet for SPI peripheral we need to PULLDOWN
|
* According the STM32 Datasheet for SPI peripheral we need to PULLDOWN
|
||||||
|
@ -580,16 +668,21 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
||||||
handle->Init.NSS = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT;
|
handle->Init.NSS = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->Init.Mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER;
|
if (slave) {
|
||||||
|
handle->Init.Mode = SPI_MODE_SLAVE;
|
||||||
|
|
||||||
if (slave && (handle->Init.Direction == SPI_DIRECTION_1LINE)) {
|
if (handle->Init.Direction == SPI_DIRECTION_1LINE) {
|
||||||
/* SPI slave implemtation in MBED does not support the 3 wires SPI.
|
/* SPI slave implemtation in MBED does not support the 3 wires SPI.
|
||||||
* (e.g. when MISO is not connected). So we're forcing slave in
|
* (e.g. when MISO is not connected). So we're forcing slave in
|
||||||
* 2LINES mode. As MISO is not connected, slave will only read
|
* 2LINES mode. As MISO is not connected, slave will only read
|
||||||
* from master, and cannot write to it. Inform user.
|
* from master, and cannot write to it. Inform user.
|
||||||
*/
|
*/
|
||||||
debug("3 wires SPI slave not supported - slave will only read\r\n");
|
debug("3 wires SPI slave not supported - slave will only read\r\n");
|
||||||
handle->Init.Direction = SPI_DIRECTION_2LINES;
|
handle->Init.Direction = SPI_DIRECTION_2LINES;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_mode(spiobj->pin_mosi, PullNone);
|
||||||
|
pin_mode(spiobj->pin_miso, PullDown); // Pull Down is set for output line
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -699,7 +792,11 @@ static inline int ssp_readable(spi_t *obj)
|
||||||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||||
|
|
||||||
// Check if data is received
|
// Check if data is received
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXP) != RESET) ? 1 : 0);
|
||||||
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
|
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +807,12 @@ static inline int ssp_writeable(spi_t *obj)
|
||||||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||||
|
|
||||||
// Check if data is transmitted
|
// Check if data is transmitted
|
||||||
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
|
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXP) != RESET) ? 1 : 0);
|
||||||
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXE) != RESET) ? 1 : 0);
|
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXE) != RESET) ? 1 : 0);
|
||||||
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,11 +821,11 @@ static inline int ssp_busy(spi_t *obj)
|
||||||
int status;
|
int status;
|
||||||
struct spi_s *spiobj = SPI_S(obj);
|
struct spi_s *spiobj = SPI_S(obj);
|
||||||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXWNE) != RESET) ? 1 : 0);
|
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXWNE) != RESET) ? 1 : 0);
|
||||||
#else /* TARGET_STM32H7 */
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
|
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,11 +947,11 @@ static inline int datasize_to_transfer_bitshift(uint32_t DataSize)
|
||||||
*/
|
*/
|
||||||
static inline int msp_writable(spi_t *obj)
|
static inline int msp_writable(spi_t *obj)
|
||||||
{
|
{
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
return (int)LL_SPI_IsActiveFlag_TXP(SPI_INST(obj));
|
return (int)LL_SPI_IsActiveFlag_TXP(SPI_INST(obj));
|
||||||
#else /* TARGET_STM32H7 */
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
return (int)LL_SPI_IsActiveFlag_TXE(SPI_INST(obj));
|
return (int)LL_SPI_IsActiveFlag_TXE(SPI_INST(obj));
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -860,11 +962,11 @@ static inline int msp_writable(spi_t *obj)
|
||||||
*/
|
*/
|
||||||
static inline int msp_readable(spi_t *obj)
|
static inline int msp_readable(spi_t *obj)
|
||||||
{
|
{
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
return (int)LL_SPI_IsActiveFlag_RXP(SPI_INST(obj));
|
return (int)LL_SPI_IsActiveFlag_RXP(SPI_INST(obj));
|
||||||
#else /* TARGET_STM32H7 */
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
return (int)LL_SPI_IsActiveFlag_RXNE(SPI_INST(obj));
|
return (int)LL_SPI_IsActiveFlag_RXNE(SPI_INST(obj));
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -891,11 +993,11 @@ static inline void msp_wait_readable(spi_t *obj)
|
||||||
*/
|
*/
|
||||||
static inline int msp_busy(spi_t *obj)
|
static inline int msp_busy(spi_t *obj)
|
||||||
{
|
{
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
return !(int)LL_SPI_IsActiveFlag_TXC(SPI_INST(obj));
|
return !(int)LL_SPI_IsActiveFlag_TXC(SPI_INST(obj));
|
||||||
#else /* TARGET_STM32H7 */
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
return (int)LL_SPI_IsActiveFlag_BSY(SPI_INST(obj));
|
return (int)LL_SPI_IsActiveFlag_BSY(SPI_INST(obj));
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -962,15 +1064,15 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
||||||
/* Transmit data */
|
/* Transmit data */
|
||||||
if (tx_length) {
|
if (tx_length) {
|
||||||
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_TX);
|
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_TX);
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
/* Set transaction size */
|
/* Set transaction size */
|
||||||
LL_SPI_SetTransferSize(SPI_INST(obj), tx_length);
|
LL_SPI_SetTransferSize(SPI_INST(obj), tx_length);
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
LL_SPI_Enable(SPI_INST(obj));
|
LL_SPI_Enable(SPI_INST(obj));
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
/* Master transfer start */
|
/* Master transfer start */
|
||||||
LL_SPI_StartMasterTransfer(SPI_INST(obj));
|
LL_SPI_StartMasterTransfer(SPI_INST(obj));
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
for (int i = 0; i < tx_length; i++) {
|
for (int i = 0; i < tx_length; i++) {
|
||||||
msp_wait_writable(obj);
|
msp_wait_writable(obj);
|
||||||
|
@ -982,19 +1084,19 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
||||||
|
|
||||||
LL_SPI_Disable(SPI_INST(obj));
|
LL_SPI_Disable(SPI_INST(obj));
|
||||||
|
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
/* Clear transaction flags */
|
/* Clear transaction flags */
|
||||||
LL_SPI_ClearFlag_EOT(SPI_INST(obj));
|
LL_SPI_ClearFlag_EOT(SPI_INST(obj));
|
||||||
LL_SPI_ClearFlag_TXTF(SPI_INST(obj));
|
LL_SPI_ClearFlag_TXTF(SPI_INST(obj));
|
||||||
/* Reset transaction size */
|
/* Reset transaction size */
|
||||||
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
|
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive data */
|
/* Receive data */
|
||||||
if (rx_length) {
|
if (rx_length) {
|
||||||
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_RX);
|
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_RX);
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
/* Set transaction size and run SPI */
|
/* Set transaction size and run SPI */
|
||||||
LL_SPI_SetTransferSize(SPI_INST(obj), rx_length);
|
LL_SPI_SetTransferSize(SPI_INST(obj), rx_length);
|
||||||
LL_SPI_Enable(SPI_INST(obj));
|
LL_SPI_Enable(SPI_INST(obj));
|
||||||
|
@ -1014,7 +1116,7 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
||||||
/* Reset transaction size */
|
/* Reset transaction size */
|
||||||
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
|
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
|
||||||
|
|
||||||
#else /* TARGET_STM32H7 */
|
#else /* SPI_IP_VERSION_V2 */
|
||||||
/* Unlike STM32H7 other STM32 families generates SPI Clock signal continuously in half-duplex receive mode
|
/* Unlike STM32H7 other STM32 families generates SPI Clock signal continuously in half-duplex receive mode
|
||||||
* till SPI is enabled. To stop clock generation a SPI should be disabled during last frame receiving,
|
* till SPI is enabled. To stop clock generation a SPI should be disabled during last frame receiving,
|
||||||
* after generation at least one SPI clock cycle. It causes necessity of critical section usage.
|
* after generation at least one SPI clock cycle. It causes necessity of critical section usage.
|
||||||
|
@ -1044,7 +1146,7 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
||||||
rx_buffer[i] = msp_read_data(obj, bitshift);
|
rx_buffer[i] = msp_read_data(obj, bitshift);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TARGET_STM32H7 */
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
return rx_length + tx_length;
|
return rx_length + tx_length;
|
||||||
|
@ -1077,10 +1179,10 @@ int spi_master_write(spi_t *obj, int value)
|
||||||
* but this will increase performances significantly
|
* but this will increase performances significantly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if TARGET_STM32H7
|
#if defined(SPI_IP_VERSION_V2)
|
||||||
/* Master transfer start */
|
/* Master transfer start */
|
||||||
LL_SPI_StartMasterTransfer(SPI_INST(obj));
|
LL_SPI_StartMasterTransfer(SPI_INST(obj));
|
||||||
#endif
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
|
|
||||||
/* Transmit data */
|
/* Transmit data */
|
||||||
msp_wait_writable(obj);
|
msp_wait_writable(obj);
|
||||||
|
@ -1241,7 +1343,7 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
||||||
NVIC_EnableIRQ(irq_n);
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
// flush FIFO
|
// flush FIFO
|
||||||
#if defined(SPI_FLAG_FRLVL) // STM32F0 STM32F3 STM32F7 STM32L4
|
#if defined(SPI_FLAG_FRLVL)
|
||||||
HAL_SPIEx_FlushRxFifo(handle);
|
HAL_SPIEx_FlushRxFifo(handle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1306,11 +1408,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;
|
||||||
|
|
||||||
DEBUG_PRINTF("SPI: Transfer: %u, %u\n", tx_length, rx_length);
|
|
||||||
|
|
||||||
// register the thunking handler
|
// register the thunking handler
|
||||||
IRQn_Type irq_n = spiobj->spiIRQ;
|
IRQn_Type irq_n = spiobj->spiIRQ;
|
||||||
NVIC_SetVector(irq_n, (uint32_t)handler);
|
NVIC_SetVector(irq_n, (uint32_t)handler);
|
||||||
|
DEBUG_PRINTF("SPI: Transfer: tx %u (%u), rx %u (%u), IRQ %u\n", use_tx, tx_length, use_rx, rx_length, irq_n);
|
||||||
|
|
||||||
// enable the right hal transfer
|
// enable the right hal transfer
|
||||||
if (use_tx && use_rx) {
|
if (use_tx && use_rx) {
|
||||||
|
@ -1355,7 +1456,7 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
|
||||||
// disable the interrupt
|
// disable the interrupt
|
||||||
NVIC_DisableIRQ(obj->spi.spiIRQ);
|
NVIC_DisableIRQ(obj->spi.spiIRQ);
|
||||||
NVIC_ClearPendingIRQ(obj->spi.spiIRQ);
|
NVIC_ClearPendingIRQ(obj->spi.spiIRQ);
|
||||||
#ifndef TARGET_STM32H7
|
#if !defined(SPI_IP_VERSION_V2)
|
||||||
if (handle->Init.Direction == SPI_DIRECTION_1LINE && obj->rx_buff.buffer != NULL) {
|
if (handle->Init.Direction == SPI_DIRECTION_1LINE && obj->rx_buff.buffer != NULL) {
|
||||||
/**
|
/**
|
||||||
* In case of 3-wire SPI data receiving we usually get dummy reads.
|
* In case of 3-wire SPI data receiving we usually get dummy reads.
|
||||||
|
@ -1365,7 +1466,7 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
|
||||||
*/
|
*/
|
||||||
spi_flush_rx(obj);
|
spi_flush_rx(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* SPI_IP_VERSION_V2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE));
|
return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE));
|
||||||
|
|
Loading…
Reference in New Issue