Skip to content

Fix analogWrite() #46

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
Jan 24, 2025
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
16 changes: 16 additions & 0 deletions cores/arduino/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/dac.h>
#include <zephyr/drivers/i2c.h>
#include <math.h>

Expand Down Expand Up @@ -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);

Expand All @@ -112,13 +124,17 @@ int digitalPinToInterrupt(pin_size_t pin);
#define portOutputRegister(x) (x)
#define portInputRegister(x) (x)

void analogReadResolution(int bits);
void analogWriteResolution(int bits);

#include <variant.h>
#ifdef __cplusplus
#include <SerialUSB.h>
#include <zephyrSerial.h>
#include <strings.h>
#include <api/itoa.h>
#include <time_macros.h>
#include <overloads.h>

// Allow namespace-less operations if Arduino.h is included
using namespace arduino;
Expand Down
9 changes: 9 additions & 0 deletions cores/arduino/overloads.h
Original file line number Diff line number Diff line change
@@ -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();
51 changes: 50 additions & 1 deletion cores/arduino/zephyrCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions loader/boards/arduino_giga_r1_m7.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ CONFIG_LLEXT_HEAP_SIZE=128
CONFIG_FPU=y

CONFIG_ADC=y
CONFIG_DAC=y
CONFIG_PWM=y

CONFIG_DMA=y
Expand Down
104 changes: 89 additions & 15 deletions loader/boards/arduino_giga_r1_m7.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,80 @@
clock-frequency = <I2C_BITRATE_FAST>;
};

// 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>;
};
};

Expand Down Expand Up @@ -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>,
Expand All @@ -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>,
Expand All @@ -466,5 +536,9 @@
<&adc1 0>,
<&adc1 18>,
<&adc1 19>;

dac = <&dac1>;
dac-channels = <1>, <2>;
dac-resolution = <12>;
};
};
Loading