@@ -43,22 +43,33 @@ static volatile uint16_t pulse_index = 0;
4343static uint16_t pulse_length ;
4444pwmio_pwmout_obj_t * pwmout_obj ;
4545volatile uint16_t current_duty_cycle ;
46+ static uint32_t min_pulse = 0 ;
47+ static alarm_id_t cur_alarm ;
4648
47- void pulse_finish (void ) {
49+ void pulse_finish (pwmio_pwmout_obj_t * carrier ) {
4850 pulse_index ++ ;
4951 // Turn pwm pin off by setting duty cyle to 1.
50- common_hal_pwmio_pwmout_set_duty_cycle (pwmout_obj ,1 );
52+ common_hal_pwmio_pwmout_set_duty_cycle (carrier ,1 );
5153 if (pulse_index >= pulse_length ) {
5254 return ;
5355 }
54- add_alarm_in_us (pulse_buffer [pulse_index ], pulseout_interrupt_handler , NULL , false);
5556 if (pulse_index % 2 == 0 ) {
56- common_hal_pwmio_pwmout_set_duty_cycle (pwmout_obj ,current_duty_cycle );
57+ common_hal_pwmio_pwmout_set_duty_cycle (carrier ,current_duty_cycle );
58+ }
59+ uint64_t delay = pulse_buffer [pulse_index ];
60+ if (delay < min_pulse ) {
61+ delay = min_pulse ;
62+ }
63+ cur_alarm = 0 ;
64+ // if the alarm cannot be set, try again with a longer delay
65+ while (cur_alarm == 0 ) {
66+ cur_alarm = add_alarm_in_us (delay , pulseout_interrupt_handler , carrier , false);
67+ delay = delay + 1 ;
5768 }
5869}
5970
6071int64_t pulseout_interrupt_handler (alarm_id_t id , void * user_data ) {
61- pulse_finish ();
72+ pulse_finish (user_data );
6273 return 0 ;
6374}
6475
@@ -75,9 +86,12 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self,
7586 refcount ++ ;
7687 pwmout_obj = (pwmio_pwmout_obj_t * )carrier ;
7788 current_duty_cycle = common_hal_pwmio_pwmout_get_duty_cycle (pwmout_obj );
89+ pwm_set_enabled (carrier -> slice ,false);
90+ common_hal_pwmio_pwmout_set_duty_cycle (pwmout_obj ,1 );
7891 self -> pin = carrier -> pin -> number ;
7992 self -> slice = carrier -> slice ;
80- pwm_set_enabled (pwmout_obj -> slice ,false);
93+ self -> carrier = pwmout_obj ;
94+ min_pulse = (1000000 / carrier -> actual_frequency );
8195}
8296
8397bool common_hal_pulseio_pulseout_deinited (pulseio_pulseout_obj_t * self ) {
@@ -97,16 +111,26 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu
97111 pulse_index = 0 ;
98112 pulse_length = length ;
99113
100- add_alarm_in_us (pulses [0 ], pulseout_interrupt_handler , NULL , false);
101- common_hal_pwmio_pwmout_set_duty_cycle (pwmout_obj ,current_duty_cycle );
102- pwm_set_enabled (pwmout_obj -> slice ,true);
114+ common_hal_pwmio_pwmout_set_duty_cycle (self -> carrier ,current_duty_cycle );
115+ pwm_set_enabled (self -> slice ,true);
116+ uint64_t delay = pulse_buffer [0 ];
117+ if (delay < min_pulse ) {
118+ delay = min_pulse ;
119+ }
120+ alarm_id_t init_alarm = 0 ;
121+ // if the alarm cannot be set, try again with a longer delay
122+ while (init_alarm == 0 ) {
123+ init_alarm = add_alarm_in_us (delay , pulseout_interrupt_handler , self -> carrier , false);
124+ delay = delay + 1 ;
125+ }
126+ cur_alarm = init_alarm ;
103127
104128 while (pulse_index < length ) {
105129 // Do other things while we wait. The interrupts will handle sending the
106130 // signal.
107131 RUN_BACKGROUND_TASKS ;
108132 }
109133 // Short delay to give pin time to settle before disabling PWM
110- common_hal_mcu_delay_us (25 );
111- pwm_set_enabled (pwmout_obj -> slice ,false);
134+ common_hal_mcu_delay_us (min_pulse );
135+ pwm_set_enabled (self -> slice ,false);
112136}
0 commit comments