Skip to content

Commit fa86c2b

Browse files
JohnK1987Jan Kamidra
andauthored
Add support of SPI API for STM32H5 family (#324)
* fix PWM pin map in context of Timer change * Note about DAC on Nucleo-H503RB * Add ADC and DAC for STM32H5 * Copyright fix * Add I2C for STM32H5 * fix I2C related code * ADC/DAC fix * Enable I2C API * Copyright fix * Add SPI for STM32H5 * Modification of stm spi API for h5 family * fix I2C device * fix I2C ASYNCH macro * fix revert back the stop variable position * Fix clock for SPI * fix some details * Rename startup_stm32h563xx.s to startup_stm32h563xx.S * Rename startup_stm32h503xx.s to startup_stm32h503xx.S --------- Co-authored-by: Jan Kamidra <[email protected]>
1 parent d1dbb40 commit fa86c2b

File tree

10 files changed

+206
-27
lines changed

10 files changed

+206
-27
lines changed

targets/TARGET_STM/TARGET_STM32H5/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ target_sources(mbed-stm32h5
1515
gpio_irq_device.c
1616
i2c_device.c
1717
serial_device.c
18+
spi_api.c
1819
pwmout_device.c
1920
)
2021

targets/TARGET_STM/TARGET_STM32H5/TARGET_STM32H503xB/TOOLCHAIN_GCC_ARM/startup_stm32h503xx.s renamed to targets/TARGET_STM/TARGET_STM32H5/TARGET_STM32H503xB/TOOLCHAIN_GCC_ARM/startup_stm32h503xx.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,4 +541,4 @@ g_pfnVectors:
541541
.thumb_set I3C2_ER_IRQHandler,Default_Handler
542542

543543
.weak COMP1_IRQHandler
544-
.thumb_set COMP1_IRQHandler,Default_Handler
544+
.thumb_set COMP1_IRQHandler,Default_Handler

targets/TARGET_STM/TARGET_STM32H5/TARGET_STM32H563xI/TOOLCHAIN_GCC_ARM/startup_stm32h563xx.s renamed to targets/TARGET_STM/TARGET_STM32H5/TARGET_STM32H563xI/TOOLCHAIN_GCC_ARM/startup_stm32h563xx.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,4 +688,4 @@ g_pfnVectors:
688688
.thumb_set LPTIM5_IRQHandler,Default_Handler
689689

690690
.weak LPTIM6_IRQHandler
691-
.thumb_set LPTIM6_IRQHandler,Default_Handler
691+
.thumb_set LPTIM6_IRQHandler,Default_Handler

targets/TARGET_STM/TARGET_STM32H5/clock_cfg/system_clock.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ else // Divisible by 5MHz
123123
RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
124124

125125
RCC_OscInitStruct.PLL.PLLP = 2;
126-
RCC_OscInitStruct.PLL.PLLQ = 2;
126+
// Most of the SPI busses are clocked off of PLL1Q, and the max usable frequency for SPI is about
127+
// ~50MHz. Plus, SPI has only limited, power-of-2 prescaler options so a high input clock really hurts
128+
// its clock resolution. So, give it a much lower input clock.
129+
RCC_OscInitStruct.PLL.PLLQ = 10; // output freq = 50MHz
127130
RCC_OscInitStruct.PLL.PLLR = 2;
128131
RCC_OscInitStruct.PLL.PLLFRACN = 0;
129132
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
@@ -189,7 +192,10 @@ uint8_t SetSysClock_PLL_HSI(void)
189192
RCC_OscInitStruct.PLL.PLLM = 4;
190193
RCC_OscInitStruct.PLL.PLLN = 31;
191194
RCC_OscInitStruct.PLL.PLLP = 2;
192-
RCC_OscInitStruct.PLL.PLLQ = 2;
195+
// Most of the SPI busses are clocked off of PLL1Q, and the max usable frequency for SPI is about
196+
// ~50MHz. Plus, SPI has only limited, power-of-2 prescaler options so a high input clock really hurts
197+
// its clock resolution. So, give it a much lower input clock.
198+
RCC_OscInitStruct.PLL.PLLQ = 10; // output freq = 50MHz
193199
RCC_OscInitStruct.PLL.PLLR = 2;
194200
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_3;
195201
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;

targets/TARGET_STM/TARGET_STM32H5/objects.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,6 @@ struct trng_s {
5151
RNG_HandleTypeDef handle;
5252
};
5353

54-
struct spi_s {
55-
SPI_HandleTypeDef handle;
56-
IRQn_Type spiIRQ;
57-
SPIName spi;
58-
PinName pin_miso;
59-
PinName pin_mosi;
60-
PinName pin_sclk;
61-
PinName pin_ssel;
62-
#if DEVICE_SPI_ASYNCH
63-
uint32_t event;
64-
uint8_t transfer_type;
65-
#endif
66-
};
67-
6854
struct serial_s {
6955
UARTName uart;
7056
int index; // Used by irq
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/* mbed Microcontroller Library
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
******************************************************************************
4+
*
5+
* Copyright (c) 2015-2024 STMicroelectronics.
6+
* All rights reserved.
7+
*
8+
* This software component is licensed by ST under BSD 3-Clause license,
9+
* the "License"; You may not use this file except in compliance with the
10+
* License. You may obtain a copy of the License at:
11+
* opensource.org/licenses/BSD-3-Clause
12+
*
13+
******************************************************************************
14+
*/
15+
16+
#include "mbed_assert.h"
17+
#include "mbed_error.h"
18+
#include "spi_api.h"
19+
20+
#if DEVICE_SPI
21+
22+
#include "cmsis.h"
23+
#include "pinmap.h"
24+
#include "PeripheralPins.h"
25+
#include "mbed_error.h"
26+
#include "spi_device.h"
27+
28+
#if DEVICE_SPI_ASYNCH
29+
#define SPI_S(obj) (( struct spi_s *)(&(obj->spi)))
30+
#else
31+
#define SPI_S(obj) (( struct spi_s *)(obj))
32+
#endif
33+
34+
/*
35+
* Only the frequency is managed in the family specific part
36+
* the rest of SPI management is common to all STM32 families
37+
*/
38+
int spi_get_clock_freq(spi_t *obj)
39+
{
40+
struct spi_s *spiobj = SPI_S(obj);
41+
int spi_hz = 0;
42+
43+
/* Get source clock depending on SPI instance */
44+
switch ((int)spiobj->spi) {
45+
case SPI_1:
46+
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI1_CLKSOURCE);
47+
break;
48+
case SPI_2:
49+
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI2_CLKSOURCE);
50+
break;
51+
case SPI_3:
52+
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI3_CLKSOURCE);
53+
break;
54+
#if defined(SPI4)
55+
case SPI_4:
56+
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI4_CLKSOURCE);
57+
break;
58+
#endif
59+
#if defined(SPI5)
60+
case SPI_5:
61+
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI5_CLKSOURCE);
62+
break;
63+
#endif
64+
#if defined(SPI6)
65+
case SPI_6:
66+
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI6_CLKSOURCE);
67+
break;
68+
#endif
69+
default:
70+
error("CLK: SPI instance not set");
71+
break;
72+
}
73+
if (spi_hz == LL_RCC_PERIPH_FREQUENCY_NO) {
74+
error("spi_hz not found\n");
75+
}
76+
return spi_hz;
77+
}
78+
79+
#endif
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* mbed Microcontroller Library
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
******************************************************************************
4+
*
5+
* Copyright (c) 2015-2024 STMicroelectronics.
6+
* All rights reserved.
7+
*
8+
* This software component is licensed by ST under BSD 3-Clause license,
9+
* the "License"; You may not use this file except in compliance with the
10+
* License. You may obtain a copy of the License at:
11+
* opensource.org/licenses/BSD-3-Clause
12+
*
13+
******************************************************************************
14+
*/
15+
16+
#ifndef MBED_SPI_DEVICE_H
17+
#define MBED_SPI_DEVICE_H
18+
19+
#include "stm32h5xx_ll_rcc.h"
20+
#include "stm32h5xx_ll_spi.h"
21+
22+
#define SPI_IP_VERSION_V2
23+
24+
// Defines the word legnth capability of the device where Nth bit allows for N window size
25+
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0xFFFFFFF8)
26+
27+
// We have DMA support
28+
#define STM32_SPI_CAPABILITY_DMA 1
29+
30+
#endif
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2016-2024 STMicroelectronics
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef MBED_OS_STM_DMA_INFO_H
19+
#define MBED_OS_STM_DMA_INFO_H
20+
21+
#include "cmsis.h"
22+
#include "stm_dma_utils.h"
23+
24+
// STM32h5 devices.
25+
// On this device, the DMA channels may be chosen arbitrarily.
26+
27+
/// Mapping from SPI index to DMA link info for Tx
28+
static const DMALinkInfo SPITxDMALinks[] = {
29+
{1, 0, GPDMA1_REQUEST_SPI1_TX},
30+
{1, 2, GPDMA1_REQUEST_SPI2_TX},
31+
{1, 4, GPDMA1_REQUEST_SPI3_TX}
32+
#if defined (SPI4)
33+
,{1, 6, GPDMA1_REQUEST_SPI4_TX}
34+
#endif
35+
#if defined (SPI5)
36+
,{2, 0, GPDMA1_REQUEST_SPI5_TX}
37+
#endif
38+
#if defined (SPI6)
39+
,{2, 2, GPDMA1_REQUEST_SPI6_TX}
40+
#endif
41+
};
42+
43+
/// Mapping from SPI index to DMA link info for Rx
44+
static const DMALinkInfo SPIRxDMALinks[] = {
45+
{1, 1, GPDMA1_REQUEST_SPI1_RX},
46+
{1, 3, GPDMA1_REQUEST_SPI2_RX},
47+
{1, 5, GPDMA1_REQUEST_SPI3_TX}
48+
#if defined (SPI4)
49+
,{1, 7, GPDMA1_REQUEST_SPI4_RX}
50+
#endif
51+
#if defined (SPI5)
52+
,{2, 1, GPDMA1_REQUEST_SPI5_RX}
53+
#endif
54+
#if defined (SPI6)
55+
,{2, 3, GPDMA1_REQUEST_SPI6_RX}
56+
#endif
57+
};
58+
59+
60+
61+
#endif //MBED_OS_STM_DMA_INFO_H

targets/TARGET_STM/stm_spi_api.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
#define TIMEOUT_1_BYTE 10
7777

7878
#if defined(SPI_FLAG_FRLVL) // STM32F0 STM32F3 STM32F7 STM32L4
79-
#if defined(STM32U5)
79+
#if defined(STM32U5) || defined(STM32H5)
8080
extern HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi);
8181
#else
8282
extern HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(SPI_HandleTypeDef *hspi);
@@ -291,8 +291,10 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
291291
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
292292
#if defined (RCC_SPI123CLKSOURCE_PLL)
293293
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
294+
#elif defined (RCC_SPI1CLKSOURCE_SYSCLK)
295+
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK;
294296
#else
295-
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK;
297+
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_PLL1Q;
296298
#endif
297299
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
298300
error("HAL_RCCEx_PeriphCLKConfig\n");
@@ -314,8 +316,10 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
314316
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
315317
#if defined (RCC_SPI123CLKSOURCE_PLL)
316318
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
317-
#else
319+
#elif defined (RCC_SPI2CLKSOURCE_SYSCLK)
318320
PeriphClkInit.Spi2ClockSelection = RCC_SPI2CLKSOURCE_SYSCLK;
321+
#else
322+
PeriphClkInit.Spi2ClockSelection = RCC_SPI2CLKSOURCE_PLL1Q;
319323
#endif
320324
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
321325
error("HAL_RCCEx_PeriphCLKConfig\n");
@@ -337,8 +341,10 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
337341
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
338342
#if defined (RCC_SPI123CLKSOURCE_PLL)
339343
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
340-
#else
344+
#elif defined (RCC_SPI2CLKSOURCE_SYSCLK)
341345
PeriphClkInit.Spi3ClockSelection = RCC_SPI3CLKSOURCE_SYSCLK;
346+
#else
347+
PeriphClkInit.Spi3ClockSelection = RCC_SPI3CLKSOURCE_PLL1Q;
342348
#endif
343349
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
344350
error("HAL_RCCEx_PeriphCLKConfig\n");
@@ -358,7 +364,11 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
358364
if (spiobj->spi == SPI_4) {
359365
#if defined(SPI_IP_VERSION_V2)
360366
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI4;
367+
#if defined RCC_SPI45CLKSOURCE_PCLK1
361368
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
369+
#else
370+
PeriphClkInit.Spi4ClockSelection = RCC_SPI4CLKSOURCE_PCLK2;
371+
#endif
362372
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
363373
error("HAL_RCCEx_PeriphCLKConfig\n");
364374
}
@@ -377,7 +387,11 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
377387
if (spiobj->spi == SPI_5) {
378388
#if defined(SPI_IP_VERSION_V2)
379389
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI5;
390+
#if defined RCC_SPI45CLKSOURCE_PCLK1
380391
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
392+
#else
393+
PeriphClkInit.Spi5ClockSelection = RCC_SPI5CLKSOURCE_PCLK3;
394+
#endif
381395
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
382396
error("HAL_RCCEx_PeriphCLKConfig\n");
383397
}
@@ -396,7 +410,11 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
396410
if (spiobj->spi == SPI_6) {
397411
#if defined(SPI_IP_VERSION_V2)
398412
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
413+
#if defined RCC_SPI6CLKSOURCE_PCLK4
399414
PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PCLK4;
415+
#else
416+
PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PCLK2;
417+
#endif
400418
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
401419
error("HAL_RCCEx_PeriphCLKConfig\n");
402420
}
@@ -508,7 +526,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
508526
SPI_INIT_DIRECT(obj, &explicit_spi_pinmap);
509527
}
510528

511-
#ifdef STM32_SPI_CAPABILITY_DMA
529+
#if STM32_SPI_CAPABILITY_DMA
512530

513531
/**
514532
* Initialize the DMA for an SPI object in the Tx direction.

targets/targets.json5

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3093,16 +3093,14 @@
30933093
],
30943094
"device_has_add": [
30953095
"MPU",
3096-
"ANALOGOUT"
3096+
"ANALOGOUT",
3097+
"SPI_32BIT_WORDS"
30973098
],
30983099
"device_has_remove": [
30993100
"FLASH",
31003101
"LPTICKER",
31013102
"CAN",
31023103
"SERIAL_FC",
3103-
"SPI",
3104-
"SPISLAVE",
3105-
"SPI_ASYNCH",
31063104
"WATCHDOG",
31073105
"ETHERNET",
31083106
"EMAC"

0 commit comments

Comments
 (0)