{"record":{"id":"30b406627f9889f3","repo":"embassy-rs/embassy","slug":"erevidiszero","errorCode":null,"errorMessage":"ErevidIsZero","messagePattern":"ErevidIsZero","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"embassy-net-enc28j60/src/lib.rs","lineNumber":102,"sourceCode":"            embassy_time::block_for(Duration::from_millis(5));\n            rst.set_high().unwrap();\n            embassy_time::block_for(Duration::from_millis(5));\n        } else {\n            embassy_time::block_for(Duration::from_millis(5));\n            self.soft_reset();\n            embassy_time::block_for(Duration::from_millis(5));\n        }\n\n        debug!(\n            \"enc28j60: erevid {=u8:x}\",\n            self.read_control_register(bank3::Register::EREVID)\n        );\n        debug!(\"enc28j60: waiting for clk\");\n        while common::ESTAT(self.read_control_register(common::Register::ESTAT)).clkrdy() == 0 {}\n        debug!(\"enc28j60: clk ok\");\n\n        if self.read_control_register(bank3::Register::EREVID) == 0 {\n            panic!(\"ErevidIsZero\");\n        }\n\n        // disable CLKOUT output\n        self.write_control_register(bank3::Register::ECOCON, 0);\n\n        self.init_rx();\n\n        // TX start\n        // \"It is recommended that an even address be used for ETXST\"\n        debug_assert_eq!(TXST % 2, 0);\n        self.write_control_register(bank0::Register::ETXSTL, TXST.low());\n        self.write_control_register(bank0::Register::ETXSTH, TXST.high());\n\n        // TX end is set in `transmit`\n\n        // MAC initialization (see section 6.5)\n        // 1. Set the MARXEN bit in MACON1 to enable the MAC to receive frames.\n        self.write_control_register(","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-net-enc28j60/src/lib.rs#L84-L120","documentation":"During enc28j60::Device::init, after the clock-ready (CLKRDY) wait, the driver reads the EREVID register (silicon revision ID, bank 3) and panics if it reads 0. EREVID == 0 means the SPI read did not return a valid revision ID, which indicates the chip is not responding correctly (wiring/SPI issues, a fake/counterfeit module, or unsupported silicon). The library treats this as an unrecoverable hardware sanity check.","triggerScenarios":"Calling enc28j60::Device::init when EREVID reads back 0: missing/incorrect SPI mode (must be mode 0), wrong CS pin or miswired MISO/MOSI, insufficient power, counterfeit ENC28J60 modules returning 0, or reading bank-3 register EREVID before the SPI interface is functional.","commonSituations":"Breadboard wiring with long/unstable SPI traces; power supply below 3.14 V; cheap clone modules where EREVID legitimately reads 0; forgetting to set the correct bank before reading EREVID in a modified driver; using a partially broken SPI bus where other reads appear to work.","solutions":["Verify SPI wiring (CS, SCK, MISO, MOSI), SPI mode 0, and a stable 3.3 V supply; scope/check MISO during the EREVID read.","Test basic SPI communication first (e.g. read ECON1 and write/read back) before init to isolate bus problems.","If using a cheap module, check for counterfeit ENC28J60 silicon — many clones report EREVID 0; consider a fallback that logs and continues.","Patch the driver to warn instead of panic (replace panic!(\"ErevidIsZero\") with a logged warning) if your hardware tolerates revision 0."],"exampleFix":"// before (driver)\nif self.read_control_register(bank3::Register::EREVID) == 0 {\n    panic!(\"ErevidIsZero\");\n}\n// after (driver)\nlet erevid = self.read_control_register(bank3::Register::EREVID);\nif erevid == 0 {\n    defmt::warn!(\"enc28j60: EREVID is 0 (counterfeit or SPI issue?), continuing\");\n}\n// caller-side guard: verify SPI echo before init\n// let econ1 = dev.read_control_register(common::Register::ECON1);\n// assert!(econ1 == expected, \"SPI bus not responding correctly\");","handlingStrategy":"validation","validationCode":"// Rust: verify SPI bus responds before calling init\nfn spi_bus_alive<D>(dev: &mut D) -> bool\nwhere D: read_control_register(...)\n{\n    // write a known pattern to ECON1 and read it back\n    let probe = dev.read_control_register(common::Register::ECON1);\n    probe != 0xFF && probe != 0x00 // all-0xFF/all-0x00 usually means no chip / floating bus\n}","typeGuard":"// Rust: guard the EREVID read yourself before driver init\nfn erevid_valid(dev: &mut Device<Spi>) -> bool {\n    dev.read_control_register(bank3::Register::EREVID) != 0\n}","tryCatchPattern":"// Rust panics cannot be caught in embedded; gate init instead:\nif !spi_bus_alive(&mut dev) {\n    defmt::error!(\"enc28j60: SPI bus not responding; check wiring/power\");\n    return Err(InitError::Bus);\n}\ndev.init(mac_addr); // safe once bus sanity-checked","preventionTips":["Verify SPI mode 0, CS wiring, and 3.3 V supply before first init.","Do a write/read-back register probe at boot to detect bus problems early.","Be aware counterfeit ENC28J60 modules legitimately report EREVID 0 — buy from reputable sources or tolerate revision 0.","Keep SPI traces short and add proper decoupling on breadboard setups."],"tags":["embedded","rust","ethernet","spi","hardware","panic"],"backgroundTag":"module-init-failed","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}