|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
SMBus 3.2 protocol layer over an injected I2C bus seam. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_smbus_cfg_t |
| Configuration descriptor for ra8_smbus_init. More... | |
Typedefs | |
| typedef void(* | ra8_smbus_alert_fn_t) (void *ctx, uint8_t target_7b, uint8_t status) |
| SMBALERT# notification callback. | |
Enumerations | |
| enum | ra8_smbus_limits_t : uint16_t { k_ra8_smbus_block_max = 255U , k_ra8_smbus_frame_max = 258U , k_ra8_smbus_alert_addr_7b = 0x0CU } |
| Spec-mandated buffer ceilings. More... | |
Functions | |
| ra8_err_t | ra8_smbus_init (const ra8_smbus_cfg_t *cfg) |
| Initialise the SMBus layer over the injected bus seam. | |
| ra8_err_t | ra8_smbus_deinit (void) |
| Tear the SMBus layer down and release the driver slot. | |
| ra8_err_t | ra8_smbus_send_byte (uint8_t target_7b, uint8_t data) |
| Send Byte transaction (SMBus 3.2 section 6.5.2). | |
| ra8_err_t | ra8_smbus_receive_byte (uint8_t target_7b, uint8_t *out_data) |
| Receive Byte transaction (SMBus 3.2 section 6.5.3). | |
| ra8_err_t | ra8_smbus_write_byte_data (uint8_t target_7b, uint8_t cmd, uint8_t data) |
| Write Byte Data: register-indexed byte write (SMBus 3.2 sec 6.5.4). | |
| ra8_err_t | ra8_smbus_read_byte_data (uint8_t target_7b, uint8_t cmd, uint8_t *out_data) |
| Read Byte Data: register-indexed byte read (SMBus 3.2 sec 6.5.5). | |
| ra8_err_t | ra8_smbus_block_write (uint8_t target_7b, uint8_t cmd, const uint8_t *data, uint8_t len) |
| Block Write (SMBus 3.2 section 6.5.7). | |
| ra8_err_t | ra8_smbus_block_read (uint8_t target_7b, uint8_t cmd, uint8_t *buf, uint8_t cap, uint8_t *out_len) |
| Block Read (SMBus 3.2 section 6.5.8). | |
| ra8_err_t | ra8_smbus_alert_register_callback (ra8_smbus_alert_fn_t fn, void *ctx) |
| Register a callback fired when ra8_smbus_alert_dispatch successfully reads the Alert Response Address. | |
| ra8_err_t | ra8_smbus_alert_dispatch (void) |
| Dispatch a single SMBALERT# event: read the ARA and fire the registered callback. | |
| uint8_t | ra8_smbus_pec (const uint8_t *data, uint32_t len) |
| Compute CRC-8/SMBus over a buffer. | |
SMBus 3.2 protocol layer over an injected I2C bus seam.
Implements the controller-side SMBus 3.2 protocol layer specified in the SMBus 3.2 specification (SBS-IF, December 2018):
SMBus is a strict subset of I2C with extra protocol rules:
This module owns the protocol framing (count byte, PEC, address stuffing for ARA) and delegates raw byte movement to the injected I2C bus seam (ra8_i2c_bus_ops_t) supplied at init – IIC_B in I2C-compat mode today, RIIC on a future board revision. The bus drivers are not modified – SMBus is layered on top, and the app owns bus bring-up/teardown (typically binding the seam via ra8_io_i2c_bus_as_ops()).
Inclusive terminology: "controller" / "peripheral" replaces the legacy controller/peripheral wording in the SMBus spec (the spec itself uses the older terminology).
Definition in file ra8_smbus.h.
| typedef void(* ra8_smbus_alert_fn_t) (void *ctx, uint8_t target_7b, uint8_t status) |
SMBALERT# notification callback.
| [in] | ctx | Caller-supplied context. |
| [in] | target_7b | 7-bit address of the peripheral that asserted ALERT, as recovered from the ARA read. |
| [in] | status | Status byte returned in the ARA payload. |
Definition at line 101 of file ra8_smbus.h.
| enum ra8_smbus_limits_t : uint16_t |
Spec-mandated buffer ceilings.
SMBus 3.2 section 6.5.7 / 6.5.8 caps a block payload at 255 bytes (the count byte is uint8_t). The on-the-wire frame is therefore at most addr + count + 255 data + PEC = 258 bytes. Callers that stack-allocate scratch buffers should size them with this enum.
| Enumerator | |
|---|---|
| k_ra8_smbus_block_max | Max data bytes per block xfer. |
| k_ra8_smbus_frame_max | Max wire bytes incl. PEC + addr. |
| k_ra8_smbus_alert_addr_7b | Alert Response Address (ARA). |
Definition at line 72 of file ra8_smbus.h.
|
nodiscard |
Dispatch a single SMBALERT# event: read the ARA and fire the registered callback.
Reads one byte from address k_ra8_smbus_alert_addr_7b (0x0C). The returned byte's upper 7 bits are the 7-bit address of the peripheral that asserted ALERT (SMBus 3.2 section 6.5.13). The LSB is the device status. If no callback has been registered the read still happens (so the bus line is released) but no further action is taken.
Test-callable: unit tests invoke this directly to simulate an ALERT event.
| k_ra8_ok | Dispatch completed (callback fired if registered). |
| k_ra8_err_not_initialized | Init not run. |
| Forwarded | codes from the bus seam read. |
Definition at line 472 of file ra8_smbus.c.
References k_ra8_err_not_initialized, k_ra8_ok, k_ra8_smbus_addr_shift, k_ra8_smbus_alert_addr_7b, and s_state.
|
nodiscard |
Register a callback fired when ra8_smbus_alert_dispatch successfully reads the Alert Response Address.
SMBus 3.2 section 6.5.13 specifies that a peripheral asserts SMBALERT# (an open-drain side-band line, not SDA/SCL) and the controller responds by reading from address 0x0C (ARA). The peripheral that won arbitration writes its 7-bit address back into the LSBs of the response byte. Because SMBALERT# is a board-level GPIO interrupt, this driver does not own the IRQ wiring – the caller arms ra8_icu to call ra8_smbus_alert_dispatch() from the SMBALERT# ISR, and the dispatch helper performs the ARA read and fires the registered callback.
| [in] | fn | Callback to fire, or NULL to detach. |
| [in] | ctx | Context pointer passed back unchanged. |
| k_ra8_ok | Callback registered or detached. |
| k_ra8_err_not_initialized | Init not run. |
Definition at line 461 of file ra8_smbus.c.
References k_ra8_err_not_initialized, k_ra8_ok, and s_state.
|
nodiscard |
Block Read (SMBus 3.2 section 6.5.8).
Wire format with PEC disabled: S | addr_w | cmd | Sr | addr_r | count | data[0..count-1] | P With PEC enabled the PEC trails the data run.
| [in] | target_7b | 7-bit peripheral address. |
| [in] | cmd | Command / register index byte. |
| [out] | buf | Destination buffer (non-NULL, capacity cap). |
| [in] | cap | Capacity of buf (1..255). |
| [out] | out_len | Bytes actually returned by the peripheral (the count field). Always populated on k_ra8_ok and on k_ra8_err_invalid_size. |
| k_ra8_ok | Block received and PEC matched if on. |
| k_ra8_err_null_ptr | buf / out_len NULL. |
| k_ra8_err_invalid_arg | cap is 0 or > 255. |
| k_ra8_err_invalid_size | Returned count exceeds cap. |
| k_ra8_err_not_initialized | Init not run. |
| k_ra8_err_crc_mismatch | PEC verification failed. |
| Forwarded | codes from the bus seam write / read. |
Definition at line 433 of file ra8_smbus.c.
References internal_block_read_finish(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_smbus_rx_bytes, RA8_CHECK_NULL_PTR, s_state, and s_tag.
|
nodiscard |
Block Write (SMBus 3.2 section 6.5.7).
Wire format with PEC disabled: S | addr_w | cmd | count | data[0..count-1] | P With PEC enabled the PEC byte is inserted before the STOP. The count byte is mandatory and must equal len (1..255).
| [in] | target_7b | 7-bit peripheral address. |
| [in] | cmd | Command / register index byte. |
| [in] | data | Payload buffer (non-NULL when len > 0). |
| [in] | len | Number of bytes (1..255). |
| k_ra8_ok | Block written. |
| k_ra8_err_null_ptr | data NULL with non-zero len. |
| k_ra8_err_invalid_arg | len is 0 or > 255. |
| k_ra8_err_not_initialized | Init not run. |
| Forwarded | codes from the bus seam write. |
Definition at line 294 of file ra8_smbus.c.
References internal_make_addr_byte(), internal_pec_update(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_smbus_pec_init, k_ra8_smbus_rw_write, k_smbus_frame_bytes, RA8_CHECK_NULL_PTR, s_state, and s_tag.
|
nodiscard |
Tear the SMBus layer down and release the driver slot.
| k_ra8_ok | Layer released. |
| k_ra8_err_not_initialized | ra8_smbus_init never ran. |
Definition at line 175 of file ra8_smbus.c.
References k_ra8_err_not_initialized, k_ra8_ok, and s_state.
|
nodiscard |
Initialise the SMBus layer over the injected bus seam.
Latches cfg->bus and the policy bits (PEC enable) for later transfers. The bus peripheral behind the seam is initialised by the app before this call – this layer never brings hardware up or down.
| [in] | cfg | Configuration descriptor. |
| k_ra8_ok | SMBus layer ready. |
| k_ra8_err_null_ptr | cfg is NULL. |
| k_ra8_err_invalid_arg | cfg->bus seam incomplete (a NULL op). |
Definition at line 152 of file ra8_smbus.c.
References ra8_smbus_cfg_t::bus, k_ra8_err_invalid_arg, k_ra8_ok, ra8_smbus_cfg_t::pec_enabled, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_i2c_bus_ops_t::read, s_state, s_tag, ra8_i2c_bus_ops_t::transfer, and ra8_i2c_bus_ops_t::write.
Referenced by main().
| uint8_t ra8_smbus_pec | ( | const uint8_t * | data, |
| uint32_t | len ) |
Compute CRC-8/SMBus over a buffer.
Polynomial 0x07, initial value 0x00, no reflection, no XOR-out (SMBus 3.2 section 5.4). Provided as a public symbol so tests can cross-check the framing; production code should not need to call this directly.
| [in] | data | Pointer to bytes (non-NULL when len > 0). |
| [in] | len | Byte count. |
| 0x00 | Either len == 0 or the input bytes happen to hash to zero. |
| other | Computed CRC-8 over data[0..len-1] per SMBus 3.2 section 5.4. |
Definition at line 122 of file ra8_smbus.c.
References internal_pec_update(), and k_ra8_smbus_pec_init.
|
nodiscard |
Read Byte Data: register-indexed byte read (SMBus 3.2 sec 6.5.5).
Wire format with PEC disabled: S | addr_w | cmd | Sr | addr_r | data | P With PEC enabled: S | addr_w | cmd | Sr | addr_r | data | PEC | P
The PEC is computed over addr_w | cmd | addr_r | data.
| [in] | target_7b | 7-bit peripheral address. |
| [in] | cmd | Command / register index byte. |
| [out] | out_data | Destination byte (non-NULL). |
| k_ra8_ok | Byte read (and PEC matched if enabled). |
| k_ra8_err_null_ptr | out_data NULL. |
| k_ra8_err_not_initialized | Init not run. |
| k_ra8_err_crc_mismatch | PEC verification failed. |
| Forwarded | codes from the bus seam write / read. |
Definition at line 259 of file ra8_smbus.c.
References internal_make_addr_byte(), internal_pec_update(), k_ra8_err_crc_mismatch, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_smbus_pec_init, k_ra8_smbus_rw_read, k_ra8_smbus_rw_write, RA8_CHECK_NULL_PTR, ra8_log_error, s_state, and s_tag.
Referenced by bm_read_or_halt(), and sd_read_whoami_or_halt().
|
nodiscard |
Receive Byte transaction (SMBus 3.2 section 6.5.3).
Wire format with PEC disabled: S | (addr<<1)|1 | data | P With PEC enabled: S | (addr<<1)|1 | data | PEC | P
| [in] | target_7b | 7-bit peripheral address. |
| [out] | out_data | Destination byte (non-NULL). |
| k_ra8_ok | Byte received (and PEC matched if enabled). |
| k_ra8_err_null_ptr | out_data is NULL. |
| k_ra8_err_not_initialized | Init not run. |
| k_ra8_err_crc_mismatch | PEC verification failed. |
| Forwarded | codes from the bus seam read. |
Definition at line 210 of file ra8_smbus.c.
References internal_make_addr_byte(), internal_pec_update(), k_ra8_err_crc_mismatch, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_smbus_pec_init, k_ra8_smbus_rw_read, RA8_CHECK_NULL_PTR, ra8_log_error, s_state, and s_tag.
Referenced by sd_read_whoami_or_halt().
|
nodiscard |
Send Byte transaction (SMBus 3.2 section 6.5.2).
Wire format with PEC disabled: S | (addr<<1)|0 | data | P With PEC enabled: S | (addr<<1)|0 | data | PEC | P
The PEC is computed over the address byte and the data byte using CRC-8 polynomial 0x07, init 0 (SMBus 3.2 section 5.4).
| [in] | target_7b | 7-bit peripheral address. |
| [in] | data | Single data byte to transmit. |
| k_ra8_ok | Byte delivered. |
| k_ra8_err_not_initialized | Init not run. |
| Forwarded | codes from the bus seam write. |
Definition at line 191 of file ra8_smbus.c.
References internal_make_addr_byte(), internal_pec_update(), k_ra8_err_not_initialized, k_ra8_smbus_pec_init, k_ra8_smbus_rw_write, and s_state.
Referenced by sd_read_whoami_or_halt().
|
nodiscard |
Write Byte Data: register-indexed byte write (SMBus 3.2 sec 6.5.4).
Wire format with PEC disabled: S | addr_w | cmd | data | P With PEC enabled the PEC is appended before the STOP.
| [in] | target_7b | 7-bit peripheral address. |
| [in] | cmd | Command / register index byte. |
| [in] | data | Data byte to write. |
| k_ra8_ok | Byte written. |
| k_ra8_err_not_initialized | Init not run. |
| Forwarded | codes from the bus seam write. |
Definition at line 240 of file ra8_smbus.c.
References internal_make_addr_byte(), internal_pec_update(), k_ra8_err_not_initialized, k_ra8_smbus_pec_init, k_ra8_smbus_rw_write, and s_state.