aboutsummaryrefslogtreecommitdiff
path: root/tests/rp/src/bin/pio_multi_load.rs
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-07-28 18:45:57 +0200
committerpennae <[email protected]>2023-07-28 19:33:02 +0200
commitcbc8871a0bb40eb5fec82e7c27ed4c0127844c3c (patch)
tree333ab4bc2d1893d42529c6a378ea51c42f8c8d22 /tests/rp/src/bin/pio_multi_load.rs
parentd752a3f9808ec9be64c720d3f80f152f0b7507df (diff)
rp: relocate programs implicitly during load
this removed the RelocatedProgram construction step from pio uses. there's not all that much to be said for the extra step because the origin can be set on the input program itself, and the remaining information exposed by RelocatedProgram can be exposed from LoadedProgram instead (even though it's already available on the pio_asm programs, albeit perhaps less convenient). we do lose access to the relocated instruction iterator, but we also cannot think of anything this iterator would actually be useful for outside of program loading.
Diffstat (limited to 'tests/rp/src/bin/pio_multi_load.rs')
-rw-r--r--tests/rp/src/bin/pio_multi_load.rs126
1 files changed, 126 insertions, 0 deletions
diff --git a/tests/rp/src/bin/pio_multi_load.rs b/tests/rp/src/bin/pio_multi_load.rs
new file mode 100644
index 000000000..356f16795
--- /dev/null
+++ b/tests/rp/src/bin/pio_multi_load.rs
@@ -0,0 +1,126 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4#[path = "../common.rs"]
5mod common;
6
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::bind_interrupts;
10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio};
12use {defmt_rtt as _, panic_probe as _};
13
14bind_interrupts!(struct Irqs {
15 PIO0_IRQ_0 => InterruptHandler<PIO0>;
16});
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 let p = embassy_rp::init(Default::default());
21 let pio = p.PIO0;
22 let Pio {
23 mut common,
24 mut sm0,
25 mut sm1,
26 mut sm2,
27 irq_flags,
28 ..
29 } = Pio::new(pio, Irqs);
30
31 // load with explicit origin works
32 let prg1 = pio_proc::pio_asm!(
33 ".origin 4"
34 "nop",
35 "nop",
36 "nop",
37 "nop",
38 "nop",
39 "nop",
40 "nop",
41 "irq 0",
42 "nop",
43 "nop",
44 );
45 let loaded1 = common.load_program(&prg1.program);
46 assert_eq!(loaded1.origin, 4);
47 assert_eq!(loaded1.wrap.source, 13);
48 assert_eq!(loaded1.wrap.target, 4);
49
50 // load without origin chooses a free space
51 let prg2 = pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 1", "nop", "nop",);
52 let loaded2 = common.load_program(&prg2.program);
53 assert_eq!(loaded2.origin, 14);
54 assert_eq!(loaded2.wrap.source, 23);
55 assert_eq!(loaded2.wrap.target, 14);
56
57 // wrapping around the end of program space automatically works
58 let prg3 =
59 pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 2",);
60 let loaded3 = common.load_program(&prg3.program);
61 assert_eq!(loaded3.origin, 24);
62 assert_eq!(loaded3.wrap.source, 3);
63 assert_eq!(loaded3.wrap.target, 24);
64
65 // check that the programs actually work
66 {
67 let mut cfg = Config::default();
68 cfg.use_program(&loaded1, &[]);
69 sm0.set_config(&cfg);
70 sm0.set_enable(true);
71 while !irq_flags.check(0) {}
72 sm0.set_enable(false);
73 }
74 {
75 let mut cfg = Config::default();
76 cfg.use_program(&loaded2, &[]);
77 sm1.set_config(&cfg);
78 sm1.set_enable(true);
79 while !irq_flags.check(1) {}
80 sm1.set_enable(false);
81 }
82 {
83 let mut cfg = Config::default();
84 cfg.use_program(&loaded3, &[]);
85 sm2.set_config(&cfg);
86 sm2.set_enable(true);
87 while !irq_flags.check(2) {}
88 sm2.set_enable(false);
89 }
90
91 // instruction memory is full now. all loads should fail.
92 {
93 let prg = pio_proc::pio_asm!(".origin 0", "nop");
94 match common.try_load_program(&prg.program) {
95 Err(LoadError::AddressInUse(0)) => (),
96 _ => panic!("program loaded when it shouldn't"),
97 };
98
99 let prg = pio_proc::pio_asm!("nop");
100 match common.try_load_program(&prg.program) {
101 Err(LoadError::InsufficientSpace) => (),
102 _ => panic!("program loaded when it shouldn't"),
103 };
104 }
105
106 // freeing some memory should allow further loads though.
107 unsafe {
108 common.free_instr(loaded3.used_memory);
109 }
110 {
111 let prg = pio_proc::pio_asm!(".origin 0", "nop");
112 match common.try_load_program(&prg.program) {
113 Ok(_) => (),
114 _ => panic!("program didn't loaded when it shouldn"),
115 };
116
117 let prg = pio_proc::pio_asm!("nop");
118 match common.try_load_program(&prg.program) {
119 Ok(_) => (),
120 _ => panic!("program didn't loaded when it shouldn"),
121 };
122 }
123
124 info!("Test OK");
125 cortex_m::asm::bkpt();
126}