diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a38f4fe..cfad248 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: targets: "armv7a-none-eabihf" - - run: just build-dir firmware + - run: just build-zynq - run: just build-dir host fmt: diff --git a/firmware/zynq7000/CHANGELOG.md b/firmware/zynq7000/CHANGELOG.md index ac98383..4c51940 100644 --- a/firmware/zynq7000/CHANGELOG.md +++ b/firmware/zynq7000/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +# [v0.2.0] 2026-04-01 + - Renamed all register blocks to `Registers` to subblocks to `Registers`. - Updated IPTR registers in the GIC module to use a custom register type instead of a raw u32. - Added SDIO registers. @@ -22,6 +24,7 @@ Documentation fix Initial release -[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-v0.1.1...HEAD +[unreleased]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-v0.2.0...HEAD +[v0.2.0]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-v0.1.0...zynq7000-v0.2.0 [v0.1.1]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/compare/zynq7000-v0.1.0...zynq7000-v0.1.1 [v0.1.0]: https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/tag/zynq7000-v0.1.0 diff --git a/firmware/zynq7000/Cargo.toml b/firmware/zynq7000/Cargo.toml index 1fbbf76..a1ebfe5 100644 --- a/firmware/zynq7000/Cargo.toml +++ b/firmware/zynq7000/Cargo.toml @@ -20,6 +20,9 @@ thiserror = { version = "2", default-features = false } once_cell = { version = "1", default-features = false, features = ["critical-section"] } defmt = { version = "1", optional = true } +[features] +defmt = ["dep:defmt", "arbitrary-int/defmt"] + [dev-dependencies] approx = "0.5" diff --git a/firmware/zynq7000/src/ddrc.rs b/firmware/zynq7000/src/ddrc.rs index 3b61c84..25e5f15 100644 --- a/firmware/zynq7000/src/ddrc.rs +++ b/firmware/zynq7000/src/ddrc.rs @@ -6,6 +6,7 @@ pub mod regs { #[bitbybit::bitenum(u2)] #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DataBusWidth { _32Bit = 0b00, _16Bit = 0b01, @@ -13,11 +14,18 @@ pub mod regs { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SoftReset { Reset = 0, Active = 1, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DdrcControl { #[bit(16, rw)] disable_auto_refresh: bool, @@ -37,7 +45,14 @@ pub mod regs { soft_reset: SoftReset, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct TwoRankConfig { #[bits(14..=18, rw)] addrmap_cs_bit0: u5, @@ -50,7 +65,13 @@ pub mod regs { } /// Queue control for the low priority and high priority read queues. - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct LprHprQueueControl { #[bits(22..=25, rw)] xact_run_length: u4, @@ -60,7 +81,13 @@ pub mod regs { min_non_critical_x32: u11, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct WriteQueueControl { #[bits(15..=25, rw)] max_starve_x32: u11, @@ -70,7 +97,13 @@ pub mod regs { min_non_critical_x32: u11, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DramParamReg0 { /// Minimum time to wait after coming out of self refresh before doing anything. This must be /// bigger than all the constraints that exist. @@ -85,7 +118,13 @@ pub mod regs { t_rc: u6, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DramParamReg1 { #[bits(28..=31, rw)] t_cke: u4, @@ -101,7 +140,13 @@ pub mod regs { wr2pre: u5, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DramParamReg2 { #[bits(28..=31, rw)] t_rcd: u4, @@ -121,12 +166,19 @@ pub mod regs { /// Weird naming. #[bitbybit::bitenum(u1, exhaustive = true)] - #[derive(Debug)] + #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum MobileSetting { Ddr2Ddr3 = 0, Lpddr2 = 1, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DramParamReg3 { #[bit(30, rw)] disable_pad_pd_feature: bool, @@ -154,12 +206,19 @@ pub mod regs { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ModeRegisterType { Write = 0, Read = 1, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DramParamReg4 { #[bit(27, rw)] mr_rdata_valid: bool, @@ -179,7 +238,13 @@ pub mod regs { enable_2t_timing_mode: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramInitParam { #[bits(11..=13, rw)] t_mrd: u3, @@ -189,7 +254,13 @@ pub mod regs { final_wait_x32: u7, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramEmr { #[bits(16..=31, rw)] emr3: u16, @@ -197,7 +268,13 @@ pub mod regs { emr2: u16, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramEmrMr { #[bits(16..=31, rw)] emr: u16, @@ -205,7 +282,13 @@ pub mod regs { mr: u16, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramBurst8ReadWrite { #[bits(0..=3, rw)] burst_rdwr: u4, @@ -217,7 +300,13 @@ pub mod regs { burstchop: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DisableDq { #[bit(1, rw)] dis_dq: bool, @@ -225,7 +314,13 @@ pub mod regs { force_low_pri_n: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramAddrMapBank { #[bits(16..=19, rw)] addrmap_bank_b6: u4, @@ -239,7 +334,13 @@ pub mod regs { addrmap_bank_b0: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramAddrMapColumn { #[bits(28..=31, rw)] addrmap_col_b11: u4, @@ -259,7 +360,13 @@ pub mod regs { addrmap_col_b2: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramAddrMapRow { #[bits(24..=27, rw)] addrmap_row_b15: u4, @@ -277,7 +384,13 @@ pub mod regs { addrmap_row_b0: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DramOdt { #[bits(16..=17, rw)] phy_idle_local_odt: u2, @@ -291,7 +404,13 @@ pub mod regs { rank0_rd_odt: u3, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyCmdTimeoutRdDataCpt { #[bits(28..=31, rw)] wrlvl_num_of_dq0: u4, @@ -314,19 +433,32 @@ pub mod regs { } #[bitbybit::bitenum(u1, exhaustive = true)] - #[derive(Debug)] + #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DllCalibSel { Periodic = 0, Manual = 1, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct DllCalib { #[bit(16, rw)] sel: DllCalibSel, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct OdtDelayHold { #[bits(12..=15, rw)] wr_odt_hold: u4, @@ -338,7 +470,13 @@ pub mod regs { rd_odt_delay: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CtrlReg1 { #[bit(12, rw)] selfref_enable: bool, @@ -356,7 +494,13 @@ pub mod regs { pageclose: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CtrlReg2 { #[bit(17, rw)] go_2_critcal_enable: bool, @@ -364,7 +508,13 @@ pub mod regs { go_2_critical_hysteresis: u8, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CtrlReg3 { #[bits(16..=25, rw)] dfi_t_wlmrd: u10, @@ -374,7 +524,13 @@ pub mod regs { wrlvl_ww: u8, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CtrlReg4 { #[bits(8..=15, rw)] dfi_t_ctrlupd_interval_max_x1024: u8, @@ -382,7 +538,13 @@ pub mod regs { dfi_t_ctrlupd_interval_min_x1024: u8, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CtrlReg5 { #[bits(20..=25, rw)] t_ckesr: u6, @@ -398,7 +560,13 @@ pub mod regs { dfi_t_ctrl_delay: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CtrlReg6 { #[bits(16..=19, rw)] t_cksx: u4, @@ -412,7 +580,13 @@ pub mod regs { t_ckpde: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CheTZq { #[bits(22..=31, rw)] t_zq_short_nop: u10, @@ -426,7 +600,13 @@ pub mod regs { dis_auto_zq: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CheTZqShortInterval { #[bits(20..=27, rw)] dram_rstn_x1024: u8, @@ -434,7 +614,13 @@ pub mod regs { t_zq_short_interval: u20, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DeepPowerdown { #[bits(1..=8, rw)] deep_powerdown_to_x1024: u8, @@ -442,7 +628,13 @@ pub mod regs { enable: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct Reg2c { #[bit(28, rw)] dfi_rd_data_eye_train: bool, @@ -460,13 +652,25 @@ pub mod regs { dfi_wrlvl_max_x1024: u12, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct Reg2d { #[bit(9, rw)] skip_ocd: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct DfiTiming { #[bits(15..=24, rw)] dfi_t_ctrlup_max: u10, @@ -476,7 +680,13 @@ pub mod regs { dfi_t_rddata_enable: u5, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct CheEccControl { #[bit(1, rw)] clear_correctable_errors: bool, @@ -485,13 +695,20 @@ pub mod regs { } #[bitbybit::bitenum(u3, exhaustive = false)] - #[derive(Debug)] + #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum EccMode { NoEcc = 0b000, SecDecOverOneBeat = 0b100, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct EccScrub { #[bit(3, rw)] disable_scrub: bool, @@ -499,7 +716,13 @@ pub mod regs { ecc_mode: Option, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyReceiverEnable { #[bits(4..=7, rw)] phy_dif_off: u4, @@ -507,7 +730,13 @@ pub mod regs { phy_dif_on: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyConfig { #[bits(24..=30, rw)] dq_offset: u7, @@ -521,7 +750,13 @@ pub mod regs { data_slice_in_use: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyInitRatio { #[bits(10..=19, rw)] gatelvl_init_ratio: u10, @@ -529,7 +764,13 @@ pub mod regs { wrlvl_init_ratio: u10, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyDqsConfig { #[bits(11..=19, rw)] dqs_slave_delay: u9, @@ -539,7 +780,13 @@ pub mod regs { dqs_slave_ratio: u10, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyWriteEnableConfig { #[bits(12..=20, rw)] fifo_we_in_delay: u9, @@ -549,7 +796,13 @@ pub mod regs { fifo_we_slave_ratio: u11, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct PhyWriteDataSlaveConfig { #[bits(11..=19, rw)] wr_data_slave_delay: u9, @@ -559,7 +812,13 @@ pub mod regs { wr_data_slave_ratio: u10, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct Reg64 { #[bit(30, rw)] cmd_latency: bool, @@ -579,7 +838,13 @@ pub mod regs { bl2: bool, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct Reg65 { #[bits(18..=19, rw)] ctrl_slave_delay: u2, @@ -599,7 +864,13 @@ pub mod regs { wr_rl_delay: u5, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct AxiPriorityWritePort { #[bit(18, rw)] disable_page_match: bool, @@ -611,7 +882,13 @@ pub mod regs { pri_wr_port: u10, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct AxiPriorityReadPort { #[bit(19, rw)] enable_hpr: bool, @@ -625,7 +902,13 @@ pub mod regs { pri_rd_port_n: u10, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct ExclusiveAccessConfig { #[bits(9..=17, rw)] access_id1_port: u9, @@ -634,13 +917,20 @@ pub mod regs { } #[bitbybit::bitenum(u1, exhaustive = true)] - #[derive(Debug)] + #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum LpddrBit { Ddr2Ddr3 = 0, Lpddr2 = 1, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct LpddrControl0 { #[bits(4..=11, rw)] mr4_margin: u8, @@ -652,13 +942,25 @@ pub mod regs { lpddr2: LpddrBit, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct LpddrControl1 { #[bits(0..=31, rw)] mr4_read_interval: u32, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct LpddrControl2 { #[bits(12..=21, rw)] t_mrw: u10, @@ -668,7 +970,13 @@ pub mod regs { min_stable_clock_x1: u4, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps + )] pub struct LpddrControl3 { #[bits(8..=17, rw)] dev_zqinit_x32: u10, @@ -678,6 +986,7 @@ pub mod regs { #[bitbybit::bitenum(u3, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum OperatingMode { DdrcInit = 0, NormalOperation = 1, @@ -703,12 +1012,19 @@ pub mod regs { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DebugStallBit { CommandsAccepted = 0, CommandsNotAccepted = 1, } - #[bitbybit::bitfield(u32, default = 0x0, debug)] + #[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps + )] pub struct ModeStatus { #[bits(16..=20, r)] dbg_hpr_queue_depth: u5, diff --git a/firmware/zynq7000/src/devcfg.rs b/firmware/zynq7000/src/devcfg.rs index 8267a5c..0f0bcd6 100644 --- a/firmware/zynq7000/src/devcfg.rs +++ b/firmware/zynq7000/src/devcfg.rs @@ -4,6 +4,7 @@ pub const DEVCFG_BASE_ADDR: usize = 0xF8007000; #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum PlConfigAccess { /// Used for JTAG access TapController = 0, @@ -13,6 +14,7 @@ pub enum PlConfigAccess { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConfigAccessPortSelect { /// Internal Configuration Access Port (ICAP), using PL or PS-based software. Icap = 0, @@ -22,6 +24,7 @@ pub enum ConfigAccessPortSelect { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum TimerSelect { _64kTimer = 0, _4kTimer = 1, @@ -29,6 +32,7 @@ pub enum TimerSelect { #[bitbybit::bitenum(u3, exhaustive = false)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum AesEnable { Disable = 0b000, Enable = 0b111, @@ -36,6 +40,7 @@ pub enum AesEnable { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum PsBootMode { NonSecure = 0, Secure = 1, @@ -43,11 +48,18 @@ pub enum PsBootMode { #[bitbybit::bitenum(u3, exhaustive = false)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ArmDapEnable { Enabled = 0b111, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct Control { #[bit(31, rw)] force_reset: bool, @@ -95,7 +107,7 @@ pub struct Control { /// The bits in this register and read/write, set-only, which means that only a PS_POR_B reset /// can clear the bits. -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, debug, defmt_fields(feature = "defmt"), forbid_overlaps)] pub struct Lock { #[bit(4, rw)] aes_fuse: bool, @@ -113,6 +125,7 @@ pub struct Lock { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum EdgeConfig { Falling = 0, Rising = 1, @@ -121,6 +134,7 @@ pub enum EdgeConfig { /// Related to the full level for reads, and the empty level for writes. #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum FifoThresholdConfig { OneFourth = 0b00, HalfEmpty = 0b01, @@ -128,7 +142,7 @@ pub enum FifoThresholdConfig { EmptyOrFull = 0b11, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"), forbid_overlaps)] pub struct Config { #[bits(10..=11, rw)] read_fifo_threshhold: FifoThresholdConfig, @@ -144,7 +158,7 @@ pub struct Config { disable_dst_incremenet: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"), forbid_overlaps)] pub struct Interrupt { /// Tri-state PL IO during HIZ. #[bit(31, rw)] @@ -199,7 +213,7 @@ pub struct Interrupt { negative_edge_pl_init: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct MiscControl { #[bits(28..=31, r)] ps_version: u4, @@ -213,6 +227,7 @@ pub struct MiscControl { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum UnacknowledgedDmaTransfers { None = 0b00, One = 0b01, @@ -220,7 +235,7 @@ pub enum UnacknowledgedDmaTransfers { ThreeOrMore = 0b11, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"), forbid_overlaps)] pub struct Status { #[bit(31, rw)] dma_command_queue_full: bool, diff --git a/firmware/zynq7000/src/eth.rs b/firmware/zynq7000/src/eth.rs index adcd59e..57da553 100644 --- a/firmware/zynq7000/src/eth.rs +++ b/firmware/zynq7000/src/eth.rs @@ -4,8 +4,7 @@ use arbitrary_int::{u2, u5}; pub const GEM_0_BASE_ADDR: usize = 0xE000_B000; pub const GEM_1_BASE_ADDR: usize = 0xE000_C000; -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct NetworkControl { #[bit(18, w)] flush_next_rx_dpram_pkt: bool, @@ -41,6 +40,7 @@ pub struct NetworkControl { /// The speed mode selects between 10 Mbps and 100 Mbps if the Gigabit enable bit is cleared. #[bitbybit::bitenum(u1, exhaustive = true)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[derive(Debug, PartialEq, Eq)] pub enum SpeedMode { Low10Mbps = 0, @@ -49,6 +49,7 @@ pub enum SpeedMode { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum PcsSelect { GmiiMii = 0, Tbi = 1, @@ -56,6 +57,7 @@ pub enum PcsSelect { #[bitbybit::bitenum(u3, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum MdcClockDivisor { Div8 = 0, Div16 = 1, @@ -82,7 +84,13 @@ impl MdcClockDivisor { } } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_fields(feature = "defmt") +)] pub struct NetworkConfig { #[bit(30, rw)] ignore_ipg_rx_error: bool, @@ -140,7 +148,7 @@ pub struct NetworkConfig { } /// PHY management status information. -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_fields(feature = "defmt"))] pub struct NetworkStatus { #[bit(6, r)] pfc_pri_pause_neg: bool, @@ -159,6 +167,7 @@ pub struct NetworkStatus { } #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BurstLength { Single, #[default] @@ -180,12 +189,14 @@ impl BurstLength { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum AhbEndianess { Little = 0, Big = 1, } #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DmaRxBufSize(u8); impl DmaRxBufSize { @@ -213,7 +224,13 @@ impl DmaRxBufSize { } } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_fields(feature = "defmt") +)] pub struct DmaConfig { #[bit(24, rw)] discard_when_ahb_full: bool, @@ -241,7 +258,7 @@ pub struct DmaConfig { burst_length: u5, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_bitfields(feature = "defmt"))] pub struct TxStatus { #[bit(8, rw)] hresp_not_ok: bool, @@ -272,7 +289,7 @@ impl TxStatus { } } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_bitfields(feature = "defmt"))] pub struct RxStatus { #[bit(3, rw)] hresp_not_ok: bool, @@ -290,7 +307,13 @@ impl RxStatus { } } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_bitfields(feature = "defmt") +)] pub struct InterruptStatus { #[bit(26, rw)] tsu_sec_incr: bool, @@ -381,13 +404,20 @@ impl InterruptControl { } #[bitbybit::bitenum(u2, exhaustive = false)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum PhyOperation { Read = 0b10, Write = 0b01, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_fields(feature = "defmt") +)] pub struct PhyMaintenance { /// Must be 1 for Clause 22 operations. #[bit(30, rw)] @@ -404,13 +434,25 @@ pub struct PhyMaintenance { data: u16, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_bitfields(feature = "defmt") +)] pub struct PauseQuantum { #[bits(0..=15, rw)] value: u16, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_bitfields(feature = "defmt") +)] pub struct MatchRegister { #[bit(31, rw)] copy_enable: bool, diff --git a/firmware/zynq7000/src/gic.rs b/firmware/zynq7000/src/gic.rs index 1e47bd3..b2a8f68 100644 --- a/firmware/zynq7000/src/gic.rs +++ b/firmware/zynq7000/src/gic.rs @@ -4,7 +4,13 @@ use arbitrary_int::{u2, u3, u5, u10}; use static_assertions::const_assert_eq; /// Distributor Control Register -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct DistributorControlRegister { #[bit(1, rw)] enable_non_secure: bool, @@ -13,7 +19,7 @@ pub struct DistributorControlRegister { } /// Read only bit. This register only returns fixed constants. -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct TypeRegister { #[bits(11..=15, r)] lspi: u5, @@ -40,10 +46,9 @@ impl TypeRegister { pub type Typer = TypeRegister; -// TODO: Use bitbybit debug derive if new release was released. -/// Interrupt processor target register (IPTR). -#[bitbybit::bitfield(u32)] -#[derive(Debug, PartialEq, Eq)] +#[bitbybit::bitfield(u32, debug)] +#[derive(PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct InterruptProcessorTargetRegister { /// Target array. Every register holds the information for 4 interrupts. #[bits(0..=1, rw, stride = 8)] @@ -141,7 +146,13 @@ impl DistributorRegisters { } /// CPU interface control register. -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct InterfaceControl { #[bit(4, rw)] sbpr: bool, @@ -156,14 +167,14 @@ pub struct InterfaceControl { } /// Priority Mask Register -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct PriorityRegister { #[bits(0..=7, rw)] priority: u8, } /// Interrupt acknowledge register. -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct InterruptSignalRegister { #[bits(10..=12, rw)] cpu_id: u3, diff --git a/firmware/zynq7000/src/gpio.rs b/firmware/zynq7000/src/gpio.rs index f86782e..8b658d4 100644 --- a/firmware/zynq7000/src/gpio.rs +++ b/firmware/zynq7000/src/gpio.rs @@ -1,5 +1,10 @@ //! # GPIO register module. -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield( + u32, + default = 0x0, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] #[derive(Debug)] pub struct MaskedOutput { #[bits(16..=31, w)] diff --git a/firmware/zynq7000/src/gtc.rs b/firmware/zynq7000/src/gtc.rs index ef4958e..2cdfd5b 100644 --- a/firmware/zynq7000/src/gtc.rs +++ b/firmware/zynq7000/src/gtc.rs @@ -2,7 +2,7 @@ pub const GTC_BASE_ADDR: usize = super::mpcore::MPCORE_BASE_ADDR + 0x0000_0200; -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_bitfields(feature = "defmt"))] pub struct GtcControl { #[bits(8..=15, rw)] prescaler: u8, @@ -16,7 +16,7 @@ pub struct GtcControl { enable: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_bitfields(feature = "defmt"))] pub struct InterruptStatus { #[bit(0, rw)] event_flag: bool, diff --git a/firmware/zynq7000/src/i2c.rs b/firmware/zynq7000/src/i2c.rs index 474f455..0e63e4c 100644 --- a/firmware/zynq7000/src/i2c.rs +++ b/firmware/zynq7000/src/i2c.rs @@ -5,20 +5,22 @@ pub const I2C_0_BASE_ADDR: usize = 0xE000_4000; pub const I2C_1_BASE_ADDR: usize = 0xE000_5000; #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Direction { Receiver = 0b1, Transmitter = 0b0, } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Mode { Slave = 0b0, Master = 0b1, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_fields(feature = "defmt"))] pub struct Control { /// Divides the input PCLK frequency by this value + 1 #[bits(14..=15, rw)] @@ -47,7 +49,7 @@ pub struct Control { dir: Direction, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct Status { #[bit(8, r)] bus_active: bool, @@ -65,19 +67,19 @@ pub struct Status { rx_rw: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct Address { #[bits(0..=9, rw)] addr: u10, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct Fifo { #[bits(0..=7, rw)] data: u8, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))] pub struct InterruptStatus { #[bit(9, rw)] arbitration_lost: bool, @@ -99,7 +101,7 @@ pub struct InterruptStatus { complete: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct InterruptMask { #[bit(9, r)] arbitration_lost: bool, @@ -121,7 +123,7 @@ pub struct InterruptMask { complete: bool, } -#[bitbybit::bitfield(u32)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct InterruptControl { #[bit(9, w)] arbitration_lost: bool, @@ -143,14 +145,14 @@ pub struct InterruptControl { complete: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct Timeout { /// Reset value: 0x1F. #[bits(0..=7, rw)] timeout: u8, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct TransferSize { #[bits(0..=7, rw)] size: u8, diff --git a/firmware/zynq7000/src/l2_cache.rs b/firmware/zynq7000/src/l2_cache.rs index 74010fb..523d700 100644 --- a/firmware/zynq7000/src/l2_cache.rs +++ b/firmware/zynq7000/src/l2_cache.rs @@ -9,13 +9,13 @@ pub struct LockdownRegisters { instruction: u32, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))] pub struct CacheSync { #[bit(0, r)] busy: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct DebugControl { #[bit(2, rw)] spniden: bool, @@ -25,7 +25,7 @@ pub struct DebugControl { disable_cache_linefill: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))] pub struct CacheId { #[bits(24..=31, r)] implementer: u8, @@ -56,14 +56,16 @@ impl Control { } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ReplacementPolicy { PseudoRandomWithLfsr = 0, RoundRobin = 1, } #[bitbybit::bitenum(u3, exhaustive = true)] -#[derive(Default, Debug)] +#[derive(Default, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum WaySize { __Reserved0 = 0b000, _16kB = 0b001, @@ -77,14 +79,21 @@ pub enum WaySize { } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Default, Debug)] +#[derive(Default, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Associativity { #[default] _8Way = 0, _16Way = 1, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct AuxControl { #[bit(30, rw)] early_bresp_enable: bool, @@ -123,7 +132,13 @@ pub struct AuxControl { full_line_zero_enable: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] #[derive(PartialEq, Eq)] pub struct LatencyConfig { /// Latency is the numerical value + 1 cycles. @@ -137,7 +152,7 @@ pub struct LatencyConfig { setup_latency: u3, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct InterruptStatus { #[bit(8, r)] dec_error_l3: bool, @@ -160,7 +175,12 @@ pub struct InterruptStatus { event_counter_overflow_increment: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield( + u32, + default = 0x0, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] #[derive(Debug)] pub struct InterruptControl { #[bit(8, w)] diff --git a/firmware/zynq7000/src/lib.rs b/firmware/zynq7000/src/lib.rs index 1c7134b..45cac5b 100644 --- a/firmware/zynq7000/src/lib.rs +++ b/firmware/zynq7000/src/lib.rs @@ -115,6 +115,7 @@ impl Peripherals { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SpiClockPhase { ActiveOutsideOfWord = 0, InactiveOutsideOfWord = 1, @@ -122,6 +123,7 @@ pub enum SpiClockPhase { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SpiClockPolarity { QuiescentLow = 0, QuiescentHigh = 1, diff --git a/firmware/zynq7000/src/mpcore.rs b/firmware/zynq7000/src/mpcore.rs index 6bff3af..59ce498 100644 --- a/firmware/zynq7000/src/mpcore.rs +++ b/firmware/zynq7000/src/mpcore.rs @@ -19,7 +19,7 @@ pub const GICD_BASE_ADDR: usize = MPCORE_BASE_ADDR + 0x1000; #[derive(derive_mmio::Mmio)] #[repr(C)] pub struct SnoopControlUnit { - ctrl: u32, + control: u32, config: u32, cpu_power_status: u32, invalidate_all_regs_in_secure_state: u32, diff --git a/firmware/zynq7000/src/priv_tim.rs b/firmware/zynq7000/src/priv_tim.rs index d397515..bbcc9df 100644 --- a/firmware/zynq7000/src/priv_tim.rs +++ b/firmware/zynq7000/src/priv_tim.rs @@ -2,7 +2,13 @@ pub const CPU_PRIV_TIM_BASE_ADDR: usize = super::mpcore::MPCORE_BASE_ADDR + 0x0000_0600; -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct Control { #[bits(8..=15, rw)] prescaler: u8, @@ -14,7 +20,13 @@ pub struct Control { enable: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct InterruptStatus { /// Cleared by writing a one. #[bit(0, rw)] diff --git a/firmware/zynq7000/src/qspi.rs b/firmware/zynq7000/src/qspi.rs index bd335e1..6978b7f 100644 --- a/firmware/zynq7000/src/qspi.rs +++ b/firmware/zynq7000/src/qspi.rs @@ -6,6 +6,7 @@ pub const QSPI_BASE_ADDR: usize = 0xE000D000; #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum InterfaceMode { LegacySpi = 0, FlashMemoryInterface = 1, @@ -13,6 +14,7 @@ pub enum InterfaceMode { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Endianness { Little = 0, Big = 1, @@ -21,6 +23,7 @@ pub enum Endianness { /// Baud rate divisor register values. #[bitbybit::bitenum(u3, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BaudRateDivisor { _2 = 0b000, _4 = 0b001, @@ -48,9 +51,13 @@ impl BaudRateDivisor { } } -// TODO: Use bitbybit debug support as soon as support for write fields has been implemented. -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct Config { #[bit(31, rw)] interface_mode: InterfaceMode, diff --git a/firmware/zynq7000/src/sdio.rs b/firmware/zynq7000/src/sdio.rs index 312db14..ae8d71a 100644 --- a/firmware/zynq7000/src/sdio.rs +++ b/firmware/zynq7000/src/sdio.rs @@ -5,6 +5,7 @@ pub const SDIO_BASE_ADDR_1: usize = 0xE010_1000; #[bitbybit::bitenum(u3, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BufferSize { _4kB = 0b000, _8kB = 0b001, @@ -16,7 +17,13 @@ pub enum BufferSize { _512kB = 0b111, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + debug, + default = 0x0, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct BlockParams { #[bits(16..=31, rw)] blocks_count: u16, @@ -28,6 +35,7 @@ pub struct BlockParams { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Default, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum CommandType { #[default] Normal = 0b00, @@ -38,6 +46,7 @@ pub enum CommandType { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ResponseType { // No response. None = 0b00, @@ -48,6 +57,7 @@ pub enum ResponseType { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BlockSelect { SingleBlock = 0, MultiBlock = 1, @@ -55,6 +65,7 @@ pub enum BlockSelect { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum TransferDirection { /// Host to card. Write = 0, @@ -62,7 +73,13 @@ pub enum TransferDirection { Read = 1, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct CommandRegister { /// Set to command number (CMD0-63, ACMD0-63) #[bits(24..=29, rw)] @@ -100,7 +117,7 @@ pub struct CommandRegister { dma_enable: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct PresentState { #[bit(24, r)] cmd_line_signal_level: bool, @@ -196,6 +213,7 @@ pub struct PresentState { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BusWidth { _1bit = 0, _4bits = 1, @@ -203,6 +221,7 @@ pub enum BusWidth { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DmaSelect { Sdma = 0b00, Adma1_32bits = 0b01, @@ -212,6 +231,7 @@ pub enum DmaSelect { #[bitbybit::bitenum(u3, exhaustive = false)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SdBusVoltageSelect { Off = 0b000, _1_8V = 0b101, @@ -219,7 +239,13 @@ pub enum SdBusVoltageSelect { _3_3V = 0b111, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct HostPowerBlockgapWakeupControl { #[bit(26, rw)] wakeup_event_enable_on_sd_card_removal: bool, @@ -255,6 +281,7 @@ pub struct HostPowerBlockgapWakeupControl { #[bitbybit::bitenum(u8, exhaustive = false)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SdClockDivisor { Div256 = 0x80, Div128 = 0x40, @@ -267,7 +294,13 @@ pub enum SdClockDivisor { Div1 = 0x00, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct ClockAndTimeoutAndSwResetControl { #[bit(26, rw)] software_reset_for_dat_line: bool, @@ -290,7 +323,7 @@ pub struct ClockAndTimeoutAndSwResetControl { internal_clock_enable: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct InterruptStatus { #[bit(29, rw)] ceata_error_status: bool, @@ -346,7 +379,7 @@ impl InterruptStatus { pub const ALL_BITS: u32 = 0x33FF06FF; } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct InterruptMask { #[bit(29, rw)] ceata_error_status: bool, @@ -398,7 +431,7 @@ pub struct InterruptMask { command_complete: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct Capabilities { #[bit(30, rw)] spi_block_mode: bool, @@ -430,7 +463,7 @@ pub struct Capabilities { timeout_clock_unit: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))] pub struct BlockSizeRegister { /// Enabled when block count enable in the transfer mode register is set to 1 and only /// valid for multiple block transfers. diff --git a/firmware/zynq7000/src/slcr/clocks.rs b/firmware/zynq7000/src/slcr/clocks.rs index 1a6017b..363bf68 100644 --- a/firmware/zynq7000/src/slcr/clocks.rs +++ b/firmware/zynq7000/src/slcr/clocks.rs @@ -4,6 +4,7 @@ use super::{CLOCK_CONTROL_OFFSET, SLCR_BASE_ADDR}; use arbitrary_int::{u4, u6, u7, u10}; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Bypass { NotBypassed = 0b00, /// This is the default reset value. @@ -12,7 +13,13 @@ pub enum Bypass { BypassedRegardlessOfPinStrapping = 0b11, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct PllControl { /// Feedback divisor for the PLL. /// @@ -68,7 +75,7 @@ impl PllControl { } } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct PllConfig { #[bits(12..=21, rw)] lock_count: u10, @@ -80,7 +87,7 @@ pub struct PllConfig { loop_resistor: u4, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct PllStatus { #[bit(5, r)] io_pll_stable: bool, @@ -96,7 +103,7 @@ pub struct PllStatus { arm_pll_lock: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"), forbid_overlaps)] pub struct FpgaClockControl { // Reset value 0x1 #[bits(20..=25, rw)] @@ -203,6 +210,7 @@ pub enum CpuClockRatio { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Debug, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SrcSelIo { IoPll = 0b00, IoPllAlt = 0b01, @@ -229,7 +237,13 @@ impl PartialEq for SrcSelIo { } } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct GigEthClockControl { #[bits(20..=25, rw)] divisor_1: u6, @@ -244,13 +258,20 @@ pub struct GigEthClockControl { } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SrcSelGigEthRclk { Mio = 0, Emio = 1, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct GigEthRclkControl { #[bit(4, rw)] srcsel: SrcSelGigEthRclk, @@ -259,8 +280,13 @@ pub struct GigEthRclkControl { clk_enable: bool, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct CanClockControl { #[bits(20..=25, rw)] divisor_1: u6, @@ -274,7 +300,13 @@ pub struct CanClockControl { clk_0_act: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct SingleCommonPeriphIoClockControl { #[bits(8..=13, rw)] divisor: u6, @@ -284,7 +316,13 @@ pub struct SingleCommonPeriphIoClockControl { clk_act: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct DualCommonPeriphIoClockControl { #[bits(8..=13, rw)] divisor: u6, @@ -297,7 +335,8 @@ pub struct DualCommonPeriphIoClockControl { } #[bitbybit::bitenum(u3, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SrcSelTpiu { IoPll = 0b000, IoPllAlt = 0b001, @@ -309,7 +348,13 @@ pub enum SrcSelTpiu { EmioTraceClkAlt2 = 0b111, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct TracePortClockControl { #[bits(8..=13, rw)] divisor: u6, @@ -324,7 +369,13 @@ pub struct TracePortClockControl { /// AMBA peripheral clock control. /// /// These clocks must be enabled if you want to read from the peripheral register space. -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct AperClockControl { #[bit(24, rw)] smc_1x_clk_act: bool, diff --git a/firmware/zynq7000/src/slcr/ddriob.rs b/firmware/zynq7000/src/slcr/ddriob.rs index 4c6160b..b4bc0e3 100644 --- a/firmware/zynq7000/src/slcr/ddriob.rs +++ b/firmware/zynq7000/src/slcr/ddriob.rs @@ -1,7 +1,8 @@ use arbitrary_int::{u2, u3}; #[bitbybit::bitenum(u4, exhaustive = false)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum VRefSel { /// VREF = 0.6 V Lpddr2 = 0b0001, @@ -13,7 +14,13 @@ pub enum VRefSel { Ddr2 = 0b1000, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct DdrControl { /// Enables VRP/VRN. #[bit(9, rw)] @@ -28,7 +35,13 @@ pub struct DdrControl { vref_int_en: bool, } -#[bitbybit::bitfield(u32, default = 0x00, debug)] +#[bitbybit::bitfield( + u32, + default = 0x00, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct DciControl { #[bit(20, rw)] update_control: bool, @@ -49,7 +62,13 @@ pub struct DciControl { reset: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct DciStatus { #[bit(13, rw)] done: bool, @@ -58,7 +77,8 @@ pub struct DciStatus { } #[bitbybit::bitenum(u2, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum OutputEnable { IBuf = 0b00, __Reserved0 = 0b01, @@ -67,7 +87,8 @@ pub enum OutputEnable { } #[bitbybit::bitenum(u2, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum InputType { Off = 0b00, VRefBasedDifferentialReceiverForSstlHstl = 0b01, @@ -76,7 +97,8 @@ pub enum InputType { } #[bitbybit::bitenum(u2, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DciType { Disabled = 0b00, DciDrive = 0b01, @@ -84,7 +106,13 @@ pub enum DciType { DciTermination = 0b11, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct DdriobConfig { #[bit(11, rw)] pullup_enable: bool, diff --git a/firmware/zynq7000/src/slcr/mio.rs b/firmware/zynq7000/src/slcr/mio.rs index 4116a39..969fc4e 100644 --- a/firmware/zynq7000/src/slcr/mio.rs +++ b/firmware/zynq7000/src/slcr/mio.rs @@ -4,14 +4,16 @@ use arbitrary_int::{u2, u3}; #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Speed { SlowCmosEdge = 0b0, FastCmosEdge = 0b1, } #[bitbybit::bitenum(u3)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum IoType { LvCmos18 = 0b001, LvCmos25 = 0b010, @@ -19,7 +21,7 @@ pub enum IoType { Hstl = 0b100, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_fields(feature = "defmt"))] #[derive(PartialEq, Eq)] pub struct Config { #[bit(13, rw)] diff --git a/firmware/zynq7000/src/slcr/mod.rs b/firmware/zynq7000/src/slcr/mod.rs index 1a89c65..dbec18e 100644 --- a/firmware/zynq7000/src/slcr/mod.rs +++ b/firmware/zynq7000/src/slcr/mod.rs @@ -17,14 +17,14 @@ pub mod mio; pub mod reset; #[bitbybit::bitenum(u3, exhaustive = false)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum VrefSel { Disabled = 0b000, Vref0_9V = 0b001, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0, debug, defmt_fields(feature = "defmt"))] pub struct GpiobControl { #[bit(11, rw)] vref_sw_en: bool, @@ -62,14 +62,14 @@ impl GpiobRegisters { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BootPllConfig { Enabled = 0, /// Disabled and bypassed. Bypassed = 1, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, default = 0, debug, defmt_fields(feature = "defmt"))] pub struct BootModeRegister { #[bit(4, r)] pll_config: BootPllConfig, @@ -79,13 +79,20 @@ pub struct BootModeRegister { #[bitbybit::bitenum(u4)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum LevelShifterConfig { DisableAll = 0x00, EnablePsToPl = 0xA, EnableAll = 0xF, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct LevelShifterRegister { #[bits(0..=3, rw)] user_lvl_shftr_en: Option, diff --git a/firmware/zynq7000/src/slcr/reset.rs b/firmware/zynq7000/src/slcr/reset.rs index 3368e55..ede1101 100644 --- a/firmware/zynq7000/src/slcr/reset.rs +++ b/firmware/zynq7000/src/slcr/reset.rs @@ -2,7 +2,13 @@ use arbitrary_int::u17; use super::{RESET_BLOCK_OFFSET, SLCR_BASE_ADDR}; -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct DualClockReset { /// Peripheral 1 AMBA software reset. #[bit(1, rw)] @@ -12,7 +18,13 @@ pub struct DualClockReset { periph0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct DualRefAndClockResetSpiUart { /// Periperal 1 Reference software reset. #[bit(3, rw)] @@ -28,7 +40,13 @@ pub struct DualRefAndClockResetSpiUart { periph0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct DualRefAndClockResetSdio { /// Periperal 1 Reference software reset. #[bit(5, rw)] @@ -44,13 +62,25 @@ pub struct DualRefAndClockResetSdio { periph0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct GpioClockReset { #[bit(0, rw)] gpio_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct EthernetReset { #[bit(5, rw)] gem1_ref_rst: bool, @@ -66,7 +96,13 @@ pub struct EthernetReset { gem0_cpu1x_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct ResetControlQspiSmc { #[bit(1, rw)] ref_reset: bool, @@ -74,7 +110,13 @@ pub struct ResetControlQspiSmc { cpu_1x_reset: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct FpgaResetControl { /// This block always needs to be written with 0. I think it contains some other hidden /// reset lines. This field makes this explicit. @@ -90,7 +132,13 @@ pub struct FpgaResetControl { fpga_0: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct CpuResetControl { #[bit(8, rw)] peripheral_reset: bool, @@ -104,19 +152,37 @@ pub struct CpuResetControl { cpu0_reset: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct PsResetControl { #[bit(0, rw)] soft_reset: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] -pub struct ResetControlOcmDdr { +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] +pub struct ResetControlSingleBit { #[bit(0, rw)] reset: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct ResetControlInterconnect { /// Care must be taken to ensure that the AXI /// interconnect does not have outstanding @@ -127,13 +193,20 @@ pub struct ResetControlInterconnect { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ApuWatchdogTarget { /// Same system level as PS_SRST_B. PsSrstB = 1, CpuAssociatedWithWdt = 0, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct WatchTimerResetControl { #[bit(1, rw)] apu_wdt_1_reset_target: ApuWatchdogTarget, @@ -149,11 +222,11 @@ pub struct WatchTimerResetControl { pub struct ResetControl { /// Processing System Software reset control pss: PsResetControl, - ddr: ResetControlOcmDdr, + ddr: ResetControlSingleBit, /// Central interconnect reset control topsw: ResetControlInterconnect, - dmac: u32, - usb: u32, + dmac: ResetControlSingleBit, + usb: DualClockReset, eth: EthernetReset, sdio: DualRefAndClockResetSdio, spi: DualRefAndClockResetSpiUart, @@ -163,7 +236,7 @@ pub struct ResetControl { gpio: GpioClockReset, lqspi: ResetControlQspiSmc, smc: ResetControlQspiSmc, - ocm: ResetControlOcmDdr, + ocm: ResetControlSingleBit, _gap0: u32, fpga: FpgaResetControl, a9_cpu: CpuResetControl, diff --git a/firmware/zynq7000/src/spi.rs b/firmware/zynq7000/src/spi.rs index 25d5b6e..6ed250a 100644 --- a/firmware/zynq7000/src/spi.rs +++ b/firmware/zynq7000/src/spi.rs @@ -9,6 +9,7 @@ pub const SPI_1_BASE_ADDR: usize = 0xE000_7000; /// The SPI reference block will be divided by a divisor value. #[bitbybit::bitenum(u3)] #[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum BaudDivSel { By4 = 0b001, By8 = 0b010, @@ -33,8 +34,13 @@ impl BaudDivSel { } } -// TODO: Use bitbybit debug support as soon as it was added. -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct Config { #[bit(17, rw)] modefail_gen_en: bool, @@ -67,7 +73,13 @@ pub struct Config { master_ern: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct InterruptStatus { #[bit(6, rw)] tx_underflow: bool, @@ -86,7 +98,12 @@ pub struct InterruptStatus { rx_ovr: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] +#[bitbybit::bitfield( + u32, + default = 0x0, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] #[derive(Debug)] pub struct InterruptControl { #[bit(6, w)] @@ -106,7 +123,7 @@ pub struct InterruptControl { rx_ovr: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct InterruptMask { #[bit(6, r)] tx_underflow: bool, @@ -126,6 +143,7 @@ pub struct InterruptMask { } #[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FifoWrite(arbitrary_int::UInt); impl FifoWrite { @@ -146,6 +164,7 @@ impl FifoWrite { } #[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FifoRead(arbitrary_int::UInt); impl FifoRead { @@ -161,7 +180,13 @@ impl FifoRead { } /// The numbers specified in the register fields are always specified in number of -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_bitfields(feature = "defmt") +)] pub struct DelayControl { /// Number of cycles the chip select is de-asserted between words when CPHA = 0 #[bits(24..=31, rw)] diff --git a/firmware/zynq7000/src/ttc.rs b/firmware/zynq7000/src/ttc.rs index 8529c7b..7eef2e8 100644 --- a/firmware/zynq7000/src/ttc.rs +++ b/firmware/zynq7000/src/ttc.rs @@ -4,8 +4,9 @@ use arbitrary_int::u4; pub const TTC_0_BASE_ADDR: usize = 0xF800_1000; pub const TTC_1_BASE_ADDR: usize = 0xF800_2000; -#[derive(Debug, Default)] #[bitbybit::bitenum(u1, exhaustive = true)] +#[derive(Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ClockSource { /// PS internal bus clock. #[default] @@ -13,7 +14,13 @@ pub enum ClockSource { External = 0b1, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct ClockControl { /// When this bit is set and the external clock is selected, the counter clocks on the /// negative edge of the external clock input. @@ -28,14 +35,16 @@ pub struct ClockControl { } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Mode { Overflow = 0b0, Interval = 0b1, } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug, Default)] +#[derive(Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum WavePolarity { /// The waveform output goes from high to low on a match 0 interrupt and returns high on /// overflow or interval interrupt. @@ -47,13 +56,20 @@ pub enum WavePolarity { } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum WaveEnable { Enable = 0b0, Disable = 0b1, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct CounterControl { #[bit(6, rw)] wave_polarity: WavePolarity, @@ -76,19 +92,25 @@ pub struct CounterControl { disable: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"), forbid_overlaps)] pub struct Counter { #[bits(0..=15, r)] count: u16, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_fields(feature = "defmt"), + forbid_overlaps +)] pub struct RwValue { #[bits(0..=15, rw)] value: u16, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct InterruptStatus { /// Even timer overflow interrupt. #[bit(5, r)] @@ -105,7 +127,13 @@ pub struct InterruptStatus { interval: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct InterruptControl { /// Even timer overflow interrupt. #[bit(5, rw)] @@ -122,7 +150,13 @@ pub struct InterruptControl { interval: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct EventControl { /// E_Ov bit. When set to 0, the event timer is disabled and set to 0 when an event timer /// register overflow occurs. Otherwise, continue counting on overflow. @@ -136,7 +170,7 @@ pub struct EventControl { enable: bool, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"), forbid_overlaps)] pub struct EventCount { #[bits(0..=15, r)] count: u16, diff --git a/firmware/zynq7000/src/uart.rs b/firmware/zynq7000/src/uart.rs index 9095977..97d1c24 100644 --- a/firmware/zynq7000/src/uart.rs +++ b/firmware/zynq7000/src/uart.rs @@ -5,7 +5,8 @@ pub const UART_0_BASE: usize = 0xE000_0000; pub const UART_1_BASE: usize = 0xE000_1000; #[bitbybit::bitenum(u3, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Parity { Even = 0b000, Odd = 0b001, @@ -21,6 +22,7 @@ pub enum Parity { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Default, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum CharLen { SixBits = 0b11, SevenBits = 0b10, @@ -31,6 +33,7 @@ pub enum CharLen { #[bitbybit::bitenum(u1, exhaustive = true)] #[derive(Default, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ClockSelect { #[default] UartRefClk = 0b0, @@ -39,6 +42,7 @@ pub enum ClockSelect { #[bitbybit::bitenum(u2)] #[derive(Default, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Stopbits { #[default] One = 0b00, @@ -48,6 +52,7 @@ pub enum Stopbits { #[bitbybit::bitenum(u2, exhaustive = true)] #[derive(Debug, Default)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ChMode { #[default] Normal = 0b00, @@ -56,7 +61,13 @@ pub enum ChMode { RemoteLoopback = 0b11, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_bitfields(feature = "defmt") +)] pub struct Control { /// Stop transmitter break. #[bit(8, rw)] @@ -87,7 +98,13 @@ pub struct Control { rx_rst: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_fields(feature = "defmt") +)] pub struct Mode { #[bits(8..=9, rw)] chmode: ChMode, @@ -102,32 +119,45 @@ pub struct Mode { clksel: ClockSelect, } -#[bitbybit::bitfield(u32, default = 0, debug)] +#[bitbybit::bitfield( + u32, + default = 0, + debug, + forbid_overlaps, + defmt_fields(feature = "defmt") +)] pub struct Baudgen { #[bits(0..=15, rw)] cd: u16, } -#[bitbybit::bitfield(u32, default = 0, debug)] +#[bitbybit::bitfield( + u32, + default = 0, + debug, + forbid_overlaps, + defmt_fields(feature = "defmt") +)] pub struct BaudRateDivisor { #[bits(0..=7, rw)] bdiv: u8, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_fields(feature = "defmt"))] pub struct Fifo { #[bits(0..=7, rw)] fifo: u8, } #[bitbybit::bitenum(u1, exhaustive = true)] -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Ttrig { LessThanTTrig = 0b0, GreaterEqualTTrig = 0b1, } -#[bitbybit::bitfield(u32, debug)] +#[bitbybit::bitfield(u32, debug, forbid_overlaps, defmt_bitfields(feature = "defmt"))] pub struct Status { #[bit(14, r)] tx_near_full: bool, @@ -154,8 +184,13 @@ pub struct Status { rx_trg: bool, } -#[bitbybit::bitfield(u32, default = 0x0)] -#[derive(Debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + forbid_overlaps, + defmt_bitfields(feature = "defmt") +)] pub struct InterruptControl { #[bit(12, w)] tx_over: bool, @@ -188,13 +223,14 @@ pub struct InterruptControl { #[bitbybit::bitfield(u32)] #[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct FifoTrigger { #[bits(0..=5, rw)] trig: u6, } -#[bitbybit::bitfield(u32)] -#[derive(Debug)] +#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))] +#[derive(PartialEq, Eq)] pub struct InterruptMask { #[bit(12, r)] tx_over: bool, @@ -226,7 +262,13 @@ pub struct InterruptMask { rx_trg: bool, } -#[bitbybit::bitfield(u32, default = 0x0, debug)] +#[bitbybit::bitfield( + u32, + default = 0x0, + debug, + defmt_bitfields(feature = "defmt"), + forbid_overlaps +)] pub struct InterruptStatus { #[bit(12, rw)] tx_over: bool, diff --git a/justfile b/justfile index 3528436..09b78b7 100644 --- a/justfile +++ b/justfile @@ -13,8 +13,10 @@ check-dir target: build-dir target: cd {{target}} && cargo build +[working-directory: 'firmware'] build-zynq: (build-dir "firmware") - cd "firmware/zedboard-fsbl" && cargo build --release + cd "zynq7000" && cargo build --all-features + cd "zedboard-fsbl" && cargo build --release clean-dir target: cd {{target}} && cargo clean