diff --git a/src/main.rs b/src/main.rs
index 73f0b1f..8813653 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,14 +1,28 @@
#![cfg_attr(not(test), no_std)]
#![no_main]
+#![feature(abi_avr_interrupt)]
+use core::sync::atomic::{AtomicI64, AtomicU8};
+use std::sync::OnceLock;
+
+use arduino_hal::{hal::port::{PD1, PD2}, pac::exint::eicra::{ISC0_A, ISC0_W, ISC1_A}, port::{mode::Input, Pin}};
use panic_halt as _;
mod servo;
use servo::{configure_timer_one, Servo};
+#[macro_use]
+use avr_device_macros;
#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
+ ENCODER.set((pins.d1, pins.d2));
+
+ //dp.EXINT.pcifr.write(0b11);
+ dp.EXINT.eicra.write(|w| w.isc0().bits(ISC0_A::VAL_0X01 as u8)); // rising and falling edge
+ dp.EXINT.eimsk.write(|w| w.int0().set_bit());
+ dp.EXINT.eicra.write(|w| w.isc1().bits(ISC1_A::VAL_0X01 as u8)); // rising and falling edge
+ dp.EXINT.eimsk.write(|w| w.int1().set_bit());
// configure timer for servos
pins.d9.into_output(); // carriage
@@ -16,7 +30,48 @@ fn main() -> ! {
let (carriage, claw) = configure_timer_one(&dp.TC1);
loop {
- carriage.set_speed(1.0);
+ let position = COUNTS.load(core::sync::atomic::Ordering::SeqCst);
+
+ let gain = position as f32 / TICKS_PER_ROT;
+
+ carriage.set_speed(gain);
arduino_hal::delay_ms(20);
}
}
+
+static ENCODER: OnceLock<(Pin, Pin)> = OnceLock::new();
+static LAST: AtomicU8 = AtomicU8::new(0);
+static COUNTS: AtomicI64 = AtomicI64::new(0);
+const TICKS_PER_ROT: f32 = 90. * 4.;
+
+#[avr_device_macros::interrupt(atmega328p)]
+fn INT0() {
+ update_encoder()
+}
+#[avr_device_macros::interrupt(atmega328p)]
+fn INT1() {
+ update_encoder()
+}
+
+fn update_encoder() {
+ let (d1,d2) = ENCODER.get().unwrap();
+ let d1 = d1.is_high();
+ let d2 = d2.is_high();
+ let curr = d2<<1+d1;
+ let last = LAST.load(core::sync::atomic::Ordering::SeqCst);
+
+ // could probably do this bitwise (subtract individual phases?)
+ let diff: i8 = match curr<<2 +last {
+ 0b0001 => 1,
+ 0b0111 => 1,
+ 0b1110 => 1,
+ 0b1000 => 1,
+ 0b0010 => -1,
+ 0b1011 => -1,
+ 0b1101 => -1,
+ 0b0100 => -1,
+ _ => 0,
+ };
+ COUNTS.fetch_add(diff as i64, core::sync::atomic::Ordering::SeqCst);
+ LAST.store(curr, core::sync::atomic::Ordering::SeqCst);
+}