ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
46
47#include <stddef.h>
48#include <stdint.h>
49
50#include "ra8_board_ek_ra8d2.h"
51#include "ra8_boot_entry.h"
52#include "ra8_cgc.h"
53#include "ra8_display_pal.h"
55#include "ra8_epaper.h"
56#include "ra8_epd_cal.h"
57#include "ra8_err.h"
58#include "ra8_io_spi_bus.h"
60#include "ra8_isr.h"
61#include "ra8_mstp.h"
62#include "ra8_panel.h"
63#include "ra8_port_constants.h"
64#include "ra8_port_utils.h"
65#include "ra8_spi.h"
66#include "ra8_time.h"
67
68/* ===========================================================================
69 * Compile-time configuration -- typed enums per the no-magic-number rule.
70 * =========================================================================== */
71
82typedef enum : uint16_t {
83 k_ep_panel_w = 128U,
84 k_ep_panel_h = 128U,
85 k_ep_cell = 16U,
86} ep_geom_t;
87
94typedef enum : uint16_t {
95 k_ep_box_x = 48U,
96 k_ep_box_y = 48U,
97 k_ep_box_w = 32U,
98 k_ep_box_h = 32U,
100
107typedef enum : uint16_t {
108 k_ep_white = 0xFFFFU,
109 k_ep_black = 0x0000U,
110} ep_color_t;
111
118typedef enum : uint32_t {
120 k_ep_spi_baud_hz = 10000000U,
121 k_ep_uart_baud = 115200U,
124} ep_bus_t;
125
132typedef enum : uint8_t {
136 k_ep_cr = '\r',
137 k_ep_lf = '\n',
138} ep_fmt_t;
139
156
157/* ===========================================================================
158 * Static storage
159 * =========================================================================== */
160
171[[gnu::aligned(k_ra8_board_fb_align_bytes)]] static uint16_t
173
185
197
199static display_handle_t* s_display = nullptr;
200
204
206static const uint8_t k_ep_msg_pass[] = "epaper: PASS\r\n";
207static const uint8_t k_ep_msg_fail[] = "epaper: FAIL\r\n";
208
222static const uint8_t k_ep_msg_no_vcom[] = "epaper: NO TRUSTED VCOM -- panel left dark\r\n";
223
243typedef enum : uint16_t {
247
248/* ===========================================================================
249 * Pure helpers (mirrored by tests/mocks/src/test_app_epaper_refresh.c)
250 * =========================================================================== */
251
273static uint16_t ep_checker_px(uint16_t x, uint16_t y)
274{
275 const uint32_t cell = (uint32_t)k_ep_cell;
276 const uint32_t sum = ((uint32_t)x / cell) + ((uint32_t)y / cell);
277 return ((sum & 1U) != 0U) ? (uint16_t)k_ep_black : (uint16_t)k_ep_white;
278}
279
308static bool ep_region_fits(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t pw, uint16_t ph)
309{
310 return ((uint32_t)x + (uint32_t)w <= (uint32_t)pw) && ((uint32_t)y + (uint32_t)h <= (uint32_t)ph);
311}
312
332static bool ep_flush_ok(ra8_err_t init_err, ra8_err_t full_err, ra8_err_t part_err)
333{
334 return (init_err == k_ra8_ok) && (full_err == k_ra8_ok) && (part_err == k_ra8_ok);
335}
336
354static uint32_t ep_u32_to_dec(uint8_t* buf, uint32_t val)
355{
356 if (val == 0U) {
357 buf[0] = (uint8_t)'0';
358 return 1U;
359 }
360 uint8_t tmp[k_ep_dec_digits];
361 uint32_t n = 0U;
362 uint32_t v = val;
363 while ((v != 0U) && (n < (uint32_t)k_ep_dec_digits)) {
364 tmp[n] = (uint8_t)('0' + (uint8_t)(v % (uint32_t)k_ep_radix));
365 v = v / (uint32_t)k_ep_radix;
366 n++;
367 }
368 for (uint32_t i = 0U; i < n; i++) {
369 buf[i] = tmp[n - 1U - i];
370 }
371 return n;
372}
373
374/* ===========================================================================
375 * Bring-up + reporting
376 * =========================================================================== */
377
389static void ep_panic_halt(void)
390{
392 while (1) {
393 __asm__ volatile("wfi");
394 }
395}
396
411static void ep_emit(const uint8_t* data, uint32_t len)
412{
413 (void)ra8_board_uart_console_write(data, (size_t)len);
414}
415
429static void ep_bringup_core(uint32_t* out_pclka_hz)
430{
431 uint32_t cpuclk0_hz = 0U;
432 if (ra8_cgc_init() != k_ra8_ok) {
434 }
437 }
438 if (ra8_cgc_get_clock_hz(k_ra8_clock_id_pclka, out_pclka_hz) != k_ra8_ok) {
440 }
441 if (ra8_mstp_init() != k_ra8_ok) {
443 }
444 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
446 }
449 }
452 }
455 }
456}
457
477static void ep_bringup_panel_bus(uint32_t pclka_hz)
478{
481 }
484 }
485
486 const ra8_spi_cfg_t spi_cfg = {
487 .baud_hz = (uint32_t)k_ep_spi_baud_hz,
488 .pclka_hz = pclka_hz,
489 .mode = k_ra8_spi_mode_0,
490 .lsb_first = false,
491 .loopback = false,
492 };
493 if (ra8_spi_init((uint8_t)k_ep_spi_channel, &spi_cfg) != k_ra8_ok) {
495 }
498 }
499
500 ra8_spi_bus_ops_t ops = {};
503 }
504 s_epaper_cfg.bus = ops;
505 s_epaper_cfg.reset_pin = (uint16_t)k_ep_reset_pin;
506 s_epaper_cfg.busy_pin = (uint16_t)k_ep_hrdy_pin;
507 s_epaper_cfg.panel_width = (uint16_t)k_ep_panel_w;
508 s_epaper_cfg.panel_height = (uint16_t)k_ep_panel_h;
509 /* Waveform mode numbers are panel data, not driver data: A2 is mode 4 on
510 * the M641 LUT (6 inch / 6 inch HD) and mode 6 elsewhere. The descriptor
511 * seeds the M641 map so init has a valid one; an app that reaches real
512 * hardware should re-derive it from ``ra8_epaper_dev_info().lut_version``
513 * once the controller has answered GET_DEV_INFO. */
514 if (ra8_epaper_waveform_cfg_for_lut("M641", &s_epaper_cfg.waveform) != k_ra8_ok) {
516 }
517}
518
541static ra8_err_t ep_vcom_get(void* ctx, uint16_t* out_mv)
542{
543 (void)ctx;
544 return ra8_epaper_get_vcom(out_mv);
545}
546
570static ra8_err_t ep_vcom_set(void* ctx, uint16_t mv)
571{
572 (void)ctx;
573 return ra8_epaper_set_vcom(mv);
574}
575
612static bool ep_calibrate_vcom(void)
613{
614 const ra8_epd_cal_cfg_t cal_cfg = {
615 .limits = {.min_mv = (uint16_t)k_ep_vcom_min_mv, .max_mv = (uint16_t)k_ep_vcom_max_mv},
616 .panel = {.get = ep_vcom_get, .set = ep_vcom_set, .ctx = nullptr},
617 .store = {.read = nullptr, .write = nullptr, .ctx = nullptr},
618 .has_provisioned = false,
619 .provisioned_mv = 0U,
620 };
621
622 ra8_epd_cal_result_t cal = {};
623 if (ra8_epd_cal_resolve(&cal_cfg, &cal) != k_ra8_ok) {
624 return false;
625 }
626 return ra8_epd_cal_apply(&cal_cfg, &cal) == k_ra8_ok;
627}
628
640static void ep_paint_checker(void)
641{
642 uint16_t* px = (uint16_t*)s_fb.pixels;
643 for (uint16_t y = 0U; y < s_fb.height_px; ++y) {
644 const uint32_t row = (uint32_t)y * (uint32_t)s_fb.width_px;
645 for (uint16_t x = 0U; x < s_fb.width_px; ++x) {
646 px[row + (uint32_t)x] = ep_checker_px(x, y);
647 }
648 }
649}
650
662static void ep_paint_region_black(void)
663{
664 uint16_t* px = (uint16_t*)s_fb.pixels;
665 const uint16_t y_limit = (uint16_t)((uint16_t)k_ep_box_y + (uint16_t)k_ep_box_h);
666 const uint16_t x_limit = (uint16_t)((uint16_t)k_ep_box_x + (uint16_t)k_ep_box_w);
667 for (uint16_t y = (uint16_t)k_ep_box_y; y < y_limit; ++y) {
668 const uint32_t row = (uint32_t)y * (uint32_t)s_fb.width_px;
669 for (uint16_t x = (uint16_t)k_ep_box_x; x < x_limit; ++x) {
670 px[row + (uint32_t)x] = (uint16_t)k_ep_black;
671 }
672 }
673}
674
690static void ep_report_stage(const char* label, uint32_t dt_ms, uint32_t pixels)
691{
692 static const uint8_t k_prefix[] = "epaper: ";
693 static const uint8_t k_ms_sep[] = " ms=";
694 static const uint8_t k_px_sep[] = " px=";
695 uint8_t line[k_ep_line_max];
696 uint32_t pos = 0U;
697 for (uint32_t i = 0U; i < (sizeof(k_prefix) - 1U); i++) {
698 line[pos++] = k_prefix[i];
699 }
700 for (uint32_t i = 0U; (label[i] != '\0') && (pos < (uint32_t)k_ep_line_max); i++) {
701 line[pos++] = (uint8_t)label[i];
702 }
703 for (uint32_t i = 0U; i < (sizeof(k_ms_sep) - 1U); i++) {
704 line[pos++] = k_ms_sep[i];
705 }
706 pos += ep_u32_to_dec(&line[pos], dt_ms);
707 for (uint32_t i = 0U; i < (sizeof(k_px_sep) - 1U); i++) {
708 line[pos++] = k_px_sep[i];
709 }
710 pos += ep_u32_to_dec(&line[pos], pixels);
711 line[pos++] = (uint8_t)k_ep_cr;
712 line[pos++] = (uint8_t)k_ep_lf;
713 ep_emit(line, pos);
714}
715
727static void ep_report_init(void)
728{
729 static const uint8_t k_prefix[] = "epaper: init ok panel=";
730 uint8_t line[k_ep_line_max];
731 uint32_t pos = 0U;
732 for (uint32_t i = 0U; i < (sizeof(k_prefix) - 1U); i++) {
733 line[pos++] = k_prefix[i];
734 }
735 pos += ep_u32_to_dec(&line[pos], (uint32_t)k_ep_panel_w);
736 line[pos++] = (uint8_t)'x';
737 pos += ep_u32_to_dec(&line[pos], (uint32_t)k_ep_panel_h);
738 line[pos++] = (uint8_t)k_ep_cr;
739 line[pos++] = (uint8_t)k_ep_lf;
740 ep_emit(line, pos);
741}
742
765static void ep_run_refresh_cycle(ra8_err_t* full_err, ra8_err_t* part_err)
766{
767 /* Full refresh: checkerboard + GC16 (quality). */
769 const uint32_t t0_full = ra8_now_ms();
771 ep_report_stage("full-refresh",
772 ra8_now_ms() - t0_full,
773 (uint32_t)k_ep_panel_w * (uint32_t)k_ep_panel_h);
774
775 /* Partial refresh: blacken a sub-rect + A2 (fast), bounds-checked first. */
776 *part_err = k_ra8_err_invalid_arg;
777 if (ep_region_fits((uint16_t)k_ep_box_x,
778 (uint16_t)k_ep_box_y,
779 (uint16_t)k_ep_box_w,
780 (uint16_t)k_ep_box_h,
781 (uint16_t)k_ep_panel_w,
782 (uint16_t)k_ep_panel_h)) {
784 const display_rect_t box = {
785 .x = (uint16_t)k_ep_box_x,
786 .y = (uint16_t)k_ep_box_y,
787 .w = (uint16_t)k_ep_box_w,
788 .h = (uint16_t)k_ep_box_h,
789 };
790 const uint32_t t0_part = ra8_now_ms();
792 ep_report_stage("partial-refresh",
793 ra8_now_ms() - t0_part,
794 (uint32_t)k_ep_box_w * (uint32_t)k_ep_box_h);
795 }
796}
797
809void main(void)
810{
811 uint32_t pclka_hz = 0U;
812 ep_bringup_core(&pclka_hz);
814 ra8_delay_ms((uint32_t)k_ep_powerup_ms);
815 ep_bringup_panel_bus(pclka_hz);
816
817 const display_cfg_t cfg = {
819 .framebuffer = s_framebuffer,
820 .framebuffer_bytes = sizeof(s_framebuffer),
821 .width_px = (uint16_t)k_ep_panel_w,
822 .height_px = (uint16_t)k_ep_panel_h,
823 .pixfmt = k_display_pixfmt_rgb565,
824 .panel_timing = &s_epaper_cfg,
825 };
826
827 const ra8_err_t init_err = display_init(&cfg, &s_display);
828 if ((init_err != k_ra8_ok) || (display_get_caps(s_display, &s_caps) != k_ra8_ok) ||
830 ep_emit(k_ep_msg_fail, (uint32_t)(sizeof(k_ep_msg_fail) - 1U));
832 }
834
835 /* INV-VCOM-1: nothing gets refreshed until this panel's own bias has
836 * been resolved and confirmed. Deliberately a halt with its own banner
837 * rather than a best-effort draw -- a blank screen is a support call,
838 * a DC-biased panel is landfill. The driver would refuse the refresh
839 * anyway; failing here says why. */
840 if (!ep_calibrate_vcom()) {
841 ep_emit(k_ep_msg_no_vcom, (uint32_t)(sizeof(k_ep_msg_no_vcom) - 1U));
843 }
844
847 ep_run_refresh_cycle(&full_err, &part_err);
848
849 (void)display_deinit(s_display); /* sleep the panel */
850
851 if (!ep_flush_ok(init_err, full_err, part_err)) {
852 ep_emit(k_ep_msg_fail, (uint32_t)(sizeof(k_ep_msg_fail) - 1U));
854 }
855 ep_emit(k_ep_msg_pass, (uint32_t)(sizeof(k_ep_msg_pass) - 1U));
856
857 while (1) {
860 }
861}
void main(void)
Secure fallback main entry point.
Definition main.c:37
@ k_ep_uart_baud
Console baud.
Definition main.c:45
static display_handle_t * s_display
Definition main.c:78
static uint16_t s_framebuffer[(size_t) k_panel_height_px *(size_t) k_panel_width_px]
1024x600 RGB565 framebuffer in external SDRAM (GLCDC scans this).
Definition main.c:67
static const uint8_t k_ep_msg_pass[]
PASS / FAIL banners.
Definition main.c:206
ep_bus_t
SPI + UART bring-up parameters.
Definition main.c:118
@ k_ep_spi_baud_hz
10 MHz (<= IT8951 24 MHz ceiling).
Definition main.c:120
@ k_ep_spi_channel
SPI_B channel 0 drives the panel.
Definition main.c:119
@ k_ep_heartbeat_ms
LED heartbeat period after PASS.
Definition main.c:123
@ k_ep_powerup_ms
PLL / panel settle before init.
Definition main.c:122
static void ep_paint_region_black(void)
Blacken the partial-refresh sub-rectangle in the framebuffer.
Definition main.c:662
ep_fmt_t
UART line-formatting constants.
Definition main.c:132
@ k_ep_cr
Ep cr.
Definition main.c:136
@ k_ep_radix
Decimal radix.
Definition main.c:135
@ k_ep_lf
Ep lf.
Definition main.c:137
@ k_ep_line_max
Max chars in one console line.
Definition main.c:133
@ k_ep_dec_digits
Max decimal digits for a uint32_t.
Definition main.c:134
ep_color_t
RGB565 shades used by the test pattern.
Definition main.c:107
@ k_ep_white
Full white (maps to 8bpp 255).
Definition main.c:108
@ k_ep_black
Full black (maps to 8bpp 0).
Definition main.c:109
static bool ep_calibrate_vcom(void)
Resolve this panel's VCOM and programme it, or refuse to draw.
Definition main.c:612
ep_geom_t
Panel + framebuffer geometry.
Definition main.c:82
@ k_ep_panel_w
Panel + framebuffer width (px).
Definition main.c:83
@ k_ep_cell
Checkerboard cell size (px).
Definition main.c:85
@ k_ep_panel_h
Panel + framebuffer height (px).
Definition main.c:84
static ra8_epaper_cfg_t s_epaper_cfg
IT8951 descriptor handed to the e-ink backend via panel_timing.
Definition main.c:196
static const uint8_t k_ep_msg_fail[]
Definition main.c:207
static void ep_panic_halt(void)
Halt forever with the red board LED on.
Definition main.c:389
static uint16_t ep_checker_px(uint16_t x, uint16_t y)
Checkerboard colour for a framebuffer pixel.
Definition main.c:273
static void ep_run_refresh_cycle(ra8_err_t *full_err, ra8_err_t *part_err)
Drive the full (checker/GC16) then partial (box/A2) refresh cycle.
Definition main.c:765
static ra8_err_t ep_vcom_get(void *ctx, uint16_t *out_mv)
ra8_epd_cal read seam bound to the IT8951 VCOM command.
Definition main.c:541
ep_pin_t
IT8951 control GPIOs on the (hypothetical) e-paper carrier.
Definition main.c:152
@ k_ep_hrdy_pin
IT8951 HRDY (P4_01).
Definition main.c:154
@ k_ep_reset_pin
IT8951 /RESET (P4_00).
Definition main.c:153
static display_caps_t s_caps
Cached backend caps + framebuffer descriptor.
Definition main.c:202
static const uint8_t k_ep_msg_no_vcom[]
Banner for the INV-VCOM-1 refusal.
Definition main.c:222
static void ep_emit(const uint8_t *data, uint32_t len)
Emit a NUL-free byte span on the SCI console (best effort).
Definition main.c:411
static void ep_report_init(void)
Print epaper: init ok panel=<w>x<h>.
Definition main.c:727
static ra8_io_spi_bus_t s_spi_bus
ra8_io SPI-bus handle bound to SPI_B channel 0.
Definition main.c:184
static bool ep_flush_ok(ra8_err_t init_err, ra8_err_t full_err, ra8_err_t part_err)
PASS verdict: every stage returned k_ra8_ok.
Definition main.c:332
static void ep_bringup_panel_bus(uint32_t pclka_hz)
Configure the panel GPIOs + SPI bus and fill s_epaper_cfg.
Definition main.c:477
static ra8_err_t ep_vcom_set(void *ctx, uint16_t mv)
ra8_epd_cal write seam bound to the IT8951 VCOM command.
Definition main.c:570
static void ep_report_stage(const char *label, uint32_t dt_ms, uint32_t pixels)
Print epaper: <label> ms=<dt> px=<count> on the console.
Definition main.c:690
static bool ep_region_fits(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t pw, uint16_t ph)
Whether a rectangle (w, h >= 1) fits wholly inside the panel.
Definition main.c:308
ep_region_t
Sub-rectangle updated by the partial refresh.
Definition main.c:94
@ k_ep_box_h
Partial-region height (px).
Definition main.c:98
@ k_ep_box_y
Partial-region top edge (px).
Definition main.c:96
@ k_ep_box_w
Partial-region width (px).
Definition main.c:97
@ k_ep_box_x
Partial-region left edge (px).
Definition main.c:95
ep_vcom_limits_t
The plausible VCOM magnitude window for this panel family.
Definition main.c:243
@ k_ep_vcom_max_mv
Highest plausible magnitude, millivolts.
Definition main.c:245
@ k_ep_vcom_min_mv
Lowest plausible magnitude, millivolts.
Definition main.c:244
static void ep_paint_checker(void)
Paint the whole framebuffer with the checkerboard pattern.
Definition main.c:640
static void ep_bringup_core(uint32_t *out_pclka_hz)
Bring up clocks, MSTP, SysTick, the console and both LEDs.
Definition main.c:429
static display_fb_t s_fb
Definition main.c:203
static uint32_t ep_u32_to_dec(uint8_t *buf, uint32_t val)
Write the decimal digits of val into buf; return the count.
Definition main.c:354
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_led_toggle(ra8_board_led_id_t led)
Toggle led's output state.
ra8_err_t ra8_board_led_init(ra8_board_led_id_t led)
Configure led as a digital output, initial level low (off).
ra8_err_t ra8_board_led_on(ra8_board_led_id_t led)
Drive led HIGH (light it).
@ k_ra8_board_led_blue
Convenience aliases by colour.
@ k_ra8_board_led_red
RA8 board led red.
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
Definition ra8_cgc.c:132
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
Definition ra8_cgc.h:70
@ k_ra8_clock_id_pclka
PCLKA.
Definition ra8_cgc.h:73
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Display Platform Abstraction Layer for the RA8D2.
@ k_display_pixfmt_rgb565
16 bpp, 5/6/5 packed.
ra8_err_t display_get_caps(const display_handle_t *d, display_caps_t *out)
Query the bound backend's runtime capabilities.
display_rect_t display_full_rect(const display_handle_t *d)
Convenience helper returning the rect covering the whole framebuffer.
ra8_err_t display_deinit(const display_handle_t *d)
Release the backend and invalidate the PAL handle.
ra8_err_t display_get_framebuffer(const display_handle_t *d, display_fb_t *out)
Return the framebuffer descriptor the backend is targeting.
ra8_err_t display_flush(const display_handle_t *d, display_rect_t rect, display_refresh_hint_t hint)
Commit pending framebuffer changes to the panel.
struct display_handle display_handle_t
ra8_err_t display_init(const display_cfg_t *cfg, display_handle_t **out_handle)
Initialise the display PAL and bring the selected backend up to a state where display_flush succeeds.
@ k_display_refresh_fast
Prioritise latency.
@ k_display_refresh_quality
Prioritise final quality.
E-ink backend (IT8951) for the display PAL.
const display_backend_iface_t k_display_backend_eink_it8951
E-ink (IT8951) backend vtable.
IT8951 e-paper controller SPI driver – public API.
ra8_err_t ra8_epaper_set_vcom(uint16_t mv)
Programme the controller's VCOM, verify it, and grant the INV-VCOM-1 permit.
Definition ra8_epaper.c:730
ra8_err_t ra8_epaper_get_vcom(uint16_t *out_mv)
Read the controller's current VCOM setting, in millivolts.
Definition ra8_epaper.c:711
ra8_err_t ra8_epaper_waveform_cfg_for_lut(const char *lut_version, ra8_epaper_waveform_cfg_t *out_cfg)
Fill a waveform map from a controller-reported LUT version.
Per-device e-paper panel calibration (VCOM) – record, storage seam, resolution policy.
ra8_err_t ra8_epd_cal_resolve(const ra8_epd_cal_cfg_t *cfg, ra8_epd_cal_result_t *out_result)
Resolve the VCOM to drive this panel at, or fail safe.
ra8_err_t ra8_epd_cal_apply(const ra8_epd_cal_cfg_t *cfg, const ra8_epd_cal_result_t *result)
Programme a resolved VCOM onto the controller and confirm it took.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
ra8_io SPI-bus facade – one controller-transfer vtable over thechip's two SPI implementations.
ra8_err_t ra8_io_spi_bus_as_ops(const ra8_io_spi_bus_t *bus, ra8_spi_bus_ops_t *out)
Expose a bound bus through the Ring-3 seam ra8_spi_bus_ops_t.
SPI_B backend binder for the ra8_io SPI-bus facade.
ra8_err_t ra8_io_spi_bus_bind_spi_b(ra8_io_spi_bus_t *bus, uint8_t channel)
Bind bus to SPI_B channel channel.
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_init(void)
Re-establish the ra8_mstp ref-count table from current hardware state.
Definition ra8_mstp.c:291
Active display-panel descriptor for the EK-RA8D2 (ER-TFT070-6).
@ k_ra8_board_fb_align_bytes
GLCDC AXI burst alignment, in bytes.
Definition ra8_panel.h:108
Typed Port / Pin Constants for the RA8D2 IOPORT Module.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
@ k_ra8_port_4
RA8 port 4.
#define RA8_PIN(port, pin)
Build a ra8_port_pin_t from explicit port / pin indices.
@ k_ra8_level_high
Drive or read 1.
@ k_ra8_pin_1
RA8 pin 1.
@ k_ra8_pin_0
RA8 pin 0.
@ k_ra8_pull_up
Internal pull-up.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_gpio_input_init(ra8_port_pin_t pin, ra8_pin_pull_t pull)
Configure a pin as a digital input.
Definition gpio.c:121
ra8_err_t ra8_gpio_output_init(ra8_port_pin_t pin, ra8_level_t init_level)
Configure a pin as a digital output and drive it to an initial level.
Definition gpio.c:88
SPI_B controller driver (RA8D2 Type-B SPI peripheral).
@ k_ra8_spi_mode_0
CPOL=0, CPHA=0.
Definition ra8_spi.h:62
ra8_err_t ra8_spi_init(uint8_t channel, const ra8_spi_cfg_t *cfg)
Initialise an SPI channel with a full config descriptor.
Definition ra8_spi_b.c:348
SysTick-based tick counter, delay and timestamp helpers.
ra8_err_t ra8_time_init(uint32_t cpu_hz)
Initialise SysTick for a 1 kHz tick interrupt.
Definition ra8_time.c:59
void ra8_delay_ms(uint32_t ms)
Busy-wait for at least ms milliseconds.
Definition ra8_time.c:129
uint32_t ra8_now_ms(void)
Short-form alias for ra8_time_ms().
Definition timer.c:19
Capabilities a backend reports after display_init.
Configuration descriptor passed into display_init.
Framebuffer descriptor returned by display_get_framebuffer.
Rectangle in framebuffer coordinates passed into display_flush.
Configuration descriptor for ra8_epaper_init.
Definition ra8_epaper.h:304
Everything ra8_epd_cal_resolve needs.
Outcome of ra8_epd_cal_resolve.
Caller-allocated SPI-bus handle binding a backend to its context.
Caller-filled SPI transfer seam: one full-duplex byte exchange.
Configuration descriptor for ra8_spi_init.
Definition ra8_spi.h:99