2323#define OUTPUT_WIDTH 16
2424// mask which bits we are using
2525uint32_t output_mask = ((1 << OUTPUT_WIDTH ) - 1 ) << OUTPUT_PIN_BASE ;
26+ // command type enum
27+ enum COMMAND {
28+ BUFFERED_HWSTART = 3 << OUTPUT_WIDTH ,
29+ BUFFERED = 1 << OUTPUT_WIDTH ,
30+ MANUAL = 0
31+ };
2632
2733#define MAX_DO_CMDS 60000
2834// two DO CMDS per INSTRUCTION
@@ -69,12 +75,6 @@ void set_status(int new_status)
6975 mutex_exit (& status_mutex );
7076}
7177
72- void configure_gpio ()
73- {
74- gpio_init_mask (output_mask );
75- gpio_set_dir_out_masked (output_mask );
76- }
77-
7878/*
7979 Start pio state machine
8080
@@ -183,64 +183,81 @@ void core1_entry() {
183183 uint offset = pio_add_program (pio , & prawn_do_program ); // load prawn_do PIO
184184 // program
185185
186+ // initialize prawn_do PIO program on chosen PIO and state machine at
187+ // required offset
188+ pio_sm_config pio_config = prawn_do_program_init (pio , sm , offset );
189+
186190 // signal core1 ready for commands
187191 multicore_fifo_push_blocking (0 );
188192
189193 while (1 ){
190194 // wait for message from main core
191- uint32_t hwstart = multicore_fifo_pop_blocking ();
195+ uint32_t command = multicore_fifo_pop_blocking ();
192196
193- set_status (TRANSITION_TO_RUNNING );
194- if (debug ){
195- fast_serial_printf ("hwstart: %d\r\n" , hwstart );
196- }
197- // (re)initialize prawn_do PIO program on chosen PIO and state machine at
198- // required offset
199- pio_sm_config pio_config = prawn_do_program_init (pio , sm , 1.f , offset );
200- // start the state machine
201- start_sm (pio , sm , dma_chan , offset , hwstart );
202- set_status (RUNNING );
203-
204- // can save IRQ PIO instruction by using the following check instead
205- //while ((dma_channel_is_busy(dma_chan) // checks if dma finished
206- // || pio_sm_is_tx_fifo_empty(pio, sm)) // ensure fifo is empty once dma finishes
207- // && get_status() != ABORT_REQUESTED) // breaks if Abort requested
208- while (!pio_interrupt_get (pio , sm ) // breaks if PIO program reaches end
209- && get_status () != ABORT_REQUESTED // breaks if Abort requested
210- ){
211- // tight loop checking for run completion
212- // exits if program signals IRQ (at end) or abort requested
213- continue ;
214- }
215- // ensure interrupt is cleared
216- pio_interrupt_clear (pio , sm );
197+ if (command & BUFFERED ){
198+ // buffered execution
199+ uint32_t hwstart = (command & BUFFERED_HWSTART );
217200
218- if (debug ){
219- fast_serial_printf ("Tight execution loop ended\r\n" );
220- uint8_t pc = pio_sm_get_pc (pio , sm );
221- fast_serial_printf ("Program ended at instr %d\r\n" , pc - offset );
222- }
201+ set_status (TRANSITION_TO_RUNNING );
202+ if (debug ){
203+ fast_serial_printf ("hwstart: %d\r\n" , hwstart );
204+ }
205+ // start the state machine
206+ start_sm (pio , sm , dma_chan , offset , hwstart );
207+ set_status (RUNNING );
208+
209+ // can save IRQ PIO instruction by using the following check instead
210+ //while ((dma_channel_is_busy(dma_chan) // checks if dma finished
211+ // || pio_sm_is_tx_fifo_empty(pio, sm)) // ensure fifo is empty once dma finishes
212+ // && get_status() != ABORT_REQUESTED) // breaks if Abort requested
213+ while (!pio_interrupt_get (pio , sm ) // breaks if PIO program reaches end
214+ && get_status () != ABORT_REQUESTED // breaks if Abort requested
215+ ){
216+ // tight loop checking for run completion
217+ // exits if program signals IRQ (at end) or abort requested
218+ continue ;
219+ }
220+ // ensure interrupt is cleared
221+ pio_interrupt_clear (pio , sm );
223222
224- if (get_status () == ABORT_REQUESTED ){
225- set_status (ABORTING );
226- stop_sm (pio , sm , dma_chan );
227- set_status (ABORTED );
228223 if (debug ){
229- fast_serial_printf ("Aborted execution\r\n" );
224+ fast_serial_printf ("Tight execution loop ended\r\n" );
225+ uint8_t pc = pio_sm_get_pc (pio , sm );
226+ fast_serial_printf ("Program ended at instr %d\r\n" , pc - offset );
227+ }
228+
229+ if (get_status () == ABORT_REQUESTED ){
230+ set_status (ABORTING );
231+ stop_sm (pio , sm , dma_chan );
232+ set_status (ABORTED );
233+ if (debug ){
234+ fast_serial_printf ("Aborted execution\r\n" );
235+ }
236+ }
237+ else {
238+ set_status (TRANSITION_TO_STOP );
239+ stop_sm (pio , sm , dma_chan );
240+ set_status (STOPPED );
241+ if (debug ){
242+ fast_serial_printf ("Execution stopped\r\n" );
243+ }
244+ }
245+ if (debug ){
246+ fast_serial_printf ("Core1 loop ended\r\n" );
230247 }
231248 }
232249 else {
233- set_status (TRANSITION_TO_STOP );
234- stop_sm (pio , sm , dma_chan );
235- set_status (STOPPED );
250+ // manual update
251+ uint32_t manual_state = command ;
252+ // put new state into the TX FIFO
253+ pio_sm_put_blocking (pio , sm , manual_state );
254+ // pull FIFO into scratch register and update pins
255+ pio_sm_exec_wait_blocking (pio , sm , pio_encode_out (pio_pins , 32 ));
236256 if (debug ){
237- fast_serial_printf ("Execution stopped \r\n" );
257+ fast_serial_printf ("Output commanded: %x \r\n" , manual_state );
238258 }
259+
239260 }
240- if (debug ){
241- fast_serial_printf ("Core1 loop ended\r\n" );
242- }
243-
244261 }
245262}
246263int main (){
@@ -332,12 +349,12 @@ int main(){
332349 }
333350 // Run command: start state machine
334351 else if (strncmp (serial_buf , "run" , 3 ) == 0 ){
335- multicore_fifo_push_blocking (1 );
352+ multicore_fifo_push_blocking (BUFFERED_HWSTART );
336353 fast_serial_printf ("ok\r\n" );
337354 }
338355 // Software start: start state machine without waiting for trigger
339356 else if (strncmp (serial_buf , "swr" , 3 ) == 0 ){
340- multicore_fifo_push_blocking (0 );
357+ multicore_fifo_push_blocking (BUFFERED );
341358 fast_serial_printf ("ok\r\n" );
342359 }
343360 // Manual update of outputs
@@ -348,8 +365,8 @@ int main(){
348365 fast_serial_printf ("invalid request\r\n" );
349366 }
350367 else {
351- configure_gpio ();
352- gpio_put_masked ( output_mask , manual_state );
368+ // bit-shift state up by one to signal manual update
369+ multicore_fifo_push_blocking ( manual_state );
353370 fast_serial_printf ("ok\r\n" );
354371 }
355372 }
0 commit comments