forked from M-Labs/artiq
grabber: refactor state machine
This commit is contained in:
parent
6cd2432e30
commit
f7678cc24a
|
@ -1,14 +1,21 @@
|
||||||
use board_misoc::csr;
|
use board_misoc::csr;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
enum State {
|
enum State {
|
||||||
Down,
|
Reset,
|
||||||
WaitResolution,
|
ExitReset,
|
||||||
Up
|
Lock,
|
||||||
|
Align,
|
||||||
|
Watch
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut GRABBER_STATE: [State; csr::GRABBER_LEN] = [State::Down; csr::GRABBER_LEN];
|
struct Info {
|
||||||
static mut GRABBER_RESOLUTION: [(u16, u16); csr::GRABBER_LEN] = [(0, 0); csr::GRABBER_LEN];
|
state: State,
|
||||||
|
frame_size: (u16, u16),
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut INFO: [Info; csr::GRABBER_LEN] =
|
||||||
|
[Info { state: State::Reset, frame_size: (0, 0) }; csr::GRABBER_LEN];
|
||||||
|
|
||||||
fn get_pll_reset(g: usize) -> bool {
|
fn get_pll_reset(g: usize) -> bool {
|
||||||
unsafe { (csr::GRABBER[g].pll_reset_read)() != 0 }
|
unsafe { (csr::GRABBER[g].pll_reset_read)() != 0 }
|
||||||
|
@ -86,43 +93,62 @@ fn get_video_clock(g: usize) -> u32 {
|
||||||
|
|
||||||
pub fn tick() {
|
pub fn tick() {
|
||||||
for g in 0..csr::GRABBER.len() {
|
for g in 0..csr::GRABBER.len() {
|
||||||
if unsafe { GRABBER_STATE[g] != State::Down } {
|
let next = match unsafe { INFO[g].state } {
|
||||||
if !clock_pattern_ok(g) || !pll_locked(g) {
|
State::Reset => {
|
||||||
set_pll_reset(g, true);
|
set_pll_reset(g, true);
|
||||||
unsafe { GRABBER_STATE[g] = State::Down; }
|
unsafe { INFO[g].frame_size = (0, 0); }
|
||||||
info!("grabber{} is down", g);
|
State::ExitReset
|
||||||
}
|
}
|
||||||
if unsafe { GRABBER_STATE[g] == State::WaitResolution } {
|
State::ExitReset => {
|
||||||
let last_xy = get_last_pixels(g);
|
|
||||||
unsafe { GRABBER_RESOLUTION[g] = last_xy; }
|
|
||||||
info!("grabber{} frame size: {}x{}",
|
|
||||||
g, last_xy.0 + 1, last_xy.1 + 1);
|
|
||||||
info!("grabber{} video clock: {}MHz", g, get_video_clock(g));
|
|
||||||
unsafe { GRABBER_STATE[g] = State::Up; }
|
|
||||||
} else {
|
|
||||||
let last_xy = get_last_pixels(g);
|
|
||||||
if unsafe { last_xy != GRABBER_RESOLUTION[g] } {
|
|
||||||
info!("grabber{} frame size: {}x{}",
|
|
||||||
g, last_xy.0 + 1, last_xy.1 + 1);
|
|
||||||
unsafe { GRABBER_RESOLUTION[g] = last_xy; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if get_pll_reset(g) {
|
if get_pll_reset(g) {
|
||||||
set_pll_reset(g, false);
|
set_pll_reset(g, false);
|
||||||
|
State::Lock
|
||||||
} else {
|
} else {
|
||||||
|
State::ExitReset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Lock => {
|
||||||
|
if pll_locked(g) {
|
||||||
|
info!("grabber{} locked: {}MHz", g, get_video_clock(g));
|
||||||
|
State::Align
|
||||||
|
} else {
|
||||||
|
State::Lock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
State::Align => {
|
||||||
if pll_locked(g) {
|
if pll_locked(g) {
|
||||||
info!("grabber{} PLL is locked", g);
|
|
||||||
if clock_align(g) {
|
if clock_align(g) {
|
||||||
info!("grabber{} is up", g);
|
info!("grabber{} alignment success", g);
|
||||||
unsafe { GRABBER_STATE[g] = State::WaitResolution; }
|
State::Watch
|
||||||
} else {
|
} else {
|
||||||
set_pll_reset(g, true);
|
info!("grabber{} alignment failure", g);
|
||||||
|
State::Reset
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
set_pll_reset(g, true);
|
info!("grabber{} lock lost", g);
|
||||||
|
State::Reset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
State::Watch => {
|
||||||
|
if pll_locked(g) {
|
||||||
|
if clock_pattern_ok(g) {
|
||||||
|
let last_xy = get_last_pixels(g);
|
||||||
|
if last_xy != unsafe { INFO[g].frame_size } {
|
||||||
|
info!("grabber{} frame size: {}x{}",
|
||||||
|
g, last_xy.0 + 1, last_xy.1 + 1);
|
||||||
|
unsafe { INFO[g].frame_size = last_xy }
|
||||||
}
|
}
|
||||||
|
State::Watch
|
||||||
|
} else {
|
||||||
|
info!("grabber{} alignment lost", g);
|
||||||
|
State::Reset
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("grabber{} lock lost", g);
|
||||||
|
State::Reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unsafe { INFO[g].state = next; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue