aboutsummaryrefslogtreecommitdiff
path: root/examples/rp/src/bin/pio_async.rs
blob: 1b075b8fd5f216b2c658b870c72d6b2b7da8a84e (plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::info;
use embassy_executor::Spawner;
use embassy_rp::gpio::{AnyPin, Pin};
use embassy_rp::pio::{
    Pio0, PioCommon, PioCommonInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0,
    Sm1, Sm2,
};
use embassy_rp::pio_instr_util;
use embassy_rp::relocate::RelocatedProgram;
use {defmt_rtt as _, panic_probe as _};

fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
    // Setup sm0

    // Send data serially to pin
    let prg = pio_proc::pio_asm!(
        ".origin 16",
        "set pindirs, 1",
        ".wrap_target",
        "out pins,1 [19]",
        ".wrap",
    );

    let relocated = RelocatedProgram::new(&prg.program);
    let out_pin = pio.make_pio_pin(pin);
    let pio_pins = [&out_pin];
    sm.set_out_pins(&pio_pins);
    pio.write_instr(relocated.origin() as usize, relocated.code());
    pio_instr_util::exec_jmp(sm, relocated.origin());
    sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32);
    sm.set_set_range(0, 1);
    let pio::Wrap { source, target } = relocated.wrap();
    sm.set_wrap(source, target);

    sm.set_autopull(true);
    sm.set_out_shift_dir(ShiftDirection::Left);
}

#[embassy_executor::task]
async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>) {
    sm.set_enable(true);

    let mut v = 0x0f0caffa;
    loop {
        sm.wait_push(v).await;
        v ^= 0xffff;
        info!("Pushed {:032b} to FIFO", v);
    }
}

fn setup_pio_task_sm1(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm1>) {
    // Setupm sm1

    // Read 0b10101 repeatedly until ISR is full
    let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",);

    let relocated = RelocatedProgram::new(&prg.program);
    pio.write_instr(relocated.origin() as usize, relocated.code());
    pio_instr_util::exec_jmp(sm, relocated.origin());
    sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
    sm.set_set_range(0, 0);
    let pio::Wrap { source, target } = relocated.wrap();
    sm.set_wrap(source, target);

    sm.set_autopush(true);
    sm.set_in_shift_dir(ShiftDirection::Right);
}

#[embassy_executor::task]
async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
    sm.set_enable(true);
    loop {
        let rx = sm.wait_pull().await;
        info!("Pulled {:032b} from FIFO", rx);
    }
}

fn setup_pio_task_sm2(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm2>) {
    // Setup sm2

    // Repeatedly trigger IRQ 3
    let prg = pio_proc::pio_asm!(
        ".origin 0",
        ".wrap_target",
        "set x,10",
        "delay:",
        "jmp x-- delay [15]",
        "irq 3 [15]",
        ".wrap",
    );
    let relocated = RelocatedProgram::new(&prg.program);
    pio.write_instr(relocated.origin() as usize, relocated.code());

    let pio::Wrap { source, target } = relocated.wrap();
    sm.set_wrap(source, target);

    pio_instr_util::exec_jmp(sm, relocated.origin());
    sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
}

#[embassy_executor::task]
async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
    sm.set_enable(true);
    loop {
        sm.wait_irq(3).await;
        info!("IRQ trigged");
    }
}

#[embassy_executor::main]
async fn main(spawner: Spawner) {
    let p = embassy_rp::init(Default::default());
    let pio = p.PIO0;

    let (mut pio0, mut sm0, mut sm1, mut sm2, ..) = pio.split();

    setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade());
    setup_pio_task_sm1(&mut pio0, &mut sm1);
    setup_pio_task_sm2(&mut pio0, &mut sm2);
    spawner.spawn(pio_task_sm0(sm0)).unwrap();
    spawner.spawn(pio_task_sm1(sm1)).unwrap();
    spawner.spawn(pio_task_sm2(sm2)).unwrap();
}