Skip to content

Commit 2594cc1

Browse files
dimitrije-lilicvladislav-pejic
authored andcommitted
drivers: adc: max32: Support for RTIO stream
Updated MAX32 driver with RTIO stream functionality. Signed-off-by: Dimitrije Lilic <dimitrije.lilic@orioninc.com>
1 parent f231fa5 commit 2594cc1

File tree

4 files changed

+151
-10
lines changed

4 files changed

+151
-10
lines changed

drivers/adc/Kconfig.max32

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,10 @@ config ADC_MAX32
1010
select PINCTRL
1111
help
1212
Enable ADC driver for ADI MAX32xxx MCUs.
13+
14+
config ADC_MAX32_STREAM
15+
bool "Use FIFO to stream data"
16+
select ADC_ASYNC
17+
depends on HAS_ADC_MAX32_REVB_ME18
18+
help
19+
Use this configuration option to enable streaming ADC data via RTIO.

drivers/adc/adc_max32.c

Lines changed: 139 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <zephyr/drivers/adc.h>
1313
#include <zephyr/drivers/pinctrl.h>
1414
#include <zephyr/drivers/clock_control/adi_max32_clock_control.h>
15+
#include <zephyr/sys/util.h>
16+
#include <zephyr/sys/byteorder.h>
1517

1618
#include <zephyr/logging/log.h>
1719
LOG_MODULE_REGISTER(adc_max32, CONFIG_ADC_LOG_LEVEL);
@@ -24,6 +26,16 @@ LOG_MODULE_REGISTER(adc_max32, CONFIG_ADC_LOG_LEVEL);
2426
/* reference voltage for the ADC */
2527
#define MAX32_ADC_VREF_MV DT_INST_PROP(0, vref_mv)
2628

29+
#define ADC_MAX32_INT_FIFO_LVL_MSK BIT(7)
30+
#define ADC_MAX32_SAMPLE_SIZE 2
31+
#define ADC_MAX32_BYTE_COUNT 16
32+
33+
enum adc_max32_fifo_format {
34+
ADC_MAX32_DATA_STATUS_FIFO,
35+
ADC_MAX32_DATA_ONLY_FIFO,
36+
ADC_MAX32_RAW_DATA_ONLY_FIFO,
37+
};
38+
2739
struct max32_adc_config {
2840
uint8_t channel_count;
2941
mxc_adc_regs_t *regs;
@@ -44,8 +56,45 @@ struct max32_adc_data {
4456
uint32_t channels;
4557
uint32_t sample_channels;
4658
const uint8_t resolution;
59+
#ifdef CONFIG_ADC_MAX32_STREAM
60+
struct rtio_iodev_sqe *sqe;
61+
struct rtio *rtio_ctx;
62+
struct rtio_iodev *iodev;
63+
uint64_t timestamp;
64+
struct rtio *r_cb;
65+
uint32_t adc_sample;
66+
uint8_t data_ready_gpio;
67+
uint8_t no_mem;
68+
struct k_timer sample_timer;
69+
const struct adc_sequence *sequence;
70+
uint8_t fifo_full_irq;
71+
#endif /* CONFIG_ADC_MAX32_STREAM */
72+
};
73+
74+
75+
#ifdef CONFIG_ADC_MAX32_STREAM
76+
/** MAX32 qscale modes */
77+
enum max32_qscale_modes {
78+
MAX32_12B_MODE = 0,
79+
};
80+
81+
struct adc_max32_fifo_config {
82+
enum adc_max32_fifo_format fifo_format;
83+
uint16_t fifo_samples;
4784
};
4885

86+
struct adc_max32_fifo_data {
87+
uint16_t is_fifo: 1;
88+
uint16_t max32_qscale_mode: 1;
89+
uint16_t diff_mode: 1;
90+
uint16_t res: 4;
91+
uint16_t fifo_byte_count: 5;
92+
uint16_t sample_set_size: 4;
93+
uint16_t vref_mv;
94+
uint64_t timestamp;
95+
} __attribute__((__packed__));
96+
#endif /* CONFIG_ADC_MAX32_STREAM */
97+
4998
#ifdef CONFIG_ADC_ASYNC
5099
static void adc_complete_cb(void *req, int error)
51100
{
@@ -54,6 +103,16 @@ static void adc_complete_cb(void *req, int error)
54103
}
55104
#endif /* CONFIG_ADC_ASYNC */
56105

106+
#ifdef CONFIG_ADC_MAX32_STREAM
107+
static void adc_complete_rtio_cb(const struct device *dev)
108+
{
109+
struct max32_adc_data *data = dev->data;
110+
struct rtio_iodev_sqe *iodev_sqe = data->sqe;
111+
112+
rtio_iodev_sqe_ok(iodev_sqe, 0);
113+
}
114+
#endif /* CONFIG_ADC_MAX32_STREAM */
115+
57116
static void adc_max32_start_channel(const struct device *dev)
58117
{
59118
struct max32_adc_data *data = dev->data;
@@ -150,8 +209,6 @@ static int adc_max32_read(const struct device *dev, const struct adc_sequence *s
150209
return ret;
151210
}
152211

153-
<<<<<<< Updated upstream
154-
=======
155212
#ifdef CONFIG_ADC_MAX32_STREAM
156213
static int start_read_stream(const struct device *dev, const struct adc_sequence *seq)
157214
{
@@ -193,7 +250,7 @@ static int start_read_stream(const struct device *dev, const struct adc_sequence
193250
void adc_max32_submit_stream(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
194251
{
195252
struct max32_adc_data *data = (struct max32_adc_data *)dev->data;
196-
const struct adc_sequence *sequence = (const struct adc_sequence *)iodev_sqe->sqe.userdata;
253+
const struct adc_read_config *read_cfg = iodev_sqe->sqe.iodev->data;
197254
int rc;
198255

199256
if (data->no_mem == 1) {
@@ -203,14 +260,13 @@ void adc_max32_submit_stream(const struct device *dev, struct rtio_iodev_sqe *io
203260
data->sqe = iodev_sqe;
204261

205262
adc_context_lock(&data->ctx, false, NULL);
206-
rc = start_read_stream(dev, sequence);
263+
rc = start_read_stream(dev, read_cfg->sequence);
207264

208265
adc_context_release(&data->ctx, rc);
209266

210267
if (rc < 0) {
211268
LOG_ERR("Error starting conversion (%d)", rc);
212269
}
213-
214270
}
215271

216272
static const uint32_t adc_max32_resolution[] = {
@@ -296,17 +352,16 @@ static int adc_max32_decoder_decode(const uint8_t *buffer, uint32_t channel, uin
296352
enc_data->max32_qscale_mode, enc_data->diff_mode,
297353
enc_data->vref_mv, data->shift);
298354

299-
300355
sample_num++;
301356
*fit += sample_set_size;
302357
count++;
303358
}
304359

305360
return 0;
361+
306362
}
307363
#endif /* CONFIG_ADC_MAX32_STREAM */
308364

309-
>>>>>>> Stashed changes
310365
#ifdef CONFIG_ADC_ASYNC
311366
static int adc_max32_read_async(const struct device *dev, const struct adc_sequence *seq,
312367
struct k_poll_signal *async)
@@ -433,6 +488,73 @@ static int adc_max32_init(const struct device *dev)
433488
return 0;
434489
}
435490

491+
#ifdef CONFIG_ADC_MAX32_STREAM
492+
static void adc_max32_rtio_isr(const struct device *dev)
493+
{
494+
struct max32_adc_data *const data = dev->data;
495+
uint32_t flags = MXC_ADC_GetFlags();
496+
uint32_t int_req = BIT(3);
497+
498+
MXC_ADC_Handler();
499+
if (flags & int_req) {
500+
MXC_ADC_Free();
501+
}
502+
MXC_ADC_ClearFlags(flags);
503+
504+
if (flags & WRAP_MXC_F_ADC_CONV_DONE_IF) {
505+
506+
data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
507+
508+
const size_t min_read_size = 64;
509+
510+
uint8_t *buf;
511+
uint32_t buf_len;
512+
513+
if (rtio_sqe_rx_buf(data->sqe, min_read_size, min_read_size,
514+
&buf, &buf_len) != 0) {
515+
data->no_mem = 1;
516+
rtio_iodev_sqe_err(data->sqe, -ENOMEM);
517+
return;
518+
}
519+
struct adc_max32_fifo_data *hdr = (struct adc_max32_fifo_data *)buf;
520+
521+
hdr->is_fifo = 1;
522+
hdr->timestamp = data->timestamp;
523+
hdr->vref_mv = MAX32_ADC_VREF_MV;
524+
hdr->max32_qscale_mode = MAX32_12B_MODE;
525+
hdr->fifo_byte_count = ADC_MAX32_BYTE_COUNT;
526+
hdr->sample_set_size = ADC_MAX32_SAMPLE_SIZE;
527+
528+
uint8_t *read_buf = buf + sizeof(*hdr);
529+
530+
Wrap_MXC_ADC_GetData((uint16_t **)&read_buf);
531+
532+
if (data->sample_channels != 0) {
533+
adc_max32_start_channel(dev);
534+
} else {
535+
Wrap_MXC_ADC_DisableConversion();
536+
adc_context_on_sampling_done(&data->ctx, dev);
537+
}
538+
}
539+
if (flags & int_req) {
540+
541+
adc_complete_rtio_cb(dev);
542+
}
543+
}
544+
545+
ADC_DECODER_API_DT_DEFINE() = {
546+
.get_frame_count = adc_max32_decoder_get_frame_count,
547+
.decode = adc_max32_decoder_decode,
548+
};
549+
550+
int adc_max32_get_decoder(const struct device *dev, const struct adc_decoder_api **api)
551+
{
552+
ARG_UNUSED(dev);
553+
*api = &ADC_DECODER_NAME();
554+
555+
return 0;
556+
}
557+
#else
436558
static void adc_max32_isr(const struct device *dev)
437559
{
438560
struct max32_adc_data *const data = dev->data;
@@ -452,6 +574,7 @@ static void adc_max32_isr(const struct device *dev)
452574
}
453575
}
454576
}
577+
#endif /* CONFIG_ADC_MAX32_STREAM */
455578

456579
static DEVICE_API(adc, adc_max32_driver_api) = {
457580
.channel_setup = adc_max32_channel_setup,
@@ -460,14 +583,21 @@ static DEVICE_API(adc, adc_max32_driver_api) = {
460583
.read_async = adc_max32_read_async,
461584
#endif /* CONFIG_ADC_ASYNC */
462585
.ref_internal = MAX32_ADC_VREF_MV,
586+
#ifdef CONFIG_ADC_MAX32_STREAM
587+
.submit = adc_max32_submit_stream,
588+
.get_decoder = adc_max32_get_decoder,
589+
#endif /* CONFIG_ADC_MAX32_STREAM */
463590
};
464591

465592
#define MAX32_ADC_INIT(_num) \
466593
PINCTRL_DT_INST_DEFINE(_num); \
467594
static void max32_adc_irq_init_##_num(void) \
468595
{ \
469-
IRQ_CONNECT(DT_INST_IRQN(_num), DT_INST_IRQ(_num, priority), adc_max32_isr, \
470-
DEVICE_DT_INST_GET(_num), 0); \
596+
COND_CODE_1(CONFIG_ADC_MAX32_STREAM, \
597+
(IRQ_CONNECT(DT_INST_IRQN(_num), DT_INST_IRQ(_num, priority), adc_max32_rtio_isr, \
598+
DEVICE_DT_INST_GET(_num), 0)), \
599+
(IRQ_CONNECT(DT_INST_IRQN(_num), DT_INST_IRQ(_num, priority), adc_max32_isr, \
600+
DEVICE_DT_INST_GET(_num), 0))); \
471601
irq_enable(DT_INST_IRQN(_num)); \
472602
}; \
473603
static const struct max32_adc_config max32_adc_config_##_num = { \

soc/adi/max32/Kconfig.soc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,12 @@ config SOC_MAX32680_M4
6969
select SOC_MAX32680
7070
select SOC_FAMILY_MAX32_M4
7171

72+
config HAS_ADC_MAX32_REVB_ME18
73+
bool "revb"
74+
7275
config SOC_MAX32690
7376
bool
77+
select HAS_ADC_MAX32_REVB_ME18
7478

7579
config SOC_MAX32690_M4
7680
bool

west.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ manifest:
144144
groups:
145145
- fs
146146
- name: hal_adi
147-
revision: 16829b77264678f31a2d077a870af7bdca2d39bd
147+
revision: pull/29/head
148148
path: modules/hal/adi
149149
groups:
150150
- hal

0 commit comments

Comments
 (0)