@@ -43,22 +43,33 @@ static volatile uint16_t pulse_index = 0;
43
43
static uint16_t pulse_length ;
44
44
pwmio_pwmout_obj_t * pwmout_obj ;
45
45
volatile uint16_t current_duty_cycle ;
46
+ static uint32_t min_pulse = 0 ;
47
+ static alarm_id_t cur_alarm ;
46
48
47
- void pulse_finish (void ) {
49
+ void pulse_finish (pwmio_pwmout_obj_t * carrier ) {
48
50
pulse_index ++ ;
49
51
// 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 );
51
53
if (pulse_index >= pulse_length ) {
52
54
return ;
53
55
}
54
- add_alarm_in_us (pulse_buffer [pulse_index ], pulseout_interrupt_handler , NULL , false);
55
56
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 ;
57
68
}
58
69
}
59
70
60
71
int64_t pulseout_interrupt_handler (alarm_id_t id , void * user_data ) {
61
- pulse_finish ();
72
+ pulse_finish (user_data );
62
73
return 0 ;
63
74
}
64
75
@@ -75,9 +86,12 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self,
75
86
refcount ++ ;
76
87
pwmout_obj = (pwmio_pwmout_obj_t * )carrier ;
77
88
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 );
78
91
self -> pin = carrier -> pin -> number ;
79
92
self -> slice = carrier -> slice ;
80
- pwm_set_enabled (pwmout_obj -> slice ,false);
93
+ self -> carrier = pwmout_obj ;
94
+ min_pulse = (1000000 / carrier -> actual_frequency );
81
95
}
82
96
83
97
bool 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
97
111
pulse_index = 0 ;
98
112
pulse_length = length ;
99
113
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 ;
103
127
104
128
while (pulse_index < length ) {
105
129
// Do other things while we wait. The interrupts will handle sending the
106
130
// signal.
107
131
RUN_BACKGROUND_TASKS ;
108
132
}
109
133
// 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);
112
136
}
0 commit comments