Skip to content

Commit bdf5009

Browse files
authored
Merge pull request #9 from dihm/manual_with_pio
Manual updates using PIO
2 parents 7887dc6 + 151c436 commit bdf5009

File tree

2 files changed

+72
-59
lines changed

2 files changed

+72
-59
lines changed

prawn_do/prawn_do.c

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
#define OUTPUT_WIDTH 16
2424
// mask which bits we are using
2525
uint32_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
}
246263
int 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
}

prawn_do/prawn_do.pio

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
.define public OUTPUT_PIN_BASE 0 ; first pin to output from
55
.define public OUTPUT_WIDTH 16 ; number of pins to output from
66

7-
; Immediately output the first entry so the outputs could be manually triggered
8-
;out pins, 32
9-
; pop off dummy reps value from OSR
10-
;out X, 32
117

128
start:
139
;wait 1 gpio TRIGGER_PIN
@@ -65,8 +61,8 @@ end_loop:
6561

6662

6763
% c-sdk {
68-
pio_sm_config prawn_do_program_init(PIO pio, uint state_machine, float div,
69-
uint offset){
64+
pio_sm_config prawn_do_program_init(PIO pio, uint state_machine, uint offset){
65+
7066
// Set pin direction of output pins to outputs
7167
pio_sm_set_consecutive_pindirs(pio, state_machine,
7268
prawn_do_OUTPUT_PIN_BASE,

0 commit comments

Comments
 (0)