mirror of https://github.com/ARMmbed/mbed-os.git
STM32 SPI : STM32H7 IP is SPI_IP_VERSION_V2
parent
d1f02f3078
commit
d3b03dec0c
|
@ -19,6 +19,8 @@
|
|||
#include "stm32h7xx_ll_rcc.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
|
||||
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0xFFFFFFF8)
|
||||
|
||||
|
|
|
@ -197,9 +197,24 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
spiobj->spi = (SPIName)pinmap->peripheral;
|
||||
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
|
||||
// Enable SPI clock
|
||||
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_CLK_ENABLE();
|
||||
spiobj->spiIRQ = SPI1_IRQn;
|
||||
}
|
||||
|
@ -207,6 +222,17 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
|
||||
#if defined SPI2_BASE
|
||||
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_CLK_ENABLE();
|
||||
spiobj->spiIRQ = SPI2_IRQn;
|
||||
}
|
||||
|
@ -214,6 +240,17 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
|
||||
#if defined SPI3_BASE
|
||||
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_CLK_ENABLE();
|
||||
spiobj->spiIRQ = SPI3_IRQn;
|
||||
}
|
||||
|
@ -221,6 +258,13 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
|
||||
#if defined SPI4_BASE
|
||||
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_CLK_ENABLE();
|
||||
spiobj->spiIRQ = SPI4_IRQn;
|
||||
}
|
||||
|
@ -228,6 +272,13 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
|
||||
#if defined SPI5_BASE
|
||||
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_CLK_ENABLE();
|
||||
spiobj->spiIRQ = SPI5_IRQn;
|
||||
}
|
||||
|
@ -235,6 +286,13 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
|
||||
#if defined SPI6_BASE
|
||||
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_CLK_ENABLE();
|
||||
spiobj->spiIRQ = SPI6_IRQn;
|
||||
}
|
||||
|
@ -289,10 +347,21 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
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.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 /* SPI_IP_VERSION_V2 */
|
||||
|
||||
/*
|
||||
* According the STM32 Datasheet for SPI peripheral we need to PULLDOWN
|
||||
|
@ -699,7 +768,11 @@ static inline int ssp_readable(spi_t *obj)
|
|||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||
|
||||
// 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);
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -710,7 +783,12 @@ static inline int ssp_writeable(spi_t *obj)
|
|||
SPI_HandleTypeDef *handle = &(spiobj->handle);
|
||||
|
||||
// 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);
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -719,11 +797,11 @@ static inline int ssp_busy(spi_t *obj)
|
|||
int status;
|
||||
struct spi_s *spiobj = SPI_S(obj);
|
||||
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);
|
||||
#else /* TARGET_STM32H7 */
|
||||
#else /* SPI_IP_VERSION_V2 */
|
||||
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -845,11 +923,11 @@ static inline int datasize_to_transfer_bitshift(uint32_t DataSize)
|
|||
*/
|
||||
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));
|
||||
#else /* TARGET_STM32H7 */
|
||||
#else /* SPI_IP_VERSION_V2 */
|
||||
return (int)LL_SPI_IsActiveFlag_TXE(SPI_INST(obj));
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -860,11 +938,11 @@ static inline int msp_writable(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));
|
||||
#else /* TARGET_STM32H7 */
|
||||
#else /* SPI_IP_VERSION_V2 */
|
||||
return (int)LL_SPI_IsActiveFlag_RXNE(SPI_INST(obj));
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -891,11 +969,11 @@ static inline void msp_wait_readable(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));
|
||||
#else /* TARGET_STM32H7 */
|
||||
#else /* SPI_IP_VERSION_V2 */
|
||||
return (int)LL_SPI_IsActiveFlag_BSY(SPI_INST(obj));
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -962,15 +1040,15 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
|||
/* Transmit data */
|
||||
if (tx_length) {
|
||||
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_TX);
|
||||
#if TARGET_STM32H7
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
/* Set transaction size */
|
||||
LL_SPI_SetTransferSize(SPI_INST(obj), tx_length);
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
LL_SPI_Enable(SPI_INST(obj));
|
||||
#if TARGET_STM32H7
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
/* Master transfer start */
|
||||
LL_SPI_StartMasterTransfer(SPI_INST(obj));
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
|
||||
for (int i = 0; i < tx_length; i++) {
|
||||
msp_wait_writable(obj);
|
||||
|
@ -982,19 +1060,19 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
|||
|
||||
LL_SPI_Disable(SPI_INST(obj));
|
||||
|
||||
#if TARGET_STM32H7
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
/* Clear transaction flags */
|
||||
LL_SPI_ClearFlag_EOT(SPI_INST(obj));
|
||||
LL_SPI_ClearFlag_TXTF(SPI_INST(obj));
|
||||
/* Reset transaction size */
|
||||
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
}
|
||||
|
||||
/* Receive data */
|
||||
if (rx_length) {
|
||||
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 */
|
||||
LL_SPI_SetTransferSize(SPI_INST(obj), rx_length);
|
||||
LL_SPI_Enable(SPI_INST(obj));
|
||||
|
@ -1014,7 +1092,7 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
|
|||
/* Reset transaction size */
|
||||
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
|
||||
* 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.
|
||||
|
@ -1044,7 +1122,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);
|
||||
}
|
||||
|
||||
#endif /* TARGET_STM32H7 */
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
}
|
||||
|
||||
return rx_length + tx_length;
|
||||
|
@ -1077,10 +1155,10 @@ int spi_master_write(spi_t *obj, int value)
|
|||
* but this will increase performances significantly
|
||||
*/
|
||||
|
||||
#if TARGET_STM32H7
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
/* Master transfer start */
|
||||
LL_SPI_StartMasterTransfer(SPI_INST(obj));
|
||||
#endif
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
|
||||
/* Transmit data */
|
||||
msp_wait_writable(obj);
|
||||
|
@ -1241,7 +1319,7 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
|||
NVIC_EnableIRQ(irq_n);
|
||||
|
||||
// flush FIFO
|
||||
#if defined(SPI_FLAG_FRLVL) // STM32F0 STM32F3 STM32F7 STM32L4
|
||||
#if defined(SPI_FLAG_FRLVL)
|
||||
HAL_SPIEx_FlushRxFifo(handle);
|
||||
#endif
|
||||
|
||||
|
@ -1306,11 +1384,10 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
|
|||
|
||||
obj->spi.event = event;
|
||||
|
||||
DEBUG_PRINTF("SPI: Transfer: %u, %u\n", tx_length, rx_length);
|
||||
|
||||
// register the thunking handler
|
||||
IRQn_Type irq_n = spiobj->spiIRQ;
|
||||
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
|
||||
if (use_tx && use_rx) {
|
||||
|
@ -1355,7 +1432,7 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
|
|||
// disable the interrupt
|
||||
NVIC_DisableIRQ(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) {
|
||||
/**
|
||||
* In case of 3-wire SPI data receiving we usually get dummy reads.
|
||||
|
@ -1365,7 +1442,7 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
|
|||
*/
|
||||
spi_flush_rx(obj);
|
||||
}
|
||||
#endif
|
||||
#endif /* SPI_IP_VERSION_V2 */
|
||||
}
|
||||
|
||||
return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE));
|
||||
|
|
Loading…
Reference in New Issue