ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_xspi.c
Go to the documentation of this file.
1
55
56#include "ra8_xspi.h"
57
58#include <stdint.h>
59
60#include "ra8_attributes.h"
61#include "ra8_check.h"
62#include "ra8_err.h"
63#include "ra8_hw_err.h"
64#include "ra8_log.h"
65#include "ra8_mstp.h"
66#include "ra8_ospi_regs.h"
68#include "ra8_system_regs.h"
69#include "ra8_xspi_internal.h"
70
72static const char* s_tag = "XSPI";
73
78typedef enum : uint8_t {
81
100typedef enum : uint8_t {
103
118typedef enum : uint32_t {
121
132
158static ra8_err_t internal_wait_octacksrdy(uint8_t expected)
159{
160 /* SRDY (clock-source ready) is bit 7 of OCTACKCR. */
161 /* HUM Ch 9.2.45 "OCTACKCR.OCTACKSRDY" p 360 */
162 volatile const uint8_t* const ckcr = ra8_sys_octackcr();
163 const uint8_t mask = (uint8_t)(1U << k_ra8_usbckcr_bit_srdy);
164 /* Bounded wait through ra8_hw_err.h: on host tests the ra8_fake_mmio
165 * seam decides the poll (first-poll success unless a test arms a
166 * fault), so the real timeout leg is reachable everywhere. */
167 if (expected != 0U) {
168 return ra8_hw_wait_flag_set8(ckcr, mask, (uint32_t)k_ra8_xspi_ckcr_spin);
169 }
170 return ra8_hw_wait_flag_clear8(ckcr, mask, (uint32_t)k_ra8_xspi_ckcr_spin);
171}
172
226{
227 static bool s_xspi_clock_inited = false;
228 if (s_xspi_clock_inited) {
229 return k_ra8_ok;
230 }
231 ra8_err_t err = k_ra8_ok;
233 {
234 /* HUM Ch 9.2.40 "OCTACKDIVCR" p 357 -- /1 keeps MOCO at its
235 * native rate (~8 MHz nominal). The IS25LX512M JEDEC bring-up
236 * runs comfortably below 50 MHz so /1 is conservative. */
237 *ra8_sys_octackdivcr() = 0U;
238
239 /* HUM Ch 9.2.45 "OCTACKCR.OCTACKSREQ" p 360 -- assert SREQ with
240 * the reset-default source (MOCO, OCTACKSEL = 0001b). */
241 const uint8_t sreq_mask = (uint8_t)(1U << k_ra8_usbckcr_bit_sreq);
242 const uint8_t src_moco = 0x01U;
243 *ra8_sys_octackcr() = (uint8_t)(src_moco | sreq_mask);
244
245 /* Step 3: wait for SRDY = 1 (chip acknowledges the request). */
246 err = internal_wait_octacksrdy(1U);
247 if (err != k_ra8_ok) {
248 ra8_log_error(s_tag, "xspi: OCTACKSRDY=1 timeout");
249 break;
250 }
251 /* Step 4: drop SREQ -- commits the (same) source selection. */
252 *ra8_sys_octackcr() = src_moco;
253 /* Step 5: wait for SRDY = 0 -- handshake done. */
254 err = internal_wait_octacksrdy(0U);
255 if (err != k_ra8_ok) {
256 ra8_log_error(s_tag, "xspi: OCTACKSRDY=0 timeout");
257 break;
258 }
259 }
260 if (err == k_ra8_ok) {
261 s_xspi_clock_inited = true;
262 ra8_log_info(s_tag, "octa block clock stable");
263 }
264 return err;
265}
266
287{
288 for (volatile uint32_t i = 0U; i < (uint32_t)k_ra8_xspi_reset_spin; i++) {
289 /* spin */
290 }
291}
292
319{
320 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
321 /* WPCS held high (write-protect deasserted) the whole time; only
322 * RSTCS toggles. */
323 reg->LIOCTL = k_ra8_xspi_lioctl_mask_wpcs; /* RSTCS = 0 (asserted, reset) */
327}
328
359{
360 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
361 reg->BMCTL0 = (uint32_t)k_ra8_xspi_bmctl0_disabled;
362 reg->CMCTLCH[0] = 0U;
363 reg->CMCTLCH[1] = 0U;
364 reg->WRAPCFG = 0U;
365 reg->COMCFG = 0U;
366 reg->LIOCFGCS[k_ra8_xspi_onboard_cs] = (uint32_t)mode;
367 reg->CDCTL0 =
370}
371
373{
374 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
375 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
376 if (instance >= (uint8_t)(sizeof(s_xspi_mstp_table) / sizeof(s_xspi_mstp_table[0]))) {
378 }
379
380 /* HUM Ch 11.2.7 "MSTPCRB" Note 3 p 444 -- MSTPB16/17 must be written
381 * AFTER OCTACLK is stable. Run the block-level OCTACKCR handshake
382 * first; the helper is idempotent so a second ra8_xspi_init call
383 * (e.g. for instance 1) skips it. */
385 if (clk_err != k_ra8_ok) {
386 return clk_err;
387 }
388
389 /* HUM Ch 11.2.7 "MSTPCRB : Module Stop Control Register B", p 444 */
390 const ra8_err_t mst_err = ra8_mstp_enable(s_xspi_mstp_table[instance]);
391 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
392 RA8_RETURN_ON_ERROR(mst_err, s_tag, "xspi_init: mstp enable");
393 /* GCOVR_EXCL_BR_STOP */
394
397
398 ra8_log_info_val(s_tag, "xspi_init inst", (uint32_t)instance);
399 return k_ra8_ok;
400}
401
402ra8_err_t ra8_xspi_direct_command(uint8_t instance, const uint8_t* cmd_buf, uint8_t len)
403{
404 RA8_CHECK_NULL_PTR(cmd_buf, s_tag, "cmd_buf must not be nullptr");
405 if (len > k_ra8_xspi_cmd_max_bytes) {
407 }
408 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
409 if (reg == nullptr) {
411 }
412
413 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
414 /* Pack the caller's bytes into CDBUF slot 0 as little-endian
415 * words. Slot 0 is the full 16-byte CDBUF window (4 u32), so
416 * raw callers can use any of the four indices. */
417 uint32_t word = 0U;
418 for (uint8_t i = 0U; i < len; i++) {
419 word |= ((uint32_t)cmd_buf[i]) << ((i % 4U) * 8U);
420 if ((i % 4U) == 3U) {
421 reg->CDBUF[i / 4U] = word;
422 word = 0U;
423 }
424 }
425 if ((len % 4U) != 0U) {
426 reg->CDBUF[len / 4U] = word;
427 }
428
429 return k_ra8_ok;
430}
431
432/* =============================================================================
433 * lifecycle + IRQ + power transition
434 * =============================================================================
435 */
436
441typedef struct {
443 void* ctx;
445
448
449ra8_err_t ra8_xspi_deinit(uint8_t instance)
450{
451 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
452 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
453
454 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
455 reg->LIOCFGCS[0] = 0U;
456 reg->INTE = 0U;
458
459 s_xspi_state[instance].fn = nullptr;
460 s_xspi_state[instance].ctx = nullptr;
461 return ra8_mstp_disable(s_xspi_mstp_table[instance]);
462}
463
464ra8_err_t ra8_xspi_get_status(uint8_t instance, uint32_t* out_mask)
465{
466 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
467 volatile const r_xspi_regs_t* reg = ra8_xspi(instance);
468 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
469 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
470 *out_mask = reg->COMSTT;
471 return k_ra8_ok;
472}
473
474ra8_err_t ra8_xspi_clear_status(uint8_t instance, uint32_t mask)
475{
476 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
477 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
478 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
479 reg->INTC = mask;
480 return k_ra8_ok;
481}
482
484{
485 if (instance >= k_ra8_xspi_instance_count) {
487 }
488 s_xspi_state[instance].fn = fn;
489 s_xspi_state[instance].ctx = ctx;
490 return k_ra8_ok;
491}
492
494void ra8_xspi_dispatch(uint8_t instance)
495{
496 if (instance >= k_ra8_xspi_instance_count) {
497 return;
498 }
499 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
500 if (reg == nullptr) { /* GCOVR_EXCL_BR_LINE -- instance bounded above */
501 return; /* GCOVR_EXCL_LINE -- MSTP fail is HW-only */
502 }
503 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
504 /* Snapshot INTS + COMSTT, clear every pending interrupt flag,
505 * then hand the INTS mask off to the user callback so it can
506 * decide whether the transfer was successful or errored. */
507 const uint32_t mask = reg->INTS;
509
510 const ra8_xspi_event_fn_t fn = s_xspi_state[instance].fn;
511 void* const ctx = s_xspi_state[instance].ctx;
512 if (fn != nullptr) {
513 fn(ctx, mask);
514 }
515}
516
518{
519 if (instance >= k_ra8_xspi_instance_count) {
521 }
522 return ra8_mstp_disable(s_xspi_mstp_table[instance]);
523}
524
526{
527 if (instance >= k_ra8_xspi_instance_count) {
529 }
530 return ra8_mstp_enable(s_xspi_mstp_table[instance]);
531}
532
533ra8_err_t ra8_xspi_xip_enter(uint8_t instance, uint8_t enter_code, uint8_t exit_code)
534{
535 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
536 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
537
538 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
539 /* FSP r_ospi_b_xip(true) flow:
540 * 1. Stage XIP enter/exit codes in CMCTLCH for both channels.
541 * 2. Map the target window read-only via BMCTL0 = 0x55.
542 * 3. Set CMCTLCH.XIPEN to arm execute-in-place.
543 * The first read on the memory-mapped window then transmits the
544 * enter code. We omit the bus-bridge prefetch dance because the
545 * driver does not enable prefetch by default. */
546 const uint32_t code_word = ((uint32_t)enter_code << k_ra8_xspi_cmctlch_xipencode_pos) |
547 ((uint32_t)exit_code << k_ra8_xspi_cmctlch_xipexcode_pos);
548
550 reg->CMCTLCH[0] = code_word | k_ra8_xspi_cmctlch_xipen_mask;
551 reg->CMCTLCH[1] = code_word | k_ra8_xspi_cmctlch_xipen_mask;
552 return k_ra8_ok;
553}
554
556{
557 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
558 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
559
560 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
561 /* FSP r_ospi_b_xip(false) flow: clear XIPEN, drop the codes,
562 * and put BMCTL0 back to read/write so direct-command transfers
563 * are no longer blocked by the memory-mapped path. */
564 reg->CMCTLCH[0] = 0U;
565 reg->CMCTLCH[1] = 0U;
567 return k_ra8_ok;
568}
569
570/* =============================================================================
571 * Sweep 6 extensions: XIP mode select, DTR, DQS calibration, suspend/resume
572 * =============================================================================
573 */
574
585
599
608
613typedef enum : uint32_t {
616
617ra8_err_t ra8_xspi_set_xip_mode(uint8_t instance, bool enable, uint8_t read_cmd, uint8_t addr_bytes)
618{
619 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
620 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
621 if ((addr_bytes != k_ra8_xspi_addr_bytes_3) && (addr_bytes != k_ra8_xspi_addr_bytes_4)) {
623 }
624
625 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
626 /* CMCFGCS slot 0 = (mode, read-cmd-word, write-cmd-word, addr-word).
627 * For XIP we only need read + addr; write opcode stays zero. */
628 const uint8_t base = 0U; /* slot 0 base index */
629 reg->CMCFGCS[base + k_ra8_xspi_cmcfgcs_word_read_cmd] = (uint32_t)read_cmd
631 reg->CMCFGCS[base + k_ra8_xspi_cmcfgcs_word_addr] = (uint32_t)addr_bytes
633
634 if (enable) {
635 /* Mirror FSP r_ospi_b_xip(true): map read-only and arm XIPEN. */
639 } else {
640 /* FSP r_ospi_b_xip(false): clear XIPEN and re-open the bus. */
641 reg->CMCTLCH[0] = 0U;
642 reg->CMCTLCH[1] = 0U;
644 }
645 return k_ra8_ok;
646}
647
648ra8_err_t ra8_xspi_set_dtr_mode(uint8_t instance, bool enable)
649{
650 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
651 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
652
653 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
654 uint32_t v = reg->LIOCFGCS[0];
655 if (enable) {
657 } else {
659 }
660 reg->LIOCFGCS[0] = v;
661 return k_ra8_ok;
662}
663
665{
666 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
667 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
668
669 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
670 /* Mirror FSP R_OSPI_B_AutoCalibrate: arm CAEN and wait for the
671 * controller to clear it once the phase-scan completes. The full
672 * preamble-pattern + CARDCMD descriptor is owned by board-level
673 * code in higher-level callers. On host tests the bounded wait
674 * consults the ra8_fake_mmio seam (first-poll success unless a test
675 * arms a fault); the CAEN bit itself stays set in host RAM because
676 * only the real controller clears it. */
678 return ra8_hw_wait_flag_clear32(&reg->CCCTLCS[0],
680 (uint32_t)k_ra8_xspi_calib_spin);
681}
682
684{
685 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
686 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
688}
689
690ra8_err_t ra8_xspi_resume(uint8_t instance)
691{
692 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
693 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
695}
696
728static ra8_err_t
729internal_issue_reset_opcode(volatile r_xspi_regs_t* reg, uint8_t opcode, uint8_t cmd_bytes)
730{
731 /* HUM Ch 44 "Octal Serial Peripheral Interface (OSPI)" p 2986 */
732 /* Build the CMD half-word for either 1S (just the opcode) or 8D
733 * (opcode + complement). The complement form is what 8D-mode SPI
734 * NOR devices require so they can distinguish "real opcode" from
735 * "garbage on the bus". */
736 /* CMD is transmitted MSB-first from CDT[31:16]; a 1-byte opcode must
737 * be left-justified to CDT[31:24] (cmd_word << 8), a 2-byte 8D pair
738 * fills the full [31:16] field. Same rule as internal_make_cdt. */
739 uint16_t cmd_word = (uint16_t)(opcode << 8U);
740 if (cmd_bytes == (uint8_t)k_ra8_xspi_reset_cmd_bytes_8d) {
741 cmd_word = (uint16_t)(opcode | (((uint16_t)(uint8_t)~opcode) << 8U));
742 }
744 (((uint32_t)cmd_bytes & k_ra8_xspi_cdt_mask_cmdsize) << k_ra8_xspi_cdt_pos_cmdsize) |
749 (((uint32_t)cmd_word) << k_ra8_xspi_cdt_pos_cmd);
753 return priv_ra8_xspi_kick_command(reg);
754}
755
756ra8_err_t ra8_xspi_software_reset(uint8_t instance, uint8_t cmd_bytes)
757{
758 volatile r_xspi_regs_t* reg = ra8_xspi(instance);
759 RA8_CHECK_NULL_PTR(reg, s_tag, "instance out of range");
760 if ((cmd_bytes != (uint8_t)k_ra8_xspi_reset_cmd_bytes_1s) &&
761 (cmd_bytes != (uint8_t)k_ra8_xspi_reset_cmd_bytes_8d)) {
763 }
764
765 /* IS25LX512M Ch 8.20-8.21 p 39: RSTEN must be the immediately
766 * preceding command before RST or the device ignores RST. */
768 if (en != k_ra8_ok) {
769 return en;
770 }
772 if (rst != k_ra8_ok) {
773 return rst;
774 }
775 return k_ra8_ok;
776}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ 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
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Bounded wait-flag primitives for RA8D2 HAL drivers.
static ra8_err_t ra8_hw_wait_flag_clear8(volatile const uint8_t *reg, uint8_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Definition ra8_hw_err.h:262
static ra8_err_t ra8_hw_wait_flag_set8(volatile const uint8_t *reg, uint8_t mask, uint32_t budget)
Spin until (*reg & mask) != 0 or budget runs out.
Definition ra8_hw_err.h:219
static ra8_err_t ra8_hw_wait_flag_clear32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Definition ra8_hw_err.h:351
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_ospi0
MSTPB16 OSPI0+DOTF0.
@ k_ra8_mstp_ospi1
MSTPB17 OSPI1+DOTF1.
xSPI / Octo-SPI controller register layout for the Renesas RA8D2
@ k_ra8_xspi_cdt_trtype_write
Write transaction (host drives).
@ k_ra8_xspi_cmctlch_xipencode_pos
XIPENCODE[7..0] enter.
@ k_ra8_xspi_cmctlch_xipexcode_pos
XIPEXCODE[15..8] exit.
@ k_ra8_xspi_cmctlch_xipen_mask
XIPEN[16] enable.
@ k_ra8_xspi_ints_mask_all
Clear every pending flag.
@ k_ra8_xspi_cdt_addsize_0
No address phase (e.g.
@ k_ra8_xspi_cdt_pos_cmd
CMD[31..16] JEDEC opcode.
@ k_ra8_xspi_cdt_pos_cmdsize
CMDSIZE[1..0] command bytes.
@ k_ra8_xspi_cdt_pos_trtype
TRTYPE[15] 0=read 1=write.
@ k_ra8_xspi_cdt_pos_addsize
ADDSIZE[4..2] address bytes.
@ k_ra8_xspi_cdt_mask_addsize
ADDSIZE field is 3 bits.
@ k_ra8_xspi_cdt_mask_trtype
TRTYPE field is 1 bit.
@ k_ra8_xspi_cdt_mask_cmdsize
CMDSIZE field is 2 bits.
@ k_ra8_xspi_cdctl0_mask_cssel
CSSEL (target select).
@ k_ra8_xspi_cmcfgcs_pos_addr_size
ADDSIZE[2..0] addr bytes.
@ k_ra8_xspi_cmcfgcs_pos_cmd
CMD[31..16] read opcode.
@ k_ra8_xspi_cdctl0_bit_cssel
Chip-select select (0 = CS0).
static volatile r_xspi_regs_t * ra8_xspi(uint8_t instance)
Get pointer to xSPI instance N (0..1).
ra8_xspi_lio_mode_t
Protocol mode values written to LIOCFGCS[n].PRTMD.
@ k_ra8_xspi_cmcfgcs_word_addr
+0x0C address-byte width.
@ k_ra8_xspi_cmcfgcs_word_read_cmd
+0x04 read-cmd + dummy cycles.
@ k_ra8_xspi_bmctl0_read_write
11 per pair: read/write.
@ k_ra8_xspi_bmctl0_disabled
All AHB access disabled.
@ k_ra8_xspi_bmctl0_read_only
01 per pair: read-only.
@ k_ra8_xspi_ccctl0_mask_caen
CAEN enable mask.
@ k_ra8_xspi_lioctl_mask_wpcs
WPCS – write-protect drive.
@ k_ra8_xspi_lioctl_mask_rstcs
RSTCS – hardware-reset drive.
@ k_ra8_xspi_instance_count
XSPI0 and XSPI1.
@ k_ra8_xspi_liocfgcs_mask_ddren
DDR / DTR enable bit.
Scoped PRCR unlock helper.
#define RA8_PROTECTED_WRITE(unlock_val)
Scoped PRCR unlock block.
System Control (SYSC) register layout for the Renesas RA8D2.
@ k_ra8_prcr_unlock_cgc
RA8 prcr unlock cgc.
static volatile uint8_t * ra8_sys_octackcr(void)
Get pointer to the 8-bit OCTACKCR (Octal-SPI clock source select).
static volatile uint8_t * ra8_sys_octackdivcr(void)
Get pointer to the 8-bit OCTACKDIVCR (Octal-SPI clock divider).
@ k_ra8_usbckcr_bit_srdy
USBCKSRDY – handshake ready.
@ k_ra8_usbckcr_bit_sreq
USBCKSREQ – request switch.
ra8_xspi_addr_bytes_t
Allowed address-byte widths for ra8_xspi_set_xip_mode.
Definition ra8_xspi.c:604
@ k_ra8_xspi_addr_bytes_4
32-bit JEDEC address.
Definition ra8_xspi.c:606
@ k_ra8_xspi_addr_bytes_3
24-bit JEDEC address.
Definition ra8_xspi.c:605
ra8_xspi_jedec_extra_t
Extra JEDEC opcodes used by suspend/resume control.
Definition ra8_xspi.c:579
@ k_ra8_spi_flash_op_suspend
0x75 erase/program suspend.
Definition ra8_xspi.c:580
@ k_ra8_spi_flash_op_resume
0x7A erase/program resume.
Definition ra8_xspi.c:581
@ k_ra8_spi_flash_op_reset_dev
0x99 RST – IS25LX512M Ch 8.21 p 39.
Definition ra8_xspi.c:583
@ k_ra8_spi_flash_op_reset_en
0x66 RSTEN – IS25LX512M Ch 8.20 p 39.
Definition ra8_xspi.c:582
ra8_err_t ra8_xspi_attach_handler(uint8_t instance, ra8_xspi_event_fn_t fn, void *ctx)
Attach a completion callback.
Definition ra8_xspi.c:483
ra8_err_t ra8_xspi_calibrate_dqs(uint8_t instance)
Run the data-strobe (DQS) calibration sequence.
Definition ra8_xspi.c:664
ra8_err_t ra8_xspi_enter_stop(uint8_t instance)
Put an xSPI instance into MSTP-gated stop.
Definition ra8_xspi.c:517
static ra8_err_t internal_xspi_clock_block_init(void)
Block-level OCTA clock init – run BEFORE the first MSTP release.
Definition ra8_xspi.c:225
ra8_err_t ra8_xspi_xip_enter(uint8_t instance, uint8_t enter_code, uint8_t exit_code)
Enable XIP (execute-in-place) memory-mapped read mode.
Definition ra8_xspi.c:533
ra8_err_t ra8_xspi_deinit(uint8_t instance)
Tear down the xSPI instance (disable + MSTP release).
Definition ra8_xspi.c:449
ra8_xspi_chip_select_t
Which controller chip-select drives the on-board OSPI flash.
Definition ra8_xspi.c:100
@ k_ra8_xspi_onboard_cs
IS25LX512M is on controller CS1.
Definition ra8_xspi.c:101
ra8_err_t ra8_xspi_set_xip_mode(uint8_t instance, bool enable, uint8_t read_cmd, uint8_t addr_bytes)
Enable or disable memory-mapped (XIP) read mode.
Definition ra8_xspi.c:617
ra8_xspi_cmd_limits_t
Byte-count limits on raw direct-command buffers.
Definition ra8_xspi.c:78
@ k_ra8_xspi_cmd_max_bytes
A CDBUF slot holds 16 bytes.
Definition ra8_xspi.c:79
ra8_err_t ra8_xspi_set_dtr_mode(uint8_t instance, bool enable)
Enable or disable double-data-rate (DDR / DTR) link mode.
Definition ra8_xspi.c:648
ra8_xspi_calib_spin_t
Bounded spin budget for the auto-calibration handshake.
Definition ra8_xspi.c:613
@ k_ra8_xspi_calib_spin
CCCTL0.CAEN poll budget.
Definition ra8_xspi.c:614
static void internal_xspi_reset_spin(void)
Bounded busy-spin used between the RSTCS reset edges.
Definition ra8_xspi.c:286
static ra8_err_t internal_issue_reset_opcode(volatile r_xspi_regs_t *reg, uint8_t opcode, uint8_t cmd_bytes)
Issue a single RSTEN-or-RST opcode in either 1S or 8D form.
Definition ra8_xspi.c:729
static void internal_xspi_reset_device(volatile r_xspi_regs_t *reg)
Pulse the controller-driven flash RESET (LIOCTL.RSTCS) low->high.
Definition ra8_xspi.c:318
ra8_err_t ra8_xspi_exit_stop(uint8_t instance)
Exit MSTP-gated stop.
Definition ra8_xspi.c:525
ra8_xspi_reset_cmd_bytes_t
Allowed cmd_bytes values for ra8_xspi_software_reset.
Definition ra8_xspi.c:595
@ k_ra8_xspi_reset_cmd_bytes_1s
1-byte opcode for 1S-1S-1S.
Definition ra8_xspi.c:596
@ k_ra8_xspi_reset_cmd_bytes_8d
2-byte opcode pair for 8D-8D-8D.
Definition ra8_xspi.c:597
ra8_xspi_reset_delay_t
Bounded busy-spin counts for the LIOCTL.RSTCS reset pulse.
Definition ra8_xspi.c:118
@ k_ra8_xspi_reset_spin
~tens of us busy-spin per reset edge.
Definition ra8_xspi.c:119
static void internal_xspi_apply_config(volatile r_xspi_regs_t *reg, ra8_xspi_lio_mode_t mode)
Apply the manual-command controller config for the on-board flash.
Definition ra8_xspi.c:358
ra8_err_t ra8_xspi_direct_command(uint8_t instance, const uint8_t *cmd_buf, uint8_t len)
Issue a raw command via the direct-command registers.
Definition ra8_xspi.c:402
ra8_err_t ra8_xspi_software_reset(uint8_t instance, uint8_t cmd_bytes)
Issue the JEDEC software-reset pair (RSTEN 0x66 + RST 0x99).
Definition ra8_xspi.c:756
ra8_err_t ra8_xspi_init(uint8_t instance, ra8_xspi_lio_mode_t mode)
Initialise an xSPI instance in the chosen link-layer IO mode.
Definition ra8_xspi.c:372
static ra8_err_t internal_wait_octacksrdy(uint8_t expected)
Bounded wait on OCTACKCR.OCTACKSRDY reaching expected.
Definition ra8_xspi.c:158
static const ra8_mstp_t s_xspi_mstp_table[]
Instance-index -> MSTP id lookup.
Definition ra8_xspi.c:128
ra8_err_t ra8_xspi_get_status(uint8_t instance, uint32_t *out_mask)
Read the xSPI COMSTT busy/error mask.
Definition ra8_xspi.c:464
static ra8_xspi_state_t s_xspi_state[k_ra8_xspi_instance_count]
Per-instance callback state (s_ prefix for file-static).
Definition ra8_xspi.c:447
ra8_err_t ra8_xspi_suspend(uint8_t instance)
Suspend a long-running flash erase / program operation.
Definition ra8_xspi.c:683
ra8_err_t ra8_xspi_clear_status(uint8_t instance, uint32_t mask)
Clear transfer-complete / error bits in INTS via INTC.
Definition ra8_xspi.c:474
ra8_err_t ra8_xspi_resume(uint8_t instance)
Resume a previously suspended erase / program.
Definition ra8_xspi.c:690
ra8_err_t ra8_xspi_xip_exit(uint8_t instance)
Disable XIP mode and restore command-only access.
Definition ra8_xspi.c:555
void ra8_xspi_dispatch(uint8_t instance)
Dispatch an xSPI event – snapshot INTS + fire callback.
Definition ra8_xspi.c:494
xSPI / Octo-SPI driver (flash read/program/erase + ID/status)
void(* ra8_xspi_event_fn_t)(void *ctx, uint32_t status_mask)
xSPI event callback.
Definition ra8_xspi.h:154
ra8_err_t priv_ra8_xspi_kick_command(volatile r_xspi_regs_t *reg)
Kick a prepared manual-command transfer by raising TRREQ.
ra8_err_t priv_ra8_xspi_issue_simple_opcode(volatile r_xspi_regs_t *reg, uint8_t opcode)
Build CDBUF[0] for a 1-byte opcode with no address / no data.
Module-private seam shared between the ra8_xspi translation units.
@ k_ra8_xspi_cdbuf_idx_data1
CDBUF[3] CDD1 – data bytes 4..7.
@ k_ra8_xspi_cdbuf_idx_data0
CDBUF[2] CDD0 – data bytes 0..3.
@ k_ra8_xspi_cdbuf_idx_cdt
CDBUF[0] CDT – type/opcode word.
@ k_ra8_xspi_cdbuf_idx_addr
CDBUF[1] CDA – flash address.
@ k_ra8_xspi_ckcr_spin
OCTACKCR SREQ/SRDY handshake budget.
xSPI per-instance register window.
volatile uint32_t COMCFG
+0x004 Channel arbitration + INT en.
volatile uint32_t LIOCFGCS[2]
+0x050..+0x054 Link I/O per target.
volatile uint32_t BMCTL0
+0x060 Bridge map control 0.
volatile uint32_t LIOCTL
+0x108 Link I/O control (WP/RST).
volatile uint32_t INTC
+0x194 Interrupt clear (W1C).
volatile uint32_t COMSTT
+0x184 Common status (MEMACC/PBUFNE).
volatile uint32_t INTS
+0x190 Interrupt status (CMDCMP=b0).
volatile uint32_t WRAPCFG
+0x000 Wrapper config (CK/DS shift).
volatile uint32_t CCCTLCS[k_ra8_xspi_ccctlcs_words]
+0x130 Calib 2x8.
volatile uint32_t INTE
+0x198 Interrupt enable.
volatile uint32_t CMCFGCS[8]
+0x010..+0x02C Command map (2x4 u32).
volatile uint32_t CDCTL0
+0x070 Manual cmd ctl 0 (TRREQ/CSSEL)
volatile uint32_t CMCTLCH[2]
+0x068..+0x06C XiP command control.
volatile uint32_t CDBUF[16]
+0x080..+0x0BC Command buf (4x4 u32).
Per-instance callback state.
Definition ra8_xspi.c:441
void * ctx
Opaque context pointer for fn.
Definition ra8_xspi.c:443
ra8_xspi_event_fn_t fn
User-supplied completion callback.
Definition ra8_xspi.c:442