ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_board_ek_ra8d2_comms.c
Go to the documentation of this file.
1
25
26#include <stddef.h>
27#include <stdint.h>
28
29#include "ra8_attributes.h"
30#include "ra8_board_ek_ra8d2.h"
32#include "ra8_cgc.h"
33#include "ra8_err.h"
34#include "ra8_gpio_constants.h"
35#include "ra8_mipi_dsi.h"
36#include "ra8_mipi_phy.h"
37#include "ra8_port_constants.h"
38#include "ra8_port_utils.h"
39#include "ra8_sci.h"
40#include "ra8_time_constants.h"
41
59{
60 if (out_rates == nullptr) {
62 }
63 const ra8_err_t err = ra8_cgc_init();
64 if (err != k_ra8_ok) {
65 return err;
66 }
67 *out_rates = (ra8_board_clock_rates_t){
68 .cpuclk0_hz = (uint32_t)k_ra8_cpuclk0_hz,
69 .pclka_hz = (uint32_t)k_ra8_pclka_hz,
70 };
71 return k_ra8_ok;
72}
73
74/* =============================================================================
75 * 10. MIPI-DSI panel bring-up (J32 -- Renesas RTKMIPILCDB00000BE mezzanine)
76 * =============================================================================
77 */
78
97
114 .lane_count = k_ra8_mipi_dsi_lanes_2,
116 .max_return_packet_size = 16U,
117 .ulps_wakeup_period = 0U,
118 .ecc_check_enable = true,
119 .eotp_enable = true,
120 .scramble_enable = false,
121 .tearing_detect_enable = true,
122 .crc_check_vc_mask = 0x01U, /* VC0 only -- the only VC J32 wires up. */
123 .timing = {}, /* TODO(panel-datasheet). */
124 .timeouts = {}, /* TODO(panel-datasheet). */
125};
126
140 .tinit = 1U,
141};
142
157 .pclka_mhz = k_panel_pclka_mhz,
158 .line_rate_mbps = (uint16_t)k_ra8_board_mipi_panel_line_rate_mbps,
159 .lane_count = k_ra8_mipi_phy_lane_count_2,
162 .pll =
163 {
164 .idiv = k_ra8_mipi_phy_idiv_1,
165 .pmul = k_ra8_mipi_phy_pmul_4,
167 .nmul_int = k_panel_pll_nmul, /* TODO(panel-datasheet). */
168 },
169 .escdiv = 0U,
171};
172
174{
175 /* Step 1: PHY first -- HUM Ch 64.3.1 startup procedure. The HAL warns
176 * "The MIPI PHY (HUM Ch 64) must be brought up first" before the DSI
177 * host can clock its LP/HS lanes. */
179 if (err != k_ra8_ok) {
180 return err;
181 }
182
183 /* Step 2: DSI host link layer (HUM Ch 65). Programmes TXSETR / DSISETR
184 * / guard-band timing / timeouts -- but does NOT start the HS clock
185 * yet, so the application can splice in the panel-side reset pulse on
186 * k_ra8_board_mipi_dsi_reset_n (P606) and backlight enable on
187 * k_ra8_board_mipi_dsi_backlight (P514) between init and clock start. */
189 if (err != k_ra8_ok) {
190 return err;
191 }
192
193 /* Step 3: kick the differential HS clock. After this returns the link
194 * is HS-ready; callers can replay the panel DCS init stream via
195 * ra8_mipi_dsi_send_command() and finally call ra8_mipi_dsi_video_start.
196 *
197 * TODO(panel-datasheet): the per-panel DCS command sequence (sleep-out,
198 * pixel-format set, display-on, etc.) for the Focus E45RA-MW276-C is
199 * not committed here -- the application currently owns it. */
201}
202
203/* =============================================================================
204 * 11. J-Link OB VCOM serial bridge (UM Table 13, page 24)
205 * =============================================================================
206 */
207
217static bool s_uart_console_initialized = false;
218
235typedef enum : uint32_t {
237 16000000UL,
239
241{
242 if (baud == 0U) {
244 }
245
246 /* SCI8's baud generator is fed by PCLKA on RA8D2 (chip HUM Ch 38.2
247 * "SCI registers"). Hardcoding a constant here was the bug behind
248 * every garbled UART symptom on apps that retune CGC: the BRR was
249 * being computed for an assumed 60 MHz against a real 125 MHz clock,
250 * so the line rate came out 2x too fast. Read PCLKA from CGC at
251 * runtime instead so the BRR tracks whatever the application's CGC
252 * tree settled on. */
253 uint32_t pclka_hz = 0U;
255 if (err != k_ra8_ok) {
256 /* ra8_cgc_get_clock_hz with a valid clock-id and non-null out always returns k_ra8_ok. */
257 return err; /* GCOVR_EXCL_LINE -- fixed PCLKA id and nonnull local satisfy get_clock_hz's only guards */
258 }
259 if (pclka_hz < (uint32_t)k_ra8_board_uart_console_min_pclka_hz) {
261 }
262
263 /* Route PD02 -> TXD8, PD03 -> RXD8 (UM Table 13 p 24). PSEL value
264 * k_ra8_psel_sci_async = 0x04 covers SCI async TXD/RXD per the chip
265 * HUM Multiplexed Pin Function Selector. */
268 "ra8_board.uart.console.txd");
269 if (err != k_ra8_ok) {
270 return err;
271 }
274 "ra8_board.uart.console.rxd");
275 if (err != k_ra8_ok) {
276 return err;
277 }
278
279 const ra8_sci_cfg_t cfg = {
280 .baud = baud,
281 .data_bits = k_ra8_sci_data_8,
282 .parity = k_ra8_sci_parity_none,
283 .stop_bits = k_ra8_sci_stop_1,
284 .pclk_hz = pclka_hz,
285 };
287 if (err != k_ra8_ok) {
288 return err;
289 }
291 return k_ra8_ok;
292}
293
294ra8_err_t ra8_board_uart_console_write(const uint8_t* data, size_t len)
295{
296 if (len == 0U) {
297 return k_ra8_ok;
298 }
299 if (data == nullptr) {
301 }
304 }
305 return ra8_sci_write_polling((uint8_t)k_ra8_board_uart_console_sci_channel, data, (uint32_t)len);
306}
307
308ra8_err_t ra8_board_uart_console_read(uint8_t* out, size_t cap, size_t* out_len)
309{
310 if (out_len == nullptr) {
312 }
313 *out_len = 0U;
314 if (cap == 0U) {
315 return k_ra8_ok;
316 }
317 if (out == nullptr) {
319 }
322 }
323
324 /* Polled non-blocking drain: pull bytes while RDRF stays set, stop
325 * the moment ra8_sci_getc_polling reports nothing available. The cap
326 * bounds the loop (NASA Rule 2). */
327 for (size_t i = 0U; i < cap; ++i) {
328 uint8_t byte = 0U;
329 const ra8_err_t err =
331 if (err != k_ra8_ok) {
332 /* No byte available yet -- treat as a non-blocking stop. */
333 return k_ra8_ok;
334 }
335 out[i] = byte;
336 *out_len += 1U;
337 }
338 return k_ra8_ok;
339}
340
347
349{
352 }
353 /* HUM Ch 38.2.17 "CSR : Common Status Register", p 2225 -- defer to
354 * ra8_sci_flush which spins on CSR.TEND for the SCI8 channel that
355 * backs this console. Lets panic_halt() drain the failure log before
356 * WFI gates the SCI clock. */
358}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
static const ra8_mipi_phy_timing_t s_mipi_phy_timing_placeholder
Placeholder D-PHY HS/LP transition timing block.
ra8_err_t ra8_board_uart_console_read(uint8_t *out, size_t cap, size_t *out_len)
Polled non-blocking read from the J-Link OB VCOM console.
bool priv_ra8_board_uart_console_is_up(void)
Implementation of priv_ra8_board_uart_console_is_up() – reads the same flag the write / read / flush ...
ra8_err_t ra8_board_clocks_init(ra8_board_clock_rates_t *out_rates)
Initialize the board-standard PLL1 clock tree and publish its rates.
ra8_board_uart_console_clock_t
Minimum SCI module operating clock accepted by the console init.
@ k_ra8_board_uart_console_min_pclka_hz
RA8 board UART console minimum pclka Hz.
static const ra8_mipi_phy_config_t s_mipi_phy_cfg
MIPI D-PHY config for the J32 mezzanine.
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_mipi_dsi_init(void)
Bring the MIPI-DSI link up (PHY + DSI controller).
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
ra8_err_t ra8_board_uart_console_flush(void)
Block until every byte queued on the J-Link OB VCOM console has finished clocking out on the wire.
ra8_board_mipi_panel_geometry_t
Static placeholder geometry + line rate for the J32 panel.
@ k_ra8_board_mipi_panel_v_active
RA8 board mipi panel v active.
@ k_ra8_board_mipi_panel_line_rate_mbps
RA8 board mipi panel line rate mbps.
@ k_ra8_board_mipi_panel_h_active
RA8 board mipi panel h active.
static bool s_uart_console_initialized
Tracks whether ra8_board_uart_console_init has succeeded.
static const ra8_mipi_dsi_config_t s_mipi_panel_cfg
MIPI DSI host link-layer config for the J32 mezzanine.
Cross-translation-unit seam for the EK-RA8D2 BSP implementation.
@ k_panel_pll_nmul
PLL integer multiplier.
@ k_panel_pclka_mhz
PCLKA assumed CGC reset default.
@ k_ra8_board_uart_console_pin_txd
PD02 TXD.
@ k_ra8_board_uart_console_pin_rxd
PD03 RXD.
@ k_ra8_board_uart_console_sci_channel
PD02/PD03 -> SCI8 (verified on real EK-RA8D2 v1 silicon).
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_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
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
Definition ra8_err.h:235
@ 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
PSEL codes for peripheral pin routing on the RA8D2.
@ k_ra8_psel_sci_async
00100b: SCI async serial (UART).
MIPI DSI-2 host driver – public API (full HUM Ch 65 surface).
ra8_err_t ra8_mipi_dsi_hs_clock_start(void)
Start the high-speed differential clock to the panel.
ra8_err_t ra8_mipi_dsi_init(const ra8_mipi_dsi_config_t *cfg)
Bring up the MIPI DSI host link layer.
@ k_ra8_mipi_dsi_clock_non_continuous
HS clock idles in LP.
@ k_ra8_mipi_dsi_lanes_2
2 data lanes + 1 clock lane.
MIPI D-PHY driver – physical layer shared by DSI and CSI.
ra8_err_t ra8_mipi_phy_init(const ra8_mipi_phy_config_t *cfg)
Bring up the D-PHY end-to-end per HUM Ch 64.3.1 p 3837.
@ k_ra8_mipi_phy_idiv_1
IDIV = 1 (no division).
@ k_ra8_mipi_phy_lane_count_2
2 data lanes (silicon maximum).
@ k_ra8_mipi_phy_mode_dsi_host
Host mode used by MIPI DSI.
@ k_ra8_mipi_phy_nfmul_0_00
NF = 0.00.
@ k_ra8_mipi_phy_clk_noncontinuous
Drop to LP-11 between bursts.
@ k_ra8_mipi_phy_pmul_4
P = 1/4 (240.
@ k_ra8_mipi_phy_eotp_enabled
Append EoTP packet.
Typed Port / Pin Constants for the RA8D2 IOPORT Module.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_pfs_route_peripheral(ra8_port_pin_t pin, ra8_psel_t psel, const char *owner)
Route a pin to a non-IRQ peripheral function via PFS.PSEL.
Definition gpio.c:238
Full-featured Serial Communications Interface driver.
ra8_err_t ra8_sci_write_polling(uint8_t channel, const uint8_t *data, uint32_t len)
Send len bytes by polling (convenience wrapper).
Definition ra8_sci.c:516
@ k_ra8_sci_stop_1
RA8 SCI stop 1.
Definition ra8_sci.h:81
@ k_ra8_sci_parity_none
RA8 SCI parity none.
Definition ra8_sci.h:71
ra8_err_t ra8_sci_init(uint8_t channel, const ra8_sci_cfg_t *cfg)
Initialise an SCI channel using the descriptor.
Definition ra8_sci.c:410
ra8_err_t ra8_sci_getc_polling(uint8_t channel, uint8_t *out_byte)
Poll-receive one byte (blocking, bounded spin).
Definition ra8_sci.c:496
@ k_ra8_sci_data_8
RA8 SCI data 8.
Definition ra8_sci.h:91
ra8_err_t ra8_sci_flush(uint8_t channel)
Block until the channel's transmit shift register is empty.
Definition ra8_sci.c:543
Named Time Unit Constants for Delay / Timeout / Tick Math.
@ k_ra8_pclka_hz
PCLKA = PLL1P/8 = 125 MHz.
@ k_ra8_cpuclk0_hz
CPUCLK0 = PLL1P/1 = 1 GHz.
Clock rates published by the standard EK-RA8D2 bring-up.
Static configuration passed to ra8_mipi_dsi_init.
Top-level configuration for ra8_mipi_phy_init.
D-PHY HS/LP transition timing values (DPHYTIM1..6).
Configuration descriptor for ra8_sci_init.
Definition ra8_sci.h:103