@@ -1061,17 +1061,47 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
10611061}
10621062
10631063bool common_hal_rp2pio_statemachine_background_write (rp2pio_statemachine_obj_t * self ,
1064- const sm_buf_info * once_write_buf , const sm_buf_info * loop_write_buf , const sm_buf_info * write_loop2_buf ,
1064+ const sm_buf_info * once_write_buf , const sm_buf_info * loop_write_buf , const sm_buf_info * loop2_write_buf ,
10651065 uint8_t stride_in_bytes , bool swap ) {
10661066
10671067 uint8_t pio_index = pio_get_index (self -> pio );
10681068 uint8_t sm = self -> state_machine ;
10691069
1070- int pending_buffers_write = (once_write_buf -> info .len != 0 ) + (loop_write_buf -> info .len != 0 );
1070+ int pending_buffers_write = (once_write_buf -> info .len != 0 ) + (loop_write_buf -> info .len != 0 ) + (loop2_write_buf -> info .len != 0 );
1071+
1072+ // If all buffer arguments have nonzero length, write once_write_buf, loop_write_buf, loop2_write_buf and repeat last two forever
1073+
10711074 if (!once_write_buf -> info .len ) {
1072- once_write_buf = loop_write_buf ;
1075+ if (!loop_write_buf -> info .len ) {
1076+ // If once_write_buf and loop_write_buf have zero length, write loop2_write_buf forever
1077+ once_write_buf = loop2_write_buf ;
1078+ loop_write_buf = loop2_write_buf ;
1079+ } else {
1080+ if (!loop2_write_buf -> info .len ) {
1081+ // If once_write_buf and loop2_write_buf have zero length, write loop_write_buf forever
1082+ once_write_buf = loop_write_buf ;
1083+ loop2_write_buf = loop_write_buf ;
1084+ } else {
1085+ // If only once_write_buf has zero length, write loop_write_buf, loop2_write_buf, and repeat last two forever
1086+ once_write_buf = loop_write_buf ;
1087+ loop_write_buf = loop2_write_buf ;
1088+ loop2_write_buf = once_write_buf ;
1089+ }
1090+ }
1091+ } else {
1092+ if (!loop_write_buf -> info .len ) {
1093+ // 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
1094+ loop_write_buf = loop2_write_buf ;
1095+ } else {
1096+ if (!loop2_write_buf -> info .len ) {
1097+ // 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
1098+ loop2_write_buf = loop_write_buf ;
1099+ }
1100+ }
10731101 }
10741102
1103+ // if DMA is already going (i.e. this is not the first call to background_write),
1104+ // block until once_write_buf and loop_write_buf have each been written at least once
10751105 if (SM_DMA_ALLOCATED_WRITE (pio_index , sm )) {
10761106 if (stride_in_bytes != self -> background_stride_in_bytes ) {
10771107 mp_raise_ValueError (MP_ERROR_TEXT ("Mismatched data size" ));
@@ -1088,11 +1118,12 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
10881118 }
10891119
10901120 common_hal_mcu_disable_interrupts ();
1091- self -> once_write_buf = * once_write_buf ;
1092- self -> loop_write_buf = * loop_write_buf ;
1121+ self -> next_write_buf_1 = * once_write_buf ;
1122+ self -> next_write_buf_2 = * loop_write_buf ;
1123+ self -> next_write_buf_3 = * loop2_write_buf ;
10931124 self -> pending_buffers_write = pending_buffers_write ;
10941125
1095- if (self -> dma_completed_write && self -> once_write_buf .info .len ) {
1126+ if (self -> dma_completed_write && self -> next_write_buf_1 .info .len ) {
10961127 rp2pio_statemachine_dma_complete_write (self , SM_DMA_GET_CHANNEL_WRITE (pio_index , sm ));
10971128 self -> dma_completed_write = false;
10981129 }
@@ -1116,8 +1147,10 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
11161147 dma_channel_config c_write ;
11171148
11181149 self -> current_write_buf = * once_write_buf ;
1119- self -> once_write_buf = * loop_write_buf ;
1120- self -> loop_write_buf = * loop_write_buf ;
1150+ self -> next_write_buf_1 = * loop_write_buf ;
1151+ self -> next_write_buf_2 = * loop2_write_buf ;
1152+ self -> next_write_buf_3 = * loop_write_buf ;
1153+
11211154 self -> pending_buffers_write = pending_buffers_write ;
11221155 self -> dma_completed_write = false;
11231156 self -> background_stride_in_bytes = stride_in_bytes ;
@@ -1150,8 +1183,10 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
11501183}
11511184
11521185void rp2pio_statemachine_dma_complete_write (rp2pio_statemachine_obj_t * self , int channel_write ) {
1153- self -> current_write_buf = self -> once_write_buf ;
1154- self -> once_write_buf = self -> loop_write_buf ;
1186+ self -> current_write_buf = self -> next_write_buf_1 ;
1187+ self -> next_write_buf_1 = self -> next_write_buf_2 ;
1188+ self -> next_write_buf_2 = self -> next_write_buf_3 ;
1189+ self -> next_write_buf_3 = self -> next_write_buf_1 ;
11551190
11561191 if (self -> current_write_buf .info .buf ) {
11571192 if (self -> pending_buffers_write > 0 ) {
@@ -1170,8 +1205,9 @@ bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_ob
11701205 uint8_t sm = self -> state_machine ;
11711206 rp2pio_statemachine_clear_dma_write (pio_index , sm );
11721207 memset (& self -> current_write_buf , 0 , sizeof (self -> current_write_buf ));
1173- memset (& self -> once_write_buf , 0 , sizeof (self -> once_write_buf ));
1174- memset (& self -> loop_write_buf , 0 , sizeof (self -> loop_write_buf ));
1208+ memset (& self -> next_write_buf_1 , 0 , sizeof (self -> next_write_buf_1 ));
1209+ memset (& self -> next_write_buf_2 , 0 , sizeof (self -> next_write_buf_2 ));
1210+ memset (& self -> next_write_buf_3 , 0 , sizeof (self -> next_write_buf_3 ));
11751211 self -> pending_buffers_write = 0 ;
11761212 return true;
11771213}
@@ -1193,9 +1229,37 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
11931229 uint8_t pio_index = pio_get_index (self -> pio );
11941230 uint8_t sm = self -> state_machine ;
11951231
1196- int pending_buffers_read = (once_read_buf -> info .len != 0 ) + (loop_read_buf -> info .len != 0 );
1232+ int pending_buffers_read = (once_read_buf -> info .len != 0 ) + (loop_read_buf -> info .len != 0 ) + (loop2_read_buf -> info .len != 0 );
1233+
1234+ // If all buffer arguments have nonzero length, read once_read_buf, loop_read_buf, loop2_read_buf and repeat last two forever
1235+
11971236 if (!once_read_buf -> info .len ) {
1198- once_read_buf = loop_read_buf ;
1237+ if (!loop_read_buf -> info .len ) {
1238+ // If once_read_buf and loop_read_buf have zero length, read loop2_read_buf forever
1239+ once_read_buf = loop2_read_buf ;
1240+ loop_read_buf = loop2_read_buf ;
1241+ } else {
1242+ if (!loop2_read_buf -> info .len ) {
1243+ // If once_read_buf and loop2_read_buf have zero length, read loop_read_buf forever
1244+ once_read_buf = loop_read_buf ;
1245+ loop2_read_buf = loop_read_buf ;
1246+ } else {
1247+ // If only once_read_buf has zero length, read loop_read_buf, loop2_read_buf, and repeat last two forever
1248+ once_read_buf = loop_read_buf ;
1249+ loop_read_buf = loop2_read_buf ;
1250+ loop2_read_buf = once_read_buf ;
1251+ }
1252+ }
1253+ } else {
1254+ if (!loop_read_buf -> info .len ) {
1255+ // 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
1256+ loop_read_buf = loop2_read_buf ;
1257+ } else {
1258+ if (!loop2_read_buf -> info .len ) {
1259+ // 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
1260+ loop2_read_buf = loop_read_buf ;
1261+ }
1262+ }
11991263 }
12001264
12011265 if (SM_DMA_ALLOCATED_READ (pio_index , sm )) {
@@ -1214,11 +1278,12 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
12141278 }
12151279
12161280 common_hal_mcu_disable_interrupts ();
1217- self -> once_read_buf = * once_read_buf ;
1218- self -> loop_read_buf = * loop_read_buf ;
1281+ self -> next_read_buf_1 = * once_read_buf ;
1282+ self -> next_read_buf_2 = * loop_read_buf ;
1283+ self -> next_read_buf_3 = * loop2_read_buf ;
12191284 self -> pending_buffers_read = pending_buffers_read ;
12201285
1221- if (self -> dma_completed_read && self -> once_read_buf .info .len ) {
1286+ if (self -> dma_completed_read && self -> next_read_buf_1 .info .len ) {
12221287 rp2pio_statemachine_dma_complete_read (self , SM_DMA_GET_CHANNEL_READ (pio_index , sm ));
12231288 self -> dma_completed_read = false;
12241289 }
@@ -1243,8 +1308,9 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
12431308 dma_channel_config c_read ;
12441309
12451310 self -> current_read_buf = * once_read_buf ;
1246- self -> once_read_buf = * loop_read_buf ;
1247- self -> loop_read_buf = * loop_read_buf ;
1311+ self -> next_read_buf_1 = * loop_read_buf ;
1312+ self -> next_read_buf_2 = * loop2_read_buf ;
1313+ self -> next_read_buf_3 = * loop_read_buf ;
12481314 self -> pending_buffers_read = pending_buffers_read ;
12491315 self -> dma_completed_read = false;
12501316
@@ -1271,8 +1337,11 @@ bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *s
12711337}
12721338
12731339void rp2pio_statemachine_dma_complete_read (rp2pio_statemachine_obj_t * self , int channel_read ) {
1274- self -> current_read_buf = self -> once_read_buf ;
1275- self -> once_read_buf = self -> loop_read_buf ;
1340+
1341+ self -> current_read_buf = self -> next_read_buf_1 ;
1342+ self -> next_read_buf_1 = self -> next_read_buf_2 ;
1343+ self -> next_read_buf_2 = self -> next_read_buf_3 ;
1344+ self -> next_read_buf_3 = self -> next_read_buf_1 ;
12761345
12771346 if (self -> current_read_buf .info .buf ) {
12781347 if (self -> pending_buffers_read > 0 ) {
@@ -1291,8 +1360,9 @@ bool common_hal_rp2pio_statemachine_stop_background_read(rp2pio_statemachine_obj
12911360 uint8_t sm = self -> state_machine ;
12921361 rp2pio_statemachine_clear_dma_read (pio_index , sm );
12931362 memset (& self -> current_read_buf , 0 , sizeof (self -> current_read_buf ));
1294- memset (& self -> once_read_buf , 0 , sizeof (self -> once_read_buf ));
1295- memset (& self -> loop_read_buf , 0 , sizeof (self -> loop_read_buf ));
1363+ memset (& self -> next_read_buf_1 , 0 , sizeof (self -> next_read_buf_1 ));
1364+ memset (& self -> next_read_buf_2 , 0 , sizeof (self -> next_read_buf_2 ));
1365+ memset (& self -> next_read_buf_3 , 0 , sizeof (self -> next_read_buf_3 ));
12961366 self -> pending_buffers_read = 0 ;
12971367 return true;
12981368}
0 commit comments