@@ -178,6 +178,21 @@ STATIC uint32_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_cou
178178 return pins_we_use ;
179179}
180180
181+ static bool can_add_program (PIO pio , const pio_program_t * program , int offset ) {
182+ if (offset == -1 ) {
183+ return pio_can_add_program (pio , program );
184+ }
185+ return pio_can_add_program_at_offset (pio , program , offset );
186+ }
187+
188+ static uint add_program (PIO pio , const pio_program_t * program , int offset ) {
189+ if (offset == -1 ) {
190+ return pio_add_program (pio , program );
191+ } else {
192+ pio_add_program_at_offset (pio , program , offset );
193+ return offset ;
194+ }
195+ }
181196
182197bool rp2pio_statemachine_construct (rp2pio_statemachine_obj_t * self ,
183198 const uint16_t * program , size_t program_len ,
@@ -197,7 +212,8 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
197212 bool claim_pins ,
198213 bool user_interruptible ,
199214 bool sideset_enable ,
200- int wrap_target , int wrap
215+ int wrap_target , int wrap ,
216+ int offset
201217 ) {
202218 // Create a program id that isn't the pointer so we can store it without storing the original object.
203219 uint32_t program_id = ~((uint32_t )program );
@@ -215,14 +231,15 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
215231 uint8_t free_count = 0 ;
216232 for (size_t j = 0 ; j < NUM_PIO_STATE_MACHINES ; j ++ ) {
217233 if (_current_program_id [i ][j ] == program_id &&
218- _current_program_len [i ][j ] == program_len ) {
234+ _current_program_len [i ][j ] == program_len &&
235+ (offset == -1 || offset == _current_program_offset [i ][j ])) {
219236 program_offset = _current_program_offset [i ][j ];
220237 }
221238 if (!pio_sm_is_claimed (pio , j )) {
222239 free_count ++ ;
223240 }
224241 }
225- if (free_count > 0 && (program_offset < 32 || pio_can_add_program (pio , & program_struct ))) {
242+ if (free_count > 0 && (program_offset < 32 || can_add_program (pio , & program_struct , offset ))) {
226243 pio_index = i ;
227244 if (program_offset < 32 ) {
228245 break ;
@@ -254,7 +271,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
254271 self -> pio = pio_instances [pio_index ];
255272 self -> state_machine = state_machine ;
256273 if (program_offset == 32 ) {
257- program_offset = pio_add_program (self -> pio , & program_struct );
274+ program_offset = add_program (self -> pio , & program_struct , offset );
258275 }
259276 self -> offset = program_offset ;
260277 _current_program_id [pio_index ][state_machine ] = program_id ;
@@ -509,7 +526,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
509526 bool wait_for_txstall ,
510527 bool auto_push , uint8_t push_threshold , bool in_shift_right ,
511528 bool user_interruptible ,
512- int wrap_target , int wrap ) {
529+ int wrap_target , int wrap ,
530+ int offset ) {
513531
514532 // First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false.
515533 uint32_t pins_we_use = wait_gpio_mask ;
@@ -598,7 +616,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
598616 true /* claim pins */ ,
599617 user_interruptible ,
600618 sideset_enable ,
601- wrap_target , wrap );
619+ wrap_target , wrap , offset );
602620 if (!ok ) {
603621 mp_raise_RuntimeError (translate ("All state machines in use" ));
604622 }
0 commit comments