4747#include "py/runtime.h"
4848#include "py/mphal.h"
4949#include "modmachine.h"
50+ #include "py/objarray.h"
5051#include "extmod/vfs_native.h"
5152
5253
5354typedef struct _mdac_obj_t {
5455 mp_obj_base_t base ;
55- int gpio_id ;
56- dac_channel_t dac_id ;
57- uint8_t * buffer ;
58- size_t buf_len ;
59- FILE * fhndl ;
60- int noise ;
56+ int gpio_id ;
57+ dac_channel_t dac_id ;
58+ uint8_t * buffer ;
59+ size_t buf_len ;
60+ size_t buf_ptr ;
61+ FILE * fhndl ;
62+ uint64_t timer_interval ;
63+ uint8_t dac_timer_mode ;
6164} mdac_obj_t ;
6265
6366extern int MainTaskCore ;
@@ -297,10 +300,23 @@ STATIC void dac_timer_isr(void *self_in)
297300 else TIMERG0 .int_clr_timers .t0 = 1 ;
298301 }
299302
300- uint32_t rnd = esp_random ();
301- rnd = ((rnd & 0xff ) ^ ((rnd >> 8 ) & 0xff ) ^ ((rnd >> 16 ) & 0xff ) ^ ((rnd >> 24 ) & 0xff ));
302- //rnd = ((rnd & 0xff) + ((rnd >> 8) & 0xff) + ((rnd >> 16) & 0xff) + ((rnd >> 24) & 0xff));
303- dac_output_voltage (self -> dac_id , (uint8_t )rnd );
303+ if (self -> dac_timer_mode == 1 ) {
304+ // Generate random noise
305+ uint32_t rnd = esp_random ();
306+ rnd = ((rnd & 0xff ) ^ ((rnd >> 8 ) & 0xff ) ^ ((rnd >> 16 ) & 0xff ) ^ ((rnd >> 24 ) & 0xff ));
307+ //rnd = ((rnd & 0xff) + ((rnd >> 8) & 0xff) + ((rnd >> 16) & 0xff) + ((rnd >> 24) & 0xff));
308+ dac_output_voltage (self -> dac_id , (uint8_t )rnd );
309+ }
310+ else if (self -> dac_timer_mode == 2 ) {
311+ // Output DAC values from buffer
312+ dac_output_voltage (self -> dac_id , self -> buffer [self -> buf_ptr ]);
313+ self -> buf_ptr ++ ;
314+ if (self -> buf_ptr >= self -> buf_len ) {
315+ if (trepeat ) self -> buf_ptr = 0 ;
316+ else timer_stop = true;
317+ }
318+ }
319+ else timer_stop = true;
304320
305321 if (timer_stop ) {
306322 // --- Finished, all data read or ADC read error ---
@@ -335,7 +351,7 @@ STATIC esp_err_t start_dac_timer(mdac_obj_t *self)
335351 config .counter_en = TIMER_PAUSE ;
336352 config .alarm_en = TIMER_ALARM_EN ;
337353 config .auto_reload = true;
338- config .divider = 80 ; // 1 MHz
354+ config .divider = ADC_TIMER_DIVIDER ; // 1 MHz
339355
340356 esp_err_t err = timer_init ((ADC_TIMER_NUM >> 1 ) & 1 , ADC_TIMER_NUM & 1 , & config );
341357 if (err != ESP_OK ) return -1 ;
@@ -347,7 +363,7 @@ STATIC esp_err_t start_dac_timer(mdac_obj_t *self)
347363 if (err != ESP_OK ) return -2 ;
348364
349365 // Configure the alarm value and the interrupt on alarm.
350- err = timer_set_alarm_value ((ADC_TIMER_NUM >> 1 ) & 1 , ADC_TIMER_NUM & 1 , self -> noise );
366+ err = timer_set_alarm_value ((ADC_TIMER_NUM >> 1 ) & 1 , ADC_TIMER_NUM & 1 , self -> timer_interval );
351367 if (err != ESP_OK ) return -3 ;
352368
353369 // Enable timer interrupt
@@ -583,9 +599,10 @@ STATIC mp_obj_t mdac_waveform(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
583599 }
584600 adc_timer_active = true;
585601 dac_timer_active = true;
602+ self -> dac_timer_mode = 1 ;
586603 timer_stop = false;
587604 if (freq < 500 || freq > 32000 ) mp_raise_ValueError ("Frequency out of range (500-32000 Hz)" );
588- self -> noise = 1000000 / freq ;
605+ self -> timer_interval = ( int ) ADC_TIMER_FREQ / freq ;
589606 int err = start_dac_timer (self ) != ESP_OK ;
590607 if (err ) {
591608 ESP_LOGE ("DAC" , "Error starting DAC timer (%d)" , err );
@@ -644,6 +661,94 @@ STATIC mp_obj_t mdac_waveform(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
644661}
645662STATIC MP_DEFINE_CONST_FUN_OBJ_KW (mdac_waveform_obj , 0 , mdac_waveform );
646663
664+ //------------------------------------------------------------------------------------------------
665+ STATIC mp_obj_t mdac_write_buffer (mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
666+ enum { ARG_data , ARG_freq , ARG_mode , ARG_wait };
667+ const mp_arg_t allowed_args [] = {
668+ { MP_QSTR_data , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = mp_const_none } },
669+ { MP_QSTR_freq , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = mp_const_none } },
670+ { MP_QSTR_mode , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false}},
671+ { MP_QSTR_wait , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false}},
672+ };
673+ 674+ mdac_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
675+ _is_init (self , true, false);
676+ 677+ dac_func_stop (self );
678+ 679+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
680+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
681+ 682+ double freq = mp_obj_get_float (args [ARG_freq ].u_obj );
683+ if ((freq < 0.001 ) || (freq > 18000.0 )) {
684+ mp_raise_ValueError ("frequency out of range (0.001 - 18000 Hz)" );
685+ }
686+ double interv = (1.0 / freq ) * ADC_TIMER_FREQ ;
687+ 688+ // Get arguments
689+ bool wait = false;
690+ trepeat = args [ARG_mode ].u_bool ;
691+ // only wait if if not continuous mode
692+ if (!trepeat ) wait = args [ARG_wait ].u_bool ;
693+ 694+ adc_timer_active = true;
695+ dac_timer_active = true;
696+ self -> buffer = NULL ;
697+ self -> buf_len = 0 ;
698+ self -> buf_ptr = 0 ;
699+ 700+ if (args [ARG_data ].u_obj != mp_const_none ) {
701+ // Play from the provided array
702+ if (!MP_OBJ_IS_TYPE (args [ARG_data ].u_obj , & mp_type_array )) {
703+ adc_timer_active = false;
704+ dac_timer_active = false;
705+ mp_raise_ValueError ("array argument expected" );
706+ }
707+ mp_obj_array_t * arr = (mp_obj_array_t * )MP_OBJ_TO_PTR (args [ARG_data ].u_obj );
708+ if (arr -> typecode != 'B' ) {
709+ adc_timer_active = false;
710+ dac_timer_active = false;
711+ mp_raise_ValueError ("array argument of type 'B' expected" );
712+ }
713+ if (arr -> len < 1 ) {
714+ self -> buf_len = 0 ;
715+ adc_timer_active = false;
716+ dac_timer_active = false;
717+ mp_raise_ValueError ("array argument length must be >= 1" );
718+ }
719+ self -> buffer = arr -> items ;
720+ if (self -> buf_len < 1 ) self -> buf_len = arr -> len ;
721+ else if (arr -> len < self -> buf_len ) self -> buf_len = arr -> len ;
722+ }
723+ else {
724+ adc_timer_active = false;
725+ dac_timer_active = false;
726+ mp_raise_ValueError ("array argument expected" );
727+ }
728+ 729+ self -> dac_timer_mode = 2 ;
730+ self -> timer_interval = (int64_t )(round (interv ));
731+ int err = start_dac_timer (self ) != ESP_OK ;
732+ if (err ) {
733+ adc_timer_active = false;
734+ dac_timer_active = false;
735+ self -> buffer = NULL ;
736+ self -> buf_len = 0 ;
737+ self -> buf_ptr = 0 ;
738+ ESP_LOGE ("DAC" , "Error starting DAC timer (%d)" , err );
739+ }
740+ 741+ if (wait ) {
742+ mp_hal_delay_ms (3 );
743+ while (dac_timer_active ) {
744+ mp_hal_delay_ms (3 );
745+ }
746+ }
747+ 748+ return mp_const_true ;
749+ }
750+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (mdac_write_buffer_obj , 0 , mdac_write_buffer );
751+ 647752//-----------------------------------------------------------------------------------------------
648753STATIC mp_obj_t mdac_write_timed (mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
649754 enum { ARG_data , ARG_freq , ARG_mode , ARG_wait };
@@ -678,7 +783,7 @@ STATIC mp_obj_t mdac_write_timed(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
678783
679784 mp_buffer_info_t src ;
680785 self -> fhndl = NULL ;
681- self -> noise = 0 ;
786+ self -> timer_interval = 0 ;
682787
683788 if (MP_OBJ_IS_STR (args [ARG_data ].u_obj )) {
684789 const char * dac_file = NULL ;
@@ -957,6 +1062,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(mdac_deinit_obj, mdac_deinit);
9571062STATIC const mp_rom_map_elem_t mdac_locals_dict_table [] = {
9581063 { MP_ROM_QSTR (MP_QSTR_write ), MP_ROM_PTR (& mdac_write_obj ) },
9591064 { MP_ROM_QSTR (MP_QSTR_write_timed ), MP_ROM_PTR (& mdac_write_timed_obj ) },
1065+ { MP_ROM_QSTR (MP_QSTR_write_buffer ),MP_ROM_PTR (& mdac_write_buffer_obj ) },
9601066 { MP_ROM_QSTR (MP_QSTR_wavplay ), MP_ROM_PTR (& mdac_play_wav_obj ) },
9611067 { MP_ROM_QSTR (MP_QSTR_waveform ), MP_ROM_PTR (& mdac_waveform_obj ) },
9621068 { MP_ROM_QSTR (MP_QSTR_stopwave ), MP_ROM_PTR (& mdac_stopfunc_obj ) },
0 commit comments