Skip to content

Commit 265bc30

Browse files
committed
Move manual updates to the PIO state machine.
This prevents output blanking during programming manual updates or transitioning between manual and buffered.
1 parent 7887dc6 commit 265bc30

File tree

1 file changed

+62
-45
lines changed

1 file changed

+62
-45
lines changed

prawn_do/prawn_do.c

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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, 1.f, 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 == 0 || command == 1){
198+
// buffered execution
199+
uint32_t hwstart = command;
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);
222+
223+
if(debug){
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+
}
223228

224-
if(get_status() == ABORT_REQUESTED){
225-
set_status(ABORTING);
226-
stop_sm(pio, sm, dma_chan);
227-
set_status(ABORTED);
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+
}
228245
if(debug){
229-
fast_serial_printf("Aborted execution\r\n");
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 >> 1;
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
}
246263
int main(){
@@ -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 << 1);
353370
fast_serial_printf("ok\r\n");
354371
}
355372
}

0 commit comments

Comments
 (0)