forked from M-Labs/zynq-rs
Compare commits
13 Commits
14b0247716
...
master
Author | SHA1 | Date | |
---|---|---|---|
1c8e2c318c | |||
67880b4e0b | |||
e96222ff6f | |||
dc1ca3d3d0 | |||
c4c52c33b4 | |||
072fd5f015 | |||
2b3c7e4b2f | |||
84d6d391ce | |||
43e0440911 | |||
3e95df1f64 | |||
26ab2927b9 | |||
dacc816eb4 | |||
fbc783d7ad |
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -8,9 +8,9 @@ checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
@ -20,9 +20,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.69"
|
version = "1.0.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -47,9 +47,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-hal"
|
name = "embedded-hal"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9"
|
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nb 0.1.3",
|
"nb 0.1.3",
|
||||||
"void",
|
"void",
|
||||||
@ -250,9 +250,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "volatile-register"
|
name = "volatile-register"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
|
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"vcell",
|
"vcell",
|
||||||
]
|
]
|
||||||
|
@ -14,7 +14,7 @@ members = [
|
|||||||
panic = "abort"
|
panic = "abort"
|
||||||
debug = true
|
debug = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
opt-level = 'z'
|
opt-level = 's'
|
||||||
lto = true
|
lto = true
|
||||||
debug-assertions = false
|
debug-assertions = false
|
||||||
overflow-checks = false
|
overflow-checks = false
|
||||||
|
12
flake.lock
generated
12
flake.lock
generated
@ -3,11 +3,11 @@
|
|||||||
"mozilla-overlay": {
|
"mozilla-overlay": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1638887313,
|
"lastModified": 1645464064,
|
||||||
"narHash": "sha256-FMYV6rVtvSIfthgC1sK1xugh3y7muoQcvduMdriz4ag=",
|
"narHash": "sha256-YeN4bpPvHkVOpQzb8APTAfE7/R+MFMwJUMkqmfvytSk=",
|
||||||
"owner": "mozilla",
|
"owner": "mozilla",
|
||||||
"repo": "nixpkgs-mozilla",
|
"repo": "nixpkgs-mozilla",
|
||||||
"rev": "7c1e8b1dd6ed0043fb4ee0b12b815256b0b9de6f",
|
"rev": "15b7a05f20aab51c4ffbefddb1b448e862dccb7d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -18,11 +18,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1642961095,
|
"lastModified": 1646588256,
|
||||||
"narHash": "sha256-RLatktZmvwFBOyqdoIk4qdS4OGKB7aKIvvs4ZP2L8D8=",
|
"narHash": "sha256-ZHljmNlt19nSm0Mz8fx6QEhddKUkU4hhwFmfNmGn+EY=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "604c44137d97b5111be1ca5c0d97f6e24fbc5c2c",
|
"rev": "2ebb6c1e5ae402ba35cca5eec58385e5f1adea04",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -278,6 +278,7 @@
|
|||||||
openocd gdb
|
openocd gdb
|
||||||
openssh rsync
|
openssh rsync
|
||||||
llvmPackages_9.clang-unwrapped
|
llvmPackages_9.clang-unwrapped
|
||||||
|
(python3.withPackages(ps: [ ps.pyftdi ]))
|
||||||
mkbootimage ];
|
mkbootimage ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -310,6 +310,8 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
|
|||||||
let phy = Phy::find(&mut inner).expect("phy");
|
let phy = Phy::find(&mut inner).expect("phy");
|
||||||
phy.reset(&mut inner);
|
phy.reset(&mut inner);
|
||||||
phy.restart_autoneg(&mut inner);
|
phy.restart_autoneg(&mut inner);
|
||||||
|
#[cfg(feature="target_kasli_soc")]
|
||||||
|
phy.set_leds(&mut inner);
|
||||||
|
|
||||||
Eth {
|
Eth {
|
||||||
rx: (),
|
rx: (),
|
||||||
|
@ -82,6 +82,10 @@ impl PhyRegister for Control {
|
|||||||
fn addr() -> u8 {
|
fn addr() -> u8 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for Control {
|
impl From<u16> for Control {
|
||||||
|
@ -11,6 +11,9 @@ pub struct PhyIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn identify_phy<PA: PhyAccess>(pa: &mut PA, addr: u8) -> Option<PhyIdentifier> {
|
pub fn identify_phy<PA: PhyAccess>(pa: &mut PA, addr: u8) -> Option<PhyIdentifier> {
|
||||||
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
pa.write_phy(addr, 0x16, 0); //reset page
|
||||||
|
|
||||||
let id1 = pa.read_phy(addr, 2);
|
let id1 = pa.read_phy(addr, 2);
|
||||||
let id2 = pa.read_phy(addr, 3);
|
let id2 = pa.read_phy(addr, 3);
|
||||||
if id1 != 0xFFFF || id2 != 0xFFFF {
|
if id1 != 0xFFFF || id2 != 0xFFFF {
|
||||||
|
79
libboard_zynq/src/eth/phy/leds.rs
Normal file
79
libboard_zynq/src/eth/phy/leds.rs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
use bit_field::BitField;
|
||||||
|
use super::{PhyRegister, Led0Control, Led1Control};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
/// LED Control Register
|
||||||
|
pub struct Leds(pub u16);
|
||||||
|
|
||||||
|
impl Leds {
|
||||||
|
pub fn led0(&self) -> Led0Control {
|
||||||
|
match self.0.get_bits(0..=3) {
|
||||||
|
0b0000 => Led0Control::OnLinkOffNoLink,
|
||||||
|
0b0001 => Led0Control::OnLinkBlinkActivityOffNoLink,
|
||||||
|
0b0010 => Led0Control::BlinkDependingOnLink,
|
||||||
|
0b0011 => Led0Control::OnActivityOffNoActivity,
|
||||||
|
0b0100 => Led0Control::BlinkActivityOffNoActivity,
|
||||||
|
0b0101 => Led0Control::OnTransmitOffNoTransmit,
|
||||||
|
0b0110 => Led0Control::OnCopperLinkOffElse,
|
||||||
|
0b0111 => Led0Control::On1000LinkOffElse,
|
||||||
|
0b1000 => Led0Control::ForceOff,
|
||||||
|
0b1001 => Led0Control::ForceOn,
|
||||||
|
0b1010 => Led0Control::ForceHiZ,
|
||||||
|
0b1011 => Led0Control::ForceBlink,
|
||||||
|
0b1100 => Led0Control::Mode1,
|
||||||
|
0b1101 => Led0Control::Mode2,
|
||||||
|
0b1110 => Led0Control::Mode3,
|
||||||
|
0b1111 => Led0Control::Mode4,
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn led1(&self) -> Led1Control {
|
||||||
|
match self.0.get_bits(4..=7) {
|
||||||
|
0b0000 => Led1Control::OnReceiveOffNoReceive,
|
||||||
|
0b0001 => Led1Control::OnLinkBlinkActivityOffNoLink,
|
||||||
|
0b0010 => Led1Control::OnLinkBlinkReceiveOffNoLink,
|
||||||
|
0b0011 => Led1Control::OnActivityOffNoActivity,
|
||||||
|
0b0100 => Led1Control::BlinkActivityOffNoActivity,
|
||||||
|
0b0101 => Led1Control::On100OrFiberOffElse,
|
||||||
|
0b0110 => Led1Control::On1001000LinkOffElse,
|
||||||
|
0b0111 => Led1Control::On100LinkOffElse,
|
||||||
|
0b1000 => Led1Control::ForceOff,
|
||||||
|
0b1001 => Led1Control::ForceOn,
|
||||||
|
0b1010 => Led1Control::ForceHiZ,
|
||||||
|
0b1011 => Led1Control::ForceBlink,
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_led0(mut self, setting: Led0Control) -> Self {
|
||||||
|
self.0.set_bits(0..=3, setting as u16);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_led1(mut self, setting: Led1Control) -> Self {
|
||||||
|
self.0.set_bits(4..=7, setting as u16);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PhyRegister for Leds {
|
||||||
|
fn addr() -> u8 {
|
||||||
|
0x10
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for Leds {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
Leds(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<u16> for Leds {
|
||||||
|
fn into(self) -> u16 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,8 @@ mod control;
|
|||||||
pub use control::Control;
|
pub use control::Control;
|
||||||
mod pssr;
|
mod pssr;
|
||||||
pub use pssr::PSSR;
|
pub use pssr::PSSR;
|
||||||
|
mod leds;
|
||||||
|
pub use leds::Leds;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub struct Link {
|
pub struct Link {
|
||||||
@ -26,6 +28,42 @@ pub enum LinkDuplex {
|
|||||||
Full,
|
Full,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub enum Led0Control {
|
||||||
|
OnLinkOffNoLink = 0b0000,
|
||||||
|
OnLinkBlinkActivityOffNoLink = 0b0001,
|
||||||
|
BlinkDependingOnLink = 0b0010,
|
||||||
|
OnActivityOffNoActivity = 0b0011,
|
||||||
|
BlinkActivityOffNoActivity = 0b0100,
|
||||||
|
OnTransmitOffNoTransmit = 0b0101,
|
||||||
|
OnCopperLinkOffElse = 0b0110,
|
||||||
|
On1000LinkOffElse = 0b0111,
|
||||||
|
ForceOff = 0b1000,
|
||||||
|
ForceOn = 0b1001,
|
||||||
|
ForceHiZ = 0b1010,
|
||||||
|
ForceBlink = 0b1011,
|
||||||
|
Mode1 = 0b1100,
|
||||||
|
Mode2 = 0b1101,
|
||||||
|
Mode3 = 0b1110,
|
||||||
|
Mode4 = 0b1111
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub enum Led1Control {
|
||||||
|
OnReceiveOffNoReceive = 0b0000,
|
||||||
|
OnLinkBlinkActivityOffNoLink = 0b0001,
|
||||||
|
OnLinkBlinkReceiveOffNoLink = 0b0010,
|
||||||
|
OnActivityOffNoActivity = 0b0011,
|
||||||
|
BlinkActivityOffNoActivity = 0b0100,
|
||||||
|
On100OrFiberOffElse = 0b0101,
|
||||||
|
On1001000LinkOffElse = 0b0110,
|
||||||
|
On100LinkOffElse = 0b0111,
|
||||||
|
ForceOff = 0b1000,
|
||||||
|
ForceOn = 0b1001,
|
||||||
|
ForceHiZ = 0b1010,
|
||||||
|
ForceBlink = 0b1011,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait PhyAccess {
|
pub trait PhyAccess {
|
||||||
fn read_phy(&mut self, addr: u8, reg: u8) -> u16;
|
fn read_phy(&mut self, addr: u8, reg: u8) -> u16;
|
||||||
fn write_phy(&mut self, addr: u8, reg: u8, data: u16);
|
fn write_phy(&mut self, addr: u8, reg: u8, data: u16);
|
||||||
@ -33,6 +71,7 @@ pub trait PhyAccess {
|
|||||||
|
|
||||||
pub trait PhyRegister {
|
pub trait PhyRegister {
|
||||||
fn addr() -> u8;
|
fn addr() -> u8;
|
||||||
|
fn page() -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +84,10 @@ const OUI_MARVELL: u32 = 0x005043;
|
|||||||
const OUI_REALTEK: u32 = 0x000732;
|
const OUI_REALTEK: u32 = 0x000732;
|
||||||
const OUI_LANTIQ : u32 = 0x355969;
|
const OUI_LANTIQ : u32 = 0x355969;
|
||||||
|
|
||||||
|
//only change pages on Kasli-SoC's Marvel 88E11xx
|
||||||
|
#[cfg(feature="target_kasli_soc")]
|
||||||
|
const PAGE_REGISTER: u8 = 0x16;
|
||||||
|
|
||||||
impl Phy {
|
impl Phy {
|
||||||
/// Probe all addresses on MDIO for a known PHY
|
/// Probe all addresses on MDIO for a known PHY
|
||||||
pub fn find<PA: PhyAccess>(pa: &mut PA) -> Option<Phy> {
|
pub fn find<PA: PhyAccess>(pa: &mut PA) -> Option<Phy> {
|
||||||
@ -84,6 +127,9 @@ impl Phy {
|
|||||||
PA: PhyAccess,
|
PA: PhyAccess,
|
||||||
PR: PhyRegister + From<u16>,
|
PR: PhyRegister + From<u16>,
|
||||||
{
|
{
|
||||||
|
#[cfg(feature="target_kasli_soc")]
|
||||||
|
pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into());
|
||||||
|
|
||||||
pa.read_phy(self.addr, PR::addr()).into()
|
pa.read_phy(self.addr, PR::addr()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +139,9 @@ impl Phy {
|
|||||||
PR: PhyRegister + From<u16> + Into<u16>,
|
PR: PhyRegister + From<u16> + Into<u16>,
|
||||||
F: FnMut(PR) -> PR,
|
F: FnMut(PR) -> PR,
|
||||||
{
|
{
|
||||||
|
#[cfg(feature="target_kasli_soc")]
|
||||||
|
pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into());
|
||||||
|
|
||||||
let reg = pa.read_phy(self.addr, PR::addr()).into();
|
let reg = pa.read_phy(self.addr, PR::addr()).into();
|
||||||
let reg = f(reg);
|
let reg = f(reg);
|
||||||
pa.write_phy(self.addr, PR::addr(), reg.into())
|
pa.write_phy(self.addr, PR::addr(), reg.into())
|
||||||
@ -106,6 +155,14 @@ impl Phy {
|
|||||||
self.modify_reg(pa, f)
|
self.modify_reg(pa, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn modify_leds<PA, F>(&self, pa: &mut PA, f: F)
|
||||||
|
where
|
||||||
|
PA: PhyAccess,
|
||||||
|
F: FnMut(Leds) -> Leds,
|
||||||
|
{
|
||||||
|
self.modify_reg(pa, f)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_control<PA: PhyAccess>(&self, pa: &mut PA) -> Control {
|
pub fn get_control<PA: PhyAccess>(&self, pa: &mut PA) -> Control {
|
||||||
self.read_reg(pa)
|
self.read_reg(pa)
|
||||||
}
|
}
|
||||||
@ -139,4 +196,12 @@ impl Phy {
|
|||||||
.set_restart_autoneg(true)
|
.set_restart_autoneg(true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature="target_kasli_soc")]
|
||||||
|
pub fn set_leds<PA: PhyAccess>(&self, pa: &mut PA) {
|
||||||
|
self.modify_leds(pa, |leds|
|
||||||
|
leds.set_led0(Led0Control::OnCopperLinkOffElse)
|
||||||
|
.set_led1(Led1Control::BlinkActivityOffNoActivity)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,10 @@ impl PhyRegister for PSSR {
|
|||||||
fn addr() -> u8 {
|
fn addr() -> u8 {
|
||||||
0x11
|
0x11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for PSSR {
|
impl From<u16> for PSSR {
|
||||||
|
@ -100,6 +100,10 @@ impl PhyRegister for Status {
|
|||||||
fn addr() -> u8 {
|
fn addr() -> u8 {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for Status {
|
impl From<u16> for Status {
|
||||||
|
@ -35,14 +35,14 @@ impl<'a> EEPROM<'a> {
|
|||||||
|
|
||||||
#[cfg(feature = "target_zc706")]
|
#[cfg(feature = "target_zc706")]
|
||||||
fn select(&mut self) -> Result<(), &'static str> {
|
fn select(&mut self) -> Result<(), &'static str> {
|
||||||
self.i2c.pca954x_select(0b1110100, self.port)?;
|
self.i2c.pca954x_select(0b1110100, Some(self.port))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
fn select(&mut self) -> Result<(), &'static str> {
|
fn select(&mut self) -> Result<(), &'static str> {
|
||||||
// tca9548 is compatible with pca9548
|
// tca9548 is compatible with pca9548
|
||||||
self.i2c.pca954x_select(0b1110001, self.port)?;
|
self.i2c.pca954x_select(0b1110001, Some(self.port))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,10 @@ use super::slcr;
|
|||||||
use super::time::Microseconds;
|
use super::time::Microseconds;
|
||||||
use embedded_hal::timer::CountDown;
|
use embedded_hal::timer::CountDown;
|
||||||
use libregister::{RegisterR, RegisterRW, RegisterW};
|
use libregister::{RegisterR, RegisterRW, RegisterW};
|
||||||
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
use log::info;
|
||||||
|
|
||||||
enum PCA954X {
|
pub enum I2cMultiplexer {
|
||||||
PCA9548 = 0,
|
PCA9548 = 0,
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
PCA9547 = 1,
|
PCA9547 = 1,
|
||||||
@ -16,7 +18,7 @@ enum PCA954X {
|
|||||||
pub struct I2c {
|
pub struct I2c {
|
||||||
regs: regs::RegisterBlock,
|
regs: regs::RegisterBlock,
|
||||||
count_down: super::timer::global::CountDown<Microseconds>,
|
count_down: super::timer::global::CountDown<Microseconds>,
|
||||||
pca_type: PCA954X
|
pca_type: I2cMultiplexer
|
||||||
}
|
}
|
||||||
|
|
||||||
impl I2c {
|
impl I2c {
|
||||||
@ -63,7 +65,7 @@ impl I2c {
|
|||||||
let self_ = Self {
|
let self_ = Self {
|
||||||
regs: regs::RegisterBlock::i2c(),
|
regs: regs::RegisterBlock::i2c(),
|
||||||
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown(),
|
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown(),
|
||||||
pca_type: PCA954X::PCA9548
|
pca_type: I2cMultiplexer::PCA9548 //default for zc706
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup GPIO output mask
|
// Setup GPIO output mask
|
||||||
@ -75,7 +77,7 @@ impl I2c {
|
|||||||
w.scl(true).sda(true)
|
w.scl(true).sda(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
//Kasli-SoC exclusive: I2C_SW_RESET configuration
|
//Kasli-SoC only: I2C_SW_RESET configuration
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
{
|
{
|
||||||
self_.regs.gpio_output_mask_lower.modify(|_, w| {
|
self_.regs.gpio_output_mask_lower.modify(|_, w| {
|
||||||
@ -144,12 +146,14 @@ impl I2c {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
pub fn pca_autodetect(&mut self) -> Result<PCA954X, &'static str> {
|
fn pca_autodetect(&mut self) -> Result<I2cMultiplexer, &'static str> {
|
||||||
// start with resetting the PCA954X
|
// start with resetting the PCA954X
|
||||||
|
// SDA must be clear (before start)
|
||||||
/*self.i2cswr_oe(false);
|
// reset time is 500ns, unit_delay (100us) to account for propagation
|
||||||
|
self.i2cswr_o(true);
|
||||||
|
self.unit_delay();
|
||||||
|
self.i2cswr_o(false);
|
||||||
self.unit_delay();
|
self.unit_delay();
|
||||||
self.i2cswr_oe(true);*/
|
|
||||||
|
|
||||||
let pca954x_read_addr = (0x71 << 1) | 0x01;
|
let pca954x_read_addr = (0x71 << 1) | 0x01;
|
||||||
|
|
||||||
@ -161,8 +165,8 @@ impl I2c {
|
|||||||
let config = self.read(false)?;
|
let config = self.read(false)?;
|
||||||
|
|
||||||
let pca = match config {
|
let pca = match config {
|
||||||
0x00 => PCA954X::PCA9548,
|
0x00 => { info!("PCA9548 detected"); I2cMultiplexer::PCA9548 },
|
||||||
0x08 => PCA954X::PCA9547,
|
0x08 => { info!("PCA9547 detected"); I2cMultiplexer::PCA9547 },
|
||||||
_ => { return Err("Unknown response for PCA954X autodetect")},
|
_ => { return Err("Unknown response for PCA954X autodetect")},
|
||||||
};
|
};
|
||||||
self.stop()?;
|
self.stop()?;
|
||||||
@ -198,7 +202,7 @@ impl I2c {
|
|||||||
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
{
|
{
|
||||||
self.unit_delay();
|
self.i2cswr_oe(true);
|
||||||
self.pca_type = self.pca_autodetect()?;
|
self.pca_type = self.pca_autodetect()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,21 +301,32 @@ impl I2c {
|
|||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pca954x_select(&mut self, address: u8, channel: u8) -> Result<(), &'static str> {
|
pub fn pca954x_select(&mut self, address: u8, channel: Option<u8>) -> Result<(), &'static str> {
|
||||||
self.start()?;
|
self.start()?;
|
||||||
// PCA9547 supports only one channel at a time
|
// PCA9547 supports only one channel at a time
|
||||||
// for compatibility, PCA9548 is treated as such
|
// for compatibility, PCA9548 is treated as such too
|
||||||
|
// channel - Some(x) - # of the channel [0,7], or None for all disabled
|
||||||
let setting = match self.pca_type {
|
let setting = match self.pca_type {
|
||||||
PCA954X::PCA9548 => 1 << channel,
|
I2cMultiplexer::PCA9548 => {
|
||||||
|
match channel {
|
||||||
|
Some(ch) => 1 << ch,
|
||||||
|
None => 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
PCA954X::PCA9547 => channel | 0x08,
|
I2cMultiplexer::PCA9547 => {
|
||||||
|
match channel {
|
||||||
|
Some(ch) => ch | 0x08,
|
||||||
|
None => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.write(address << 1)? {
|
if !self.write(address << 1)? {
|
||||||
return Err("PCA9548 failed to ack write address")
|
return Err("PCA954X failed to ack write address")
|
||||||
}
|
}
|
||||||
if !self.write(setting)? {
|
if !self.write(setting)? {
|
||||||
return Err("PCA9548 failed to ack control word")
|
return Err("PCA954X failed to ack control word")
|
||||||
}
|
}
|
||||||
self.stop()?;
|
self.stop()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -30,7 +30,19 @@ impl fmt::Display for NetAddresses {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_adresses(cfg: &Config) -> NetAddresses {
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
|
fn get_address_from_eeprom() -> EthernetAddress {
|
||||||
|
use libboard_zynq::i2c::{I2c, eeprom};
|
||||||
|
|
||||||
|
let mut i2c = I2c::i2c0();
|
||||||
|
i2c.init().unwrap();
|
||||||
|
let mut eeprom = eeprom::EEPROM::new(&mut i2c, 16);
|
||||||
|
let address = eeprom.read_eui48().unwrap_or([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
|
||||||
|
|
||||||
|
EthernetAddress(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_addresses(cfg: &Config) -> NetAddresses {
|
||||||
#[cfg(feature = "target_zc706")]
|
#[cfg(feature = "target_zc706")]
|
||||||
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x52]);
|
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x52]);
|
||||||
#[cfg(feature = "target_zc706")]
|
#[cfg(feature = "target_zc706")]
|
||||||
@ -44,7 +56,7 @@ pub fn get_adresses(cfg: &Config) -> NetAddresses {
|
|||||||
#[cfg(feature = "target_redpitaya")]
|
#[cfg(feature = "target_redpitaya")]
|
||||||
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 55);
|
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 55);
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
|
let mut hardware_addr = get_address_from_eeprom();
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56);
|
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56);
|
||||||
|
|
||||||
|
20
openocd/common.cfg
Normal file
20
openocd/common.cfg
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
set XC7_JSHUTDOWN 0x0d
|
||||||
|
set XC7_JPROGRAM 0x0b
|
||||||
|
set XC7_JSTART 0x0c
|
||||||
|
set XC7_BYPASS 0x3f
|
||||||
|
|
||||||
|
proc xc7_program {tap} {
|
||||||
|
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
||||||
|
irscan $tap $XC7_JSHUTDOWN
|
||||||
|
irscan $tap $XC7_JPROGRAM
|
||||||
|
runtest 60000
|
||||||
|
#JSTART prevents this from working...
|
||||||
|
#irscan $tap $XC7_JSTART
|
||||||
|
runtest 2000
|
||||||
|
irscan $tap $XC7_BYPASS
|
||||||
|
runtest 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
pld device virtex2 zynq.tap 1
|
||||||
|
init
|
||||||
|
xc7_program zynq.tap
|
@ -8,26 +8,7 @@ source ./zynq-7000.cfg
|
|||||||
|
|
||||||
reset_config srst_only srst_push_pull
|
reset_config srst_only srst_push_pull
|
||||||
|
|
||||||
set XC7_JSHUTDOWN 0x0d
|
source ./common.cfg
|
||||||
set XC7_JPROGRAM 0x0b
|
|
||||||
set XC7_JSTART 0x0c
|
|
||||||
set XC7_BYPASS 0x3f
|
|
||||||
|
|
||||||
proc xc7_program {tap} {
|
|
||||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
|
||||||
irscan $tap $XC7_JSHUTDOWN
|
|
||||||
irscan $tap $XC7_JPROGRAM
|
|
||||||
runtest 60000
|
|
||||||
#JSTART prevents this from working...
|
|
||||||
#irscan $tap $XC7_JSTART
|
|
||||||
runtest 2000
|
|
||||||
irscan $tap $XC7_BYPASS
|
|
||||||
runtest 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
pld device virtex2 zynq.tap 1
|
|
||||||
init
|
|
||||||
xc7_program zynq.tap
|
|
||||||
|
|
||||||
reset halt
|
reset halt
|
||||||
|
|
||||||
|
@ -17,26 +17,7 @@ reset_config srst_only srst_open_drain
|
|||||||
adapter srst pulse_width 250
|
adapter srst pulse_width 250
|
||||||
adapter srst delay 400
|
adapter srst delay 400
|
||||||
|
|
||||||
set XC7_JSHUTDOWN 0x0d
|
source ./common.cfg
|
||||||
set XC7_JPROGRAM 0x0b
|
|
||||||
set XC7_JSTART 0x0c
|
|
||||||
set XC7_BYPASS 0x3f
|
|
||||||
|
|
||||||
proc xc7_program {tap} {
|
|
||||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
|
||||||
irscan $tap $XC7_JSHUTDOWN
|
|
||||||
irscan $tap $XC7_JPROGRAM
|
|
||||||
runtest 60000
|
|
||||||
#JSTART prevents this from working...
|
|
||||||
#irscan $tap $XC7_JSTART
|
|
||||||
runtest 2000
|
|
||||||
irscan $tap $XC7_BYPASS
|
|
||||||
runtest 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
pld device virtex2 zynq.tap 1
|
|
||||||
init
|
|
||||||
xc7_program zynq.tap
|
|
||||||
|
|
||||||
reset halt
|
reset halt
|
||||||
|
|
||||||
|
@ -8,26 +8,7 @@ source ./zynq-7000.cfg
|
|||||||
|
|
||||||
reset_config none
|
reset_config none
|
||||||
|
|
||||||
set XC7_JSHUTDOWN 0x0d
|
source ./common.cfg
|
||||||
set XC7_JPROGRAM 0x0b
|
|
||||||
set XC7_JSTART 0x0c
|
|
||||||
set XC7_BYPASS 0x3f
|
|
||||||
|
|
||||||
proc xc7_program {tap} {
|
|
||||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
|
||||||
irscan $tap $XC7_JSHUTDOWN
|
|
||||||
irscan $tap $XC7_JPROGRAM
|
|
||||||
runtest 60000
|
|
||||||
#JSTART prevents this from working...
|
|
||||||
#irscan $tap $XC7_JSTART
|
|
||||||
runtest 2000
|
|
||||||
irscan $tap $XC7_BYPASS
|
|
||||||
runtest 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
pld device virtex2 zynq.tap 1
|
|
||||||
init
|
|
||||||
xc7_program zynq.tap
|
|
||||||
|
|
||||||
halt
|
halt
|
||||||
|
|
||||||
|
@ -10,26 +10,7 @@ reset_config srst_only srst_open_drain
|
|||||||
adapter srst pulse_width 250
|
adapter srst pulse_width 250
|
||||||
adapter srst delay 400
|
adapter srst delay 400
|
||||||
|
|
||||||
set XC7_JSHUTDOWN 0x0d
|
source ./common.cfg
|
||||||
set XC7_JPROGRAM 0x0b
|
|
||||||
set XC7_JSTART 0x0c
|
|
||||||
set XC7_BYPASS 0x3f
|
|
||||||
|
|
||||||
proc xc7_program {tap} {
|
|
||||||
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
|
|
||||||
irscan $tap $XC7_JSHUTDOWN
|
|
||||||
irscan $tap $XC7_JPROGRAM
|
|
||||||
runtest 60000
|
|
||||||
#JSTART prevents this from working...
|
|
||||||
#irscan $tap $XC7_JSTART
|
|
||||||
runtest 2000
|
|
||||||
irscan $tap $XC7_BYPASS
|
|
||||||
runtest 2000
|
|
||||||
}
|
|
||||||
|
|
||||||
pld device virtex2 zynq.tap 1
|
|
||||||
init
|
|
||||||
xc7_program zynq.tap
|
|
||||||
|
|
||||||
reset halt
|
reset halt
|
||||||
|
|
||||||
|
@ -136,7 +136,14 @@ pub fn main_core0() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
v => {
|
v => {
|
||||||
panic!("Boot mode {:?} not supported", v);
|
log::error!("Boot mode {:?} not supported", v);
|
||||||
|
log::info!("Fall back on netboot");
|
||||||
|
netboot::netboot(
|
||||||
|
&mut bootgen_file,
|
||||||
|
config,
|
||||||
|
&mut __runtime_start as *mut usize as *mut u8,
|
||||||
|
max_len,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ pub fn netboot<File: Read + Seek>(
|
|||||||
runtime_max_len: usize,
|
runtime_max_len: usize,
|
||||||
) {
|
) {
|
||||||
log::info!("Preparing network for netboot");
|
log::info!("Preparing network for netboot");
|
||||||
let net_addresses = net_settings::get_adresses(&cfg);
|
let net_addresses = net_settings::get_addresses(&cfg);
|
||||||
log::info!("Network addresses: {}", net_addresses);
|
log::info!("Network addresses: {}", net_addresses);
|
||||||
let eth = Eth::eth0(net_addresses.hardware_addr.0.clone());
|
let eth = Eth::eth0(net_addresses.hardware_addr.0.clone());
|
||||||
let eth = eth.start_rx(8);
|
let eth = eth.start_rx(8);
|
||||||
|
Loading…
Reference in New Issue
Block a user