1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /***********************************************************************************************************************
8 * Includes
9 **********************************************************************************************************************/
10 #include "bsp_api.h"
11 #include "r_ospi_b.h"
12
13 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
14 #include "r_transfer_api.h"
15 #include "r_dmac.h"
16 #endif
17
18 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
19 #include "hw_sce_ra_private.h"
20 #endif
21
22 /***********************************************************************************************************************
23 * Macro definitions
24 **********************************************************************************************************************/
25
26 /* "xSPI" in ASCII. Used to determine if the control block is open. */
27 #define OSPI_B_PRV_OPEN (0x78535049U)
28
29 #define OSPI_B_PRV_BMCTL_DEFAULT_VALUE (0x0C)
30
31 #define OSPI_B_PRV_CMCFG_1BYTE_VALUE_MASK (0xFF00U)
32 #define OSPI_B_PRV_CMCFG_2BYTE_VALUE_MASK (0xFFFFU)
33
34 #define OSPI_B_PRV_AUTOCALIBRATION_DATA_SIZE (0xFU)
35 #define OSPI_B_PRV_AUTOCALIBRATION_LATENCY_CYCLES (0U)
36
37 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_0 (0xFFFF0000U)
38 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_1 (0x000800FFU)
39 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_2 (0x00FFF700U)
40 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_3 (0xF700F708U)
41
42 #define OSPI_B_PRV_ADDRESS_REPLACE_VALUE (0xF0U)
43 #define OSPI_B_PRV_ADDRESS_REPLACE_ENABLE_BITS (OSPI_B_PRV_ADDRESS_REPLACE_VALUE << \
44 R_XSPI_CMCFGCS_CMCFG0_ADDRPEN_Pos)
45 #define OSPI_B_PRV_ADDRESS_REPLACE_MASK (~(OSPI_B_PRV_ADDRESS_REPLACE_VALUE << 24))
46
47 #define OSPI_B_PRV_AUTOCALIBRATION_FRAME_INTERVAL (0x1FU)
48 #define OSPI_B_PRV_AUTOCALIBRATION_NO_WRITE_CMD (0x1U)
49 #define OSPI_B_PRV_AUTOCALIBRATION_SHIFT_DS_END_VALUE (0x1FU)
50
51 #define OSPI_B_PRV_WORD_ACCESS_SIZE (4U)
52 #define OSPI_B_PRV_HALF_WORD_ACCESS_SIZE (2U)
53
54 #define OSPI_B_PRV_DIRECT_ADDR_AND_DATA_MASK (7U)
55 #define OSPI_B_PRV_PAGE_SIZE_BYTES (256U)
56
57 #define OSPI_B_PRV_DIRECT_CMD_SIZE_MASK (0x3U)
58
59 #define OSPI_B_PRV_CDTBUF_CMD_OFFSET (16U)
60 #define OSPI_B_PRV_CDTBUF_CMD_UPPER_OFFSET (24U)
61 #define OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK (0xFFU)
62 #define OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT (8U)
63 #define OSPI_B_PRV_CDTBUF_CMD_2B_VALUE_MASK (0xFFFFU)
64
65 #define OSPI_B_PRV_BMCTL0_DISABLED_VALUE (0x00) // 0b0000'0000
66 #define OSPI_B_PRV_BMCTL0_READ_ONLY_VALUE (0x55) // 0b0101'0101
67 #define OSPI_B_PRV_BMCTL0_WRITE_ONLY_VALUE (0xAA) // 0b1010'1010
68 #define OSPI_B_PRV_BMCTL0_READ_WRITE_VALUE (0xFF) // 0b1111'1111
69
70 #define OSPI_B_PRV_BMCTL1_CLEAR_PREFETCH_MASK (0x03 << R_XSPI_BMCTL1_PBUFCLRCH_Pos)
71 #define OSPI_B_PRV_BMCTL1_PUSH_COMBINATION_WRITE_MASK (0x03 << R_XSPI_BMCTL1_MWRPUSHCH_Pos)
72
73 #define OSPI_B_PRV_COMSTT_MEMACCCH_MASK (0x03 << R_XSPI_COMSTT_MEMACCCH_Pos)
74
75 #define OSPI_B_SOFTWARE_DELAY (50U)
76
77 #define OSPI_B_PRV_DOTF_REG00_RESET_VALUE (0x22000000)
78
79 /* These are used as modulus checking, make sure they are powers of 2. */
80 #define OSPI_B_PRV_CPU_ACCESS_LENGTH (8U)
81 #define OSPI_B_PRV_CPU_ACCESS_ALIGNMENT (8U)
82
83 #define OSPI_B_PRV_PROTOCOL_USES_DS_MASK (0x200U)
84
85 #define OSPI_B_PRV_UINT32_BITS (32)
86
87 #ifndef OSPI_B_MAX_WRITE_ENABLE_LOOPS
88 #define OSPI_B_MAX_WRITE_ENABLE_LOOPS (5)
89 #endif
90
91 /* Number of address bytes in 4 byte address mode. */
92 #define OSPI_B_4_BYTE_ADDRESS (4U)
93
94 /***********************************************************************************************************************
95 * Typedef definitions
96 **********************************************************************************************************************/
97
98 /***********************************************************************************************************************
99 * Private function prototypes
100 **********************************************************************************************************************/
101 static bool r_ospi_b_status_sub(ospi_b_instance_ctrl_t * p_instance_ctrl, uint8_t bit_pos);
102 static fsp_err_t r_ospi_b_protocol_specific_settings(ospi_b_instance_ctrl_t * p_instance_ctrl);
103 static fsp_err_t r_ospi_b_write_enable(ospi_b_instance_ctrl_t * p_instance_ctrl);
104 static void r_ospi_b_direct_transfer(ospi_b_device_number_t channel,
105 spi_flash_direct_transfer_t * const p_transfer,
106 spi_flash_direct_transfer_dir_t direction);
107 static ospi_b_xspi_command_set_t const * r_ospi_b_command_set_get(ospi_b_instance_ctrl_t * p_instance_ctrl);
108
109 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
110 static fsp_err_t r_ospi_b_automatic_calibration_seq(ospi_b_instance_ctrl_t * p_instance_ctrl);
111
112 #endif
113
114 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
115 static void r_ospi_b_xip(ospi_b_instance_ctrl_t * p_instance_ctrl, bool is_entering);
116
117 #endif
118
119 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
120 static fsp_err_t r_ospi_b_dotf_setup(ospi_b_dotf_cfg_t * p_dotf_cfg);
121
122 #endif
123
124 /***********************************************************************************************************************
125 * Private global variables
126 **********************************************************************************************************************/
127
128 /* Bit-flags specifying which channels are open so the module can be stopped when all are closed. */
129 static uint32_t g_ospi_b_channels_open_flags = 0;
130
131 /*******************************************************************************************************************//**
132 * @addtogroup OSPI_B
133 * @{
134 **********************************************************************************************************************/
135
136 /***********************************************************************************************************************
137 * Global Variables
138 **********************************************************************************************************************/
139
140 const spi_flash_api_t g_ospi_b_on_spi_flash =
141 {
142 .open = R_OSPI_B_Open,
143 .directWrite = R_OSPI_B_DirectWrite,
144 .directRead = R_OSPI_B_DirectRead,
145 .directTransfer = R_OSPI_B_DirectTransfer,
146 .spiProtocolSet = R_OSPI_B_SpiProtocolSet,
147 .write = R_OSPI_B_Write,
148 .erase = R_OSPI_B_Erase,
149 .statusGet = R_OSPI_B_StatusGet,
150 .xipEnter = R_OSPI_B_XipEnter,
151 .xipExit = R_OSPI_B_XipExit,
152 .bankSet = R_OSPI_B_BankSet,
153 .close = R_OSPI_B_Close,
154 .autoCalibrate = R_OSPI_B_AutoCalibrate,
155 };
156
157 /***********************************************************************************************************************
158 * Functions
159 **********************************************************************************************************************/
160
161 /*******************************************************************************************************************//**
162 * Open the xSPI device. After the driver is open, the xSPI device can be accessed like internal flash memory.
163 *
164 * Implements @ref spi_flash_api_t::open.
165 *
166 * @retval FSP_SUCCESS Configuration was successful.
167 * @retval FSP_ERR_ASSERTION The parameter p_ctrl or p_cfg is NULL.
168 * @retval FSP_ERR_ALREADY_OPEN Driver has already been opened with the same p_ctrl.
169 * @retval FSP_ERR_CALIBRATE_FAILED Failed to perform auto-calibrate.
170 **********************************************************************************************************************/
R_OSPI_B_Open(spi_flash_ctrl_t * const p_ctrl,spi_flash_cfg_t const * const p_cfg)171 fsp_err_t R_OSPI_B_Open (spi_flash_ctrl_t * const p_ctrl, spi_flash_cfg_t const * const p_cfg)
172 {
173 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
174
175 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
176 FSP_ASSERT(NULL != p_instance_ctrl);
177 FSP_ASSERT(NULL != p_cfg);
178 FSP_ASSERT(NULL != p_cfg->p_extend);
179 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
180 #endif
181
182 ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
183
184 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
185 FSP_ERROR_RETURN((g_ospi_b_channels_open_flags & (1U << p_cfg_extend->channel)) == 0, FSP_ERR_ALREADY_OPEN);
186 #endif
187
188 /* Enable clock to the xSPI block */
189 R_BSP_MODULE_START(FSP_IP_OSPI, 0U);
190
191 /* Initialize control block. */
192 p_instance_ctrl->p_cfg = p_cfg;
193 p_instance_ctrl->spi_protocol = p_cfg->spi_protocol;
194 p_instance_ctrl->channel = p_cfg_extend->channel;
195
196 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
197 if (NULL != p_cfg_extend->p_dotf_cfg)
198 {
199 fsp_err_t dotf_ret = r_ospi_b_dotf_setup((ospi_b_dotf_cfg_t *) p_cfg_extend->p_dotf_cfg);
200 if (FSP_SUCCESS != dotf_ret)
201 {
202 /* If the DOTF initialization fails, stop the module if no other channels are active. */
203 if (g_ospi_b_channels_open_flags == 0)
204 {
205 R_BSP_MODULE_STOP(FSP_IP_OSPI, 0U);
206 }
207
208 return dotf_ret;
209 }
210 }
211 #endif
212
213 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
214 transfer_instance_t const * p_transfer = p_cfg_extend->p_lower_lvl_transfer;
215 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
216 FSP_ASSERT(NULL != p_transfer);
217 #endif
218
219 /* Initialize transfer instance */
220 p_transfer->p_api->open(p_transfer->p_ctrl, p_transfer->p_cfg);
221 #endif
222
223 /* Disable memory-mapping for this slave. It will be enabled later on after initialization. */
224 if (OSPI_B_DEVICE_NUMBER_0 == p_instance_ctrl->channel)
225 {
226 R_XSPI->BMCTL0 &= ~(R_XSPI_BMCTL0_CH0CS0ACC_Msk | R_XSPI_BMCTL0_CH1CS0ACC_Msk);
227 }
228 else
229 {
230 R_XSPI->BMCTL0 &= ~(R_XSPI_BMCTL0_CH0CS1ACC_Msk | R_XSPI_BMCTL0_CH1CS1ACC_Msk);
231 }
232
233 /* Perform xSPI Initial configuration as described in hardware manual (see Section 37.3.8
234 * 'Flow of Operations' of the RA8M1 manual R01UH0994EJ0100). */
235
236 /* Set xSPI protocol mode. */
237 uint32_t liocfg = ((uint32_t) p_cfg->spi_protocol) << R_XSPI_LIOCFGCS_PRTMD_Pos;
238 R_XSPI->LIOCFGCS[p_cfg_extend->channel] = liocfg;
239
240 /* Set xSPI drive/sampling timing. */
241 if (OSPI_B_DEVICE_NUMBER_0 == p_instance_ctrl->channel)
242 {
243 R_XSPI->WRAPCFG = ((uint32_t) p_cfg_extend->data_latch_delay_clocks << R_XSPI_WRAPCFG_DSSFTCS0_Pos) &
244 R_XSPI_WRAPCFG_DSSFTCS0_Msk;
245 }
246 else
247 {
248 R_XSPI->WRAPCFG = ((uint32_t) p_cfg_extend->data_latch_delay_clocks << R_XSPI_WRAPCFG_DSSFTCS1_Pos) &
249 R_XSPI_WRAPCFG_DSSFTCS1_Msk;
250 }
251
252 /* Set minimum cycles between xSPI frames. */
253 liocfg |= ((uint32_t) p_cfg_extend->p_timing_settings->command_to_command_interval << R_XSPI_LIOCFGCS_CSMIN_Pos) &
254 R_XSPI_LIOCFGCS_CSMIN_Msk;
255
256 /* Set CS asserting extension in cycles */
257 liocfg |= ((uint32_t) p_cfg_extend->p_timing_settings->cs_pulldown_lead << R_XSPI_LIOCFGCS_CSASTEX_Pos) &
258 R_XSPI_LIOCFGCS_CSASTEX_Msk;
259
260 /* Set CS releasing extension in cycles */
261 liocfg |= ((uint32_t) p_cfg_extend->p_timing_settings->cs_pullup_lag << R_XSPI_LIOCFGCS_CSNEGEX_Pos) &
262 R_XSPI_LIOCFGCS_CSNEGEX_Msk;
263
264 /* Set xSPI CSn signal timings. */
265 R_XSPI->LIOCFGCS[p_cfg_extend->channel] = liocfg;
266
267 /* Set xSPI memory-mapping operation. */
268 fsp_err_t ret = r_ospi_b_protocol_specific_settings(p_instance_ctrl);
269
270 /* Return response after issuing write transaction to xSPI bus, Enable prefetch function and combination if desired. */
271 const uint32_t bmcfgch = (0 << R_XSPI_BMCFGCH_WRMD_Pos) |
272 ((OSPI_B_CFG_COMBINATION_FUNCTION << R_XSPI_BMCFGCH_MWRCOMB_Pos) &
273 (R_XSPI_BMCFGCH_MWRCOMB_Msk | R_XSPI_BMCFGCH_MWRSIZE_Msk)) |
274 ((OSPI_B_CFG_PREFETCH_FUNCTION << R_XSPI_BMCFGCH_PREEN_Pos) &
275 R_XSPI_BMCFGCH_PREEN_Msk);
276
277 /* Both of these should have the same configuration and it affects all OSPI slave channels. */
278 R_XSPI->BMCFGCH[0] = bmcfgch;
279 R_XSPI->BMCFGCH[1] = bmcfgch;
280
281 /* Re-activate memory-mapped mode in Read/Write. */
282 if (p_instance_ctrl->channel == 0)
283 {
284 R_XSPI->BMCTL0 |= R_XSPI_BMCTL0_CH0CS0ACC_Msk | R_XSPI_BMCTL0_CH1CS0ACC_Msk;
285 }
286 else
287 {
288 R_XSPI->BMCTL0 |= R_XSPI_BMCTL0_CH0CS1ACC_Msk | R_XSPI_BMCTL0_CH1CS1ACC_Msk;
289 }
290
291 if (FSP_SUCCESS == ret)
292 {
293 p_instance_ctrl->open = OSPI_B_PRV_OPEN;
294 g_ospi_b_channels_open_flags |= (1U << p_instance_ctrl->channel);
295 }
296 else if (g_ospi_b_channels_open_flags == 0)
297 {
298 /* If the open fails and no other channels are open, stop the module. */
299 R_BSP_MODULE_STOP(FSP_IP_OSPI, 0U);
300 }
301 else
302 {
303 // Do nothing.
304 }
305
306 return ret;
307 }
308
309 /*******************************************************************************************************************//**
310 * Writes raw data directly to the OctaFlash. API not supported. Use R_OSPI_B_DirectTransfer
311 *
312 * Implements @ref spi_flash_api_t::directWrite.
313 *
314 * @retval FSP_ERR_UNSUPPORTED API not supported by OSPI.
315 **********************************************************************************************************************/
R_OSPI_B_DirectWrite(spi_flash_ctrl_t * p_ctrl,uint8_t const * const p_src,uint32_t const bytes,bool const read_after_write)316 fsp_err_t R_OSPI_B_DirectWrite (spi_flash_ctrl_t * p_ctrl,
317 uint8_t const * const p_src,
318 uint32_t const bytes,
319 bool const read_after_write)
320 {
321 FSP_PARAMETER_NOT_USED(p_ctrl);
322 FSP_PARAMETER_NOT_USED(p_src);
323 FSP_PARAMETER_NOT_USED(bytes);
324 FSP_PARAMETER_NOT_USED(read_after_write);
325
326 FSP_RETURN(FSP_ERR_UNSUPPORTED);
327 }
328
329 /*******************************************************************************************************************//**
330 * Reads raw data directly from the OctaFlash. API not supported. Use R_OSPI_B_DirectTransfer.
331 *
332 * Implements @ref spi_flash_api_t::directRead.
333 *
334 * @retval FSP_ERR_UNSUPPORTED API not supported by OSPI.
335 **********************************************************************************************************************/
R_OSPI_B_DirectRead(spi_flash_ctrl_t * p_ctrl,uint8_t * const p_dest,uint32_t const bytes)336 fsp_err_t R_OSPI_B_DirectRead (spi_flash_ctrl_t * p_ctrl, uint8_t * const p_dest, uint32_t const bytes)
337 {
338 FSP_PARAMETER_NOT_USED(p_ctrl);
339 FSP_PARAMETER_NOT_USED(p_dest);
340 FSP_PARAMETER_NOT_USED(bytes);
341
342 FSP_RETURN(FSP_ERR_UNSUPPORTED);
343 }
344
345 /*******************************************************************************************************************//**
346 * Read/Write raw data directly with the OctaFlash.
347 *
348 * Implements @ref spi_flash_api_t::directTransfer.
349 *
350 * @retval FSP_SUCCESS The flash was programmed successfully.
351 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
352 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
353 **********************************************************************************************************************/
R_OSPI_B_DirectTransfer(spi_flash_ctrl_t * p_ctrl,spi_flash_direct_transfer_t * const p_transfer,spi_flash_direct_transfer_dir_t direction)354 fsp_err_t R_OSPI_B_DirectTransfer (spi_flash_ctrl_t * p_ctrl,
355 spi_flash_direct_transfer_t * const p_transfer,
356 spi_flash_direct_transfer_dir_t direction)
357 {
358 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
359
360 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
361 FSP_ASSERT(NULL != p_instance_ctrl);
362 FSP_ASSERT(NULL != p_transfer);
363 FSP_ASSERT(0 != p_transfer->command_length);
364 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
365 #endif
366
367 r_ospi_b_direct_transfer(p_instance_ctrl->channel, p_transfer, direction);
368
369 return FSP_SUCCESS;
370 }
371
372 /*******************************************************************************************************************//**
373 * Enters XIP (execute in place) mode.
374 *
375 * Implements @ref spi_flash_api_t::xipEnter.
376 *
377 * @retval FSP_SUCCESS XiP mode was entered successfully.
378 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
379 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
380 * @retval FSP_ERR_UNSUPPORTED XiP support is not enabled.
381 **********************************************************************************************************************/
R_OSPI_B_XipEnter(spi_flash_ctrl_t * p_ctrl)382 fsp_err_t R_OSPI_B_XipEnter (spi_flash_ctrl_t * p_ctrl)
383 {
384 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
385 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
386
387 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
388 FSP_ASSERT(NULL != p_instance_ctrl);
389 FSP_ASSERT(NULL != p_instance_ctrl->p_cfg);
390 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
391 #endif
392
393 r_ospi_b_xip(p_instance_ctrl, true);
394
395 return FSP_SUCCESS;
396 #else
397 FSP_PARAMETER_NOT_USED(p_ctrl);
398
399 return FSP_ERR_UNSUPPORTED;
400 #endif
401 }
402
403 /*******************************************************************************************************************//**
404 * Exits XIP (execute in place) mode.
405 *
406 * Implements @ref spi_flash_api_t::xipExit.
407 *
408 * @retval FSP_SUCCESS XiP mode was entered successfully.
409 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
410 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
411 * @retval FSP_ERR_UNSUPPORTED XiP support is not enabled.
412 **********************************************************************************************************************/
R_OSPI_B_XipExit(spi_flash_ctrl_t * p_ctrl)413 fsp_err_t R_OSPI_B_XipExit (spi_flash_ctrl_t * p_ctrl)
414 {
415 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
416 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
417
418 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
419 FSP_ASSERT(NULL != p_instance_ctrl);
420 FSP_ASSERT(NULL != p_instance_ctrl->p_cfg);
421 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
422 #endif
423
424 r_ospi_b_xip(p_instance_ctrl, false);
425
426 return FSP_SUCCESS;
427 #else
428 FSP_PARAMETER_NOT_USED(p_ctrl);
429
430 return FSP_ERR_UNSUPPORTED;
431 #endif
432 }
433
434 /*******************************************************************************************************************//**
435 * Program a page of data to the flash.
436 *
437 * Implements @ref spi_flash_api_t::write.
438 *
439 * @retval FSP_SUCCESS The flash was programmed successfully.
440 * @retval FSP_ERR_ASSERTION p_instance_ctrl, p_dest or p_src is NULL, or byte_count crosses a page boundary.
441 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
442 * @retval FSP_ERR_INVALID_SIZE Insufficient space remaining in page or write length is not a multiple of CPU access size when not using the DMAC.
443 * @retval FSP_ERR_DEVICE_BUSY Another Write/Erase transaction is in progress.
444 * @retval FSP_ERR_WRITE_FAILED Write operation failed.
445 * @retval FSP_ERR_INVALID_ADDRESS Destination or source is not aligned to CPU access alignment when not using the DMAC.
446 **********************************************************************************************************************/
R_OSPI_B_Write(spi_flash_ctrl_t * p_ctrl,uint8_t const * const p_src,uint8_t * const p_dest,uint32_t byte_count)447 fsp_err_t R_OSPI_B_Write (spi_flash_ctrl_t * p_ctrl,
448 uint8_t const * const p_src,
449 uint8_t * const p_dest,
450 uint32_t byte_count)
451 {
452 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
453 fsp_err_t err = FSP_SUCCESS;
454 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
455 FSP_ASSERT(NULL != p_instance_ctrl);
456 FSP_ASSERT(NULL != p_src);
457 FSP_ASSERT(NULL != p_dest);
458 FSP_ASSERT(0 != byte_count);
459 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
460
461 /* Check that space remaining in page is sufficient for requested write size */
462 uint32_t page_size = p_instance_ctrl->p_cfg->page_size_bytes;
463 uint32_t page_offset = (uint32_t) p_dest & (page_size - 1);
464 FSP_ERROR_RETURN((page_size - page_offset) >= byte_count, FSP_ERR_INVALID_SIZE);
465
466 #if !OSPI_B_CFG_DMAC_SUPPORT_ENABLE
467 FSP_ERROR_RETURN((byte_count & (OSPI_B_PRV_CPU_ACCESS_LENGTH - 1)) == 0, FSP_ERR_INVALID_SIZE);
468 FSP_ERROR_RETURN(((uint32_t) p_dest & (OSPI_B_PRV_CPU_ACCESS_ALIGNMENT - 1)) == 0, FSP_ERR_INVALID_ADDRESS);
469 #if defined(__llvm__) && !defined(__ARMCC_VERSION)
470
471 /* LLVM needs 32-bit aligned data. */
472 FSP_ERROR_RETURN(((uint32_t) p_src & (0x3)) == 0, FSP_ERR_INVALID_ADDRESS);
473 #endif
474 #endif
475 #endif
476
477 FSP_ERROR_RETURN(false == r_ospi_b_status_sub(p_instance_ctrl, p_instance_ctrl->p_cfg->write_status_bit),
478 FSP_ERR_DEVICE_BUSY);
479
480 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
481 spi_flash_cfg_t * p_cfg = (spi_flash_cfg_t *) p_instance_ctrl->p_cfg;
482 ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
483
484 /* Setup and start DMAC transfer. */
485 transfer_instance_t const * p_transfer = p_cfg_extend->p_lower_lvl_transfer;
486
487 /* Enable Octa-SPI DMA Bufferable Write */
488 dmac_extended_cfg_t const * p_dmac_extend = p_transfer->p_cfg->p_extend;
489 R_DMAC0_Type * p_dma_reg = R_DMAC0 + (sizeof(R_DMAC0_Type) * p_dmac_extend->channel);
490 p_dma_reg->DMBWR = R_DMAC0_DMBWR_BWE_Msk;
491
492 /* Update the block-mode transfer settings */
493 p_transfer->p_cfg->p_info->p_src = p_src;
494 p_transfer->p_cfg->p_info->p_dest = p_dest;
495 p_transfer->p_cfg->p_info->transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE;
496 p_transfer->p_cfg->p_info->transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL;
497 p_transfer->p_cfg->p_info->length = (uint16_t) byte_count;
498 err = p_transfer->p_api->reconfigure(p_transfer->p_ctrl, p_transfer->p_cfg->p_info);
499 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
500
501 r_ospi_b_write_enable(p_instance_ctrl);
502
503 /* Start DMA */
504 err = p_transfer->p_api->softwareStart(p_transfer->p_ctrl, TRANSFER_START_MODE_REPEAT);
505 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
506
507 /* Wait for DMAC to complete to maintain deterministic processing and backward compatability */
508 volatile transfer_properties_t transfer_properties = {0U};
509 err = p_transfer->p_api->infoGet(p_transfer->p_ctrl, (transfer_properties_t *) &transfer_properties);
510 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
511 while (FSP_SUCCESS == err && transfer_properties.transfer_length_remaining > 0)
512 {
513 err = p_transfer->p_api->infoGet(p_transfer->p_ctrl, (transfer_properties_t *) &transfer_properties);
514 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
515 }
516
517 /* Disable Octa-SPI DMA Bufferable Write */
518 p_dma_reg->DMBWR = 0U;
519
520 /* If this number of bytes is less than the combination count, push the data to force a transaction. */
521 if (OSPI_B_CFG_COMBINATION_FUNCTION != OSPI_B_COMBINATION_FUNCTION_DISABLE)
522 {
523 uint8_t combo_bytes = (uint8_t) (2U * ((uint8_t) OSPI_B_CFG_COMBINATION_FUNCTION + 1U));
524 if (byte_count < combo_bytes)
525 {
526 R_XSPI->BMCTL1 = OSPI_B_PRV_BMCTL1_PUSH_COMBINATION_WRITE_MASK;;
527 }
528 }
529
530 #else
531 uint64_t * p_dest64 = (uint64_t *) ((uint32_t) p_dest & ~(OSPI_B_PRV_CPU_ACCESS_ALIGNMENT - 1));
532 uint64_t * p_src64 = (uint64_t *) p_src;
533
534 err = r_ospi_b_write_enable(p_instance_ctrl);
535 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
536
537 while (sizeof(uint64_t) <= byte_count)
538 {
539 /* When combination function is enabled, xSPI master transmits a xSPI
540 * frame with the selected size while the sequential address is incremental. Please read Section 37.3.3.3
541 * Combination Function' of the RA8M1 manual R01UH0994EJ0100. So Basically Enable command should be
542 * sent only once for a single burst(incremented addresses up to set combination size.). */
543 *p_dest64 = *p_src64;
544 p_dest64++;
545 p_src64++;
546 byte_count -= sizeof(uint64_t);
547 }
548
549 __DMB();
550
551 R_XSPI->BMCTL1 = OSPI_B_PRV_BMCTL1_PUSH_COMBINATION_WRITE_MASK;
552 #endif
553
554 return FSP_SUCCESS;
555 }
556
557 /*******************************************************************************************************************//**
558 * Erase a block or sector of flash. The byte_count must exactly match one of the erase sizes defined in spi_flash_cfg_t.
559 * For chip erase, byte_count must be SPI_FLASH_ERASE_SIZE_CHIP_ERASE.
560 *
561 * Implements @ref spi_flash_api_t::erase.
562 *
563 * @retval FSP_SUCCESS The command to erase the flash was executed successfully.
564 * @retval FSP_ERR_ASSERTION p_instance_ctrl or p_device_address is NULL, byte_count doesn't match an erase
565 * size defined in spi_flash_cfg_t, or byte_count is set to 0.
566 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
567 * @retval FSP_ERR_DEVICE_BUSY The device is busy.
568 * @retval FSP_ERR_WRITE_FAILED Write operation failed.
569 **********************************************************************************************************************/
R_OSPI_B_Erase(spi_flash_ctrl_t * p_ctrl,uint8_t * const p_device_address,uint32_t byte_count)570 fsp_err_t R_OSPI_B_Erase (spi_flash_ctrl_t * p_ctrl, uint8_t * const p_device_address, uint32_t byte_count)
571 {
572 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
573
574 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
575 FSP_ASSERT(NULL != p_instance_ctrl);
576 FSP_ASSERT(NULL != p_device_address);
577 FSP_ASSERT(0 != byte_count);
578 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
579 #endif
580 spi_flash_cfg_t const * p_cfg = p_instance_ctrl->p_cfg;
581 uint16_t erase_command = 0;
582 const uint32_t chip_address_base = p_instance_ctrl->channel ?
583 BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS :
584 BSP_FEATURE_OSPI_B_DEVICE_0_START_ADDRESS;
585 uint32_t chip_address = (uint32_t) p_device_address - chip_address_base;
586 bool send_address = true;
587
588 ospi_b_xspi_command_set_t const * p_cmd_set = p_instance_ctrl->p_cmd_set;
589
590 FSP_ERROR_RETURN(false == r_ospi_b_status_sub(p_instance_ctrl, p_cfg->write_status_bit), FSP_ERR_DEVICE_BUSY);
591
592 /* Select the erase commands from either the default SPI settings or the protocol settings if provided. */
593 spi_flash_erase_command_t const * p_erase_list = ((NULL != p_cmd_set) && p_cmd_set->p_erase_command_list) ?
594 p_cmd_set->p_erase_command_list : p_cfg->p_erase_command_list;
595 const uint8_t erase_list_length = ((NULL != p_cmd_set) && p_cmd_set->p_erase_command_list) ?
596 p_cmd_set->erase_command_list_length : p_cfg->erase_command_list_length;
597
598 for (uint32_t index = 0; index < erase_list_length; index++)
599 {
600 /* If requested byte_count is supported by underlying flash, store the command. */
601 if (byte_count == p_erase_list[index].size)
602 {
603 if (SPI_FLASH_ERASE_SIZE_CHIP_ERASE == byte_count)
604 {
605 /* Don't send address for chip erase. */
606 send_address = false;
607 }
608
609 erase_command = p_erase_list[index].command;
610 break;
611 }
612 }
613
614 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
615 FSP_ASSERT(0U != erase_command);
616 #endif
617
618 fsp_err_t err = r_ospi_b_write_enable(p_instance_ctrl);
619 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
620
621 spi_flash_direct_transfer_t direct_command = {0};
622 direct_command.command = erase_command;
623 direct_command.address = chip_address;
624 direct_command.address_length = (!send_address) ? 0U :
625 ((SPI_FLASH_ADDRESS_BYTES_3 == p_instance_ctrl->p_cfg->address_bytes) ? 3U : 4U);
626 direct_command.command_length = (NULL != p_cmd_set) ? (uint8_t) p_cmd_set->command_bytes : 1U;
627
628 r_ospi_b_direct_transfer(p_instance_ctrl->channel, &direct_command, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
629
630 /* If prefetch is enabled, make sure the banks aren't being used and flush the prefetch caches after an erase. */
631 #if OSPI_B_CFG_PREFETCH_FUNCTION
632 FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
633 R_XSPI->BMCTL1 = OSPI_B_PRV_BMCTL1_CLEAR_PREFETCH_MASK;
634 #endif
635
636 return FSP_SUCCESS;
637 }
638
639 /*******************************************************************************************************************//**
640 * Gets the write or erase status of the flash.
641 *
642 * Implements @ref spi_flash_api_t::statusGet.
643 *
644 * @retval FSP_SUCCESS The write status is in p_status.
645 * @retval FSP_ERR_ASSERTION p_instance_ctrl or p_status is NULL.
646 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
647 **********************************************************************************************************************/
R_OSPI_B_StatusGet(spi_flash_ctrl_t * p_ctrl,spi_flash_status_t * const p_status)648 fsp_err_t R_OSPI_B_StatusGet (spi_flash_ctrl_t * p_ctrl, spi_flash_status_t * const p_status)
649 {
650 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
651
652 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
653 FSP_ASSERT(NULL != p_instance_ctrl);
654 FSP_ASSERT(NULL != p_status);
655 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
656 #endif
657
658 /* Read device status. */
659 p_status->write_in_progress = r_ospi_b_status_sub(p_instance_ctrl, p_instance_ctrl->p_cfg->write_status_bit);
660
661 return FSP_SUCCESS;
662 }
663
664 /*******************************************************************************************************************//**
665 * Selects the bank to access. Use ospi_b_bank_select_t as the bank value.
666 *
667 * Implements @ref spi_flash_api_t::bankSet.
668 *
669 * @retval FSP_ERR_UNSUPPORTED This function is unsupported.
670 **********************************************************************************************************************/
R_OSPI_B_BankSet(spi_flash_ctrl_t * p_ctrl,uint32_t bank)671 fsp_err_t R_OSPI_B_BankSet (spi_flash_ctrl_t * p_ctrl, uint32_t bank)
672 {
673 FSP_PARAMETER_NOT_USED(p_ctrl);
674 FSP_PARAMETER_NOT_USED(bank);
675
676 FSP_RETURN(FSP_ERR_UNSUPPORTED);
677 }
678
679 /*******************************************************************************************************************//**
680 * Sets the SPI protocol.
681 *
682 * Implements @ref spi_flash_api_t::spiProtocolSet.
683 *
684 * @retval FSP_SUCCESS SPI protocol updated on MPU peripheral.
685 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
686 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
687 * @retval FSP_ERR_CALIBRATE_FAILED Failed to perform auto-calibrate.
688 **********************************************************************************************************************/
R_OSPI_B_SpiProtocolSet(spi_flash_ctrl_t * p_ctrl,spi_flash_protocol_t spi_protocol)689 fsp_err_t R_OSPI_B_SpiProtocolSet (spi_flash_ctrl_t * p_ctrl, spi_flash_protocol_t spi_protocol)
690 {
691 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
692
693 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
694 FSP_ASSERT(NULL != p_instance_ctrl);
695 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
696 #endif
697 p_instance_ctrl->spi_protocol = spi_protocol;
698
699 /* Update the SPI protocol and its associated registers. */
700 return r_ospi_b_protocol_specific_settings(p_instance_ctrl);
701 }
702
703 /*******************************************************************************************************************//**
704 * Close the OSPI driver module.
705 *
706 * Implements @ref spi_flash_api_t::close.
707 *
708 * @retval FSP_SUCCESS Configuration was successful.
709 * @retval FSP_ERR_ASSERTION p_instance_ctrl is NULL.
710 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
711 **********************************************************************************************************************/
R_OSPI_B_Close(spi_flash_ctrl_t * p_ctrl)712 fsp_err_t R_OSPI_B_Close (spi_flash_ctrl_t * p_ctrl)
713 {
714 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
715
716 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
717 FSP_ASSERT(NULL != p_instance_ctrl);
718 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
719 #endif
720
721 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
722
723 /* Initialize transfer instance */
724 ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) (p_instance_ctrl->p_cfg->p_extend);
725 transfer_instance_t const * p_transfer = p_cfg_extend->p_lower_lvl_transfer;
726 p_transfer->p_api->close(p_transfer->p_ctrl);
727 #endif
728
729 p_instance_ctrl->open = 0U;
730 g_ospi_b_channels_open_flags &= ~(1U << p_instance_ctrl->channel);
731
732 /* Disable clock to the OSPI block if all channels are closed. */
733 if (g_ospi_b_channels_open_flags == 0)
734 {
735 R_BSP_MODULE_STOP(FSP_IP_OSPI, 0U);
736 }
737
738 return FSP_SUCCESS;
739 }
740
741 /*******************************************************************************************************************//**
742 * AutoCalibrate the OSPI_B DS signal.
743 *
744 * Implements @ref spi_flash_api_t::autoCalibrate.
745 *
746 * @retval FSP_SUCCESS Autocalibration completed successfully.
747 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
748 * @retval FSP_ERR_NOT_OPEN Driver is not opened.
749 * @retval FSP_ERR_UNSUPPORTED Autocalibration support is not enabled.
750 * @retval FSP_ERR_CALIBRATE_FAILED Failed to perform auto-calibrate.
751 **********************************************************************************************************************/
R_OSPI_B_AutoCalibrate(spi_flash_ctrl_t * const p_ctrl)752 fsp_err_t R_OSPI_B_AutoCalibrate (spi_flash_ctrl_t * const p_ctrl)
753 {
754 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
755 ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
756
757 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
758 FSP_ASSERT(NULL != p_instance_ctrl);
759 FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
760 #endif
761
762 /* Perform Automatic Calibration to appropriately update WRAPCFG DSSFTCSn field. */
763 if (0 != (OSPI_B_PRV_PROTOCOL_USES_DS_MASK & p_instance_ctrl->spi_protocol))
764 {
765 return r_ospi_b_automatic_calibration_seq(p_instance_ctrl);
766 }
767
768 return FSP_SUCCESS;
769 #else
770 FSP_PARAMETER_NOT_USED(p_ctrl);
771
772 return FSP_ERR_UNSUPPORTED;
773 #endif
774 }
775
776 /*******************************************************************************************************************//**
777 * @} (end addtogroup OSPI)
778 **********************************************************************************************************************/
779
780 /*******************************************************************************************************************//**
781 * Perform initialization based on SPI/OPI protocol
782 *
783 * @param[in] p_instance_ctrl Pointer to OSPI specific control structure
784 *
785 * @retval FSP_SUCCESS Protocol based settings completed successfully.
786 * @retval FSP_ERR_CALIBRATE_FAILED Auto-Calibration failed.
787 **********************************************************************************************************************/
r_ospi_b_protocol_specific_settings(ospi_b_instance_ctrl_t * p_instance_ctrl)788 static fsp_err_t r_ospi_b_protocol_specific_settings (ospi_b_instance_ctrl_t * p_instance_ctrl)
789 {
790 spi_flash_cfg_t const * p_cfg = p_instance_ctrl->p_cfg;
791 ospi_b_extended_cfg_t const * p_extend = (ospi_b_extended_cfg_t const *) p_cfg->p_extend;
792 fsp_err_t ret = FSP_SUCCESS;
793
794 /* Get the command set for the configured protocol and save it to the control struct. */
795 ospi_b_xspi_command_set_t const * p_cmd_set = r_ospi_b_command_set_get(p_instance_ctrl);
796 p_instance_ctrl->p_cmd_set = p_cmd_set;
797
798 /* Update the SPI protocol. */
799 R_XSPI->LIOCFGCS_b[p_instance_ctrl->channel].PRTMD = p_instance_ctrl->spi_protocol & R_XSPI_LIOCFGCS_PRTMD_Msk;
800
801 /* Specifies the read/write commands and Read dummy clocks for Device
802 * (see Section 37.3.8.5 'Flow of Memory-mapping' of the RA8M1 manual R01UH0994EJ0100). */
803 uint32_t cmcfg0 = (OSPI_B_PRV_ADDRESS_REPLACE_ENABLE_BITS) |
804 (((uint32_t) p_cfg->address_bytes << R_XSPI_CMCFGCS_CMCFG0_ADDSIZE_Pos) &
805 R_XSPI_CMCFGCS_CMCFG0_ADDSIZE_Msk);
806
807 /* Use profile 1.0 format always for 8D-8D-8D. */
808 if (SPI_FLASH_PROTOCOL_8D_8D_8D == p_instance_ctrl->spi_protocol)
809 {
810 cmcfg0 |= (1U << R_XSPI_CMCFGCS_CMCFG0_FFMT_Pos);
811 }
812
813 R_XSPI->CMCFGCS[p_instance_ctrl->channel].CMCFG0 = cmcfg0;
814
815 /* Grab the appropriate command values. */
816 uint16_t read_command = (NULL != p_cmd_set) ? p_cmd_set->read_command : p_cfg->read_command;
817 uint16_t write_command = (NULL != p_cmd_set) ? p_cmd_set->page_program_command : p_cfg->page_program_command;
818
819 /* If no length is specified or if the command byte length is 1, move the command to the upper byte. */
820 if ((p_cmd_set == NULL) || (OSPI_B_COMMAND_BYTES_1 == p_cmd_set->command_bytes))
821 {
822 read_command =
823 (uint16_t) ((read_command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT);
824 write_command =
825 (uint16_t) ((write_command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT);
826 }
827
828 const uint8_t read_dummy_cycles = (NULL != p_cmd_set) ?
829 p_cmd_set->read_dummy_cycles : p_extend->read_dummy_cycles;
830 const uint8_t write_dummy_cycles = (NULL != p_cmd_set) ?
831 p_cmd_set->program_dummy_cycles : p_extend->program_dummy_cycles;
832
833 R_XSPI->CMCFGCS[p_instance_ctrl->channel].CMCFG1 =
834 (uint32_t) (((uint32_t) (read_command) << R_XSPI_CMCFGCS_CMCFG1_RDCMD_Pos) |
835 ((uint32_t) (read_dummy_cycles << R_XSPI_CMCFGCS_CMCFG1_RDLATE_Pos) &
836 R_XSPI_CMCFGCS_CMCFG1_RDLATE_Msk));
837
838 R_XSPI->CMCFGCS[p_instance_ctrl->channel].CMCFG2 =
839 (uint32_t) (((uint32_t) (write_command) << R_XSPI_CMCFGCS_CMCFG2_WRCMD_Pos) |
840 ((uint32_t) (write_dummy_cycles << R_XSPI_CMCFGCS_CMCFG2_WRLATE_Pos) &
841 R_XSPI_CMCFGCS_CMCFG2_WRLATE_Msk));
842
843 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
844 ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
845
846 /* Perform Automatic Calibration to appropriately update WRAPCFG DSSFTCSn field. */
847 if ((0 == p_cfg_extend->data_latch_delay_clocks) &&
848 (0 != (OSPI_B_PRV_PROTOCOL_USES_DS_MASK & p_instance_ctrl->spi_protocol)))
849 {
850 ret = r_ospi_b_automatic_calibration_seq(p_instance_ctrl);
851 }
852 #endif
853
854 return ret;
855 }
856
857 /*******************************************************************************************************************//**
858 * Gets device status.
859 *
860 * @param[in] p_instance_ctrl Pointer to a driver handle
861 * @param[in] bit_pos Write-in-progress bit position
862 *
863 * @return True if busy, false if not.
864 **********************************************************************************************************************/
r_ospi_b_status_sub(ospi_b_instance_ctrl_t * p_instance_ctrl,uint8_t bit_pos)865 static bool r_ospi_b_status_sub (ospi_b_instance_ctrl_t * p_instance_ctrl, uint8_t bit_pos)
866 {
867 spi_flash_cfg_t const * p_cfg = p_instance_ctrl->p_cfg;
868 spi_flash_direct_transfer_t direct_command = {0};
869 ospi_b_xspi_command_set_t const * p_cmd_set = p_instance_ctrl->p_cmd_set;
870
871 if (NULL == p_cmd_set)
872 {
873 direct_command.command = p_cfg->status_command;
874 direct_command.command_length = 1U;
875 direct_command.dummy_cycles = ((ospi_b_extended_cfg_t const *) p_cfg->p_extend)->status_dummy_cycles;
876 }
877 else
878 {
879 direct_command.command = p_cmd_set->status_command;
880 direct_command.command_length = (uint8_t) p_cmd_set->command_bytes;
881 direct_command.dummy_cycles = p_cmd_set->status_dummy_cycles;
882 }
883
884 /* Skip status check if no command was specified. */
885 if (0 == direct_command.command)
886 {
887 return false;
888 }
889
890 /* 8D-8D-8D mode requires an address for any kind of read. */
891 if (SPI_FLASH_PROTOCOL_8D_8D_8D == p_instance_ctrl->spi_protocol)
892 {
893 direct_command.address_length = (p_cfg->address_bytes + 1U) & OSPI_B_PRV_DIRECT_ADDR_AND_DATA_MASK;
894 }
895
896 direct_command.data_length = 1U;
897 r_ospi_b_direct_transfer(p_instance_ctrl->channel, &direct_command, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
898
899 return (direct_command.data >> bit_pos) & 1U;
900 }
901
902 /*******************************************************************************************************************//**
903 * Send Write enable command to the OctaFlash
904 *
905 * @param[in] p_instance_ctrl Pointer to OSPI specific control structure
906 *
907 * @retval FSP_SUCCESS Write operation completed.
908 * @retval FSP_ERR_WRITE_FAILED Write operation failed.
909 **********************************************************************************************************************/
r_ospi_b_write_enable(ospi_b_instance_ctrl_t * p_instance_ctrl)910 static fsp_err_t r_ospi_b_write_enable (ospi_b_instance_ctrl_t * p_instance_ctrl)
911 {
912 spi_flash_direct_transfer_t direct_command = {0};
913 spi_flash_cfg_t const * p_cfg = p_instance_ctrl->p_cfg;
914 ospi_b_xspi_command_set_t const * p_cmd_set = p_instance_ctrl->p_cmd_set;
915
916 if (NULL == p_cmd_set)
917 {
918 direct_command.command = p_cfg->write_enable_command;
919 direct_command.command_length = 1U;
920 }
921 else
922 {
923 direct_command.command = p_cmd_set->write_enable_command;
924 direct_command.command_length = (uint8_t) p_cmd_set->command_bytes;
925 }
926
927 /* If the command is 0x00, then skip sending the write enable. */
928 if (0 == direct_command.command)
929 {
930 return FSP_SUCCESS;
931 }
932
933 r_ospi_b_direct_transfer(p_instance_ctrl->channel, &direct_command, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
934
935 /* In case write enable is not checked, assume write is enabled. */
936 bool write_enabled = true;
937
938 #if OSPI_B_MAX_WRITE_ENABLE_LOOPS > 0U
939
940 /* Verify write is enabled. */
941 for (uint32_t i = 0U; i < OSPI_B_MAX_WRITE_ENABLE_LOOPS; i++)
942 {
943 write_enabled = r_ospi_b_status_sub(p_instance_ctrl, p_instance_ctrl->p_cfg->write_enable_bit);
944 if (write_enabled)
945 {
946 break;
947 }
948 }
949 #endif
950
951 FSP_ERROR_RETURN(write_enabled, FSP_ERR_WRITE_FAILED);
952
953 return FSP_SUCCESS;
954 }
955
956 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
957
958 /*******************************************************************************************************************//**
959 * Perform Automatic Calibration
960 *
961 * @param[in] p_instance_ctrl Pointer to OSPI specific control structure
962 *
963 * @retval FSP_SUCCESS Auto-Calibration completed successfully.
964 * @retval FSP_ERR_CALIBRATE_FAILED Auto-Calibration failed.
965 **********************************************************************************************************************/
r_ospi_b_automatic_calibration_seq(ospi_b_instance_ctrl_t * p_instance_ctrl)966 static fsp_err_t r_ospi_b_automatic_calibration_seq (ospi_b_instance_ctrl_t * p_instance_ctrl)
967 {
968 fsp_err_t ret = FSP_SUCCESS;
969 spi_flash_cfg_t * p_cfg = (spi_flash_cfg_t *) p_instance_ctrl->p_cfg;
970 ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
971
972 ospi_b_xspi_command_set_t const * p_cmd_set = p_instance_ctrl->p_cmd_set;
973
974 ospi_b_device_number_t channel = p_instance_ctrl->channel;
975
976 /* Check that calibration is not in progress. */
977 if (0 != R_XSPI->CCCTLCS[channel].CCCTL0_b.CAEN)
978 {
979 ret = FSP_ERR_CALIBRATE_FAILED;
980 }
981 else
982 {
983 const uint8_t command_bytes = (NULL != p_cmd_set) ? (uint8_t) p_cmd_set->command_bytes : 1U;
984 uint16_t read_command = (NULL != p_cmd_set) ? p_cmd_set->read_command : p_cfg->read_command;
985 const uint8_t read_dummy_cycles = (NULL != p_cmd_set) ? p_cmd_set->read_dummy_cycles : 0U;
986 const uint8_t address_bytes = (p_cfg->address_bytes == SPI_FLASH_ADDRESS_BYTES_3) ? 3U : 4U;
987
988 /* If using 1 command byte, shift the read command over as the peripheral expects. */
989 if (1U == command_bytes)
990 {
991 read_command =
992 (uint16_t) ((read_command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) <<
993 OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT);
994 }
995
996 R_XSPI->CCCTLCS[channel].CCCTL1 =
997 (((uint32_t) command_bytes << R_XSPI_CCCTLCS_CCCTL1_CACMDSIZE_Pos) &
998 R_XSPI_CCCTLCS_CCCTL1_CACMDSIZE_Msk) |
999 (((uint32_t) address_bytes << R_XSPI_CCCTLCS_CCCTL1_CAADDSIZE_Pos) & R_XSPI_CCCTLCS_CCCTL1_CAADDSIZE_Msk) |
1000 (OSPI_B_PRV_AUTOCALIBRATION_DATA_SIZE << R_XSPI_CCCTLCS_CCCTL1_CADATASIZE_Pos) |
1001 (OSPI_B_PRV_AUTOCALIBRATION_LATENCY_CYCLES << R_XSPI_CCCTLCS_CCCTL1_CAWRLATE_Pos) |
1002 (((uint32_t) read_dummy_cycles << R_XSPI_CCCTLCS_CCCTL1_CARDLATE_Pos) &
1003 R_XSPI_CCCTLCS_CCCTL1_CARDLATE_Msk);
1004
1005 R_XSPI->CCCTLCS[channel].CCCTL2 =
1006 (((uint32_t) read_command << R_XSPI_CCCTLCS_CCCTL2_CARDCMD_Pos) &
1007 R_XSPI_CCCTLCS_CCCTL2_CARDCMD_Msk);
1008
1009 R_XSPI->CCCTLCS[channel].CCCTL3 = (uint32_t) p_cfg_extend->p_autocalibration_preamble_pattern_addr &
1010 OSPI_B_PRV_ADDRESS_REPLACE_MASK;
1011 R_XSPI->CCCTLCS[channel].CCCTL4 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_0;
1012 R_XSPI->CCCTLCS[channel].CCCTL5 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_1;
1013 R_XSPI->CCCTLCS[channel].CCCTL6 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_2;
1014 R_XSPI->CCCTLCS[channel].CCCTL7 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_3;
1015
1016 R_XSPI->CCCTLCS[channel].CCCTL0 =
1017 (OSPI_B_PRV_AUTOCALIBRATION_NO_WRITE_CMD << R_XSPI_CCCTLCS_CCCTL0_CANOWR_Pos) |
1018 (OSPI_B_PRV_AUTOCALIBRATION_FRAME_INTERVAL <<
1019 R_XSPI_CCCTLCS_CCCTL0_CAITV_Pos) |
1020 (OSPI_B_PRV_AUTOCALIBRATION_SHIFT_DS_END_VALUE <<
1021 R_XSPI_CCCTLCS_CCCTL0_CASFTEND_Pos);
1022
1023 /* Automatic Calibration Enable */
1024 R_XSPI->CCCTLCS[channel].CCCTL0_b.CAEN = 1;
1025
1026 /* Check calibration success or failure. */
1027 while ((0 == ((R_XSPI->INTS >> (R_XSPI_INTS_CASUCCS_Pos + channel)) & 0x01)) &&
1028 (0 == ((R_XSPI->INTS >> (R_XSPI_INTS_CAFAILCS_Pos + channel)) & 0x01)))
1029 {
1030 /* Do nothing. */
1031 }
1032
1033 /* Disable automatic calibration */
1034 R_XSPI->CCCTLCS[channel].CCCTL0_b.CAEN = 0;
1035
1036 if (1 == ((R_XSPI->INTS >> (R_XSPI_INTS_CASUCCS_Pos + channel)) & 0x01))
1037 {
1038 /* Clear automatic calibration success status */
1039 R_XSPI->INTC = (uint32_t) 1 << (R_XSPI_INTS_CASUCCS_Pos + channel);
1040 }
1041 else if (1 == ((R_XSPI->INTS >> (R_XSPI_INTS_CAFAILCS_Pos + channel)) & 0x01))
1042 {
1043 ret = FSP_ERR_CALIBRATE_FAILED;
1044
1045 /* Clear automatic calibration failure status */
1046 R_XSPI->INTC = (uint32_t) 1 << (R_XSPI_INTS_CAFAILCS_Pos + channel);
1047 }
1048 else
1049 {
1050 /* Do nothing. */
1051 }
1052 }
1053
1054 return ret;
1055 }
1056
1057 #endif
1058
1059 /*******************************************************************************************************************//**
1060 * Performs direct data transfer with the OctaFlash
1061 *
1062 * @param[in] channel Device number to send the direct transfer to
1063 * @param[in] p_transfer Pointer to transfer parameters
1064 * @param[in] direction Read/Write
1065 **********************************************************************************************************************/
r_ospi_b_direct_transfer(ospi_b_device_number_t channel,spi_flash_direct_transfer_t * const p_transfer,spi_flash_direct_transfer_dir_t direction)1066 static void r_ospi_b_direct_transfer (ospi_b_device_number_t channel,
1067 spi_flash_direct_transfer_t * const p_transfer,
1068 spi_flash_direct_transfer_dir_t direction)
1069 {
1070 /* Setup the manual command control. Cancel any ongoing transactions, direct mode, set channel, 1 transaction. */
1071 R_XSPI->CDCTL0 = ((((uint32_t) channel) << R_XSPI_CDCTL0_CSSEL_Pos) & R_XSPI_CDCTL0_CSSEL_Msk);
1072
1073 /* Direct Read/Write settings
1074 * (see RA8M1 User's Manual section "Flow of Manual-command Procedure"). */
1075 FSP_HARDWARE_REGISTER_WAIT(R_XSPI->CDCTL0_b.TRREQ, 0);
1076
1077 uint32_t cdtbuf0 =
1078 (((uint32_t) p_transfer->command_length << R_XSPI_CDBUF_CDT_CMDSIZE_Pos) & R_XSPI_CDBUF_CDT_CMDSIZE_Msk) |
1079 (((uint32_t) p_transfer->address_length << R_XSPI_CDBUF_CDT_ADDSIZE_Pos) & R_XSPI_CDBUF_CDT_ADDSIZE_Msk) |
1080 (((uint32_t) p_transfer->data_length << R_XSPI_CDBUF_CDT_DATASIZE_Pos) & R_XSPI_CDBUF_CDT_DATASIZE_Msk) |
1081 (((uint32_t) p_transfer->dummy_cycles << R_XSPI_CDBUF_CDT_LATE_Pos) & R_XSPI_CDBUF_CDT_LATE_Msk) |
1082 (((uint32_t) direction << R_XSPI_CDBUF_CDT_TRTYPE_Pos) & R_XSPI_CDBUF_CDT_TRTYPE_Msk);
1083
1084 cdtbuf0 |= (1 == p_transfer->command_length) ?
1085 ((p_transfer->command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_UPPER_OFFSET) :
1086 ((p_transfer->command & OSPI_B_PRV_CDTBUF_CMD_2B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_OFFSET);
1087
1088 R_XSPI->CDBUF[0].CDT = cdtbuf0;
1089
1090 R_XSPI->CDBUF[0].CDA = p_transfer->address;
1091
1092 if (SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE == direction)
1093 {
1094 R_XSPI->CDBUF[0].CDD0 = (uint32_t) (p_transfer->data_u64 & UINT32_MAX);
1095 if (p_transfer->data_length > sizeof(uint32_t))
1096 {
1097 R_XSPI->CDBUF[0].CDD1 = (uint32_t) (p_transfer->data_u64 >> OSPI_B_PRV_UINT32_BITS);
1098 }
1099 }
1100
1101 R_XSPI->CDCTL0_b.TRREQ = 1;
1102 FSP_HARDWARE_REGISTER_WAIT(R_XSPI->INTS_b.CMDCMP, 1);
1103
1104 if (SPI_FLASH_DIRECT_TRANSFER_DIR_READ == direction)
1105 {
1106 p_transfer->data_u64 = R_XSPI->CDBUF[0].CDD0;
1107 if (p_transfer->data_length > sizeof(uint32_t))
1108 {
1109 p_transfer->data_u64 |= (((uint64_t) R_XSPI->CDBUF[0].CDD1) << OSPI_B_PRV_UINT32_BITS);
1110 }
1111 }
1112
1113 R_XSPI->INTC = 1 << R_XSPI_INTC_CMDCMPC_Pos;
1114 }
1115
1116 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
1117
1118 /*******************************************************************************************************************//**
1119 * Configures the device to enter or exit XiP mode.
1120 *
1121 * @param[in] p_instance_ctrl Pointer to the instance ctrl struct.
1122 * @param[in] is_entering true if entering XiP mode, false if exiting.
1123 **********************************************************************************************************************/
r_ospi_b_xip(ospi_b_instance_ctrl_t * p_instance_ctrl,bool is_entering)1124 static void r_ospi_b_xip (ospi_b_instance_ctrl_t * p_instance_ctrl, bool is_entering)
1125 {
1126 const spi_flash_cfg_t * p_cfg = p_instance_ctrl->p_cfg;
1127 volatile uint8_t * p_dummy_read_address = (volatile uint8_t *)
1128 ((OSPI_B_DEVICE_NUMBER_0 == p_instance_ctrl->channel) ?
1129 BSP_FEATURE_OSPI_B_DEVICE_0_START_ADDRESS :
1130 BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS);
1131 volatile uint8_t dummy_read = 0;
1132
1133 FSP_PARAMETER_NOT_USED(dummy_read); // Suppress variable not used error.
1134
1135 /* Clear the pre-fetch buffer for this bank so the next read is guaranteed to use the XiP code. */
1136 #if OSPI_B_CFG_PREFETCH_FUNCTION
1137 R_XSPI->BMCTL1 |= 0x03U << R_XSPI_BMCTL1_PBUFCLRCH_Pos;
1138 #endif
1139
1140 /* Wait for any on-going access to complete. */
1141 FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
1142
1143 if (is_entering)
1144 {
1145 /* Change memory-mapping to read-only mode. */
1146 R_XSPI->BMCTL0 = OSPI_B_PRV_BMCTL0_READ_ONLY_VALUE;
1147
1148 /* Configure XiP codes and enable. */
1149 const uint32_t cmctlch = R_XSPI_CMCTLCH_XIPEN_Msk |
1150 ((uint32_t) (p_cfg->xip_enter_command << R_XSPI_CMCTLCH_XIPENCODE_Pos)) |
1151 ((uint32_t) (p_cfg->xip_exit_command << R_XSPI_CMCTLCH_XIPEXCODE_Pos));
1152
1153 /* XiP enter/exit codes are configured only for memory mapped operations and affects both OSPI slave channels. */
1154 R_XSPI->CMCTLCH[0] = cmctlch;
1155 R_XSPI->CMCTLCH[1] = cmctlch;
1156
1157 /* Perform a read to send the enter code. All further reads will use the enter code and will not send a read command code. */
1158 dummy_read = *p_dummy_read_address;
1159
1160 /* Wait for the read to complete. */
1161 FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
1162 }
1163 else
1164 {
1165 /* Disable XiP. */
1166 R_XSPI->CMCTLCH[0] &= ~R_XSPI_CMCTLCH_XIPEN_Msk;
1167 R_XSPI->CMCTLCH[1] &= ~R_XSPI_CMCTLCH_XIPEN_Msk;
1168
1169 /* Perform a read to send the exit code. All further reads will not send an exit code. */
1170 dummy_read = *p_dummy_read_address;
1171
1172 /* Wait for the read to complete. */
1173 FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
1174
1175 /* Change memory-mapping back to R/W mode. */
1176 R_XSPI->BMCTL0 = OSPI_B_PRV_BMCTL0_READ_WRITE_VALUE;
1177 }
1178 }
1179
1180 #endif
1181
1182 /*******************************************************************************************************************//**
1183 * Gets the xspi command set for a protocol mode if it exists.
1184 *
1185 * @param[in] p_instance_ctrl Pointer to the instance ctrl struct.
1186 * @return Pointer to the command set, or NULL if it is normal SPI or has not been configured.
1187 **********************************************************************************************************************/
r_ospi_b_command_set_get(ospi_b_instance_ctrl_t * p_instance_ctrl)1188 static ospi_b_xspi_command_set_t const * r_ospi_b_command_set_get (ospi_b_instance_ctrl_t * p_instance_ctrl)
1189 {
1190 ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
1191
1192 if ((SPI_FLASH_PROTOCOL_EXTENDED_SPI == p_instance_ctrl->spi_protocol) ||
1193 (0 == p_cfg_extend->xspi_command_set_list_length))
1194 {
1195
1196 /* Normal SPI and modes not defined fallback to the commands defined in the spi_flash_cfg_t struct. */
1197 return NULL;
1198 }
1199
1200 for (uint32_t i = 0; i < p_cfg_extend->xspi_command_set_list_length; i++)
1201 {
1202 if (p_cfg_extend->p_xspi_command_set_list[i].protocol == p_instance_ctrl->spi_protocol)
1203 {
1204 return &p_cfg_extend->p_xspi_command_set_list[i];
1205 }
1206 }
1207
1208 /* If the protocol isn't found, return NULL. */
1209 return NULL;
1210 }
1211
1212 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
1213
1214 /*******************************************************************************************************************//**
1215 * Configures the device for DOTF operation.
1216 *
1217 * @param[in] p_dotf_cfg Pointer to the instance ctrl struct.
1218 * @retval FSP_SUCCESS DOTF configuration completed successfully.
1219 * @retval FSP_ERR_CRYPTO_SCE_KEY_SET_FAIL Key initialization failed.
1220 * @retval FSP_ERR_CRYPTO_SCE_FAIL Key wrapping failed.
1221 * @retval FSP_ERR_INVALID_ARGUMENT Invalid key type argument.
1222 **********************************************************************************************************************/
r_ospi_b_dotf_setup(ospi_b_dotf_cfg_t * p_dotf_cfg)1223 static fsp_err_t r_ospi_b_dotf_setup (ospi_b_dotf_cfg_t * p_dotf_cfg)
1224 {
1225 fsp_err_t sce_ret = FSP_SUCCESS;
1226 uint32_t seed[2] = {0};
1227 uint32_t wrapped_key[HW_SCE_AES256_KEY_INDEX_WORD_SIZE] = {0};
1228 sce_oem_cmd_t key_cmd = SCE_OEM_CMD_AES128;
1229
1230 if((((uint32_t) &(p_dotf_cfg->p_key[0])) & 0x03) && (((uint32_t) &(p_dotf_cfg->p_iv[0])) & 0x03))
1231 {
1232 return FSP_ERR_INVALID_ARGUMENT;
1233 }
1234
1235 if (OSPI_B_DOTF_AES_KEY_TYPE_128 == p_dotf_cfg->key_type)
1236 {
1237 key_cmd = SCE_OEM_CMD_AES128;
1238 }
1239 else if (OSPI_B_DOTF_AES_KEY_TYPE_192 == p_dotf_cfg->key_type)
1240 {
1241 key_cmd = SCE_OEM_CMD_AES192;
1242 }
1243 else if (OSPI_B_DOTF_AES_KEY_TYPE_256 == p_dotf_cfg->key_type)
1244 {
1245 key_cmd = SCE_OEM_CMD_AES256;
1246 }
1247 else
1248 {
1249 return FSP_ERR_INVALID_ARGUMENT;
1250 }
1251
1252 /* Initialize the crypto engine. */
1253 HW_SCE_McuSpecificInit();
1254
1255 /* Copnvert plaintext key to wrapped form. */
1256 sce_ret =
1257 HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
1258 key_cmd,
1259 NULL,
1260 NULL,
1261 (uint8_t *) p_dotf_cfg->p_key,
1262 (uint32_t *) wrapped_key);
1263 if (FSP_SUCCESS != sce_ret)
1264 {
1265 return sce_ret;
1266 }
1267
1268 /* Use wrapped key with DOTF AES Engine. */
1269 if (SCE_OEM_CMD_AES128 == key_cmd)
1270 {
1271 sce_ret = HW_SCE_Aes128OutputKeyForDotfSub(wrapped_key, seed);
1272 }
1273 else if (SCE_OEM_CMD_AES192 == key_cmd)
1274 {
1275 sce_ret = HW_SCE_Aes192OutputKeyForDotfSub(wrapped_key, seed);
1276 }
1277 else
1278 {
1279 sce_ret = HW_SCE_Aes256OutputKeyForDotfSub(wrapped_key, seed);
1280 }
1281
1282 if (sce_ret == FSP_SUCCESS)
1283 {
1284 /* Disable byte order conversion. */
1285 R_DOTF->REG00 = (OSPI_B_PRV_DOTF_REG00_RESET_VALUE | R_DOTF_REG00_B09_Msk);
1286
1287 /* Load the IV. */
1288 R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[0]);
1289 R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[1]);
1290 R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[2]);
1291 R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[3]);
1292 }
1293
1294 /* Set the start and end area for DOTF conversion. */
1295 R_DOTF->CONVAREAST = (uint32_t) p_dotf_cfg->p_start_addr;
1296 R_DOTF->CONVAREAD = (uint32_t) p_dotf_cfg->p_end_addr;
1297
1298 return sce_ret;
1299 }
1300
1301 #endif
1302