diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index bd01f174ed..e38cac224a 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -168,7 +168,9 @@ endif SRC_ASF := \ gcc/gcc/startup_$(CHIP_FAMILY).c \ gcc/system_$(CHIP_FAMILY).c \ + hal/src/hal_adc_sync.c \ hal/src/hal_atomic.c \ + hal/src/hal_dac_sync.c \ hal/src/hal_delay.c \ hal/src/hal_flash.c \ hal/src/hal_i2c_m_sync.c \ @@ -177,7 +179,9 @@ SRC_ASF := \ hal/src/hal_spi_m_sync.c \ hal/src/hal_timer.c \ hal/src/hal_usb_device.c \ + hpl/adc/hpl_adc.c \ hpl/core/hpl_init.c \ + hpl/dac/hpl_dac.c \ hpl/gclk/hpl_gclk.c \ hpl/nvmctrl/hpl_nvmctrl.c \ hpl/pm/hpl_pm.c \ @@ -265,10 +269,10 @@ SRC_COMMON_HAL = \ os/__init__.c \ storage/__init__.c \ time/__init__.c \ -# analogio/__init__.c \ + analogio/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ - audiobusio/__init__.c \ +# audiobusio/__init__.c \ audiobusio/PDMIn.c \ audioio/__init__.c \ audioio/AudioOut.c \ diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_adc_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_adc_config.h new file mode 100644 index 0000000000..627f4e9bd4 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_adc_config.h @@ -0,0 +1,296 @@ +/* Auto-generated config file hpl_adc_config.h */ +#ifndef HPL_ADC_CONFIG_H +#define HPL_ADC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#ifndef CONF_ADC_0_ENABLE +#define CONF_ADC_0_ENABLE 1 +#endif + +// Basic Configuration + +// Conversion resolution +// <0x0=>12-bit +// <0x1=>16-bit (averaging must be enabled) +// <0x2=>10-bit +// <0x3=>8-bit +// Defines the bit resolution for the ADC sample values (RESSEL) +// adc_resolution +#ifndef CONF_ADC_0_RESSEL +#define CONF_ADC_0_RESSEL 0x0 +#endif + +// Reference Selection +// <0x0=>1.0V voltage reference +// <0x1=>1/1.48 VDDANA +// <0x2=>1/2 VDDANA (only for VDDANA > 2.0V) +// <0x3=>External reference A +// <0x4=>External reference B +// Select the reference for the ADC (REFSEL) +// adc_reference +#ifndef CONF_ADC_0_REFSEL +#define CONF_ADC_0_REFSEL 0x2 +#endif + +// Prescaler configuration +// <0x0=>Peripheral clock divided by 4 +// <0x1=>Peripheral clock divided by 8 +// <0x2=>Peripheral clock divided by 16 +// <0x3=>Peripheral clock divided by 32 +// <0x4=>Peripheral clock divided by 64 +// <0x5=>Peripheral clock divided by 128 +// <0x6=>Peripheral clock divided by 256 +// <0x7=>Peripheral clock divided by 512 +// These bits define the ADC clock relative to the peripheral clock (PRESCALER) +// adc_prescaler +#ifndef CONF_ADC_0_PRESCALER +#define CONF_ADC_0_PRESCALER 0x3 +#endif + +// Free Running Mode +// When enabled, the ADC is in free running mode and a new conversion will be initiated when a previous conversion completes. (FREERUN) +// adc_freerunning_mode +#ifndef CONF_ADC_0_FREERUN +#define CONF_ADC_0_FREERUN 0 +#endif + +// Differential Mode +// In differential mode, the voltage difference between the MUXPOS and MUXNEG inputs will be converted by the ADC. (DIFFMODE) +// adc_differential_mode +#ifndef CONF_ADC_0_DIFFMODE +#define CONF_ADC_0_DIFFMODE 0 +#endif + +// Positive Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x08=>ADC AIN8 pin +// <0x09=>ADC AIN9 pin +// <0x0A=>ADC AIN10 pin +// <0x0B=>ADC AIN11 pin +// <0x0C=>ADC AIN12 pin +// <0x0D=>ADC AIN13 pin +// <0x0E=>ADC AIN14 pin +// <0x0F=>ADC AIN15 pin +// <0x10=>ADC AIN16 pin +// <0x11=>ADC AIN17 pin +// <0x12=>ADC AIN18 pin +// <0x13=>ADC AIN19 pin +// <0x18=>Temperature reference +// <0x19=>Bandgap voltage +// <0x1A=>1/4 scaled core supply +// <0x1B=>1/4 scaled I/O supply +// <0x1C=>DAC output +// These bits define the Mux selection for the positive ADC input. (MUXPOS) +// adc_pinmux_positive +#ifndef CONF_ADC_0_MUXPOS +#define CONF_ADC_0_MUXPOS 0x02 +#endif + +// Negative Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x18=>Internal ground +// <0x19=>I/O ground +// These bits define the Mux selection for the negative ADC input. (MUXNEG) +// adc_pinmux_negative +#ifndef CONF_ADC_0_MUXNEG +#define CONF_ADC_0_MUXNEG 0x18 +#endif + +// + +// Advanced Configuration +// adc_advanced_settings +#ifndef CONF_ADC_0_ADVANCED_CONFIG +#define CONF_ADC_0_ADVANCED_CONFIG 0 +#endif + +// Run in standby +// Indicates whether the ADC will continue running in standby sleep mode or not (RUNSTDBY) +// adc_arch_runstdby +#ifndef CONF_ADC_0_RUNSTDBY +#define CONF_ADC_0_RUNSTDBY 0 +#endif + +// Debug Run +// If enabled, the ADC is running if the CPU is halted by an external debugger. (DBGRUN) +// adc_arch_dbgrun +#ifndef CONF_ADC_0_DBGRUN +#define CONF_ADC_0_DBGRUN 0 +#endif + +// Left-Adjusted Result +// When enabled, the ADC conversion result is left-adjusted in the RESULT register. The high byte of the 12-bit result will be present in the upper part of the result register. (LEFTADJ) +// adc_arch_leftadj +#ifndef CONF_ADC_0_LEFTADJ +#define CONF_ADC_0_LEFTADJ 0 +#endif + +// Reference Buffer Offset Compensation Enable +// The accuracy of the gain stage can be increased by enabling the reference buffer offset compensation. This will decrease the input impedance and thus increase the start-up time of the reference. (REFCOMP) +// adc_arch_refcomp +#ifndef CONF_ADC_0_REFCOMP +#define CONF_ADC_0_REFCOMP 0 +#endif + +// Digital Correction Logic Enabled +// When enabled, the ADC conversion result in the RESULT register is then corrected for gain and offset based on the values in the GAINCAL and OFFSETCAL registers. (CORREN) +// adc_arch_corren +#ifndef CONF_ADC_0_CORREN +#define CONF_ADC_0_CORREN 0 +#endif + +// Offset Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for offset error before being written to the Result register. (OFFSETCORR) +// adc_arch_offsetcorr +#ifndef CONF_ADC_0_OFFSETCORR +#define CONF_ADC_0_OFFSETCORR 0 +#endif + +// Gain Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for gain error before being written to the result register. (GAINCORR) +// adc_arch_gaincorr +#ifndef CONF_ADC_0_GAINCORR +#define CONF_ADC_0_GAINCORR 0 +#endif + +// Gain Factor Selection +// <0x0=>1x +// <0x1=>2x +// <0x2=>4x +// <0x3=>8x +// <0x4=>16x +// <0xF=>1/2x +// These bits set the gain factor of the ADC gain stage. (GAIN) +// adc_arch_gain +#ifndef CONF_ADC_0_GAIN +#define CONF_ADC_0_GAIN 0x0 +#endif + +// Adjusting Result / Division Coefficient <0-7> +// These bits define the division coefficient in 2n steps. (ADJRES) +// adc_arch_adjres +#ifndef CONF_ADC_0_ADJRES +#define CONF_ADC_0_ADJRES 0x0 +#endif + +// Number of Samples to be Collected +// <0x0=>1 sample +// <0x1=>2 samples +// <0x2=>4 samples +// <0x3=>8 samples +// <0x4=>16 samples +// <0x5=>32 samples +// <0x6=>64 samples +// <0x7=>128 samples +// <0x8=>256 samples +// <0x9=>512 samples +// <0xA=>1024 samples +// Define how many samples should be added together.The result will be available in the Result register (SAMPLENUM) +// adc_arch_samplenum +#ifndef CONF_ADC_0_SAMPLENUM +#define CONF_ADC_0_SAMPLENUM 0x0 +#endif + +// Sampling Time Length <0-63> +// These bits control the ADC sampling time in number of half CLK_ADC cycles, depending of the prescaler value, thus controlling the ADC input impedance. (SAMPLEN) +// adc_arch_samplen +#ifndef CONF_ADC_0_SAMPLEN +#define CONF_ADC_0_SAMPLEN 0 +#endif + +// Window Monitor Mode +// <0x0=>No window mode +// <0x1=>Mode 1: RESULT above lower threshold +// <0x2=>Mode 2: RESULT beneath upper threshold +// <0x3=>Mode 3: RESULT inside lower and upper threshold +// <0x4=>Mode 4: RESULT outside lower and upper threshold +// These bits enable and define the window monitor mode. (WINMODE) +// adc_arch_winmode +#ifndef CONF_ADC_0_WINMODE +#define CONF_ADC_0_WINMODE 0x0 +#endif + +// Window Monitor Lower Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINLT) +// adc_arch_winlt +#ifndef CONF_ADC_0_WINLT +#define CONF_ADC_0_WINLT 0 +#endif + +// Window Monitor Upper Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINUT) +// adc_arch_winut +#ifndef CONF_ADC_0_WINUT +#define CONF_ADC_0_WINUT 0 +#endif + +// Number of Input Channels Included in Scan <0-15> +// This register gives the number of input sources included in pin scan. The number of input sources included is INPUTSCAN + 1. 0 disables the input scan feature. (INPUTSCAN) +// adc_arch_inputscan +#ifndef CONF_ADC_0_INPUTSCAN +#define CONF_ADC_0_INPUTSCAN 0 +#endif + +// Positive Mux Setting Offset <0-15> +// When inputscan is enabled this value define the pin offset, which means that the actual input pin sampled is the muxpos pin + input offset. (INPUTOFFSET) +// adc_arch_inputoffset +#ifndef CONF_ADC_0_INPUTOFFSET +#define CONF_ADC_0_INPUTOFFSET 0 +#endif + +// + +// Event Control +// adc_arch_event_settings +#ifndef CONF_ADC_0_EVENT_CONFIG +#define CONF_ADC_0_EVENT_CONFIG 0 +#endif + +// Window Monitor Event Out +// Enables event output on window event (WINMONEO) +// adc_arch_winmoneo +#ifndef CONF_ADC_0_WINMONEO +#define CONF_ADC_0_WINMONEO 0 +#endif + +// Result Ready Event Out +// Enables event output on result ready event (RESRDEO) +// adc_arch_resrdyeo +#ifndef CONF_ADC_0_RESRDYEO +#define CONF_ADC_0_RESRDYEO 0 +#endif + +// Trigger Synchronization On Event +// Trigger a flush operation and a new conversion on event in (SYNCEI) +// adc_arch_syncei +#ifndef CONF_ADC_0_SYNCEI +#define CONF_ADC_0_SYNCEI 0 +#endif + +// Trigger Conversion On Event +// Trigger a conversion on event. (STARTEI) +// adc_arch_startei +#ifndef CONF_ADC_0_STARTEI +#define CONF_ADC_0_STARTEI 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_ADC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_dac_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_dac_config.h new file mode 100644 index 0000000000..42b893a359 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_dac_config.h @@ -0,0 +1,86 @@ +/* Auto-generated config file hpl_dac_config.h */ +#ifndef HPL_DAC_CONFIG_H +#define HPL_DAC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic configuration +// Reference Selection +// <0x00=> Internal 1.0v reference +// <0x01=> AVCC +// <0x02=> External reference +// dac_arch_refsel +#ifndef CONF_DAC_REFSEL +#define CONF_DAC_REFSEL 1 +#endif +// + +// Advanced Configuration +// dac_advanced_settings +#ifndef CONF_DAC_ADVANCED_CONFIG +#define CONF_DAC_ADVANCED_CONFIG 0 +#endif + +// Run in standby +// Indicates whether the DAC will continue running in standby sleep mode or not +// dac_arch_runstdby +#ifndef CONF_DAC_RUNSTDBY +#define CONF_DAC_RUNSTDBY 0 +#endif + +// Bypass DATABUF Write Protection +// Indicate whether DATABUF write protection is bypass +// dac_arch_bdwp +#ifndef CONF_DAC_BDWP +#define CONF_DAC_BDWP 0 +#endif + +// Voltage Pump Disable +// Indicate whether voltage pump is disable or not +// dac_arch_vpd +#ifndef CONF_DAC_VPD +#define CONF_DAC_VPD 0 +#endif + +// Left Adjusted Data +// Indicate how the data is adjusted in the Data and Data Buffer register +// dac_arch_leftadj +#ifndef CONF_DAC_LEFTADJ +#define CONF_DAC_LEFTADJ 1 +#endif + +// Internal Output Enable +// Indicate whether internal output is enable or not +// dac_arch_ioen +#ifndef CONF_DAC_IOEN +#define CONF_DAC_IOEN 0 +#endif + +// External Output Enable +// Indicate whether external output is enable or not +// dac_arch_eoen +#ifndef CONF_DAC_EOEN +#define CONF_DAC_EOEN 1 +#endif + +// + +// Event configuration +// Data Buffer Empty Event Output +// Indicate whether Data Buffer Empty Event is enabled and generated when the Data Buffer register is empty or not +// dac_arch_emptyeo +#ifndef CONF_DAC_EMPTYEO +#define CONF_DAC_EMPTYEO 0 +#endif + +// Start Conversion on Event Input +// Indicate whether Start Conversion is enabled and data are loaded from the Data Buffer register to the Data register upon event reception or not +// dac_arch_startei +#ifndef CONF_DAC_STARTEI +#define CONF_DAC_STARTEI 0 +#endif +// + +// <<< end of configuration section >>> + +#endif // HPL_DAC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_adc_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_adc_config.h new file mode 100644 index 0000000000..13d8151028 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_adc_config.h @@ -0,0 +1,303 @@ +/* Auto-generated config file hpl_adc_config.h */ +#ifndef HPL_ADC_CONFIG_H +#define HPL_ADC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#ifndef CONF_ADC_0_ENABLE +#define CONF_ADC_0_ENABLE 1 +#endif + +// Basic Configuration + +// Conversion Result Resolution +// <0x0=>12-bit +// <0x1=>16-bit (averaging must be enabled) +// <0x2=>10-bit +// <0x3=>8-bit +// Defines the bit resolution for the ADC sample values (RESSEL) +// adc_resolution +#ifndef CONF_ADC_0_RESSEL +#define CONF_ADC_0_RESSEL 0x0 +#endif + +// Reference Selection +// <0x0=>Internal bandgap reference +// <0x2=>1/2 VDDANA (only for VDDANA > 2.0V) +// <0x3=>VDDANA +// <0x4=>External reference A +// <0x5=>External reference B +// <0x6=>External reference C +// Select the reference for the ADC (REFSEL) +// adc_reference +#ifndef CONF_ADC_0_REFSEL +#define CONF_ADC_0_REFSEL 0x0 +#endif + +// Prescaler configuration +// <0x0=>Peripheral clock divided by 2 +// <0x1=>Peripheral clock divided by 4 +// <0x2=>Peripheral clock divided by 8 +// <0x3=>Peripheral clock divided by 16 +// <0x4=>Peripheral clock divided by 32 +// <0x5=>Peripheral clock divided by 64 +// <0x6=>Peripheral clock divided by 128 +// <0x7=>Peripheral clock divided by 256 +// These bits define the ADC clock relative to the peripheral clock (PRESCALER) +// adc_prescaler +#ifndef CONF_ADC_0_PRESCALER +#define CONF_ADC_0_PRESCALER 0x3 +#endif + +// Free Running Mode +// When enabled, the ADC is in free running mode and a new conversion will be initiated when a previous conversion completes. (FREERUN) +// adc_freerunning_mode +#ifndef CONF_ADC_0_FREERUN +#define CONF_ADC_0_FREERUN 0 +#endif + +// Differential Mode +// In differential mode, the voltage difference between the MUXPOS and MUXNEG inputs will be converted by the ADC. (DIFFMODE) +// adc_differential_mode +#ifndef CONF_ADC_0_DIFFMODE +#define CONF_ADC_0_DIFFMODE 0 +#endif + +// Positive Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x08=>ADC AIN8 pin +// <0x09=>ADC AIN9 pin +// <0x0A=>ADC AIN10 pin +// <0x0B=>ADC AIN11 pin +// <0x0C=>ADC AIN12 pin +// <0x0D=>ADC AIN13 pin +// <0x0E=>ADC AIN14 pin +// <0x0F=>ADC AIN15 pin +// <0x18=>1/4 scaled core supply +// <0x19=>1/4 Scaled VBAT Supply +// <0x1A=>1/4 scaled I/O supply +// <0x1B=>Bandgap voltage +// <0x1C=>Temperature reference (PTAT) +// <0x1D=>Temperature reference (CTAT) +// <0x1E=>DAC Output +// These bits define the Mux selection for the positive ADC input. (MUXPOS) +// adc_pinmux_positive +#ifndef CONF_ADC_0_MUXPOS +#define CONF_ADC_0_MUXPOS 0x0 +#endif + +// Negative Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x18=>Internal ground +// <0x19=>I/O ground +// These bits define the Mux selection for the negative ADC input. (MUXNEG) +// adc_pinmux_negative +#ifndef CONF_ADC_0_MUXNEG +#define CONF_ADC_0_MUXNEG 0x0 +#endif + +// + +// Advanced Configuration +// adc_advanced_settings +#ifndef CONF_ADC_0_ADVANCED +#define CONF_ADC_0_ADVANCED 0 +#endif + +// Run in standby +// Indicates whether the ADC will continue running in standby sleep mode or not (RUNSTDBY) +// adc_arch_runstdby +#ifndef CONF_ADC_0_RUNSTDBY +#define CONF_ADC_0_RUNSTDBY 0 +#endif + +// Debug Run +// If enabled, the ADC is running if the CPU is halted by an external debugger. (DBGRUN) +// adc_arch_dbgrun +#ifndef CONF_ADC_0_DBGRUN +#define CONF_ADC_0_DBGRUN 0 +#endif + +// On Demand Control +// Will keep the ADC peripheral running if requested by other peripherals (ONDEMAND) +// adc_arch_ondemand +#ifndef CONF_ADC_0_ONDEMAND +#define CONF_ADC_0_ONDEMAND 0 +#endif + +// Left-Adjusted Result +// When enabled, the ADC conversion result is left-adjusted in the RESULT register. The high byte of the 12-bit result will be present in the upper part of the result register. (LEFTADJ) +// adc_arch_leftadj +#ifndef CONF_ADC_0_LEFTADJ +#define CONF_ADC_0_LEFTADJ 0 +#endif + +// Reference Buffer Offset Compensation Enable +// The accuracy of the gain stage can be increased by enabling the reference buffer offset compensation. This will decrease the input impedance and thus increase the start-up time of the reference. (REFCOMP) +// adc_arch_refcomp +#ifndef CONF_ADC_0_REFCOMP +#define CONF_ADC_0_REFCOMP 0 +#endif + +// Comparator Offset Compensation Enable +// This bit indicates whether the Comparator Offset Compensation is enabled or not (OFFCOMP) +// adc_arch_offcomp +#ifndef CONF_ADC_0_OFFCOMP +#define CONF_ADC_0_OFFCOMP 0 +#endif + +// Digital Correction Logic Enabled +// When enabled, the ADC conversion result in the RESULT register is then corrected for gain and offset based on the values in the GAINCAL and OFFSETCAL registers. (CORREN) +// adc_arch_corren +#ifndef CONF_ADC_0_CORREN +#define CONF_ADC_0_CORREN 0 +#endif + +// Offset Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for offset error before being written to the Result register. (OFFSETCORR) +// adc_arch_offsetcorr +#ifndef CONF_ADC_0_OFFSETCORR +#define CONF_ADC_0_OFFSETCORR 0 +#endif + +// Gain Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for gain error before being written to the result register. (GAINCORR) +// adc_arch_gaincorr +#ifndef CONF_ADC_0_GAINCORR +#define CONF_ADC_0_GAINCORR 0 +#endif + +// Adjusting Result / Division Coefficient <0-7> +// These bits define the division coefficient in 2n steps. (ADJRES) +// adc_arch_adjres +#ifndef CONF_ADC_0_ADJRES +#define CONF_ADC_0_ADJRES 0x0 +#endif + +// Number of Samples to be Collected +// <0x0=>1 sample +// <0x1=>2 samples +// <0x2=>4 samples +// <0x3=>8 samples +// <0x4=>16 samples +// <0x5=>32 samples +// <0x6=>64 samples +// <0x7=>128 samples +// <0x8=>256 samples +// <0x9=>512 samples +// <0xA=>1024 samples +// Define how many samples should be added together.The result will be available in the Result register (SAMPLENUM) +// adc_arch_samplenum +#ifndef CONF_ADC_0_SAMPLENUM +#define CONF_ADC_0_SAMPLENUM 0x0 +#endif + +// Sampling Time Length <0-63> +// These bits control the ADC sampling time in number of half CLK_ADC cycles, depending of the prescaler value, thus controlling the ADC input impedance. (SAMPLEN) +// adc_arch_samplen +#ifndef CONF_ADC_0_SAMPLEN +#define CONF_ADC_0_SAMPLEN 0 +#endif + +// Window Monitor Mode +// <0x0=>No window mode +// <0x1=>Mode 1: RESULT above lower threshold +// <0x2=>Mode 2: RESULT beneath upper threshold +// <0x3=>Mode 3: RESULT inside lower and upper threshold +// <0x4=>Mode 4: RESULT outside lower and upper threshold +// These bits enable and define the window monitor mode. (WINMODE) +// adc_arch_winmode +#ifndef CONF_ADC_0_WINMODE +#define CONF_ADC_0_WINMODE 0x0 +#endif + +// Window Monitor Lower Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINLT) +// adc_arch_winlt +#ifndef CONF_ADC_0_WINLT +#define CONF_ADC_0_WINLT 0 +#endif + +// Window Monitor Upper Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINUT) +// adc_arch_winut +#ifndef CONF_ADC_0_WINUT +#define CONF_ADC_0_WINUT 0 +#endif + +// Bitmask for positive input sequence <0-4294967295> +// Use this parameter to input the bitmask for positive input sequence control (refer to datasheet for the device). +// adc_arch_seqen +#ifndef CONF_ADC_0_SEQEN +#define CONF_ADC_0_SEQEN 0x0 +#endif + +// + +// Event Control +// adc_arch_event_settings +#ifndef CONF_ADC_0_EVENT_CONTROL +#define CONF_ADC_0_EVENT_CONTROL 0 +#endif + +// Window Monitor Event Out +// Enables event output on window event (WINMONEO) +// adc_arch_winmoneo +#ifndef CONF_ADC_0_WINMONEO +#define CONF_ADC_0_WINMONEO 0 +#endif + +// Result Ready Event Out +// Enables event output on result ready event (RESRDEO) +// adc_arch_resrdyeo +#ifndef CONF_ADC_0_RESRDYEO +#define CONF_ADC_0_RESRDYEO 0 +#endif + +// Invert flush Event Signal +// Invert the flush event input signal (FLUSHINV) +// adc_arch_flushinv +#ifndef CONF_ADC_0_FLUSHINV +#define CONF_ADC_0_FLUSHINV 0 +#endif + +// Trigger Flush On Event +// Trigger an ADC pipeline flush on event (FLUSHEI) +// adc_arch_flushei +#ifndef CONF_ADC_0_FLUSHEI +#define CONF_ADC_0_FLUSHEI 0 +#endif + +// Invert Start Conversion Event Signal +// Invert the start conversion event input signal (STARTINV) +// adc_arch_startinv +#ifndef CONF_ADC_0_STARTINV +#define CONF_ADC_0_STARTINV 0 +#endif + +// Trigger Conversion On Event +// Trigger a conversion on event. (STARTEI) +// adc_arch_startei +#ifndef CONF_ADC_0_STARTEI +#define CONF_ADC_0_STARTEI 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_ADC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h new file mode 100644 index 0000000000..6e530941e7 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h @@ -0,0 +1,169 @@ +/* Auto-generated config file hpl_dac_config.h */ +#ifndef HPL_DAC_CONFIG_H +#define HPL_DAC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic configuration +// Reference Selection +// <0x00=> Unbuffered external voltage reference +// <0x01=> Voltage supply +// <0x02=> Buffered external voltage reference +// <0x03=> Internal bandgap reference +// dac_arch_refsel +#ifndef CONF_DAC_REFSEL +#define CONF_DAC_REFSEL 0 +#endif + +// Differential mode +// Indicates whether the differential mode is enabled or not +// dac_arch_diff +#ifndef CONF_DAC_DIFF +#define CONF_DAC_DIFF 0 +#endif +// + +// Advanced Configuration +// dac_advanced_settings +#ifndef CONF_DAC_ADVANCED_CONFIG +#define CONF_DAC_ADVANCED_CONFIG 0 +#endif + +// Debug Run +// Indicate whether running when CPU is halted +// adc_arch_dbgrun +#ifndef CONF_DAC_DBGRUN +#define CONF_DAC_DBGRUN 1 +#endif + +// Channel 0 configuration +// Left Adjusted Data +// Indicate how the data is adjusted in the Data and Data Buffer register +// dac0_arch_leftadj +#ifndef CONF_DAC0_LEFTADJ +#define CONF_DAC0_LEFTADJ 1 +#endif + +// Current control +// <0=> GCLK_DAC <= 1.2MHz (100kSPS) +// <1=> 1.2MHz < GCLK_DAC <= 6MHz (500kSPS) +// <2=> 6MHz < GCLK_DAC <= 12MHz (1MSPS) +// This defines the current in output buffer according to conversion rate +// dac0_arch_cctrl +#ifndef CONF_DAC0_CCTRL +#define CONF_DAC0_CCTRL 1 +#endif + +// Run in standby +// Indicates whether the DAC channel will continue running in standby sleep mode or not +// dac0_arch_runstdby +#ifndef CONF_DAC0_RUNSTDBY +#define CONF_DAC0_RUNSTDBY 0 +#endif + +// Dithering Mode +// Indicate whether dithering mode is enabled +// dac0_arch_ditrher +#ifndef CONF_DAC0_DITHER +#define CONF_DAC0_DITHER 0 +#endif + +// Refresh period <0x00-0xFF> +// This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us +// dac0_arch_refresh +#ifndef CONF_DAC0_REFRESH +#define CONF_DAC0_REFRESH 0 +#endif +// +// Channel 1 configuration +// Left Adjusted Data +// Indicate how the data is adjusted in the Data and Data Buffer register +// dac1_arch_leftadj +#ifndef CONF_DAC1_LEFTADJ +#define CONF_DAC1_LEFTADJ 1 +#endif + +// Current control +// <0=> GCLK_DAC <= 1.2MHz (100kSPS) +// <1=> 1.2MHz < GCLK_DAC <= 6MHz (500kSPS) +// <2=> 6MHz < GCLK_DAC <= 12MHz (1MSPS) +// This defines the current in output buffer according to conversion rate +// dac1_arch_cctrl +#ifndef CONF_DAC1_CCTRL +#define CONF_DAC1_CCTRL 1 +#endif + +// Run in standby +// Indicates whether the DAC channel will continue running in standby sleep mode or not +// dac1_arch_runstdby +#ifndef CONF_DAC1_RUNSTDBY +#define CONF_DAC1_RUNSTDBY 0 +#endif + +// Dithering Mode +// Indicate whether dithering mode is enabled +// dac1_arch_ditrher +#ifndef CONF_DAC1_DITHER +#define CONF_DAC1_DITHER 0 +#endif + +// Refresh period <0x00-0xFF> +// This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us +// dac1_arch_refresh +#ifndef CONF_DAC1_REFRESH +#define CONF_DAC1_REFRESH 0 +#endif +// + +// Event configuration +// Inversion of DAC 0 event +// <0=> Detection on rising edge pf the input event +// <1=> Detection on falling edge pf the input event +// This defines the edge detection of the input event +// dac_arch_invei0 +#ifndef CONF_DAC_INVEI0 +#define CONF_DAC_INVEI0 0 +#endif + +// Data Buffer of DAC 0 Empty Event Output +// Indicate whether Data Buffer Empty Event is enabled and generated when the Data Buffer register is empty or not +// dac_arch_emptyeo_0 +#ifndef CONF_DAC_EMPTYEO0 +#define CONF_DAC_EMPTYEO0 0 +#endif + +// Start Conversion Event Input DAC 0 +// Indicate whether Start input event is enabled +// dac_arch_startei_0 +#ifndef CONF_DAC_STARTEI0 +#define CONF_DAC_STARTEI0 0 +#endif +// Inversion of DAC 1 event +// <0=> Detection on rising edge pf the input event +// <1=> Detection on falling edge pf the input event +// This defines the edge detection of the input event +// dac_arch_invei1 +#ifndef CONF_DAC_INVEI1 +#define CONF_DAC_INVEI1 0 +#endif + +// Data Buffer of DAC 1 Empty Event Output +// Indicate whether Data Buffer Empty Event is enabled and generated when the Data Buffer register is empty or not +// dac_arch_emptyeo_1 +#ifndef CONF_DAC_EMPTYEO1 +#define CONF_DAC_EMPTYEO1 0 +#endif + +// Start Conversion Event Input DAC 1 +// Indicate whether Start input event is enabled +// dac_arch_startei_1 +#ifndef CONF_DAC_STARTEI1 +#define CONF_DAC_STARTEI1 0 +#endif + +// +// + +// <<< end of configuration section >>> + +#endif // HPL_DAC_CONFIG_H diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.c b/ports/atmel-samd/common-hal/analogio/AnalogIn.c index cbb9f5de51..c27d17f558 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogIn.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogIn.c @@ -33,19 +33,40 @@ #include "py/runtime.h" #include "py/binary.h" #include "py/mphal.h" + #include "shared-bindings/analogio/AnalogIn.h" -#include "asf/sam0/drivers/adc/adc.h" -#include "samd21_pins.h" +#include "atmel_start_pins.h" +#include "hal/include/hal_adc_sync.h" +#include "hpl/gclk/hpl_gclk_base.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, const mcu_pin_obj_t *pin) { - if (!pin->has_adc) { + uint8_t adc_index; + uint8_t adc_channel = 0xff; + for (adc_index = 0; adc_index < NUM_ADC_PER_PIN; adc_index++) { + // TODO(tannewt): Only use ADC0 on the SAMD51 when touch isn't being + // used. + if (pin->adc_input[adc_index] != 0xff) { + adc_channel = pin->adc_input[adc_index]; + break; + } + } + if (adc_channel == 0xff) { // No ADC function on that pin mp_raise_ValueError("Pin does not have ADC capabilities"); } claim_pin(pin); + gpio_set_pin_function(pin->pin, GPIO_PIN_FUNCTION_B); + + static Adc* adc_insts[] = ADC_INSTS; + self->instance = adc_insts[adc_index]; + self->channel = adc_channel; self->pin = pin; } @@ -68,21 +89,62 @@ 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. - struct adc_config config_adc; - adc_get_config_defaults(&config_adc); + // Turn the clocks on. + #ifdef SAMD51 + if (self->instance == ADC0) { + hri_mclk_set_APBDMASK_ADC0_bit(MCLK); + hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); + } else if (self->instance == ADC1) { + hri_mclk_set_APBDMASK_ADC1_bit(MCLK); + hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); + } + #endif - config_adc.reference = ADC_REFERENCE_INTVCC1; - config_adc.gain_factor = ADC_GAIN_FACTOR_DIV2; - config_adc.positive_input = self->pin->adc_input; - config_adc.resolution = ADC_RESOLUTION_12BIT; - // Default input clock is GCLK0 (48 MHz) - // 48Mhz / 32 = 1.5MHz. Max ADC clock is 2.1MHz - config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV32; + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBC, ADC); + _gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + #endif - struct adc_module adc_instance; - // ADC must have been disabled before adc_init() is called. - adc_init(&adc_instance, ADC, &config_adc); - adc_enable(&adc_instance); + struct adc_sync_descriptor adc; + adc_sync_init(&adc, self->instance, (void *)NULL); + adc_sync_set_reference(&adc, ADC_REFCTRL_REFSEL_INTVCC1_Val); + adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val); + + #ifdef SAMD21 + adc_sync_set_channel_gain(&adc, self->channel, ADC_INPUTCTRL_GAIN_DIV2_Val); + + // Load the factory calibration + hri_adc_set_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos); + // Bits 7:5 + uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; + // Bits 4:0 + linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; + hri_adc_set_CALIB_LINEARITY_CAL_bf(ADC, linearity); + #endif + + // SAMD51 has a CALIB register but doesn't have documented fuses for them. + #ifdef SAMD51 + uint8_t biasrefbuf; + uint8_t biasr2r; + uint8_t biascomp; + if (self->instance == ADC0) { + biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos; + biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos; + biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos; + } else { + biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos; + biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos; + biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos; + } + hri_adc_set_CALIB_BIASREFBUF_bf(self->instance, biasrefbuf); + hri_adc_set_CALIB_BIASR2R_bf(self->instance, biasr2r); + hri_adc_set_CALIB_BIASCOMP_bf(self->instance, biascomp); + #endif + + adc_sync_enable_channel(&adc, self->channel); + + // We need to set the inputs because the above channel enable only enables the ADC. + adc_sync_set_inputs(&adc, self->channel, ADC_INPUTCTRL_MUXNEG_GND_Val, self->channel); // Read twice and discard first result, as recommended in section 14 of // http://www.atmel.com/images/Atmel-42645-ADC-Configurations-with-Examples_ApplicationNote_AT11481.pdf @@ -90,28 +152,13 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { // like voltage reference / ADC channel change" // Empirical observation shows the first reading is quite different than subsequent ones. - uint16_t data; - enum status_code status; + uint16_t value; + adc_sync_read_channel(&adc, self->channel, ((uint8_t*) &value), 2); + adc_sync_read_channel(&adc, self->channel, ((uint8_t*) &value), 2); - adc_start_conversion(&adc_instance); - do { - status = adc_read(&adc_instance, &data); - } while (status == STATUS_BUSY); - if (status == STATUS_ERR_OVERFLOW) { - mp_raise_RuntimeError("ADC result overwritten before reading"); - } - - adc_start_conversion(&adc_instance); - do { - status = adc_read(&adc_instance, &data); - } while (status == STATUS_BUSY); - if (status == STATUS_ERR_OVERFLOW) { - mp_raise_RuntimeError("ADC result overwritten before reading"); - } - - adc_disable(&adc_instance); - // Scale to 16 bits. In the future we might make this be this be under API control. - return data * 16; + adc_sync_deinit(&adc); + // Shift the value to be 16 bit. + return value << 4; } float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.h b/ports/atmel-samd/common-hal/analogio/AnalogIn.h index 36fb14a92c..0b13ba7e14 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogIn.h +++ b/ports/atmel-samd/common-hal/analogio/AnalogIn.h @@ -34,6 +34,8 @@ typedef struct { mp_obj_base_t base; const mcu_pin_obj_t * pin; + Adc* instance; + uint8_t channel; } analogio_analogin_obj_t; void analogin_reset(void); diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c index d547873918..1d53781b16 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -31,32 +31,72 @@ #include "py/runtime.h" #include "shared-bindings/analogio/AnalogOut.h" +#include "shared-bindings/microcontroller/Pin.h" -#include "asf/sam0/drivers/dac/dac.h" -#include "samd21_pins.h" +#include "atmel_start_pins.h" +#include "hal/include/hal_dac_sync.h" +#include "hpl/gclk/hpl_gclk_base.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif + +#ifdef SAMD51 +#include "samd51_pins.h" +#endif void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin) { - if (pin->pin != PIN_PA02) { + if (pin->pin != PIN_PA02 + #ifdef SAMD51 + && pin->pin != PIN_PA05 + #endif + ) { mp_raise_ValueError("AnalogOut not supported on given pin"); return; } - struct dac_config config_dac; - dac_get_config_defaults(&config_dac); - config_dac.reference = DAC_REFERENCE_AVCC; - enum status_code status = dac_init(&self->dac_instance, DAC, &config_dac); - if (status != STATUS_OK) { + + self->channel = 0; + #ifdef SAMD51 + if (pin->pin == PIN_PA05) { + self->channel = 1; + } + #endif + + #ifdef SAMD51 + hri_mclk_set_APBDMASK_DAC_bit(MCLK); + hri_gclk_write_PCHCTRL_reg(GCLK, DAC_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK5_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); + #endif + + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBC, DAC); + _gclk_enable_channel(DAC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + #endif + + // 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); - struct dac_chan_config config_analogout_chan; - dac_chan_get_config_defaults(&config_analogout_chan); - dac_chan_set_config(&self->dac_instance, DAC_CHANNEL_0, &config_analogout_chan); - dac_chan_enable(&self->dac_instance, DAC_CHANNEL_0); + gpio_set_pin_function(pin->pin, GPIO_PIN_FUNCTION_B); - dac_enable(&self->dac_instance); + dac_sync_enable_channel(&self->descriptor, self->channel); } bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { @@ -67,14 +107,35 @@ void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { if (common_hal_analogio_analogout_deinited(self)) { return; } - dac_disable(&self->dac_instance); - dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0); + dac_sync_disable_channel(&self->descriptor, self->channel); reset_pin(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. } void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value) { - // Input is 16 bit but we only support 10 bit so we shift the input. - dac_chan_write(&self->dac_instance, DAC_CHANNEL_0, value >> 6); + // Input is 16 bit so make sure and set LEFTADJ to 1 to 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) { + #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; + + // TODO(tannewt): Turn off the DAC clocks to save power. } diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.h b/ports/atmel-samd/common-hal/analogio/AnalogOut.h index b60658da69..3710a7211a 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.h +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.h @@ -29,14 +29,17 @@ #include "common-hal/microcontroller/Pin.h" -#include "asf/sam0/drivers/dac/dac.h" +#include "hal/include/hal_dac_sync.h" #include "py/obj.h" typedef struct { mp_obj_base_t base; - struct dac_module dac_instance; + struct dac_sync_descriptor descriptor; + uint8_t channel; bool deinited; } analogio_analogout_obj_t; +void analogout_reset(void); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 2c8a66a88f..a78210a566 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -212,14 +212,13 @@ extern const struct _mp_obj_module_t usb_hid_module; // Disabled for now. // { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, -// { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, - // { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, #define MICROPY_PORT_BUILTIN_MODULES \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 8c8045c001..5d483b7bf4 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -43,7 +43,8 @@ #include "hri/hri_rstc_d51.h" #endif - +#include "common-hal/analogio/AnalogIn.h" +#include "common-hal/analogio/AnalogOut.h" #include "common-hal/microcontroller/Pin.h" #include "tick.h" @@ -207,16 +208,14 @@ void reset_port(void) { // pulseout_reset(); // pwmout_reset(); // #endif -// -// analogin_reset(); -// + + analogin_reset(); + // #ifdef CIRCUITPY_GAMEPAD_TICKS // gamepad_reset(); // #endif // -// // Wait for the DAC to sync then reset. -// while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} -// DAC->CTRLA.reg |= DAC_CTRLA_SWRST; + analogout_reset(); reset_all_pins(); // @@ -276,9 +275,9 @@ void reset_port(void) { */ __attribute__((used)) void HardFault_Handler(void) { - while (true) { + while (true) { asm(""); - } + } for (uint32_t i = 0; i < 100000; i++) { asm("noop;"); }