44 * SPDX-License-Identifier: Apache-2.0
55 */
66
7+ #define ADC_CONTEXT_USES_KERNEL_TIMER
78#include "adc_context.h"
89#include <nrfx_saadc.h>
910#include <zephyr/dt-bindings/adc/nrf-saadc-v3.h>
@@ -103,20 +104,15 @@ struct driver_data {
103104 uint8_t active_channel_cnt ;
104105 void * mem_reg ;
105106 void * user_buffer ;
106- struct k_timer timer ;
107- bool internal_timer_enabled ;
108107};
109108
110109static struct driver_data m_data = {
110+ ADC_CONTEXT_INIT_TIMER (m_data , ctx ),
111111 ADC_CONTEXT_INIT_LOCK (m_data , ctx ),
112112 ADC_CONTEXT_INIT_SYNC (m_data , ctx ),
113113 .mem_reg = DMM_DEV_TO_REG (DT_NODELABEL (adc )),
114- .internal_timer_enabled = false,
115114};
116115
117- /* Maximum value of the internal timer interval in microseconds. */
118- #define ADC_INTERNAL_TIMER_INTERVAL_MAX_US 128U
119-
120116/* Forward declaration */
121117static void event_handler (const nrfx_saadc_evt_t * event );
122118
@@ -389,57 +385,22 @@ static void adc_context_start_sampling(struct adc_context *ctx)
389385
390386static void adc_context_update_buffer_pointer (struct adc_context * ctx , bool repeat )
391387{
392- if (!m_data .internal_timer_enabled ) {
393- void * samples_buffer ;
394-
395- if (!repeat ) {
396- m_data .user_buffer =
397- (uint16_t * )m_data .user_buffer + m_data .active_channel_cnt ;
398- }
399-
400- int error = dmm_buffer_in_prepare (
401- m_data .mem_reg , m_data .user_buffer ,
402- NRFX_SAADC_SAMPLES_TO_BYTES (m_data .active_channel_cnt ), & samples_buffer );
403- if (error != 0 ) {
404- LOG_ERR ("DMM buffer allocation failed err=%d" , error );
405- adc_context_complete (ctx , - EIO );
406- }
407-
408- nrfx_err_t nrfx_err =
409- nrfx_saadc_buffer_set (samples_buffer , m_data .active_channel_cnt );
410- if (nrfx_err != NRFX_SUCCESS ) {
411- LOG_ERR ("Failed to set buffer: %08x" , nrfx_err );
412- adc_context_complete (ctx , - EIO );
413- }
414- }
415- }
416-
417- static inline void adc_context_enable_timer (struct adc_context * ctx )
418- {
419- if (!m_data .internal_timer_enabled ) {
420- k_timer_start (& m_data .timer , K_NO_WAIT , K_USEC (ctx -> options .interval_us ));
421- } else {
422- nrfx_err_t ret = nrfx_saadc_mode_trigger ();
388+ void * samples_buffer ;
423389
424- if (ret != NRFX_SUCCESS ) {
425- LOG_ERR ("Cannot start sampling: %d" , ret );
426- adc_context_complete (& m_data .ctx , - EIO );
427- }
390+ if (!repeat ) {
391+ m_data .user_buffer = (uint16_t * )m_data .user_buffer + m_data .active_channel_cnt ;
428392 }
429- }
430393
431- static inline void adc_context_disable_timer (struct adc_context * ctx )
432- {
433- if (!m_data .internal_timer_enabled ) {
434- k_timer_stop (& m_data .timer );
394+ int error = dmm_buffer_in_prepare (
395+ m_data .mem_reg , m_data .user_buffer ,
396+ NRFX_SAADC_SAMPLES_TO_BYTES (m_data .active_channel_cnt ),
397+ & samples_buffer );
398+ if (error != 0 ) {
399+ LOG_ERR ("DMM buffer allocation failed err=%d" , error );
400+ adc_context_complete (ctx , - EIO );
435401 }
436- }
437-
438- static void adc_context_on_timer_expired (struct k_timer * timer_id )
439- {
440- ARG_UNUSED (timer_id );
441402
442- adc_context_request_next_sampling ( & m_data .ctx );
403+ nrfx_saadc_buffer_set ( samples_buffer , m_data .active_channel_cnt );
443404}
444405
445406static int get_resolution (const struct adc_sequence * sequence , nrf_saadc_resolution_t * resolution )
@@ -529,66 +490,29 @@ static int check_buffer_size(const struct adc_sequence *sequence, uint8_t active
529490 return 0 ;
530491}
531492
532- static inline void single_ended_channel_cut_negative_sample (uint16_t channel_bit ,
533- uint8_t single_ended_channels ,
534- int16_t * * sample )
535- {
536- if ((channel_bit & single_ended_channels ) && (* sample < 0 )) {
537- * * sample = 0 ;
538- }
539-
540- (* sample )++ ;
541- }
542-
543493static bool has_single_ended (const struct adc_sequence * sequence )
544494{
545495 return sequence -> channels & m_data .single_ended_channels ;
546496}
547497
548- static void correct_single_ended (const struct adc_sequence * sequence , nrf_saadc_value_t * buffer ,
549- uint16_t buffer_size )
498+ static void correct_single_ended (const struct adc_sequence * sequence , nrf_saadc_value_t * buffer )
550499{
500+ uint16_t channel_bit = BIT (0 );
551501 uint8_t selected_channels = sequence -> channels ;
552502 uint8_t single_ended_channels = m_data .single_ended_channels ;
553503 int16_t * sample = (int16_t * )buffer ;
554504
555- for (uint16_t channel_bit = BIT (0 ); channel_bit <= single_ended_channels ;
556- channel_bit <<= 1 ) {
557- if (!(channel_bit & selected_channels )) {
558- continue ;
559- }
560-
561- if (m_data .internal_timer_enabled ) {
562- if (!(channel_bit & single_ended_channels )) {
563- continue ;
505+ while (channel_bit <= single_ended_channels ) {
506+ if (channel_bit & selected_channels ) {
507+ if ((channel_bit & single_ended_channels ) && (* sample < 0 )) {
508+ * sample = 0 ;
564509 }
565510
566- for (int i = 0 ; i < buffer_size ; i ++ ) {
567- if (sample [i ] < 0 ) {
568- sample [i ] = 0 ;
569- }
570- }
571- } else {
572- single_ended_channel_cut_negative_sample (channel_bit , single_ended_channels ,
573- & sample );
511+ sample ++ ;
574512 }
575- }
576- }
577-
578- /* The internal timer runs at 16 MHz, so to convert the interval in microseconds
579- * to the internal timer CC value, we can use the formula:
580- * interval_cc = interval_us * 16 MHz
581- * where 16 MHz is the frequency of the internal timer.
582- *
583- * The maximum value for interval_cc is 2047, which corresponds to
584- * approximately 7816 Hz ~ 128us.
585- * The minimum value for interval_cc is depends on the SoC.
586- */
587- static inline uint16_t interval_to_cc (uint16_t interval_us )
588- {
589- NRFX_ASSERT ((interval_us <= ADC_INTERNAL_TIMER_INTERVAL_MAX_US ) && (interval_us > 0 ));
590513
591- return (interval_us * 16 ) - 1 ;
514+ channel_bit <<= 1 ;
515+ }
592516}
593517
594518static int start_read (const struct device * dev ,
@@ -638,28 +562,10 @@ static int start_read(const struct device *dev,
638562 return error ;
639563 }
640564
641- if ((active_channel_cnt == 1 ) && (sequence -> options != NULL ) &&
642- (sequence -> options -> interval_us <= ADC_INTERNAL_TIMER_INTERVAL_MAX_US ) &&
643- (sequence -> options -> interval_us > 0 )) {
644-
645- nrfx_saadc_adv_config_t adv_config = {
646- .oversampling = oversampling ,
647- .burst = NRF_SAADC_BURST_DISABLED ,
648- .internal_timer_cc = interval_to_cc (sequence -> options -> interval_us ),
649- .start_on_end = true,
650- };
651-
652- m_data .internal_timer_enabled = true;
653-
654- nrfx_err = nrfx_saadc_advanced_mode_set (selected_channels , resolution , & adv_config ,
655- event_handler );
656- } else {
657- m_data .internal_timer_enabled = false;
658-
659- nrfx_err = nrfx_saadc_simple_mode_set (selected_channels , resolution , oversampling ,
660- event_handler );
661- }
662-
565+ nrfx_err = nrfx_saadc_simple_mode_set (selected_channels ,
566+ resolution ,
567+ oversampling ,
568+ event_handler );
663569 if (nrfx_err != NRFX_SUCCESS ) {
664570 return - EINVAL ;
665571 }
@@ -672,11 +578,9 @@ static int start_read(const struct device *dev,
672578 m_data .active_channel_cnt = active_channel_cnt ;
673579 m_data .user_buffer = sequence -> buffer ;
674580
675- error = dmm_buffer_in_prepare (m_data .mem_reg , m_data .user_buffer ,
676- (m_data .internal_timer_enabled
677- ? (NRFX_SAADC_SAMPLES_TO_BYTES (active_channel_cnt ) *
678- (1 + sequence -> options -> extra_samplings ))
679- : NRFX_SAADC_SAMPLES_TO_BYTES (active_channel_cnt )),
581+ error = dmm_buffer_in_prepare (m_data .mem_reg ,
582+ m_data .user_buffer ,
583+ NRFX_SAADC_SAMPLES_TO_BYTES (active_channel_cnt ),
680584 & samples_buffer );
681585 if (error != 0 ) {
682586 LOG_ERR ("DMM buffer allocation failed err=%d" , error );
@@ -686,15 +590,7 @@ static int start_read(const struct device *dev,
686590 /* Buffer is filled in chunks, each chunk composed of number of samples equal to number
687591 * of active channels. Buffer pointer is advanced and reloaded after each chunk.
688592 */
689- nrfx_err = nrfx_saadc_buffer_set (
690- samples_buffer ,
691- (m_data .internal_timer_enabled
692- ? (active_channel_cnt * (1 + sequence -> options -> extra_samplings ))
693- : active_channel_cnt ));
694- if (nrfx_err != NRFX_SUCCESS ) {
695- LOG_ERR ("Failed to set buffer: %08x" , nrfx_err );
696- return - EINVAL ;
697- }
593+ nrfx_saadc_buffer_set (samples_buffer , active_channel_cnt );
698594
699595 adc_context_start_read (& m_data .ctx , sequence );
700596
@@ -737,15 +633,11 @@ static void event_handler(const nrfx_saadc_evt_t *event)
737633 if (event -> type == NRFX_SAADC_EVT_DONE ) {
738634 dmm_buffer_in_release (
739635 m_data .mem_reg , m_data .user_buffer ,
740- (m_data .internal_timer_enabled
741- ? (NRFX_SAADC_SAMPLES_TO_BYTES (m_data .active_channel_cnt ) *
742- (1 + m_data .ctx .sequence .options -> extra_samplings ))
743- : NRFX_SAADC_SAMPLES_TO_BYTES (m_data .active_channel_cnt )),
636+ NRFX_SAADC_SAMPLES_TO_BYTES (m_data .active_channel_cnt ),
744637 event -> data .done .p_buffer );
745638
746639 if (has_single_ended (& m_data .ctx .sequence )) {
747- correct_single_ended (& m_data .ctx .sequence , m_data .user_buffer ,
748- event -> data .done .size );
640+ correct_single_ended (& m_data .ctx .sequence , m_data .user_buffer );
749641 }
750642 nrfy_saadc_disable (NRF_SAADC );
751643 adc_context_on_sampling_done (& m_data .ctx , DEVICE_DT_INST_GET (0 ));
@@ -755,17 +647,13 @@ static void event_handler(const nrfx_saadc_evt_t *event)
755647 LOG_ERR ("Cannot start sampling: 0x%08x" , err );
756648 adc_context_complete (& m_data .ctx , - EIO );
757649 }
758- } else if (event -> type == NRFX_SAADC_EVT_FINISHED ) {
759- adc_context_complete (& m_data .ctx , 0 );
760650 }
761651}
762652
763653static int init_saadc (const struct device * dev )
764654{
765655 nrfx_err_t err ;
766656
767- k_timer_init (& m_data .timer , adc_context_on_timer_expired , NULL );
768-
769657 /* The priority value passed here is ignored (see nrfx_glue.h). */
770658 err = nrfx_saadc_init (0 );
771659 if (err != NRFX_SUCCESS ) {
0 commit comments