forked from M-Labs/artiq
firmware: make i2c busno u8
This commit is contained in:
parent
13c45c8766
commit
4f97d00e79
|
@ -2,16 +2,16 @@ use csr;
|
||||||
use clock;
|
use clock;
|
||||||
|
|
||||||
fn half_period() { clock::spin_us(100) }
|
fn half_period() { clock::spin_us(100) }
|
||||||
fn sda_bit(busno: u32) -> u8 { 1 << (2 * busno + 1) }
|
fn sda_bit(busno: u8) -> u8 { 1 << (2 * busno + 1) }
|
||||||
fn scl_bit(busno: u32) -> u8 { 1 << (2 * busno) }
|
fn scl_bit(busno: u8) -> u8 { 1 << (2 * busno) }
|
||||||
|
|
||||||
fn sda_i(busno: u32) -> 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sda_oe(busno: u32, 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) };
|
||||||
|
@ -19,7 +19,7 @@ fn sda_oe(busno: u32, oe: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sda_o(busno: u32, 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) };
|
||||||
|
@ -27,7 +27,7 @@ fn sda_o(busno: u32, o: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scl_oe(busno: u32, 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) };
|
||||||
|
@ -35,7 +35,7 @@ fn scl_oe(busno: u32, oe: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scl_o(busno: u32, 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) };
|
||||||
|
@ -45,6 +45,7 @@ fn scl_o(busno: u32, o: bool) {
|
||||||
|
|
||||||
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;
|
||||||
// Set SCL as output, and high level
|
// Set SCL as output, and high level
|
||||||
scl_o(busno, true);
|
scl_o(busno, true);
|
||||||
scl_oe(busno, true);
|
scl_oe(busno, true);
|
||||||
|
@ -62,7 +63,7 @@ pub fn init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(busno: u32) {
|
pub fn start(busno: u8) {
|
||||||
// Set SCL high then SDA low
|
// Set SCL high then SDA low
|
||||||
scl_o(busno, true);
|
scl_o(busno, true);
|
||||||
half_period();
|
half_period();
|
||||||
|
@ -70,7 +71,7 @@ pub fn start(busno: u32) {
|
||||||
half_period();
|
half_period();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restart(busno: u32) {
|
pub fn restart(busno: u8) {
|
||||||
// Set SCL low then SDA high */
|
// Set SCL low then SDA high */
|
||||||
scl_o(busno, false);
|
scl_o(busno, false);
|
||||||
half_period();
|
half_period();
|
||||||
|
@ -80,7 +81,7 @@ pub fn restart(busno: u32) {
|
||||||
start(busno);
|
start(busno);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(busno: u32) {
|
pub fn stop(busno: u8) {
|
||||||
// First, make sure SCL is low, so that the target releases the SDA line
|
// First, make sure SCL is low, so that the target releases the SDA line
|
||||||
scl_o(busno, false);
|
scl_o(busno, false);
|
||||||
half_period();
|
half_period();
|
||||||
|
@ -92,7 +93,7 @@ pub fn stop(busno: u32) {
|
||||||
half_period();
|
half_period();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u8) -> bool {
|
pub fn write(busno: u8, data: u8) -> bool {
|
||||||
// MSB first
|
// MSB first
|
||||||
for bit in (0..8).rev() {
|
for bit in (0..8).rev() {
|
||||||
// Set SCL low and set our bit on SDA
|
// Set SCL low and set our bit on SDA
|
||||||
|
@ -115,7 +116,7 @@ pub fn write(busno: u32, data: u8) -> bool {
|
||||||
!sda_i(busno)
|
!sda_i(busno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(busno: u32, ack: bool) -> u8 {
|
pub fn read(busno: u8, ack: bool) -> u8 {
|
||||||
// Set SCL low first, otherwise setting SDA as input may cause a transition
|
// 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.
|
// on SDA with SCL high which will be interpreted as START/STOP condition.
|
||||||
scl_o(busno, false);
|
scl_o(busno, false);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use i2c;
|
use i2c;
|
||||||
use clock;
|
use clock;
|
||||||
|
|
||||||
const BUSNO: u32 = 0;
|
const BUSNO: u8 = 0;
|
||||||
const ADDRESS: u8 = 0x68;
|
const ADDRESS: u8 = 0x68;
|
||||||
|
|
||||||
#[cfg(soc_platform = "kc705")]
|
#[cfg(soc_platform = "kc705")]
|
||||||
|
|
|
@ -242,20 +242,20 @@ extern fn cache_put(key: *const u8, list: ArtiqList<i32>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn i2c_start(busno: i32) {
|
extern fn i2c_start(busno: i32) {
|
||||||
send(&I2CStartRequest { busno: busno as u32 });
|
send(&I2CStartRequest { busno: busno as u8 });
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn i2c_stop(busno: i32) {
|
extern fn i2c_stop(busno: i32) {
|
||||||
send(&I2CStopRequest { busno: busno as u32 });
|
send(&I2CStopRequest { busno: busno as u8 });
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn i2c_write(busno: i32, data: i8) -> bool {
|
extern fn i2c_write(busno: i32, data: i8) -> bool {
|
||||||
send(&I2CWriteRequest { busno: busno as u32, data: data as u8 });
|
send(&I2CWriteRequest { busno: busno as u8, data: data as u8 });
|
||||||
recv!(&I2CWriteReply { ack } => ack)
|
recv!(&I2CWriteReply { ack } => ack)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn i2c_read(busno: i32, ack: bool) -> i8 {
|
extern fn i2c_read(busno: i32, ack: bool) -> i8 {
|
||||||
send(&I2CReadRequest { busno: busno as u32, ack: ack });
|
send(&I2CReadRequest { busno: busno as u8, ack: ack });
|
||||||
recv!(&I2CReadReply { data } => data) as i8
|
recv!(&I2CReadReply { data } => data) as i8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,11 +57,11 @@ pub enum Message<'a> {
|
||||||
CachePutRequest { key: &'a str, value: &'a [i32] },
|
CachePutRequest { key: &'a str, value: &'a [i32] },
|
||||||
CachePutReply { succeeded: bool },
|
CachePutReply { succeeded: bool },
|
||||||
|
|
||||||
I2CStartRequest { busno: u32 },
|
I2CStartRequest { busno: u8 },
|
||||||
I2CStopRequest { busno: u32 },
|
I2CStopRequest { busno: u8 },
|
||||||
I2CWriteRequest { busno: u32, data: u8 },
|
I2CWriteRequest { busno: u8, data: u8 },
|
||||||
I2CWriteReply { ack: bool },
|
I2CWriteReply { ack: bool },
|
||||||
I2CReadRequest { busno: u32, ack: bool },
|
I2CReadRequest { busno: u8, ack: bool },
|
||||||
I2CReadReply { data: u8 },
|
I2CReadReply { data: u8 },
|
||||||
|
|
||||||
Log(fmt::Arguments<'a>),
|
Log(fmt::Arguments<'a>),
|
||||||
|
|
Loading…
Reference in New Issue