mirror of https://github.com/ARMmbed/mbed-os.git
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 <odiin@windowslive.com>pull/15530/head
parent
d1dbb405c8
commit
fa86c2b73c
|
|
@ -15,6 +15,7 @@ target_sources(mbed-stm32h5
|
|||
gpio_irq_device.c
|
||||
i2c_device.c
|
||||
serial_device.c
|
||||
spi_api.c
|
||||
pwmout_device.c
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -541,4 +541,4 @@ g_pfnVectors:
|
|||
.thumb_set I3C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak COMP1_IRQHandler
|
||||
.thumb_set COMP1_IRQHandler,Default_Handler
|
||||
.thumb_set COMP1_IRQHandler,Default_Handler
|
||||
|
|
@ -688,4 +688,4 @@ g_pfnVectors:
|
|||
.thumb_set LPTIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM6_IRQHandler
|
||||
.thumb_set LPTIM6_IRQHandler,Default_Handler
|
||||
.thumb_set LPTIM6_IRQHandler,Default_Handler
|
||||
|
|
@ -123,7 +123,10 @@ else // Divisible by 5MHz
|
|||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
|
||||
|
||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||
RCC_OscInitStruct.PLL.PLLQ = 2;
|
||||
// Most of the SPI busses are clocked off of PLL1Q, and the max usable frequency for SPI is about
|
||||
// ~50MHz. Plus, SPI has only limited, power-of-2 prescaler options so a high input clock really hurts
|
||||
// its clock resolution. So, give it a much lower input clock.
|
||||
RCC_OscInitStruct.PLL.PLLQ = 10; // output freq = 50MHz
|
||||
RCC_OscInitStruct.PLL.PLLR = 2;
|
||||
RCC_OscInitStruct.PLL.PLLFRACN = 0;
|
||||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
|
||||
|
|
@ -189,7 +192,10 @@ uint8_t SetSysClock_PLL_HSI(void)
|
|||
RCC_OscInitStruct.PLL.PLLM = 4;
|
||||
RCC_OscInitStruct.PLL.PLLN = 31;
|
||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||
RCC_OscInitStruct.PLL.PLLQ = 2;
|
||||
// Most of the SPI busses are clocked off of PLL1Q, and the max usable frequency for SPI is about
|
||||
// ~50MHz. Plus, SPI has only limited, power-of-2 prescaler options so a high input clock really hurts
|
||||
// its clock resolution. So, give it a much lower input clock.
|
||||
RCC_OscInitStruct.PLL.PLLQ = 10; // output freq = 50MHz
|
||||
RCC_OscInitStruct.PLL.PLLR = 2;
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_3;
|
||||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
|
||||
|
|
|
|||
|
|
@ -51,20 +51,6 @@ struct trng_s {
|
|||
RNG_HandleTypeDef handle;
|
||||
};
|
||||
|
||||
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 {
|
||||
UARTName uart;
|
||||
int index; // Used by irq
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/* mbed Microcontroller Library
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2015-2024 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "mbed_assert.h"
|
||||
#include "mbed_error.h"
|
||||
#include "spi_api.h"
|
||||
|
||||
#if DEVICE_SPI
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "PeripheralPins.h"
|
||||
#include "mbed_error.h"
|
||||
#include "spi_device.h"
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
#define SPI_S(obj) (( struct spi_s *)(&(obj->spi)))
|
||||
#else
|
||||
#define SPI_S(obj) (( struct spi_s *)(obj))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only the frequency is managed in the family specific part
|
||||
* the rest of SPI management is common to all STM32 families
|
||||
*/
|
||||
int spi_get_clock_freq(spi_t *obj)
|
||||
{
|
||||
struct spi_s *spiobj = SPI_S(obj);
|
||||
int spi_hz = 0;
|
||||
|
||||
/* Get source clock depending on SPI instance */
|
||||
switch ((int)spiobj->spi) {
|
||||
case SPI_1:
|
||||
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI1_CLKSOURCE);
|
||||
break;
|
||||
case SPI_2:
|
||||
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI2_CLKSOURCE);
|
||||
break;
|
||||
case SPI_3:
|
||||
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI3_CLKSOURCE);
|
||||
break;
|
||||
#if defined(SPI4)
|
||||
case SPI_4:
|
||||
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI4_CLKSOURCE);
|
||||
break;
|
||||
#endif
|
||||
#if defined(SPI5)
|
||||
case SPI_5:
|
||||
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI5_CLKSOURCE);
|
||||
break;
|
||||
#endif
|
||||
#if defined(SPI6)
|
||||
case SPI_6:
|
||||
spi_hz = LL_RCC_GetSPIClockFreq(LL_RCC_SPI6_CLKSOURCE);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error("CLK: SPI instance not set");
|
||||
break;
|
||||
}
|
||||
if (spi_hz == LL_RCC_PERIPH_FREQUENCY_NO) {
|
||||
error("spi_hz not found\n");
|
||||
}
|
||||
return spi_hz;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* mbed Microcontroller Library
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2015-2024 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef MBED_SPI_DEVICE_H
|
||||
#define MBED_SPI_DEVICE_H
|
||||
|
||||
#include "stm32h5xx_ll_rcc.h"
|
||||
#include "stm32h5xx_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)
|
||||
|
||||
// We have DMA support
|
||||
#define STM32_SPI_CAPABILITY_DMA 1
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2016-2024 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"
|
||||
|
||||
// STM32h5 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}
|
||||
#if defined (SPI4)
|
||||
,{1, 6, GPDMA1_REQUEST_SPI4_TX}
|
||||
#endif
|
||||
#if defined (SPI5)
|
||||
,{2, 0, GPDMA1_REQUEST_SPI5_TX}
|
||||
#endif
|
||||
#if defined (SPI6)
|
||||
,{2, 2, GPDMA1_REQUEST_SPI6_TX}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// 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}
|
||||
#if defined (SPI4)
|
||||
,{1, 7, GPDMA1_REQUEST_SPI4_RX}
|
||||
#endif
|
||||
#if defined (SPI5)
|
||||
,{2, 1, GPDMA1_REQUEST_SPI5_RX}
|
||||
#endif
|
||||
#if defined (SPI6)
|
||||
,{2, 3, GPDMA1_REQUEST_SPI6_RX}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //MBED_OS_STM_DMA_INFO_H
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
#define TIMEOUT_1_BYTE 10
|
||||
|
||||
#if defined(SPI_FLAG_FRLVL) // STM32F0 STM32F3 STM32F7 STM32L4
|
||||
#if defined(STM32U5)
|
||||
#if defined(STM32U5) || defined(STM32H5)
|
||||
extern HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi);
|
||||
#else
|
||||
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)
|
|||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
|
||||
#if defined (RCC_SPI123CLKSOURCE_PLL)
|
||||
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
|
||||
#elif defined (RCC_SPI1CLKSOURCE_SYSCLK)
|
||||
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK;
|
||||
#else
|
||||
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK;
|
||||
PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_PLL1Q;
|
||||
#endif
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||
|
|
@ -314,8 +316,10 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
|
||||
#if defined (RCC_SPI123CLKSOURCE_PLL)
|
||||
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
|
||||
#else
|
||||
#elif defined (RCC_SPI2CLKSOURCE_SYSCLK)
|
||||
PeriphClkInit.Spi2ClockSelection = RCC_SPI2CLKSOURCE_SYSCLK;
|
||||
#else
|
||||
PeriphClkInit.Spi2ClockSelection = RCC_SPI2CLKSOURCE_PLL1Q;
|
||||
#endif
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||
|
|
@ -337,8 +341,10 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
|
||||
#if defined (RCC_SPI123CLKSOURCE_PLL)
|
||||
PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
|
||||
#else
|
||||
#elif defined (RCC_SPI2CLKSOURCE_SYSCLK)
|
||||
PeriphClkInit.Spi3ClockSelection = RCC_SPI3CLKSOURCE_SYSCLK;
|
||||
#else
|
||||
PeriphClkInit.Spi3ClockSelection = RCC_SPI3CLKSOURCE_PLL1Q;
|
||||
#endif
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||
|
|
@ -358,7 +364,11 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
if (spiobj->spi == SPI_4) {
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI4;
|
||||
#if defined RCC_SPI45CLKSOURCE_PCLK1
|
||||
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
|
||||
#else
|
||||
PeriphClkInit.Spi4ClockSelection = RCC_SPI4CLKSOURCE_PCLK2;
|
||||
#endif
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||
}
|
||||
|
|
@ -377,7 +387,11 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
if (spiobj->spi == SPI_5) {
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI5;
|
||||
#if defined RCC_SPI45CLKSOURCE_PCLK1
|
||||
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK1;
|
||||
#else
|
||||
PeriphClkInit.Spi5ClockSelection = RCC_SPI5CLKSOURCE_PCLK3;
|
||||
#endif
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||
}
|
||||
|
|
@ -396,7 +410,11 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
if (spiobj->spi == SPI_6) {
|
||||
#if defined(SPI_IP_VERSION_V2)
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
|
||||
#if defined RCC_SPI6CLKSOURCE_PCLK4
|
||||
PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PCLK4;
|
||||
#else
|
||||
PeriphClkInit.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PCLK2;
|
||||
#endif
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||
}
|
||||
|
|
@ -508,7 +526,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
SPI_INIT_DIRECT(obj, &explicit_spi_pinmap);
|
||||
}
|
||||
|
||||
#ifdef STM32_SPI_CAPABILITY_DMA
|
||||
#if STM32_SPI_CAPABILITY_DMA
|
||||
|
||||
/**
|
||||
* Initialize the DMA for an SPI object in the Tx direction.
|
||||
|
|
|
|||
|
|
@ -3093,16 +3093,14 @@
|
|||
],
|
||||
"device_has_add": [
|
||||
"MPU",
|
||||
"ANALOGOUT"
|
||||
"ANALOGOUT",
|
||||
"SPI_32BIT_WORDS"
|
||||
],
|
||||
"device_has_remove": [
|
||||
"FLASH",
|
||||
"LPTICKER",
|
||||
"CAN",
|
||||
"SERIAL_FC",
|
||||
"SPI",
|
||||
"SPISLAVE",
|
||||
"SPI_ASYNCH",
|
||||
"WATCHDOG",
|
||||
"ETHERNET",
|
||||
"EMAC"
|
||||
|
|
|
|||
Loading…
Reference in New Issue