Skip to main content

pamoja_radios/sx1302/
driver.rs

1//! Driving a concentrator over a real bus.
2//!
3//! The modules beside this one are data: the transfers the chip answers, the registers it
4//! keeps, the order its microcontrollers are loaded in. This walks that data against an SPI
5//! device and a reset line, which is all a concentrator needs to be brought up.
6//!
7//! Bringing one up is four things, in order. The board is reset, which the host does rather
8//! than the chip. The version register is read, which says whether anything is answering at
9//! all. The front ends are reset through the concentrator itself. Then each microcontroller
10//! is given its firmware, without which the chip reports a healthy version and hears nothing.
11//!
12//! The timings come from the reference implementation rather than from taste, and each one
13//! says where it came from.
14
15use embedded_hal::delay::DelayNs;
16use embedded_hal::digital::{self, OutputPin};
17use embedded_hal::spi::{Operation, SpiDevice};
18
19use super::channel;
20use super::chip::{self, Model};
21use super::firmware::{self, LoadError, Mcu};
22use super::lbt;
23use super::mcu;
24use super::register::{self, Register};
25use super::spi as frame;
26use super::sx1250;
27use super::timestamp;
28use super::tx::{self, Chain, FrontEnd, Trigger, TxStatus};
29
30/// How long the reset line is held, in microseconds.
31///
32/// The reference platform script waits a tenth of a second between every edge it drives, and
33/// this is that wait.
34pub const RESET_HOLD_US: u32 = 100_000;
35
36/// How long a front end is held in reset, in microseconds, as the reference holds it.
37pub const RADIO_RESET_HOLD_US: u32 = 500_000;
38
39/// How long a front end is given to come out of reset, in microseconds.
40pub const RADIO_RESET_SETTLE_US: u32 = 10_000;
41
42/// How long to wait between asking a microcontroller what it is doing, in microseconds.
43pub const MCU_POLL_US: u32 = 1_000;
44
45/// How many times to ask before giving up on it.
46///
47/// The reference waits forever. A gateway that hangs on a board which never came up is worse
48/// than one that says so, which is why this ends.
49pub const MCU_ATTEMPTS: u32 = 1_000;
50
51/// How long an SX1250 is given to finish calibrating itself, in microseconds.
52pub const RADIO_CALIBRATE_US: u32 = 10_000;
53
54/// How many one-millisecond polls an aborted chain is given to come free: the second
55/// Semtech's `sx1302_tx_abort` waits.
56pub const ABORT_POLLS: u32 = 1_000;
57
58const fn lbt_chain_bit(chain: Chain) -> u8 {
59    match chain {
60        Chain::A => 0,
61        Chain::B => 1,
62    }
63}
64
65/// Why the concentrator could not be driven.
66#[derive(Debug)]
67pub enum ConcentratorError<E> {
68    /// The SPI device failed.
69    Spi(E),
70    /// The reset line could not be driven.
71    Pin(digital::ErrorKind),
72    /// The version register answered with something else, so nothing is on the bus, or the
73    /// board is unpowered, or it is wired to the wrong device.
74    NotAnswering {
75        /// What the version register read.
76        version: u8,
77    },
78    /// The part number is one this crate does not drive.
79    UnknownModel {
80        /// What the one-time programmable memory answered with.
81        byte: u8,
82    },
83    /// The firmware did not load.
84    Firmware(LoadError),
85    /// The receive buffer holds more than the caller left room for.
86    Overrun {
87        /// How many bytes are waiting.
88        waiting: u16,
89    },
90    /// A front end did not settle into the mode it was put in.
91    FrontEndMode {
92        /// The mode it was asked for.
93        wanted: u8,
94        /// The mode its status reported.
95        read: u8,
96    },
97    /// A front end refused its own image calibration.
98    ImageCalibration,
99    /// A carrier outside every band a front end calibrates over.
100    UnsupportedBand {
101        /// The carrier asked for, in hertz.
102        hertz: u32,
103    },
104    /// A channel too far from the carrier for the radio to hear, however the register that
105    /// carries the offset holds it.
106    ChannelOutOfReach {
107        /// The offset asked for, in hertz.
108        offset_hz: i32,
109    },
110    /// A rate the fixed-rate receiver cannot be set to.
111    ServiceRate {
112        /// The spreading factor asked for.
113        spreading_factor: u8,
114        /// The bandwidth asked for, in hertz.
115        bandwidth_hz: u32,
116    },
117    /// A channel the frequency shift keying receiver cannot be set to.
118    FskChannel {
119        /// The bit rate asked for, in bits per second.
120        bitrate: u32,
121        /// How many sync word bytes were asked for.
122        sync_word_len: u8,
123    },
124    /// A packet the transmit chain cannot be told to send.
125    Transmit(tx::TransmitError),
126    /// A microcontroller never reached the state it was waited for.
127    Stalled {
128        /// The state it was waited for.
129        wanted: u8,
130        /// The state it was last reporting.
131        reading: u8,
132    },
133    /// A microcontroller is running firmware this crate does not drive.
134    WrongFirmware {
135        /// The version expected.
136        wanted: u8,
137        /// The version it reported.
138        running: u8,
139    },
140}
141
142impl<E: core::fmt::Debug> core::error::Error for ConcentratorError<E> {}
143
144impl<E: core::fmt::Debug> core::fmt::Display for ConcentratorError<E> {
145    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146        match self {
147            ConcentratorError::Spi(error) => write!(f, "the SPI device failed: {error:?}"),
148            ConcentratorError::Pin(kind) => write!(f, "the reset line failed: {kind:?}"),
149            ConcentratorError::NotAnswering { version } => write!(
150                f,
151                "the version register read {version:#04x} rather than {:#04x}, so no concentrator is answering",
152                chip::EXPECTED_VERSION
153            ),
154            ConcentratorError::UnknownModel { byte } => {
155                write!(f, "part number {byte:#04x} is not one this crate drives")
156            }
157            ConcentratorError::Firmware(error) => error.fmt(f),
158            ConcentratorError::Overrun { waiting } => write!(
159                f,
160                "the receive buffer holds {waiting} bytes, which is more than there is room for"
161            ),
162            ConcentratorError::FrontEndMode { wanted, read } => write!(
163                f,
164                "the front end reports mode {read} rather than {wanted}, so it never settled"
165            ),
166            ConcentratorError::ImageCalibration => {
167                f.write_str("the front end refused its own image calibration")
168            }
169            ConcentratorError::UnsupportedBand { hertz } => write!(
170                f,
171                "{hertz} Hz is outside every band a front end calibrates over"
172            ),
173            ConcentratorError::ChannelOutOfReach { offset_hz } => write!(
174                f,
175                "a channel {offset_hz} Hz from the carrier is outside the {} Hz a radio hears",
176                channel::RX_BANDWIDTH_HZ
177            ),
178            ConcentratorError::ServiceRate {
179                spreading_factor,
180                bandwidth_hz,
181            } => write!(
182                f,
183                "the service channel cannot run spreading factor {spreading_factor} at {bandwidth_hz} Hz"
184            ),
185            ConcentratorError::FskChannel {
186                bitrate,
187                sync_word_len,
188            } => write!(
189                f,
190                "the FSK channel cannot run {bitrate} bits a second with a {sync_word_len} byte sync word"
191            ),
192            ConcentratorError::Transmit(error) => error.fmt(f),
193            ConcentratorError::Stalled { wanted, reading } => write!(
194                f,
195                "a microcontroller stopped at {reading} rather than reaching {wanted}"
196            ),
197            ConcentratorError::WrongFirmware { wanted, running } => write!(
198                f,
199                "a microcontroller is running firmware {running} rather than {wanted}"
200            ),
201        }
202    }
203}
204
205/// Turns a pin failure into an error, keeping only what the trait promises.
206fn pin<P: digital::Error, E>(error: P) -> ConcentratorError<E> {
207    ConcentratorError::Pin(error.kind())
208}
209
210/// A concentrator on an SPI device, with its reset line.
211pub struct Sx1302<SPI, RESET, D> {
212    spi: SPI,
213    reset: RESET,
214    delay: D,
215}
216
217impl<SPI, RESET, D> Sx1302<SPI, RESET, D> {
218    /// Wraps a concentrator's SPI device and reset line. Nothing is sent until it is used.
219    ///
220    /// # Arguments
221    ///
222    /// * `spi` - the SPI device the concentrator answers on.
223    /// * `reset` - the line its reset pin is on, which the host drives.
224    /// * `delay` - how the driver waits.
225    ///
226    /// # Returns
227    ///
228    /// The concentrator.
229    pub const fn new(spi: SPI, reset: RESET, delay: D) -> Sx1302<SPI, RESET, D> {
230        Sx1302 { spi, reset, delay }
231    }
232
233    /// Gives the SPI device and the lines back.
234    ///
235    /// # Returns
236    ///
237    /// What was handed over, so a caller can drive something else with them.
238    pub fn release(self) -> (SPI, RESET, D) {
239        (self.spi, self.reset, self.delay)
240    }
241}
242
243impl<SPI, RESET, D> Sx1302<SPI, RESET, D>
244where
245    SPI: SpiDevice,
246    RESET: OutputPin,
247    D: DelayNs,
248{
249    /// Pulses the reset line.
250    ///
251    /// The concentrator does not reset itself. On a gateway board the line is a host pin, and
252    /// this drives it the way the reference platform script does.
253    ///
254    /// # Returns
255    ///
256    /// `Ok(())` once the chip has been released and given time to come up.
257    ///
258    /// # Errors
259    ///
260    /// Returns [`ConcentratorError::Pin`] if the line cannot be driven.
261    pub fn reset(&mut self) -> Result<(), ConcentratorError<SPI::Error>> {
262        self.reset.set_high().map_err(pin)?;
263        self.delay.delay_us(RESET_HOLD_US);
264        self.reset.set_low().map_err(pin)?;
265        self.delay.delay_us(RESET_HOLD_US);
266        Ok(())
267    }
268
269    /// Reads the version register.
270    ///
271    /// # Returns
272    ///
273    /// What it answered with, which is [`EXPECTED_VERSION`](chip::EXPECTED_VERSION) on a
274    /// concentrator that is powered and wired the right way round.
275    ///
276    /// # Errors
277    ///
278    /// Returns [`ConcentratorError::Spi`] if the transfer fails.
279    pub fn version(&mut self) -> Result<u8, ConcentratorError<SPI::Error>> {
280        self.read_register(register::COMMON_VERSION)
281    }
282
283    /// Checks that a concentrator is answering at all.
284    ///
285    /// # Returns
286    ///
287    /// `Ok(())` when the version register reads what it should.
288    ///
289    /// # Errors
290    ///
291    /// Returns [`ConcentratorError::NotAnswering`] carrying what it read instead, which
292    /// separates an unpowered board (zero) from a bus nothing is driving (all ones).
293    pub fn check(&mut self) -> Result<(), ConcentratorError<SPI::Error>> {
294        let version = self.version()?;
295        if chip::answers(version) {
296            Ok(())
297        } else {
298            Err(ConcentratorError::NotAnswering { version })
299        }
300    }
301
302    /// Reads the part number out of the one-time programmable memory.
303    ///
304    /// # Returns
305    ///
306    /// Which concentrator this is.
307    ///
308    /// # Errors
309    ///
310    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
311    pub fn identify(&mut self) -> Result<Model, ConcentratorError<SPI::Error>> {
312        let mut answer = 0u8;
313        for step in chip::identify() {
314            match step {
315                chip::Step::Write(register, value) => self.write_register(register, value)?,
316                chip::Step::Read(register) => answer = self.read_register(register)?,
317            }
318        }
319        Ok(Model::of(answer))
320    }
321
322    /// Resets the front end on a chain, through the concentrator.
323    ///
324    /// The concentrator is clocked from the host while it does this, so it is still listening
325    /// on the bus while the radio it drives is held down.
326    ///
327    /// # Arguments
328    ///
329    /// * `chain` - which chain's front end to reset.
330    /// * `front_end` - which front end it is, since the SX1250 calibrates itself afterwards.
331    ///
332    /// # Returns
333    ///
334    /// `Ok(())` once it is out of reset and settled.
335    ///
336    /// # Errors
337    ///
338    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
339    pub fn reset_front_end(
340        &mut self,
341        chain: Chain,
342        front_end: FrontEnd,
343    ) -> Result<(), ConcentratorError<SPI::Error>> {
344        let (enable, held) = match chain {
345            Chain::A => (register::RF_EN_A_RADIO_EN, register::RF_EN_A_RADIO_RST),
346            Chain::B => (register::RF_EN_B_RADIO_EN, register::RF_EN_B_RADIO_RST),
347        };
348
349        self.write_register(register::COMMON_CLK32_RIF_CTRL, 0)?;
350        self.write_register(enable, 1)?;
351
352        self.write_register(held, 1)?;
353        self.delay.delay_us(RADIO_RESET_HOLD_US);
354        self.write_register(held, 0)?;
355        self.delay.delay_us(RADIO_RESET_SETTLE_US);
356
357        // The SX1250 calibrates itself on the way out, and wants holding again while it does.
358        if matches!(front_end, FrontEnd::Sx1250) {
359            self.write_register(held, 1)?;
360            self.delay.delay_us(RADIO_CALIBRATE_US);
361        }
362
363        Ok(())
364    }
365
366    /// Gives a microcontroller its firmware, and checks that it took.
367    ///
368    /// The image is written, read back, and compared before the microcontroller is released,
369    /// and the chip is asked afterwards whether it accepted it. Both checks matter, and they
370    /// fail differently: a read-back mismatch means the bus is not carrying the bytes, while
371    /// a parity failure means they arrived and the image itself is wrong.
372    ///
373    /// # Arguments
374    ///
375    /// * `mcu` - which microcontroller to load.
376    /// * `image` - the firmware, which is [`FIRMWARE_LEN`](firmware::FIRMWARE_LEN) bytes.
377    ///
378    /// # Returns
379    ///
380    /// `Ok(())` once it is loaded and the chip has accepted it.
381    ///
382    /// # Errors
383    ///
384    /// Returns [`ConcentratorError::Firmware`] for an image of the wrong size, a read-back
385    /// that differs, or a parity check the chip refused.
386    pub fn load_firmware(
387        &mut self,
388        mcu: Mcu,
389        image: &[u8],
390    ) -> Result<(), ConcentratorError<SPI::Error>> {
391        firmware::check_size(image).map_err(ConcentratorError::Firmware)?;
392
393        for step in firmware::steps(mcu) {
394            match step {
395                firmware::Load::Write(register, value) => self.write_register(register, value)?,
396                firmware::Load::WriteFirmware(address) => self.write_memory(address, image)?,
397                firmware::Load::ReadBack(address) => self.verify_memory(address, image)?,
398                firmware::Load::CheckParity(register) => {
399                    if self.read_register(register)? != 0 {
400                        return Err(ConcentratorError::Firmware(LoadError::ParityFailed));
401                    }
402                }
403            }
404        }
405
406        Ok(())
407    }
408
409    /// Reads one register.
410    ///
411    /// # Arguments
412    ///
413    /// * `register` - which register.
414    ///
415    /// # Returns
416    ///
417    /// Its value, taken out of the byte it shares with its neighbors.
418    ///
419    /// # Errors
420    ///
421    /// Returns [`ConcentratorError::Spi`] if the transfer fails.
422    pub fn read_register(
423        &mut self,
424        register: Register,
425    ) -> Result<u8, ConcentratorError<SPI::Error>> {
426        let byte = self.read_byte(register.address)?;
427        Ok(register.decode(byte))
428    }
429
430    /// Writes one register, leaving the rest of the byte it shares as it was.
431    ///
432    /// # Arguments
433    ///
434    /// * `register` - which register.
435    /// * `value` - what to put there.
436    ///
437    /// # Returns
438    ///
439    /// `Ok(())` once written.
440    ///
441    /// # Errors
442    ///
443    /// Returns [`ConcentratorError::Spi`] if a transfer fails. A register narrower than a
444    /// byte is read first, so this can cost two transfers.
445    pub fn write_register(
446        &mut self,
447        register: Register,
448        value: u8,
449    ) -> Result<(), ConcentratorError<SPI::Error>> {
450        let byte = if register.is_whole_byte() {
451            value
452        } else {
453            let held = self.read_byte(register.address)?;
454            register.encode(held, value)
455        };
456        self.write_byte(register.address, byte)
457    }
458
459    /// Writes a run of bytes into the chip's memory.
460    ///
461    /// # Arguments
462    ///
463    /// * `address` - where the first byte lands.
464    /// * `data` - the bytes.
465    ///
466    /// # Returns
467    ///
468    /// `Ok(())` once every chunk has gone out.
469    ///
470    /// # Errors
471    ///
472    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
473    pub fn write_memory(
474        &mut self,
475        address: u16,
476        data: &[u8],
477    ) -> Result<(), ConcentratorError<SPI::Error>> {
478        let mut at = address;
479        let mut sent = 0usize;
480        while sent < data.len() {
481            let take = core::cmp::min(data.len() - sent, frame::BURST_CHUNK);
482            let header = frame::burst_write_header(frame::TARGET_CONCENTRATOR, at);
483            self.spi
484                .transaction(&mut [
485                    Operation::Write(&header),
486                    Operation::Write(&data[sent..sent + take]),
487                ])
488                .map_err(ConcentratorError::Spi)?;
489            at = at.wrapping_add(take as u16);
490            sent += take;
491        }
492        Ok(())
493    }
494
495    /// Reads a run of bytes out of the chip's memory.
496    ///
497    /// # Arguments
498    ///
499    /// * `address` - where to start.
500    /// * `into` - where to put them.
501    ///
502    /// # Returns
503    ///
504    /// `Ok(())` once it is filled.
505    ///
506    /// # Errors
507    ///
508    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
509    pub fn read_memory(
510        &mut self,
511        address: u16,
512        into: &mut [u8],
513    ) -> Result<(), ConcentratorError<SPI::Error>> {
514        self.burst_read(address, into, true)
515    }
516
517    /// Reads a port rather than a window, so every chunk comes from the same address.
518    ///
519    /// The receive buffer is a port: reading it moves the chip pointer along by itself. A
520    /// reader that moves the address as well walks past the packets it came for, which only
521    /// shows once there is more waiting than one chunk holds.
522    ///
523    /// # Arguments
524    ///
525    /// * `address` - the port to read.
526    /// * `into` - where the bytes go, filled to its length.
527    ///
528    /// # Returns
529    ///
530    /// `Ok(())` once it is filled.
531    ///
532    /// # Errors
533    ///
534    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
535    pub fn read_fifo(
536        &mut self,
537        address: u16,
538        into: &mut [u8],
539    ) -> Result<(), ConcentratorError<SPI::Error>> {
540        self.burst_read(address, into, false)
541    }
542
543    /// How many bytes the receive buffer is holding.
544    ///
545    /// The count is read twice and the larger kept. A read of the pair can answer with less
546    /// than is really there, and the reference guards against it the same way.
547    ///
548    /// # Returns
549    ///
550    /// The number of bytes waiting, which is zero when nothing has been heard.
551    ///
552    /// # Errors
553    ///
554    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
555    pub fn waiting(&mut self) -> Result<u16, ConcentratorError<SPI::Error>> {
556        let first = self.buffer_count()?;
557        let second = self.buffer_count()?;
558        Ok(if second > first { second } else { first })
559    }
560
561    /// Takes everything the receive buffer is holding.
562    ///
563    /// What comes back is packets back to back, each wrapped in the metadata the chip writes
564    /// around it, which [`packets`](super::rx::packets) walks.
565    ///
566    /// # Arguments
567    ///
568    /// * `into` - where the bytes go. [`BUFFER_LEN`](super::rx::BUFFER_LEN) always fits.
569    ///
570    /// # Returns
571    ///
572    /// What was read, which is empty when nothing has been heard.
573    ///
574    /// # Errors
575    ///
576    /// Returns [`ConcentratorError::Overrun`] if more is waiting than there is room for,
577    /// having read nothing, so a larger buffer still gets it. Returns
578    /// [`ConcentratorError::Spi`] if a transfer fails.
579    pub fn receive<'a>(
580        &mut self,
581        into: &'a mut [u8],
582    ) -> Result<&'a [u8], ConcentratorError<SPI::Error>> {
583        let waiting = self.waiting()?;
584        let wanted = usize::from(waiting);
585        if wanted == 0 {
586            return Ok(&[]);
587        }
588        if wanted > into.len() {
589            return Err(ConcentratorError::Overrun { waiting });
590        }
591        self.read_fifo(register::RX_BUFFER_BASE, &mut into[..wanted])?;
592        Ok(&into[..wanted])
593    }
594
595    /// Loads a packet and arms the trigger that sends it.
596    ///
597    /// The chip is not handed the packet and the moment together. The payload goes into the
598    /// buffer of the chain, the delay it starts early by is programmed, and only then is the
599    /// trigger armed. [`steps`](super::tx::steps) holds that order and this walks it.
600    ///
601    /// # Arguments
602    ///
603    /// * `chain` - which transmit chain sends it.
604    /// * `transmit` - the packet and everything the modulator has to be told about it. A
605    ///   chain given a payload without this sends it on whatever it was last set to.
606    /// * `trigger` - what the send waits for.
607    /// * `start_delay` - what [`start_delay`](super::tx::start_delay) worked out.
608    ///
609    /// # Returns
610    ///
611    /// `Ok(())` once the trigger is armed. The packet leaves when the trigger says.
612    ///
613    /// # Errors
614    ///
615    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
616    pub fn transmit(
617        &mut self,
618        chain: Chain,
619        transmit: &tx::Transmit<'_>,
620        trigger: Trigger,
621        start_delay: u16,
622    ) -> Result<(), ConcentratorError<SPI::Error>> {
623        // The modulator is configured and started before the payload is loaded, which is
624        // the order the reference uses and the only one that describes the packet.
625        for (register, value) in
626            tx::settings(chain, transmit).map_err(ConcentratorError::Transmit)?
627        {
628            self.write_register(register, value)?;
629        }
630
631        self.send(chain, transmit.payload, trigger, start_delay)
632    }
633
634    /// Loads a payload into a chain that is already configured, and arms its trigger.
635    ///
636    /// [`transmit`](Self::transmit) describes a packet and then calls this. A caller answering
637    /// on settings the chain already holds can call it directly, which is every downlink
638    /// after the first on one channel.
639    ///
640    /// # Arguments
641    ///
642    /// * `chain` - which transmit chain sends it.
643    /// * `payload` - the bytes the chain sends. For frequency shift keying the length byte
644    ///   goes first, as the chip reads it out of the buffer.
645    /// * `trigger` - what the send waits for.
646    /// * `start_delay` - what [`start_delay`](super::tx::start_delay) worked out.
647    ///
648    /// # Returns
649    ///
650    /// `Ok(())` once the trigger is armed. The packet leaves when the trigger says.
651    ///
652    /// # Errors
653    ///
654    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
655    pub fn send(
656        &mut self,
657        chain: Chain,
658        payload: &[u8],
659        trigger: Trigger,
660        start_delay: u16,
661    ) -> Result<(), ConcentratorError<SPI::Error>> {
662        for step in tx::steps(chain, trigger, start_delay) {
663            match step {
664                tx::Send::SetStartDelay(delay) => {
665                    let bytes = tx::start_delay_bytes(delay);
666                    self.write_register(chain.start_delay_msb(), bytes[0])?;
667                    self.write_register(chain.start_delay_lsb(), bytes[1])?;
668                }
669                tx::Send::OpenBuffer(register) => self.write_register(register, 1)?,
670                tx::Send::WritePayload(address) => self.write_memory(address, payload)?,
671                tx::Send::CloseBuffer(register) => self.write_register(register, 0)?,
672                tx::Send::SetTimerTrigger(value) => {
673                    for (index, byte) in tx::trigger_bytes(value).into_iter().enumerate() {
674                        self.write_register(chain.timer_byte(index as u8), byte)?;
675                    }
676                }
677                tx::Send::ResetTrigger(register) => self.write_register(register, 0)?,
678                tx::Send::ArmTrigger(register) => self.write_register(register, 1)?,
679            }
680        }
681        Ok(())
682    }
683
684    /// Waits for a transmission a carrier check guards to start, and reports whether the
685    /// check let it go out.
686    ///
687    /// Semtech's `lgw_lbt_tx_status`: poll the gain control until it reports the chain
688    /// started, read whether the check held it back, clear the status through the first
689    /// mailbox, wait for it to read clear, and acknowledge. The status is cleared even when the
690    /// start never came, so the next transmission is not read against this one.
691    ///
692    /// # Arguments
693    ///
694    /// * `chain` - the chain the packet was armed on.
695    ///
696    /// # Returns
697    ///
698    /// `true` if the packet went out, `false` if the channel was busy.
699    ///
700    /// # Errors
701    ///
702    /// Returns [`ConcentratorError::Stalled`] if the transmission never started or its status
703    /// never cleared, and [`ConcentratorError::Spi`] if a transfer fails.
704    pub fn checked_transmission(
705        &mut self,
706        chain: Chain,
707    ) -> Result<bool, ConcentratorError<SPI::Error>> {
708        let mut status = 0;
709        let mut started = false;
710        for _ in 0..lbt::OUTCOME_POLLS {
711            status = self.read_register(register::AGC_MCU_STATUS)?;
712            if lbt::started(status, chain) {
713                started = true;
714                break;
715            }
716            self.delay.delay_us(MCU_POLL_US);
717        }
718        let allowed = started && !lbt::refused(status, chain);
719
720        self.write_register(register::agc_mailbox_write(0), lbt::CLEAR_TRANSMIT_STATUS)?;
721        let mut reading = status;
722        let mut cleared = false;
723        for _ in 0..lbt::OUTCOME_POLLS {
724            reading = self.read_register(register::AGC_MCU_STATUS)?;
725            if reading == 0 {
726                cleared = true;
727                break;
728            }
729            self.delay.delay_us(MCU_POLL_US);
730        }
731        self.write_register(register::agc_mailbox_write(0), lbt::ACKNOWLEDGE_CLEARED)?;
732
733        if !started {
734            return Err(ConcentratorError::Stalled {
735                wanted: 1 << lbt_chain_bit(chain),
736                reading: status,
737            });
738        }
739        if !cleared {
740            return Err(ConcentratorError::Stalled { wanted: 0, reading });
741        }
742        Ok(allowed)
743    }
744
745    /// Takes back a packet armed on a chain and waits for the chain to come free.
746    ///
747    /// Semtech's `sx1302_tx_abort`: every trigger reset, then the status polled for up to a
748    /// second.
749    ///
750    /// # Arguments
751    ///
752    /// * `chain` - the chain to free.
753    ///
754    /// # Errors
755    ///
756    /// Returns [`ConcentratorError::Stalled`] if the chain does not come free, and
757    /// [`ConcentratorError::Spi`] if a transfer fails.
758    pub fn abort(&mut self, chain: Chain) -> Result<(), ConcentratorError<SPI::Error>> {
759        for trigger in [Trigger::Immediate, Trigger::At(0), Trigger::OnGps] {
760            self.write_register(chain.trigger(trigger), 0)?;
761        }
762        let mut reading = 0;
763        for _ in 0..ABORT_POLLS {
764            reading = self.read_register(chain.status())?;
765            if TxStatus::of(reading).is_free() {
766                return Ok(());
767            }
768            self.delay.delay_us(MCU_POLL_US);
769        }
770        Err(ConcentratorError::Stalled {
771            wanted: tx::STATUS_FREE,
772            reading,
773        })
774    }
775
776    /// What a transmit chain is doing.
777    ///
778    /// # Arguments
779    ///
780    /// * `chain` - the chain to ask.
781    ///
782    /// # Returns
783    ///
784    /// Its state, which is [`TxStatus::Free`] when it will take another packet.
785    ///
786    /// # Errors
787    ///
788    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
789    pub fn tx_status(&mut self, chain: Chain) -> Result<TxStatus, ConcentratorError<SPI::Error>> {
790        let value = self.read_register(chain.status())?;
791        Ok(TxStatus::of(value))
792    }
793
794    /// Points a concentrator at the channels it is to listen on.
795    ///
796    /// A concentrator that has been reset and given firmware still hears nothing until this
797    /// has run. Its receivers have been given no frequencies, no radio to take samples from,
798    /// no spreading factors to look for, and no permission to run at all.
799    /// [`steps`](super::channel::steps) holds that order and this walks it.
800    ///
801    /// # Arguments
802    ///
803    /// * `plan` - what to listen for.
804    ///
805    /// # Returns
806    ///
807    /// `Ok(())` once the receivers are running.
808    ///
809    /// # Errors
810    ///
811    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
812    pub fn configure_channels(
813        &mut self,
814        plan: &channel::Plan,
815    ) -> Result<(), ConcentratorError<SPI::Error>> {
816        // The offset register reaches far past what the radio hears, so a channel outside
817        // the window is refused here rather than configured into silence.
818        for listener in &plan.channels {
819            if listener.enabled && !channel::reachable(listener.offset_hz) {
820                return Err(ConcentratorError::ChannelOutOfReach {
821                    offset_hz: listener.offset_hz,
822                });
823            }
824        }
825
826        // The fixed-rate receiver takes a spreading factor and a bandwidth of its own, and
827        // silently keeps its last ones for a pair it cannot be set to.
828        if let Some(service) = plan.service {
829            if !channel::reachable(service.offset_hz) {
830                return Err(ConcentratorError::ChannelOutOfReach {
831                    offset_hz: service.offset_hz,
832                });
833            }
834            if !service.supported() {
835                return Err(ConcentratorError::ServiceRate {
836                    spreading_factor: service.spreading_factor,
837                    bandwidth_hz: service.bandwidth_hz,
838                });
839            }
840        }
841
842        // The same for the receiver that hears frequency shift keying: a rate it cannot be
843        // set to would leave it running at whatever it was last given.
844        if let Some(fsk) = plan.fsk {
845            if !channel::reachable(fsk.offset_hz) {
846                return Err(ConcentratorError::ChannelOutOfReach {
847                    offset_hz: fsk.offset_hz,
848                });
849            }
850            if !fsk.supported() {
851                return Err(ConcentratorError::FskChannel {
852                    bitrate: fsk.bitrate,
853                    sync_word_len: fsk.sync_word_len,
854                });
855            }
856        }
857
858        for channel::Step::Write(register, value) in channel::steps(plan) {
859            self.write_register(register, value)?;
860        }
861        Ok(())
862    }
863
864    /// Takes the concentrator clock from the front end on a chain.
865    ///
866    /// Until this runs the chip is clocked by the bus, which is enough to answer registers
867    /// and nothing else. The front end it takes the clock from has to be in receive, which
868    /// is where [`setup_front_end`](Self::setup_front_end) leaves it.
869    ///
870    /// # Arguments
871    ///
872    /// * `chain` - the chain whose front end carries the clock.
873    ///
874    /// # Returns
875    ///
876    /// `Ok(())` once the chip is running on the radio clock.
877    ///
878    /// # Errors
879    ///
880    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
881    pub fn select_clock(&mut self, chain: Chain) -> Result<(), ConcentratorError<SPI::Error>> {
882        let (a, b) = match chain {
883            Chain::A => (1, 0),
884            Chain::B => (0, 1),
885        };
886        self.write_register(register::CLOCK_RADIO_A_SELECT, a)?;
887        self.write_register(register::CLOCK_RADIO_B_SELECT, b)?;
888        self.write_register(register::CLOCK_DIVIDER_ENABLE, 1)?;
889        self.write_register(register::COMMON_CLK32_RIF_CTRL, 1)
890    }
891
892    /// Hands the front ends back to the gain control.
893    ///
894    /// The host drives them while they are being reset and tuned. From here on the gain
895    /// control owns them, which is what lets it move gains while packets are arriving.
896    ///
897    /// # Returns
898    ///
899    /// `Ok(())` once the host has let go.
900    ///
901    /// # Errors
902    ///
903    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
904    pub fn release_front_ends(&mut self) -> Result<(), ConcentratorError<SPI::Error>> {
905        self.write_register(register::COMMON_HOST_RADIO_CTRL, 0)
906    }
907
908    /// Configures the gain control microcontroller and lets it run.
909    ///
910    /// Loading its firmware is only half of bringing it up: it comes out of reset waiting to
911    /// be told what gains to use, one group of settings at a time, and a concentrator whose
912    /// gain control was never configured hears very little.
913    /// [`start_gain_control`](super::mcu::start_gain_control) holds that exchange and this
914    /// walks it against the mailboxes.
915    ///
916    /// # Arguments
917    ///
918    /// * `front_end` - which front end the board carries, which decides the gains and the
919    ///   firmware version expected.
920    /// * `listen_before_talk` - whether the SX1261 beside the concentrator checks a channel
921    ///   before the gateway talks on it.
922    ///
923    /// # Returns
924    ///
925    /// `Ok(())` once the microcontroller has taken every group and been told there is no
926    /// more to come.
927    ///
928    /// # Errors
929    ///
930    /// Returns [`ConcentratorError::WrongFirmware`] if it is running an image this crate does
931    /// not drive, [`ConcentratorError::Stalled`] if it stops acknowledging, and
932    /// [`ConcentratorError::Spi`] if a transfer fails.
933    pub fn start_gain_control(
934        &mut self,
935        front_end: FrontEnd,
936        listen_before_talk: bool,
937    ) -> Result<(), ConcentratorError<SPI::Error>> {
938        for step in mcu::start_gain_control(front_end, listen_before_talk) {
939            self.take(step, register::AGC_MCU_STATUS, true)?;
940        }
941        Ok(())
942    }
943
944    /// Configures the arbiter microcontroller and lets it run.
945    ///
946    /// The arbiter shares the receivers between the channels. It comes up halted and stays
947    /// halted until it is told to resume.
948    ///
949    /// # Arguments
950    ///
951    /// * `dual_demodulation` - which spreading factors are demodulated twice over, one bit
952    ///   each counting from SF5. Demodulating twice buys a finer timestamp and costs
953    ///   capacity, so a gateway that does not need one passes zero.
954    ///
955    /// # Returns
956    ///
957    /// `Ok(())` once the arbiter reports it is running again.
958    ///
959    /// # Errors
960    ///
961    /// Returns [`ConcentratorError::WrongFirmware`] if it is running an image this crate does
962    /// not drive, [`ConcentratorError::Stalled`] if it never resumes, and
963    /// [`ConcentratorError::Spi`] if a transfer fails.
964    pub fn start_arbiter(
965        &mut self,
966        dual_demodulation: u8,
967    ) -> Result<(), ConcentratorError<SPI::Error>> {
968        for step in mcu::start_arbiter(dual_demodulation) {
969            self.take(step, register::ARB_MCU_STATUS, false)?;
970        }
971        Ok(())
972    }
973
974    /// Walks one step of a microcontroller exchange.
975    ///
976    /// The gain control answers through mailboxes and the arbiter through its own registers,
977    /// which is the only difference between the two exchanges.
978    fn take(
979        &mut self,
980        step: mcu::Step,
981        status: Register,
982        mailboxes: bool,
983    ) -> Result<(), ConcentratorError<SPI::Error>> {
984        match step {
985            mcu::Step::Await(wanted) => self.settle(status, wanted),
986            mcu::Step::Version(wanted) => {
987                let running = if mailboxes {
988                    self.read_register(register::agc_mailbox_read(0))?
989                } else {
990                    self.read_register(register::arbiter_status(0))?
991                };
992                if running == wanted {
993                    Ok(())
994                } else {
995                    Err(ConcentratorError::WrongFirmware { wanted, running })
996                }
997            }
998            mcu::Step::Write(index, value) => {
999                let held = if mailboxes {
1000                    register::agc_mailbox_write(index)
1001                } else {
1002                    register::arbiter_config(index)
1003                };
1004                self.write_register(held, value)
1005            }
1006            // Only the gain control announces a group and is read back; the arbiter takes
1007            // its settings directly and reports through its own registers.
1008            mcu::Step::Notify(code) => self.write_register(register::agc_mailbox_write(3), code),
1009            mcu::Step::Verify(mailbox, wanted) => {
1010                let read = self.read_register(register::agc_mailbox_read(mailbox))?;
1011                if read == wanted {
1012                    Ok(())
1013                } else {
1014                    Err(ConcentratorError::Stalled {
1015                        wanted,
1016                        reading: read,
1017                    })
1018                }
1019            }
1020        }
1021    }
1022
1023    /// Waits for a microcontroller to reach a state, and gives up rather than hanging.
1024    ///
1025    /// The reference spins here with no way out. A board that is unpowered, half loaded or
1026    /// wired to the wrong device would stop a gateway dead, so this bounds the wait and
1027    /// reports the state it was stuck on.
1028    fn settle(
1029        &mut self,
1030        status: Register,
1031        wanted: u8,
1032    ) -> Result<(), ConcentratorError<SPI::Error>> {
1033        let mut reading = 0;
1034        for _ in 0..MCU_ATTEMPTS {
1035            reading = self.read_register(status)?;
1036            if reading == wanted {
1037                return Ok(());
1038            }
1039            self.delay.delay_us(MCU_POLL_US);
1040        }
1041        Err(ConcentratorError::Stalled { wanted, reading })
1042    }
1043
1044    /// Reads the counter packets are stamped against.
1045    ///
1046    /// Both counters come back in one burst, and the burst is read twice, because a read can
1047    /// catch a counter mid-step. When the two agree the first is kept; when a high byte has
1048    /// moved between them a third read settles it. That is what the reference does, and it
1049    /// is a different guard from the one on the receive byte count, where the larger of two
1050    /// readings is kept instead.
1051    ///
1052    /// # Arguments
1053    ///
1054    /// * `counter` - the state carried between readings, which is what widens a counter of
1055    ///   27 bits past its rollover.
1056    ///
1057    /// # Returns
1058    ///
1059    /// The free running counter and then the pulse one, in microseconds.
1060    ///
1061    /// # Errors
1062    ///
1063    /// Returns [`ConcentratorError::Spi`] if a transfer fails.
1064    pub fn counter(
1065        &mut self,
1066        counter: &mut timestamp::Counter,
1067    ) -> Result<(u32, u32), ConcentratorError<SPI::Error>> {
1068        let mut bytes = [0u8; timestamp::COUNTERS_LEN];
1069        self.read_memory(timestamp::COUNTERS, &mut bytes)?;
1070
1071        let mut again = [0u8; timestamp::COUNTERS_LEN];
1072        self.read_memory(timestamp::COUNTERS, &mut again)?;
1073
1074        if timestamp::disagrees(&bytes, &again) {
1075            self.read_memory(timestamp::COUNTERS, &mut bytes)?;
1076        }
1077        Ok(counter.read(&bytes))
1078    }
1079
1080    /// Sends a command to the front end on a chain.
1081    ///
1082    /// A front end answers on the same bus as the concentrator, with the first byte of the
1083    /// frame naming it rather than the concentrator. It gives the host no line to watch, so
1084    /// this waits [`WAIT_BUSY_US`](super::sx1250::WAIT_BUSY_US) first, as the reference does.
1085    ///
1086    /// # Arguments
1087    ///
1088    /// * `chain` - the chain the front end is on.
1089    /// * `opcode` - the command.
1090    /// * `data` - what the command carries.
1091    ///
1092    /// # Returns
1093    ///
1094    /// `Ok(())` once it has been sent.
1095    ///
1096    /// # Errors
1097    ///
1098    /// Returns [`ConcentratorError::Spi`] if the transfer fails.
1099    pub fn radio_command(
1100        &mut self,
1101        chain: Chain,
1102        opcode: u8,
1103        data: &[u8],
1104    ) -> Result<(), ConcentratorError<SPI::Error>> {
1105        self.delay.delay_us(sx1250::WAIT_BUSY_US);
1106        let header = sx1250::header(chain, opcode);
1107        self.spi
1108            .transaction(&mut [Operation::Write(&header), Operation::Write(data)])
1109            .map_err(ConcentratorError::Spi)
1110    }
1111
1112    /// Asks the front end on a chain for an answer.
1113    ///
1114    /// # Arguments
1115    ///
1116    /// * `chain` - the chain the front end is on.
1117    /// * `opcode` - the command.
1118    /// * `into` - where the answer goes, filled to its length.
1119    ///
1120    /// # Returns
1121    ///
1122    /// `Ok(())` once it is filled.
1123    ///
1124    /// # Errors
1125    ///
1126    /// Returns [`ConcentratorError::Spi`] if the transfer fails.
1127    pub fn radio_query(
1128        &mut self,
1129        chain: Chain,
1130        opcode: u8,
1131        into: &mut [u8],
1132    ) -> Result<(), ConcentratorError<SPI::Error>> {
1133        self.delay.delay_us(sx1250::WAIT_BUSY_US);
1134        let header = sx1250::header(chain, opcode);
1135        self.spi
1136            .transaction(&mut [Operation::Write(&header), Operation::Read(into)])
1137            .map_err(ConcentratorError::Spi)
1138    }
1139
1140    /// Brings the front end on a chain up and leaves it listening.
1141    ///
1142    /// A concentrator hears nothing until this has run, because the carrier is set here
1143    /// rather than on the concentrator. It also matters beyond receiving: the concentrator
1144    /// takes its clock from a front end that is in receive, so one left idle stops the chip
1145    /// beside it. [`setup`](super::sx1250::setup) holds the order and this walks it.
1146    ///
1147    /// # Arguments
1148    ///
1149    /// * `chain` - the chain the front end is on.
1150    /// * `hertz` - the carrier to tune to.
1151    /// * `single_input` - whether the board wires the front end single ended rather than
1152    ///   differential.
1153    ///
1154    /// # Returns
1155    ///
1156    /// `Ok(())` once it is tuned and listening.
1157    ///
1158    /// # Errors
1159    ///
1160    /// Returns [`ConcentratorError::FrontEndMode`] if it does not settle into a standby it
1161    /// was put in, which is what an unpowered or unclocked front end looks like, and
1162    /// [`ConcentratorError::Spi`] if a transfer fails.
1163    pub fn setup_front_end(
1164        &mut self,
1165        chain: Chain,
1166        hertz: u32,
1167        single_input: bool,
1168    ) -> Result<(), ConcentratorError<SPI::Error>> {
1169        for step in sx1250::setup(hertz, single_input) {
1170            match step {
1171                sx1250::Step::Standby(standby) => {
1172                    self.radio_command(chain, sx1250::OP_SET_STANDBY, &[standby.value()])?;
1173                }
1174                sx1250::Step::Wait(micros) => self.delay.delay_us(micros),
1175                sx1250::Step::ExpectMode(wanted) => {
1176                    let mut status = [0u8; 1];
1177                    self.radio_query(chain, sx1250::OP_GET_STATUS, &mut status)?;
1178                    let read = sx1250::mode(status[0]);
1179                    if read != wanted {
1180                        return Err(ConcentratorError::FrontEndMode { wanted, read });
1181                    }
1182                }
1183                sx1250::Step::Calibrate(mask) => {
1184                    self.radio_command(chain, sx1250::OP_CALIBRATE, &[mask])?;
1185                }
1186                sx1250::Step::Register(address, value) => {
1187                    let [high, low] = address.to_be_bytes();
1188                    self.radio_command(chain, sx1250::OP_WRITE_REGISTER, &[high, low, value])?;
1189                }
1190                sx1250::Step::ClearOffset(address) => {
1191                    let [high, low] = address.to_be_bytes();
1192                    self.radio_command(chain, sx1250::OP_WRITE_REGISTER, &[high, low, 0, 0, 0])?;
1193                }
1194                sx1250::Step::Tune(carrier) => {
1195                    let bytes = sx1250::frequency_bytes(carrier);
1196                    self.radio_command(chain, sx1250::OP_SET_RF_FREQUENCY, &bytes)?;
1197                }
1198                sx1250::Step::ListenContinuously => {
1199                    self.radio_command(chain, sx1250::OP_SET_RX, &sx1250::RX_CONTINUOUS)?;
1200                }
1201            }
1202        }
1203        Ok(())
1204    }
1205
1206    /// Calibrates the front end on a chain over the band a carrier falls in.
1207    ///
1208    /// The chip calibrates a band rather than a frequency, and it knows five of them. This
1209    /// is the SX1250 half of radio calibration: it runs once the front ends have been reset
1210    /// and while the host still drives them, before the receivers are given their channels.
1211    /// The front ends that came before calibrate through a firmware image instead.
1212    ///
1213    /// # Arguments
1214    ///
1215    /// * `chain` - the chain the front end is on.
1216    /// * `hertz` - the carrier it will be tuned to.
1217    ///
1218    /// # Returns
1219    ///
1220    /// `Ok(())` once the chip reports no fault.
1221    ///
1222    /// # Errors
1223    ///
1224    /// Returns [`ConcentratorError::UnsupportedBand`] for a carrier outside every band,
1225    /// without sending anything, [`ConcentratorError::ImageCalibration`] if the chip reports
1226    /// the calibration failed, and [`ConcentratorError::Spi`] if a transfer fails.
1227    pub fn calibrate_front_end(
1228        &mut self,
1229        chain: Chain,
1230        hertz: u32,
1231    ) -> Result<(), ConcentratorError<SPI::Error>> {
1232        let band = sx1250::image_band(hertz).ok_or(ConcentratorError::UnsupportedBand { hertz })?;
1233        self.radio_command(chain, sx1250::OP_CALIBRATE_IMAGE, &band)?;
1234        self.delay.delay_us(sx1250::IMAGE_CALIBRATE_US);
1235
1236        let mut errors = [0u8; 3];
1237        self.radio_query(chain, sx1250::OP_GET_DEVICE_ERRORS, &mut errors)?;
1238        if sx1250::image_failed(errors[2]) {
1239            return Err(ConcentratorError::ImageCalibration);
1240        }
1241        Ok(())
1242    }
1243
1244    /// Reads the byte count once, high bits first.
1245    fn buffer_count(&mut self) -> Result<u16, ConcentratorError<SPI::Error>> {
1246        let high = self.read_register(register::RX_BUFFER_NB_BYTES_MSB)?;
1247        let low = self.read_register(register::RX_BUFFER_NB_BYTES_LSB)?;
1248        Ok((u16::from(high) << 8) | u16::from(low))
1249    }
1250
1251    /// Reads a run of bytes a chunk at a time, moving the address on only for a window.
1252    fn burst_read(
1253        &mut self,
1254        address: u16,
1255        into: &mut [u8],
1256        advance: bool,
1257    ) -> Result<(), ConcentratorError<SPI::Error>> {
1258        let mut at = address;
1259        let mut read = 0usize;
1260        while read < into.len() {
1261            let take = core::cmp::min(into.len() - read, frame::BURST_CHUNK);
1262            let header = frame::burst_read_header(frame::TARGET_CONCENTRATOR, at);
1263            self.spi
1264                .transaction(&mut [
1265                    Operation::Write(&header),
1266                    Operation::Read(&mut into[read..read + take]),
1267                ])
1268                .map_err(ConcentratorError::Spi)?;
1269            if advance {
1270                at = at.wrapping_add(take as u16);
1271            }
1272            read += take;
1273        }
1274        Ok(())
1275    }
1276
1277    /// Reads memory back a chunk at a time and compares it with what was written.
1278    ///
1279    /// A whole firmware image is eight kilobytes, which is a great deal of stack to ask for
1280    /// on a small host, so this compares as it goes rather than holding a second copy.
1281    fn verify_memory(
1282        &mut self,
1283        address: u16,
1284        written: &[u8],
1285    ) -> Result<(), ConcentratorError<SPI::Error>> {
1286        let mut chunk = [0u8; frame::BURST_CHUNK];
1287        let mut at = address;
1288        let mut done = 0usize;
1289
1290        while done < written.len() {
1291            let take = core::cmp::min(written.len() - done, frame::BURST_CHUNK);
1292            self.read_memory(at, &mut chunk[..take])?;
1293
1294            if let Err(LoadError::ReadBackDiffers { at: differs }) =
1295                firmware::compare(&written[done..done + take], &chunk[..take])
1296            {
1297                return Err(ConcentratorError::Firmware(LoadError::ReadBackDiffers {
1298                    at: done + differs,
1299                }));
1300            }
1301
1302            at = at.wrapping_add(take as u16);
1303            done += take;
1304        }
1305
1306        Ok(())
1307    }
1308
1309    /// Reads the byte a register lives in.
1310    fn read_byte(&mut self, address: u16) -> Result<u8, ConcentratorError<SPI::Error>> {
1311        let out = frame::read(frame::TARGET_CONCENTRATOR, address);
1312        let mut back = [0u8; frame::READ_LEN];
1313        self.spi
1314            .transfer(&mut back, &out)
1315            .map_err(ConcentratorError::Spi)?;
1316        Ok(frame::read_value(&back).unwrap_or(0))
1317    }
1318
1319    /// Writes the byte a register lives in.
1320    fn write_byte(&mut self, address: u16, value: u8) -> Result<(), ConcentratorError<SPI::Error>> {
1321        self.spi
1322            .write(&frame::write(frame::TARGET_CONCENTRATOR, address, value))
1323            .map_err(ConcentratorError::Spi)
1324    }
1325}
1326
1327#[cfg(test)]
1328mod tests {
1329    use pamoja_hal::script::{DelayLog, PinScript, SpiScript, SpiStep};
1330
1331    use super::*;
1332
1333    /// A concentrator whose bus answers with exactly these steps.
1334    fn driven(steps: Vec<SpiStep>) -> Sx1302<SpiScript, PinScript, DelayLog> {
1335        Sx1302::new(SpiScript::new(steps), PinScript::new([]), DelayLog::new())
1336    }
1337
1338    #[test]
1339    fn a_channel_the_radio_cannot_hear_is_refused_before_the_bus_is_touched() {
1340        // Nothing is scripted, so any transfer at all would fail the script. The refusal
1341        // comes first, which is the point: the chip would take this offset and then hear
1342        // nothing on that channel.
1343        let mut chip = driven(Vec::new());
1344        let plan = channel::Plan::new(867_800_000, &[1_000_000]);
1345
1346        let refused = chip
1347            .configure_channels(&plan)
1348            .expect_err("a megahertz is past the radio window");
1349        assert!(matches!(
1350            refused,
1351            ConcentratorError::ChannelOutOfReach {
1352                offset_hz: 1_000_000
1353            }
1354        ));
1355    }
1356
1357    /// The transfer that reads one byte, and the answer it brings back.
1358    fn reads(address: u16, value: u8) -> SpiStep {
1359        let mut reply = [0u8; frame::READ_LEN];
1360        reply[frame::READ_LEN - 1] = value;
1361        SpiStep::transfer(
1362            frame::read(frame::TARGET_CONCENTRATOR, address).to_vec(),
1363            reply.to_vec(),
1364        )
1365    }
1366
1367    /// The transfer that writes one byte.
1368    fn writes(address: u16, value: u8) -> SpiStep {
1369        SpiStep::write(frame::write(frame::TARGET_CONCENTRATOR, address, value).to_vec())
1370    }
1371
1372    /// The two transfers that read a run of bytes out of one address.
1373    fn fetches(address: u16, reply: Vec<u8>) -> Vec<SpiStep> {
1374        vec![
1375            SpiStep::write(frame::burst_read_header(frame::TARGET_CONCENTRATOR, address).to_vec()),
1376            SpiStep::read(reply),
1377        ]
1378    }
1379
1380    /// The two transfers that write a run of bytes to one address.
1381    fn sends(address: u16, payload: Vec<u8>) -> Vec<SpiStep> {
1382        vec![
1383            SpiStep::write(frame::burst_write_header(frame::TARGET_CONCENTRATOR, address).to_vec()),
1384            SpiStep::write(payload),
1385        ]
1386    }
1387
1388    #[test]
1389    fn pointing_a_concentrator_at_its_channels_ends_by_switching_them_on() {
1390        let plan = channel::Plan::new(867_500_000, &[-400_000, -200_000, 0]);
1391
1392        // A register that owns its byte is one write. One that shares a byte is read first,
1393        // so the neighbors beside it survive, which is two transfers rather than one.
1394        let mut steps = Vec::new();
1395        for channel::Step::Write(held, value) in channel::steps(&plan) {
1396            if held.is_whole_byte() {
1397                steps.push(writes(held.address, value));
1398            } else {
1399                steps.push(reads(held.address, 0));
1400                steps.push(writes(held.address, held.encode(0, value)));
1401            }
1402        }
1403
1404        // The bus refuses anything the driver issues out of order or in the wrong shape.
1405        let mut chip = driven(steps);
1406        chip.configure_channels(&plan).expect("the bus answers");
1407
1408        let channel::Step::Write(last, value) =
1409            channel::steps(&plan).last().expect("there are steps");
1410        assert_eq!(last, register::COMMON_GLOBAL_ENABLE);
1411        assert_eq!(value, 0x01);
1412    }
1413
1414    #[test]
1415    fn a_checked_transmission_reports_whether_the_channel_let_it_go() {
1416        // Semtech's `lgw_lbt_tx_status`: the gain control reports chain A started (bit 0),
1417        // with bit 6 clear, so the carrier check let it out. The status is then cleared
1418        // through mailbox 0 and acknowledged.
1419        let status = register::AGC_MCU_STATUS.address;
1420        let mailbox = register::agc_mailbox_write(0).address;
1421        let mut chip = driven(vec![
1422            reads(status, 0x00),
1423            reads(status, 0x00),
1424            reads(status, 0x01),
1425            writes(mailbox, 0xff),
1426            reads(status, 0x01),
1427            reads(status, 0x00),
1428            writes(mailbox, 0x00),
1429        ]);
1430        assert!(chip
1431            .checked_transmission(Chain::A)
1432            .expect("the bus answers"));
1433
1434        // The same start with bit 6 set: the channel was busy and nothing went out.
1435        let mut chip = driven(vec![
1436            reads(status, 0x41),
1437            writes(mailbox, 0xff),
1438            reads(status, 0x00),
1439            writes(mailbox, 0x00),
1440        ]);
1441        assert!(!chip
1442            .checked_transmission(Chain::A)
1443            .expect("the bus answers"));
1444
1445        // Chain B reads bits 1 and 7, so a busy chain A says nothing about it.
1446        let mut chip = driven(vec![
1447            reads(status, 0x42),
1448            writes(mailbox, 0xff),
1449            reads(status, 0x00),
1450            writes(mailbox, 0x00),
1451        ]);
1452        assert!(chip
1453            .checked_transmission(Chain::B)
1454            .expect("the bus answers"));
1455    }
1456
1457    #[test]
1458    fn a_checked_transmission_that_never_starts_still_clears_its_status() {
1459        let status = register::AGC_MCU_STATUS.address;
1460        let mailbox = register::agc_mailbox_write(0).address;
1461        let mut steps: Vec<SpiStep> = (0..lbt::OUTCOME_POLLS)
1462            .map(|_| reads(status, 0x00))
1463            .collect();
1464        steps.extend([
1465            writes(mailbox, 0xff),
1466            reads(status, 0x00),
1467            writes(mailbox, 0x00),
1468        ]);
1469        let mut chip = driven(steps);
1470        assert!(matches!(
1471            chip.checked_transmission(Chain::A),
1472            Err(ConcentratorError::Stalled {
1473                wanted: 0x01,
1474                reading: 0x00
1475            })
1476        ));
1477        let (spi, _, _) = chip.release();
1478        assert!(
1479            spi.done(),
1480            "the clear and the acknowledgment still went out"
1481        );
1482    }
1483
1484    #[test]
1485    fn aborting_resets_every_trigger_then_waits_for_the_chain() {
1486        // Semtech's `sx1302_tx_abort`: immediate, delayed and GPS triggers to zero, then the
1487        // status polled until the chain is free.
1488        let chain = Chain::A;
1489        let mut steps = Vec::new();
1490        for trigger in [Trigger::Immediate, Trigger::At(0), Trigger::OnGps] {
1491            let held = chain.trigger(trigger);
1492            steps.push(reads(held.address, 0x07));
1493            steps.push(writes(held.address, held.encode(0x07, 0)));
1494        }
1495        steps.extend([
1496            reads(chain.status().address, 0x91),
1497            reads(chain.status().address, 0x91),
1498            reads(chain.status().address, tx::STATUS_FREE),
1499        ]);
1500        let mut chip = driven(steps);
1501        chip.abort(chain).expect("the chain comes free");
1502        let (spi, _, _) = chip.release();
1503        assert!(spi.done());
1504    }
1505
1506    #[test]
1507    fn the_counter_is_read_twice_and_kept_from_the_first() {
1508        // The counter runs at 32 MHz, so 64 ticks is two microseconds and 32 is one.
1509        let mut steps = fetches(0x6101, vec![0, 0, 0, 32, 0, 0, 0, 64]);
1510        steps.extend(fetches(0x6101, vec![0, 0, 0, 32, 0, 0, 0, 64]));
1511        let mut chip = driven(steps);
1512
1513        let mut counter = timestamp::Counter::new();
1514        let (free, pulse) = chip.counter(&mut counter).expect("the bus answers");
1515        assert_eq!((free, pulse), (2, 1));
1516    }
1517
1518    #[test]
1519    fn a_counter_that_stepped_between_readings_is_read_again() {
1520        // The second reading carries a different high byte, so neither is trusted and a
1521        // third is taken.
1522        let mut steps = fetches(0x6101, vec![0, 0, 0, 32, 0, 0, 0, 64]);
1523        steps.extend(fetches(0x6101, vec![0, 0, 0, 32, 1, 0, 0, 0]));
1524        steps.extend(fetches(0x6101, vec![0, 0, 0, 32, 0, 0, 1, 0]));
1525        let mut chip = driven(steps);
1526
1527        let mut counter = timestamp::Counter::new();
1528        let (free, _) = chip.counter(&mut counter).expect("the bus answers");
1529        assert_eq!(free, 8);
1530    }
1531
1532    /// The transfers that send one command to a front end.
1533    fn a_front_end_is_told(chain: Chain, opcode: u8, data: Vec<u8>) -> Vec<SpiStep> {
1534        vec![
1535            SpiStep::write(sx1250::header(chain, opcode).to_vec()),
1536            SpiStep::write(data),
1537        ]
1538    }
1539
1540    /// The transfers that ask a front end for an answer.
1541    fn a_front_end_answers(chain: Chain, opcode: u8, reply: Vec<u8>) -> Vec<SpiStep> {
1542        vec![
1543            SpiStep::write(sx1250::header(chain, opcode).to_vec()),
1544            SpiStep::read(reply),
1545        ]
1546    }
1547
1548    #[test]
1549    fn the_clock_moves_to_the_radio_before_anything_is_configured() {
1550        // Three bits share the byte at the clock block, so each is read before it is
1551        // written, and the last write moves the internal clock over to the radio.
1552        let mut chip = driven(vec![
1553            reads(0x57c0, 0),
1554            writes(0x57c0, 0b0000_0001),
1555            reads(0x57c0, 0b0000_0001),
1556            writes(0x57c0, 0b0000_0001),
1557            reads(0x57c0, 0b0000_0001),
1558            writes(0x57c0, 0b0000_0101),
1559            reads(0x5601, 0),
1560            writes(0x5601, 0b0001_0000),
1561        ]);
1562
1563        chip.select_clock(Chain::A).expect("the bus answers");
1564    }
1565
1566    #[test]
1567    fn the_second_radio_carries_the_clock_when_it_is_asked_to() {
1568        let mut chip = driven(vec![
1569            reads(0x57c0, 0b0000_0001),
1570            writes(0x57c0, 0b0000_0000),
1571            reads(0x57c0, 0),
1572            writes(0x57c0, 0b0000_0010),
1573            reads(0x57c0, 0b0000_0010),
1574            writes(0x57c0, 0b0000_0110),
1575            reads(0x5601, 0),
1576            writes(0x5601, 0b0001_0000),
1577        ]);
1578
1579        chip.select_clock(Chain::B).expect("the bus answers");
1580    }
1581
1582    #[test]
1583    fn a_microcontroller_that_never_answers_is_given_up_on() {
1584        // The reference waits here forever. A board that is unpowered or half loaded would
1585        // stop a gateway dead, so this ends and says what it was stuck on.
1586        let steps = vec![reads(0x5781, 0x00); MCU_ATTEMPTS as usize];
1587        let mut chip = driven(steps);
1588
1589        match chip.start_gain_control(FrontEnd::Sx1250, false) {
1590            Err(ConcentratorError::Stalled { wanted, reading }) => {
1591                assert_eq!((wanted, reading), (mcu::STATUS_RUNNING, 0x00));
1592            }
1593            other => panic!("a silent microcontroller is reported: {other:?}"),
1594        }
1595    }
1596
1597    #[test]
1598    fn firmware_the_crate_does_not_drive_is_named() {
1599        // It came up and answered, but it is not the image this crate knows how to talk to.
1600        let mut chip = driven(vec![reads(0x5781, mcu::STATUS_RUNNING), reads(0x5790, 3)]);
1601
1602        match chip.start_gain_control(FrontEnd::Sx1250, false) {
1603            Err(ConcentratorError::WrongFirmware { wanted, running }) => {
1604                assert_eq!((wanted, running), (mcu::AGC_VERSION_SX1250, 3));
1605            }
1606            other => panic!("the version it is running is reported: {other:?}"),
1607        }
1608    }
1609
1610    #[test]
1611    fn the_arbiter_reads_its_version_from_its_own_register() {
1612        // The arbiter answers through debug registers rather than mailboxes, which is the
1613        // only difference between the two exchanges.
1614        let mut chip = driven(vec![reads(0x6081, mcu::STATUS_RUNNING), reads(0x608d, 1)]);
1615
1616        match chip.start_arbiter(0x00) {
1617            Err(ConcentratorError::WrongFirmware { wanted, running }) => {
1618                assert_eq!((wanted, running), (mcu::ARB_VERSION, 1));
1619            }
1620            other => panic!("the arbiter version is read from 0x608d: {other:?}"),
1621        }
1622    }
1623
1624    #[test]
1625    fn bringing_a_front_end_up_tunes_it_and_leaves_it_listening() {
1626        // Every transfer a bring-up issues, in order. The status reads answer with the mode
1627        // in the top bits, which is what the chip does once it has settled.
1628        let mut steps = a_front_end_is_told(Chain::A, sx1250::OP_SET_STANDBY, vec![0x00]);
1629        steps.extend(a_front_end_answers(
1630            Chain::A,
1631            sx1250::OP_GET_STATUS,
1632            vec![0x20],
1633        ));
1634        steps.extend(a_front_end_is_told(
1635            Chain::A,
1636            sx1250::OP_CALIBRATE,
1637            vec![0x7f],
1638        ));
1639        steps.extend(a_front_end_is_told(
1640            Chain::A,
1641            sx1250::OP_SET_STANDBY,
1642            vec![0x01],
1643        ));
1644        steps.extend(a_front_end_answers(
1645            Chain::A,
1646            sx1250::OP_GET_STATUS,
1647            vec![0x30],
1648        ));
1649        for (high, low, value) in [
1650            (0x06, 0xa1, 0x01),
1651            (0x06, 0xa2, 0x00),
1652            (0x06, 0xa3, 0x00),
1653            (0x05, 0x82, 0x00),
1654            (0x05, 0x83, 0x00),
1655            (0x05, 0x84, 0x00),
1656            (0x05, 0x85, 0x00),
1657            (0x05, 0x80, 0x00),
1658            (0x08, 0xb6, 0x2a),
1659        ] {
1660            steps.extend(a_front_end_is_told(
1661                Chain::A,
1662                sx1250::OP_WRITE_REGISTER,
1663                vec![high, low, value],
1664            ));
1665        }
1666        steps.extend(a_front_end_is_told(
1667            Chain::A,
1668            sx1250::OP_SET_RF_FREQUENCY,
1669            vec![0x36, 0x41, 0x99, 0x99],
1670        ));
1671        steps.extend(a_front_end_is_told(
1672            Chain::A,
1673            sx1250::OP_WRITE_REGISTER,
1674            vec![0x08, 0x8f, 0x00, 0x00, 0x00],
1675        ));
1676        steps.extend(a_front_end_is_told(
1677            Chain::A,
1678            sx1250::OP_SET_RX,
1679            vec![0xff, 0xff, 0xff],
1680        ));
1681        steps.extend(a_front_end_is_told(
1682            Chain::A,
1683            sx1250::OP_WRITE_REGISTER,
1684            vec![0x05, 0x87, 0x0b],
1685        ));
1686
1687        let mut chip = driven(steps);
1688        chip.setup_front_end(Chain::A, 868_100_000, false)
1689            .expect("the bus answers");
1690    }
1691
1692    #[test]
1693    fn a_front_end_that_never_settles_says_what_it_read() {
1694        // An unpowered or unclocked front end answers with a mode it was not put in, and
1695        // going on to tune it would be tuning nothing.
1696        let mut steps = a_front_end_is_told(Chain::B, sx1250::OP_SET_STANDBY, vec![0x00]);
1697        steps.extend(a_front_end_answers(
1698            Chain::B,
1699            sx1250::OP_GET_STATUS,
1700            vec![0x00],
1701        ));
1702
1703        let mut chip = driven(steps);
1704        match chip.setup_front_end(Chain::B, 868_100_000, false) {
1705            Err(ConcentratorError::FrontEndMode { wanted, read }) => {
1706                assert_eq!((wanted, read), (0x02, 0x00));
1707            }
1708            other => panic!("a front end that never settles is reported: {other:?}"),
1709        }
1710    }
1711
1712    #[test]
1713    fn a_carrier_outside_every_band_is_refused_before_the_bus() {
1714        // Nothing is sent, so a configuration mistake is not mistaken for a bus fault.
1715        let mut chip = driven(vec![]);
1716        match chip.calibrate_front_end(Chain::A, 880_000_000) {
1717            Err(ConcentratorError::UnsupportedBand { hertz }) => assert_eq!(hertz, 880_000_000),
1718            other => panic!("a carrier between the bands is refused: {other:?}"),
1719        }
1720    }
1721
1722    #[test]
1723    fn a_front_end_that_refuses_its_calibration_is_reported() {
1724        let mut steps = a_front_end_is_told(Chain::A, sx1250::OP_CALIBRATE_IMAGE, vec![0xd7, 0xdb]);
1725        steps.extend(a_front_end_answers(
1726            Chain::A,
1727            sx1250::OP_GET_DEVICE_ERRORS,
1728            vec![0x00, 0x00, 0b0001_0000],
1729        ));
1730
1731        let mut chip = driven(steps);
1732        assert!(matches!(
1733            chip.calibrate_front_end(Chain::A, 868_100_000),
1734            Err(ConcentratorError::ImageCalibration)
1735        ));
1736    }
1737
1738    #[test]
1739    fn a_calibrated_front_end_reports_nothing() {
1740        let mut steps = a_front_end_is_told(Chain::A, sx1250::OP_CALIBRATE_IMAGE, vec![0xe1, 0xe9]);
1741        steps.extend(a_front_end_answers(
1742            Chain::A,
1743            sx1250::OP_GET_DEVICE_ERRORS,
1744            vec![0x00, 0x00, 0x00],
1745        ));
1746
1747        let mut chip = driven(steps);
1748        chip.calibrate_front_end(Chain::A, 915_000_000)
1749            .expect("the bus answers");
1750    }
1751
1752    #[test]
1753    fn a_quiet_concentrator_hands_back_nothing() {
1754        let mut chip = driven(vec![
1755            reads(0x58c8, 0),
1756            reads(0x58c9, 0),
1757            reads(0x58c8, 0),
1758            reads(0x58c9, 0),
1759        ]);
1760
1761        let mut buffer = [0u8; 32];
1762        assert!(chip
1763            .receive(&mut buffer)
1764            .expect("the bus answers")
1765            .is_empty());
1766    }
1767
1768    #[test]
1769    fn the_byte_count_is_read_twice_and_the_larger_kept() {
1770        // A read of the pair can answer with less than is really there, so two are taken and
1771        // the larger wins. Here the second read sees three more bytes, and all five arrive.
1772        let mut steps = vec![
1773            reads(0x58c8, 0),
1774            reads(0x58c9, 2),
1775            reads(0x58c8, 0),
1776            reads(0x58c9, 5),
1777        ];
1778        steps.extend(fetches(0x4000, vec![1, 2, 3, 4, 5]));
1779        let mut chip = driven(steps);
1780
1781        let mut buffer = [0u8; 32];
1782        let heard = chip.receive(&mut buffer).expect("the bus answers");
1783        assert_eq!(heard, [1, 2, 3, 4, 5]);
1784    }
1785
1786    #[test]
1787    fn more_than_fits_is_refused_before_a_byte_is_read() {
1788        // Nothing is taken out of the buffer, so the same packets are still there for a
1789        // caller that comes back with room for them.
1790        let mut chip = driven(vec![
1791            reads(0x58c8, 0),
1792            reads(0x58c9, 16),
1793            reads(0x58c8, 0),
1794            reads(0x58c9, 16),
1795        ]);
1796
1797        let mut buffer = [0u8; 8];
1798        match chip.receive(&mut buffer) {
1799            Err(ConcentratorError::Overrun { waiting }) => assert_eq!(waiting, 16),
1800            other => panic!("a buffer too small is refused, not filled: {other:?}"),
1801        }
1802    }
1803
1804    #[test]
1805    fn a_fetch_larger_than_one_chunk_reads_the_same_port_again() {
1806        // The receive buffer is a port, not a window. Reading it moves the chip pointer
1807        // along, so the second chunk comes from the same address. A reader that advanced
1808        // would ask for the address a chunk higher and get the wrong bytes.
1809        let mut steps = fetches(0x4000, vec![0xa5; frame::BURST_CHUNK]);
1810        steps.extend(fetches(0x4000, vec![0xc0; 100]));
1811        let mut chip = driven(steps);
1812
1813        let mut buffer = [0u8; frame::BURST_CHUNK + 100];
1814        chip.read_fifo(0x4000, &mut buffer)
1815            .expect("the bus answers");
1816        assert_eq!(buffer[0], 0xa5);
1817        assert_eq!(buffer[frame::BURST_CHUNK], 0xc0);
1818    }
1819
1820    #[test]
1821    fn a_packet_the_chain_cannot_describe_never_reaches_the_bus() {
1822        // Nothing is scripted, so any transfer at all would fail the script. The refusal
1823        // comes first, which matters more here than it looks: a chain left half configured
1824        // would put the next packet on the air with whatever it was given for this one.
1825        let mut chip = driven(Vec::new());
1826        let request = tx::Transmit {
1827            frequency_hz: 868_100_000,
1828            link: pamoja_lora::LinkSettings::new(7, 62_500),
1829            gain: tx::DEFAULT_GAINS[0],
1830            invert_polarity: true,
1831            public: true,
1832            payload: &[0x01],
1833        };
1834
1835        let refused = chip
1836            .transmit(Chain::A, &request, Trigger::Immediate, 0x0102)
1837            .expect_err("a chain does not transmit at 62500 Hz");
1838        assert!(matches!(
1839            refused,
1840            ConcentratorError::Transmit(tx::TransmitError::Bandwidth { hertz: 62_500 })
1841        ));
1842    }
1843
1844    #[test]
1845    fn a_send_loads_the_payload_before_it_arms_the_trigger() {
1846        // The delay is programmed, the buffer is opened and written and closed, and only
1847        // then is the trigger cleared and set. Arming first would send whatever was there.
1848        let mut steps = vec![
1849            writes(0x5205, 0x01),
1850            writes(0x5206, 0x02),
1851            reads(0x5207, 0),
1852            writes(0x5207, 1),
1853        ];
1854        steps.extend(sends(0x5300, vec![0xde, 0xad]));
1855        steps.extend(vec![
1856            reads(0x5207, 1),
1857            writes(0x5207, 0),
1858            reads(0x5200, 0),
1859            writes(0x5200, 0),
1860            reads(0x5200, 0),
1861            writes(0x5200, 1),
1862        ]);
1863        let mut chip = driven(steps);
1864
1865        chip.send(Chain::A, &[0xde, 0xad], Trigger::Immediate, 0x0102)
1866            .expect("the bus answers");
1867    }
1868
1869    #[test]
1870    fn a_timed_send_counts_down_the_addresses() {
1871        // A send one second out at this delay is 1000000 * 32 - 258 ticks, which is
1872        // 0x01e846fe. The least significant byte goes to the highest of the four addresses,
1873        // which is the one thing about this register that is easy to get backward.
1874        let mut steps = vec![
1875            writes(0x5205, 0x01),
1876            writes(0x5206, 0x02),
1877            reads(0x5207, 0),
1878            writes(0x5207, 1),
1879        ];
1880        steps.extend(sends(0x5300, vec![0x01]));
1881        steps.extend(vec![
1882            reads(0x5207, 1),
1883            writes(0x5207, 0),
1884            writes(0x5204, 0xfe),
1885            writes(0x5203, 0x46),
1886            writes(0x5202, 0xe8),
1887            writes(0x5201, 0x01),
1888            reads(0x5200, 0),
1889            writes(0x5200, 0),
1890            reads(0x5200, 0),
1891            writes(0x5200, 0b10),
1892        ]);
1893        let mut chip = driven(steps);
1894
1895        chip.send(Chain::A, &[0x01], Trigger::At(1_000_000), 0x0102)
1896            .expect("the bus answers");
1897    }
1898
1899    #[test]
1900    fn a_chain_that_will_take_a_packet_reads_free() {
1901        let mut chip = driven(vec![reads(0x5211, tx::STATUS_FREE)]);
1902
1903        let status = chip.tx_status(Chain::A).expect("the bus answers");
1904        assert!(status.is_free(), "{status:?}");
1905    }
1906
1907    #[test]
1908    fn a_concentrator_that_answers_reads_the_documented_version() {
1909        let mut chip = driven(vec![reads(0x5606, chip::EXPECTED_VERSION)]);
1910        assert_eq!(chip.version().expect("the bus answers"), 0x10);
1911    }
1912
1913    #[test]
1914    fn a_board_that_is_not_there_says_what_it_read() {
1915        // An unpowered board reads zero and a bus nothing drives reads all ones, and the
1916        // caller is told which, because they are different faults to go and look for.
1917        for absent in [0x00, 0xff] {
1918            let mut chip = driven(vec![reads(0x5606, absent)]);
1919            match chip.check() {
1920                Err(ConcentratorError::NotAnswering { version }) => assert_eq!(version, absent),
1921                other => panic!("a silent board is reported, not accepted: {other:?}"),
1922            }
1923        }
1924
1925        let mut chip = driven(vec![reads(0x5606, chip::EXPECTED_VERSION)]);
1926        assert!(chip.check().is_ok());
1927    }
1928
1929    #[test]
1930    fn identifying_selects_the_byte_then_reads_it() {
1931        // The part number is not a register: it is selected in one transfer and read in the
1932        // next, so both go out in order.
1933        let mut chip = driven(vec![
1934            writes(0x6180, chip::MODEL_BYTE_ADDRESS),
1935            reads(0x6181, 0x03),
1936        ]);
1937        assert_eq!(chip.identify().expect("the bus answers"), Model::Sx1303);
1938
1939        let mut chip = driven(vec![
1940            writes(0x6180, chip::MODEL_BYTE_ADDRESS),
1941            reads(0x6181, 0x02),
1942        ]);
1943        assert_eq!(chip.identify().expect("the bus answers"), Model::Sx1302);
1944    }
1945
1946    #[test]
1947    fn a_narrow_register_is_read_before_it_is_written() {
1948        // The clock control shares its byte with the radio control beside it, so writing it
1949        // costs a read first and must leave the neighbor alone.
1950        let held = 0b0000_1000; // the host radio control bit, which must survive
1951        let mut chip = driven(vec![
1952            reads(0x5601, held),
1953            writes(0x5601, held | 0b0001_0000),
1954        ]);
1955
1956        chip.write_register(register::COMMON_CLK32_RIF_CTRL, 1)
1957            .expect("the bus answers");
1958    }
1959
1960    #[test]
1961    fn a_whole_byte_is_written_without_reading_it_first() {
1962        // The one-time programmable address is the whole byte, so there is nothing to preserve.
1963        let mut chip = driven(vec![writes(0x6180, 0xd0)]);
1964        chip.write_register(register::OTP_BYTE_ADDR, 0xd0)
1965            .expect("the bus answers");
1966    }
1967
1968    #[test]
1969    fn resetting_a_front_end_clocks_the_chip_from_the_host_first() {
1970        // Clearing the clock control keeps the concentrator listening while the radio it
1971        // drives is held down, which is why it comes before anything else.
1972        let mut chip = driven(vec![
1973            reads(0x5601, 0),
1974            writes(0x5601, 0),
1975            reads(0x5783, 0),
1976            writes(0x5783, 0b0000_0100),
1977            reads(0x5783, 0b0000_0100),
1978            writes(0x5783, 0b0000_1100),
1979            reads(0x5783, 0b0000_1100),
1980            writes(0x5783, 0b0000_0100),
1981        ]);
1982
1983        chip.reset_front_end(Chain::A, FrontEnd::Sx125x)
1984            .expect("the bus answers");
1985    }
1986
1987    #[test]
1988    fn an_sx1250_is_held_again_while_it_calibrates() {
1989        // The newer front end calibrates itself on the way out, so it takes one more write
1990        // than the older one does.
1991        let mut chip = driven(vec![
1992            reads(0x5601, 0),
1993            writes(0x5601, 0),
1994            reads(0x5784, 0),
1995            writes(0x5784, 0b0000_0100),
1996            reads(0x5784, 0b0000_0100),
1997            writes(0x5784, 0b0000_1100),
1998            reads(0x5784, 0b0000_1100),
1999            writes(0x5784, 0b0000_0100),
2000            reads(0x5784, 0b0000_0100),
2001            writes(0x5784, 0b0000_1100),
2002        ]);
2003
2004        chip.reset_front_end(Chain::B, FrontEnd::Sx1250)
2005            .expect("the bus answers");
2006    }
2007
2008    #[test]
2009    fn an_image_of_the_wrong_size_never_reaches_the_bus() {
2010        // Nothing is scripted, so any transfer at all would fail the test.
2011        let mut chip = driven(vec![]);
2012        match chip.load_firmware(Mcu::Agc, &[0u8; 16]) {
2013            Err(ConcentratorError::Firmware(LoadError::WrongSize { offered })) => {
2014                assert_eq!(offered, 16);
2015            }
2016            other => panic!("a short image is refused before anything is written: {other:?}"),
2017        }
2018    }
2019
2020    #[test]
2021    fn the_reset_line_is_pulsed_and_then_released() {
2022        let mut chip = driven(vec![]);
2023        chip.reset().expect("the line is drivable");
2024
2025        let (_, pins, delay) = chip.release();
2026        assert_eq!(
2027            pins.driven(),
2028            [digital::PinState::High, digital::PinState::Low]
2029        );
2030        assert_eq!(
2031            delay.waits_ns().len(),
2032            2,
2033            "held, then given time to come up"
2034        );
2035    }
2036}