ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_eink.c File Reference

IT8951 e-paper SPI-device model for ra8_emulator. More...

#include "board_periph_eink.h"
#include <stdint.h>
#include <stdio.h>
#include "board_periph.h"
#include "emu_host_io_internal.h"
Include dependency graph for board_periph_eink.c:

Go to the source code of this file.

Data Structures

struct  eink_model_t
 The modelled IT8951 controller's whole state. More...

Enumerations

enum  eink_preamble_t : uint16_t {
  k_eink_pre_cmd = 0x6000U ,
  k_eink_pre_wr = 0x0000U ,
  k_eink_pre_rd = 0x1000U
}
 SPI preamble words (IT8951 DS chapter 3.4 table 3-3). More...
enum  eink_cmd_t : uint16_t {
  k_eink_cmd_sys_run = 0x0001U ,
  k_eink_cmd_sleep = 0x0003U ,
  k_eink_cmd_reg_rd = 0x0010U ,
  k_eink_cmd_reg_wr = 0x0011U ,
  k_eink_cmd_ld_img_area = 0x0021U ,
  k_eink_cmd_ld_img_end = 0x0022U ,
  k_eink_cmd_dpy_area = 0x0034U ,
  k_eink_cmd_vcom = 0x0039U ,
  k_eink_cmd_get_dev_info = 0x0302U
}
 IT8951 user commands the ra8_epaper driver issues (DS chapter 4.2). More...
enum  eink_vcom_arg_t : uint16_t {
  k_eink_vcom_get = 0x0000U ,
  k_eink_vcom_set = 0x0001U
}
 Direction word of the VCOM command (DS user command set). More...
enum  eink_vcom_default_t : uint16_t { k_eink_vcom_power_on_mv = 1530U }
 VCOM the modelled controller powers up holding. More...
enum  eink_reg_t : uint16_t { k_eink_reg_lutafsr = 0x1224U }
 Controller registers whose read value the model must answer. More...
enum  eink_geom_t : uint16_t {
  k_eink_panel_w = 128U ,
  k_eink_panel_h = 128U
}
 Fixed panel geometry the model reports through GET_DEV_INFO. More...
enum  eink_datawr_idx_t : uint16_t {
  k_eink_idx_reg_addr = 0U ,
  k_eink_idx_ld_arg0 = 0U ,
  k_eink_idx_ld_w = 3U ,
  k_eink_idx_ld_h = 4U ,
  k_eink_idx_ld_px_start = 5U ,
  k_eink_idx_dpy_wf = 4U ,
  k_eink_idx_vcom_dir = 0U ,
  k_eink_idx_vcom_val = 1U
}
 Data-word positions within a command's argument stream. More...
enum  eink_wire_pf_t : uint16_t {
  k_eink_wire_pf_2bpp = 0U ,
  k_eink_wire_pf_3bpp = 1U ,
  k_eink_wire_pf_4bpp = 2U ,
  k_eink_wire_pf_8bpp = 3U
}
 LD_IMG_AREA arg0 pixel-format codes. More...
enum  eink_read_idx_t : uint8_t {
  k_eink_rd_dummy_hi = 0U ,
  k_eink_rd_dummy_lo = 1U ,
  k_eink_rd_val_hi = 2U ,
  k_eink_rd_val_lo = 3U
}
 Byte positions in the 4-byte (2-word) read-burst response buffer. More...
enum  eink_sizing_t : uint32_t {
  k_eink_byte_shift = 8U ,
  k_eink_byte_mask = 0xFFU ,
  k_eink_read_bytes = 4U ,
  k_eink_dev_words = 20U ,
  k_eink_word_bits = 16U ,
  k_eink_pf_shift = 4U ,
  k_eink_pf_mask = 0x3U ,
  k_eink_idle_byte = 0x00U
}
 Byte-assembly + read-burst sizing constants (no magic numbers). More...
enum  eink_hrdy_pin_t : uint8_t {
  k_eink_hrdy_port = 4U ,
  k_eink_hrdy_pin = 1U
}
 Panel HRDY "ready" GPIO on the modelled carrier. More...
enum  eink_state_t : uint8_t {
  k_eink_st_preamble = 0U ,
  k_eink_st_cmd = 1U ,
  k_eink_st_datawr = 2U
}
 Host-word interpretation state. More...

Functions

static RA8_INTERNAL uint16_t internal_eink_reg_value (uint16_t reg)
 Read-back value for a controller register.
static RA8_INTERNAL uint16_t internal_eink_dev_info_word (uint16_t idx)
 Word i of the (discarded) GET_DEV_INFO block: W, H, then zeros.
static RA8_INTERNAL uint16_t internal_eink_px_per_word (uint16_t wire_pf)
 Pixels a 16-bit data word carries at the given wire pixel format.
static RA8_INTERNAL void internal_eink_begin_read (void)
 Load rd_buf with [dummy word, value word] and open the read burst.
static RA8_INTERNAL void internal_eink_consume_data (uint16_t word)
 Interpret one data word against the command currently in flight.
static RA8_INTERNAL void internal_eink_consume_word (uint16_t word)
 Advance the state machine by one fully-assembled 16-bit word.
bool board_eink_attach (void)
 Attach (arm) the modelled IT8951 e-paper controller.
bool board_eink_attached (void)
 Report whether the IT8951 controller is currently attached.
uint8_t board_eink_exchange (uint8_t tx)
 Exchange one full-duplex SPI byte with the modelled controller.
void board_eink_reset (void)
 Reset the controller's command / read framing to power-on.
void board_eink_apply_gpio_defaults (void)
 Re-arm the panel HRDY "ready" GPIO input high (if attached).
void board_eink_report (void)
 Print the controller's end-of-run summary line (if attached).

Variables

static eink_model_t s_eink
 The single modelled controller.

Detailed Description

IT8951 e-paper SPI-device model for ra8_emulator.

Implements board_periph_eink.h. The controller is a byte state machine on the SPI_B bus: it assembles the 16-bit words the ra8_epaper driver clocks MSB-first, tracks the current preamble / command / register, and returns the controller's response bytes during a read burst so the driver's GET_DEV_INFO drain and its LUTAFSR "LUT idle" poll complete exactly as they do on silicon (EIL == HIL).

Wire protocol (IT8951 datasheet rev 0.2 chapter 3.4 "SPI Interface" + chapter 4 "Application Note"): every transaction opens with a 16-bit preamble – 0x6000 (command follows), 0x0000 (data write follows) or 0x1000 (data read follows) – then 16-bit words are clocked MSB-first. The driver's read_data16 reads one dummy word then the value word after a read preamble, so each read burst here serves two words (four bytes).

The model is transport-symmetric with board_periph_sd.c: it self-frames off the preamble words (no chip-select wiring needed) and exposes attach / exchange / reset the SPI_B block calls. The panel HRDY "ready" GPIO is driven high from the GPIO block's reset via board_eink_apply_gpio_defaults.

Since
0.1.0

Definition in file board_periph_eink.c.

Enumeration Type Documentation

◆ eink_cmd_t

enum eink_cmd_t : uint16_t

IT8951 user commands the ra8_epaper driver issues (DS chapter 4.2).

Enumerator
k_eink_cmd_sys_run 

Wake from standby.

k_eink_cmd_sleep 

Enter deep-sleep.

k_eink_cmd_reg_rd 

Register read.

k_eink_cmd_reg_wr 

Register write.

k_eink_cmd_ld_img_area 

Begin load (rectangle).

k_eink_cmd_ld_img_end 

End load.

k_eink_cmd_dpy_area 

Refresh rectangle.

k_eink_cmd_vcom 

Get / set VCOM bias.

k_eink_cmd_get_dev_info 

40-byte info block.

Definition at line 52 of file board_periph_eink.c.

◆ eink_datawr_idx_t

enum eink_datawr_idx_t : uint16_t

Data-word positions within a command's argument stream.

Enumerator
k_eink_idx_reg_addr 

REG_RD/REG_WR: register address word.

k_eink_idx_ld_arg0 

LD_IMG_AREA: endian/pf/rotate word.

k_eink_idx_ld_w 

LD_IMG_AREA: width (arg3 after arg0).

k_eink_idx_ld_h 

LD_IMG_AREA: height (arg4 after arg0).

k_eink_idx_ld_px_start 

LD_IMG_AREA: first pixel word.

k_eink_idx_dpy_wf 

DPY_AREA: waveform word (arg4).

k_eink_idx_vcom_dir 

VCOM: direction word (get / set).

k_eink_idx_vcom_val 

VCOM: value word on a set.

Definition at line 115 of file board_periph_eink.c.

◆ eink_geom_t

enum eink_geom_t : uint16_t

Fixed panel geometry the model reports through GET_DEV_INFO.

Informational only – the driver drains and discards the device block – but kept faithful to the demo panel so the emulator report reads sensibly.

Enumerator
k_eink_panel_w 

Reported panel width (priv_px).

k_eink_panel_h 

Reported panel height (priv_px).

Definition at line 106 of file board_periph_eink.c.

◆ eink_hrdy_pin_t

enum eink_hrdy_pin_t : uint8_t

Panel HRDY "ready" GPIO on the modelled carrier.

Must match the epaper_refresh app's busy_pin (P4_01) so the firmware's HRDY poll reads the level this model drives.

Enumerator
k_eink_hrdy_port 

HRDY on PORT4.

k_eink_hrdy_pin 

HRDY on pin 1 (P4_01).

Definition at line 176 of file board_periph_eink.c.

◆ eink_preamble_t

enum eink_preamble_t : uint16_t

SPI preamble words (IT8951 DS chapter 3.4 table 3-3).

Enumerator
k_eink_pre_cmd 

Host -> command write.

k_eink_pre_wr 

Host -> data write.

k_eink_pre_rd 

Host <- data read.

Definition at line 42 of file board_periph_eink.c.

◆ eink_read_idx_t

enum eink_read_idx_t : uint8_t

Byte positions in the 4-byte (2-word) read-burst response buffer.

Enumerator
k_eink_rd_dummy_hi 

High byte of the dummy word.

k_eink_rd_dummy_lo 

Low byte of the dummy word.

k_eink_rd_val_hi 

High byte of the value word.

k_eink_rd_val_lo 

Low byte of the value word.

Definition at line 147 of file board_periph_eink.c.

◆ eink_reg_t

enum eink_reg_t : uint16_t

Controller registers whose read value the model must answer.

Enumerator
k_eink_reg_lutafsr 

LUT busy status: 0 = idle (DS 4.2.4).

Definition at line 94 of file board_periph_eink.c.

◆ eink_sizing_t

enum eink_sizing_t : uint32_t

Byte-assembly + read-burst sizing constants (no magic numbers).

Enumerator
k_eink_byte_shift 

Bits per byte.

k_eink_byte_mask 

Low-byte extraction mask.

k_eink_read_bytes 

Bytes per read burst (dummy + value).

k_eink_dev_words 

GET_DEV_INFO block length (40 / 2).

k_eink_word_bits 

Bits carried by one 16-bit word.

k_eink_pf_shift 

LD_IMG_AREA arg0 pixel-format shift.

k_eink_pf_mask 

LD_IMG_AREA arg0 pixel-format mask.

k_eink_idle_byte 

Non-read response / idle byte.

Definition at line 158 of file board_periph_eink.c.

◆ eink_state_t

enum eink_state_t : uint8_t

Host-word interpretation state.

Enumerator
k_eink_st_preamble 

Next assembled word is a preamble.

k_eink_st_cmd 

Next assembled word is a command.

k_eink_st_datawr 

Next assembled word is data.

Definition at line 185 of file board_periph_eink.c.

◆ eink_vcom_arg_t

enum eink_vcom_arg_t : uint16_t

Direction word of the VCOM command (DS user command set).

Enumerator
k_eink_vcom_get 

Controller answers with its VCOM.

k_eink_vcom_set 

Controller consumes the next word.

Definition at line 68 of file board_periph_eink.c.

◆ eink_vcom_default_t

enum eink_vcom_default_t : uint16_t

VCOM the modelled controller powers up holding.

A vendor-provisioned IT8951 driver board boots with the VCOM its own configuration stores, and the firmware's calibration resolver reads it back as its first-choice source. The model reports a plausible in-range magnitude in millivolts so that path exercises end-to-end in the emulator exactly as it does on silicon (EIL == HIL). This is a modelled controller value, not a calibration default for any real panel – real panels carry their own VCOM printed on the flex cable.

Enumerator
k_eink_vcom_power_on_mv 

Reported VCOM magnitude (mV).

Definition at line 86 of file board_periph_eink.c.

◆ eink_wire_pf_t

enum eink_wire_pf_t : uint16_t

LD_IMG_AREA arg0 pixel-format codes.

The controller numbers its formats 2 bpp = 0, 3 bpp = 1, 4 bpp = 2, 8 bpp = 3. The model decodes the field so its pixel accounting stays correct when the firmware switches depth – at 4 bpp one 16-bit word carries four pixels, not two.

Enumerator
k_eink_wire_pf_2bpp 

2 bits per pixel.

k_eink_wire_pf_3bpp 

3 bits per pixel.

k_eink_wire_pf_4bpp 

4 bits per pixel.

k_eink_wire_pf_8bpp 

8 bits per pixel.

Definition at line 136 of file board_periph_eink.c.

Function Documentation

◆ board_eink_apply_gpio_defaults()

void board_eink_apply_gpio_defaults ( void )

Re-arm the panel HRDY "ready" GPIO input high (if attached).

Drives the modelled HRDY pin high through board_periph_gpio_set_input so the firmware's ra8_gpio_read of the busy line returns "ready". Called from the GPIO/PORT block's power-on reset AFTER it clears every port, so the level survives the reset that would otherwise clear it. A no-op when no controller is attached.

Returns
None.
Precondition
The GPIO/PORT block model is registered.
Called after the GPIO block cleared its ports.
Postcondition
When attached, the HRDY pin reads high.
When not attached, no GPIO state is modified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 452 of file board_periph_eink.c.

References board_periph_gpio_set_input(), k_eink_hrdy_pin, k_eink_hrdy_port, and s_eink.

Referenced by internal_port_reset().

◆ board_eink_attach()

bool board_eink_attach ( void )

Attach (arm) the modelled IT8951 e-paper controller.

Sets the module's armed flag so board_eink_attached returns true and the SPI_B block routes byte exchanges into board_eink_exchange. Idempotent: a second call is a no-op. Panel geometry is the fixed demo size the model reports through GET_DEV_INFO.

Returns
true once the controller is armed and serving.
Return values
trueController armed (always, on this in-memory model).
Precondition
Called once during ra8_emulator start-up (single-threaded arg parse).
No physical hardware is required.
Postcondition
board_eink_attached returns true.
The command / read framing is reset to power-on.
Note
Not thread-safe.
Since
0.1.0

Definition at line 397 of file board_periph_eink.c.

References board_eink_reset(), and s_eink.

Referenced by internal_args_try_mode().

◆ board_eink_attached()

bool board_eink_attached ( void )

Report whether the IT8951 controller is currently attached.

Returns
true if --eink armed the controller.
Return values
falseNo --eink was passed.
true--eink armed the controller.
Precondition
None.
None.
Postcondition
No state is modified.
No state is modified.
Note
Not thread-safe.
Since
0.1.0

Report whether the it8951 controller is currently attached; this step is contained within the board periph eink model and uses bounded caller or module-owned storage.

Definition at line 404 of file board_periph_eink.c.

References s_eink.

Referenced by internal_spi_spdr_write().

◆ board_eink_exchange()

uint8_t board_eink_exchange ( uint8_t tx)

Exchange one full-duplex SPI byte with the modelled controller.

Advances the IT8951 byte state machine: assembles 16-bit words from the host TX stream, latches preambles / commands / register + image data, and returns the controller's response byte during a read burst (0xFF idle otherwise).

Parameters
[in]txByte clocked out by the host (host-out).
Returns
The byte the controller drives back (controller-out).
Return values
0Bus idle / no read byte pending.
Precondition
A controller is attached (board_eink_attached is true).
None.
Postcondition
The model's command / read framing may advance by one byte.
The captured pixel / refresh counters may advance.
Note
Not thread-safe.
Since
0.1.0

Definition at line 409 of file board_periph_eink.c.

References internal_eink_consume_word(), k_eink_byte_shift, k_eink_idle_byte, and s_eink.

Referenced by internal_spi_spdr_write().

◆ board_eink_report()

void board_eink_report ( void )

Print the controller's end-of-run summary line (if attached).

One injected error sink line reporting the pixels loaded and refreshes issued, so a run visibly exercised the image-load + display path. A no-op when no controller is attached.

Returns
None.
Precondition
None.
None.
Postcondition
No model state is modified.
At most one line is written to injected error sink.
Note
Not thread-safe.
Since
0.1.0

Definition at line 460 of file board_periph_eink.c.

References priv_emu_io_errf(), and s_eink.

Referenced by internal_spi_report().

◆ board_eink_reset()

void board_eink_reset ( void )

Reset the controller's command / read framing to power-on.

Clears the in-flight word assembly, current command, register-read target and read cursor; the armed / attached flag is preserved. Called from the SPI_B block's power-on reset (board_periph_spi.c).

Returns
None.
Precondition
None.
None.
Postcondition
The byte state machine is back at "expect preamble".
The attached flag is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 435 of file board_periph_eink.c.

References internal_eink_px_per_word(), k_eink_st_preamble, k_eink_vcom_power_on_mv, k_eink_wire_pf_8bpp, and s_eink.

Referenced by board_eink_attach(), and internal_spi_reset().

◆ internal_eink_begin_read()

RA8_INTERNAL void internal_eink_begin_read ( void )
static

Load rd_buf with [dummy word, value word] and open the read burst.

Load rd_buf with [dummy word, value word] and open the read burst; this step is contained within the board periph eink model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for eink begin read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph eink model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 296 of file board_periph_eink.c.

References internal_eink_dev_info_word(), internal_eink_reg_value(), k_eink_byte_mask, k_eink_byte_shift, k_eink_cmd_get_dev_info, k_eink_cmd_reg_rd, k_eink_cmd_vcom, k_eink_idle_byte, k_eink_rd_dummy_hi, k_eink_rd_dummy_lo, k_eink_rd_val_hi, k_eink_rd_val_lo, k_eink_read_bytes, RA8_INTERNAL, and s_eink.

Referenced by internal_eink_consume_word().

◆ internal_eink_consume_data()

RA8_INTERNAL void internal_eink_consume_data ( uint16_t word)
static

Interpret one data word against the command currently in flight.

Interpret one data word against the command currently in flight; this step is contained within the board periph eink model and uses bounded caller or module-owned storage.

Parameters
[in]wordInstruction or register word processed by the operation.
Precondition
Arguments satisfy the ranges documented for eink consume data.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph eink model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 327 of file board_periph_eink.c.

References internal_eink_px_per_word(), k_eink_cmd_dpy_area, k_eink_cmd_ld_img_area, k_eink_cmd_reg_rd, k_eink_cmd_reg_wr, k_eink_cmd_vcom, k_eink_idx_dpy_wf, k_eink_idx_ld_arg0, k_eink_idx_ld_px_start, k_eink_idx_reg_addr, k_eink_idx_vcom_dir, k_eink_idx_vcom_val, k_eink_pf_mask, k_eink_pf_shift, k_eink_vcom_set, RA8_INTERNAL, and s_eink.

Referenced by internal_eink_consume_word().

◆ internal_eink_consume_word()

RA8_INTERNAL void internal_eink_consume_word ( uint16_t word)
static

Advance the state machine by one fully-assembled 16-bit word.

Advance the state machine by one fully-assembled 16-bit word; this step is contained within the board periph eink model and uses bounded caller or module-owned storage.

Parameters
[in]wordInstruction or register word processed by the operation.
Precondition
Arguments satisfy the ranges documented for eink consume word.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph eink model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 370 of file board_periph_eink.c.

References internal_eink_begin_read(), internal_eink_consume_data(), k_eink_cmd_get_dev_info, k_eink_pre_cmd, k_eink_pre_rd, k_eink_pre_wr, k_eink_st_cmd, k_eink_st_datawr, k_eink_st_preamble, RA8_INTERNAL, and s_eink.

Referenced by board_eink_exchange().

◆ internal_eink_dev_info_word()

RA8_INTERNAL uint16_t internal_eink_dev_info_word ( uint16_t idx)
static

Word i of the (discarded) GET_DEV_INFO block: W, H, then zeros.

Word i of the (discarded) get_dev_info block: w, h, then zeros; this step is contained within the board periph eink model and uses bounded caller or module-owned storage.

Parameters
[in]idxBounded index of the selected entry.
Returns
The eink dev info word result produced by the board periph eink model.
Return values
valueThe operation-specific eink dev info word value.
Precondition
Arguments satisfy the ranges documented for eink dev info word.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph eink model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 252 of file board_periph_eink.c.

References k_eink_panel_h, k_eink_panel_w, and RA8_INTERNAL.

Referenced by internal_eink_begin_read().

◆ internal_eink_px_per_word()

RA8_INTERNAL uint16_t internal_eink_px_per_word ( uint16_t wire_pf)
static

Pixels a 16-bit data word carries at the given wire pixel format.

Pixels a 16-bit data word carries at the given wire pixel format; this step is contained within the board periph eink model and uses bounded caller or module-owned storage.

Parameters
[in]wire_pfWire pf input used by the operation.
Returns
The eink px per word result produced by the board periph eink model.
Return values
valueThe operation-specific eink px per word value.
Precondition
Arguments satisfy the ranges documented for eink px per word.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph eink model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 274 of file board_periph_eink.c.

References k_eink_wire_pf_2bpp, k_eink_wire_pf_3bpp, k_eink_wire_pf_4bpp, k_eink_word_bits, and RA8_INTERNAL.

Referenced by board_eink_reset(), and internal_eink_consume_data().

◆ internal_eink_reg_value()

RA8_INTERNAL uint16_t internal_eink_reg_value ( uint16_t reg)
static

Read-back value for a controller register.

The only register the driver reads is LUTAFSR, which must read 0 ("no LUT busy") so the display poll completes; every other read is 0 too.

Parameters
[in]regRegister address the driver selected.
Returns
The 16-bit register value (0 for LUTAFSR / anything else).
Return values
valueThe operation-specific eink reg value value.
Precondition
Arguments satisfy the ranges documented for eink reg value.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph eink model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 233 of file board_periph_eink.c.

References k_eink_reg_lutafsr, and RA8_INTERNAL.

Referenced by internal_eink_begin_read().

Variable Documentation

◆ s_eink