Skip to content

Commit d3b03de

Browse files
committed
STM32 SPI : STM32H7 IP is SPI_IP_VERSION_V2
1 parent d1f02f3 commit d3b03de

File tree

2 files changed

+109
-30
lines changed

2 files changed

+109
-30
lines changed

targets/TARGET_STM/TARGET_STM32H7/spi_device.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "stm32h7xx_ll_rcc.h"
2020
#include "stm32h7xx_ll_spi.h"
2121

22+
#define SPI_IP_VERSION_V2
23+
2224
// Defines the word legnth capability of the device where Nth bit allows for N window size
2325
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0xFFFFFFF8)
2426

targets/TARGET_STM/stm_spi_api.c

Lines changed: 107 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -197,44 +197,102 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
197197
spiobj->spi = (SPIName)pinmap->peripheral;
198198
MBED_ASSERT(spiobj->spi != (SPIName)NC);
199199

200+
#if defined(SPI_IP_VERSION_V2)
201+
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
202+
#endif /* SPI_IP_VERSION_V2 */
203+
200204
#if defined SPI1_BASE
201205
// Enable SPI clock
202206
if (spiobj->spi == SPI_1) {
207+
#if defined(SPI_IP_VERSION_V2)
208+
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
209+
#if defined (RCC_SPI123CLKSOURCE_PLL)
210+
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
211+
#else
212+
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK;
213+
#endif
214+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
215+
error("HAL_RCCEx_PeriphCLKConfig\n");
216+
}
217+
#endif /* SPI_IP_VERSION_V2 */
203218
__HAL_RCC_SPI1_CLK_ENABLE();
204219
spiobj->spiIRQ = SPI1_IRQn;
205220
}
206221
#endif
207222

208223
#if defined SPI2_BASE
209224
if (spiobj->spi == SPI_2) {
225+
#if defined(SPI_IP_VERSION_V2)
226+
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
227+
#if defined (RCC_SPI123CLKSOURCE_PLL)
228+
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
229+
#else
230+
PeriphClkInit.Spi2ClockSelection = RCC_SPI2CLKSOURCE_SYSCLK;
231+
#endif
232+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
233+
error("HAL_RCCEx_PeriphCLKConfig\n");
234+
}
235+
#endif /* SPI_IP_VERSION_V2 */
210236
__HAL_RCC_SPI2_CLK_ENABLE();
211237
spiobj->spiIRQ = SPI2_IRQn;
212238
}
213239
#endif
214240

215241
#if defined SPI3_BASE
216242
if (spiobj->spi == SPI_3) {
243+
#if defined(SPI_IP_VERSION_V2)
244+
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
245+
#if defined (RCC_SPI123CLKSOURCE_PLL)
246+
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
247+
#else
248+
PeriphClkInit.Spi3ClockSelection = RCC_SPI3CLKSOURCE_SYSCLK;
249+
#endif
250+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
251+
error("HAL_RCCEx_PeriphCLKConfig\n");
252+
}
253+
#endif /* SPI_IP_VERSION_V2 */
217254
__HAL_RCC_SPI3_CLK_ENABLE();
218255
spiobj->spiIRQ = SPI3_IRQn;
219256
}
220257
#endif
221258

222259
#if defined SPI4_BASE
223260
if (spiobj->spi == SPI_4) {
261+
#if defined(SPI_IP_VERSION_V2)
262+
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI4;
263+
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
264+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
265+
error("HAL_RCCEx_PeriphCLKConfig\n");
266+
}
267+
#endif /* SPI_IP_VERSION_V2 */
224268
__HAL_RCC_SPI4_CLK_ENABLE();
225269
spiobj->spiIRQ = SPI4_IRQn;
226270
}
227271
#endif
228272

229273
#if defined SPI5_BASE
230274
if (spiobj->spi == SPI_5) {
275+
#if defined(SPI_IP_VERSION_V2)
276+
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI5;
277+
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
278+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
279+
error("HAL_RCCEx_PeriphCLKConfig\n");
280+
}
281+
#endif /* SPI_IP_VERSION_V2 */
231282
__HAL_RCC_SPI5_CLK_ENABLE();
232283
spiobj->spiIRQ = SPI5_IRQn;
233284
}
234285
#endif
235286

236287
#if defined SPI6_BASE
237288
if (spiobj->spi == SPI_6) {
289+
#if defined(SPI_IP_VERSION_V2)
290+
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
291+
PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PCLK4;
292+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
293+
error("HAL_RCCEx_PeriphCLKConfig\n");
294+
}
295+
#endif /* SPI_IP_VERSION_V2 */
238296
__HAL_RCC_SPI6_CLK_ENABLE();
239297
spiobj->spiIRQ = SPI6_IRQn;
240298
}
@@ -289,10 +347,21 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
289347
handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
290348
handle->Init.TIMode = SPI_TIMODE_DISABLE;
291349

292-
#if TARGET_STM32H7
350+
#if defined (SPI_IP_VERSION_V2)
351+
handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
293352
handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
294353
handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
295-
#endif
354+
handle->Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
355+
handle->Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
356+
handle->Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
357+
handle->Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
358+
handle->Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
359+
handle->Init.IOSwap = SPI_IO_SWAP_DISABLE;
360+
#if defined(SPI_RDY_MASTER_MANAGEMENT_INTERNALLY)
361+
handle->Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
362+
handle->Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
363+
#endif
364+
#endif /* SPI_IP_VERSION_V2 */
296365

297366
/*
298367
* According the STM32 Datasheet for SPI peripheral we need to PULLDOWN
@@ -699,7 +768,11 @@ static inline int ssp_readable(spi_t *obj)
699768
SPI_HandleTypeDef *handle = &(spiobj->handle);
700769

701770
// Check if data is received
771+
#if defined(SPI_IP_VERSION_V2)
772+
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXP) != RESET) ? 1 : 0);
773+
#else /* SPI_IP_VERSION_V2 */
702774
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
775+
#endif /* SPI_IP_VERSION_V2 */
703776
return status;
704777
}
705778

@@ -710,7 +783,12 @@ static inline int ssp_writeable(spi_t *obj)
710783
SPI_HandleTypeDef *handle = &(spiobj->handle);
711784

712785
// Check if data is transmitted
786+
#if defined(SPI_IP_VERSION_V2)
787+
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXP) != RESET) ? 1 : 0);
788+
#else /* SPI_IP_VERSION_V2 */
713789
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_TXE) != RESET) ? 1 : 0);
790+
#endif /* SPI_IP_VERSION_V2 */
791+
714792
return status;
715793
}
716794

@@ -719,11 +797,11 @@ static inline int ssp_busy(spi_t *obj)
719797
int status;
720798
struct spi_s *spiobj = SPI_S(obj);
721799
SPI_HandleTypeDef *handle = &(spiobj->handle);
722-
#if TARGET_STM32H7
800+
#if defined(SPI_IP_VERSION_V2)
723801
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_RXWNE) != RESET) ? 1 : 0);
724-
#else /* TARGET_STM32H7 */
802+
#else /* SPI_IP_VERSION_V2 */
725803
status = ((__HAL_SPI_GET_FLAG(handle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
726-
#endif /* TARGET_STM32H7 */
804+
#endif /* SPI_IP_VERSION_V2 */
727805
return status;
728806
}
729807

@@ -845,11 +923,11 @@ static inline int datasize_to_transfer_bitshift(uint32_t DataSize)
845923
*/
846924
static inline int msp_writable(spi_t *obj)
847925
{
848-
#if TARGET_STM32H7
926+
#if defined(SPI_IP_VERSION_V2)
849927
return (int)LL_SPI_IsActiveFlag_TXP(SPI_INST(obj));
850-
#else /* TARGET_STM32H7 */
928+
#else /* SPI_IP_VERSION_V2 */
851929
return (int)LL_SPI_IsActiveFlag_TXE(SPI_INST(obj));
852-
#endif /* TARGET_STM32H7 */
930+
#endif /* SPI_IP_VERSION_V2 */
853931
}
854932

855933
/**
@@ -860,11 +938,11 @@ static inline int msp_writable(spi_t *obj)
860938
*/
861939
static inline int msp_readable(spi_t *obj)
862940
{
863-
#if TARGET_STM32H7
941+
#if defined(SPI_IP_VERSION_V2)
864942
return (int)LL_SPI_IsActiveFlag_RXP(SPI_INST(obj));
865-
#else /* TARGET_STM32H7 */
943+
#else /* SPI_IP_VERSION_V2 */
866944
return (int)LL_SPI_IsActiveFlag_RXNE(SPI_INST(obj));
867-
#endif /* TARGET_STM32H7 */
945+
#endif /* SPI_IP_VERSION_V2 */
868946
}
869947

870948
/**
@@ -891,11 +969,11 @@ static inline void msp_wait_readable(spi_t *obj)
891969
*/
892970
static inline int msp_busy(spi_t *obj)
893971
{
894-
#if TARGET_STM32H7
972+
#if defined(SPI_IP_VERSION_V2)
895973
return !(int)LL_SPI_IsActiveFlag_TXC(SPI_INST(obj));
896-
#else /* TARGET_STM32H7 */
974+
#else /* SPI_IP_VERSION_V2 */
897975
return (int)LL_SPI_IsActiveFlag_BSY(SPI_INST(obj));
898-
#endif /* TARGET_STM32H7 */
976+
#endif /* SPI_IP_VERSION_V2 */
899977
}
900978

901979
/**
@@ -962,15 +1040,15 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
9621040
/* Transmit data */
9631041
if (tx_length) {
9641042
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_TX);
965-
#if TARGET_STM32H7
1043+
#if defined(SPI_IP_VERSION_V2)
9661044
/* Set transaction size */
9671045
LL_SPI_SetTransferSize(SPI_INST(obj), tx_length);
968-
#endif /* TARGET_STM32H7 */
1046+
#endif /* SPI_IP_VERSION_V2 */
9691047
LL_SPI_Enable(SPI_INST(obj));
970-
#if TARGET_STM32H7
1048+
#if defined(SPI_IP_VERSION_V2)
9711049
/* Master transfer start */
9721050
LL_SPI_StartMasterTransfer(SPI_INST(obj));
973-
#endif /* TARGET_STM32H7 */
1051+
#endif /* SPI_IP_VERSION_V2 */
9741052

9751053
for (int i = 0; i < tx_length; i++) {
9761054
msp_wait_writable(obj);
@@ -982,19 +1060,19 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
9821060

9831061
LL_SPI_Disable(SPI_INST(obj));
9841062

985-
#if TARGET_STM32H7
1063+
#if defined(SPI_IP_VERSION_V2)
9861064
/* Clear transaction flags */
9871065
LL_SPI_ClearFlag_EOT(SPI_INST(obj));
9881066
LL_SPI_ClearFlag_TXTF(SPI_INST(obj));
9891067
/* Reset transaction size */
9901068
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
991-
#endif /* TARGET_STM32H7 */
1069+
#endif /* SPI_IP_VERSION_V2 */
9921070
}
9931071

9941072
/* Receive data */
9951073
if (rx_length) {
9961074
LL_SPI_SetTransferDirection(SPI_INST(obj), LL_SPI_HALF_DUPLEX_RX);
997-
#if TARGET_STM32H7
1075+
#if defined(SPI_IP_VERSION_V2)
9981076
/* Set transaction size and run SPI */
9991077
LL_SPI_SetTransferSize(SPI_INST(obj), rx_length);
10001078
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
10141092
/* Reset transaction size */
10151093
LL_SPI_SetTransferSize(SPI_INST(obj), 0);
10161094

1017-
#else /* TARGET_STM32H7 */
1095+
#else /* SPI_IP_VERSION_V2 */
10181096
/* Unlike STM32H7 other STM32 families generates SPI Clock signal continuously in half-duplex receive mode
10191097
* till SPI is enabled. To stop clock generation a SPI should be disabled during last frame receiving,
10201098
* 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
10441122
rx_buffer[i] = msp_read_data(obj, bitshift);
10451123
}
10461124

1047-
#endif /* TARGET_STM32H7 */
1125+
#endif /* SPI_IP_VERSION_V2 */
10481126
}
10491127

10501128
return rx_length + tx_length;
@@ -1077,10 +1155,10 @@ int spi_master_write(spi_t *obj, int value)
10771155
* but this will increase performances significantly
10781156
*/
10791157

1080-
#if TARGET_STM32H7
1158+
#if defined(SPI_IP_VERSION_V2)
10811159
/* Master transfer start */
10821160
LL_SPI_StartMasterTransfer(SPI_INST(obj));
1083-
#endif
1161+
#endif /* SPI_IP_VERSION_V2 */
10841162

10851163
/* Transmit data */
10861164
msp_wait_writable(obj);
@@ -1241,7 +1319,7 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
12411319
NVIC_EnableIRQ(irq_n);
12421320

12431321
// flush FIFO
1244-
#if defined(SPI_FLAG_FRLVL) // STM32F0 STM32F3 STM32F7 STM32L4
1322+
#if defined(SPI_FLAG_FRLVL)
12451323
HAL_SPIEx_FlushRxFifo(handle);
12461324
#endif
12471325

@@ -1306,11 +1384,10 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
13061384

13071385
obj->spi.event = event;
13081386

1309-
DEBUG_PRINTF("SPI: Transfer: %u, %u\n", tx_length, rx_length);
1310-
13111387
// register the thunking handler
13121388
IRQn_Type irq_n = spiobj->spiIRQ;
13131389
NVIC_SetVector(irq_n, (uint32_t)handler);
1390+
DEBUG_PRINTF("SPI: Transfer: tx %u (%u), rx %u (%u), IRQ %u\n", use_tx, tx_length, use_rx, rx_length, irq_n);
13141391

13151392
// enable the right hal transfer
13161393
if (use_tx && use_rx) {
@@ -1355,7 +1432,7 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
13551432
// disable the interrupt
13561433
NVIC_DisableIRQ(obj->spi.spiIRQ);
13571434
NVIC_ClearPendingIRQ(obj->spi.spiIRQ);
1358-
#ifndef TARGET_STM32H7
1435+
#if !defined(SPI_IP_VERSION_V2)
13591436
if (handle->Init.Direction == SPI_DIRECTION_1LINE && obj->rx_buff.buffer != NULL) {
13601437
/**
13611438
* 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)
13651442
*/
13661443
spi_flush_rx(obj);
13671444
}
1368-
#endif
1445+
#endif /* SPI_IP_VERSION_V2 */
13691446
}
13701447

13711448
return (event & (obj->spi.event | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE));

0 commit comments

Comments
 (0)