Skip to content

Fix resolution #829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions cores/arduino/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,20 @@ PinName analogInputToPinName(uint32_t pin);

// Default Definitions, could be redefined in variant.h
#ifndef ADC_RESOLUTION
#define ADC_RESOLUTION 12
#define ADC_RESOLUTION 10
#endif
#ifndef DACC_RESOLUTION

#define DACC_RESOLUTION 12
#endif

#ifndef PWM_RESOLUTION
#define PWM_RESOLUTION 8
#endif

_Static_assert((ADC_RESOLUTION > 0) &&(ADC_RESOLUTION <= 32),
"ADC_RESOLUTION must be 0 < x <= 32!");
_Static_assert((PWM_RESOLUTION > 0) &&(PWM_RESOLUTION <= 32),
"PWM_RESOLUTION must be 0 < x <= 32!");

#ifndef PWM_FREQUENCY
#define PWM_FREQUENCY 1000
#endif
Expand Down
2 changes: 1 addition & 1 deletion cores/arduino/stm32/analog.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ extern "C" {
/* Exported functions ------------------------------------------------------- */
void dac_write_value(PinName pin, uint32_t value, uint8_t do_init);
void dac_stop(PinName pin);
uint16_t adc_read_value(PinName pin);
uint16_t adc_read_value(PinName pin, uint32_t resolution);
void pwm_start(PinName pin, uint32_t clock_freq, uint32_t value, TimerCompareFormat_t resolution);
void pwm_stop(PinName pin);
uint32_t get_pwm_channel(PinName pin);
Expand Down
105 changes: 96 additions & 9 deletions cores/arduino/wiring_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,104 @@ extern "C" {
uint32_t g_anOutputPinConfigured[MAX_NB_PORT] = {0};
#endif

static int _readResolution = 10;
int _writeResolution = PWM_RESOLUTION;
#if !defined(ADC_RESOLUTION_16B)
#define MAX_ADC_RESOLUTION 12
#else
#define MAX_ADC_RESOLUTION 16
#endif
#define MAX_PWM_RESOLUTION 16

static int _readResolution = ADC_RESOLUTION;
static int _internalReadResolution =
#if ADC_RESOLUTION > MAX_ADC_RESOLUTION
MAX_ADC_RESOLUTION
#else

#ifdef ADC_RESOLUTION_12B

#if ADC_RESOLUTION <= 6 && defined(ADC_RESOLUTION_6B)
6
#elif ADC_RESOLUTION <= 8
8
#elif ADC_RESOLUTION <= 10
10
#elif ADC_RESOLUTION <= 12
12
#elif ADC_RESOLUTION <= 14 && defined(ADC_RESOLUTION_14B)
14
#elif defined(ADC_RESOLUTION_16B)
16
#endif
#else /* ADC_RESOLUTION_12B */
12
#endif /* ADC_RESOLUTION_12B */
#endif /* ADC_RESOLUTION > MAX_ADC_RESOLUTION */
;

static int _writeResolution = PWM_RESOLUTION;
static int _internalWriteResolution =
#if PWM_RESOLUTION > MAX_PWM_RESOLUTION
MAX_PWM_RESOLUTION
#else
PWM_RESOLUTION
#endif
;

static uint32_t _writeFreq = PWM_FREQUENCY;

void analogReadResolution(int res)
{
_readResolution = res;
if ((res > 0) && (res <= 32)) {
_readResolution = res;
_internalReadResolution = _readResolution;
if (_readResolution > MAX_ADC_RESOLUTION) {
_internalReadResolution = MAX_ADC_RESOLUTION;
} else {
#ifdef ADC_RESOLUTION_12B
#ifdef ADC_RESOLUTION_6B
if (_internalReadResolution <= 6) {
_internalReadResolution = 6;
} else
#endif
if (_internalReadResolution <= 8) {
_internalReadResolution = 8;
} else if (_internalReadResolution <= 10) {
_internalReadResolution = 10;
} else if (_internalReadResolution <= 12) {
_internalReadResolution = 12;
}
#ifdef ADC_RESOLUTION_14B
else if (_internalReadResolution <= 14) {
_internalReadResolution = 14;
}
#endif
#ifdef ADC_RESOLUTION_16B
else if (_internalReadResolution <= 16) {
_internalReadResolution = 16;
}
#endif
#else
/* STM32F1xx have no ADC_RESOLUTION_xB */
_internalReadResolution = 12;
#endif
}
} else {
Error_Handler();
}
}

void analogWriteResolution(int res)
{
_writeResolution = res;
if ((res > 0) && (res <= 32)) {
_writeResolution = res;
if (_writeResolution > MAX_ADC_RESOLUTION) {
_internalWriteResolution = MAX_ADC_RESOLUTION;
} else {
_internalWriteResolution = _writeResolution;
}
} else {
Error_Handler();
}
}

void analogWriteFrequency(uint32_t freq)
Expand All @@ -67,16 +153,16 @@ void analogReference(eAnalogReference ulMode)
UNUSED(ulMode);
}

//perform the read operation on the selected analog pin.
//the initialization of the analog PIN is done through this function
// Perform the read operation on the selected analog pin.
// the initialization of the analog PIN is done through this function
uint32_t analogRead(uint32_t ulPin)
{
uint32_t value = 0;
#if defined(HAL_ADC_MODULE_ENABLED) && !defined(HAL_ADC_MODULE_ONLY)
PinName p = analogInputToPinName(ulPin);
if (p != NC) {
value = adc_read_value(p);
value = mapResolution(value, ADC_RESOLUTION, _readResolution);
value = adc_read_value(p, _internalReadResolution);
value = mapResolution(value, _internalReadResolution, _readResolution);
}
#else
UNUSED(ulPin);
Expand Down Expand Up @@ -115,7 +201,8 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue)
if (is_pin_configured(p, g_anOutputPinConfigured) == false) {
set_pin_configured(p, g_anOutputPinConfigured);
}
pwm_start(p, _writeFreq, ulValue, _writeResolution);
ulValue = mapResolution(ulValue, _writeResolution, _internalWriteResolution);
pwm_start(p, _writeFreq, ulValue, _internalWriteResolution);
} else
#endif /* HAL_TIM_MODULE_ENABLED && !HAL_TIM_MODULE_ONLY */
{
Expand Down
33 changes: 31 additions & 2 deletions libraries/SrcWrapper/src/stm32/analog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,9 +758,10 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
/**
* @brief This function will set the ADC to the required value
* @param pin : the pin to use
* @param resolution : resolution for converted data: 6/8/10/12/14/16
* @retval the value of the adc
*/
uint16_t adc_read_value(PinName pin)
uint16_t adc_read_value(PinName pin, uint32_t resolution)
{
ADC_HandleTypeDef AdcHandle = {};
ADC_ChannelConfTypeDef AdcChannelConf = {};
Expand Down Expand Up @@ -794,7 +795,35 @@ uint16_t adc_read_value(PinName pin)
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* (A)synchronous clock mode, input ADC clock divided */
#endif
#ifdef ADC_RESOLUTION_12B
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */
switch (resolution) {
#ifdef ADC_RESOLUTION_6B
case 6:
AdcHandle.Init.Resolution = ADC_RESOLUTION_6B; /* resolution for converted data */
break;
#endif
case 8:
AdcHandle.Init.Resolution = ADC_RESOLUTION_8B; /* resolution for converted data */
break;
case 10:
AdcHandle.Init.Resolution = ADC_RESOLUTION_10B; /* resolution for converted data */
break;
case 12:
default:
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* resolution for converted data */
break;
#ifdef ADC_RESOLUTION_14B
case 14:
AdcHandle.Init.Resolution = ADC_RESOLUTION_14B; /* resolution for converted data */
break;
#endif
#ifdef ADC_RESOLUTION_16B
case 16:
AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; /* resolution for converted data */
break;
#endif
}
#else
UNUSED(resolution);
#endif
#ifdef ADC_DATAALIGN_RIGHT
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */
Expand Down
11 changes: 0 additions & 11 deletions variants/BLACK_F407XX/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,6 @@ extern "C" {
#define NUM_ANALOG_INPUTS 14
#define NUM_ANALOG_FIRST 44

// Below ADC, DAC and PWM definitions already done in the core
// Could be redefined here if needed
// ADC resolution is 12bits
//#define ADC_RESOLUTION 12
//#define DACC_RESOLUTION 12

// PWM resolution
//#define PWM_RESOLUTION 8
//#define PWM_FREQUENCY 1000
//#define PWM_MAX_DUTY_CYCLE 255

// On-board LED pin number
#define LED_D2 PA6
#define LED_D3 PA7
Expand Down
11 changes: 0 additions & 11 deletions variants/BLUE_F407VE_Mini/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,6 @@ extern "C" {
#define NUM_ANALOG_INPUTS 14
#define NUM_ANALOG_FIRST 80

// Below ADC, DAC and PWM definitions already done in the core
// Could be redefined here if needed
// ADC resolution is 12bits
//#define ADC_RESOLUTION 12
//#define DACC_RESOLUTION 12

// PWM resolution
//#define PWM_RESOLUTION 8
//#define PWM_FREQUENCY 1000
//#define PWM_MAX_DUTY_CYCLE 255

// On-board LED pin number
#define LED_BUILTIN PB9

Expand Down
7 changes: 3 additions & 4 deletions variants/board_template/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,10 @@ extern "C" {
// First analog pin value (A0) must be greater than or equal to NUM_ANALOG_INPUTS
#define NUM_ANALOG_FIRST 0

// Below ADC, DAC and PWM definitions already done in the core
// Below ADC and PWM definitions already done in the core
// Could be redefined here if needed
// ADC resolution is 12bits
//#define ADC_RESOLUTION 12
//#define DACC_RESOLUTION 12
// ADC resolution is 10 bits
//#define ADC_RESOLUTION 10

// PWM resolution
//#define PWM_RESOLUTION 8
Expand Down