From 500b21c236cc2506df0bef1e1c8a04fbb6a4ceb9 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Tue, 10 Sep 2019 19:48:24 -0400 Subject: [PATCH] First pass at full LL implementation --- ports/stm32f4/common-hal/analogio/AnalogIn.c | 22 +-- ports/stm32f4/common-hal/analogio/AnalogOut.c | 176 +++++++++--------- ports/stm32f4/common-hal/analogio/AnalogOut.h | 3 - ports/stm32f4/mpconfigport.mk | 1 + 4 files changed, 93 insertions(+), 109 deletions(-) diff --git a/ports/stm32f4/common-hal/analogio/AnalogIn.c b/ports/stm32f4/common-hal/analogio/AnalogIn.c index 7318e3a2d9..d7f2a76a9d 100644 --- a/ports/stm32f4/common-hal/analogio/AnalogIn.c +++ b/ports/stm32f4/common-hal/analogio/AnalogIn.c @@ -33,6 +33,7 @@ #include "stm32f4xx_hal.h" #include "stm32f4xx_ll_gpio.h" #include "stm32f4xx_ll_adc.h" +#include "stm32f4xx_ll_bus.h" //mp_raise_ValueError(translate("U dun goofed")); @@ -45,7 +46,6 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, } //TODO: add ADC traits to structure? - //LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); //required? LL_GPIO_SetPinMode(pin_port(pin->number), pin_mask(pin->number), LL_GPIO_MODE_ANALOG); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); //TODO: conditional on ADC unit claim_pin(pin); @@ -68,32 +68,28 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { // Something else might have used the ADC in a different way, // so we completely re-initialize it. + //LL Implementation if (LL_ADC_IsEnabled(ADC1) == 0) { LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE); LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_SINGLE); LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE); - LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_4); + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, stm32_adc_channel(self->pin->adc)); + //LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_4); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_4, LL_ADC_SAMPLINGTIME_56CYCLES); + LL_ADC_SetChannelSamplingTime(ADC1, stm32_adc_channel(self->pin->adc), LL_ADC_SAMPLINGTIME_56CYCLES); LL_ADC_EnableIT_OVR(ADC1); } - LL_ADC_Enable(ADC1); - - - struct adc_sync_descriptor adc; - - samd_peripherals_adc_setup(&adc, self->instance); - - ConversionStartPoll_ADC_GrpRegular(); - + uint16_t uhADCxConvertedData = (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1); + LL_ADC_REG_StartConversionSWStart(ADC1); + while (LL_ADC_IsActiveFlag_EOCS(ADC1) == 0) {} /* Retrieve ADC conversion data */ /* (data scale corresponds to ADC resolution: 12 bits) */ uhADCxConvertedData = LL_ADC_REG_ReadConversionData12(ADC1); // Shift the value to be 16 bit. - return value << 4; + return uhADCxConvertedData << 4; } float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.c b/ports/stm32f4/common-hal/analogio/AnalogOut.c index 9ac1f7bd15..5caf7aa81c 100644 --- a/ports/stm32f4/common-hal/analogio/AnalogOut.c +++ b/ports/stm32f4/common-hal/analogio/AnalogOut.c @@ -31,77 +31,67 @@ #include "py/runtime.h" #include "shared-bindings/analogio/AnalogOut.h" -#include "shared-bindings/audioio/AudioOut.h" #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" -#include "atmel_start_pins.h" -#include "hal/include/hal_dac_sync.h" -#include "hpl/gclk/hpl_gclk_base.h" -#include "peripheral_clk_config.h" - -#ifdef SAMD21 -#include "hpl/pm/hpl_pm_base.h" -#endif - void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin) { - #if defined(SAMD21) && !defined(PIN_PA02) - mp_raise_NotImplementedError(translate("No DAC on chip")); - #else - if (pin->number != PIN_PA02 - #ifdef SAMD51 - && pin->number != PIN_PA05 - #endif - ) { - mp_raise_ValueError(translate("AnalogOut not supported on given pin")); - return; - } + // #if defined(SAMD21) && !defined(PIN_PA02) + // mp_raise_NotImplementedError(translate("No DAC on chip")); + // #else + // if (pin->number != PIN_PA02 + // #ifdef SAMD51 + // && pin->number != PIN_PA05 + // #endif + // ) { + // mp_raise_ValueError(translate("AnalogOut not supported on given pin")); + // return; + // } - self->channel = 0; - #ifdef SAMD51 - if (pin->number == PIN_PA05) { - self->channel = 1; - } - #endif + // self->channel = 0; + // #ifdef SAMD51 + // if (pin->number == PIN_PA05) { + // self->channel = 1; + // } + // #endif - #ifdef SAMD51 - hri_mclk_set_APBDMASK_DAC_bit(MCLK); - #endif + // #ifdef SAMD51 + // hri_mclk_set_APBDMASK_DAC_bit(MCLK); + // #endif - #ifdef SAMD21 - _pm_enable_bus_clock(PM_BUS_APBC, DAC); - #endif + // #ifdef SAMD21 + // _pm_enable_bus_clock(PM_BUS_APBC, DAC); + // #endif - // SAMD21: This clock should be <= 12 MHz, per datasheet section 47.6.3. - // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6. - _gclk_enable_channel(DAC_GCLK_ID, CONF_GCLK_DAC_SRC); + // // SAMD21: This clock should be <= 12 MHz, per datasheet section 47.6.3. + // // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6. + // _gclk_enable_channel(DAC_GCLK_ID, CONF_GCLK_DAC_SRC); - // Don't double init the DAC on the SAMD51 when both outputs are in use. We use the free state - // of each output pin to determine DAC state. - int32_t result = ERR_NONE; - #ifdef SAMD51 - if (!common_hal_mcu_pin_is_free(&pin_PA02) || !common_hal_mcu_pin_is_free(&pin_PA05)) { - #endif - // Fake the descriptor if the DAC is already initialized. - self->descriptor.device.hw = DAC; - #ifdef SAMD51 - } else { - #endif - result = dac_sync_init(&self->descriptor, DAC); - #ifdef SAMD51 - } - #endif - if (result != ERR_NONE) { - mp_raise_OSError(MP_EIO); - return; - } - claim_pin(pin); + // // Don't double init the DAC on the SAMD51 when both outputs are in use. We use the free state + // // of each output pin to determine DAC state. + // int32_t result = ERR_NONE; + // #ifdef SAMD51 + // if (!common_hal_mcu_pin_is_free(&pin_PA02) || !common_hal_mcu_pin_is_free(&pin_PA05)) { + // #endif + // // Fake the descriptor if the DAC is already initialized. + // self->descriptor.device.hw = DAC; + // #ifdef SAMD51 + // } else { + // #endif + // result = dac_sync_init(&self->descriptor, DAC); + // #ifdef SAMD51 + // } + // #endif + // if (result != ERR_NONE) { + // mp_raise_OSError(MP_EIO); + // return; + // } + // claim_pin(pin); - gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_B); + // gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_B); - dac_sync_enable_channel(&self->descriptor, self->channel); - #endif + // dac_sync_enable_channel(&self->descriptor, self->channel); + // #endif } bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { @@ -109,47 +99,47 @@ bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { } void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { - #if (defined(SAMD21) && defined(PIN_PA02)) || defined(SAMD51) - if (common_hal_analogio_analogout_deinited(self)) { - return; - } - dac_sync_disable_channel(&self->descriptor, self->channel); - reset_pin_number(PIN_PA02); - // Only deinit the DAC on the SAMD51 if both outputs are free. - #ifdef SAMD51 - if (common_hal_mcu_pin_is_free(&pin_PA02) && common_hal_mcu_pin_is_free(&pin_PA05)) { - #endif - dac_sync_deinit(&self->descriptor); - #ifdef SAMD51 - } - #endif - self->deinited = true; - // TODO(tannewt): Turn off the DAC clocks to save power. - #endif + // #if (defined(SAMD21) && defined(PIN_PA02)) || defined(SAMD51) + // if (common_hal_analogio_analogout_deinited(self)) { + // return; + // } + // dac_sync_disable_channel(&self->descriptor, self->channel); + // reset_pin_number(PIN_PA02); + // // Only deinit the DAC on the SAMD51 if both outputs are free. + // #ifdef SAMD51 + // if (common_hal_mcu_pin_is_free(&pin_PA02) && common_hal_mcu_pin_is_free(&pin_PA05)) { + // #endif + // dac_sync_deinit(&self->descriptor); + // #ifdef SAMD51 + // } + // #endif + // self->deinited = true; + // // TODO(tannewt): Turn off the DAC clocks to save power. + // #endif } void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value) { - #if defined(SAMD21) && !defined(PIN_PA02) - return; - #endif - // Input is 16 bit so make sure and set LEFTADJ to 1 so it takes the top - // bits. This is currently done in asf4_conf/*/hpl_dac_config.h. - dac_sync_write(&self->descriptor, self->channel, &value, 1); + // #if defined(SAMD21) && !defined(PIN_PA02) + // return; + // #endif + // // Input is 16 bit so make sure and set LEFTADJ to 1 so it takes the top + // // bits. This is currently done in asf4_conf/*/hpl_dac_config.h. + // dac_sync_write(&self->descriptor, self->channel, &value, 1); } void analogout_reset(void) { // audioout_reset also resets the DAC, and does a smooth ramp down to avoid clicks // if it was enabled, so do that instead if AudioOut is enabled. -#if CIRCUITPY_AUDIOIO - audioout_reset(); -#else - #ifdef SAMD21 - while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} - #endif - #ifdef SAMD51 - while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) {} - #endif - DAC->CTRLA.reg |= DAC_CTRLA_SWRST; -#endif +// #if CIRCUITPY_AUDIOIO +// audioout_reset(); +// #else +// #ifdef SAMD21 +// while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} +// #endif +// #ifdef SAMD51 +// while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) {} +// #endif +// DAC->CTRLA.reg |= DAC_CTRLA_SWRST; +// #endif } diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.h b/ports/stm32f4/common-hal/analogio/AnalogOut.h index 3710a7211a..f2952e9f96 100644 --- a/ports/stm32f4/common-hal/analogio/AnalogOut.h +++ b/ports/stm32f4/common-hal/analogio/AnalogOut.h @@ -29,13 +29,10 @@ #include "common-hal/microcontroller/Pin.h" -#include "hal/include/hal_dac_sync.h" - #include "py/obj.h" typedef struct { mp_obj_base_t base; - struct dac_sync_descriptor descriptor; uint8_t channel; bool deinited; } analogio_analogout_obj_t; diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk index 1d44feec9f..fc180f93e7 100644 --- a/ports/stm32f4/mpconfigport.mk +++ b/ports/stm32f4/mpconfigport.mk @@ -17,6 +17,7 @@ CIRCUITPY_MINIMAL_BUILD = 1 CIRCUITPY_BOARD = 1 CIRCUITPY_DIGITALIO = 1 +CIRCUITPY_ANALOGIO = 1 CIRCUITPY_MICROCONTROLLER = 1 CIRCUITPY_BUSIO = 1 CIRCUITPY_TIME = 1