Skip to content

Commit 96ad455

Browse files
committed
analogWrite: implement DAC pins
1 parent 90d578a commit 96ad455

File tree

4 files changed

+75
-0
lines changed

4 files changed

+75
-0
lines changed

Diff for: cores/arduino/Arduino.h

+16
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <zephyr/drivers/gpio.h>
1313
#include <zephyr/drivers/pwm.h>
1414
#include <zephyr/drivers/adc.h>
15+
#include <zephyr/drivers/dac.h>
1516
#include <zephyr/drivers/i2c.h>
1617
#include <math.h>
1718

@@ -102,6 +103,17 @@ enum analogPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user),
102103

103104
#endif
104105

106+
#ifdef CONFIG_DAC
107+
108+
#undef DAC0
109+
#undef DAC1
110+
#undef DAC2
111+
#undef DAC3
112+
#define DAC_ENUMS(n, p, i) DAC ## i = i,
113+
enum dacPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_ENUMS) NUM_OF_DACS };
114+
115+
#endif
116+
105117
void interrupts(void);
106118
void noInterrupts(void);
107119

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

127+
void analogReadResolution(int bits);
128+
void analogWriteResolution(int bits);
129+
115130
#include <variant.h>
116131
#ifdef __cplusplus
117132
#include <SerialUSB.h>
118133
#include <zephyrSerial.h>
119134
#include <strings.h>
120135
#include <api/itoa.h>
121136
#include <time_macros.h>
137+
#include <overloads.h>
122138

123139
// Allow namespace-less operations if Arduino.h is included
124140
using namespace arduino;

Diff for: cores/arduino/overloads.h

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifdef CONFIG_DAC
2+
3+
void analogWrite(enum dacPins pinNumber, int value);
4+
5+
#endif
6+
7+
// In c++ mode, we also provide analogReadResolution and analogWriteResolution getters
8+
int analogReadResolution();
9+
int analogWriteResolution();

Diff for: cores/arduino/zephyrCommon.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,28 @@ size_t analog_pin_index(pin_size_t pinNumber) {
184184

185185
#endif //CONFIG_ADC
186186

187+
#ifdef CONFIG_DAC
188+
189+
#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), dac))
190+
191+
#define DAC_NODE DT_PHANDLE(DT_PATH(zephyr_user), dac)
192+
#define DAC_RESOLUTION DT_PROP(DT_PATH(zephyr_user), dac_resolution)
193+
static const struct device *const dac_dev = DEVICE_DT_GET(DAC_NODE);
194+
195+
#define DAC_CHANNEL_DEFINE(n, p, i) \
196+
{ \
197+
.channel_id = DT_PROP_BY_IDX(n, p, i), \
198+
.resolution = DAC_RESOLUTION, \
199+
.buffered = true, \
200+
},
201+
202+
static const struct dac_channel_cfg dac_ch_cfg[] =
203+
{ DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_CHANNEL_DEFINE) };
204+
205+
#endif
206+
207+
#endif //CONFIG_DAC
208+
187209
static unsigned int irq_key;
188210
static bool interrupts_disabled = false;
189211
}
@@ -276,6 +298,16 @@ unsigned long micros(void) {
276298

277299
unsigned long millis(void) { return k_uptime_get_32(); }
278300

301+
#if defined(CONFIG_DAC) || defined(CONFIG_PWM)
302+
static int _analog_write_resolution = 8;
303+
void analogWriteResolution(int bits) {
304+
_analog_write_resolution = bits;
305+
}
306+
int analogWriteResolution() {
307+
return _analog_write_resolution;
308+
}
309+
#endif
310+
279311
#ifdef CONFIG_PWM
280312

281313
void analogWrite(pin_size_t pinNumber, int value)
@@ -290,6 +322,8 @@ void analogWrite(pin_size_t pinNumber, int value)
290322
return;
291323
}
292324

325+
value = map(value, 0, 1 << _analog_write_resolution, 0, arduino_pwm[idx].period);
326+
293327
if (((uint32_t)value) > arduino_pwm[idx].period) {
294328
value = arduino_pwm[idx].period;
295329
} else if (value < 0) {
@@ -305,6 +339,21 @@ void analogWrite(pin_size_t pinNumber, int value)
305339

306340
#endif
307341

342+
#ifdef CONFIG_DAC
343+
void analogWrite(enum dacPins dacName, int value)
344+
{
345+
if (dacName >= NUM_OF_DACS) {
346+
return;
347+
}
348+
349+
dac_channel_setup(dac_dev, &dac_ch_cfg[dacName]);
350+
351+
const int max_dac_value = 1U << dac_ch_cfg[dacName].resolution;
352+
dac_write_value(dac_dev, dac_ch_cfg[dacName].channel_id, map(value, 0, 1 << _analog_write_resolution, 0, max_dac_value));
353+
}
354+
#endif
355+
356+
308357
#ifdef CONFIG_ADC
309358

310359
void analogReference(uint8_t mode)

Diff for: loader/boards/arduino_giga_r1_m7.conf

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ CONFIG_LLEXT_HEAP_SIZE=128
1818
CONFIG_FPU=y
1919

2020
CONFIG_ADC=y
21+
CONFIG_DAC=y
2122
CONFIG_PWM=y
2223

2324
CONFIG_DMA=y

0 commit comments

Comments
 (0)