forked from M-Labs/artiq
firmware: oops, misoc #[cfg]s were missing from libboard_artiq.
This commit is contained in:
parent
ca419aa3c2
commit
d3066e5044
|
@ -38,6 +38,8 @@ dependencies = [
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"board 0.0.0",
|
"board 0.0.0",
|
||||||
"build_artiq 0.0.0",
|
"build_artiq 0.0.0",
|
||||||
|
"build_misoc 0.0.0",
|
||||||
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -9,10 +9,12 @@ name = "board_artiq"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
build_misoc = { path = "../libbuild_misoc" }
|
||||||
build_artiq = { path = "../libbuild_artiq" }
|
build_artiq = { path = "../libbuild_artiq" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
|
log = { version = "0.3", default-features = false }
|
||||||
board = { path = "../libboard" }
|
board = { path = "../libboard" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
extern crate build_misoc;
|
||||||
extern crate build_artiq;
|
extern crate build_artiq;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -24,5 +25,6 @@ fn gen_hmc7043_writes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
build_misoc::cfg();
|
||||||
gen_hmc7043_writes();
|
gen_hmc7043_writes();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,18 @@
|
||||||
#[cfg(has_i2c)]
|
#[cfg(has_i2c)]
|
||||||
use csr;
|
mod imp {
|
||||||
|
use board::{csr, clock};
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
fn half_period() { clock::spin_us(100) }
|
||||||
mod io {
|
|
||||||
use csr;
|
|
||||||
use clock;
|
|
||||||
|
|
||||||
pub fn half_period() { clock::spin_us(100) }
|
|
||||||
fn sda_bit(busno: u8) -> u8 { 1 << (2 * busno + 1) }
|
fn sda_bit(busno: u8) -> u8 { 1 << (2 * busno + 1) }
|
||||||
fn scl_bit(busno: u8) -> u8 { 1 << (2 * busno) }
|
fn scl_bit(busno: u8) -> u8 { 1 << (2 * busno) }
|
||||||
|
|
||||||
pub fn sda_i(busno: u8) -> bool {
|
fn sda_i(busno: u8) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::i2c::in_read() & sda_bit(busno) != 0
|
csr::i2c::in_read() & sda_bit(busno) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sda_oe(busno: u8, oe: bool) {
|
fn sda_oe(busno: u8, oe: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let reg = csr::i2c::oe_read();
|
let reg = csr::i2c::oe_read();
|
||||||
let reg = if oe { reg | sda_bit(busno) } else { reg & !sda_bit(busno) };
|
let reg = if oe { reg | sda_bit(busno) } else { reg & !sda_bit(busno) };
|
||||||
|
@ -24,7 +20,7 @@ mod io {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sda_o(busno: u8, o: bool) {
|
fn sda_o(busno: u8, o: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let reg = csr::i2c::out_read();
|
let reg = csr::i2c::out_read();
|
||||||
let reg = if o { reg | sda_bit(busno) } else { reg & !sda_bit(busno) };
|
let reg = if o { reg | sda_bit(busno) } else { reg & !sda_bit(busno) };
|
||||||
|
@ -32,7 +28,7 @@ mod io {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scl_oe(busno: u8, oe: bool) {
|
fn scl_oe(busno: u8, oe: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let reg = csr::i2c::oe_read();
|
let reg = csr::i2c::oe_read();
|
||||||
let reg = if oe { reg | scl_bit(busno) } else { reg & !scl_bit(busno) };
|
let reg = if oe { reg | scl_bit(busno) } else { reg & !scl_bit(busno) };
|
||||||
|
@ -40,151 +36,144 @@ mod io {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scl_o(busno: u8, o: bool) {
|
fn scl_o(busno: u8, o: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let reg = csr::i2c::out_read();
|
let reg = csr::i2c::out_read();
|
||||||
let reg = if o { reg | scl_bit(busno) } else { reg & !scl_bit(busno) };
|
let reg = if o { reg | scl_bit(busno) } else { reg & !scl_bit(busno) };
|
||||||
csr::i2c::out_write(reg)
|
csr::i2c::out_write(reg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
pub fn init() {
|
||||||
pub fn init() {
|
for busno in 0..csr::CONFIG_I2C_BUS_COUNT {
|
||||||
for busno in 0..csr::CONFIG_I2C_BUS_COUNT {
|
let busno = busno as u8;
|
||||||
let busno = busno as u8;
|
// Set SCL as output, and high level
|
||||||
// Set SCL as output, and high level
|
scl_o(busno, true);
|
||||||
io::scl_o(busno, true);
|
scl_oe(busno, true);
|
||||||
io::scl_oe(busno, true);
|
// Prepare a zero level on SDA so that sda_oe pulls it down
|
||||||
// Prepare a zero level on SDA so that sda_oe pulls it down
|
sda_o(busno, false);
|
||||||
io::sda_o(busno, false);
|
// Release SDA
|
||||||
// Release SDA
|
sda_oe(busno, false);
|
||||||
io::sda_oe(busno, false);
|
|
||||||
|
|
||||||
// Check the I2C bus is ready
|
// Check the I2C bus is ready
|
||||||
io::half_period();
|
half_period();
|
||||||
io::half_period();
|
half_period();
|
||||||
if !io::sda_i(busno) {
|
if !sda_i(busno) {
|
||||||
error!("SDA is stuck low on bus #{}", busno)
|
error!("SDA is stuck low on bus #{}", busno)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
pub fn start(busno: u8) -> Result<(), ()> {
|
||||||
pub fn start(busno: u8) -> Result<(), ()> {
|
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
||||||
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
return Err(())
|
||||||
return Err(())
|
}
|
||||||
|
// Set SCL high then SDA low
|
||||||
|
scl_o(busno, true);
|
||||||
|
half_period();
|
||||||
|
sda_oe(busno, true);
|
||||||
|
half_period();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
// Set SCL high then SDA low
|
|
||||||
io::scl_o(busno, true);
|
|
||||||
io::half_period();
|
|
||||||
io::sda_oe(busno, true);
|
|
||||||
io::half_period();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
pub fn restart(busno: u8) -> Result<(), ()> {
|
||||||
pub fn restart(busno: u8) -> Result<(), ()> {
|
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
||||||
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
return Err(())
|
||||||
return Err(())
|
}
|
||||||
|
// Set SCL low then SDA high */
|
||||||
|
scl_o(busno, false);
|
||||||
|
half_period();
|
||||||
|
sda_oe(busno, false);
|
||||||
|
half_period();
|
||||||
|
// Do a regular start
|
||||||
|
start(busno)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
// Set SCL low then SDA high */
|
|
||||||
io::scl_o(busno, false);
|
|
||||||
io::half_period();
|
|
||||||
io::sda_oe(busno, false);
|
|
||||||
io::half_period();
|
|
||||||
// Do a regular start
|
|
||||||
start(busno)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
pub fn stop(busno: u8) -> Result<(), ()> {
|
||||||
pub fn stop(busno: u8) -> Result<(), ()> {
|
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
||||||
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
return Err(())
|
||||||
return Err(())
|
}
|
||||||
|
// First, make sure SCL is low, so that the target releases the SDA line
|
||||||
|
scl_o(busno, false);
|
||||||
|
half_period();
|
||||||
|
// Set SCL high then SDA high
|
||||||
|
sda_oe(busno, true);
|
||||||
|
scl_o(busno, true);
|
||||||
|
half_period();
|
||||||
|
sda_oe(busno, false);
|
||||||
|
half_period();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
// First, make sure SCL is low, so that the target releases the SDA line
|
|
||||||
io::scl_o(busno, false);
|
|
||||||
io::half_period();
|
|
||||||
// Set SCL high then SDA high
|
|
||||||
io::sda_oe(busno, true);
|
|
||||||
io::scl_o(busno, true);
|
|
||||||
io::half_period();
|
|
||||||
io::sda_oe(busno, false);
|
|
||||||
io::half_period();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
pub fn write(busno: u8, data: u8) -> Result<bool, ()> {
|
||||||
pub fn write(busno: u8, data: u8) -> Result<bool, ()> {
|
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
||||||
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
return Err(())
|
||||||
return Err(())
|
}
|
||||||
|
// MSB first
|
||||||
|
for bit in (0..8).rev() {
|
||||||
|
// Set SCL low and set our bit on SDA
|
||||||
|
scl_o(busno, false);
|
||||||
|
sda_oe(busno, data & (1 << bit) == 0);
|
||||||
|
half_period();
|
||||||
|
// Set SCL high ; data is shifted on the rising edge of SCL
|
||||||
|
scl_o(busno, true);
|
||||||
|
half_period();
|
||||||
|
}
|
||||||
|
// Check ack
|
||||||
|
// Set SCL low, then release SDA so that the I2C target can respond
|
||||||
|
scl_o(busno, false);
|
||||||
|
half_period();
|
||||||
|
sda_oe(busno, false);
|
||||||
|
// Set SCL high and check for ack
|
||||||
|
scl_o(busno, true);
|
||||||
|
half_period();
|
||||||
|
// returns true if acked (I2C target pulled SDA low)
|
||||||
|
Ok(!sda_i(busno))
|
||||||
}
|
}
|
||||||
// MSB first
|
|
||||||
for bit in (0..8).rev() {
|
pub fn read(busno: u8, ack: bool) -> Result<u8, ()> {
|
||||||
// Set SCL low and set our bit on SDA
|
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
||||||
io::scl_o(busno, false);
|
return Err(())
|
||||||
io::sda_oe(busno, data & (1 << bit) == 0);
|
}
|
||||||
io::half_period();
|
// Set SCL low first, otherwise setting SDA as input may cause a transition
|
||||||
// Set SCL high ; data is shifted on the rising edge of SCL
|
// on SDA with SCL high which will be interpreted as START/STOP condition.
|
||||||
io::scl_o(busno, true);
|
scl_o(busno, false);
|
||||||
io::half_period();
|
half_period(); // make sure SCL has settled low
|
||||||
|
sda_oe(busno, false);
|
||||||
|
|
||||||
|
let mut data: u8 = 0;
|
||||||
|
|
||||||
|
// MSB first
|
||||||
|
for bit in (0..8).rev() {
|
||||||
|
scl_o(busno, false);
|
||||||
|
half_period();
|
||||||
|
// Set SCL high and shift data
|
||||||
|
scl_o(busno, true);
|
||||||
|
half_period();
|
||||||
|
if sda_i(busno) { data |= 1 << bit }
|
||||||
|
}
|
||||||
|
// Send ack
|
||||||
|
// Set SCL low and pull SDA low when acking
|
||||||
|
scl_o(busno, false);
|
||||||
|
if ack { sda_oe(busno, true) }
|
||||||
|
half_period();
|
||||||
|
// then set SCL high
|
||||||
|
scl_o(busno, true);
|
||||||
|
half_period();
|
||||||
|
|
||||||
|
Ok(data)
|
||||||
}
|
}
|
||||||
// Check ack
|
|
||||||
// Set SCL low, then release SDA so that the I2C target can respond
|
|
||||||
io::scl_o(busno, false);
|
|
||||||
io::half_period();
|
|
||||||
io::sda_oe(busno, false);
|
|
||||||
// Set SCL high and check for ack
|
|
||||||
io::scl_o(busno, true);
|
|
||||||
io::half_period();
|
|
||||||
// returns true if acked (I2C target pulled SDA low)
|
|
||||||
Ok(!io::sda_i(busno))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
|
||||||
pub fn read(busno: u8, ack: bool) -> Result<u8, ()> {
|
|
||||||
if busno as u32 >= csr::CONFIG_I2C_BUS_COUNT {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
// Set SCL low first, otherwise setting SDA as input may cause a transition
|
|
||||||
// on SDA with SCL high which will be interpreted as START/STOP condition.
|
|
||||||
io::scl_o(busno, false);
|
|
||||||
io::half_period(); // make sure SCL has settled low
|
|
||||||
io::sda_oe(busno, false);
|
|
||||||
|
|
||||||
let mut data: u8 = 0;
|
|
||||||
|
|
||||||
// MSB first
|
|
||||||
for bit in (0..8).rev() {
|
|
||||||
io::scl_o(busno, false);
|
|
||||||
io::half_period();
|
|
||||||
// Set SCL high and shift data
|
|
||||||
io::scl_o(busno, true);
|
|
||||||
io::half_period();
|
|
||||||
if io::sda_i(busno) { data |= 1 << bit }
|
|
||||||
}
|
|
||||||
// Send ack
|
|
||||||
// Set SCL low and pull SDA low when acking
|
|
||||||
io::scl_o(busno, false);
|
|
||||||
if ack { io::sda_oe(busno, true) }
|
|
||||||
io::half_period();
|
|
||||||
// then set SCL high
|
|
||||||
io::scl_o(busno, true);
|
|
||||||
io::half_period();
|
|
||||||
|
|
||||||
Ok(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(has_i2c))]
|
#[cfg(not(has_i2c))]
|
||||||
pub fn init() {}
|
mod imp {
|
||||||
#[cfg(not(has_i2c))]
|
pub fn init() {}
|
||||||
pub fn start(_busno: u8) -> Result<(), ()> { Err(()) }
|
pub fn start(_busno: u8) -> Result<(), ()> { Err(()) }
|
||||||
#[cfg(not(has_i2c))]
|
pub fn restart(_busno: u8) -> Result<(), ()> { Err(()) }
|
||||||
pub fn restart(_busno: u8) -> Result<(), ()> { Err(()) }
|
pub fn stop(_busno: u8) -> Result<(), ()> { Err(()) }
|
||||||
#[cfg(not(has_i2c))]
|
pub fn write(_busno: u8, _data: u8) -> Result<bool, ()> { Err(()) }
|
||||||
pub fn stop(_busno: u8) -> Result<(), ()> { Err(()) }
|
pub fn read(_busno: u8, _ack: bool) -> Result<u8, ()> { Err(()) }
|
||||||
#[cfg(not(has_i2c))]
|
}
|
||||||
pub fn write(_busno: u8, _data: u8) -> Result<bool, ()> { Err(()) }
|
|
||||||
#[cfg(not(has_i2c))]
|
pub use self::imp::*;
|
||||||
pub fn read(_busno: u8, _ack: bool) -> Result<u8, ()> { Err(()) }
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
extern crate board;
|
extern crate board;
|
||||||
|
|
||||||
pub mod pcr;
|
pub mod pcr;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use core::result;
|
use core::result;
|
||||||
|
use board::{csr, clock};
|
||||||
use i2c;
|
use i2c;
|
||||||
use clock;
|
|
||||||
use csr;
|
|
||||||
|
|
||||||
type Result<T> = result::Result<T, &'static str>;
|
type Result<T> = result::Result<T, &'static str>;
|
||||||
|
|
||||||
|
@ -200,8 +199,8 @@ pub fn setup(settings: &FrequencySettings) -> Result<()> {
|
||||||
if !has_clkin2()? {
|
if !has_clkin2()? {
|
||||||
return Err("Si5324 misses CLKIN2 signal");
|
return Err("Si5324 misses CLKIN2 signal");
|
||||||
}
|
}
|
||||||
monitor_lock()?;
|
|
||||||
|
|
||||||
|
monitor_lock()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue