mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-25 03:08:27 +08:00
grabber: add parser, report detected frame size in core device log
This commit is contained in:
parent
37e303dafc
commit
4f56710e4b
@ -1,6 +1,13 @@
|
||||
use board_misoc::csr;
|
||||
|
||||
static mut GRABBER_UP: &'static mut [bool] = &mut [false; csr::GRABBER_LEN];
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum State {
|
||||
Down,
|
||||
WaitResolution,
|
||||
Up
|
||||
}
|
||||
|
||||
static mut GRABBER_STATE: &'static mut [State] = &mut [State::Down; csr::GRABBER_LEN];
|
||||
|
||||
fn get_pll_reset(g: usize) -> bool {
|
||||
unsafe { (csr::GRABBER[g].pll_reset_read)() != 0 }
|
||||
@ -64,14 +71,25 @@ fn clock_align(g: usize) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn get_last_pixels(g: usize) -> (u16, u16) {
|
||||
unsafe { ((csr::GRABBER[g].last_x_read)(),
|
||||
(csr::GRABBER[g].last_y_read)()) }
|
||||
}
|
||||
|
||||
pub fn tick() {
|
||||
for g in 0..csr::GRABBER.len() {
|
||||
if unsafe { GRABBER_UP[g] } {
|
||||
if unsafe { GRABBER_STATE[g] != State::Down } {
|
||||
if !clock_pattern_ok(g) || !pll_locked(g) {
|
||||
set_pll_reset(g, true);
|
||||
unsafe { GRABBER_UP[g] = false; }
|
||||
unsafe { GRABBER_STATE[g] = State::Down; }
|
||||
info!("grabber{} is down", g);
|
||||
}
|
||||
if unsafe { GRABBER_STATE[g] == State::WaitResolution } {
|
||||
let (last_x, last_y) = get_last_pixels(g);
|
||||
info!("grabber{} detected frame size: {}x{}",
|
||||
g, last_x + 1, last_y + 1);
|
||||
unsafe { GRABBER_STATE[g] = State::Up; }
|
||||
}
|
||||
} else {
|
||||
if get_pll_reset(g) {
|
||||
set_pll_reset(g, false);
|
||||
@ -80,7 +98,7 @@ pub fn tick() {
|
||||
info!("grabber{} PLL is locked", g);
|
||||
if clock_align(g) {
|
||||
info!("grabber{} is up", g);
|
||||
unsafe { GRABBER_UP[g] = true; }
|
||||
unsafe { GRABBER_STATE[g] = State::WaitResolution; }
|
||||
} else {
|
||||
set_pll_reset(g, true);
|
||||
}
|
||||
|
77
artiq/gateware/grabber/core.py
Normal file
77
artiq/gateware/grabber/core.py
Normal file
@ -0,0 +1,77 @@
|
||||
from migen import *
|
||||
from migen.genlib.cdc import MultiReg
|
||||
from misoc.interconnect.csr import *
|
||||
|
||||
|
||||
bitseq = [
|
||||
# 0 1 2 3 4 5 6
|
||||
6, 5, 4, 3, 2, 1, 27,
|
||||
|
||||
# 7 8 9 10 11 12 13
|
||||
26, 0, 13, 12, 11, 10, 9,
|
||||
|
||||
# 14 15 16 17 18 19 20
|
||||
25, 24, 8, 7, 20, 19, 18,
|
||||
|
||||
# 21 22 23
|
||||
17, 23, 22
|
||||
]
|
||||
|
||||
assert len(set(bitseq)) == 24
|
||||
|
||||
|
||||
class Parser(Module, AutoCSR):
|
||||
"""Parses 28 bit encoded words and track pixel coordinates."""
|
||||
def __init__(self, width=12):
|
||||
self.cl = cl = Signal(28)
|
||||
|
||||
self.last_x = CSRStatus(width)
|
||||
self.last_y = CSRStatus(width)
|
||||
|
||||
self.pix = pix = Record([
|
||||
("x", width),
|
||||
("y", width),
|
||||
("a", 8),
|
||||
("b", 8),
|
||||
("c", 8),
|
||||
("stb", 1), # dval
|
||||
("eop", 1), # ~fval (i.e. not together with stb)
|
||||
])
|
||||
|
||||
# # #
|
||||
|
||||
last_x = Signal(width)
|
||||
last_y = Signal(width)
|
||||
|
||||
lval = Signal()
|
||||
fval = Signal()
|
||||
dval = Signal()
|
||||
self.comb += [
|
||||
Cat(dval, fval, lval).eq(cl[14:17]),
|
||||
pix.stb.eq(dval),
|
||||
pix.eop.eq(~fval),
|
||||
Cat(pix.a, pix.b, pix.c).eq(Cat(cl[i] for i in bitseq))
|
||||
]
|
||||
last_lval = Signal()
|
||||
last_fval = Signal()
|
||||
self.sync.cl += [
|
||||
last_lval.eq(lval),
|
||||
last_fval.eq(fval),
|
||||
pix.x.eq(pix.x + 1),
|
||||
If(~lval,
|
||||
pix.x.eq(0),
|
||||
If(last_lval, last_x.eq(pix.x)),
|
||||
If(last_fval & last_lval,
|
||||
pix.y.eq(pix.y + 1)
|
||||
)
|
||||
),
|
||||
If(~fval,
|
||||
If(last_fval, last_y.eq(pix.y)),
|
||||
pix.y.eq(0)
|
||||
)
|
||||
]
|
||||
|
||||
self.specials += [
|
||||
MultiReg(last_x, self.last_x.status),
|
||||
MultiReg(last_y, self.last_y.status)
|
||||
]
|
@ -2,6 +2,7 @@ from migen import *
|
||||
|
||||
from artiq.gateware.rtio import rtlink
|
||||
from artiq.gateware.grabber import deserializer_7series
|
||||
from artiq.gateware.grabber.core import *
|
||||
|
||||
|
||||
class Grabber(Module):
|
||||
@ -11,6 +12,8 @@ class Grabber(Module):
|
||||
rtlink.IInterface(10))
|
||||
|
||||
self.submodules.deserializer = deserializer_7series.Deserializer(pins)
|
||||
self.submodules.parser = Parser()
|
||||
self.comb += self.parser.cl.eq(self.deserializer.q)
|
||||
|
||||
def get_csrs(self):
|
||||
return self.deserializer.get_csrs()
|
||||
return self.deserializer.get_csrs() + self.parser.get_csrs()
|
||||
|
Loading…
Reference in New Issue
Block a user