added pio-based rotary encoder reading.
This commit is contained in:
parent
6f6ecc833e
commit
c726ab4aa7
|
@ -20,6 +20,8 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
|
|||
rp-pico = "0.8"
|
||||
max31855 = "0.1.0"
|
||||
hd44780-driver = "0.4.0"
|
||||
pio-proc = "0.2"
|
||||
pio = "0.2"
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
|
|
51
src/encoder.pio
Normal file
51
src/encoder.pio
Normal file
|
@ -0,0 +1,51 @@
|
|||
; from https://github.com/GitJer/Rotary_encoder/blob/master/pio_rotary_encoder.pio
|
||||
.program pio_rotary_encoder
|
||||
.wrap_target
|
||||
.origin 0 ; The jump table has to start at 0
|
||||
; it contains the correct jumps for each of the 16
|
||||
; combination of 4 bits formed by A'B'AB
|
||||
; A = current reading of pin_A of the rotary encoder
|
||||
; A' = previous reading of pin_A of the rotary encoder
|
||||
; B = current reading of pin_B of the rotary encoder
|
||||
; B' = previous reading of pin_B of the rotary encoder
|
||||
jmp read ; 0000 = from 00 to 00 = no change in reading
|
||||
jmp CW ; 0001 = from 00 to 01 = clockwise rotation
|
||||
jmp CCW ; 0010 = from 00 to 10 = counter clockwise rotation
|
||||
jmp read ; 0011 = from 00 to 11 = error
|
||||
|
||||
jmp CCW ; 0100 = from 01 to 00 = counter clockwise rotation
|
||||
jmp read ; 0101 = from 01 to 01 = no change in reading
|
||||
jmp read ; 0110 = from 01 to 10 = error
|
||||
jmp CW ; 0111 = from 01 to 11 = clockwise rotation
|
||||
|
||||
jmp CW ; 1000 = from 10 to 00 = clockwise rotation
|
||||
jmp read ; 1001 = from 10 to 01 = error
|
||||
jmp read ; 1010 = from 10 to 10 = no change in reading
|
||||
jmp CCW ; 1011 = from 10 to 11 = counter clockwise rotation
|
||||
|
||||
jmp read ; 1100 = from 11 to 00 = error
|
||||
jmp CCW ; 1101 = from 11 to 01 = counter clockwise rotation
|
||||
jmp CW ; 1110 = from 11 to 10 = clockwise rotation
|
||||
jmp read ; 1111 = from 11 to 11 = no change in reading
|
||||
|
||||
pc_start: ; this is the entry point for the program
|
||||
in pins 2 ; read the current values of A and B and use
|
||||
; them to initialize the previous values (A'B')
|
||||
read:
|
||||
mov osr isr ; the OSR is (after the next instruction) used to shift
|
||||
; the two bits with the previous values into the ISR
|
||||
out isr 2 ; shift the previous value into the ISR. This also sets
|
||||
; all other bits in the ISR to 0
|
||||
in pins 2 ; shift the current value into the ISR
|
||||
; the 16 LSB of the ISR now contain 000000000000A'B'AB
|
||||
; this represents a jmp instruction to the address A'B'AB
|
||||
mov exec isr ; do the jmp encoded in the ISR
|
||||
CW: ; a clockwise rotation was detected
|
||||
irq 0 ; signal a clockwise rotation via an IRQ
|
||||
jmp read ; jump to reading the current values of A and B
|
||||
CCW: ; a counter clockwise rotation was detected
|
||||
irq 1 ; signal a counter clockwise rotation via an IRQ
|
||||
; jmp read ; jump to reading the current values of A and B.
|
||||
; the jmp isn't needed because of the .wrap, and the first
|
||||
; statement of the program happens to be a jmp read
|
||||
.wrap
|
41
src/main.rs
41
src/main.rs
|
@ -28,14 +28,15 @@ mod app {
|
|||
Gpio0, Gpio1, Gpio14, Gpio16, Gpio17, Gpio18, Gpio19, Gpio2, Gpio20, Gpio21,
|
||||
Gpio25, Gpio3, Gpio4, Gpio5,
|
||||
},
|
||||
FunctionSio, FunctionSpi, FunctionUart, Pin, PullDown, SioOutput,
|
||||
FunctionPio0, FunctionSio, FunctionSpi, FunctionUart, Pin, PullDown, SioOutput,
|
||||
},
|
||||
pio::PIOExt,
|
||||
sio::Sio,
|
||||
spi::{self, Spi},
|
||||
uart::{self, UartConfig, UartPeripheral},
|
||||
watchdog::Watchdog,
|
||||
},
|
||||
pac::{SPI0, UART0},
|
||||
pac::{self, SPI0, UART0},
|
||||
Pins,
|
||||
};
|
||||
|
||||
|
@ -119,6 +120,7 @@ mod app {
|
|||
#[init]
|
||||
fn init(mut ctx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||
let mut watchdog = Watchdog::new(ctx.device.WATCHDOG);
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
let sio = Sio::new(ctx.device.SIO);
|
||||
|
||||
// External high-speed crystal on the pico board is 12Mhz
|
||||
|
@ -212,6 +214,25 @@ mod app {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let rotary_clk: Pin<_, FunctionPio0, _> = pins.gpio11.into_function();
|
||||
let rotary_clk_id = rotary_clk.id().num;
|
||||
let rotary_dt: Pin<_, FunctionPio0, _> = pins.gpio12.into_function();
|
||||
let rotary_dt_id = rotary_dt.id().num;
|
||||
let program = pio_proc::pio_file!("src/encoder.pio");
|
||||
|
||||
let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS);
|
||||
pio.irq0().enable_sm_interrupt(0);
|
||||
pio.irq1().enable_sm_interrupt(1);
|
||||
let installed = pio.install(&program.program).unwrap();
|
||||
let (mut sm, _, _) = rp_pico::hal::pio::PIOBuilder::from_program(installed)
|
||||
.set_pins(rotary_clk_id, 2)
|
||||
.build(sm0);
|
||||
sm.set_pindirs([
|
||||
(rotary_clk_id, rp_pico::hal::pio::PinDir::Output),
|
||||
(rotary_dt_id, rp_pico::hal::pio::PinDir::Output),
|
||||
]);
|
||||
sm.start();
|
||||
|
||||
let mono = Rp2040Mono::new(ctx.device.TIMER);
|
||||
|
||||
heartbeat::spawn().unwrap();
|
||||
|
@ -234,6 +255,22 @@ mod app {
|
|||
)
|
||||
}
|
||||
|
||||
#[task(binds = PIO0_IRQ_0, shared = [target_temp])]
|
||||
fn inc_target(mut ctx: inc_target::Context) {
|
||||
ctx.shared.target_temp.lock(|t| {
|
||||
*t += 1.0;
|
||||
});
|
||||
update_display::spawn().unwrap();
|
||||
}
|
||||
|
||||
#[task(binds = PIO0_IRQ_1, shared = [target_temp])]
|
||||
fn dec_target(mut ctx: dec_target::Context) {
|
||||
ctx.shared.target_temp.lock(|t| {
|
||||
*t -= 1.0;
|
||||
});
|
||||
update_display::spawn().unwrap();
|
||||
}
|
||||
|
||||
#[task(local = [thermocouple], shared = [recent_temp, uart])]
|
||||
fn read_temp(mut ctx: read_temp::Context) {
|
||||
match ctx.local.thermocouple.read_temp() {
|
||||
|
|
Loading…
Reference in a new issue