46
loading...
This website collects cookies to deliver better user experience
main
function.program
section in which you define the PIO instructions, and a c-sdk
section that contains a function for exposing the PIO program to your main
program. The basic layout is this:.program hello
...
% c-sdk {
...
%}
.program hello
set pindirs, 1
loop:
set pins, 1 [31]
set pins, 0 [31]
jmp loop
program
statement starts the declaration of a PIO program. It needs to have an identifier, which will be used during the compilation and linking process.SET
instruction is a multi-purpose statement. This line means that we will set all configured set pins to be outputsloop
declaration is a free-form label to group parts of a larger program.JMP
we go back to the previous defined loop
label.% c-sdk {
static inline void hello_program_init(PIO pio, uint sm, uint offset, uint pin) {
// 1. Define a config object
pio_sm_config config = hello_program_get_default_config(offset);
// 2. Set and initialize the output pins
sm_config_set_set_pins(&config, pin, 1);
// 3. Apply the configuration & activate the State Machine
pio_sm_init(pio, sm, offset, &config);
pio_sm_set_enabled(pio, sm, true);
}
%}
#include <stdio.h>
#include <stdbool.h>
#include <pico/stdlib.h>
#include <hardware/pio.h>
#include <hello.pio.h>
#define LED_BUILTIN 25;
int main() {
stdio_init_all();
PIO pio = pio0;
uint state_machine_id = 0;
uint offset = pio_add_program(pio, &hello_program);
hello_program_init(pio, state_machine_id, offset, LED_BUILTIN, 1);
while(1) {
//do nothing
}
}
hello_program_init
, and define a pointer to the program as hello_program
. Mind the naming conventions!x
and y
, these 32-bit registers allow you to store any additional data that is required for the state machine..program NAME
- the name of the program, and also the name of the header file that will be generated during compilation to give you access to the state machine in your main program.define NAME VALUE
- similar to your C program, you can define top-level constants that are visible in the state machineLABEL:
- labels are syntactic grouping of related statements. You can define any label, and then jump back to it; COMMENT
- Anything behind a semicolon is a comment.wrap_target
and .wrap
- Instructions to repeatedly run a section of you PIO program.word
- Store a raw 16-bit value as instructions in the program (each PIO statement is a 16-bit value).side_set COUNT (opt)
- This instruction additionally configures the SIDE pins of this program. The COUNT value is the number of bits that is reduced from the instruction, and the opt value determines whether side
statements inside your PIO program are optional or mandatory. When you work with this declaration, then you can attach additional commands to all expressions, for example out x, 1 side 0
would shift one bite from the OSR
to the FIFO RX, and set the SIDE pin to logic level LOW.in SOURCE count
- Shift data into the ISR, where SOURCE can be X
, Y
, OSR
or ISR
, and count is 0...32
out DESTINATION count
- Shift data out of the OSR, to DESTINATION X
, Y
, ISR
mov DESTINATION, SOURCE
- Move data from SOURCE (X
, Y
, OSR
or ISR
) to DESTINATION (X
, Y
, OSR
or ISR
)set DESTIANTION, data
- write a 5-bit data value to DESTIANTION (X
, Y
)pull
- Load data from the TX FIFO into the OSRpush
- Push data from the ISR to the RX FIFO, then clear the ISRirq INDEX op
- Modify the IRQ number index
to be either cleared (op=0
) or set (op=1
)set PINDIRS, 1
- define the configured SET pins as output pinsset PINS, value
- write HIGH (value=1
) or LOW (value=1
) to the SET pinsmov PINS, SOURCE
- write from SOURCE (X
, Y
, OSR
, ISR
) to OUT pins
(X
, Y
, OSR
or ISR
)set PINDIRS, 0
- define the configured SET pins as input pinsmov DESTINATION, PINS
- write from IN pins to DESTINATION (X
, Y
, OSR
, ISR
, and OUT PINS
)jmp CONDITION LABEL
- go to LABEL
when one the following type of CONDITION
is true
!(X|Y|OSRE)
- true when X
, Y
, OSR
is emptyX-- | Y--)
- true when scratch register is empty, otherwise decrement the scratch registerPIN
- true when the JUMP pin is logic level HIGHwait POLARITY TYPE NUMBER
- delay the further processing until the POLARITY matches the ..
pin NUMBER
- INPUT pingpio NUMBER
- absolutely numbered gpioirq NUMBER
- IRQ number (if POLARITY is 1, the IRQ number is cleared)nop
- Don’t do anythingJMP
instructionstatic inline void __program_init(PIO pio, uint sm, uint offset, uint in_pin, uint in_pin_count, uint out_pin, uint out_pin_count, float frequency) {
// 1. Define a config object
pio_sm_config config = __program_get_default_config(offset);
// 2. Set and initialize the input pins
sm_config_set_in_pins(&config, in_pin);
pio_sm_set_consecutive_pindirs(pio, sm, in_pin, in_pin_count, 1);
pio_gpio_init(pio, in_pin);
// 3. Set and initialize the output pins
sm_config_set_out_pins(&config, out_pin, out_pin_count);
pio_sm_set_consecutive_pindirs(pio, sm, out_pin, out_pin_count, 0);
// 4. Set clock divider
if (frequency < 2000) {
frequency = 2000;
}
float clock_divider = (float) clock_get_hz(clk_sys) / frequency * 1000;
sm_config_set_clkdiv(&config, clock_divider);
// 5. Configure input shift register
// args: BOOL right_shift, BOOL auto_push, 1..32 push_threshold
sm_config_set_in_shift(&config, true, false, 32);
// 6. Configure output shift register
// args: BOOL right_shift, BOOL auto_push, 1..32 push_threshold
sm_config_set_out_shift(&config, true, false, 32);
// 7. Join the ISR & OSR
// PIO_FIFO_JOIN_NONE = 0, PIO_FIFO_JOIN_TX = 1, PIO_FIFO_JOIN_RX = 2
sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_NONE);
// 8. Apply the configuration
pio_sm_init(pio, sm, offset, &config);
// 9. Activate the State Machine
pio_sm_set_enabled(pio, sm, true);
}
46