ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_i2c_devices.c
Go to the documentation of this file.
1
15
16#include <string.h>
17
18#include "board_periph.h"
20
42
69
79typedef struct {
81 uint16_t reg_ptr;
82 bool ptr_set;
83 uint32_t reads;
85
93typedef struct {
94 uint8_t soc_pct;
95 bool charging;
97
105typedef struct {
107 uint16_t reg_ptr;
108 bool ptr_set;
109 uint32_t reads;
111
113
115static battery_state_t s_battery = {.soc_pct = (uint8_t)k_battery_soc_default, .charging = false};
117
129RA8_INTERNAL static void internal_lsm6dso_seed16(lsm6dso_state_t* s, uint8_t reg, uint16_t val)
130{
131 s->regs[reg] = (uint8_t)((uint32_t)val & (uint32_t)k_i3c_dev_byte_mask);
132 s->regs[(uint8_t)(reg + 1U)] = (uint8_t)((uint32_t)val >> 8U);
133}
134
145{
146 for (uint32_t i = 0U; i < (uint32_t)k_lsm6dso_reg_file; i++) {
147 s->regs[i] = 0U;
148 }
149 s->regs[(uint8_t)k_lsm6dso_reg_who_am_i] = (uint8_t)k_lsm6dso_who_am_i_val;
152 s->reg_ptr = 0U;
153 s->ptr_set = false;
154 s->reads = 0U;
155}
156
167RA8_INTERNAL static void internal_lsm6dso_write(void* ctx, uint8_t byte)
168{
170 if (!s->ptr_set) {
171 s->reg_ptr = byte;
172 s->ptr_set = true;
173 return;
174 }
175 if (s->reg_ptr < (uint16_t)k_lsm6dso_reg_file) {
176 s->regs[s->reg_ptr] = byte; /* CTRL config writes land harmlessly. */
177 }
178 s->reg_ptr = (uint16_t)(s->reg_ptr + 1U);
179}
180
194RA8_INTERNAL static uint32_t internal_lsm6dso_read(void* ctx, uint8_t* buf, uint32_t max)
195{
197 for (uint32_t i = 0U; i < max; i++) {
198 buf[i] = (s->reg_ptr < (uint16_t)k_lsm6dso_reg_file) ? s->regs[s->reg_ptr] : 0U;
199 s->reg_ptr = (uint16_t)(s->reg_ptr + 1U);
200 }
201 s->reads++;
202 return max;
203}
204
215{
217 s->ptr_set = false;
218}
219
231RA8_INTERNAL static void internal_fuelgauge_put16(max17048_state_t* s, uint8_t reg, uint16_t val)
232{
233 s->regs[reg] = (uint8_t)(val >> (uint16_t)k_battery_byte_shift);
234 s->regs[(uint8_t)(reg + 1U)] = (uint8_t)(val & (uint16_t)k_battery_byte_mask);
235}
236
247{
248 for (uint32_t i = 0U; i < (uint32_t)k_max17048_reg_file; i++) {
249 s->regs[i] = 0U;
250 }
252 /* SOC: high byte is the integer percent, low byte the 1/256 fraction (0). */
254 s,
255 (uint8_t)k_max17048_reg_soc,
256 (uint16_t)((uint16_t)s_battery.soc_pct << (uint16_t)k_battery_byte_shift));
258 /* CRATE is signed: positive while charging, negative while discharging. */
259 const int32_t crate =
260 s_battery.charging ? (int32_t)k_battery_crate_mag : -(int32_t)k_battery_crate_mag;
261 internal_fuelgauge_put16(s, (uint8_t)k_max17048_reg_crate, (uint16_t)(int16_t)crate);
262}
263
274RA8_INTERNAL static void internal_fuelgauge_write(void* ctx, uint8_t byte)
275{
277 if (!s->ptr_set) {
278 s->reg_ptr = byte;
279 s->ptr_set = true;
280 return;
281 }
282 if (s->reg_ptr < (uint16_t)k_max17048_reg_file) {
283 s->regs[s->reg_ptr] = byte;
284 }
285 s->reg_ptr = (uint16_t)(s->reg_ptr + 1U);
286}
287
301RA8_INTERNAL static uint32_t internal_fuelgauge_read(void* ctx, uint8_t* buf, uint32_t max)
302{
304 for (uint32_t i = 0U; i < max; i++) {
305 buf[i] = (s->reg_ptr < (uint16_t)k_max17048_reg_file) ? s->regs[s->reg_ptr] : 0U;
306 s->reg_ptr = (uint16_t)(s->reg_ptr + 1U);
307 }
308 s->reads++;
309 return max;
310}
311
322{
324 s->ptr_set = false;
325}
326
327void board_periph_battery_set(uint8_t soc_pct, bool charging)
328{
329 s_battery.soc_pct = (soc_pct > (uint8_t)k_battery_soc_max) ? (uint8_t)k_battery_soc_max : soc_pct;
330 s_battery.charging = charging;
332}
333
334void board_periph_battery_get(uint8_t* out_soc, bool* out_charging)
335{
336 if (out_soc != nullptr) {
337 *out_soc = s_battery.soc_pct;
338 }
339 if (out_charging != nullptr) {
340 *out_charging = s_battery.charging;
341 }
342}
343
346{
349 internal_fuelgauge_seed(&s_fuelgauge); /* lay the register file from s_battery (CLI-set) */
350}
351
354{
359 &s_lsm6dso);
360 /* MAX17048-class fuel gauge at 0x36: exposes the battery state-of-charge +
361 * charge direction so a battery monitor reads a real % over I2C. */
366 &s_fuelgauge);
367}
368
371{
372 return s_lsm6dso.reads;
373}
Register-accurate peripheral-model framework for the board emulator.
lsm6dso_const_t
ST LSM6DSO 6-DoF IMU constants (libs/ra8_lsm6dso, DS12140 Rev 4).
@ k_lsm6dso_addr_7b
SA0-high 7-bit I2C address.
@ k_lsm6dso_reg_outz_l_a
Accel Z low byte (OUTZ_L_A).
@ k_lsm6dso_who_am_i_val
Expected WHO_AM_I value.
@ k_lsm6dso_reg_file
Flat register-file size (bytes).
@ k_lsm6dso_seed_accel_z
Synthetic accel Z (~+1 g at +-2 g FS).
@ k_lsm6dso_seed_gyro_x
Synthetic gyro X (small steady rate).
static RA8_INTERNAL void internal_lsm6dso_stop(void *ctx)
STOP / transfer end: re-arm pointer capture for the next transfer.
static RA8_INTERNAL void internal_lsm6dso_reset_regs(lsm6dso_state_t *s)
Reset the register file: WHO_AM_I + synthetic accel/gyro samples.
void board_periph_battery_get(uint8_t *out_soc, bool *out_charging)
Read back the emulated battery state (for the status overlay).
static RA8_INTERNAL void internal_fuelgauge_write(void *ctx, uint8_t byte)
MAX17048 write: first byte is the register pointer, then it advances.
static RA8_INTERNAL void internal_fuelgauge_stop(void *ctx)
MAX17048 STOP: re-arm the register-pointer capture.
static RA8_INTERNAL void internal_fuelgauge_put16(max17048_state_t *s, uint8_t reg, uint16_t val)
Write a big-endian 16-bit value at register reg of s.
static battery_state_t s_battery
Battery state + the fuel-gauge device that exposes it over I2C.
max17048_const_t
Maxim MAX17048 fuel-gauge constants (battery state-of-charge over I2C).
@ k_battery_byte_mask
Low-byte mask.
@ k_max17048_addr_7b
MAX17048 7-bit I2C address.
@ k_max17048_reg_crate
CRATE: charge rate (signed, 0.208%/hr).
@ k_battery_version_val
Reported VERSION.
@ k_battery_vcell_default
~3.80 V at 78.125 uV/LSB.
@ k_battery_byte_shift
High-byte shift for a 16-bit register.
@ k_battery_soc_max
SOC clamp ceiling.
@ k_battery_soc_default
Default state-of-charge percent.
@ k_max17048_reg_version
VERSION register.
@ k_max17048_reg_soc
SOC: state-of-charge (1/256 %/LSB).
@ k_battery_crate_mag
|CRATE| ~5 %/hr (sign = charging).
@ k_max17048_reg_vcell
VCELL: cell voltage (78.125 uV/LSB).
@ k_max17048_reg_file
Flat register-file size (bytes).
static RA8_INTERNAL uint32_t internal_fuelgauge_read(void *ctx, uint8_t *buf, uint32_t max)
MAX17048 read: serve consecutive register bytes (auto-increment).
static RA8_INTERNAL void internal_fuelgauge_seed(max17048_state_t *s)
Lay the MAX17048 register file from the current s_battery state.
static max17048_state_t s_fuelgauge
void priv_board_i2c_imu_fuel_reset(void)
Implementation of priv_board_i2c_imu_fuel_reset() – re-lay register files.
void board_periph_battery_set(uint8_t soc_pct, bool charging)
Set the emulated battery state surfaced by the MAX17048 fuel gauge.
static RA8_INTERNAL uint32_t internal_lsm6dso_read(void *ctx, uint8_t *buf, uint32_t max)
LSM6DSO -> controller: burst from the pointer, auto-incrementing.
static RA8_INTERNAL void internal_lsm6dso_write(void *ctx, uint8_t byte)
Controller -> LSM6DSO: start register first, then config payload.
uint32_t priv_board_i2c_imu_reads(void)
Implementation of priv_board_i2c_imu_reads() – report telemetry.
static lsm6dso_state_t s_lsm6dso
void priv_board_i2c_imu_fuel_register(void)
Implementation of priv_board_i2c_imu_fuel_register() – bus attach.
static RA8_INTERNAL void internal_lsm6dso_seed16(lsm6dso_state_t *s, uint8_t reg, uint16_t val)
Perform lsm6dso seed16 for the board periph I2C devices model.
Module-private interfaces shared by the board_periph_i2c TUs.
void priv_i2c_device_register(uint8_t addr_7b, void(*wr)(void *, uint8_t), uint32_t(*rd)(void *, uint8_t *, uint32_t), void(*stop)(void *), void *ctx)
Register a device model in the first free bus slot (drop if full).
@ k_i3c_dev_byte_mask
One-byte mask for register-file lanes.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_lsm6dso_reg_outx_l_g
OUTX_L_G (DS12140 sec 9.29).
@ k_lsm6dso_reg_who_am_i
WHO_AM_I (DS12140 sec 9.11).
User-settable battery state surfaced by the MAX17048 fuel gauge.
bool charging
Charger attached (CRATE positive).
uint8_t soc_pct
State-of-charge percent (0..100).
One ST LSM6DSO IMU device: a flat auto-incrementing register file.
uint8_t regs[k_lsm6dso_reg_file]
Flat register file.
uint16_t reg_ptr
Active register pointer.
uint32_t reads
Register reads answered (report).
bool ptr_set
Start register captured this xfer.
One MAX17048 fuel gauge: a flat big-endian register file + read pointer.
uint16_t reg_ptr
Active register pointer.
uint8_t regs[k_max17048_reg_file]
Flat register file (big-endian).
uint32_t reads
Register reads answered (report).
bool ptr_set
Start register captured this xfer.