2525 */
2626
2727#include "common-hal/pulseio/PulseIn.h"
28+ #include "shared-bindings/microcontroller/__init__.h"
2829#include "py/runtime.h"
2930
3031STATIC uint8_t refcount = 0 ;
@@ -33,17 +34,11 @@ STATIC pulseio_pulsein_obj_t * handles[RMT_CHANNEL_MAX];
3334// Requires rmt.c void esp32s2_peripherals_reset_all(void) to reset
3435
3536STATIC void update_internal_buffer (pulseio_pulsein_obj_t * self ) {
36- //mp_printf(&mp_plat_print, "Update internal Buffer\n");
3737 uint32_t length = 0 ;
3838 rmt_item32_t * items = (rmt_item32_t * ) xRingbufferReceive (self -> buf_handle , & length , 0 );
3939 if (items ) {
4040 length /= 4 ;
41- //mp_printf(&mp_plat_print, "Length%d\n",length);
42- // TODO: If the size of the recieve is larger than the buffer, reset it?
43-
4441 for (size_t i = 0 ; i < length ; i ++ ) {
45- //mp_printf(&mp_plat_print, "Item d0:%d, l0:%d, d1:%d, l1:%d\n",(items[i].duration0 * 3),
46- // items[i].level0,(items[i].duration1 * 3),items[i].level1);
4742 uint16_t pos = (self -> start + self -> len ) % self -> maxlen ;
4843 self -> buffer [pos ] = items [i ].duration0 * 3 ;
4944 // Check if second item exists before incrementing
@@ -69,25 +64,16 @@ STATIC void update_internal_buffer(pulseio_pulsein_obj_t* self) {
6964// We can't access the RMT interrupt, so we need a global service to prevent
7065// the ringbuffer from overflowing and crashing the peripheral
7166void pulsein_background (void ) {
72- //mp_printf(&mp_plat_print, "BG Task!\n");
7367 for (size_t i = 0 ; i < RMT_CHANNEL_MAX ; i ++ ) {
7468 if (handles [i ]) {
75- //mp_printf(&mp_plat_print, "Located viable handle:%d\n",i);
7669 update_internal_buffer (handles [i ]);
7770 UBaseType_t items_waiting ;
7871 vRingbufferGetInfo (handles [i ]-> buf_handle , NULL , NULL , NULL , NULL , & items_waiting );
79- //mp_printf(&mp_plat_print, "items waiting:%d\n",items_waiting);
80- // if (items_waiting > handles[i]->maxlen) {
81- // mp_printf(&mp_plat_print, "Overage!\n");
82- // mp_printf(&mp_plat_print, "Items waiting detected:%d\n", items_waiting);
83- // update_internal_buffer(handles[i]);
84- // }
8572 }
8673 }
8774}
8875
8976void pulsein_reset (void ) {
90- mp_printf (& mp_plat_print , "Pulsein Reset called\n" );
9177 for (size_t i = 0 ; i < RMT_CHANNEL_MAX ; i ++ ) {
9278 handles [i ] = NULL ;
9379 }
@@ -103,48 +89,48 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu
10389 }
10490 self -> pin = pin ;
10591 self -> maxlen = maxlen ;
106- // self->idle_state = idle_state;
92+ self -> idle_state = idle_state ;
10793 self -> start = 0 ;
10894 self -> len = 0 ;
109- // self->first_edge = true;
11095 self -> paused = false;
111- // self->last_overflow = 0;
112- // self->last_count = 0;
11396
114- rmt_channel_t channel = esp32s2_peripherals_find_and_reserve_rmt ();
115- mp_printf (& mp_plat_print , "Selected Channel:%d!\n" ,channel );
97+ // Set pull settings
98+ gpio_pullup_dis (pin -> number );
99+ gpio_pulldown_dis (pin -> number );
100+ if (idle_state ) {
101+ gpio_pullup_en (pin -> number );
102+ } else {
103+ gpio_pulldown_en (pin -> number );
104+ }
116105
117- // Configure Channel
106+ // Find a free RMT Channel and configure it
107+ rmt_channel_t channel = esp32s2_peripherals_find_and_reserve_rmt ();
118108 rmt_config_t config = RMT_DEFAULT_CONFIG_RX (pin -> number , channel );
119109 config .rx_config .filter_en = true;
120- config .rx_config .idle_threshold = 30000 ;
121- config .clk_div = 240 ;
122-
110+ config .rx_config .idle_threshold = 30000 ; // 30*3=90ms idle required to register a sequence
111+ config .clk_div = 240 ; // All measurements are divided by 3 to accomodate 65ms pulses
123112 rmt_config (& config );
124- size_t len = 1000 ; //TODO: pick a reasonable number for this?
125- // size_t len = maxlen * 4;
126- rmt_driver_install (channel , len , 0 );
113+ rmt_driver_install (channel , 1000 , 0 ); //TODO: pick a more specific buffer size?
127114
115+ // Store this object and the buffer handle for background updates
128116 self -> channel = channel ;
129-
130- // Store handle for background updates
131117 handles [channel ] = self ;
132-
133118 rmt_get_ringbuf_handle (channel , & (self -> buf_handle ));
134- rmt_rx_start (channel , true);
135119
120+ // start RMT RX, and enable ticks so the core doesn't turn off.
121+ rmt_rx_start (channel , true);
136122 supervisor_enable_tick ();
137123 refcount ++ ;
138124}
139125
140126bool common_hal_pulseio_pulsein_deinited (pulseio_pulsein_obj_t * self ) {
141- return handles [self -> channel ] ? true : false ;
127+ return handles [self -> channel ] ? false : true ;
142128}
143129
144130void common_hal_pulseio_pulsein_deinit (pulseio_pulsein_obj_t * self ) {
145131 handles [self -> channel ] = NULL ;
146132 esp32s2_peripherals_free_rmt (self -> channel );
147- reset_pin_number (self -> pin );
133+ reset_pin_number (self -> pin -> number );
148134 refcount -- ;
149135 if (refcount == 0 ) {
150136 supervisor_disable_tick ();
@@ -153,7 +139,7 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
153139
154140void common_hal_pulseio_pulsein_pause (pulseio_pulsein_obj_t * self ) {
155141 self -> paused = true;
156- rmt_rx_stop ();
142+ rmt_rx_stop (self -> channel );
157143}
158144
159145void common_hal_pulseio_pulsein_resume (pulseio_pulsein_obj_t * self , uint16_t trigger_duration ) {
@@ -162,17 +148,25 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t tri
162148 common_hal_pulseio_pulsein_pause (self );
163149 }
164150
151+ if (trigger_duration > 0 ) {
152+ gpio_set_direction (self -> pin -> number , GPIO_MODE_DEF_OUTPUT );
153+ gpio_set_level (self -> pin -> number , !self -> idle_state );
154+ common_hal_mcu_delay_us ((uint32_t )trigger_duration );
155+ gpio_set_level (self -> pin -> number , self -> idle_state );
156+ gpio_set_direction (self -> pin -> number , GPIO_MODE_INPUT ); // should revert to pull direction
157+ }
158+
165159 self -> paused = false;
166- rmt_rx_start ();
160+ rmt_rx_start (self -> channel , false );
167161}
168162
169163void common_hal_pulseio_pulsein_clear (pulseio_pulsein_obj_t * self ) {
164+ // Buffer only updates in BG tasks or fetches, so no extra protection is needed
170165 self -> start = 0 ;
171166 self -> len = 0 ;
172167}
173168
174169uint16_t common_hal_pulseio_pulsein_get_item (pulseio_pulsein_obj_t * self , int16_t index ) {
175- //mp_printf(&mp_plat_print, "Call GetItem\n");
176170 update_internal_buffer (self );
177171 if (index < 0 ) {
178172 index += self -> len ;
@@ -185,7 +179,6 @@ uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_
185179}
186180
187181uint16_t common_hal_pulseio_pulsein_popleft (pulseio_pulsein_obj_t * self ) {
188- mp_printf (& mp_plat_print , "Call PopLeft\n" );
189182 update_internal_buffer (self );
190183
191184 if (self -> len == 0 ) {
@@ -197,28 +190,6 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
197190 self -> len -- ;
198191
199192 return value ;
200-
201-
202- // uint32_t length = 0;
203- // rmt_item32_t *items = (rmt_item32_t *) xRingbufferReceive(self->buf_handle, &length, 10);
204- // mp_printf(&mp_plat_print, "Length%d\n",length);
205- // if (items) {
206- // length /= 4;
207- // mp_printf(&mp_plat_print, "Length%d\n",length);
208- // for (size_t i=0; i < length; i++) {
209- // mp_printf(&mp_plat_print, "Item d0:%d, l0:%d, d1:%d, l1:%d\n",(items[i].duration0 * 3),
210- // items[i].level0,(items[i].duration1 * 3),items[i].level1);
211- // }
212- // vRingbufferReturnItem(self->buf_handle, (void *) items);
213- // }
214- // // while(items) {
215- // // mp_printf(&mp_plat_print, "Length%d",length);
216- // // mp_printf(&mp_plat_print, "Item val0:%d, val1:%d, val:%d",items->duration0,
217- // // items->duration1,items->val);
218- // // vRingbufferReturnItem(self->buf_handle, (void *) items);
219- // // items = (rmt_item32_t *) xRingbufferReceive(self->buf_handle, &length, 1);
220- // // }
221- // return items ? items[0].duration0 : false;
222193}
223194
224195uint16_t common_hal_pulseio_pulsein_get_maxlen (pulseio_pulsein_obj_t * self ) {
0 commit comments