mirror of https://github.com/ARMmbed/mbed-os.git
STM32U5 specific driver files
parent
e2ca71d1bf
commit
f45b1890aa
|
@ -4,6 +4,7 @@
|
||||||
add_subdirectory(TARGET_STM32U575xG EXCLUDE_FROM_ALL)
|
add_subdirectory(TARGET_STM32U575xG EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(TARGET_STM32U575xI EXCLUDE_FROM_ALL)
|
add_subdirectory(TARGET_STM32U575xI EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(TARGET_STM32U585xI EXCLUDE_FROM_ALL)
|
add_subdirectory(TARGET_STM32U585xI EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
add_subdirectory(STM32Cube_FW EXCLUDE_FROM_ALL)
|
add_subdirectory(STM32Cube_FW EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
add_library(mbed-stm32u5 INTERFACE)
|
add_library(mbed-stm32u5 INTERFACE)
|
||||||
|
@ -15,6 +16,14 @@ target_include_directories(mbed-stm32u5
|
||||||
|
|
||||||
target_sources(mbed-stm32u5
|
target_sources(mbed-stm32u5
|
||||||
INTERFACE
|
INTERFACE
|
||||||
|
analogin_device.c
|
||||||
|
analogout_device.c
|
||||||
|
flash_api.c
|
||||||
|
gpio_irq_device.c
|
||||||
|
pwmout_device.c
|
||||||
|
i2c_device.c
|
||||||
|
serial_device.c
|
||||||
|
spi_api.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(mbed-stm32u5 INTERFACE mbed-stm mbed-stm32u5cube-fw)
|
target_link_libraries(mbed-stm32u5 INTERFACE mbed-stm mbed-stm32u5cube-fw)
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_PERIPHERALNAMES_H
|
||||||
|
#define MBED_PERIPHERALNAMES_H
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ADC_1 = (int)ADC1_BASE,
|
||||||
|
ADC_4 = (int)ADC4_BASE
|
||||||
|
} ADCName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DAC_1 = (int)DAC1_BASE
|
||||||
|
} DACName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_1 = (int)USART1_BASE,
|
||||||
|
UART_2 = (int)USART2_BASE,
|
||||||
|
UART_3 = (int)USART3_BASE,
|
||||||
|
UART_4 = (int)UART4_BASE,
|
||||||
|
UART_5 = (int)UART5_BASE,
|
||||||
|
LPUART_1 = (int)LPUART1_BASE
|
||||||
|
} UARTName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SPI_1 = (int)SPI1_BASE,
|
||||||
|
SPI_2 = (int)SPI2_BASE,
|
||||||
|
SPI_3 = (int)SPI3_BASE
|
||||||
|
} SPIName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
I2C_1 = (int)I2C1_BASE,
|
||||||
|
I2C_2 = (int)I2C2_BASE,
|
||||||
|
I2C_3 = (int)I2C3_BASE,
|
||||||
|
I2C_4 = (int)I2C4_BASE
|
||||||
|
} I2CName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PWM_1 = (int)TIM1_BASE,
|
||||||
|
PWM_2 = (int)TIM2_BASE,
|
||||||
|
PWM_3 = (int)TIM3_BASE,
|
||||||
|
PWM_4 = (int)TIM4_BASE,
|
||||||
|
PWM_5 = (int)TIM5_BASE,
|
||||||
|
PWM_8 = (int)TIM8_BASE,
|
||||||
|
PWM_15 = (int)TIM15_BASE,
|
||||||
|
PWM_16 = (int)TIM16_BASE,
|
||||||
|
PWM_17 = (int)TIM17_BASE
|
||||||
|
} PWMName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CAN_1 = (int)FDCAN1_BASE
|
||||||
|
} CANName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QSPI_1 = (int)OCTOSPI1_R_BASE,
|
||||||
|
QSPI_2 = (int)OCTOSPI2_R_BASE
|
||||||
|
} QSPIName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OSPI_1 = (int)OCTOSPI1_R_BASE,
|
||||||
|
OSPI_2 = (int)OCTOSPI2_R_BASE
|
||||||
|
} OSPIName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USB_FS = (int)USB_OTG_FS_BASE
|
||||||
|
} USBName;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,244 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "analogin_api.h"
|
||||||
|
|
||||||
|
#if DEVICE_ANALOGIN
|
||||||
|
|
||||||
|
#include "mbed_wait_api.h"
|
||||||
|
#include "cmsis.h"
|
||||||
|
#include "pinmap.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
#include "PeripheralPins.h"
|
||||||
|
|
||||||
|
#if STATIC_PINMAP_READY
|
||||||
|
#define ANALOGIN_INIT_DIRECT analogin_init_direct
|
||||||
|
void analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
|
||||||
|
#else
|
||||||
|
#define ANALOGIN_INIT_DIRECT _analogin_init_direct
|
||||||
|
static void _analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
uint32_t function = (uint32_t)pinmap->function;
|
||||||
|
|
||||||
|
// Get the peripheral name from the pin and assign it to the object
|
||||||
|
obj->handle.Instance = (ADC_TypeDef *)pinmap->peripheral;
|
||||||
|
|
||||||
|
// ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...)
|
||||||
|
// are described in PinNames.h and PeripheralPins.c
|
||||||
|
// Pin value must be between 0xF0 and 0xFF
|
||||||
|
if ((pinmap->pin < 0xF0) || (pinmap->pin >= 0x100)) {
|
||||||
|
// Configure GPIO
|
||||||
|
pin_function(pinmap->pin, pinmap->function);
|
||||||
|
pin_mode(pinmap->pin, PullNone);
|
||||||
|
} else {
|
||||||
|
// Internal channels
|
||||||
|
// No GPIO configuration for internal channels
|
||||||
|
}
|
||||||
|
MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC);
|
||||||
|
MBED_ASSERT(function != (uint32_t)NC);
|
||||||
|
|
||||||
|
obj->channel = STM_PIN_CHANNEL(function);
|
||||||
|
|
||||||
|
// Save pin number for the read function
|
||||||
|
obj->pin = pinmap->pin;
|
||||||
|
|
||||||
|
if (obj->handle.Instance == ADC1) {
|
||||||
|
__HAL_RCC_ADC1_CLK_ENABLE();
|
||||||
|
} else if (obj->handle.Instance == ADC4) {
|
||||||
|
__HAL_RCC_ADC4_CLK_ENABLE();
|
||||||
|
} else {
|
||||||
|
error("ADC instance error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||||
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADCDAC;
|
||||||
|
PeriphClkInit.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HSI;
|
||||||
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
|
||||||
|
error("HAL_RCCEx_PeriphCLKConfig\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure ADC object structures
|
||||||
|
obj->handle.State = HAL_ADC_STATE_RESET;
|
||||||
|
obj->handle.DMA_Handle = NULL;
|
||||||
|
obj->handle.Lock = HAL_UNLOCKED;
|
||||||
|
|
||||||
|
obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
|
||||||
|
obj->handle.Init.Resolution = ADC_RESOLUTION_12B;
|
||||||
|
obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||||
|
obj->handle.Init.ScanConvMode = ADC_SCAN_DISABLE;
|
||||||
|
obj->handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||||
|
obj->handle.Init.LowPowerAutoWait = DISABLE;
|
||||||
|
obj->handle.Init.LowPowerAutoPowerOff = ADC_LOW_POWER_NONE;
|
||||||
|
obj->handle.Init.ContinuousConvMode = DISABLE;
|
||||||
|
obj->handle.Init.NbrOfConversion = 1;
|
||||||
|
obj->handle.Init.DiscontinuousConvMode = DISABLE;
|
||||||
|
obj->handle.Init.DMAContinuousRequests = DISABLE;
|
||||||
|
obj->handle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
|
||||||
|
obj->handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
|
||||||
|
obj->handle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
|
||||||
|
obj->handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
|
||||||
|
obj->handle.Init.OversamplingMode = DISABLE;
|
||||||
|
obj->handle.Init.GainCompensation = 0;
|
||||||
|
obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||||
|
obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
||||||
|
obj->handle.Init.VrefProtection = ADC_VREF_PPROT_NONE;
|
||||||
|
|
||||||
|
if (HAL_ADC_Init(&obj->handle) != HAL_OK) {
|
||||||
|
error("Cannot initialize ADC\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ADCEx_Calibration_Start(&obj->handle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK) {
|
||||||
|
error("HAL_ADCEx_Calibration_Start\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void analogin_init(analogin_t *obj, PinName pin)
|
||||||
|
{
|
||||||
|
int peripheral;
|
||||||
|
int function;
|
||||||
|
|
||||||
|
if ((pin < 0xF0) || (pin >= 0x100)) {
|
||||||
|
peripheral = (int)pinmap_peripheral(pin, PinMap_ADC);
|
||||||
|
function = (int)pinmap_find_function(pin, PinMap_ADC);
|
||||||
|
} else {
|
||||||
|
peripheral = (int)pinmap_peripheral(pin, PinMap_ADC_Internal);
|
||||||
|
function = (int)pinmap_find_function(pin, PinMap_ADC_Internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PinMap static_pinmap = {pin, peripheral, function};
|
||||||
|
|
||||||
|
ANALOGIN_INIT_DIRECT(obj, &static_pinmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t adc_read(analogin_t *obj)
|
||||||
|
{
|
||||||
|
ADC_ChannelConfTypeDef sConfig = {0};
|
||||||
|
|
||||||
|
// Configure ADC channel
|
||||||
|
if (obj->handle.Instance == ADC1) {
|
||||||
|
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||||
|
sConfig.SamplingTime = ADC_SAMPLETIME_36CYCLES;
|
||||||
|
} else if (obj->handle.Instance == ADC4) {
|
||||||
|
sConfig.Rank = ADC4_REGULAR_RANK_1;
|
||||||
|
sConfig.SamplingTime = ADC4_SAMPLETIME_12CYCLES_5;
|
||||||
|
}
|
||||||
|
sConfig.SingleDiff = ADC_SINGLE_ENDED;
|
||||||
|
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
||||||
|
sConfig.Offset = 0;
|
||||||
|
sConfig.OffsetRightShift = DISABLE;
|
||||||
|
sConfig.OffsetSignedSaturation = DISABLE;
|
||||||
|
|
||||||
|
switch (obj->channel) {
|
||||||
|
case 0:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_VREFINT;
|
||||||
|
sConfig.SamplingTime = ADC_SAMPLETIME_391CYCLES_5;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_4;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_5;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_6;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_8;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_9;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_10;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_11;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_12;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_13;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_14;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_15;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_16;
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_17;
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_VBAT;
|
||||||
|
sConfig.SamplingTime = ADC_SAMPLETIME_814CYCLES;
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
|
||||||
|
sConfig.SamplingTime = ADC_SAMPLETIME_391CYCLES_5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("ADC channel not expected\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ADC_ConfigChannel(&obj->handle, &sConfig) != HAL_OK) {
|
||||||
|
error("HAL_ADC_ConfigChannel\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ADC_Start(&obj->handle) != HAL_OK) {
|
||||||
|
error("HAL_ADC_Start\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait end of conversion and get value
|
||||||
|
uint16_t adcValue = 0;
|
||||||
|
if (HAL_ADC_PollForConversion(&obj->handle, 10) != HAL_OK) {
|
||||||
|
error("HAL_ADC_PollForConversion error 0x%x\n", obj->handle.State);
|
||||||
|
} else {
|
||||||
|
adcValue = (uint16_t)HAL_ADC_GetValue(&obj->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ADC_Stop(&obj->handle) != HAL_OK) {
|
||||||
|
error("HAL_ADC_Stop\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE((&obj->handle)->Instance), LL_ADC_PATH_INTERNAL_NONE);
|
||||||
|
|
||||||
|
return adcValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PinMap *analogin_pinmap()
|
||||||
|
{
|
||||||
|
return PinMap_ADC;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,146 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "analogout_api.h"
|
||||||
|
|
||||||
|
#if DEVICE_ANALOGOUT
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
#include "pinmap.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
#include "PeripheralPins.h"
|
||||||
|
|
||||||
|
// These variables are used for the "free" function
|
||||||
|
static int channel1_used = 0;
|
||||||
|
#if defined(DAC_CHANNEL_2)
|
||||||
|
static int channel2_used = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STATIC_PINMAP_READY
|
||||||
|
#define ANALOGOUT_INIT_DIRECT analogout_init_direct
|
||||||
|
void analogout_init_direct(dac_t *obj, const PinMap *pinmap)
|
||||||
|
#else
|
||||||
|
#define ANALOGOUT_INIT_DIRECT _analogout_init_direct
|
||||||
|
static void _analogout_init_direct(dac_t *obj, const PinMap *pinmap)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
DAC_ChannelConfTypeDef sConfig = {0};
|
||||||
|
|
||||||
|
// Get the peripheral name from the pin and assign it to the object
|
||||||
|
obj->dac = (DACName)pinmap->peripheral;
|
||||||
|
MBED_ASSERT(obj->dac != (DACName)NC);
|
||||||
|
|
||||||
|
// Get the pin function and assign the used channel to the object
|
||||||
|
uint32_t function = (uint32_t)pinmap->function;
|
||||||
|
MBED_ASSERT(function != (uint32_t)NC);
|
||||||
|
|
||||||
|
switch (STM_PIN_CHANNEL(function)) {
|
||||||
|
case 1:
|
||||||
|
obj->channel = DAC_CHANNEL_1;
|
||||||
|
break;
|
||||||
|
#if defined(DAC_CHANNEL_2)
|
||||||
|
case 2:
|
||||||
|
obj->channel = DAC_CHANNEL_2;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
error("Unknown DAC channel");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure GPIO
|
||||||
|
pin_function(pinmap->pin, pinmap->function);
|
||||||
|
pin_mode(pinmap->pin, PullNone);
|
||||||
|
|
||||||
|
// Save the pin for future use
|
||||||
|
obj->pin = pinmap->pin;
|
||||||
|
|
||||||
|
// Enable DAC clock
|
||||||
|
__HAL_RCC_DAC1_CLK_ENABLE();
|
||||||
|
|
||||||
|
// Configure DAC
|
||||||
|
obj->handle.Instance = (DAC_TypeDef *)DAC_1;
|
||||||
|
obj->handle.State = HAL_DAC_STATE_RESET;
|
||||||
|
|
||||||
|
if (HAL_DAC_Init(&obj->handle) != HAL_OK) {
|
||||||
|
error("HAL_DAC_Init failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
|
||||||
|
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
|
||||||
|
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
|
||||||
|
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
|
||||||
|
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
|
||||||
|
|
||||||
|
if (obj->channel == DAC_CHANNEL_1) {
|
||||||
|
channel1_used = 1;
|
||||||
|
}
|
||||||
|
#if defined(DAC_CHANNEL_2)
|
||||||
|
if (obj->channel == DAC_CHANNEL_2) {
|
||||||
|
channel2_used = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
|
||||||
|
error("Cannot configure DAC channel\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
analogout_write_u16(obj, 0);
|
||||||
|
HAL_DAC_Start(&obj->handle, obj->channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void analogout_init(dac_t *obj, PinName pin)
|
||||||
|
{
|
||||||
|
int peripheral = (int)pinmap_peripheral(pin, PinMap_DAC);
|
||||||
|
int function = (int)pinmap_find_function(pin, PinMap_DAC);
|
||||||
|
|
||||||
|
const PinMap static_pinmap = {pin, peripheral, function};
|
||||||
|
|
||||||
|
ANALOGOUT_INIT_DIRECT(obj, &static_pinmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void analogout_free(dac_t *obj)
|
||||||
|
{
|
||||||
|
// Reset DAC and disable clock
|
||||||
|
if (obj->channel == DAC_CHANNEL_1) {
|
||||||
|
channel1_used = 0;
|
||||||
|
}
|
||||||
|
#if defined(DAC_CHANNEL_2)
|
||||||
|
if (obj->channel == DAC_CHANNEL_2) {
|
||||||
|
channel2_used = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((channel1_used == 0)
|
||||||
|
#if defined(DAC_CHANNEL_2)
|
||||||
|
&& (channel2_used == 0)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
__HAL_RCC_DAC1_FORCE_RESET();
|
||||||
|
__HAL_RCC_DAC1_RELEASE_RESET();
|
||||||
|
__HAL_RCC_DAC1_CLK_DISABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure GPIO back to reset value
|
||||||
|
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
const PinMap *analogout_pinmap()
|
||||||
|
{
|
||||||
|
return PinMap_DAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEVICE_ANALOGOUT
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_CAN_DEVICE_H
|
||||||
|
#define MBED_CAN_DEVICE_H
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEVICE_CAN
|
||||||
|
|
||||||
|
#define CAN_NUM 1 // Number of CAN peripherals present in the STM32 serie
|
||||||
|
|
||||||
|
#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn
|
||||||
|
#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler
|
||||||
|
#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn
|
||||||
|
#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler
|
||||||
|
#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn
|
||||||
|
#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler
|
||||||
|
#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn
|
||||||
|
#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler
|
||||||
|
#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn
|
||||||
|
#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler
|
||||||
|
|
||||||
|
#endif // DEVICE_CAN
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_CMSIS_H
|
||||||
|
#define MBED_CMSIS_H
|
||||||
|
|
||||||
|
#include "stm32u5xx.h"
|
||||||
|
#include "cmsis_nvic.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,254 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "flash_api.h"
|
||||||
|
#include "platform/mbed_critical.h"
|
||||||
|
|
||||||
|
#if DEVICE_FLASH
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the page of a given address
|
||||||
|
* @param Addr: Address of the FLASH Memory
|
||||||
|
* @retval The page of a given address
|
||||||
|
*/
|
||||||
|
static uint32_t GetPage(uint32_t Addr)
|
||||||
|
{
|
||||||
|
uint32_t page = 0;
|
||||||
|
|
||||||
|
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
|
||||||
|
/* Bank 1 */
|
||||||
|
page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
|
||||||
|
} else {
|
||||||
|
/* Bank 2 */
|
||||||
|
page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address
|
||||||
|
* @param Addr: Address of the FLASH Memory
|
||||||
|
* @retval The bank of a given address
|
||||||
|
*/
|
||||||
|
static uint32_t GetBank(uint32_t Addr)
|
||||||
|
{
|
||||||
|
uint32_t bank = 0;
|
||||||
|
|
||||||
|
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
|
||||||
|
bank = FLASH_BANK_1;
|
||||||
|
} else {
|
||||||
|
bank = FLASH_BANK_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initialize the flash peripheral and the flash_t object
|
||||||
|
*
|
||||||
|
* @param obj The flash object
|
||||||
|
* @return 0 for success, -1 for error
|
||||||
|
*/
|
||||||
|
int32_t flash_init(flash_t *obj)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Uninitialize the flash peripheral and the flash_t object
|
||||||
|
*
|
||||||
|
* @param obj The flash object
|
||||||
|
* @return 0 for success, -1 for error
|
||||||
|
*/
|
||||||
|
int32_t flash_free(flash_t *obj)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Erase one sector starting at defined address
|
||||||
|
*
|
||||||
|
* The address should be at sector boundary. This function does not do any check for address alignments
|
||||||
|
* @param obj The flash object
|
||||||
|
* @param address The sector starting address
|
||||||
|
* @return 0 for success, -1 for error
|
||||||
|
*/
|
||||||
|
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
|
{
|
||||||
|
uint32_t FirstPage = 0, BankNumber = 0;
|
||||||
|
uint32_t PAGEError = 0;
|
||||||
|
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||||
|
|
||||||
|
if ((address >= (flash_get_start_address(obj) + flash_get_size(obj))) || (address < flash_get_start_address(obj))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ICACHE_Disable() != HAL_OK)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_FLASH_Unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_util_critical_section_enter();
|
||||||
|
|
||||||
|
/* Clear error programming flags */
|
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
||||||
|
|
||||||
|
/* Get the 1st page to erase */
|
||||||
|
FirstPage = GetPage(address);
|
||||||
|
/* MBED HAL erases 1 page / sector at a time */
|
||||||
|
/* Get the bank */
|
||||||
|
BankNumber = GetBank(address);
|
||||||
|
|
||||||
|
/* Fill EraseInit structure*/
|
||||||
|
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||||
|
EraseInitStruct.Banks = BankNumber;
|
||||||
|
EraseInitStruct.Page = FirstPage;
|
||||||
|
EraseInitStruct.NbPages = 1;
|
||||||
|
|
||||||
|
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_util_critical_section_exit();
|
||||||
|
|
||||||
|
if (HAL_FLASH_Lock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ICACHE_Enable() != HAL_OK)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Program one page starting at defined address
|
||||||
|
*
|
||||||
|
* The page should be at page boundary, should not cross multiple sectors.
|
||||||
|
* This function does not do any check for address alignments or if size
|
||||||
|
* is aligned to a page size.
|
||||||
|
* @param obj The flash object
|
||||||
|
* @param address The sector starting address
|
||||||
|
* @param data The data buffer to be programmed
|
||||||
|
* @param size The number of bytes to program
|
||||||
|
* @return 0 for success, -1 for error
|
||||||
|
*/
|
||||||
|
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
|
const uint8_t *data, uint32_t size)
|
||||||
|
{
|
||||||
|
uint32_t StartAddress = 0;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
|
if ((address >= (flash_get_start_address(obj) + flash_get_size(obj))) || (address < flash_get_start_address(obj))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size % flash_get_page_size(obj)) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ICACHE_Disable() != HAL_OK)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_FLASH_Unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear error programming flags */
|
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
||||||
|
|
||||||
|
/* Program the user Flash area word by word */
|
||||||
|
StartAddress = address;
|
||||||
|
|
||||||
|
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||||
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, address, ((uint32_t) data)) == HAL_OK) {
|
||||||
|
address = address + 16;
|
||||||
|
data = data + 16;
|
||||||
|
} else {
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_FLASH_Unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_ICACHE_Enable() != HAL_OK)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get sector size
|
||||||
|
*
|
||||||
|
* @param obj The flash object
|
||||||
|
* @param address The sector starting address
|
||||||
|
* @return The size of a sector
|
||||||
|
*/
|
||||||
|
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||||
|
{
|
||||||
|
if ((address >= (flash_get_start_address(obj) + flash_get_size(obj))) || (address < flash_get_start_address(obj))) {
|
||||||
|
return MBED_FLASH_INVALID_SIZE;
|
||||||
|
} else {
|
||||||
|
return FLASH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get page size
|
||||||
|
*
|
||||||
|
* @param obj The flash object
|
||||||
|
* @return The size of a page
|
||||||
|
*/
|
||||||
|
uint32_t flash_get_page_size(const flash_t *obj)
|
||||||
|
{
|
||||||
|
/* The Flash memory is programmed 137 bits at a time (128-bit data + 9 bits ECC). */
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get start address for the flash region
|
||||||
|
*
|
||||||
|
* @param obj The flash object
|
||||||
|
* @return The start address for the flash region
|
||||||
|
*/
|
||||||
|
uint32_t flash_get_start_address(const flash_t *obj)
|
||||||
|
{
|
||||||
|
return FLASH_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the flash region size
|
||||||
|
*
|
||||||
|
* @param obj The flash object
|
||||||
|
* @return The flash region size
|
||||||
|
*/
|
||||||
|
uint32_t flash_get_size(const flash_t *obj)
|
||||||
|
{
|
||||||
|
return FLASH_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t flash_get_erase_value(const flash_t *obj)
|
||||||
|
{
|
||||||
|
(void)obj;
|
||||||
|
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "cmsis.h"
|
||||||
|
#include "gpio_irq_device.h"
|
||||||
|
|
||||||
|
// Used to return the index for channels array.
|
||||||
|
const exti_lines_t pin_lines_desc[16] = {
|
||||||
|
// EXTI0
|
||||||
|
{.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0
|
||||||
|
// EXTI1
|
||||||
|
{.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1
|
||||||
|
// EXTI2
|
||||||
|
{.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2
|
||||||
|
// EXTI3
|
||||||
|
{.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3
|
||||||
|
// EXTI4
|
||||||
|
{.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4
|
||||||
|
// EXTI5
|
||||||
|
{.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI5_IRQn}, // pin 5
|
||||||
|
// EXTI6
|
||||||
|
{.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI6_IRQn}, // pin 6
|
||||||
|
// EXTI7
|
||||||
|
{.gpio_idx = 0, .irq_index = 7, .irq_n = EXTI7_IRQn}, // pin 7
|
||||||
|
// EXTI8
|
||||||
|
{.gpio_idx = 0, .irq_index = 8, .irq_n = EXTI8_IRQn}, // pin 8
|
||||||
|
// EXTI9
|
||||||
|
{.gpio_idx = 0, .irq_index = 9, .irq_n = EXTI9_IRQn}, // pin 9
|
||||||
|
// EXTI10
|
||||||
|
{.gpio_idx = 0, .irq_index = 10, .irq_n = EXTI10_IRQn}, // pin 10
|
||||||
|
// EXTI11
|
||||||
|
{.gpio_idx = 0, .irq_index = 11, .irq_n = EXTI11_IRQn}, // pin 11
|
||||||
|
// EXTI12
|
||||||
|
{.gpio_idx = 0, .irq_index = 12, .irq_n = EXTI12_IRQn}, // pin 12
|
||||||
|
// EXTI13
|
||||||
|
{.gpio_idx = 0, .irq_index = 13, .irq_n = EXTI13_IRQn}, // pin 13
|
||||||
|
// EXTI14
|
||||||
|
{.gpio_idx = 0, .irq_index = 14, .irq_n = EXTI14_IRQn}, // pin 14
|
||||||
|
// EXTI15
|
||||||
|
{.gpio_idx = 0, .irq_index = 15, .irq_n = EXTI15_IRQn}, // pin 15
|
||||||
|
};
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_GPIO_IRQ_DEVICE_H
|
||||||
|
#define MBED_GPIO_IRQ_DEVICE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32u5xx_ll_exti.h"
|
||||||
|
|
||||||
|
// Number of EXTI irq vectors (EXTI0 to EXTI15)
|
||||||
|
#define CHANNEL_NUM (16)
|
||||||
|
|
||||||
|
#define EXTI_IRQ0_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ1_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ2_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ3_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ4_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ5_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ6_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ7_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ8_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ9_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ10_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ11_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ12_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ13_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ14_NUM_LINES 1
|
||||||
|
#define EXTI_IRQ15_NUM_LINES 1
|
||||||
|
|
||||||
|
// Max pins for one line
|
||||||
|
#define MAX_PIN_LINE (1)
|
||||||
|
|
||||||
|
/* Structure to describe how the HW EXTI lines are defined in this HW */
|
||||||
|
typedef struct exti_lines {
|
||||||
|
uint32_t gpio_idx; // an index entry for each EXIT line
|
||||||
|
uint32_t irq_index; // the IRQ index
|
||||||
|
IRQn_Type irq_n; // the corresponding EXTI IRQn
|
||||||
|
} exti_lines_t;
|
||||||
|
|
||||||
|
// Used to return the index for channels array.
|
||||||
|
extern const exti_lines_t pin_lines_desc[];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "i2c_device.h"
|
||||||
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
#include "stm32u5xx_ll_rcc.h"
|
||||||
|
|
||||||
|
/* Define I2C Device */
|
||||||
|
#if DEVICE_I2C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2C clock source frequency according I2C instance used.
|
||||||
|
* @param i2c I2C instance name.
|
||||||
|
* @retval I2C clock source frequency in Hz.
|
||||||
|
*/
|
||||||
|
uint32_t i2c_get_pclk(I2CName i2c)
|
||||||
|
{
|
||||||
|
uint32_t clocksource;
|
||||||
|
uint32_t pclk = 0;
|
||||||
|
if (i2c == I2C_1) {
|
||||||
|
clocksource = __HAL_RCC_GET_I2C1_SOURCE();
|
||||||
|
switch (clocksource) {
|
||||||
|
case RCC_I2C1CLKSOURCE_PCLK1:
|
||||||
|
pclk = HAL_RCC_GetPCLK1Freq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C1CLKSOURCE_SYSCLK:
|
||||||
|
pclk = HAL_RCC_GetSysClockFreq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C1CLKSOURCE_HSI:
|
||||||
|
pclk = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if defined I2C2_BASE
|
||||||
|
else if (i2c == I2C_2) {
|
||||||
|
clocksource = __HAL_RCC_GET_I2C2_SOURCE();
|
||||||
|
switch (clocksource) {
|
||||||
|
case RCC_I2C2CLKSOURCE_PCLK1:
|
||||||
|
pclk = HAL_RCC_GetPCLK1Freq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C2CLKSOURCE_SYSCLK:
|
||||||
|
pclk = HAL_RCC_GetSysClockFreq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C2CLKSOURCE_HSI:
|
||||||
|
pclk = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined I2C3_BASE
|
||||||
|
else if (i2c == I2C_3) {
|
||||||
|
clocksource = __HAL_RCC_GET_I2C3_SOURCE();
|
||||||
|
switch (clocksource) {
|
||||||
|
case RCC_I2C3CLKSOURCE_PCLK3:
|
||||||
|
pclk = HAL_RCC_GetPCLK3Freq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C3CLKSOURCE_SYSCLK:
|
||||||
|
pclk = HAL_RCC_GetSysClockFreq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C3CLKSOURCE_HSI:
|
||||||
|
pclk = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined I2C4_BASE
|
||||||
|
else if (i2c == I2C_4) {
|
||||||
|
clocksource = __HAL_RCC_GET_I2C4_SOURCE();
|
||||||
|
switch (clocksource) {
|
||||||
|
case RCC_I2C4CLKSOURCE_PCLK1:
|
||||||
|
pclk = HAL_RCC_GetPCLK1Freq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C4CLKSOURCE_SYSCLK:
|
||||||
|
pclk = HAL_RCC_GetSysClockFreq();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RCC_I2C4CLKSOURCE_HSI:
|
||||||
|
pclk = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
// should not happend
|
||||||
|
error("I2C: unknown instance");
|
||||||
|
}
|
||||||
|
return pclk;
|
||||||
|
}
|
||||||
|
#endif // DEVICE_I2C
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_I2C_DEVICE_H
|
||||||
|
#define MBED_I2C_DEVICE_H
|
||||||
|
|
||||||
|
#include "PeripheralNames.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define I2C Device */
|
||||||
|
#if DEVICE_I2C
|
||||||
|
|
||||||
|
/* Define IP version */
|
||||||
|
#define I2C_IP_VERSION_V2
|
||||||
|
|
||||||
|
// Common settings: I2C clock = 160 MHz, Analog filter = ON, Digital filter coefficient = 0
|
||||||
|
#define TIMING_VAL_160M_CLK_100KHZ 0x90A13E56 // Standard mode with Rise Time = 400ns and Fall Time = 100ns
|
||||||
|
#define TIMING_VAL_160M_CLK_400KHZ 0x30D2153A // Fast mode with Rise Time = 250ns and Fall Time = 100ns
|
||||||
|
#define TIMING_VAL_160M_CLK_1MHZ 0x10830F28 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
|
||||||
|
#define I2C_PCLK_160M 160000000 // 160 MHz
|
||||||
|
|
||||||
|
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
|
||||||
|
|
||||||
|
/* Family specifc settings for clock source */
|
||||||
|
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK
|
||||||
|
#define I2CAPI_I2C2_CLKSRC RCC_I2C2CLKSOURCE_SYSCLK
|
||||||
|
#define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK
|
||||||
|
#define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK
|
||||||
|
|
||||||
|
uint32_t i2c_get_pclk(I2CName i2c);
|
||||||
|
uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, int hz);
|
||||||
|
|
||||||
|
#if MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
|
||||||
|
uint32_t i2c_compute_timing(uint32_t clock_src_freq, uint32_t i2c_freq);
|
||||||
|
void i2c_compute_presc_scldel_sdadel(uint32_t clock_src_freq, uint32_t I2C_speed);
|
||||||
|
uint32_t i2c_compute_scll_sclh(uint32_t clock_src_freq, uint32_t I2C_speed);
|
||||||
|
#endif // MBED_CONF_TARGET_I2C_TIMING_VALUE_ALGO
|
||||||
|
|
||||||
|
#endif // DEVICE_I2C
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,195 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_OBJECTS_H
|
||||||
|
#define MBED_OBJECTS_H
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
#include "PortNames.h"
|
||||||
|
#include "PeripheralNames.h"
|
||||||
|
#include "PinNames.h"
|
||||||
|
#include "stm32u5xx_ll_usart.h"
|
||||||
|
#include "stm32u5xx_ll_lpuart.h"
|
||||||
|
#include "stm32u5xx_ll_tim.h"
|
||||||
|
#include "stm32u5xx_ll_rtc.h"
|
||||||
|
#include "stm32u5xx_ll_pwr.h"
|
||||||
|
#include "stm32u5xx_ll_rcc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RTC_WKUP_IRQn RTC_IRQn
|
||||||
|
|
||||||
|
#define HAL_CRC_IS_SUPPORTED(polynomial, width) ((width) == 7 || (width) == 8 || (width) == 16 || (width) == 32)
|
||||||
|
|
||||||
|
struct gpio_irq_s {
|
||||||
|
IRQn_Type irq_n;
|
||||||
|
uint32_t irq_index;
|
||||||
|
uint32_t event;
|
||||||
|
PinName pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct port_s {
|
||||||
|
PortName port;
|
||||||
|
uint32_t mask;
|
||||||
|
PinDirection direction;
|
||||||
|
__IO uint32_t *reg_in;
|
||||||
|
__IO uint32_t *reg_out;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct trng_s {
|
||||||
|
RNG_HandleTypeDef handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pwmout_s {
|
||||||
|
PWMName pwm;
|
||||||
|
PinName pin;
|
||||||
|
uint32_t prescaler;
|
||||||
|
uint32_t period;
|
||||||
|
uint32_t pulse;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t inverted;
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
uint32_t baudrate;
|
||||||
|
uint32_t databits;
|
||||||
|
uint32_t stopbits;
|
||||||
|
uint32_t parity;
|
||||||
|
PinName pin_tx;
|
||||||
|
PinName pin_rx;
|
||||||
|
#if DEVICE_SERIAL_ASYNCH
|
||||||
|
uint32_t events;
|
||||||
|
#endif
|
||||||
|
#if DEVICE_SERIAL_FC
|
||||||
|
uint32_t hw_flow_ctl;
|
||||||
|
PinName pin_rts;
|
||||||
|
PinName pin_cts;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct i2c_s {
|
||||||
|
/* The 1st 2 members I2CName i2c
|
||||||
|
* and I2C_HandleTypeDef handle should
|
||||||
|
* be kept as the first members of this struct
|
||||||
|
* to ensure i2c_get_obj to work as expected
|
||||||
|
*/
|
||||||
|
I2CName i2c;
|
||||||
|
I2C_HandleTypeDef handle;
|
||||||
|
uint8_t index;
|
||||||
|
int hz;
|
||||||
|
PinName sda;
|
||||||
|
PinName scl;
|
||||||
|
IRQn_Type event_i2cIRQ;
|
||||||
|
IRQn_Type error_i2cIRQ;
|
||||||
|
uint32_t XferOperation;
|
||||||
|
volatile uint8_t event;
|
||||||
|
volatile int pending_start;
|
||||||
|
int current_hz;
|
||||||
|
#if DEVICE_I2CSLAVE
|
||||||
|
uint8_t slave;
|
||||||
|
volatile uint8_t pending_slave_tx_master_rx;
|
||||||
|
volatile uint8_t pending_slave_rx_maxter_tx;
|
||||||
|
uint8_t *slave_rx_buffer;
|
||||||
|
volatile uint8_t slave_rx_buffer_size;
|
||||||
|
volatile uint8_t slave_rx_count;
|
||||||
|
#endif
|
||||||
|
#if DEVICE_I2C_ASYNCH
|
||||||
|
uint32_t address;
|
||||||
|
uint8_t stop;
|
||||||
|
uint8_t available_events;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct flash_s {
|
||||||
|
/* nothing to be stored for now */
|
||||||
|
uint32_t dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct analogin_s {
|
||||||
|
ADC_HandleTypeDef handle;
|
||||||
|
PinName pin;
|
||||||
|
uint8_t channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "gpio_object.h"
|
||||||
|
|
||||||
|
#if DEVICE_ANALOGOUT
|
||||||
|
struct dac_s {
|
||||||
|
DACName dac;
|
||||||
|
PinName pin;
|
||||||
|
uint32_t channel;
|
||||||
|
DAC_HandleTypeDef handle;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEVICE_CAN
|
||||||
|
struct can_s {
|
||||||
|
CAN_HandleTypeDef CanHandle;
|
||||||
|
int index;
|
||||||
|
int hz;
|
||||||
|
int rxIrqEnabled;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct qspi_s {
|
||||||
|
OSPI_HandleTypeDef handle;
|
||||||
|
QSPIName qspi;
|
||||||
|
PinName io0;
|
||||||
|
PinName io1;
|
||||||
|
PinName io2;
|
||||||
|
PinName io3;
|
||||||
|
PinName sclk;
|
||||||
|
PinName ssel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ospi_s {
|
||||||
|
OSPI_HandleTypeDef handle;
|
||||||
|
OSPIName ospi;
|
||||||
|
PinName io0;
|
||||||
|
PinName io1;
|
||||||
|
PinName io2;
|
||||||
|
PinName io3;
|
||||||
|
PinName io4;
|
||||||
|
PinName io5;
|
||||||
|
PinName io6;
|
||||||
|
PinName io7;
|
||||||
|
PinName sclk;
|
||||||
|
PinName ssel;
|
||||||
|
PinName dqs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_PIN_DEVICE_H
|
||||||
|
#define MBED_PIN_DEVICE_H
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
#include "stm32u5xx_ll_gpio.h"
|
||||||
|
|
||||||
|
extern const uint32_t ll_pin_defines[16];
|
||||||
|
|
||||||
|
/* Family specific implementations */
|
||||||
|
static inline void stm_pin_DisconnectDebug(PinName pin)
|
||||||
|
{
|
||||||
|
/* empty for now */
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config)
|
||||||
|
{
|
||||||
|
switch (pull_config) {
|
||||||
|
case GPIO_PULLUP:
|
||||||
|
LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP);
|
||||||
|
break;
|
||||||
|
case GPIO_PULLDOWN:
|
||||||
|
LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stm_pin_SetAFPin(GPIO_TypeDef *gpio, PinName pin, uint32_t afnum)
|
||||||
|
{
|
||||||
|
uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)];
|
||||||
|
|
||||||
|
if (STM_PIN(pin) > 7) {
|
||||||
|
LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum);
|
||||||
|
} else {
|
||||||
|
LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "cmsis.h"
|
||||||
|
#include "pwmout_api.h"
|
||||||
|
#include "pwmout_device.h"
|
||||||
|
|
||||||
|
#if DEVICE_PWMOUT
|
||||||
|
|
||||||
|
const pwm_apb_map_t pwm_apb_map_table[] = {
|
||||||
|
#if defined(TIM2_BASE)
|
||||||
|
{PWM_2, PWMOUT_ON_APB1},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM3_BASE)
|
||||||
|
{PWM_3, PWMOUT_ON_APB1},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM4_BASE)
|
||||||
|
{PWM_4, PWMOUT_ON_APB1},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM5_BASE)
|
||||||
|
{PWM_5, PWMOUT_ON_APB1},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM1_BASE)
|
||||||
|
{PWM_1, PWMOUT_ON_APB2},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM8_BASE)
|
||||||
|
{PWM_8, PWMOUT_ON_APB2},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM15_BASE)
|
||||||
|
{PWM_15, PWMOUT_ON_APB2},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM16_BASE)
|
||||||
|
{PWM_16, PWMOUT_ON_APB2},
|
||||||
|
#endif
|
||||||
|
#if defined(TIM17_BASE)
|
||||||
|
{PWM_17, PWMOUT_ON_APB2},
|
||||||
|
#endif
|
||||||
|
{(PWMName) 0, PWMOUT_UNKNOWN}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEVICE_PWMOUT
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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_PWMOUT_DEVICE_H
|
||||||
|
#define MBED_PWMOUT_DEVICE_H
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEVICE_PWMOUT
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PWMOUT_ON_APB1 = 0,
|
||||||
|
PWMOUT_ON_APB2 = 1,
|
||||||
|
PWMOUT_UNKNOWN = 2
|
||||||
|
} PwmoutApb;
|
||||||
|
|
||||||
|
/* Structure to describe Timers to APB */
|
||||||
|
typedef struct pwm_apb_map {
|
||||||
|
PWMName pwm; // an index entry for each EXIT line
|
||||||
|
PwmoutApb pwmoutApb;
|
||||||
|
} pwm_apb_map_t;
|
||||||
|
|
||||||
|
extern const pwm_apb_map_t pwm_apb_map_table[];
|
||||||
|
|
||||||
|
#endif // DEVICE_PWMOUT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,722 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if DEVICE_SERIAL
|
||||||
|
|
||||||
|
#include "serial_api_hal.h"
|
||||||
|
|
||||||
|
#define UART_NUM (6) // USART1, USART2, USART3, UART4, UART5, LPUART1
|
||||||
|
|
||||||
|
uint32_t serial_irq_ids[UART_NUM] = {0};
|
||||||
|
UART_HandleTypeDef uart_handlers[UART_NUM];
|
||||||
|
|
||||||
|
static uart_irq_handler irq_handler;
|
||||||
|
|
||||||
|
// Defined in serial_api.c
|
||||||
|
extern int8_t get_uart_index(UARTName uart_name);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INTERRUPTS HANDLING
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static void uart_irq(UARTName uart_name)
|
||||||
|
{
|
||||||
|
int8_t id = get_uart_index(uart_name);
|
||||||
|
|
||||||
|
if (id >= 0) {
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[id];
|
||||||
|
if (serial_irq_ids[id] != 0) {
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET && __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE)) {
|
||||||
|
irq_handler(serial_irq_ids[id], TxIrq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET && __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE)) {
|
||||||
|
irq_handler(serial_irq_ids[id], RxIrq);
|
||||||
|
/* Flag has been cleared when reading the content */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) {
|
||||||
|
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(USART1_BASE)
|
||||||
|
static void uart1_irq(void)
|
||||||
|
{
|
||||||
|
uart_irq(UART_1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USART2_BASE)
|
||||||
|
static void uart2_irq(void)
|
||||||
|
{
|
||||||
|
uart_irq(UART_2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USART3_BASE)
|
||||||
|
static void uart3_irq(void)
|
||||||
|
{
|
||||||
|
uart_irq(UART_3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(UART4_BASE)
|
||||||
|
static void uart4_irq(void)
|
||||||
|
{
|
||||||
|
uart_irq(UART_4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(UART5_BASE)
|
||||||
|
static void uart5_irq(void)
|
||||||
|
{
|
||||||
|
uart_irq(UART_5);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LPUART1_BASE)
|
||||||
|
static void lpuart1_irq(void)
|
||||||
|
{
|
||||||
|
uart_irq(LPUART_1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
|
||||||
|
irq_handler = handler;
|
||||||
|
serial_irq_ids[obj_s->index] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
IRQn_Type irq_n = (IRQn_Type)0;
|
||||||
|
uint32_t vector = 0;
|
||||||
|
|
||||||
|
switch (obj_s->uart) {
|
||||||
|
#if defined(USART1_BASE)
|
||||||
|
case UART_1:
|
||||||
|
irq_n = USART1_IRQn;
|
||||||
|
vector = (uint32_t)&uart1_irq;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USART2_BASE)
|
||||||
|
case UART_2:
|
||||||
|
irq_n = USART2_IRQn;
|
||||||
|
vector = (uint32_t)&uart2_irq;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USART3_BASE)
|
||||||
|
case UART_3:
|
||||||
|
irq_n = USART3_IRQn;
|
||||||
|
vector = (uint32_t)&uart3_irq;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(UART4_BASE)
|
||||||
|
case UART_4:
|
||||||
|
irq_n = UART4_IRQn;
|
||||||
|
vector = (uint32_t)&uart4_irq;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(UART5_BASE)
|
||||||
|
case UART_5:
|
||||||
|
irq_n = UART5_IRQn;
|
||||||
|
vector = (uint32_t)&uart5_irq;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(LPUART1_BASE)
|
||||||
|
case LPUART_1:
|
||||||
|
irq_n = LPUART1_IRQn;
|
||||||
|
vector = (uint32_t)&lpuart1_irq;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
if (irq == RxIrq) {
|
||||||
|
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
|
||||||
|
} else { // TxIrq
|
||||||
|
__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
|
||||||
|
}
|
||||||
|
NVIC_SetVector(irq_n, vector);
|
||||||
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
|
} else { // disable
|
||||||
|
int all_disabled = 0;
|
||||||
|
if (irq == RxIrq) {
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
|
||||||
|
// Check if TxIrq is disabled too
|
||||||
|
if (LL_LPUART_IsEnabledIT_TXE(huart->Instance) == 0) {
|
||||||
|
all_disabled = 1;
|
||||||
|
}
|
||||||
|
} else { // TxIrq
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
|
||||||
|
// Check if RxIrq is disabled too
|
||||||
|
if (LL_LPUART_IsEnabledIT_RXNE(huart->Instance) == 0) {
|
||||||
|
all_disabled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_disabled) {
|
||||||
|
NVIC_DisableIRQ(irq_n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* READ/WRITE
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
int serial_getc(serial_t *obj)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
while (!serial_readable(obj));
|
||||||
|
if (obj_s->databits == UART_WORDLENGTH_8B) {
|
||||||
|
return (int)(huart->Instance->RDR & (uint8_t)0xFF);
|
||||||
|
} else {
|
||||||
|
return (int)(huart->Instance->RDR & (uint16_t)0x1FF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_putc(serial_t *obj, int c)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
while (!serial_writable(obj));
|
||||||
|
if (obj_s->databits == UART_WORDLENGTH_8B) {
|
||||||
|
huart->Instance->TDR = (uint8_t)(c & (uint8_t)0xFF);
|
||||||
|
} else {
|
||||||
|
huart->Instance->TDR = (uint16_t)(c & (uint16_t)0x1FF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_clear(serial_t *obj)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
/* Clear RXNE and error flags */
|
||||||
|
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR;
|
||||||
|
HAL_UART_ErrorCallback(huart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_break_set(serial_t *obj)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
HAL_LIN_SendBreak(huart);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEVICE_SERIAL_ASYNCH
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* LOCAL HELPER FUNCTIONS
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the TX buffer for an asynchronous write serial transaction
|
||||||
|
*
|
||||||
|
* @param obj The serial object.
|
||||||
|
* @param tx The buffer for sending.
|
||||||
|
* @param tx_length The number of words to transmit.
|
||||||
|
*/
|
||||||
|
static void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
|
||||||
|
{
|
||||||
|
(void)width;
|
||||||
|
|
||||||
|
// Exit if a transmit is already on-going
|
||||||
|
if (serial_tx_active(obj)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->tx_buff.buffer = tx;
|
||||||
|
obj->tx_buff.length = tx_length;
|
||||||
|
obj->tx_buff.pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the RX buffer for an asynchronous write serial transaction
|
||||||
|
*
|
||||||
|
* @param obj The serial object.
|
||||||
|
* @param tx The buffer for sending.
|
||||||
|
* @param tx_length The number of words to transmit.
|
||||||
|
*/
|
||||||
|
static void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
|
||||||
|
{
|
||||||
|
(void)width;
|
||||||
|
|
||||||
|
// Exit if a reception is already on-going
|
||||||
|
if (serial_rx_active(obj)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->rx_buff.buffer = rx;
|
||||||
|
obj->rx_buff.length = rx_length;
|
||||||
|
obj->rx_buff.pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure events
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
* @param event The logical OR of the events to configure
|
||||||
|
* @param enable Set to non-zero to enable events, or zero to disable them
|
||||||
|
*/
|
||||||
|
static void serial_enable_event(serial_t *obj, int event, uint8_t enable)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
|
||||||
|
// Shouldn't have to enable interrupt here, just need to keep track of the requested events.
|
||||||
|
if (enable) {
|
||||||
|
obj_s->events |= event;
|
||||||
|
} else {
|
||||||
|
obj_s->events &= ~event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get index of serial object TX IRQ, relating it to the physical peripheral.
|
||||||
|
*
|
||||||
|
* @param uart_name i.e. UART_1, UART_2, ...
|
||||||
|
* @return internal NVIC TX IRQ index of U(S)ART peripheral
|
||||||
|
*/
|
||||||
|
static IRQn_Type serial_get_irq_n(UARTName uart_name)
|
||||||
|
{
|
||||||
|
IRQn_Type irq_n;
|
||||||
|
|
||||||
|
switch (uart_name) {
|
||||||
|
#if defined(USART1_BASE)
|
||||||
|
case UART_1:
|
||||||
|
irq_n = USART1_IRQn;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USART2_BASE)
|
||||||
|
case UART_2:
|
||||||
|
irq_n = USART2_IRQn;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(USART3_BASE)
|
||||||
|
case UART_3:
|
||||||
|
irq_n = USART3_IRQn;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(UART4_BASE)
|
||||||
|
case UART_4:
|
||||||
|
irq_n = UART4_IRQn;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(UART5_BASE)
|
||||||
|
case UART_5:
|
||||||
|
irq_n = UART5_IRQn;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(LPUART1_BASE)
|
||||||
|
case LPUART_1:
|
||||||
|
irq_n = LPUART1_IRQn;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
irq_n = (IRQn_Type)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return irq_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* MBED API FUNCTIONS
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin asynchronous TX transfer. The used buffer is specified in the serial
|
||||||
|
* object, tx_buff
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
* @param tx The buffer for sending
|
||||||
|
* @param tx_length The number of words to transmit
|
||||||
|
* @param tx_width The bit width of buffer word
|
||||||
|
* @param handler The serial handler
|
||||||
|
* @param event The logical OR of events to be registered
|
||||||
|
* @param hint A suggestion for how to use DMA with this transfer
|
||||||
|
* @return Returns number of data transfered, or 0 otherwise
|
||||||
|
*/
|
||||||
|
int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
|
||||||
|
{
|
||||||
|
// TODO: DMA usage is currently ignored
|
||||||
|
(void) hint;
|
||||||
|
|
||||||
|
// Check buffer is ok
|
||||||
|
MBED_ASSERT(tx != (void *)0);
|
||||||
|
MBED_ASSERT(tx_width == 8); // support only 8b width
|
||||||
|
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
if (tx_length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up buffer
|
||||||
|
serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width);
|
||||||
|
|
||||||
|
// Set up events
|
||||||
|
serial_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events
|
||||||
|
serial_enable_event(obj, event, 1); // Set only the wanted events
|
||||||
|
|
||||||
|
// Enable interrupt
|
||||||
|
IRQn_Type irq_n = serial_get_irq_n(obj_s->uart);
|
||||||
|
NVIC_ClearPendingIRQ(irq_n);
|
||||||
|
NVIC_DisableIRQ(irq_n);
|
||||||
|
NVIC_SetPriority(irq_n, 1);
|
||||||
|
NVIC_SetVector(irq_n, (uint32_t)handler);
|
||||||
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
|
// the following function will enable UART_IT_TXE and error interrupts
|
||||||
|
if (HAL_UART_Transmit_IT(huart, (uint8_t *)tx, tx_length) != HAL_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin asynchronous RX transfer (enable interrupt for data collecting)
|
||||||
|
* The used buffer is specified in the serial object, rx_buff
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
* @param rx The buffer for sending
|
||||||
|
* @param rx_length The number of words to transmit
|
||||||
|
* @param rx_width The bit width of buffer word
|
||||||
|
* @param handler The serial handler
|
||||||
|
* @param event The logical OR of events to be registered
|
||||||
|
* @param handler The serial handler
|
||||||
|
* @param char_match A character in range 0-254 to be matched
|
||||||
|
* @param hint A suggestion for how to use DMA with this transfer
|
||||||
|
*/
|
||||||
|
void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
|
||||||
|
{
|
||||||
|
// TODO: DMA usage is currently ignored
|
||||||
|
(void) hint;
|
||||||
|
|
||||||
|
/* Sanity check arguments */
|
||||||
|
MBED_ASSERT(obj);
|
||||||
|
MBED_ASSERT(rx != (void *)0);
|
||||||
|
MBED_ASSERT(rx_width == 8); // support only 8b width
|
||||||
|
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
serial_enable_event(obj, SERIAL_EVENT_RX_ALL, 0);
|
||||||
|
serial_enable_event(obj, event, 1);
|
||||||
|
|
||||||
|
// set CharMatch
|
||||||
|
obj->char_match = char_match;
|
||||||
|
|
||||||
|
serial_rx_buffer_set(obj, rx, rx_length, rx_width);
|
||||||
|
|
||||||
|
IRQn_Type irq_n = serial_get_irq_n(obj_s->uart);
|
||||||
|
NVIC_ClearPendingIRQ(irq_n);
|
||||||
|
NVIC_DisableIRQ(irq_n);
|
||||||
|
NVIC_SetPriority(irq_n, 0);
|
||||||
|
NVIC_SetVector(irq_n, (uint32_t)handler);
|
||||||
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
|
// following HAL function will enable the RXNE interrupt + error interrupts
|
||||||
|
HAL_UART_Receive_IT(huart, (uint8_t *)rx, rx_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to determine if the serial peripheral is already in use for TX
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
* @return Non-zero if the TX transaction is ongoing, 0 otherwise
|
||||||
|
*/
|
||||||
|
uint8_t serial_tx_active(serial_t *obj)
|
||||||
|
{
|
||||||
|
MBED_ASSERT(obj);
|
||||||
|
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
return (((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_TX) == HAL_UART_STATE_BUSY_TX) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to determine if the serial peripheral is already in use for RX
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
* @return Non-zero if the RX transaction is ongoing, 0 otherwise
|
||||||
|
*/
|
||||||
|
uint8_t serial_rx_active(serial_t *obj)
|
||||||
|
{
|
||||||
|
MBED_ASSERT(obj);
|
||||||
|
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
return (((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
|
||||||
|
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear PE flag
|
||||||
|
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
|
||||||
|
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear FE flag
|
||||||
|
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) {
|
||||||
|
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear NE flag
|
||||||
|
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
|
||||||
|
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear ORE flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The asynchronous TX and RX handler.
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
* @return Returns event flags if a TX/RX transfer termination condition was met or 0 otherwise
|
||||||
|
*/
|
||||||
|
int serial_irq_handler_asynch(serial_t *obj)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
volatile int return_event = 0;
|
||||||
|
uint8_t *buf = (uint8_t *)(obj->rx_buff.buffer);
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
// TX PART:
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
|
||||||
|
// Return event SERIAL_EVENT_TX_COMPLETE if requested
|
||||||
|
if ((obj_s->events & SERIAL_EVENT_TX_COMPLETE) != 0) {
|
||||||
|
return_event |= (SERIAL_EVENT_TX_COMPLETE & obj_s->events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle error events
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) {
|
||||||
|
return_event |= (SERIAL_EVENT_RX_PARITY_ERROR & obj_s->events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) {
|
||||||
|
return_event |= (SERIAL_EVENT_RX_FRAMING_ERROR & obj_s->events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
|
||||||
|
if (__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) {
|
||||||
|
return_event |= (SERIAL_EVENT_RX_OVERRUN_ERROR & obj_s->events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_UART_IRQHandler(huart);
|
||||||
|
|
||||||
|
// Abort if an error occurs
|
||||||
|
if ((return_event & SERIAL_EVENT_RX_PARITY_ERROR) ||
|
||||||
|
(return_event & SERIAL_EVENT_RX_FRAMING_ERROR) ||
|
||||||
|
(return_event & SERIAL_EVENT_RX_OVERRUN_ERROR)) {
|
||||||
|
return return_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
//RX PART
|
||||||
|
if (huart->RxXferSize != 0) {
|
||||||
|
obj->rx_buff.pos = huart->RxXferSize - huart->RxXferCount;
|
||||||
|
}
|
||||||
|
if ((huart->RxXferCount == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
|
||||||
|
return_event |= (SERIAL_EVENT_RX_COMPLETE & obj_s->events);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if char_match is present
|
||||||
|
if (obj_s->events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
|
||||||
|
if (buf != NULL) {
|
||||||
|
for (i = 0; i < obj->rx_buff.pos; i++) {
|
||||||
|
if (buf[i] == obj->char_match) {
|
||||||
|
obj->rx_buff.pos = i;
|
||||||
|
return_event |= (SERIAL_EVENT_RX_CHARACTER_MATCH & obj_s->events);
|
||||||
|
serial_rx_abort_asynch(obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return return_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort the ongoing TX transaction. It disables the enabled interupt for TX and
|
||||||
|
* flush TX hardware buffer if TX FIFO is used
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
*/
|
||||||
|
void serial_tx_abort_asynch(serial_t *obj)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_TC);
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
|
||||||
|
|
||||||
|
// reset states
|
||||||
|
huart->TxXferCount = 0;
|
||||||
|
// update handle state
|
||||||
|
if (huart->gState == HAL_UART_STATE_BUSY_TX_RX) {
|
||||||
|
huart->gState = HAL_UART_STATE_BUSY_RX;
|
||||||
|
} else {
|
||||||
|
huart->gState = HAL_UART_STATE_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort the ongoing RX transaction It disables the enabled interrupt for RX and
|
||||||
|
* flush RX hardware buffer if RX FIFO is used
|
||||||
|
*
|
||||||
|
* @param obj The serial object
|
||||||
|
*/
|
||||||
|
void serial_rx_abort_asynch(serial_t *obj)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
|
||||||
|
|
||||||
|
// disable interrupts
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
|
||||||
|
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
|
||||||
|
|
||||||
|
// clear flags
|
||||||
|
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
|
||||||
|
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear errors flag
|
||||||
|
|
||||||
|
// reset states
|
||||||
|
huart->RxXferCount = 0;
|
||||||
|
// update handle state
|
||||||
|
if (huart->RxState == HAL_UART_STATE_BUSY_TX_RX) {
|
||||||
|
huart->RxState = HAL_UART_STATE_BUSY_TX;
|
||||||
|
} else {
|
||||||
|
huart->RxState = HAL_UART_STATE_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DEVICE_SERIAL_ASYNCH */
|
||||||
|
|
||||||
|
#if DEVICE_SERIAL_FC
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set HW Control Flow
|
||||||
|
* @param obj The serial object
|
||||||
|
* @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
|
||||||
|
* @param pinmap Pointer to structure which holds static pinmap
|
||||||
|
*/
|
||||||
|
#if STATIC_PINMAP_READY
|
||||||
|
#define SERIAL_SET_FC_DIRECT serial_set_flow_control_direct
|
||||||
|
void serial_set_flow_control_direct(serial_t *obj, FlowControl type, const serial_fc_pinmap_t *pinmap)
|
||||||
|
#else
|
||||||
|
#define SERIAL_SET_FC_DIRECT _serial_set_flow_control_direct
|
||||||
|
static void _serial_set_flow_control_direct(serial_t *obj, FlowControl type, const serial_fc_pinmap_t *pinmap)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
|
||||||
|
if (type == FlowControlNone) {
|
||||||
|
// Disable hardware flow control
|
||||||
|
obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
|
||||||
|
}
|
||||||
|
if (type == FlowControlRTS) {
|
||||||
|
// Enable RTS
|
||||||
|
MBED_ASSERT(pinmap->rx_flow_pin != NC);
|
||||||
|
obj_s->hw_flow_ctl = UART_HWCONTROL_RTS;
|
||||||
|
obj_s->pin_rts = pinmap->rx_flow_pin;
|
||||||
|
// Enable the pin for RTS function
|
||||||
|
pin_function(pinmap->rx_flow_pin, pinmap->rx_flow_function);
|
||||||
|
pin_mode(pinmap->rx_flow_pin, PullNone);
|
||||||
|
}
|
||||||
|
if (type == FlowControlCTS) {
|
||||||
|
// Enable CTS
|
||||||
|
MBED_ASSERT(pinmap->tx_flow_pin != NC);
|
||||||
|
obj_s->hw_flow_ctl = UART_HWCONTROL_CTS;
|
||||||
|
obj_s->pin_cts = pinmap->tx_flow_pin;
|
||||||
|
// Enable the pin for CTS function
|
||||||
|
pin_function(pinmap->tx_flow_pin, pinmap->tx_flow_function);
|
||||||
|
pin_mode(pinmap->tx_flow_pin, PullNone);
|
||||||
|
}
|
||||||
|
if (type == FlowControlRTSCTS) {
|
||||||
|
// Enable CTS & RTS
|
||||||
|
MBED_ASSERT(pinmap->rx_flow_pin != NC);
|
||||||
|
MBED_ASSERT(pinmap->tx_flow_pin != NC);
|
||||||
|
obj_s->hw_flow_ctl = UART_HWCONTROL_RTS_CTS;
|
||||||
|
obj_s->pin_rts = pinmap->rx_flow_pin;;
|
||||||
|
obj_s->pin_cts = pinmap->tx_flow_pin;;
|
||||||
|
// Enable the pin for CTS function
|
||||||
|
pin_function(pinmap->tx_flow_pin, pinmap->tx_flow_function);
|
||||||
|
pin_mode(pinmap->tx_flow_pin, PullNone);
|
||||||
|
// Enable the pin for RTS function
|
||||||
|
pin_function(pinmap->rx_flow_pin, pinmap->rx_flow_function);
|
||||||
|
pin_mode(pinmap->rx_flow_pin, PullNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
init_uart(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set HW Control Flow
|
||||||
|
* @param obj The serial object
|
||||||
|
* @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
|
||||||
|
* @param rxflow Pin for the rxflow
|
||||||
|
* @param txflow Pin for the txflow
|
||||||
|
*/
|
||||||
|
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
|
||||||
|
{
|
||||||
|
struct serial_s *obj_s = SERIAL_S(obj);
|
||||||
|
|
||||||
|
UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
|
||||||
|
UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
|
||||||
|
|
||||||
|
if (((UARTName)pinmap_merge(uart_rts, obj_s->uart) == (UARTName)NC) || ((UARTName)pinmap_merge(uart_cts, obj_s->uart) == (UARTName)NC)) {
|
||||||
|
MBED_ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int peripheral = (int)pinmap_merge(uart_rts, uart_cts);
|
||||||
|
|
||||||
|
int tx_flow_function = (int)pinmap_find_function(txflow, PinMap_UART_CTS);
|
||||||
|
int rx_flow_function = (int)pinmap_find_function(rxflow, PinMap_UART_RTS);
|
||||||
|
|
||||||
|
const serial_fc_pinmap_t explicit_uart_fc_pinmap = {peripheral, txflow, tx_flow_function, rxflow, rx_flow_function};
|
||||||
|
|
||||||
|
SERIAL_SET_FC_DIRECT(obj, type, &explicit_uart_fc_pinmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DEVICE_SERIAL_FC */
|
||||||
|
|
||||||
|
#endif /* DEVICE_SERIAL */
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "spi_api.h"
|
||||||
|
|
||||||
|
#if DEVICE_SPI
|
||||||
|
|
||||||
|
#include "cmsis.h"
|
||||||
|
#include "pinmap.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
#include "PeripheralPins.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 = HAL_RCC_GetPCLK2Freq();
|
||||||
|
break;
|
||||||
|
case SPI_2:
|
||||||
|
spi_hz = HAL_RCC_GetPCLK1Freq();
|
||||||
|
break;
|
||||||
|
case SPI_3:
|
||||||
|
spi_hz = HAL_RCC_GetPCLK3Freq();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("CLK: SPI instance not set");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return spi_hz;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 "stm32u5xx_ll_spi.h"
|
||||||
|
|
||||||
|
#define SPI_IP_VERSION_V2 // SPI2S2 / SPI2S3 IP version
|
||||||
|
|
||||||
|
// Defines the word legnth capability of the device where Nth bit allows for N window size
|
||||||
|
#define STM32_SPI_CAPABILITY_WORD_LENGTH (0x0000FFF8)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2021 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 __US_TICKER_DATA_H
|
||||||
|
#define __US_TICKER_DATA_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32u5xx.h"
|
||||||
|
#include "stm32u5xx_ll_tim.h"
|
||||||
|
|
||||||
|
#define TIM_MST TIM5
|
||||||
|
#define TIM_MST_IRQ TIM5_IRQn
|
||||||
|
#define TIM_MST_RCC __HAL_RCC_TIM5_CLK_ENABLE()
|
||||||
|
|
||||||
|
#define TIM_MST_RESET_ON __HAL_RCC_TIM5_FORCE_RESET()
|
||||||
|
#define TIM_MST_RESET_OFF __HAL_RCC_TIM5_RELEASE_RESET()
|
||||||
|
|
||||||
|
#define TIM_MST_BIT_WIDTH 32 // 16 or 32
|
||||||
|
|
||||||
|
#define TIM_MST_PCLK 1 // Select the peripheral clock number (1 or 2)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __US_TICKER_DATA_H
|
Loading…
Reference in New Issue