This repository was archived by the owner on May 28, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.pio
More file actions
66 lines (52 loc) · 3.64 KB
/
main.pio
File metadata and controls
66 lines (52 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
.program bitbang0 ; define program name
.side_set 1 ; dedicate one of the five timing bits for the pinout value
; define some constants
.define public upkeep_instruction_count 4
/*.define public clock_divisor 1000*/
.define public clock_divisor 10
; python stuff from the example that "we don't have to worry about"
/*.lang_opt python sideset_init = pico.PIO.OUT_HIGH15*/
/*.lang_opt python out_init = pico.PIO.OUT_HIGH16*/
/*.lang_opt python out_shiftdir = 1*/
// each cycle runs for delay_unit * fifo_value + 2 instructions
.wrap_target
pull noblock side 0 ; TODO: pull until last value (skip if queue has many)
out x, 32 side 1
mov y, x side 1
offwait:
jmp y-- offwait side 1
mov y, x side 0
onwait:
jmp y-- onwait side 0
.wrap
% c-sdk {
// yoinked from https://github.com/raspberrypi/pico-examples/blob/master/pio/ws2812/ws2812.pio#L31-L47 and https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdfpg 41
#include "hardware/clocks.h"
static inline float pio_clock_freq()
{
return clock_get_hz(clk_sys);
}
static inline void bitbang0_init(
PIO pio, // which of the two PIO instances we are using
uint sm, // which (of four) state machine to use
uint offset, // where the program is loaded (in the 5 bit address space, (but TODO actually 4 bc we stole a bit for the output value?))
uint pin, // the pin to wiggle
float freq // 'frequency or baud rate' of the output, whatever that means
) {
pio_gpio_init(pio, pin); // init the pin for pio usage
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); // set a range (of length one, aka one pin) to be output
pio_sm_config c = bitbang0_program_get_default_config(offset); // get the default config??????? which we will modify
sm_config_set_sideset_pins(&c, pin); // set the sideset pin. we have .side_set 1 so its only one pin, but with .side_set 3 it would set three pins
//sm_config_set_out_shift(&c, false, true, 32); // configure the out instruction
// ^^^^^ false for shifting MSB first
// ^^^^ true for autopullg MSB first
// ^^ autopull trheshhold, aka number of bits before the OSR register is refilled from the fifo
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); // HELPPPP not documented in the datasheet
int cycles_per_bit = 4; // can use constants declared in assembly bc they were declared with `public`
/*float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); // some math to divide up the clock speed to get the correct bitrate*/
float div = bitbang0_clock_divisor;
sm_config_set_clkdiv(&c, div); // divide the actual clock speed so the state machine ticks once every `div` core clocks
pio_sm_init(pio, sm, offset, &c); // load config into state machine and go to the start adress
pio_sm_set_enabled(pio, sm, true); // launch!
}
%}