@@ -1048,17 +1048,47 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
10481048}
10491049
10501050bool common_hal_rp2pio_statemachine_background_write (rp2pio_statemachine_obj_t * self ,
1051- const sm_buf_info * once_write_buf , const sm_buf_info * loop_write_buf , const sm_buf_info * write_loop2_buf ,
1051+ const sm_buf_info * once_write_buf , const sm_buf_info * loop_write_buf , const sm_buf_info * loop2_write_buf ,
10521052 uint8_t stride_in_bytes , bool swap ) {
10531053
10541054 uint8_t pio_index = pio_get_index (self -> pio );
10551055 uint8_t sm = self -> state_machine ;
10561056
1057- int pending_buffers_write = (once_write_buf -> info .len != 0 ) + (loop_write_buf -> info .len != 0 );
1057+ int pending_buffers_write = (once_write_buf -> info .len != 0 ) + (loop_write_buf -> info .len != 0 ) + (loop2_write_buf -> info .len != 0 );
1058+
1059+ // If all buffer arguments have nonzero length, write once_write_buf, loop_write_buf, loop2_write_buf and repeat last two forever
1060+
10581061 if (!once_write_buf -> info .len ) {
1059- once_write_buf = loop_write_buf ;
1062+ if (!loop_write_buf -> info .len ) {
1063+ // If once_write_buf and loop_write_buf have zero length, write loop2_write_buf forever
1064+ once_write_buf = loop2_write_buf ;
1065+ loop_write_buf = loop2_write_buf ;
1066+ } else {
1067+ if (!loop2_write_buf -> info .len ) {
1068+ // If once_write_buf and loop2_write_buf have zero length, write loop_write_buf forever
1069+ once_write_buf = loop_write_buf ;
1070+ loop2_write_buf = loop_write_buf ;
1071+ } else {
1072+ // If only once_write_buf has zero length, write loop_write_buf, loop2_write_buf, and repeat last two forever
1073+ once_write_buf = loop_write_buf ;
1074+ loop_write_buf = loop2_write_buf ;
1075+ loop2_write_buf = once_write_buf ;
1076+ }
1077+ }
1078+ } else {
1079+ if (!loop_write_buf -> info .len ) {
1080+ // If once_write_buf has nonzero length and loop_write_buf has zero length, write once_write_buf, loop2_write_buf and repeat last buf forever
1081+ loop_write_buf = loop2_write_buf ;
1082+ } else {
1083+ if (!loop2_write_buf -> info .len ) {
1084+ // If once_write_buf has nonzero length and loop2_write_buf have zero length, write once_write_buf, loop_write_buf and repeat last buf forever
1085+ loop2_write_buf = loop_write_buf ;
1086+ }
1087+ }
10601088 }
10611089
1090+ // if DMA is already going (i.e. this is not the first call to background_write),
1091+ // block until once_write_buf and loop_write_buf have each been written at least once
10621092 if (SM_DMA_ALLOCATED_WRITE (pio_index , sm )) {
10631093 if (stride_in_bytes != self -> background_stride_in_bytes ) {
10641094 mp_raise_ValueError (MP_ERROR_TEXT ("Mismatched data size" ));
@@ -1075,11 +1105,12 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
10751105 }
10761106
10771107 common_hal_mcu_disable_interrupts ();
1078- self -> once_write_buf = * once_write_buf ;
1079- self -> loop_write_buf = * loop_write_buf ;
1108+ self -> next_write_buf_1 = * once_write_buf ;
1109+ self -> next_write_buf_2 = * loop_write_buf ;
1110+ self -> next_write_buf_3 = * loop2_write_buf ;
10801111 self -> pending_buffers_write = pending_buffers_write ;
10811112
1082- if (self -> dma_completed_write && self -> once_write_buf .info .len ) {
1113+ if (self -> dma_completed_write && self -> next_write_buf_1 .info .len ) {
10831114 rp2pio_statemachine_dma_complete_write (self , SM_DMA_GET_CHANNEL_WRITE (pio_index , sm ));
10841115 self -> dma_completed_write = false;
10851116 }
@@ -1103,8 +1134,10 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
11031134 dma_channel_config c_write ;
11041135
11051136 self -> current_write_buf = * once_write_buf ;
1106- self -> once_write_buf = * loop_write_buf ;
1107- self -> loop_write_buf = * loop_write_buf ;
1137+ self -> next_write_buf_1 = * loop_write_buf ;
1138+ self -> next_write_buf_2 = * loop2_write_buf ;
1139+ self -> next_write_buf_3 = * loop_write_buf ;
1140+
11081141 self -> pending_buffers_write = pending_buffers_write ;
11091142 self -> dma_completed_write = false;
11101143 self -> background_stride_in_bytes = stride_in_bytes ;
@@ -1133,8 +1166,10 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
11331166}
11341167
11351168void rp2pio_statemachine_dma_complete_write (rp2pio_statemachine_obj_t * self , int channel_write ) {
1136- self -> current_write_buf = self -> once_write_buf ;
1137- self -> once_write_buf = self -> loop_write_buf ;
1169+ self -> current_write_buf = self -> next_write_buf_1 ;
1170+ self -> next_write_buf_1 = self -> next_write_buf_2 ;
1171+ self -> next_write_buf_2 = self -> next_write_buf_3 ;
1172+ self -> next_write_buf_3 = self -> next_write_buf_1 ;
11381173
11391174 if (self -> current_write_buf .info .buf ) {
11401175 if (self -> pending_buffers_write > 0 ) {
@@ -1153,8 +1188,9 @@ bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_ob
11531188 uint8_t sm = self -> state_machine ;
11541189 rp2pio_statemachine_clear_dma_write (pio_index , sm );
11551190 memset (& self -> current_write_buf , 0 , sizeof (self -> current_write_buf ));
1156- memset (& self -> once_write_buf , 0 , sizeof (self -> once_write_buf ));
1157- memset (& self -> loop_write_buf , 0 , sizeof (self -> loop_write_buf ));
1191+ memset (& self -> next_write_buf_1 , 0 , sizeof (self -> next_write_buf_1 ));
1192+ memset (& self -> next_write_buf_2 , 0 , sizeof (self -> next_write_buf_2 ));
1193+ memset (& self -> next_write_buf_3 , 0 , sizeof (self -> next_write_buf_3 ));
11581194 self -> pending_buffers_write = 0 ;
11591195 return true;
11601196}
@@ -1176,9 +1212,37 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
11761212 uint8_t pio_index = pio_get_index (self -> pio );
11771213 uint8_t sm = self -> state_machine ;
11781214
1179- int pending_buffers_read = (once_read_buf -> info .len != 0 ) + (loop_read_buf -> info .len != 0 );
1215+ int pending_buffers_read = (once_read_buf -> info .len != 0 ) + (loop_read_buf -> info .len != 0 ) + (loop2_read_buf -> info .len != 0 );
1216+
1217+ // If all buffer arguments have nonzero length, read once_read_buf, loop_read_buf, loop2_read_buf and repeat last two forever
1218+
11801219 if (!once_read_buf -> info .len ) {
1181- once_read_buf = loop_read_buf ;
1220+ if (!loop_read_buf -> info .len ) {
1221+ // If once_read_buf and loop_read_buf have zero length, read loop2_read_buf forever
1222+ once_read_buf = loop2_read_buf ;
1223+ loop_read_buf = loop2_read_buf ;
1224+ } else {
1225+ if (!loop2_read_buf -> info .len ) {
1226+ // If once_read_buf and loop2_read_buf have zero length, read loop_read_buf forever
1227+ once_read_buf = loop_read_buf ;
1228+ loop2_read_buf = loop_read_buf ;
1229+ } else {
1230+ // If only once_read_buf has zero length, read loop_read_buf, loop2_read_buf, and repeat last two forever
1231+ once_read_buf = loop_read_buf ;
1232+ loop_read_buf = loop2_read_buf ;
1233+ loop2_read_buf = once_read_buf ;
1234+ }
1235+ }
1236+ } else {
1237+ if (!loop_read_buf -> info .len ) {
1238+ // If once_read_buf has nonzero length and loop_read_buf has zero length, read once_read_buf, loop2_read_buf and repeat last buf forever
1239+ loop_read_buf = loop2_read_buf ;
1240+ } else {
1241+ if (!loop2_read_buf -> info .len ) {
1242+ // If once_read_buf has nonzero length and loop2_read_buf have zero length, read once_read_buf, loop_read_buf and repeat last buf forever
1243+ loop2_read_buf = loop_read_buf ;
1244+ }
1245+ }
11821246 }
11831247
11841248 if (SM_DMA_ALLOCATED_READ (pio_index , sm )) {
@@ -1197,11 +1261,12 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
11971261 }
11981262
11991263 common_hal_mcu_disable_interrupts ();
1200- self -> once_read_buf = * once_read_buf ;
1201- self -> loop_read_buf = * loop_read_buf ;
1264+ self -> next_read_buf_1 = * once_read_buf ;
1265+ self -> next_read_buf_2 = * loop_read_buf ;
1266+ self -> next_read_buf_3 = * loop2_read_buf ;
12021267 self -> pending_buffers_read = pending_buffers_read ;
12031268
1204- if (self -> dma_completed_read && self -> once_read_buf .info .len ) {
1269+ if (self -> dma_completed_read && self -> next_read_buf_1 .info .len ) {
12051270 rp2pio_statemachine_dma_complete_read (self , SM_DMA_GET_CHANNEL_READ (pio_index , sm ));
12061271 self -> dma_completed_read = false;
12071272 }
@@ -1226,8 +1291,9 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
12261291 dma_channel_config c_read ;
12271292
12281293 self -> current_read_buf = * once_read_buf ;
1229- self -> once_read_buf = * loop_read_buf ;
1230- self -> loop_read_buf = * loop_read_buf ;
1294+ self -> next_read_buf_1 = * loop_read_buf ;
1295+ self -> next_read_buf_2 = * loop2_read_buf ;
1296+ self -> next_read_buf_3 = * loop_read_buf ;
12311297 self -> pending_buffers_read = pending_buffers_read ;
12321298 self -> dma_completed_read = false;
12331299
@@ -1254,8 +1320,11 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
12541320}
12551321
12561322void rp2pio_statemachine_dma_complete_read (rp2pio_statemachine_obj_t * self , int channel_read ) {
1257- self -> current_read_buf = self -> once_read_buf ;
1258- self -> once_read_buf = self -> loop_read_buf ;
1323+
1324+ self -> current_read_buf = self -> next_read_buf_1 ;
1325+ self -> next_read_buf_1 = self -> next_read_buf_2 ;
1326+ self -> next_read_buf_2 = self -> next_read_buf_3 ;
1327+ self -> next_read_buf_3 = self -> next_read_buf_1 ;
12591328
12601329 if (self -> current_read_buf .info .buf ) {
12611330 if (self -> pending_buffers_read > 0 ) {
@@ -1274,8 +1343,9 @@ bool common_hal_rp2pio_statemachine_stop_background_read(rp2pio_statemachine_obj
12741343 uint8_t sm = self -> state_machine ;
12751344 rp2pio_statemachine_clear_dma_read (pio_index , sm );
12761345 memset (& self -> current_read_buf , 0 , sizeof (self -> current_read_buf ));
1277- memset (& self -> once_read_buf , 0 , sizeof (self -> once_read_buf ));
1278- memset (& self -> loop_read_buf , 0 , sizeof (self -> loop_read_buf ));
1346+ memset (& self -> next_read_buf_1 , 0 , sizeof (self -> next_read_buf_1 ));
1347+ memset (& self -> next_read_buf_2 , 0 , sizeof (self -> next_read_buf_2 ));
1348+ memset (& self -> next_read_buf_3 , 0 , sizeof (self -> next_read_buf_3 ));
12791349 self -> pending_buffers_read = 0 ;
12801350 return true;
12811351}
0 commit comments