diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index beefd337..470cc112 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,17 @@ enum analogPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), #endif +#ifdef CONFIG_DAC + +#undef DAC0 +#undef DAC1 +#undef DAC2 +#undef DAC3 +#define DAC_ENUMS(n, p, i) DAC ## i = i, +enum dacPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_ENUMS) NUM_OF_DACS }; + +#endif + void interrupts(void); void noInterrupts(void); @@ -112,6 +124,9 @@ int digitalPinToInterrupt(pin_size_t pin); #define portOutputRegister(x) (x) #define portInputRegister(x) (x) +void analogReadResolution(int bits); +void analogWriteResolution(int bits); + #include #ifdef __cplusplus #include @@ -119,6 +134,7 @@ int digitalPinToInterrupt(pin_size_t pin); #include #include #include +#include // Allow namespace-less operations if Arduino.h is included using namespace arduino; diff --git a/cores/arduino/overloads.h b/cores/arduino/overloads.h new file mode 100644 index 00000000..5670b270 --- /dev/null +++ b/cores/arduino/overloads.h @@ -0,0 +1,9 @@ +#ifdef CONFIG_DAC + +void analogWrite(enum dacPins pinNumber, int value); + +#endif + +// In c++ mode, we also provide analogReadResolution and analogWriteResolution getters +int analogReadResolution(); +int analogWriteResolution(); \ No newline at end of file diff --git a/cores/arduino/zephyrCommon.cpp b/cores/arduino/zephyrCommon.cpp index 8dc0c84d..2f1cc5cc 100644 --- a/cores/arduino/zephyrCommon.cpp +++ b/cores/arduino/zephyrCommon.cpp @@ -163,7 +163,7 @@ size_t pwm_pin_index(pin_size_t pinNumber) { DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)), #define ADC_CH_CFG(n,p,i) arduino_adc[i].channel_cfg, -const struct adc_dt_spec arduino_adc[] = +static const struct adc_dt_spec arduino_adc[] = { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, ADC_DT_SPEC) }; /* io-channel-pins node provides a mapping digital pin numbers to adc channels */ @@ -184,6 +184,28 @@ size_t analog_pin_index(pin_size_t pinNumber) { #endif //CONFIG_ADC +#ifdef CONFIG_DAC + +#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), dac)) + +#define DAC_NODE DT_PHANDLE(DT_PATH(zephyr_user), dac) +#define DAC_RESOLUTION DT_PROP(DT_PATH(zephyr_user), dac_resolution) +static const struct device *const dac_dev = DEVICE_DT_GET(DAC_NODE); + +#define DAC_CHANNEL_DEFINE(n, p, i) \ + { \ + .channel_id = DT_PROP_BY_IDX(n, p, i), \ + .resolution = DAC_RESOLUTION, \ + .buffered = true, \ + }, + +static const struct dac_channel_cfg dac_ch_cfg[] = + { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_CHANNEL_DEFINE) }; + +#endif + +#endif //CONFIG_DAC + static unsigned int irq_key; static bool interrupts_disabled = false; } @@ -276,6 +298,16 @@ unsigned long micros(void) { unsigned long millis(void) { return k_uptime_get_32(); } +#if defined(CONFIG_DAC) || defined(CONFIG_PWM) +static int _analog_write_resolution = 8; +void analogWriteResolution(int bits) { + _analog_write_resolution = bits; +} +int analogWriteResolution() { + return _analog_write_resolution; +} +#endif + #ifdef CONFIG_PWM void analogWrite(pin_size_t pinNumber, int value) @@ -290,6 +322,8 @@ void analogWrite(pin_size_t pinNumber, int value) return; } + value = map(value, 0, 1 << _analog_write_resolution, 0, arduino_pwm[idx].period); + if (((uint32_t)value) > arduino_pwm[idx].period) { value = arduino_pwm[idx].period; } else if (value < 0) { @@ -305,6 +339,21 @@ void analogWrite(pin_size_t pinNumber, int value) #endif +#ifdef CONFIG_DAC +void analogWrite(enum dacPins dacName, int value) +{ + if (dacName >= NUM_OF_DACS) { + return; + } + + dac_channel_setup(dac_dev, &dac_ch_cfg[dacName]); + + const int max_dac_value = 1U << dac_ch_cfg[dacName].resolution; + dac_write_value(dac_dev, dac_ch_cfg[dacName].channel_id, map(value, 0, 1 << _analog_write_resolution, 0, max_dac_value)); +} +#endif + + #ifdef CONFIG_ADC void analogReference(uint8_t mode) diff --git a/loader/boards/arduino_giga_r1_m7.conf b/loader/boards/arduino_giga_r1_m7.conf index 03ad44fd..b3e8280b 100644 --- a/loader/boards/arduino_giga_r1_m7.conf +++ b/loader/boards/arduino_giga_r1_m7.conf @@ -18,6 +18,7 @@ CONFIG_LLEXT_HEAP_SIZE=128 CONFIG_FPU=y CONFIG_ADC=y +CONFIG_DAC=y CONFIG_PWM=y CONFIG_DMA=y diff --git a/loader/boards/arduino_giga_r1_m7.overlay b/loader/boards/arduino_giga_r1_m7.overlay index fef941a7..03c2ae54 100644 --- a/loader/boards/arduino_giga_r1_m7.overlay +++ b/loader/boards/arduino_giga_r1_m7.overlay @@ -57,26 +57,80 @@ clock-frequency = ; }; -// XCLK as PWM from PJ9 &timers1 { status = "okay"; - st,prescaler = <0>; + st,prescaler = <4>; - cam_clock_pwm: pwm { + pwm1: pwm { status = "okay"; - pinctrl-0 = <&tim1_ch3_pj9>; + pinctrl-0 = <&tim1_ch3_pj9 &tim1_ch1_pk1 &tim1_ch2_pj11>; pinctrl-names = "default"; }; }; -&cam_clock_pwm { - /* ...then use the pwmclock node to start the clock generation */ +&timers2 { + status = "okay"; + st,prescaler = <100>; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch4_pa3 &tim2_ch3_pa2>; + pinctrl-names = "default"; + }; +}; + +&timers3 { + status = "okay"; + st,prescaler = <100>; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch2_pa7 &tim3_ch1_pb4>; + pinctrl-names = "default"; + }; +}; + +&timers4 { + status = "okay"; + st,prescaler = <100>; + + pwm4: pwm { + status = "okay"; + pinctrl-0 = <&tim4_ch2_pd13 &tim4_ch3_pb8 &tim4_ch4_pb9>; + pinctrl-names = "default"; + }; +}; + +&timers8 { + status = "okay"; + st,prescaler = <100>; + + pwm8: pwm { + status = "okay"; + pinctrl-0 = <&tim8_ch1_pj8 &tim8_ch2_pj10>; + pinctrl-names = "default"; + }; +}; + +&timers12 { + status = "okay"; + st,prescaler = <100>; + + pwm12: pwm { + status = "okay"; + pinctrl-0 = <&tim12_ch1_ph6>; + pinctrl-names = "default"; + }; +}; + +&pwm1 { + /* Use the pwmclock node to start the clock generation */ pwmclock: pwmclock { status = "okay"; compatible = "pwm-clock"; clock-frequency = <0>; #clock-cells = <1>; - pwms = <&cam_clock_pwm 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>; + pwms = <&pwm1 3 PWM_HZ(12000000) PWM_POLARITY_NORMAL>; }; }; @@ -422,14 +476,18 @@ <&gpioe 3 GPIO_ACTIVE_LOW>; pwm-pin-gpios = <&gpioj 9 0>, - <&arduino_header 6 0>, - <&arduino_header 5 0>, - <&arduino_header 17 0>, - <&arduino_header 12 0>, - <&arduino_header 2 0>, - <&arduino_header 3 0>, + <&arduino_header 8 0>, <&arduino_header 9 0>, - <&arduino_header 10 0>; + <&arduino_header 10 0>, + <&arduino_header 11 0>, + <&arduino_header 12 0>, + <&arduino_header 13 0>, + <&arduino_header 14 0>, + <&arduino_header 15 0>, + <&arduino_header 16 0>, + <&arduino_header 17 0>, + <&arduino_header 18 0>, + <&arduino_header 19 0>; adc-pin-gpios = <&gpioc 4 0>, <&gpioc 5 0>, @@ -450,7 +508,19 @@ cdc-acm = <&cdc_acm_uart0>; i2cs = <&i2c2>, <&i2c4>, <&i2c1>; spis = <&spi1>, <&spi5>; - pwms = <&cam_clock_pwm 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>; + pwms = <&pwm1 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>, + <&pwm2 4 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm2 3 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm8 1 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm3 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm4 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm3 1 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm4 3 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm4 4 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm1 1 PWM_HZ(5000) PWM_POLARITY_NORMAL>, + <&pwm8 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm1 2 PWM_HZ(5000) PWM_POLARITY_NORMAL>, + <&pwm12 1 PWM_HZ(500) PWM_POLARITY_NORMAL>; io-channels = <&adc1 4>, <&adc1 8>, @@ -466,5 +536,9 @@ <&adc1 0>, <&adc1 18>, <&adc1 19>; + + dac = <&dac1>; + dac-channels = <1>, <2>; + dac-resolution = <12>; }; };