Compare commits

...

13 commits

Author SHA1 Message Date
Scott Shawcroft
8f4225038b
thread names 2025-02-07 11:24:47 -08:00
Scott Shawcroft
47acffe181
Merge remote-tracking branch 'renesas/support_renesas_ra8_ospi' into circuitpython 2025-01-23 12:46:08 -08:00
Scott Shawcroft
7ebfd5ef16
Merge remote-tracking branch 'renesas/support_renesas_ra6_qspi' into circuitpython 2025-01-23 11:56:38 -08:00
Scott Shawcroft
81eef20ccc
Tweaks for nrf
* Disable handwritten check so we can override from board defs
* Shrink HEAP for netcpu so it fits.
* Disable netcpu logging so it doesn't conflict with appcpu.
2025-01-23 11:53:43 -08:00
Quy Tran
fe043e2998 samples: driver: Update samples/tests to run with Renesas QSPI driver
Update samples/tests to run QSPI flash driver on Renesas RA6

Signed-off-by: Quy Tran <quy.tran.pz@renesas.com>
2025-01-21 19:35:48 +07:00
Quy Tran
c7ec106e58 boards: renesas: Add boards support for QSPI flash driver
- Add support for QSPI flash driver on EK-RA6E2, EK-RA6M3, EK-RA6M4
and EK-RA6M5
- Remove flash0's partitions in ek_ra6e2

Signed-off-by: Quy Tran <quy.tran.pz@renesas.com>
Signed-off-by: Khoa Nguyen <khoa.nguyen.xh@renesas.com>
2025-01-21 19:35:42 +07:00
Quy Tran
913a137c6a dts: renesas: Add devicetree property for QSPI support on RA6
Add qspi node on Renesas RA6 devicetree to support QSPI flash driver

Signed-off-by: Quy Tran <quy.tran.pz@renesas.com>
2025-01-21 19:33:35 +07:00
Tri Nguyen
99b401dcb6 drivers: flash: Initial support QSPI Flash driver for Renesas RA6
Add QSPI Flash driver supports for Renesas RA6.

Signed-off-by: Tri Nguyen <tri.nguyen.wj@bp.renesas.com>
Signed-off-by: Thao Luong <thao.luong.uw@renesas.com>
2025-01-21 19:33:34 +07:00
Tri Nguyen
8db190571c samples: drivers: Add ospi driver for RA8
Add sample ospi for spi_flash and jesd216

Signed-off-by: Tri Nguyen <tri.nguyen.wj@bp.renesas.com>
Signed-off-by: Thao Luong <thao.luong.uw@renesas.com>
2025-01-20 00:07:33 +07:00
Tri Nguyen
a24fa32f3d tests: drivers: flash: add ospi driver for RA8
Add test for ospi driver in RA8 boards

Signed-off-by: Tri Nguyen <tri.nguyen.wj@bp.renesas.com>
Signed-off-by: Thao Luong <thao.luong.uw@renesas.com>
2025-01-20 00:07:33 +07:00
Quy Tran
09f24acafc boards: renesas: Add boards support for OSPI flash driver on RA8
Add support for OSPI flash driver on EK-RA8D1 and EK-RA8M1

Signed-off-by: Quy Tran <quy.tran.pz@renesas.com>
2025-01-20 00:07:33 +07:00
Quy Tran
84e49e565d dts: renesas: Add devicetree property for OSPI support on RA8
Add ospi node on Renesas RA8 devicetree to support QSPI flash driver

Signed-off-by: Quy Tran <quy.tran.pz@renesas.com>
2025-01-20 00:07:33 +07:00
Tri Nguyen
cf0531046e drivers: flash: Initial support OSPI flash driver on RA8 boards
Support OSPI flash driver on EK-RA8M1 and EK-RA8D1 with ospi_b
and S28HL512T flash.

Signed-off-by: Tri Nguyen <tri.nguyen.wj@bp.renesas.com>
Signed-off-by: Thao Luong <thao.luong.uw@renesas.com>
2025-01-20 00:07:29 +07:00
44 changed files with 2284 additions and 92 deletions

View file

@ -10,8 +10,8 @@ CONFIG_HW_STACK_PROTECTION=y
CONFIG_GPIO=y CONFIG_GPIO=y
# Enable UART driver # Enable UART driver
CONFIG_SERIAL=y CONFIG_SERIAL=n
# Enable console # Enable console
CONFIG_CONSOLE=y CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=y CONFIG_UART_CONSOLE=n

View file

@ -108,6 +108,8 @@ The below features are currently supported on Zephyr OS for EK-RA6E2 board:
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| FLASH | on-chip | flash | | FLASH | on-chip | flash |
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| QSPI | on-chip | qspi flash |
+-----------+------------+----------------------+
Other hardware features are currently not supported by the port. Other hardware features are currently not supported by the port.

View file

@ -46,4 +46,16 @@
<RA_PSEL(RA_PSEL_GPT1, 4, 8)>; <RA_PSEL(RA_PSEL_GPT1, 4, 8)>;
}; };
}; };
qspi_default: qspi_default {
group1 {
/* QSPICLK QSSL QIO0 QIO1 QIO2 QIO3 */
psels = <RA_PSEL(RA_PSEL_QSPI, 1, 0)>,
<RA_PSEL(RA_PSEL_QSPI, 1, 12)>,
<RA_PSEL(RA_PSEL_QSPI, 1, 2)>,
<RA_PSEL(RA_PSEL_QSPI, 1, 1)>,
<RA_PSEL(RA_PSEL_QSPI, 1, 4)>,
<RA_PSEL(RA_PSEL_QSPI, 1, 3)>;
};
};
}; };

View file

@ -178,3 +178,16 @@
}; };
}; };
}; };
&qspi0 {
pinctrl-0 = <&qspi_default>;
pinctrl-names = "default";
status = "okay";
at25sf128a: ra-qspi-nor@60000000 {
compatible = "renesas,ra-qspi-nor";
reg = <0x60000000 DT_SIZE_M(16)>;
status = "okay";
write-block-size = <1>;
erase-block-size = <4096>;
};
};

View file

@ -110,6 +110,8 @@ The below features are currently supported on Zephyr OS for EK-RA6M3 board:
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| FLASH | on-chip | flash | | FLASH | on-chip | flash |
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| QSPI | on-chip | qspi flash |
+-----------+------------+----------------------+
Other hardware features are currently not supported by the port. Other hardware features are currently not supported by the port.

View file

@ -53,4 +53,16 @@
<RA_PSEL(RA_PSEL_GPT1, 4, 6)>; <RA_PSEL(RA_PSEL_GPT1, 4, 6)>;
}; };
}; };
qspi_default: qspi_default {
group1 {
/* QSPICLK QSSL QIO0 QIO1 QIO2 QIO3 */
psels = <RA_PSEL(RA_PSEL_QSPI, 3, 5)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 6)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 7)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 8)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 9)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 10)>;
};
};
}; };

View file

@ -173,3 +173,16 @@
}; };
}; };
}; };
&qspi0 {
pinctrl-0 = <&qspi_default>;
pinctrl-names = "default";
status = "okay";
mx25l25645g: ra-qspi-nor@60000000 {
compatible = "renesas,ra-qspi-nor";
reg = <0x60000000 DT_SIZE_M(32)>;
status = "okay";
write-block-size = <1>;
erase-block-size = <4096>;
};
};

View file

@ -115,6 +115,8 @@ The below features are currently supported on Zephyr OS for EK-RA6M4 board:
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| ENTROPY | on-chip | entropy | | ENTROPY | on-chip | entropy |
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| QSPI | on-chip | qspi flash |
+-----------+------------+----------------------+
Other hardware features are currently not supported by the port. Other hardware features are currently not supported by the port.

View file

@ -46,4 +46,16 @@
<RA_PSEL(RA_PSEL_GPT1, 4, 6)>; <RA_PSEL(RA_PSEL_GPT1, 4, 6)>;
}; };
}; };
qspi_default: qspi_default {
group1 {
/* QSPICLK QSSL QIO0 QIO1 QIO2 QIO3 */
psels = <RA_PSEL(RA_PSEL_QSPI, 3, 5)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 6)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 7)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 8)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 9)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 10)>;
};
};
}; };

View file

@ -161,3 +161,16 @@
&trng { &trng {
status = "okay"; status = "okay";
}; };
&qspi0 {
pinctrl-0 = <&qspi_default>;
pinctrl-names = "default";
status = "okay";
mx25l25645g: ra-qspi-nor@60000000 {
compatible = "renesas,ra-qspi-nor";
reg = <0x60000000 DT_SIZE_M(32)>;
status = "okay";
write-block-size = <1>;
erase-block-size = <4096>;
};
};

View file

@ -115,6 +115,8 @@ The below features are currently supported on Zephyr OS for EK-RA6M5 board:
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| ENTROPY | on-chip | entropy | | ENTROPY | on-chip | entropy |
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| QSPI | on-chip | qspi flash |
+-----------+------------+----------------------+
Other hardware features are currently not supported by the port. Other hardware features are currently not supported by the port.

View file

@ -53,4 +53,16 @@
<RA_PSEL(RA_PSEL_GPT1, 4, 6)>; <RA_PSEL(RA_PSEL_GPT1, 4, 6)>;
}; };
}; };
qspi_default: qspi_default {
group1 {
/* QSPICLK QSSL QIO0 QIO1 QIO2 QIO3 */
psels = <RA_PSEL(RA_PSEL_QSPI, 3, 5)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 6)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 7)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 8)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 9)>,
<RA_PSEL(RA_PSEL_QSPI, 3, 10)>;
};
};
}; };

View file

@ -165,3 +165,16 @@
&trng { &trng {
status = "okay"; status = "okay";
}; };
&qspi0 {
pinctrl-0 = <&qspi_default>;
pinctrl-names = "default";
status = "okay";
mx25l25645g: ra-qspi-nor@60000000 {
compatible = "renesas,ra-qspi-nor";
reg = <0x60000000 DT_SIZE_M(32)>;
status = "okay";
write-block-size = <1>;
erase-block-size = <4096>;
};
};

View file

@ -123,6 +123,8 @@ The below features are currently supported on Zephyr OS for EK-RA8D1 board:
+--------------+------------+-----------------------------------+ +--------------+------------+-----------------------------------+
| SDHC | on-chip | sdhc | | SDHC | on-chip | sdhc |
+--------------+------------+-----------------------------------+ +--------------+------------+-----------------------------------+
| OSPI | on-chip | ospi flash |
+--------------+------------+-----------------------------------+
**Note:** **Note:**

View file

@ -261,4 +261,22 @@
drive-strength = "highspeed-high"; drive-strength = "highspeed-high";
}; };
}; };
ospi0_default: ospi0_default {
group1 {
/* sclk dqs sio0-7 */
psels = <RA_PSEL(RA_PSEL_OSPI, 8, 8)>, <RA_PSEL(RA_PSEL_OSPI, 8, 1)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 0)>, <RA_PSEL(RA_PSEL_OSPI, 8, 3)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 3)>, <RA_PSEL(RA_PSEL_OSPI, 1, 1)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 2)>, <RA_PSEL(RA_PSEL_OSPI, 8, 0)>,
<RA_PSEL(RA_PSEL_OSPI, 8, 2)>, <RA_PSEL(RA_PSEL_OSPI, 8, 4)>;
drive-strength = "highspeed-high";
};
group2 {
/* cs1 rst ecsint1 */
psels = <RA_PSEL(RA_PSEL_OSPI, 1, 4)>, <RA_PSEL(RA_PSEL_OSPI, 1, 6)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 5)>;
drive-strength = "high";
};
};
}; };

View file

@ -6,6 +6,7 @@
/dts-v1/; /dts-v1/;
#include <renesas/ra/ra8/r7fa8d1bhecbd.dtsi> #include <renesas/ra/ra8/r7fa8d1bhecbd.dtsi>
#include <zephyr/dt-bindings/flash_controller/xspi.h>
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input-event-codes.h> #include <dt-bindings/input/input-event-codes.h>
#include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h> #include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h>
@ -111,6 +112,17 @@
}; };
}; };
&pll2 {
status = "okay";
clocks = <&xtal>;
div = <2>;
mul = <80 0>;
pll2p {
status = "okay";
freq = <DT_FREQ_M(400)>;
div = <2>;
};
};
&sciclk { &sciclk {
clocks = <&pllp>; clocks = <&pllp>;
@ -130,6 +142,12 @@
status = "okay"; status = "okay";
}; };
&octaspiclk {
clocks = <&pll2p>;
div = <2>;
status = "okay";
};
&ioport0 { &ioport0 {
status = "okay"; status = "okay";
}; };
@ -300,3 +318,43 @@ zephyr_mipi_dsi: &mipi_dsi {};
renesas_mipi_i2c: &iic1{}; renesas_mipi_i2c: &iic1{};
pmod_sd_shield: &sdhc1 {}; pmod_sd_shield: &sdhc1 {};
&ospi0 {
pinctrl-0 = <&ospi0_default>;
pinctrl-names = "default";
status = "okay";
s28hl512t: s28hl512t@90000000 {
compatible = "renesas,ra-ospi-b-nor";
protocol-mode = <XSPI_OCTO_MODE>;
data-rate = <XSPI_DTR_TRANSFER>;
ospi-max-frequency = <DT_FREQ_M(200)>;
reg = <0x90000000 DT_SIZE_M(64)>;
write-block-size = <1>;
pages_layout: pages_layout {
pages_layout_4k: pages_layout_4k {
pages-count = <32>;
pages-size = <DT_SIZE_K(4)>;
};
pages_layout_128k: pages_layout_128k {
pages-count = <1>;
pages-size = <DT_SIZE_K(128)>;
};
pages_layout_256k: pages_layout_256k {
pages-count = <255>;
pages-size = <DT_SIZE_K(256)>;
};
};
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "nor";
reg = <0x00000000 DT_SIZE_M(64)>;
};
};
};
};

View file

@ -120,6 +120,8 @@ The below features are currently supported on Zephyr OS for EK-RA8M1 board:
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| SDHC | on-chip | sdhc | | SDHC | on-chip | sdhc |
+-----------+------------+----------------------+ +-----------+------------+----------------------+
| OSPI | on-chip | ospi flash |
+-----------+------------+----------------------+
**Note:** **Note:**

View file

@ -138,4 +138,22 @@
drive-strength = "highspeed-high"; drive-strength = "highspeed-high";
}; };
}; };
ospi0_default: ospi0_default {
group1 {
/* sclk dqs sio0-7 */
psels = <RA_PSEL(RA_PSEL_OSPI, 8, 8)>, <RA_PSEL(RA_PSEL_OSPI, 8, 1)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 0)>, <RA_PSEL(RA_PSEL_OSPI, 8, 3)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 3)>, <RA_PSEL(RA_PSEL_OSPI, 1, 1)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 2)>, <RA_PSEL(RA_PSEL_OSPI, 8, 0)>,
<RA_PSEL(RA_PSEL_OSPI, 8, 2)>, <RA_PSEL(RA_PSEL_OSPI, 8, 4)>;
drive-strength = "highspeed-high";
};
group2 {
/* cs1 rst ecsint1 */
psels = <RA_PSEL(RA_PSEL_OSPI, 1, 4)>, <RA_PSEL(RA_PSEL_OSPI, 1, 6)>,
<RA_PSEL(RA_PSEL_OSPI, 1, 5)>;
drive-strength = "high";
};
};
}; };

View file

@ -7,6 +7,7 @@
#include <renesas/ra/ra8/r7fa8m1ahecbd.dtsi> #include <renesas/ra/ra8/r7fa8m1ahecbd.dtsi>
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/flash_controller/xspi.h>
#include <zephyr/dt-bindings/adc/adc.h> #include <zephyr/dt-bindings/adc/adc.h>
#include <zephyr/dt-bindings/input/input-event-codes.h> #include <zephyr/dt-bindings/input/input-event-codes.h>
#include "ek_ra8m1-pinctrl.dtsi" #include "ek_ra8m1-pinctrl.dtsi"
@ -148,6 +149,17 @@
}; };
}; };
&pll2 {
status = "okay";
clocks = <&xtal>;
div = <2>;
mul = <80 0>;
pll2p {
status = "okay";
freq = <DT_FREQ_M(400)>;
div = <2>;
};
};
&sciclk { &sciclk {
clocks = <&pllp>; clocks = <&pllp>;
@ -161,6 +173,12 @@
status = "okay"; status = "okay";
}; };
&octaspiclk {
clocks = <&pll2p>;
div = <2>;
status = "okay";
};
&ioport0 { &ioport0 {
status = "okay"; status = "okay";
}; };
@ -349,3 +367,43 @@ pmod_header: &pmod1_header {};
}; };
pmod_sd_shield: &sdhc0 {}; pmod_sd_shield: &sdhc0 {};
&ospi0 {
pinctrl-0 = <&ospi0_default>;
pinctrl-names = "default";
status = "okay";
s28hl512t: s28hl512t@90000000 {
compatible = "renesas,ra-ospi-b-nor";
protocol-mode = <XSPI_OCTO_MODE>;
data-rate = <XSPI_DTR_TRANSFER>;
ospi-max-frequency = <DT_FREQ_M(200)>;
reg = <0x90000000 DT_SIZE_M(64)>;
write-block-size = <1>;
pages_layout: pages_layout {
pages_layout_4k: pages_layout_4k {
pages-count = <32>;
pages-size = <DT_SIZE_K(4)>;
};
pages_layout_128k: pages_layout_128k {
pages-count = <1>;
pages-size = <DT_SIZE_K(128)>;
};
pages_layout_256k: pages_layout_256k {
pages-count = <255>;
pages-size = <DT_SIZE_K(256)>;
};
};
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "nor";
reg = <0x00000000 DT_SIZE_M(64)>;
};
};
};
};

View file

@ -358,7 +358,7 @@ if(EXISTS ${DOTCONFIG} AND EXISTS ${merge_config_files_checksum_file})
endif() endif()
if(CREATE_NEW_DOTCONFIG) if(CREATE_NEW_DOTCONFIG)
set(input_configs_flags --handwritten-input-configs) # set(input_configs_flags --handwritten-input-configs)
set(input_configs ${merge_config_files} ${FORCED_CONF_FILE}) set(input_configs ${merge_config_files} ${FORCED_CONF_FILE})
build_info(kconfig files PATH ${input_configs}) build_info(kconfig files PATH ${input_configs})
else() else()

View file

@ -154,7 +154,9 @@ zephyr_library_include_directories_ifdef(
${ZEPHYR_BASE}/drivers/memc ${ZEPHYR_BASE}/drivers/memc
) )
zephyr_library_sources_ifdef(CONFIG_FLASH_QSPI_RENESAS_RA flash_qspi_renesas_ra.c)
if(CONFIG_RA_FLASH_HP) if(CONFIG_RA_FLASH_HP)
zephyr_library_sources(flash_hp_ra.c) zephyr_library_sources(flash_hp_ra.c)
zephyr_library_sources_ifdef(CONFIG_FLASH_EX_OP_ENABLED flash_hp_ra_ex_op.c) zephyr_library_sources_ifdef(CONFIG_FLASH_EX_OP_ENABLED flash_hp_ra_ex_op.c)
endif() endif()
zephyr_library_sources_ifdef(CONFIG_FLASH_OSPI_B_RENESAS_RA flash_renesas_ra_ospi_b.c)

View file

@ -191,6 +191,8 @@ source "drivers/flash/Kconfig.numaker"
source "drivers/flash/Kconfig.numaker_rmc" source "drivers/flash/Kconfig.numaker_rmc"
source "drivers/flash/Kconfig.nxp_s32" source "drivers/flash/Kconfig.nxp_s32"
source "drivers/flash/Kconfig.renesas_ra" source "drivers/flash/Kconfig.renesas_ra"
source "drivers/flash/Kconfig.renesas_ra_flash_ospi_b"
source "drivers/flash/Kconfig.renesas_ra_flash_qspi"
source "drivers/flash/Kconfig.rpi_pico" source "drivers/flash/Kconfig.rpi_pico"
source "drivers/flash/Kconfig.rv32m1" source "drivers/flash/Kconfig.rv32m1"
source "drivers/flash/Kconfig.sam" source "drivers/flash/Kconfig.sam"

View file

@ -0,0 +1,18 @@
# Renesas RA Family
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
config FLASH_OSPI_B_RENESAS_RA
bool "Renesas RA Octal-SPI driver"
default y
depends on DT_HAS_RENESAS_RA_OSPI_B_NOR_ENABLED
select FLASH_HAS_DRIVER_ENABLED
select FLASH_HAS_PAGE_LAYOUT
select FLASH_HAS_EXPLICIT_ERASE
select USE_RA_FSP_OSPI_B_NOR_FLASH
select FLASH_JESD216
select FLASH_HAS_EX_OP
select PINCTRL
help
Enable Octal-SPI Nor flash driver for RA series

View file

@ -0,0 +1,18 @@
# Renesas RA Family
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
config FLASH_QSPI_RENESAS_RA
bool "RA Quad-SPI driver"
default y
depends on DT_HAS_RENESAS_RA_QSPI_NOR_ENABLED
select FLASH_HAS_DRIVER_ENABLED
select FLASH_HAS_PAGE_LAYOUT
select FLASH_HAS_EXPLICIT_ERASE
select USE_RA_FSP_QSPI_NOR_FLASH
select FLASH_HAS_EX_OP
select FLASH_JESD216
select PINCTRL
help
Enable Quad-SPI Nor flash driver for RA series

View file

@ -0,0 +1,567 @@
/*
* Copyright (c) 2024 Renesas Electronics Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#define DT_DRV_COMPAT renesas_ra_qspi_nor
#include <zephyr/init.h>
#include <soc.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/drivers/flash/ra_flash_api_extensions.h>
#include "spi_nor.h"
#include "r_spi_flash_api.h"
#include "r_qspi.h"
/* Flash QPI (4-4-4) opcodes */
#define QSPI_QPI_CMD_QPIID (0xAF) /* QPI ID Read */
#define QSPI_QPI_CMD_RDSFDP (0x5A) /* Read SFDP */
#define QSPI_QPI_CMD_RSTQIO (0xF5) /* Reset QPI */
#define QSPI_QPI_CMD_EQIO (0x35) /* Enable QPI */
/* XIP (Execute In Place) mode */
#define QSPI_CMD_XIP_ENTER (0x20) /* XIP Enter command */
#define QSPI_CMD_XIP_EXIT (0xFF) /* XIP Exit command */
#define WRITE_STATUS_BIT 0
#if defined(CONFIG_SOC_SERIES_RA6E2)
#define STATUS_REG_PAYLOAD {0x01, 0x00}
#define SET_SREG_VALUE (0x00)
#else
#define STATUS_REG_PAYLOAD {0x01, 0x40, 0x00}
#define SET_SREG_VALUE (0x40)
#endif
/* one byte data transfer */
#define ONE_BYTE (1)
#define THREE_BYTE (3)
#define FOUR_BYTE (4)
#define RESET_VALUE (0x00)
/* default memory value */
#define QSPI_DEFAULT_MEM_VAL (0xFF)
#define QSPI0_NODE DT_INST_PARENT(0)
#define RA_QSPI_NOR_NODE DT_INST(0, renesas_ra_qspi_nor)
#define QSPI_WRITE_BLK_SZ DT_PROP(RA_QSPI_NOR_NODE, write_block_size)
#define QSPI_ERASE_BLK_SZ DT_PROP(RA_QSPI_NOR_NODE, erase_block_size)
/* QSPI flash page Size */
#define PAGE_SIZE_BYTE SPI_NOR_PAGE_SIZE
/* sector size of QSPI flash device */
#define BLOCK_SIZE_4K (4096U)
#define BLOCK_SIZE_32K (32678U)
#define BLOCK_SIZE_64K (65536U)
/* QSPI flash address through page*/
#define QSPI_FLASH_ADDRESS(page_no) \
((uint8_t *)(QSPI_DEVICE_START_ADDRESS + ((page_no) * SPI_NOR_PAGE_SIZE)))
/* Flash Size*/
#define QSPI_NOR_FLASH_SIZE DT_REG_SIZE(RA_QSPI_NOR_NODE)
#define ERASE_COMMAND_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0]))
#define QSPI_ENABLE_QUAD_MODE DT_PROP(RA_QSPI_NOR_NODE, qpi_enable)
PINCTRL_DT_DEFINE(QSPI0_NODE);
LOG_MODULE_REGISTER(flash_qspi_renesas_ra, CONFIG_FLASH_LOG_LEVEL);
struct qspi_flash_ra_data {
struct st_qspi_instance_ctrl qspi_ctrl;
struct st_spi_flash_cfg qspi_cfg;
struct k_sem sem;
};
struct ra_qspi_nor_flash_config {
const struct pinctrl_dev_config *pcfg;
};
static const spi_flash_erase_command_t g_qspi_erase_command_list[4] = {
{.command = 0x20, .size = 4096},
{.command = 0x52, .size = 32768},
{.command = 0xD8, .size = 65536},
{.command = 0xC7, .size = SPI_FLASH_ERASE_SIZE_CHIP_ERASE},
};
static const struct ra_qspi_nor_flash_config qspi_nor_dev_config = {
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(QSPI0_NODE),
};
static const struct flash_parameters qspi_flash_ra_config_para = {
.write_block_size = QSPI_WRITE_BLK_SZ,
.erase_value = 0xff,
};
static const qspi_extended_cfg_t g_qspi_extended_cfg = {
.min_qssl_deselect_cycles = QSPI_QSSL_MIN_HIGH_LEVEL_8_QSPCLK,
.qspclk_div = QSPI_QSPCLK_DIV_2,
};
static struct qspi_flash_ra_data qspi_flash_data = {
.qspi_cfg = {
.spi_protocol = SPI_FLASH_PROTOCOL_EXTENDED_SPI,
.read_mode = SPI_FLASH_READ_MODE_FAST_READ_QUAD_IO,
.address_bytes = SPI_FLASH_ADDRESS_BYTES_3,
.dummy_clocks = SPI_FLASH_DUMMY_CLOCKS_DEFAULT,
.page_program_address_lines = SPI_FLASH_DATA_LINES_1,
.page_size_bytes = PAGE_SIZE_BYTE,
.page_program_command = (SPI_NOR_CMD_PP),
.write_enable_command = (SPI_NOR_CMD_WREN),
.status_command = (SPI_NOR_CMD_RDSR),
.write_status_bit = WRITE_STATUS_BIT,
.xip_enter_command = QSPI_CMD_XIP_ENTER,
.xip_exit_command = QSPI_CMD_XIP_EXIT,
.p_erase_command_list = &g_qspi_erase_command_list[0],
.erase_command_list_length = ERASE_COMMAND_LENGTH(g_qspi_erase_command_list),
.p_extend = &g_qspi_extended_cfg,
}};
static void acquire_device(const struct device *dev)
{
struct qspi_flash_ra_data *dev_data = dev->data;
k_sem_take(&dev_data->sem, K_FOREVER);
}
static void release_device(const struct device *dev)
{
struct qspi_flash_ra_data *dev_data = dev->data;
k_sem_give(&dev_data->sem);
}
static int get_flash_status(const struct device *dev)
{
struct qspi_flash_ra_data *qspi_data = dev->data;
spi_flash_status_t status = {.write_in_progress = true};
int32_t time_out = (INT32_MAX);
int err;
do {
err = R_QSPI_StatusGet(&qspi_data->qspi_ctrl, &status);
if (err != FSP_SUCCESS) {
LOG_ERR("Status get failed");
return -EIO;
}
--time_out;
if (RESET_VALUE >= time_out) {
return -EIO;
}
} while (false != status.write_in_progress);
return 0;
}
#if defined(CONFIG_FLASH_EX_OP_ENABLED)
static int qspi_flash_ra_ex_op(const struct device *dev, uint16_t code, const uintptr_t in,
void *out)
{
int err = 0;
uint8_t cmd;
struct qspi_flash_ra_data *qspi_data = dev->data;
ARG_UNUSED(in);
ARG_UNUSED(out);
acquire_device(dev);
switch (code) {
case QSPI_FLASH_EX_OP_EXIT_QPI:
if (SPI_FLASH_PROTOCOL_QPI != qspi_data->qspi_cfg.spi_protocol) {
err = 0;
break;
}
cmd = QSPI_QPI_CMD_RSTQIO;
err = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &cmd, ONE_BYTE, false);
if (err != FSP_SUCCESS) {
LOG_ERR("Direct write for EXIT QPI failed");
err = -EIO;
}
break;
case FLASH_EX_OP_RESET:
cmd = SPI_NOR_CMD_RESET_EN;
err = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &cmd, ONE_BYTE, false);
if (err == FSP_SUCCESS) {
cmd = SPI_NOR_CMD_RESET_MEM;
err = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &cmd, ONE_BYTE, false);
if (err != FSP_SUCCESS) {
LOG_ERR("Direct write for RESET MEM failed");
err = -EIO;
}
} else {
if (err != FSP_SUCCESS) {
LOG_ERR("Direct write for RESET Flash failed");
err = -EIO;
}
}
break;
default:
break;
}
release_device(dev);
return err;
}
#endif
#if CONFIG_FLASH_PAGE_LAYOUT
static const struct flash_pages_layout qspi_flash_ra_layout = {
.pages_count = QSPI_NOR_FLASH_SIZE / QSPI_ERASE_BLK_SZ,
.pages_size = QSPI_ERASE_BLK_SZ,
};
void qspi_flash_ra_page_layout(const struct device *dev, const struct flash_pages_layout **layout,
size_t *layout_size)
{
ARG_UNUSED(dev);
*layout = &qspi_flash_ra_layout;
*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
#if defined(CONFIG_FLASH_JESD216_API)
static int qspi_flash_ra_read_jedec_id(const struct device *dev, uint8_t *id)
{
struct qspi_flash_ra_data *qspi_data = dev->data;
int err = 0;
uint8_t cmd;
if (id == NULL) {
return -EINVAL;
}
acquire_device(dev);
if (SPI_FLASH_PROTOCOL_QPI == qspi_data->qspi_cfg.spi_protocol) {
cmd = QSPI_QPI_CMD_QPIID;
} else {
cmd = SPI_NOR_CMD_RDID;
}
err = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &cmd, ONE_BYTE, true);
if (err != FSP_SUCCESS) {
LOG_ERR("Direct write for READ ID failed");
err = -EIO;
goto out;
}
err = R_QSPI_DirectRead(&qspi_data->qspi_ctrl, id, THREE_BYTE);
if (err != FSP_SUCCESS) {
LOG_ERR("Direct read failed");
err = -EIO;
goto out;
}
err = get_flash_status(dev);
if (err != FSP_SUCCESS) {
LOG_ERR("Failed to get status for QSPI operation");
err = -EIO;
}
out:
release_device(dev);
return err;
}
static int qspi_flash_ra_sfdp_read(const struct device *dev, off_t addr, void *data, size_t size)
{
struct qspi_flash_ra_data *qspi_data = dev->data;
int err = 0;
uint8_t buffer[size];
acquire_device(dev);
memset(&buffer[0], 0, sizeof(buffer));
buffer[0] = QSPI_QPI_CMD_RDSFDP;
buffer[1] = addr;
buffer[2] = addr >> 8;
buffer[3] = addr >> 16;
err = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &buffer[0], FOUR_BYTE, true);
if (err != FSP_SUCCESS) {
LOG_ERR("Direct write for READ SFDP failed");
err = -EIO;
goto out;
}
err = R_QSPI_DirectRead(&qspi_data->qspi_ctrl, &buffer[0], size);
if (err != FSP_SUCCESS) {
LOG_ERR("Direct read failed");
err = -EIO;
goto out;
}
err = get_flash_status(dev);
if (err != FSP_SUCCESS) {
LOG_ERR("Failed to get status for QSPI operation");
err = -EIO;
goto out;
}
if (SPI_FLASH_PROTOCOL_QPI == qspi_data->qspi_cfg.spi_protocol) {
/* 3 dummy byte */
memcpy(data, &buffer[4], size);
} else {
/* 1 dummy byte */
memcpy(data, &buffer[1], size);
}
out:
release_device(dev);
return err;
}
#endif
static bool qspi_flash_ra_valid(off_t area_size, off_t offset, size_t len)
{
if ((offset < 0) || (offset >= area_size) || ((area_size - offset) < len)) {
return false;
}
return true;
}
static int qspi_flash_ra_erase(const struct device *dev, off_t offset, size_t len)
{
struct qspi_flash_ra_data *qspi_data = dev->data;
int err = 0;
struct flash_pages_info page_info_start, page_info_end;
uint32_t erase_size;
int rc;
if (!len) {
return 0;
}
if (!qspi_flash_ra_valid(QSPI_NOR_FLASH_SIZE, offset, len)) {
LOG_ERR("The offset 0x%lx is invalid", (long)offset);
return -EINVAL;
}
if (len % QSPI_ERASE_BLK_SZ != 0) {
LOG_ERR("The size %u is not align with block size (%u)", len, QSPI_ERASE_BLK_SZ);
return -EINVAL;
}
rc = flash_get_page_info_by_offs(dev, offset, &page_info_start);
if ((rc != 0) || (offset != page_info_start.start_offset)) {
LOG_ERR("The offset 0x%lx is not aligned with the starting sector", (long)offset);
return -EINVAL;
}
rc = flash_get_page_info_by_offs(dev, (offset + len), &page_info_end);
if ((rc != 0) || ((offset + len) != page_info_end.start_offset)) {
LOG_ERR("The size %u is not aligned with the ending sector", len);
return -EINVAL;
}
acquire_device(dev);
while (len > 0) {
if (len < BLOCK_SIZE_32K) {
erase_size = BLOCK_SIZE_4K;
} else if (len < BLOCK_SIZE_64K) {
erase_size = BLOCK_SIZE_32K;
} else {
erase_size = BLOCK_SIZE_64K;
}
err = R_QSPI_Erase(&qspi_data->qspi_ctrl,
(uint8_t *)(QSPI_DEVICE_START_ADDRESS + offset), erase_size);
if (err) {
LOG_ERR("Erase failed");
err = -EIO;
break;
}
err = get_flash_status(dev);
if (err) {
LOG_ERR("failed to get status for QSPI operation");
err = -EIO;
break;
}
offset += erase_size;
len -= erase_size;
}
release_device(dev);
return err;
}
static int qspi_flash_ra_read(const struct device *dev, off_t offset, void *data, size_t len)
{
if (!len) {
return 0;
}
if (!qspi_flash_ra_valid(QSPI_NOR_FLASH_SIZE, offset, len)) {
return -EINVAL;
}
acquire_device(dev);
memcpy(data, (uint8_t *)(QSPI_DEVICE_START_ADDRESS + offset), len);
release_device(dev);
return 0;
}
static int qspi_flash_ra_write(const struct device *dev, off_t offset, const void *data, size_t len)
{
struct qspi_flash_ra_data *qspi_data = dev->data;
int err = 0;
uint32_t remaining_bytes = len;
const uint8_t *p_data = data;
uint32_t size = len;
if (!len) {
return 0;
}
if (!qspi_flash_ra_valid(QSPI_NOR_FLASH_SIZE, offset, len)) {
return -EINVAL;
}
acquire_device(dev);
while (remaining_bytes > 0) {
size = remaining_bytes > PAGE_SIZE_BYTE ? PAGE_SIZE_BYTE : remaining_bytes;
err = R_QSPI_Write(&qspi_data->qspi_ctrl, p_data,
(uint8_t *)(QSPI_DEVICE_START_ADDRESS + offset), size);
if (err) {
LOG_ERR("Direct write failed");
err = -EIO;
break;
}
err = get_flash_status(dev);
if (err) {
LOG_ERR("Failed to get status for QSPI operation");
err = -EIO;
break;
}
remaining_bytes -= size;
offset += size;
p_data += size;
}
release_device(dev);
return err;
}
static const struct flash_parameters *qspi_flash_ra_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &qspi_flash_ra_config_para;
}
static const struct flash_driver_api qspi_flash_ra_api = {
.erase = qspi_flash_ra_erase,
.write = qspi_flash_ra_write,
.read = qspi_flash_ra_read,
.get_parameters = qspi_flash_ra_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = qspi_flash_ra_page_layout,
#endif
#if defined(CONFIG_FLASH_JESD216_API)
.sfdp_read = qspi_flash_ra_sfdp_read,
.read_jedec_id = qspi_flash_ra_read_jedec_id,
#endif
#if defined(CONFIG_FLASH_EX_OP_ENABLED)
.ex_op = qspi_flash_ra_ex_op,
#endif /* CONFIG_FLASH_EX_OP_ENABLED */
};
static int set_qspi_flash_status(const struct device *dev)
{
struct qspi_flash_ra_data *qspi_data = dev->data;
uint8_t data_sreg[] = STATUS_REG_PAYLOAD;
uint8_t sreg_data = 0;
int ret;
ret = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, data_sreg, sizeof(data_sreg), false);
if (ret) {
LOG_ERR("Direct write for STATUS_REG_PAYLOAD fail");
return -EIO;
}
ret = get_flash_status(dev);
if (ret) {
LOG_ERR("Failed to get status for QSPI operation");
return -EIO;
}
ret = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &(qspi_data->qspi_cfg.status_command),
ONE_BYTE, true);
if (ret) {
LOG_ERR("Direct write for status command fail ");
return -EIO;
}
ret = R_QSPI_DirectRead(&qspi_data->qspi_ctrl, &sreg_data, ONE_BYTE);
if (ret) {
LOG_ERR("Direct read fail");
return -EIO;
}
if (SET_SREG_VALUE != sreg_data) {
LOG_ERR("Verify status register data failed");
return -EIO;
}
return ret;
}
static int qspi_flash_ra_init(const struct device *dev)
{
const struct ra_qspi_nor_flash_config *config = dev->config;
struct qspi_flash_ra_data *qspi_data = dev->data;
int ret;
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
if (ret) {
LOG_ERR("Failed to configure pins for QSPI");
return -EIO;
}
k_sem_init(&qspi_data->sem, 1, 1);
ret = R_QSPI_Open(&qspi_data->qspi_ctrl, &qspi_data->qspi_cfg);
if (ret) {
LOG_ERR("Open failed");
return -EIO;
}
ret = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &(qspi_data->qspi_cfg.write_enable_command),
ONE_BYTE, false);
if (ret) {
LOG_ERR("Direct write enable command failed");
return -EIO;
}
ret = get_flash_status(dev);
if (ret) {
LOG_ERR("Failed to get status for QSPI operation");
return -EIO;
}
ret = set_qspi_flash_status(dev);
if (ret) {
LOG_ERR("Set qspi flash status failed");
return -EIO;
}
#if QSPI_ENABLE_QUAD_MODE
uint8_t data_qpi_en = QSPI_QPI_CMD_EQIO;
qspi_data->qspi_cfg.spi_protocol = SPI_FLASH_PROTOCOL_QPI;
ret = R_QSPI_DirectWrite(&qspi_data->qspi_ctrl, &data_qpi_en, ONE_BYTE, false);
if (ret) {
LOG_ERR("Direct write SPI_FLASH_PROTOCOL_QPI failed");
return -EIO;
}
ret = R_QSPI_SpiProtocolSet(&qspi_data->qspi_ctrl, SPI_FLASH_PROTOCOL_QPI);
if (ret) {
LOG_ERR("Set SpiProtocol failed");
return -EIO;
}
#endif
return 0;
}
DEVICE_DT_INST_DEFINE(0, qspi_flash_ra_init, NULL, &qspi_flash_data, &qspi_nor_dev_config,
POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, &qspi_flash_ra_api);

View file

@ -0,0 +1,775 @@
/*
* Copyright (c) 2024 Renesas Electronics Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT renesas_ra_ospi_b_nor
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/init.h>
#include <soc.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/pinctrl.h>
#include "flash_renesas_ra_ospi_b.h"
LOG_MODULE_REGISTER(flash_renesas_ra_ospi_b, CONFIG_FLASH_LOG_LEVEL);
struct flash_renesas_ra_ospi_b_data {
ospi_b_instance_ctrl_t ospi_b_ctrl;
spi_flash_cfg_t ospi_b_cfg;
ospi_b_timing_setting_t ospi_b_timing_settings;
ospi_b_xspi_command_set_t ospi_b_high_speed_command_set;
ospi_b_extended_cfg_t ospi_b_config_extend;
struct k_sem sem;
};
struct flash_renesas_ra_ospi_b_config {
size_t flash_size;
int protocol;
int data_rate;
uint32_t max_frequency;
const struct device *clock_dev;
struct clock_control_ra_subsys_cfg clock_subsys;
const struct pinctrl_dev_config *pcfg;
};
static const struct flash_parameters ospi_b_ra_param = {
.write_block_size = DT_PROP(RA_OSPI_B_NOR_NODE, write_block_size),
.erase_value = ERASE_VALUE,
};
static void acquire_device(const struct device *dev)
{
struct flash_renesas_ra_ospi_b_data *dev_data = dev->data;
k_sem_take(&dev_data->sem, K_FOREVER);
}
static void release_device(const struct device *dev)
{
struct flash_renesas_ra_ospi_b_data *dev_data = dev->data;
k_sem_give(&dev_data->sem);
}
static fsp_err_t flash_renesas_ra_ospi_b_wait_operation(ospi_b_instance_ctrl_t *p_ctrl,
uint32_t timeout)
{
fsp_err_t err = FSP_SUCCESS;
spi_flash_status_t status = {RESET_VALUE};
status.write_in_progress = true;
while (status.write_in_progress) {
/* Get device status */
R_OSPI_B_StatusGet(p_ctrl, &status);
if (timeout == RESET_VALUE) {
LOG_ERR("Time out for operation");
return FSP_ERR_TIMEOUT;
}
k_sleep(K_USEC(50));
timeout--;
}
return err;
}
static fsp_err_t flash_renesas_ra_ospi_b_write_enable(ospi_b_instance_ctrl_t *p_ctrl)
{
fsp_err_t err = FSP_SUCCESS;
spi_flash_direct_transfer_t transfer = {RESET_VALUE};
/* Transfer write enable command */
transfer = (SPI_FLASH_PROTOCOL_EXTENDED_SPI == p_ctrl->spi_protocol)
? direct_transfer[TRANSFER_WRITE_ENABLE_SPI]
: direct_transfer[TRANSFER_WRITE_ENABLE_OSPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
if (err != FSP_SUCCESS) {
return err;
}
/* Read Status Register */
transfer = (SPI_FLASH_PROTOCOL_EXTENDED_SPI == p_ctrl->spi_protocol)
? direct_transfer[TRANSFER_READ_STATUS_SPI]
: direct_transfer[TRANSFER_READ_STATUS_OSPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
if (err != FSP_SUCCESS) {
return err;
}
/* Check Write Enable bit in Status Register */
if (SPI_NOR_WREN_MASK != (transfer.data & SPI_NOR_WREN_MASK)) {
LOG_ERR("Write enable failed");
return FSP_ERR_ABORTED;
}
return err;
}
static fsp_err_t flash_renesas_ra_ospi_b_setup_calibrate_data(ospi_b_instance_ctrl_t *p_ctrl)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t autocalibration_data[] = {0xFFFF0000U, 0x000800FFU, 0x00FFF700U, 0xF700F708U};
/* Verify auto-calibration data */
if (memcmp((uint8_t *)APP_ADDRESS(SECTOR_THREE), &autocalibration_data,
sizeof(autocalibration_data)) != RESET_VALUE) {
/* Erase the flash sector that stores auto-calibration data */
err = R_OSPI_B_Erase(p_ctrl, (uint8_t *)APP_ADDRESS(SECTOR_THREE),
SPI_NOR_SECTOR_SIZE);
if (err != FSP_SUCCESS) {
return err;
}
/* Wait until erase operation completes */
err = flash_renesas_ra_ospi_b_wait_operation(p_ctrl, TIME_ERASE_4K);
if (err != FSP_SUCCESS) {
return err;
}
/* Write auto-calibration data to the flash */
err = R_OSPI_B_Write(p_ctrl, (uint8_t *)&autocalibration_data,
(uint8_t *)APP_ADDRESS(SECTOR_THREE),
sizeof(autocalibration_data));
if (err != FSP_SUCCESS) {
return err;
}
/* Wait until write operation completes */
err = flash_renesas_ra_ospi_b_wait_operation(p_ctrl, TIME_WRITE);
if (err != FSP_SUCCESS) {
return err;
}
}
return err;
}
static fsp_err_t flash_renesas_ra_ospi_b_spi_mode_init(ospi_b_instance_ctrl_t *p_ctrl,
spi_flash_cfg_t *p_cfg)
{
/* By default, the flash device is in SPI mode, so it is necessary to open the OSPI module
* in SPI mode
*/
fsp_err_t err = FSP_SUCCESS;
spi_flash_direct_transfer_t transfer = {RESET_VALUE};
/* Open OSPI module */
err = R_OSPI_B_Open(p_ctrl, p_cfg);
/* DDR sampling window extend */
R_XSPI->LIOCFGCS_b[p_ctrl->channel].DDRSMPEX = 1;
/* Switch OSPI module to 1S-1S-1S mode to configure flash device */
err = R_OSPI_B_SpiProtocolSet(p_ctrl, SPI_FLASH_PROTOCOL_EXTENDED_SPI);
if (err != FSP_SUCCESS) {
return err;
}
/* Reset flash device by driving OM_RESET pin */
R_XSPI->LIOCTL_b.RSTCS0 = 0;
k_sleep(K_USEC(500));
R_XSPI->LIOCTL_b.RSTCS0 = 1;
k_sleep(K_NSEC(50));
/* Transfer write enable command */
err = flash_renesas_ra_ospi_b_write_enable(p_ctrl);
if (err != FSP_SUCCESS) {
return err;
}
/* Write to CFR2V to configure Address Byte Length and Memory Array Read Latency */
transfer = direct_transfer[TRANSFER_WRITE_CFR2V_SPI];
transfer.address_length = ADDRESS_LENGTH_THREE;
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
if (err != FSP_SUCCESS) {
return err;
}
/* Transfer write enable command */
err = flash_renesas_ra_ospi_b_write_enable(p_ctrl);
if (err != FSP_SUCCESS) {
return err;
}
/* Write to CFR3V to configure Volatile Register Read Latency */
transfer = direct_transfer[TRANSFER_WRITE_CFR3V_SPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
if (err != FSP_SUCCESS) {
return err;
}
/* Read back and verify CFR2V register data */
transfer = direct_transfer[TRANSFER_READ_CFR2V_SPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
if (err != FSP_SUCCESS) {
return err;
}
if (DATA_CFR2V_REGISTER != (uint8_t)transfer.data) {
LOG_ERR("Verify CFR2V register data Failed");
return FSP_ERR_ABORTED;
}
/* Read back and verify CFR3V register data */
transfer = direct_transfer[TRANSFER_READ_CFR3V_SPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
if (err != FSP_SUCCESS) {
return err;
}
if (DATA_CFR3V_REGISTER != (uint8_t)transfer.data) {
LOG_ERR("Verify CFR3V register data Failed");
return FSP_ERR_ABORTED;
}
/* Setup calibrate data */
err = flash_renesas_ra_ospi_b_setup_calibrate_data(p_ctrl);
if (err != FSP_SUCCESS) {
return err;
}
return err;
}
static fsp_err_t flash_renesas_ra_ospi_b_set_protocol_to_opi(ospi_b_instance_ctrl_t *p_ctrl,
const struct device *dev)
{
fsp_err_t err = FSP_SUCCESS;
spi_flash_direct_transfer_t transfer = {RESET_VALUE};
/* Transfer write enable command */
err = flash_renesas_ra_ospi_b_write_enable(p_ctrl);
if (err != FSP_SUCCESS) {
return err;
}
/* Write to CFR5V Register to Configure flash device interface mode */
transfer = direct_transfer[TRANSFER_WRITE_CFR5V_SPI];
transfer.data = DATA_SET_OSPI_CFR5V_REGISTER;
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
if (err != FSP_SUCCESS) {
return err;
}
/* Switch OSPI module mode to OPI mode */
err = R_OSPI_B_SpiProtocolSet(p_ctrl, SPI_FLASH_PROTOCOL_8D_8D_8D);
if (err != FSP_SUCCESS) {
return err;
}
/* Read back and verify CFR5V register data */
transfer = direct_transfer[TRANSFER_READ_CFR5V_OSPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
if (err != FSP_SUCCESS) {
return err;
}
if (DATA_SET_OSPI_CFR5V_REGISTER != (uint8_t)transfer.data) {
LOG_ERR("Verify CFR5V register data Failed");
return FSP_ERR_ABORTED;
}
return err;
}
static inline bool flash_renesas_ra_ospi_b_is_valid_address(const struct device *dev, off_t offset,
size_t len)
{
const struct flash_renesas_ra_ospi_b_config *config = dev->config;
return (offset >= 0 && (offset < (config->flash_size)) &&
(len <= (config->flash_size - offset)));
}
#if defined(CONFIG_FLASH_EX_OP_ENABLED)
static int flash_renesas_ra_ospi_b_ex_op(const struct device *dev, uint16_t code,
const uintptr_t in, void *out)
{
struct flash_renesas_ra_ospi_b_data *ospi_b_data = dev->data;
spi_flash_direct_transfer_t transfer = {RESET_VALUE};
int err = -ENOTSUP;
ARG_UNUSED(in);
ARG_UNUSED(out);
acquire_device(dev);
if (code == FLASH_EX_OP_RESET) {
err = flash_renesas_ra_ospi_b_write_enable(&ospi_b_data->ospi_b_ctrl);
if (err == FSP_SUCCESS) {
/* Enable reset */
transfer = (SPI_FLASH_PROTOCOL_EXTENDED_SPI ==
ospi_b_data->ospi_b_ctrl.spi_protocol)
? direct_transfer[TRANSFER_RESET_ENABLE_SPI]
: direct_transfer[TRANSFER_RESET_ENABLE_OSPI];
err = R_OSPI_B_DirectTransfer(&ospi_b_data->ospi_b_ctrl, &transfer,
SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
}
if (err == FSP_SUCCESS) {
/* Reset Register */
transfer = (SPI_FLASH_PROTOCOL_EXTENDED_SPI ==
ospi_b_data->ospi_b_ctrl.spi_protocol)
? direct_transfer[TRANSFER_RESET_MEM_SPI]
: direct_transfer[TRANSFER_RESET_MEM_OSPI];
err = R_OSPI_B_DirectTransfer(&ospi_b_data->ospi_b_ctrl, &transfer,
SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
}
if (err != FSP_SUCCESS) {
err = -EIO;
}
}
release_device(dev);
return err;
}
#endif
#if CONFIG_FLASH_PAGE_LAYOUT
#define SET_PAGES(node_id) \
{.pages_count = DT_PROP(node_id, pages_count), .pages_size = DT_PROP(node_id, pages_size)},
static const struct flash_pages_layout ospi_b_flash_ra_layout[] = {
DT_FOREACH_CHILD(DT_NODELABEL(pages_layout), SET_PAGES)};
void flash_renesas_ra_ospi_b_page_layout(const struct device *dev,
const struct flash_pages_layout **layout,
size_t *layout_size)
{
ARG_UNUSED(dev);
*layout = ospi_b_flash_ra_layout;
*layout_size = ARRAY_SIZE(ospi_b_flash_ra_layout);
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
#if defined(CONFIG_FLASH_JESD216_API)
static fsp_err_t flash_renesas_ra_ospi_b_read_device_id(ospi_b_instance_ctrl_t *p_ctrl,
uint8_t *const p_id)
{
fsp_err_t err = FSP_SUCCESS;
spi_flash_direct_transfer_t transfer = {RESET_VALUE};
/* Read and check flash device ID */
transfer = (SPI_FLASH_PROTOCOL_EXTENDED_SPI == p_ctrl->spi_protocol)
? direct_transfer[TRANSFER_READ_DEVICE_ID_SPI]
: direct_transfer[TRANSFER_READ_DEVICE_ID_OSPI];
err = R_OSPI_B_DirectTransfer(p_ctrl, &transfer, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
if (err != FSP_SUCCESS) {
return err;
}
/* Get flash device ID */
memcpy(p_id, &transfer.data, sizeof(transfer.data));
return err;
}
static int flash_renesas_ra_ospi_b_read_jedec_id(const struct device *dev, uint8_t *id)
{
struct flash_renesas_ra_ospi_b_data *ospi_b_data = dev->data;
int err = 0;
if (id == NULL) {
return -EINVAL;
}
acquire_device(dev);
err = flash_renesas_ra_ospi_b_read_device_id(&ospi_b_data->ospi_b_ctrl, id);
if (err) {
LOG_ERR("Failed to read jedec id");
err = -EIO;
} else {
LOG_INF("Manuf ID = %02x Memory Type = %02x Memory Density = %02x ID Length "
"= %02x\n",
id[0], id[1], id[2], id[3]);
}
release_device(dev);
return err;
}
static int flash_renesas_ra_ospi_b_sfdp_read(const struct device *dev, off_t offset, void *data,
size_t len)
{
struct flash_renesas_ra_ospi_b_data *ospi_b_data = dev->data;
spi_flash_direct_transfer_t transfer = {RESET_VALUE};
uint64_t size;
uint8_t *p_src;
int err = 0;
if (len == 0) {
return 0;
}
if (data != NULL) {
p_src = data;
} else {
return -EINVAL;
}
acquire_device(dev);
if (ospi_b_data->ospi_b_ctrl.spi_protocol == SPI_FLASH_PROTOCOL_EXTENDED_SPI) {
transfer = direct_transfer[TRANSFER_READ_SFDP_ID_SPI];
} else {
transfer = direct_transfer[TRANSFER_READ_SFDP_ID_OSPI];
}
while (len > 0) {
size = len > transfer.data_length ? transfer.data_length : len;
transfer.address = offset;
transfer.data_length = size;
err = R_OSPI_B_DirectTransfer(&ospi_b_data->ospi_b_ctrl, &transfer,
SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
if (err) {
LOG_ERR("Failed to read SFDP id");
release_device(dev);
return -EIO;
}
memcpy(p_src, &transfer.data, size);
len -= size;
offset += size;
p_src += size;
}
release_device(dev);
return err;
}
#endif
static int flash_renesas_ra_ospi_b_erase(const struct device *dev, off_t offset, size_t len)
{
struct flash_renesas_ra_ospi_b_data *ospi_b_data = dev->data;
const struct flash_renesas_ra_ospi_b_config *config = dev->config;
uint32_t erase_size, erase_timeout;
int err = 0;
struct flash_pages_info page_info_start, page_info_end;
int rc;
if (!len) {
return 0;
} else if (len % SPI_NOR_SECTOR_SIZE != 0) {
LOG_ERR("Wrong sector size 0x%x", len);
return -EINVAL;
}
if (!flash_renesas_ra_ospi_b_is_valid_address(dev, offset, len)) {
LOG_ERR("Address or size exceeds expected values: "
"addr 0x%lx, size %u",
(long)offset, len);
return -EINVAL;
}
/* check offset and len that valid in sector layout */
rc = flash_get_page_info_by_offs(dev, offset, &page_info_start);
if ((rc != 0) || (offset != page_info_start.start_offset)) {
LOG_ERR("The offset 0x%lx is not aligned with the starting sector", (long)offset);
return -EINVAL;
}
rc = flash_get_page_info_by_offs(dev, (offset + len), &page_info_end);
if ((rc != 0) || ((offset + len) != page_info_end.start_offset)) {
LOG_ERR("The size %u is not aligned with the ending sector", len);
return -EINVAL;
}
acquire_device(dev);
while (len > 0) {
if (offset == 0 && len == config->flash_size) {
/* Chip erase */
LOG_INF("Chip Erase");
erase_size = SPI_FLASH_ERASE_SIZE_CHIP_ERASE;
erase_timeout = UINT32_MAX;
} else if ((offset) <= (off_t)(ospi_b_flash_ra_layout[0].pages_size *
(ospi_b_flash_ra_layout[0].pages_count))) {
erase_size = SPI_NOR_SECTOR_SIZE;
erase_timeout = TIME_ERASE_4K;
} else {
erase_size = SECTOR_SIZE_256K;
erase_timeout = TIME_ERASE_256K;
}
err = R_OSPI_B_Erase(
&ospi_b_data->ospi_b_ctrl,
(uint8_t *)(BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS + offset),
erase_size);
if (err != FSP_SUCCESS) {
err = -EIO;
break;
}
err = flash_renesas_ra_ospi_b_wait_operation(&ospi_b_data->ospi_b_ctrl,
erase_timeout);
if (err != FSP_SUCCESS) {
err = -EIO;
break;
}
offset += erase_size;
len -= len < erase_size ? len : erase_size;
}
release_device(dev);
return err;
}
static int flash_renesas_ra_ospi_b_read(const struct device *dev, off_t offset, void *data,
size_t len)
{
if (!len) {
return 0;
}
if (!flash_renesas_ra_ospi_b_is_valid_address(dev, offset, len)) {
LOG_ERR("address or size exceeds expected values: "
"addr 0x%lx, size %zu",
(long)offset, len);
return -EINVAL;
}
memcpy(data, (uint8_t *)(BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS) + offset, len);
return 0;
}
static int flash_renesas_ra_ospi_b_write(const struct device *dev, off_t offset, const void *data,
size_t len)
{
struct flash_renesas_ra_ospi_b_data *ospi_b_data = dev->data;
int err = 0;
uint32_t size;
const uint8_t *p_src;
if (!len) {
return 0;
}
if (data != NULL) {
p_src = data;
} else {
return -EINVAL;
}
if (!flash_renesas_ra_ospi_b_is_valid_address(dev, offset, len)) {
LOG_ERR("address or size exceeds expected values: "
"addr 0x%lx, size %zu",
(long)offset, len);
return -EINVAL;
}
acquire_device(dev);
while (len > 0) {
size = len > ospi_b_data->ospi_b_cfg.page_size_bytes
? ospi_b_data->ospi_b_cfg.page_size_bytes
: len;
err = R_OSPI_B_Write(
&ospi_b_data->ospi_b_ctrl, p_src,
(uint8_t *)(BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS + offset), size);
if (err != FSP_SUCCESS) {
err = -EIO;
break;
}
err = flash_renesas_ra_ospi_b_wait_operation(&ospi_b_data->ospi_b_ctrl, TIME_WRITE);
if (err != FSP_SUCCESS) {
err = -EIO;
break;
}
len -= size;
offset += size;
p_src = p_src + size;
}
release_device(dev);
return err;
}
static const struct flash_parameters *
flash_renesas_ra_ospi_b_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &ospi_b_ra_param;
}
static int flash_renesas_ra_ospi_b_get_size(const struct device *dev, uint64_t *size)
{
const struct flash_renesas_ra_ospi_b_config *config = dev->config;
*size = (uint64_t)config->flash_size;
return 0;
}
static DEVICE_API(flash, flash_renesas_ra_ospi_b_api) = {
.erase = flash_renesas_ra_ospi_b_erase,
.write = flash_renesas_ra_ospi_b_write,
.read = flash_renesas_ra_ospi_b_read,
.get_parameters = flash_renesas_ra_ospi_b_get_parameters,
.get_size = flash_renesas_ra_ospi_b_get_size,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = flash_renesas_ra_ospi_b_page_layout,
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
#if defined(CONFIG_FLASH_JESD216_API)
.sfdp_read = flash_renesas_ra_ospi_b_sfdp_read,
.read_jedec_id = flash_renesas_ra_ospi_b_read_jedec_id,
#endif /* CONFIG_FLASH_JESD216_API */
#if defined(CONFIG_FLASH_EX_OP_ENABLED)
.ex_op = flash_renesas_ra_ospi_b_ex_op,
#endif /* CONFIG_FLASH_EX_OP_ENABLED */
};
static int flash_renesas_ra_ospi_b_init(const struct device *dev)
{
const struct flash_renesas_ra_ospi_b_config *config = dev->config;
struct flash_renesas_ra_ospi_b_data *data = dev->data;
uint32_t clock_freq;
int err = 0;
/* protocol/data_rate of XSPI checking */
if (config->protocol == XSPI_DUAL_MODE || config->protocol == XSPI_QUAD_MODE) {
LOG_ERR("XSPI mode DUAL|QUAD currently not support");
return -ENOTSUP;
} else if (((config->protocol != XSPI_OCTO_MODE) &&
(config->data_rate == XSPI_DTR_TRANSFER)) ||
((config->protocol == XSPI_OCTO_MODE) &&
(config->data_rate == XSPI_STR_TRANSFER))) {
LOG_ERR("XSPI mode SPI/DTR or OPI/STR is not valid");
return -ENOTSUP;
}
if (!device_is_ready(config->clock_dev)) {
LOG_ERR("Clock control device not ready");
return -ENODEV;
}
err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_subsys);
if (err < 0) {
LOG_ERR("Could not initialize clock (%d)", err);
return err;
}
err = clock_control_get_rate(config->clock_dev,
(clock_control_subsys_t)&config->clock_subsys, &clock_freq);
if (err) {
LOG_ERR("Failed to get clock frequency (%d)", err);
return err;
}
if ((config->protocol == XSPI_SPI_MODE && (config->max_frequency / 2) < clock_freq) ||
(config->protocol == XSPI_OCTO_MODE && (config->max_frequency) < clock_freq)) {
LOG_ERR("Invalid clock frequency (%u)", clock_freq);
return -EINVAL;
}
err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
if (err) {
LOG_ERR("Failed to configure pins (%d)", err);
return err;
}
k_sem_init(&data->sem, 1, 1);
err = flash_renesas_ra_ospi_b_spi_mode_init(&data->ospi_b_ctrl, &data->ospi_b_cfg);
if (err) {
LOG_ERR("Init SPI mode failed");
return -EIO;
}
if (config->protocol == XSPI_OCTO_MODE) {
err = flash_renesas_ra_ospi_b_set_protocol_to_opi(&data->ospi_b_ctrl, dev);
if (err) {
LOG_ERR("Init OPI mode failed");
return -EIO;
}
}
LOG_INF("Mode: %d Freq: %u", config->protocol, clock_freq);
return err;
}
PINCTRL_DT_DEFINE(DT_INST_PARENT(0));
static const struct flash_renesas_ra_ospi_b_config ospi_b_config = {
.flash_size = DT_REG_SIZE(RA_OSPI_B_NOR_NODE),
.protocol = DT_PROP(RA_OSPI_B_NOR_NODE, protocol_mode),
.data_rate = DT_PROP(RA_OSPI_B_NOR_NODE, data_rate),
.max_frequency = DT_PROP(RA_OSPI_B_NOR_NODE, ospi_max_frequency),
.clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(0))),
.clock_subsys = {.mstp = (uint32_t)DT_CLOCKS_CELL(DT_INST_PARENT(0), mstp),
.stop_bit = (uint32_t)DT_CLOCKS_CELL(DT_INST_PARENT(0), stop_bit)},
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(0))};
static struct flash_renesas_ra_ospi_b_data ospi_b_data = {
.ospi_b_timing_settings = {.command_to_command_interval = OSPI_B_COMMAND_INTERVAL_CLOCKS_2,
.cs_pullup_lag = OSPI_B_COMMAND_CS_PULLUP_CLOCKS_NO_EXTENSION,
.cs_pulldown_lead =
OSPI_B_COMMAND_CS_PULLDOWN_CLOCKS_NO_EXTENSION},
.ospi_b_high_speed_command_set = {.protocol = SPI_FLASH_PROTOCOL_8D_8D_8D,
.command_bytes = OSPI_B_COMMAND_BYTES_2,
.read_command = SPI_NOR_OCMD_READ,
.page_program_command = SPI_NOR_OCMD_PP_4B,
.write_enable_command = SPI_NOR_OCMD_WEN,
.status_command = SPI_NOR_OCMD_RSR,
.read_dummy_cycles = SPI_NOR_DUMMY_RD_MEM_OCTAL,
.program_dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL,
.status_dummy_cycles = SPI_NOR_DUMMY_RD_REG_OCTAL,
.p_erase_command_list = high_speed_erase_command_list,
.erase_command_list_length = ERASE_COMMAND_LENGTH(
high_speed_erase_command_list)},
.ospi_b_config_extend = {.channel = OSPI_B_DEVICE_NUMBER_1,
.data_latch_delay_clocks = 0,
.p_timing_settings = &ospi_b_data.ospi_b_timing_settings,
.p_xspi_command_set_list =
&ospi_b_data.ospi_b_high_speed_command_set,
.xspi_command_set_list_length = 1U,
.p_autocalibration_preamble_pattern_addr =
APP_ADDRESS(SECTOR_THREE),
.read_dummy_cycles = SPI_NOR_DUMMY_RD_MEM,
.program_dummy_cycles = SPI_NOR_DUMMY_WR,
.status_dummy_cycles = 0},
.ospi_b_cfg = {.spi_protocol = SPI_FLASH_PROTOCOL_1S_1S_1S,
.read_mode = SPI_FLASH_READ_MODE_STANDARD,
.address_bytes = SPI_FLASH_ADDRESS_BYTES_4,
.dummy_clocks = SPI_FLASH_DUMMY_CLOCKS_DEFAULT,
.page_program_address_lines = (spi_flash_data_lines_t)0U,
.page_size_bytes = PAGE_SIZE_BYTE,
.write_status_bit = WRITE_STATUS_BIT,
.write_enable_bit = WRITE_ENABLE_BIT,
.page_program_command = SPI_NOR_CMD_PP_4B,
.write_enable_command = SPI_NOR_CMD_WREN,
.status_command = SPI_NOR_CMD_RDSR,
.read_command = SPI_NOR_CMD_READ_FAST,
.xip_enter_command = 0U,
.xip_exit_command = 0U,
.erase_command_list_length = ERASE_COMMAND_LENGTH(erase_command_list),
.p_erase_command_list = &erase_command_list[0],
.p_extend = &ospi_b_data.ospi_b_config_extend}};
DEVICE_DT_INST_DEFINE(0, flash_renesas_ra_ospi_b_init, NULL, &ospi_b_data, &ospi_b_config,
POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, &flash_renesas_ra_ospi_b_api);

View file

@ -0,0 +1,291 @@
/*
* Copyright (c) 2024 Renesas Electronics Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVERS_FLASH_RENESAS_RA_OSPI_B_H_
#define ZEPHYR_DRIVERS_FLASH_RENESAS_RA_OSPI_B_H_
#include <zephyr/drivers/flash.h>
#include <zephyr/dt-bindings/flash_controller/xspi.h>
#include <zephyr/drivers/clock_control/renesas_ra_cgc.h>
#include <r_spi_flash_api.h>
#include <r_ospi_b.h>
#include "spi_nor.h"
/* Device node */
#define RA_OSPI_B_NOR_NODE DT_INST(0, renesas_ra_ospi_b_nor)
/* Flash erase value */
#define ERASE_VALUE (0xff)
/* Page size */
#define PAGE_SIZE_BYTE 64
/* Flash device sector size */
#define SECTOR_SIZE_128K (0x20000)
#define SECTOR_SIZE_256K (0x40000)
/* Flash device timing */
#define TIME_ERASE_256K (16000)
#define TIME_ERASE_4K (1000U)
#define TIME_WRITE (1000U)
/* Bit status */
#define WRITE_STATUS_BIT (0)
#define WRITE_ENABLE_BIT (1)
/* Calibration sector */
#define SECTOR_THREE (2U)
/* Command length */
#define COMMAND_LENGTH_SPI (1U)
#define COMMAND_LENGTH_OSPI (2U)
/* Transfer address length */
#define ADDRESS_DUMMY (0U)
#define ADDRESS_LENGTH_ZERO (0U)
#define ADDRESS_LENGTH_THREE (3U)
#define ADDRESS_LENGTH_FOUR (4U)
/* Transfer data length */
#define DATA_DUMMY (0U)
#define DATA_LENGTH_ZERO (0U)
#define DATA_LENGTH_ONE (1U)
#define DATA_LENGTH_TWO (2U)
#define DATA_LENGTH_FOUR (4U)
#define DATA_LENGTH_EIGHT (8U)
/* Configure flash device */
#define DATA_CFR2V_REGISTER (0x83)
#define DATA_CFR3V_REGISTER (0x40)
#define DATA_SET_SPI_CFR5V_REGISTER (0x40)
#define DATA_SET_OSPI_CFR5V_REGISTER (0x43)
/* Flash device address space mapping */
#define APP_ADDRESS(sector_no) \
((uint8_t *)(BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS + \
((sector_no) * SPI_NOR_SECTOR_SIZE)))
/* Erase command */
static const spi_flash_erase_command_t erase_command_list[] = {
{.command = SPI_NOR_CMD_SE_4B, .size = SPI_NOR_SECTOR_SIZE},
{.command = SPI_NOR_CMD_SE_256KB, .size = SECTOR_SIZE_256K},
{.command = SPI_NOR_CMD_ERCHP, .size = SPI_FLASH_ERASE_SIZE_CHIP_ERASE}};
static const spi_flash_erase_command_t high_speed_erase_command_list[] = {
{.command = SPI_NOR_OCMD_SE_4KB, .size = SPI_NOR_SECTOR_SIZE},
{.command = SPI_NOR_OCMD_SE_256KB, .size = SECTOR_SIZE_256K},
{.command = SPI_NOR_OCMD_ERCHP, .size = SPI_FLASH_ERASE_SIZE_CHIP_ERASE}};
/* Erase command length */
#define ERASE_COMMAND_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0]))
/* Reset value */
#define RESET_VALUE (0x00)
/* Transfer table */
typedef enum e_transfer {
TRANSFER_WRITE_ENABLE_SPI = 0,
TRANSFER_WRITE_CFR2V_SPI,
TRANSFER_WRITE_CFR3V_SPI,
TRANSFER_WRITE_CFR5V_SPI,
TRANSFER_READ_STATUS_SPI,
TRANSFER_READ_CFR2V_SPI,
TRANSFER_READ_CFR3V_SPI,
TRANSFER_READ_CFR5V_SPI,
TRANSFER_READ_DEVICE_ID_SPI,
TRANSFER_READ_SFDP_ID_SPI,
TRANSFER_RESET_ENABLE_SPI,
TRANSFER_RESET_MEM_SPI,
TRANSFER_WRITE_ENABLE_OSPI,
TRANSFER_WRITE_CFR2V_OSPI,
TRANSFER_WRITE_CFR3V_OSPI,
TRANSFER_WRITE_CFR5V_OSPI,
TRANSFER_READ_STATUS_OSPI,
TRANSFER_READ_CFR2V_OSPI,
TRANSFER_READ_CFR3V_OSPI,
TRANSFER_READ_CFR5V_OSPI,
TRANSFER_READ_DEVICE_ID_OSPI,
TRANSFER_READ_SFDP_ID_OSPI,
TRANSFER_RESET_ENABLE_OSPI,
TRANSFER_RESET_MEM_OSPI,
TRANSFER_MAX
} transfer_t;
spi_flash_direct_transfer_t direct_transfer[TRANSFER_MAX] = {
/* Transfer structure for SPI mode */
[TRANSFER_WRITE_ENABLE_SPI] = {.command = SPI_NOR_CMD_WREN,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ZERO,
.dummy_cycles = SPI_NOR_DUMMY_WR},
[TRANSFER_WRITE_CFR2V_SPI] = {.command = SPI_NOR_CMD_WR_WRARG,
.address = SPI_NOR_CFR2V_ADDR,
.data = DATA_CFR2V_REGISTER,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_WR},
[TRANSFER_WRITE_CFR3V_SPI] = {.command = SPI_NOR_CMD_WR_WRARG,
.address = SPI_NOR_CFR3V_ADDR,
.data = DATA_CFR3V_REGISTER,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_WR},
[TRANSFER_WRITE_CFR5V_SPI] = {.command = SPI_NOR_CMD_WR_WRARG,
.address = SPI_NOR_CFR5V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_WR},
[TRANSFER_READ_STATUS_SPI] = {.command = SPI_NOR_CMD_RDSR,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_RD_STATUS},
[TRANSFER_READ_CFR2V_SPI] = {.command = SPI_NOR_CMD_RREG,
.address = SPI_NOR_CFR2V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_RD_REG},
[TRANSFER_READ_CFR3V_SPI] = {.command = SPI_NOR_CMD_RREG,
.address = SPI_NOR_CFR3V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_RD_REG},
[TRANSFER_READ_CFR5V_SPI] = {.command = SPI_NOR_CMD_RREG,
.address = SPI_NOR_CFR5V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_ONE,
.dummy_cycles = SPI_NOR_DUMMY_RD_REG},
[TRANSFER_READ_DEVICE_ID_SPI] = {.command = SPI_NOR_CMD_RDID,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_FOUR,
.dummy_cycles = SPI_NOR_DUMMY_RD_STATUS},
[TRANSFER_READ_SFDP_ID_SPI] = {.command = SPI_NOR_CMD_RSFDPID,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_THREE,
.data_length = DATA_LENGTH_EIGHT,
.dummy_cycles = SPI_NOR_DUMMY_RD_SFDP},
[TRANSFER_RESET_ENABLE_SPI] = {.command = SPI_NOR_CMD_RESET_EN,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ZERO,
.dummy_cycles = SPI_NOR_DUMMY_WR},
[TRANSFER_RESET_MEM_SPI] = {.command = SPI_NOR_CMD_RESET_MEM,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_SPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ZERO,
.dummy_cycles = SPI_NOR_DUMMY_WR},
/* Transfer structure for OPI mode */
[TRANSFER_WRITE_ENABLE_OSPI] = {.command = SPI_NOR_OCMD_WEN,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ZERO,
.dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL},
[TRANSFER_WRITE_CFR2V_OSPI] = {.command = SPI_NOR_OCMD_WR_REG2,
.address = SPI_NOR_CFR2V_ADDR,
.data = DATA_CFR2V_REGISTER,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL},
[TRANSFER_WRITE_CFR3V_OSPI] = {.command = SPI_NOR_OCMD_WR_REG2,
.address = SPI_NOR_CFR3V_ADDR,
.data = DATA_CFR3V_REGISTER,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL},
[TRANSFER_WRITE_CFR5V_OSPI] = {.command = SPI_NOR_OCMD_WR_REG2,
.address = SPI_NOR_CFR5V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL},
[TRANSFER_READ_STATUS_OSPI] = {.command = SPI_NOR_OCMD_RSR,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_RD_STATUS_OCTAL},
[TRANSFER_READ_CFR2V_OSPI] = {.command = SPI_NOR_OCMD_RSR,
.address = SPI_NOR_CFR2V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_RD_REG_OCTAL},
[TRANSFER_READ_CFR3V_OSPI] = {.command = SPI_NOR_OCMD_RSR,
.address = SPI_NOR_CFR3V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_RD_REG_OCTAL},
[TRANSFER_READ_CFR5V_OSPI] = {.command = SPI_NOR_OCMD_RREG,
.address = SPI_NOR_CFR5V_ADDR,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_TWO,
.dummy_cycles = SPI_NOR_DUMMY_RD_REG_OCTAL},
[TRANSFER_READ_DEVICE_ID_OSPI] = {.command = SPI_NOR_OCMD_RDID,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_FOUR,
.dummy_cycles = SPI_NOR_DUMMY_RD_STATUS_OCTAL},
[TRANSFER_READ_SFDP_ID_OSPI] = {.command = SPI_NOR_OCMD_RSFDPID,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_FOUR,
.data_length = DATA_LENGTH_EIGHT,
.dummy_cycles = SPI_NOR_DUMMY_RD_SFDP_OCTAL},
[TRANSFER_RESET_ENABLE_OSPI] = {.command = SPI_NOR_OCMD_RST_EN,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ZERO,
.dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL},
[TRANSFER_RESET_MEM_OSPI] = {.command = SPI_NOR_OCMD_RST_MEM,
.address = ADDRESS_DUMMY,
.data = DATA_DUMMY,
.command_length = COMMAND_LENGTH_OSPI,
.address_length = ADDRESS_LENGTH_ZERO,
.data_length = DATA_LENGTH_ZERO,
.dummy_cycles = SPI_NOR_DUMMY_WR_OCTAL},
};
#endif /* ZEPHYR_DRIVERS_FLASH_RENESAS_RA_OSPI_B_H_ */

View file

@ -9,110 +9,146 @@
#include <zephyr/sys/util.h> #include <zephyr/sys/util.h>
#define SPI_NOR_MAX_ID_LEN 3 #define SPI_NOR_MAX_ID_LEN 3
/* Status register bits */ /* Status register bits */
#define SPI_NOR_WIP_BIT BIT(0) /* Write in progress */ #define SPI_NOR_WIP_BIT BIT(0) /* Write in progress */
#define SPI_NOR_WEL_BIT BIT(1) /* Write enable latch */ #define SPI_NOR_WEL_BIT BIT(1) /* Write enable latch */
/* Flash opcodes */ /* Flash opcodes */
#define SPI_NOR_CMD_WRSR 0x01 /* Write status register */ #define SPI_NOR_CMD_WRSR 0x01 /* Write status register */
#define SPI_NOR_CMD_RDSR 0x05 /* Read status register */ #define SPI_NOR_CMD_RDSR 0x05 /* Read status register */
#define SPI_NOR_CMD_WRSR2 0x31 /* Write status register 2 */ #define SPI_NOR_CMD_WRSR2 0x31 /* Write status register 2 */
#define SPI_NOR_CMD_RDSR2 0x35 /* Read status register 2 */ #define SPI_NOR_CMD_RDSR2 0x35 /* Read status register 2 */
#define SPI_NOR_CMD_RDSR3 0x15 /* Read status register 3 */ #define SPI_NOR_CMD_RDSR3 0x15 /* Read status register 3 */
#define SPI_NOR_CMD_WRSR3 0x11 /* Write status register 3 */ #define SPI_NOR_CMD_WRSR3 0x11 /* Write status register 3 */
#define SPI_NOR_CMD_READ 0x03 /* Read data */ #define SPI_NOR_CMD_READ 0x03 /* Read data */
#define SPI_NOR_CMD_READ_FAST 0x0B /* Read data */ #define SPI_NOR_CMD_READ_FAST 0x0B /* Read data */
#define SPI_NOR_CMD_DREAD 0x3B /* Read data (1-1-2) */ #define SPI_NOR_CMD_DREAD 0x3B /* Read data (1-1-2) */
#define SPI_NOR_CMD_2READ 0xBB /* Read data (1-2-2) */ #define SPI_NOR_CMD_2READ 0xBB /* Read data (1-2-2) */
#define SPI_NOR_CMD_QREAD 0x6B /* Read data (1-1-4) */ #define SPI_NOR_CMD_QREAD 0x6B /* Read data (1-1-4) */
#define SPI_NOR_CMD_4READ 0xEB /* Read data (1-4-4) */ #define SPI_NOR_CMD_4READ 0xEB /* Read data (1-4-4) */
#define SPI_NOR_CMD_WREN 0x06 /* Write enable */ #define SPI_NOR_CMD_WREN 0x06 /* Write enable */
#define SPI_NOR_CMD_WRDI 0x04 /* Write disable */ #define SPI_NOR_CMD_WRDI 0x04 /* Write disable */
#define SPI_NOR_CMD_PP 0x02 /* Page program */ #define SPI_NOR_CMD_PP 0x02 /* Page program */
#define SPI_NOR_CMD_PP_1_1_2 0xA2 /* Dual Page program (1-1-2) */ #define SPI_NOR_CMD_PP_1_1_2 0xA2 /* Dual Page program (1-1-2) */
#define SPI_NOR_CMD_PP_1_1_4 0x32 /* Quad Page program (1-1-4) */ #define SPI_NOR_CMD_PP_1_1_4 0x32 /* Quad Page program (1-1-4) */
#define SPI_NOR_CMD_PP_1_4_4 0x38 /* Quad Page program (1-4-4) */ #define SPI_NOR_CMD_PP_1_4_4 0x38 /* Quad Page program (1-4-4) */
#define SPI_NOR_CMD_RDCR 0x15 /* Read control register */ #define SPI_NOR_CMD_RDCR 0x15 /* Read control register */
#define SPI_NOR_CMD_SE 0x20 /* Sector erase */ #define SPI_NOR_CMD_SE 0x20 /* Sector erase */
#define SPI_NOR_CMD_SE_4B 0x21 /* Sector erase 4 byte address*/ #define SPI_NOR_CMD_SE_4B 0x21 /* Sector erase 4 byte address*/
#define SPI_NOR_CMD_BE_32K 0x52 /* Block erase 32KB */ #define SPI_NOR_CMD_BE_32K 0x52 /* Block erase 32KB */
#define SPI_NOR_CMD_BE 0xD8 /* Block erase */ #define SPI_NOR_CMD_BE 0xD8 /* Block erase */
#define SPI_NOR_CMD_BE_4B 0xDC /* Block erase 4 byte address*/ #define SPI_NOR_CMD_BE_4B 0xDC /* Block erase 4 byte address*/
#define SPI_NOR_CMD_CE 0xC7 /* Chip erase */ #define SPI_NOR_CMD_CE 0xC7 /* Chip erase */
#define SPI_NOR_CMD_RDID 0x9F /* Read JEDEC ID */ #define SPI_NOR_CMD_RDID 0x9F /* Read JEDEC ID */
#define SPI_NOR_CMD_ULBPR 0x98 /* Global Block Protection Unlock */ #define SPI_NOR_CMD_ULBPR 0x98 /* Global Block Protection Unlock */
#define SPI_NOR_CMD_4BA 0xB7 /* Enter 4-Byte Address Mode */ #define SPI_NOR_CMD_4BA 0xB7 /* Enter 4-Byte Address Mode */
#define SPI_NOR_CMD_DPD 0xB9 /* Deep Power Down */ #define SPI_NOR_CMD_DPD 0xB9 /* Deep Power Down */
#define SPI_NOR_CMD_RDPD 0xAB /* Release from Deep Power Down */ #define SPI_NOR_CMD_RDPD 0xAB /* Release from Deep Power Down */
#define SPI_NOR_CMD_WR_CFGREG2 0x72 /* Write config register 2 */ #define SPI_NOR_CMD_WR_CFGREG2 0x72 /* Write config register 2 */
#define SPI_NOR_CMD_RD_CFGREG2 0x71 /* Read config register 2 */ #define SPI_NOR_CMD_RD_CFGREG2 0x71 /* Read config register 2 */
#define SPI_NOR_CMD_RESET_EN 0x66 /* Reset Enable */ #define SPI_NOR_CMD_RESET_EN 0x66 /* Reset Enable */
#define SPI_NOR_CMD_RESET_MEM 0x99 /* Reset Memory */ #define SPI_NOR_CMD_RESET_MEM 0x99 /* Reset Memory */
#define SPI_NOR_CMD_BULKE 0x60 /* Bulk Erase */ #define SPI_NOR_CMD_BULKE 0x60 /* Bulk Erase */
#define SPI_NOR_CMD_READ_4B 0x13 /* Read data 4 Byte Address */ #define SPI_NOR_CMD_READ_4B 0x13 /* Read data 4 Byte Address */
#define SPI_NOR_CMD_READ_FAST_4B 0x0C /* Fast Read 4 Byte Address */ #define SPI_NOR_CMD_READ_FAST_4B 0x0C /* Fast Read 4 Byte Address */
#define SPI_NOR_CMD_DREAD_4B 0x3C /* Read data (1-1-2) 4 Byte Address */ #define SPI_NOR_CMD_DREAD_4B 0x3C /* Read data (1-1-2) 4 Byte Address */
#define SPI_NOR_CMD_2READ_4B 0xBC /* Read data (1-2-2) 4 Byte Address */ #define SPI_NOR_CMD_2READ_4B 0xBC /* Read data (1-2-2) 4 Byte Address */
#define SPI_NOR_CMD_QREAD_4B 0x6C /* Read data (1-1-4) 4 Byte Address */ #define SPI_NOR_CMD_QREAD_4B 0x6C /* Read data (1-1-4) 4 Byte Address */
#define SPI_NOR_CMD_4READ_4B 0xEC /* Read data (1-4-4) 4 Byte Address */ #define SPI_NOR_CMD_4READ_4B 0xEC /* Read data (1-4-4) 4 Byte Address */
#define SPI_NOR_CMD_PP_4B 0x12 /* Page Program 4 Byte Address */ #define SPI_NOR_CMD_PP_4B 0x12 /* Page Program 4 Byte Address */
#define SPI_NOR_CMD_PP_1_1_4_4B 0x34 /* Quad Page program (1-1-4) 4 Byte Address */ #define SPI_NOR_CMD_PP_1_1_4_4B 0x34 /* Quad Page program (1-1-4) 4 Byte Address */
#define SPI_NOR_CMD_PP_1_4_4_4B 0x3e /* Quad Page program (1-4-4) 4 Byte Address */ #define SPI_NOR_CMD_PP_1_4_4_4B 0x3e /* Quad Page program (1-4-4) 4 Byte Address */
#define SPI_NOR_CMD_WR_WRARG 0x71 /* Write Any Register for S28Hx512T */
#define SPI_NOR_CMD_RSFDPID 0x5A /* Read SFDP ID for S28Hx512T */
#define SPI_NOR_CMD_RREG 0x65 /* Read Any Register for S28Hx512T */
#define SPI_NOR_CMD_SE_256KB 0xDC /* Sector Erase 256KB for S28Hx512T */
#define SPI_NOR_CMD_ERCHP 0x60 /* Erase Chip for S28Hx512T */
/* Flash octal opcodes */ /* Flash octal opcodes */
#define SPI_NOR_OCMD_SE 0x21DE /* Octal Sector erase */ #define SPI_NOR_OCMD_SE 0x21DE /* Octal Sector erase */
#define SPI_NOR_OCMD_CE 0xC738 /* Octal Chip erase */ #define SPI_NOR_OCMD_CE 0xC738 /* Octal Chip erase */
#define SPI_NOR_OCMD_RDSR 0x05FA /* Octal Read status register */ #define SPI_NOR_OCMD_RDSR 0x05FA /* Octal Read status register */
#define SPI_NOR_OCMD_DTR_RD 0xEE11 /* Octal IO DTR read command */ #define SPI_NOR_OCMD_DTR_RD 0xEE11 /* Octal IO DTR read command */
#define SPI_NOR_OCMD_RD 0xEC13 /* Octal IO read command */ #define SPI_NOR_OCMD_RD 0xEC13 /* Octal IO read command */
#define SPI_NOR_OCMD_PAGE_PRG 0x12ED /* Octal Page Prog */ #define SPI_NOR_OCMD_PAGE_PRG 0x12ED /* Octal Page Prog */
#define SPI_NOR_OCMD_WREN 0x06F9 /* Octal Write enable */ #define SPI_NOR_OCMD_WREN 0x06F9 /* Octal Write enable */
#define SPI_NOR_OCMD_NOP 0x00FF /* Octal No operation */ #define SPI_NOR_OCMD_NOP 0x00FF /* Octal No operation */
#define SPI_NOR_OCMD_RESET_EN 0x6699 /* Octal Reset Enable */ #define SPI_NOR_OCMD_RESET_EN 0x6699 /* Octal Reset Enable */
#define SPI_NOR_OCMD_RESET_MEM 0x9966 /* Octal Reset Memory */ #define SPI_NOR_OCMD_RESET_MEM 0x9966 /* Octal Reset Memory */
#define SPI_NOR_OCMD_WR_CFGREG2 0x728D /* Octal Write configuration Register2 */ #define SPI_NOR_OCMD_WR_CFGREG2 0x728D /* Octal Write configuration Register2 */
#define SPI_NOR_OCMD_RD_CFGREG2 0x718E /* Octal Read configuration Register2 */ #define SPI_NOR_OCMD_RD_CFGREG2 0x718E /* Octal Read configuration Register2 */
#define SPI_NOR_OCMD_BULKE 0x609F /* Octa Bulk Erase */ #define SPI_NOR_OCMD_BULKE 0x609F /* Octa Bulk Erase */
/* Page, sector, and block size are standard, not configurable. */ #define SPI_NOR_OCMD_WEN 0x0606 /* Octal Write enable for S28Hx512T */
#define SPI_NOR_PAGE_SIZE 0x0100U #define SPI_NOR_OCMD_RSR 0x0505 /* Octal Read status register for S28Hx512T */
#define SPI_NOR_SECTOR_SIZE 0x1000U #define SPI_NOR_OCMD_WR_REG2 0x7171 /* Octal Write config register 2 for S28Hx512T */
#define SPI_NOR_BLOCK_SIZE 0x10000U #define SPI_NOR_OCMD_RDID 0x9F9F /* Octal Read JEDEC ID for S28Hx512T */
#define SPI_NOR_OCMD_RSFDPID 0x5A5A /* Octal Read SFDP ID for S28Hx512T */
#define SPI_NOR_OCMD_RREG 0x6565 /* Octal Read Any Register for S28Hx512T */
#define SPI_NOR_OCMD_PP_4B 0x1212 /* Octal Page Program 4 Byte Address for S28Hx512T */
#define SPI_NOR_OCMD_READ 0xEEEE /* Octal Read data for S28Hx512T */
#define SPI_NOR_OCMD_RST_EN 0x6666 /* Octal Reset Enable for S28Hx512T */
#define SPI_NOR_OCMD_RST_MEM 0x9999 /* Reset Memory for S28Hx512T */
#define SPI_NOR_OCMD_SE_4KB 0x2121 /* Octal Sector Erase 4Kb address for S28Hx512T */
#define SPI_NOR_OCMD_SE_256KB 0xDCDC /* Octal Sector Erase 256Kb address for S28Hx512T */
#define SPI_NOR_OCMD_ERCHP 0x6060 /* Octal Erase Chip for S28Hx512T */
/* Page, sector, and block size are standard, not configurable. */
#define SPI_NOR_PAGE_SIZE 0x0100U
#define SPI_NOR_SECTOR_SIZE 0x1000U
#define SPI_NOR_BLOCK_SIZE 0x10000U
/* Flash Auto-polling values */ /* Flash Auto-polling values */
#define SPI_NOR_WREN_MATCH 0x02 #define SPI_NOR_WREN_MATCH 0x02
#define SPI_NOR_WREN_MASK 0x02 #define SPI_NOR_WREN_MASK 0x02
#define SPI_NOR_WEL_MATCH 0x00 #define SPI_NOR_WEL_MATCH 0x00
#define SPI_NOR_WEL_MASK 0x02 #define SPI_NOR_WEL_MASK 0x02
#define SPI_NOR_MEM_RDY_MATCH 0x00 #define SPI_NOR_MEM_RDY_MATCH 0x00
#define SPI_NOR_MEM_RDY_MASK 0x01 #define SPI_NOR_MEM_RDY_MASK 0x01
#define SPI_NOR_AUTO_POLLING_INTERVAL 0x10 #define SPI_NOR_AUTO_POLLING_INTERVAL 0x10
/* Flash Dummy Cycles values */ /* Flash Dummy Cycles values */
#define SPI_NOR_DUMMY_RD 8U #define SPI_NOR_DUMMY_RD 8U
#define SPI_NOR_DUMMY_RD_OCTAL 6U #define SPI_NOR_DUMMY_RD_OCTAL 6U
#define SPI_NOR_DUMMY_RD_OCTAL_DTR 6U #define SPI_NOR_DUMMY_RD_OCTAL_DTR 6U
#define SPI_NOR_DUMMY_REG_OCTAL 4U #define SPI_NOR_DUMMY_REG_OCTAL 4U
#define SPI_NOR_DUMMY_REG_OCTAL_DTR 5U #define SPI_NOR_DUMMY_REG_OCTAL_DTR 5U
#define SPI_NOR_DUMMY_WR 0U
#define SPI_NOR_DUMMY_WR_OCTAL 0U
#define SPI_NOR_DUMMY_RD_STATUS 0U
#define SPI_NOR_DUMMY_RD_STATUS_OCTAL 4U
#define SPI_NOR_DUMMY_RD_REG 1U
#define SPI_NOR_DUMMY_RD_REG_OCTAL 4U
#define SPI_NOR_DUMMY_RD_MEM 3U
#define SPI_NOR_DUMMY_RD_MEM_OCTAL 10U
#define SPI_NOR_DUMMY_RD_SFDP 8U
#define SPI_NOR_DUMMY_RD_SFDP_OCTAL 8U
/* Memory registers address */ /* Memory registers address */
#define SPI_NOR_REG2_ADDR1 0x0000000 #define SPI_NOR_REG2_ADDR1 0x0000000
#define SPI_NOR_CR2_STR_OPI_EN 0x01 #define SPI_NOR_CR2_STR_OPI_EN 0x01
#define SPI_NOR_CR2_DTR_OPI_EN 0x02 #define SPI_NOR_CR2_DTR_OPI_EN 0x02
#define SPI_NOR_REG2_ADDR3 0x00000300 #define SPI_NOR_REG2_ADDR3 0x00000300
#define SPI_NOR_CR2_DUMMY_CYCLES_66MHZ 0x07 #define SPI_NOR_CR2_DUMMY_CYCLES_66MHZ 0x07
#define SPI_NOR_CFR1V_ADDR 0x00800002
#define SPI_NOR_CFR2V_ADDR 0x00800003
#define SPI_NOR_CFR3V_ADDR 0x00800004
#define SPI_NOR_CFR4V_ADDR 0x00800005
#define SPI_NOR_CFR5V_ADDR 0x00800006
/* Test whether offset is aligned to a given number of bits. */ /* Test whether offset is aligned to a given number of bits. */
#define SPI_NOR_IS_ALIGNED(_ofs, _bits) (((_ofs) & BIT_MASK(_bits)) == 0) #define SPI_NOR_IS_ALIGNED(_ofs, _bits) (((_ofs) & BIT_MASK(_bits)) == 0)
#define SPI_NOR_IS_SECTOR_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 12) #define SPI_NOR_IS_SECTOR_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 12)
#define SPI_NOR_IS_32K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 15) #define SPI_NOR_IS_32K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 15)
#define SPI_NOR_IS_64K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 16) #define SPI_NOR_IS_64K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 16)
#define CMD_RDCR 0x15 /* Read the configuration register. */ #define CMD_RDCR 0x15 /* Read the configuration register. */

View file

@ -7,6 +7,8 @@
#include <zephyr/dt-bindings/clock/ra_clock.h> #include <zephyr/dt-bindings/clock/ra_clock.h>
#include <arm/renesas/ra/ra6/ra6-cm4-common.dtsi> #include <arm/renesas/ra/ra6/ra6-cm4-common.dtsi>
/delete-node/ &qspi0;
/ { / {
soc { soc {
sram0: memory@1ffe0000 { sram0: memory@1ffe0000 {

View file

@ -8,6 +8,8 @@
#include <zephyr/dt-bindings/clock/ra_clock.h> #include <zephyr/dt-bindings/clock/ra_clock.h>
#include <zephyr/dt-bindings/pwm/ra_pwm.h> #include <zephyr/dt-bindings/pwm/ra_pwm.h>
/delete-node/ &qspi0;
/ { / {
soc { soc {
sram0: memory@1ffe0000 { sram0: memory@1ffe0000 {

View file

@ -492,6 +492,14 @@
#pwm-cells = <3>; #pwm-cells = <3>;
status = "disabled"; status = "disabled";
}; };
qspi0: qspi0@64000000 {
compatible = "renesas,ra-qspi";
#address-cells = <0x1>;
#size-cells = <0x1>;
reg = <0x64000000 0x808>;
status = "disabled";
};
}; };
}; };

View file

@ -597,6 +597,14 @@
interrupts = <49 1>, <50 1>; interrupts = <49 1>, <50 1>;
interrupt-names = "frdyi", "fiferr"; interrupt-names = "frdyi", "fiferr";
}; };
qspi0: qspi0@64000000 {
compatible = "renesas,ra-qspi";
#address-cells = <0x1>;
#size-cells = <0x1>;
reg = <0x64000000 0x808>;
status = "disabled";
};
}; };
}; };

View file

@ -477,6 +477,15 @@
status = "disabled"; status = "disabled";
}; };
ospi0: ospi@40268000 {
compatible = "renesas,ra-ospi-b";
reg = <0x40268000 0x19c>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&octaspiclk MSTPB 16>;
status = "disabled";
};
option_setting_ofs: option_setting_ofs@300a100 { option_setting_ofs: option_setting_ofs@300a100 {
compatible = "zephyr,memory-region"; compatible = "zephyr,memory-region";
reg = <0x0300a100 0x18>; reg = <0x0300a100 0x18>;

View file

@ -0,0 +1,65 @@
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
description: Renesas RA OSPI FLASH
compatible: "renesas,ra-ospi-b-nor"
include: [flash-controller.yaml]
on-bus: ospi
properties:
reg:
required: true
description: Flash Memory base address and size in bytes
protocol-mode:
type: int
required: true
description: |
The width and rate of XSPI bus to which flash memory is connected.
Possible values are :
- XSPI_SPI_MODE <1> = SPI mode on 1 data line
- XSPI_DUAL_MODE <2> = Dual mode on 2 data lines
- XSPI_QUAD_MODE <4> = Quad mode on 4 data lines
- XSPI_OCTO_MODE <8> = Octo mode on 8 data lines
enum:
- 1
- 2
- 4
- 8
data-rate:
type: int
required: true
description: |
The SPI data Rate is STR or DTR
Possible values are :
- XSPI_STR_TRANSFER <1> = Single Rate Transfer
- XSPI_DTR_TRANSFER <2> = Dual Rate Transfer (only with XSPI_OCTO_MODE)
ospi-max-frequency:
type: int
required: true
description: Max frequency input on OSPI
write-block-size:
type: int
description: Address alignment required by flash write operations
child-binding:
description: OSPI Flash page layout description
child-binding:
description: Individual flash page layout entry
properties:
pages-count:
description: Number of consecutive pages with size pages-size bytes
type: int
required: true
pages-size:
type: int
required: true

View file

@ -0,0 +1,27 @@
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
description: Renesas RA QSPI FLASH
compatible: "renesas,ra-qspi-nor"
include: [base.yaml]
on-bus: qspi
properties:
reg:
required: true
description: Flash Memory base address and size in bytes
erase-block-size:
type: int
description: address alignment required by flash erase operations
write-block-size:
type: int
description: address alignment required by flash write operations
qpi-enable:
type: boolean
description: Enable Quad SPI protocol (QPI) (4-4-4)

View file

@ -0,0 +1,23 @@
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
description: Renesas RA OSPI
compatible: "renesas,ra-ospi-b"
include: [base.yaml, pinctrl-device.yaml]
bus: ospi
properties:
reg:
required: true
pinctrl-0:
required: true
pinctrl-names:
required: true
clocks:
required: true

View file

@ -0,0 +1,20 @@
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
description: Renesas RA QSPI
compatible: "renesas,ra-qspi"
include: [base.yaml, pinctrl-device.yaml]
bus: qspi
properties:
reg:
required: true
pinctrl-0:
required: true
pinctrl-names:
required: true

View file

@ -11,6 +11,9 @@
enum ra_ex_ops { enum ra_ex_ops {
FLASH_RA_EX_OP_WRITE_PROTECT = FLASH_EX_OP_VENDOR_BASE, FLASH_RA_EX_OP_WRITE_PROTECT = FLASH_EX_OP_VENDOR_BASE,
/* Reset Flash device (at QPI(4-4-4) mode) */
QSPI_FLASH_EX_OP_EXIT_QPI,
}; };
typedef struct { typedef struct {
@ -142,5 +145,4 @@ typedef struct flash_ra_ex_write_protect_out {
flash_ra_cf_block_map protected_premanent; flash_ra_cf_block_map protected_premanent;
} flash_ra_ex_write_protect_out_t; } flash_ra_ex_write_protect_out_t;
#endif /* CONFIG_FLASH_RA_WRITE_PROTECT */ #endif /* CONFIG_FLASH_RA_WRITE_PROTECT */
#endif #endif

View file

@ -236,7 +236,7 @@ struct net_mgmt_event_static_handler {
* @brief Helper to initialize a struct net_mgmt_event_callback properly * @brief Helper to initialize a struct net_mgmt_event_callback properly
* @param cb A valid application's callback structure pointer. * @param cb A valid application's callback structure pointer.
* @param handler A valid handler function pointer. * @param handler A valid handler function pointer.
* @param mgmt_event_mask A mask of relevant events for the handler * @param mgmt_event_mask A mask of relevant events for the handler. Ensure all events share a layer code.
*/ */
#ifdef CONFIG_NET_MGMT_EVENT #ifdef CONFIG_NET_MGMT_EVENT
static inline static inline

View file

@ -149,6 +149,16 @@ config USE_RA_FSP_SDHI
help help
Enable RA FSP SDHI driver Enable RA FSP SDHI driver
config USE_RA_FSP_QSPI_NOR_FLASH
bool
help
Enable RA FSP Quad-SPI driver
config USE_RA_FSP_OSPI_B_NOR_FLASH
bool
help
Enable RA FSP Octal-SPI driver
endif # HAS_RENESAS_RA_FSP endif # HAS_RENESAS_RA_FSP
if HAS_RENESAS_RZ_FSP if HAS_RENESAS_RZ_FSP

View file

@ -1146,12 +1146,17 @@ static void handler(void)
#endif #endif
ctx = get_default_context(); ctx = get_default_context();
struct k_work_queue_config wq_cfg = {
.name = "wpa_supplicant_wq",
.no_yield = false,
.essential = false
};
k_work_queue_init(&ctx->iface_wq); k_work_queue_init(&ctx->iface_wq);
k_work_queue_start(&ctx->iface_wq, iface_wq_stack, k_work_queue_start(&ctx->iface_wq, iface_wq_stack,
K_THREAD_STACK_SIZEOF(iface_wq_stack), K_THREAD_STACK_SIZEOF(iface_wq_stack),
CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_PRIO, CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_PRIO,
NULL); &wq_cfg);
k_work_init(&ctx->iface_work, iface_work_handler); k_work_init(&ctx->iface_work, iface_work_handler);
@ -1214,6 +1219,7 @@ static int init(void)
K_THREAD_STACK_SIZEOF(supplicant_thread_stack), K_THREAD_STACK_SIZEOF(supplicant_thread_stack),
(k_thread_entry_t)handler, NULL, NULL, NULL, (k_thread_entry_t)handler, NULL, NULL, NULL,
CONFIG_WIFI_NM_WPA_SUPPLICANT_PRIO, 0, K_NO_WAIT); CONFIG_WIFI_NM_WPA_SUPPLICANT_PRIO, 0, K_NO_WAIT);
k_thread_name_set(&tid, "wpa_supplicant");
return 0; return 0;
} }

View file

@ -26,6 +26,10 @@
#define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_s32_qspi_nor) #define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_s32_qspi_nor)
#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_imx_flexspi_nor) #elif DT_HAS_COMPAT_STATUS_OKAY(nxp_imx_flexspi_nor)
#define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_imx_flexspi_nor) #define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_imx_flexspi_nor)
#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_ospi_b_nor)
#define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_ospi_b_nor)
#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_qspi_nor)
#define FLASH_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_qspi_nor)
#else #else
#error Unsupported flash driver #error Unsupported flash driver
#define FLASH_NODE DT_INVALID_NODE #define FLASH_NODE DT_INVALID_NODE

View file

@ -21,14 +21,21 @@
#elif defined(CONFIG_BOARD_NPCX9M6F_EVB) || \ #elif defined(CONFIG_BOARD_NPCX9M6F_EVB) || \
defined(CONFIG_BOARD_NPCX7M6FB_EVB) defined(CONFIG_BOARD_NPCX7M6FB_EVB)
#define SPI_FLASH_TEST_REGION_OFFSET 0x7F000 #define SPI_FLASH_TEST_REGION_OFFSET 0x7F000
#elif defined(CONFIG_BOARD_EK_RA8M1) || defined(CONFIG_BOARD_EK_RA8D1)
#define SPI_FLASH_TEST_REGION_OFFSET 0x40000
#else #else
#define SPI_FLASH_TEST_REGION_OFFSET 0xff000 #define SPI_FLASH_TEST_REGION_OFFSET 0xff000
#endif #endif
#if defined(CONFIG_BOARD_EK_RA8M1) || defined(CONFIG_BOARD_EK_RA8D1)
#define SPI_FLASH_SECTOR_SIZE 262144
#else
#define SPI_FLASH_SECTOR_SIZE 4096 #define SPI_FLASH_SECTOR_SIZE 4096
#endif
#if defined(CONFIG_FLASH_STM32_OSPI) || defined(CONFIG_FLASH_STM32_QSPI) || \
defined(CONFIG_FLASH_STM32_XSPI) || defined(CONFIG_FLASH_OSPI_B_RENESAS_RA) || \
defined(CONFIG_FLASH_QSPI_RENESAS_RA)
#if defined(CONFIG_FLASH_STM32_OSPI) || \
defined(CONFIG_FLASH_STM32_QSPI) || \
defined(CONFIG_FLASH_STM32_XSPI)
#define SPI_FLASH_MULTI_SECTOR_TEST #define SPI_FLASH_MULTI_SECTOR_TEST
#endif #endif
@ -42,15 +49,27 @@
#define SPI_FLASH_COMPAT st_stm32_xspi_nor #define SPI_FLASH_COMPAT st_stm32_xspi_nor
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_qspi_nor) #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_qspi_nor)
#define SPI_FLASH_COMPAT nordic_qspi_nor #define SPI_FLASH_COMPAT nordic_qspi_nor
#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_ospi_b_nor)
#define SPI_FLASH_COMPAT renesas_ra_ospi_b_nor
#elif DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_qspi_nor)
#define SPI_FLASH_COMPAT renesas_ra_qspi_nor
#else #else
#define SPI_FLASH_COMPAT invalid #define SPI_FLASH_COMPAT invalid
#endif #endif
#if defined(CONFIG_FLASH_OSPI_B_RENESAS_RA)
const uint8_t erased[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#else
const uint8_t erased[] = { 0xff, 0xff, 0xff, 0xff }; const uint8_t erased[] = { 0xff, 0xff, 0xff, 0xff };
#endif
void single_sector_test(const struct device *flash_dev) void single_sector_test(const struct device *flash_dev)
{ {
#if defined(CONFIG_FLASH_OSPI_B_RENESAS_RA)
const uint8_t expected[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
#else
const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 }; const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 };
#endif
const size_t len = sizeof(expected); const size_t len = sizeof(expected);
uint8_t buf[sizeof(expected)]; uint8_t buf[sizeof(expected)];
int rc; int rc;
@ -122,7 +141,11 @@ void single_sector_test(const struct device *flash_dev)
#if defined SPI_FLASH_MULTI_SECTOR_TEST #if defined SPI_FLASH_MULTI_SECTOR_TEST
void multi_sector_test(const struct device *flash_dev) void multi_sector_test(const struct device *flash_dev)
{ {
#if defined(CONFIG_FLASH_OSPI_B_RENESAS_RA)
const uint8_t expected[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
#else
const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 }; const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 };
#endif
const size_t len = sizeof(expected); const size_t len = sizeof(expected);
uint8_t buf[sizeof(expected)]; uint8_t buf[sizeof(expected)];
int rc; int rc;

View file

@ -12,8 +12,12 @@
#if defined(CONFIG_NORDIC_QSPI_NOR) #if defined(CONFIG_NORDIC_QSPI_NOR)
#define TEST_AREA_DEV_NODE DT_INST(0, nordic_qspi_nor) #define TEST_AREA_DEV_NODE DT_INST(0, nordic_qspi_nor)
#elif defined(CONFIG_FLASH_OSPI_B_RENESAS_RA)
#define TEST_AREA_DEV_NODE DT_INST(0, renesas_ra_ospi_b_nor)
#elif defined(CONFIG_SPI_NOR) #elif defined(CONFIG_SPI_NOR)
#define TEST_AREA_DEV_NODE DT_INST(0, jedec_spi_nor) #define TEST_AREA_DEV_NODE DT_INST(0, jedec_spi_nor)
#elif defined(CONFIG_FLASH_QSPI_RENESAS_RA)
#define TEST_AREA_DEV_NODE DT_INST(0, renesas_ra_qspi_nor)
#else #else
#define TEST_AREA storage_partition #define TEST_AREA storage_partition
#endif #endif
@ -30,12 +34,18 @@
#elif defined(TEST_AREA_DEV_NODE) #elif defined(TEST_AREA_DEV_NODE)
#define TEST_AREA_DEVICE DEVICE_DT_GET(TEST_AREA_DEV_NODE) #define TEST_AREA_DEVICE DEVICE_DT_GET(TEST_AREA_DEV_NODE)
#if defined CONFIG_FLASH_OSPI_B_RENESAS_RA
#define TEST_AREA_OFFSET 0x40000
#else
#define TEST_AREA_OFFSET 0xff000 #define TEST_AREA_OFFSET 0xff000
#endif
#if DT_NODE_HAS_PROP(TEST_AREA_DEV_NODE, size_in_bytes) #if DT_NODE_HAS_PROP(TEST_AREA_DEV_NODE, size_in_bytes)
#define TEST_AREA_MAX DT_PROP(TEST_AREA_DEV_NODE, size_in_bytes) #define TEST_AREA_MAX DT_PROP(TEST_AREA_DEV_NODE, size_in_bytes)
#else #elif DT_NODE_HAS_PROP(TEST_AREA_DEV_NODE, size)
#define TEST_AREA_MAX (DT_PROP(TEST_AREA_DEV_NODE, size) / 8) #define TEST_AREA_MAX (DT_PROP(TEST_AREA_DEV_NODE, size) / 8)
#else
#define TEST_AREA_MAX DT_REG_SIZE(TEST_AREA_DEV_NODE)
#endif #endif
#else #else