mirror of https://github.com/ARMmbed/mbed-os.git
Add AnalogIn and AnalogOut APIs support for STM32H5 (#314)
* fix PWM pin map in context of Timer change * Note about DAC on Nucleo-H503RB * Add ADC and DAC for STM32H5 * Copyright fix * ADC/DAC fix --------- Co-authored-by: Jan Kamidra <odiin@windowslive.com>pull/15530/head
parent
c1e3c86a4d
commit
8d2ede6498
|
@ -10,6 +10,8 @@ add_library(mbed-stm32h5 INTERFACE)
|
|||
target_sources(mbed-stm32h5
|
||||
INTERFACE
|
||||
clock_cfg/system_clock.c
|
||||
analogin_device.c
|
||||
analogout_device.c
|
||||
gpio_irq_device.c
|
||||
serial_device.c
|
||||
pwmout_device.c
|
||||
|
|
|
@ -68,7 +68,7 @@ MBED_WEAK const PinMap PinMap_ADC_Internal[] = {
|
|||
};
|
||||
|
||||
//*** DAC ***
|
||||
|
||||
// Not usable in case of Nucleo-H503RB board because both pins are already used.
|
||||
MBED_WEAK const PinMap PinMap_DAC[] = {
|
||||
{PA_4, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC1_OUT1 // Connected to STDIO_UART_TX
|
||||
{PA_5, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC1_OUT2 // Connected to USER_LED
|
||||
|
|
|
@ -128,43 +128,43 @@ MBED_WEAK const PinMap PinMap_I2C_SCL[] = {
|
|||
|
||||
//*** PWM ***
|
||||
|
||||
// TIM5 cannot be used because already used by the us_ticker
|
||||
// TIM3 cannot be used because already used by the us_ticker
|
||||
// (update us_ticker_data.h file if another timer is chosen)
|
||||
MBED_WEAK const PinMap PinMap_PWM[] = {
|
||||
//{PA_0, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
|
||||
{PA_0, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
|
||||
{PA_0, PWM_5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1
|
||||
//{PA_1, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2
|
||||
{PA_1, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2
|
||||
{PA_1, PWM_5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2
|
||||
{PA_1_ALT0, PWM_15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF4_TIM15, 1, 1)}, // TIM15_CH1N
|
||||
//{PA_2, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
|
||||
{PA_2, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
|
||||
{PA_2, PWM_5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3
|
||||
{PA_2_ALT0, PWM_15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF4_TIM15, 1, 0)}, // TIM15_CH1
|
||||
//{PA_3, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
|
||||
{PA_3, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
|
||||
{PA_3, PWM_5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4
|
||||
{PA_3_ALT0, PWM_15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF4_TIM15, 2, 0)}, // TIM15_CH2
|
||||
//{PA_5, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
|
||||
{PA_5, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
|
||||
{PA_5_ALT0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N
|
||||
{PA_6, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
|
||||
//{PA_6, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
|
||||
{PA_6_ALT0, PWM_13, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1
|
||||
{PA_7, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N
|
||||
{PA_7_ALT0, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
|
||||
//{PA_7_ALT0, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
|
||||
{PA_7_ALT1, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N
|
||||
{PA_7_ALT2, PWM_14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1
|
||||
{PA_8, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1
|
||||
{PA_9, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2
|
||||
{PA_10, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3
|
||||
{PA_11, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4
|
||||
//{PA_15, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
|
||||
{PA_15, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
|
||||
{PB_0, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N
|
||||
{PB_0_ALT0, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3
|
||||
//{PB_0_ALT0, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3
|
||||
{PB_0_ALT1, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N
|
||||
{PB_1, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N
|
||||
{PB_1_ALT0, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4
|
||||
//{PB_1_ALT0, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4
|
||||
{PB_1_ALT1, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N
|
||||
{PB_2, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 4, 1)}, // TIM8_CH4N
|
||||
//{PB_3, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2
|
||||
{PB_4, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
|
||||
{PB_5, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
|
||||
{PB_3, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2
|
||||
//{PB_4, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
|
||||
//{PB_5, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
|
||||
{PB_6, PWM_4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1
|
||||
{PB_6_ALT0, PWM_16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM16, 1, 1)}, // TIM16_CH1N
|
||||
{PB_7, PWM_4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2
|
||||
|
@ -173,7 +173,7 @@ MBED_WEAK const PinMap PinMap_PWM[] = {
|
|||
{PB_8_ALT0, PWM_16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM16, 1, 0)}, // TIM16_CH1
|
||||
{PB_9, PWM_4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4
|
||||
{PB_9_ALT0, PWM_17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM17, 1, 0)}, // TIM17_CH1
|
||||
//{PB_10, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
|
||||
{PB_10, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
|
||||
{PB_13, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N
|
||||
{PB_14, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N
|
||||
{PB_14_ALT0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N
|
||||
|
@ -183,15 +183,15 @@ MBED_WEAK const PinMap PinMap_PWM[] = {
|
|||
{PB_15_ALT1, PWM_12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM12, 2, 0)}, // TIM12_CH2
|
||||
{PC_2, PWM_4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4
|
||||
{PC_2_ALT0, PWM_17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM17, 1, 0)}, // TIM17_CH1
|
||||
//{PC_4, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
|
||||
{PC_4, PWM_2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
|
||||
{PC_5, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM1, 4, 1)}, // TIM1_CH4N
|
||||
{PC_6, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
|
||||
//{PC_6, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
|
||||
{PC_6_ALT0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1
|
||||
{PC_7, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
|
||||
//{PC_7, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
|
||||
{PC_7_ALT0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2
|
||||
{PC_8, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3
|
||||
//{PC_8, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3
|
||||
{PC_8_ALT0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3
|
||||
{PC_9, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4
|
||||
//{PC_9, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4
|
||||
{PC_9_ALT0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4
|
||||
{PC_12, PWM_15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM15, 1, 0)}, // TIM15_CH1
|
||||
{PD_0, PWM_8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM8, 4, 1)}, // TIM8_CH4N
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/* 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 "analogin_api.h"
|
||||
|
||||
#if DEVICE_ANALOGIN
|
||||
|
||||
#include "mbed_wait_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
|
||||
void analogin_clock_configuration(void)
|
||||
{
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInitStruct.AdcDacClockSelection = LL_RCC_ADCDAC_CLKSOURCE_HCLK;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
|
||||
error("analogin_init HAL_RCCEx_PeriphCLKConfig");
|
||||
}
|
||||
}
|
||||
|
||||
void analogin_init(analogin_t *obj, PinName pin)
|
||||
{
|
||||
uint32_t function = (uint32_t)NC;
|
||||
|
||||
// ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...)
|
||||
// are described in PinNames.h and PeripheralPins.c
|
||||
// Pin value must be between 0xF0 and 0xFF
|
||||
if ((pin < 0xF0) || (pin >= (PinName)ALT0)) {
|
||||
// Normal channels
|
||||
// Get the peripheral name from the pin and assign it to the object
|
||||
obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC);
|
||||
// Get the functions (adc channel) from the pin and assign it to the object
|
||||
function = pinmap_function(pin, PinMap_ADC);
|
||||
// Configure GPIO
|
||||
pinmap_pinout(pin, PinMap_ADC);
|
||||
} else {
|
||||
// Internal channels
|
||||
obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC_Internal);
|
||||
function = pinmap_function(pin, PinMap_ADC_Internal);
|
||||
// No GPIO configuration for internal channels
|
||||
}
|
||||
MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC);
|
||||
MBED_ASSERT(function != (uint32_t)NC);
|
||||
|
||||
analogin_clock_configuration();
|
||||
|
||||
obj->channel = STM_PIN_CHANNEL(function);
|
||||
obj->differential = STM_PIN_INVERTED(function);
|
||||
|
||||
// Save pin number for the read function
|
||||
obj->pin = pin;
|
||||
|
||||
// Configure ADC object structures
|
||||
obj->handle.State = HAL_ADC_STATE_RESET;
|
||||
obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV10;
|
||||
obj->handle.Init.Resolution = ADC_RESOLUTION_12B;
|
||||
obj->handle.Init.ScanConvMode = ADC_SCAN_DISABLE;
|
||||
obj->handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||
obj->handle.Init.LowPowerAutoWait = DISABLE;
|
||||
obj->handle.Init.ContinuousConvMode = DISABLE;
|
||||
obj->handle.Init.NbrOfConversion = 1;
|
||||
obj->handle.Init.DiscontinuousConvMode = DISABLE;
|
||||
obj->handle.Init.NbrOfDiscConversion = 0;
|
||||
obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
||||
obj->handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
|
||||
obj->handle.Init.OversamplingMode = DISABLE;
|
||||
obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
|
||||
__HAL_RCC_ADC_CLK_ENABLE();
|
||||
|
||||
if (HAL_ADC_Init(&obj->handle) != HAL_OK) {
|
||||
error("analogin_init HAL_ADC_Init");
|
||||
}
|
||||
|
||||
// Calibration
|
||||
HAL_ADCEx_Calibration_Start(&obj->handle, ADC_SINGLE_ENDED);
|
||||
}
|
||||
|
||||
uint16_t adc_read(analogin_t *obj)
|
||||
{
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
// Configure ADC channel
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
|
||||
sConfig.Offset = 0;
|
||||
sConfig.SingleDiff = ADC_SINGLE_ENDED;
|
||||
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
||||
|
||||
switch (obj->pin) {
|
||||
case ADC_TEMP:
|
||||
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
|
||||
break;
|
||||
|
||||
case ADC_VREF:
|
||||
sConfig.Channel = ADC_CHANNEL_VREFINT;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
|
||||
break;
|
||||
|
||||
case ADC_VBAT:
|
||||
sConfig.Channel = ADC_CHANNEL_VBAT;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (obj->channel) {
|
||||
case 0:
|
||||
sConfig.Channel = ADC_CHANNEL_0;
|
||||
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_18;
|
||||
break;
|
||||
case 19:
|
||||
sConfig.Channel = ADC_CHANNEL_19;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (HAL_ADC_ConfigChannel(&obj->handle, &sConfig) != HAL_OK) {
|
||||
error("HAL_ADC_ConfigChannel issue");
|
||||
}
|
||||
|
||||
if (HAL_ADC_Start(&obj->handle) != HAL_OK) {
|
||||
error("HAL_ADC_Start issue");
|
||||
}
|
||||
|
||||
// Wait end of conversion and get value
|
||||
uint16_t adcValue = 0;
|
||||
if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) {
|
||||
adcValue = (uint16_t)HAL_ADC_GetValue(&obj->handle);
|
||||
}
|
||||
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE((&obj->handle)->Instance), LL_ADC_PATH_INTERNAL_NONE);
|
||||
|
||||
if (HAL_ADC_Stop(&obj->handle) != HAL_OK) {
|
||||
error("HAL_ADC_Stop issue");
|
||||
}
|
||||
|
||||
return adcValue;
|
||||
}
|
||||
|
||||
const PinMap *analogin_pinmap()
|
||||
{
|
||||
return PinMap_ADC;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
/* 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 "analogout_api.h"
|
||||
|
||||
#if DEVICE_ANALOGOUT
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
#include "stm32h5xx_hal.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
|
||||
|
||||
void analogout_clock_configuration(void)
|
||||
{
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_DAC;
|
||||
PeriphClkInitStruct.AdcDacClockSelection = LL_RCC_ADCDAC_CLKSOURCE_HCLK;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
|
||||
error("analogout_init HAL_RCCEx_PeriphCLKConfig");
|
||||
}
|
||||
}
|
||||
|
||||
void analogout_init(dac_t *obj, PinName pin)
|
||||
{
|
||||
DAC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
// Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
|
||||
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
|
||||
// Get the functions (dac channel) from the pin and assign it to the object
|
||||
uint32_t function = pinmap_function(pin, PinMap_DAC);
|
||||
MBED_ASSERT(function != (uint32_t)NC);
|
||||
|
||||
// Save the channel for the write and read functions
|
||||
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;
|
||||
}
|
||||
|
||||
if (obj->dac == (DACName)NC) {
|
||||
error("DAC pin mapping failed");
|
||||
}
|
||||
|
||||
// Configure GPIO
|
||||
pinmap_pinout(pin, PinMap_DAC);
|
||||
|
||||
// Save the pin for future use
|
||||
obj->pin = pin;
|
||||
|
||||
analogout_clock_configuration();
|
||||
|
||||
__GPIOA_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_DAC1_CLK_ENABLE();
|
||||
|
||||
obj->handle.Instance = DAC1;
|
||||
obj->handle.State = HAL_DAC_STATE_RESET;
|
||||
|
||||
if (HAL_DAC_Init(&obj->handle) != HAL_OK) {
|
||||
error("HAL_DAC_Init failed");
|
||||
}
|
||||
|
||||
sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_160MHZ;
|
||||
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
|
||||
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
|
||||
|
||||
if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
|
||||
error("HAL_DAC_ConfigChannel failed");
|
||||
}
|
||||
|
||||
if (obj->channel == DAC_CHANNEL_1) {
|
||||
channel1_used = 1;
|
||||
}
|
||||
#if defined(DAC_CHANNEL_2)
|
||||
if (obj->channel == DAC_CHANNEL_2) {
|
||||
channel2_used = 1;
|
||||
}
|
||||
#endif
|
||||
analogout_write_u16(obj, 0);
|
||||
HAL_DAC_Start(&obj->handle, obj->channel);
|
||||
}
|
||||
|
||||
void analogout_free(dac_t *obj)
|
||||
{
|
||||
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
|
||||
) {
|
||||
// Reset DAC and disable clock
|
||||
__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
|
|
@ -3092,11 +3092,10 @@
|
|||
"MBED_TICKLESS"
|
||||
],
|
||||
"device_has_add": [
|
||||
"MPU"
|
||||
"MPU",
|
||||
"ANALOGOUT"
|
||||
],
|
||||
"device_has_remove": [
|
||||
"ANALOGOUT",
|
||||
"ANALOGIN",
|
||||
"FLASH",
|
||||
"LPTICKER",
|
||||
"CAN",
|
||||
|
@ -3139,6 +3138,9 @@
|
|||
// MCU VDD defaults to 3.3V though can be changed to 1.8V based on JP2 setting on nucleo board.
|
||||
"default-adc-vref": 3.3
|
||||
},
|
||||
"device_has_remove": [
|
||||
"ANALOGOUT" // both DAC pins are in conflict with LED1 and STDIO_UART_TX
|
||||
],
|
||||
"supported_form_factors": [
|
||||
"ARDUINO_UNO"
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue