1 /* 2 * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRF_QSPI_H__ 33 #define NRF_QSPI_H__ 34 35 #include <nrfx.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** 42 * @defgroup nrf_qspi_hal QSPI HAL 43 * @{ 44 * @ingroup nrf_qspi 45 * @brief Hardware access layer for managing the QSPI peripheral. 46 */ 47 48 /** 49 * @brief This value can be used as a parameter for the @ref nrf_qspi_pins_set 50 * function to specify that a given QSPI signal (SCK, CSN, IO0, IO1, IO2, or IO3) 51 * will not be connected to a physical pin. 52 */ 53 #define NRF_QSPI_PIN_NOT_CONNECTED 0xFF 54 55 /** 56 * @brief Macro for setting proper values to pin registers. 57 */ 58 59 #define NRF_QSPI_PIN_VAL(pin) (pin) == NRF_QSPI_PIN_NOT_CONNECTED ? 0xFFFFFFFF : (pin) 60 61 /** 62 * @brief QSPI tasks. 63 */ 64 typedef enum 65 { 66 /*lint -save -e30*/ 67 NRF_QSPI_TASK_ACTIVATE = offsetof(NRF_QSPI_Type, TASKS_ACTIVATE), /**< Activate the QSPI interface. */ 68 NRF_QSPI_TASK_READSTART = offsetof(NRF_QSPI_Type, TASKS_READSTART), /**< Start transfer from external flash memory to internal RAM. */ 69 NRF_QSPI_TASK_WRITESTART = offsetof(NRF_QSPI_Type, TASKS_WRITESTART), /**< Start transfer from internal RAM to external flash memory. */ 70 NRF_QSPI_TASK_ERASESTART = offsetof(NRF_QSPI_Type, TASKS_ERASESTART), /**< Start external flash memory erase operation. */ 71 NRF_QSPI_TASK_DEACTIVATE = offsetof(NRF_QSPI_Type, TASKS_DEACTIVATE), /**< Deactivate the QSPI interface. */ 72 /*lint -restore*/ 73 } nrf_qspi_task_t; 74 75 /** 76 * @brief QSPI events. 77 */ 78 typedef enum 79 { 80 /*lint -save -e30*/ 81 NRF_QSPI_EVENT_READY = offsetof(NRF_QSPI_Type, EVENTS_READY) /**< QSPI peripheral is ready after it executes any task. */ 82 /*lint -restore*/ 83 } nrf_qspi_event_t; 84 85 /** 86 * @brief QSPI interrupts. 87 */ 88 typedef enum 89 { 90 NRF_QSPI_INT_READY_MASK = QSPI_INTENSET_READY_Msk /**< Interrupt on READY event. */ 91 } nrf_qspi_int_mask_t; 92 93 /** 94 * @brief QSPI frequency divider values. 95 */ 96 typedef enum 97 { 98 NRF_QSPI_FREQ_32MDIV1, /**< 32.0 MHz. */ 99 NRF_QSPI_FREQ_32MDIV2, /**< 16.0 MHz. */ 100 NRF_QSPI_FREQ_32MDIV3, /**< 10.6 MHz. */ 101 NRF_QSPI_FREQ_32MDIV4, /**< 8.00 MHz. */ 102 NRF_QSPI_FREQ_32MDIV5, /**< 6.40 MHz. */ 103 NRF_QSPI_FREQ_32MDIV6, /**< 5.33 MHz. */ 104 NRF_QSPI_FREQ_32MDIV7, /**< 4.57 MHz. */ 105 NRF_QSPI_FREQ_32MDIV8, /**< 4.00 MHz. */ 106 NRF_QSPI_FREQ_32MDIV9, /**< 3.55 MHz. */ 107 NRF_QSPI_FREQ_32MDIV10, /**< 3.20 MHz. */ 108 NRF_QSPI_FREQ_32MDIV11, /**< 2.90 MHz. */ 109 NRF_QSPI_FREQ_32MDIV12, /**< 2.66 MHz. */ 110 NRF_QSPI_FREQ_32MDIV13, /**< 2.46 MHz. */ 111 NRF_QSPI_FREQ_32MDIV14, /**< 2.29 MHz. */ 112 NRF_QSPI_FREQ_32MDIV15, /**< 2.13 MHz. */ 113 NRF_QSPI_FREQ_32MDIV16, /**< 2.00 MHz. */ 114 } nrf_qspi_frequency_t; 115 116 /** 117 * @brief Interface configuration for a read operation. 118 */ 119 typedef enum 120 { 121 NRF_QSPI_READOC_FASTREAD = QSPI_IFCONFIG0_READOC_FASTREAD, /**< Single data line SPI. FAST_READ (opcode 0x0B). */ 122 NRF_QSPI_READOC_READ2O = QSPI_IFCONFIG0_READOC_READ2O, /**< Dual data line SPI. READ2O (opcode 0x3B). */ 123 NRF_QSPI_READOC_READ2IO = QSPI_IFCONFIG0_READOC_READ2IO, /**< Dual data line SPI. READ2IO (opcode 0xBB). */ 124 NRF_QSPI_READOC_READ4O = QSPI_IFCONFIG0_READOC_READ4O, /**< Quad data line SPI. READ4O (opcode 0x6B). */ 125 NRF_QSPI_READOC_READ4IO = QSPI_IFCONFIG0_READOC_READ4IO /**< Quad data line SPI. READ4IO (opcode 0xEB). */ 126 } nrf_qspi_readoc_t; 127 128 /** 129 * @brief Interface configuration for a write operation. 130 */ 131 typedef enum 132 { 133 NRF_QSPI_WRITEOC_PP = QSPI_IFCONFIG0_WRITEOC_PP, /**< Single data line SPI. PP (opcode 0x02). */ 134 NRF_QSPI_WRITEOC_PP2O = QSPI_IFCONFIG0_WRITEOC_PP2O, /**< Dual data line SPI. PP2O (opcode 0xA2). */ 135 NRF_QSPI_WRITEOC_PP4O = QSPI_IFCONFIG0_WRITEOC_PP4O, /**< Quad data line SPI. PP4O (opcode 0x32). */ 136 NRF_QSPI_WRITEOC_PP4IO = QSPI_IFCONFIG0_WRITEOC_PP4IO, /**< Quad data line SPI. READ4O (opcode 0x38). */ 137 } nrf_qspi_writeoc_t; 138 139 /** 140 * @brief Interface configuration for addressing mode. 141 */ 142 typedef enum 143 { 144 NRF_QSPI_ADDRMODE_24BIT = QSPI_IFCONFIG0_ADDRMODE_24BIT, /**< 24-bit addressing. */ 145 NRF_QSPI_ADDRMODE_32BIT = QSPI_IFCONFIG0_ADDRMODE_32BIT /**< 32-bit addressing. */ 146 } nrf_qspi_addrmode_t; 147 148 /** 149 * @brief QSPI SPI mode. Polarization and phase configuration. 150 */ 151 typedef enum 152 { 153 NRF_QSPI_MODE_0 = QSPI_IFCONFIG1_SPIMODE_MODE0, /**< Mode 0 (CPOL=0, CPHA=0). */ 154 NRF_QSPI_MODE_1 = QSPI_IFCONFIG1_SPIMODE_MODE3 /**< Mode 1 (CPOL=1, CPHA=1). */ 155 } nrf_qspi_spi_mode_t; 156 157 /** 158 * @brief Addressing configuration mode. 159 */ 160 typedef enum 161 { 162 NRF_QSPI_ADDRCONF_MODE_NOINSTR = QSPI_ADDRCONF_MODE_NoInstr, /**< Do not send any instruction. */ 163 NRF_QSPI_ADDRCONF_MODE_OPCODE = QSPI_ADDRCONF_MODE_Opcode, /**< Send opcode. */ 164 NRF_QSPI_ADDRCONF_MODE_OPBYTE0 = QSPI_ADDRCONF_MODE_OpByte0, /**< Send opcode, byte0. */ 165 NRF_QSPI_ADDRCONF_MODE_ALL = QSPI_ADDRCONF_MODE_All /**< Send opcode, byte0, byte1. */ 166 } nrf_qspi_addrconfig_mode_t; 167 168 /** 169 * @brief Erasing data length. 170 */ 171 typedef enum 172 { 173 NRF_QSPI_ERASE_LEN_4KB = QSPI_ERASE_LEN_LEN_4KB, /**< Erase 4 kB block (flash command 0x20). */ 174 NRF_QSPI_ERASE_LEN_64KB = QSPI_ERASE_LEN_LEN_64KB, /**< Erase 64 kB block (flash command 0xD8). */ 175 NRF_QSPI_ERASE_LEN_ALL = QSPI_ERASE_LEN_LEN_All /**< Erase all (flash command 0xC7). */ 176 } nrf_qspi_erase_len_t; 177 178 /** 179 * @brief Custom instruction length. 180 */ 181 typedef enum 182 { 183 NRF_QSPI_CINSTR_LEN_1B = QSPI_CINSTRCONF_LENGTH_1B, /**< Send opcode only. */ 184 NRF_QSPI_CINSTR_LEN_2B = QSPI_CINSTRCONF_LENGTH_2B, /**< Send opcode, CINSTRDAT0.BYTE0. */ 185 NRF_QSPI_CINSTR_LEN_3B = QSPI_CINSTRCONF_LENGTH_3B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE1. */ 186 NRF_QSPI_CINSTR_LEN_4B = QSPI_CINSTRCONF_LENGTH_4B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE2. */ 187 NRF_QSPI_CINSTR_LEN_5B = QSPI_CINSTRCONF_LENGTH_5B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE3. */ 188 NRF_QSPI_CINSTR_LEN_6B = QSPI_CINSTRCONF_LENGTH_6B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE4. */ 189 NRF_QSPI_CINSTR_LEN_7B = QSPI_CINSTRCONF_LENGTH_7B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE5. */ 190 NRF_QSPI_CINSTR_LEN_8B = QSPI_CINSTRCONF_LENGTH_8B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE6. */ 191 NRF_QSPI_CINSTR_LEN_9B = QSPI_CINSTRCONF_LENGTH_9B /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE7. */ 192 } nrf_qspi_cinstr_len_t; 193 194 /** 195 * @brief Pins configuration. 196 */ 197 typedef struct 198 { 199 uint8_t sck_pin; /**< SCK pin number. */ 200 uint8_t csn_pin; /**< Chip select pin number. */ 201 uint8_t io0_pin; /**< IO0/MOSI pin number. */ 202 uint8_t io1_pin; /**< IO1/MISO pin number. */ 203 uint8_t io2_pin; /**< IO2 pin number (optional). 204 * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed. 205 */ 206 uint8_t io3_pin; /**< IO3 pin number (optional). 207 * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed. 208 */ 209 } nrf_qspi_pins_t; 210 211 /** 212 * @brief Custom instruction configuration. 213 */ 214 typedef struct 215 { 216 uint8_t opcode; /**< Opcode used in custom instruction transmission. */ 217 nrf_qspi_cinstr_len_t length; /**< Length of the custom instruction data. */ 218 bool io2_level; /**< I/O line level during transmission. */ 219 bool io3_level; /**< I/O line level during transmission. */ 220 bool wipwait; /**< Wait if a Wait in Progress bit is set in the memory status byte. */ 221 bool wren; /**< Send write enable before instruction. */ 222 } nrf_qspi_cinstr_conf_t; 223 224 /** 225 * @brief Addressing mode register configuration. See @ref nrf_qspi_addrconfig_set 226 */ 227 typedef struct 228 { 229 uint8_t opcode; /**< Opcode used to enter proper addressing mode. */ 230 uint8_t byte0; /**< Byte following the opcode. */ 231 uint8_t byte1; /**< Byte following byte0. */ 232 nrf_qspi_addrconfig_mode_t mode; /**< Extended addresing mode. */ 233 bool wipwait; /**< Enable/disable waiting for complete operation execution. */ 234 bool wren; /**< Send write enable before instruction. */ 235 } nrf_qspi_addrconfig_conf_t; 236 237 /** 238 * @brief Structure with QSPI protocol interface configuration. 239 */ 240 typedef struct 241 { 242 nrf_qspi_readoc_t readoc; /**< Read operation code. */ 243 nrf_qspi_writeoc_t writeoc; /**< Write operation code. */ 244 nrf_qspi_addrmode_t addrmode; /**< Addresing mode (24-bit or 32-bit). */ 245 bool dpmconfig; /**< Enable the Deep Power-down Mode (DPM) feature. */ 246 } nrf_qspi_prot_conf_t; 247 248 /** 249 * @brief QSPI physical interface configuration. 250 */ 251 typedef struct 252 { 253 uint8_t sck_delay; /**< tSHSL, tWHSL, and tSHWL in number of 16 MHz periods (62.5ns). */ 254 bool dpmen; /**< Enable the DPM feature. */ 255 nrf_qspi_spi_mode_t spi_mode; /**< SPI phase and polarization. */ 256 nrf_qspi_frequency_t sck_freq; /**< SCK frequency given as enum @ref nrf_qspi_frequency_t. */ 257 } nrf_qspi_phy_conf_t; 258 259 /** 260 * @brief Function for activating a specific QSPI task. 261 * 262 * @param[in] p_reg Pointer to the peripheral register structure. 263 * @param[in] task Task to activate. 264 */ 265 __STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task); 266 267 /** 268 * @brief Function for getting the address of a specific QSPI task register. 269 * 270 * @param[in] p_reg Pointer to the peripheral register structure. 271 * @param[in] task Requested task. 272 * 273 * @return Address of the specified task register. 274 */ 275 __STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg, 276 nrf_qspi_task_t task); 277 278 /** 279 * @brief Function for clearing a specific QSPI event. 280 * 281 * @param[in] p_reg Pointer to the peripheral register structure. 282 * @param[in] qspi_event Event to clear. 283 */ 284 __STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event); 285 286 /** 287 * @brief Function for checking the state of a specific SPI event. 288 * 289 * @param[in] p_reg Pointer to the peripheral register structure. 290 * @param[in] qspi_event Event to check. 291 * 292 * @retval true If the event is set. 293 * @retval false If the event is not set. 294 */ 295 __STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event); 296 297 /** 298 * @brief Function for getting the address of a specific QSPI event register. 299 * 300 * @param[in] p_reg Pointer to the peripheral register structure. 301 * @param[in] qspi_event Requested event. 302 * 303 * @return Address of the specified event register. 304 */ 305 __STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg, 306 nrf_qspi_event_t qspi_event); 307 308 /** 309 * @brief Function for enabling specified interrupts. 310 * 311 * @param[in] p_reg Pointer to the peripheral register structure. 312 * @param[in] qspi_int_mask Interrupts to enable. 313 */ 314 __STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask); 315 316 /** 317 * @brief Function for disabling specified interrupts. 318 * 319 * @param[in] p_reg Pointer to the peripheral register structure. 320 * @param[in] qspi_int_mask Interrupts to disable. 321 */ 322 __STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask); 323 324 /** 325 * @brief Function for retrieving the state of a given interrupt. 326 * 327 * @param[in] p_reg Pointer to the peripheral register structure. 328 * @param[in] qspi_int Interrupt to check. 329 * 330 * @retval true If the interrupt is enabled. 331 * @retval false If the interrupt is not enabled. 332 */ 333 __STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, 334 nrf_qspi_int_mask_t qspi_int); 335 336 /** 337 * @brief Function for enabling the QSPI peripheral. 338 * 339 * @param[in] p_reg Pointer to the peripheral register structure. 340 */ 341 __STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg); 342 343 /** 344 * @brief Function for disabling the QSPI peripheral. 345 * 346 * @param[in] p_reg Pointer to the peripheral register structure. 347 */ 348 __STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg); 349 350 /** 351 * @brief Function for configuring QSPI pins. 352 * 353 * If a given signal is not needed, pass the @ref NRF_QSPI_PIN_NOT_CONNECTED 354 * value instead of its pin number. 355 * 356 * @param[in] p_reg Pointer to the peripheral register structure. 357 * @param[in] p_pins Pointer to the pins configuration structure. See @ref nrf_qspi_pins_t. 358 */ 359 __STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, 360 const nrf_qspi_pins_t * p_pins); 361 362 /** 363 * @brief Function for setting the QSPI XIPOFFSET register. 364 * 365 * @param[in] p_reg Pointer to the peripheral register structure. 366 * @param[in] xip_offset Address offset in the external memory for Execute in Place operation. 367 */ 368 __STATIC_INLINE void nrf_qspi_xip_offset_set(NRF_QSPI_Type * p_reg, 369 uint32_t xip_offset); 370 371 /** 372 * @brief Function for setting the QSPI IFCONFIG0 register. 373 * 374 * @param[in] p_reg Pointer to the peripheral register structure. 375 * @param[in] p_config Pointer to the QSPI protocol interface configuration structure. See @ref nrf_qspi_prot_conf_t. 376 */ 377 __STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg, 378 const nrf_qspi_prot_conf_t * p_config); 379 380 /** 381 * @brief Function for setting the QSPI IFCONFIG1 register. 382 * 383 * @param[in] p_reg Pointer to the peripheral register structure. 384 * @param[in] p_config Pointer to the QSPI physical interface configuration structure. See @ref nrf_qspi_phy_conf_t. 385 */ 386 __STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg, 387 const nrf_qspi_phy_conf_t * p_config); 388 389 /** 390 * @brief Function for setting the QSPI ADDRCONF register. 391 * 392 * Function must be executed before sending task NRF_QSPI_TASK_ACTIVATE. Data stored in the structure 393 * is sent during the start of the peripheral. Remember that the reset instruction can set 394 * addressing mode to default in the memory device. If memory reset is necessary before configuring 395 * the addressing mode, use custom instruction feature instead of this function. 396 * Case with reset: Enable the peripheral without setting ADDRCONF register, send reset instructions 397 * using a custom instruction feature (reset enable and then reset), set proper addressing mode 398 * using the custom instruction feature. 399 * 400 * @param[in] p_reg Pointer to the peripheral register structure. 401 * @param[in] p_config Pointer to the addressing mode configuration structure. See @ref nrf_qspi_addrconfig_conf_t. 402 */ 403 __STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg, 404 const nrf_qspi_addrconfig_conf_t * p_config); 405 406 /** 407 * @brief Function for setting write data into the peripheral register (without starting the process). 408 * 409 * @param[in] p_reg Pointer to the peripheral register structure. 410 * @param[in] p_buffer Pointer to the writing buffer. 411 * @param[in] length Lenght of the writing data. 412 * @param[in] dest_addr Address in memory to write to. 413 */ 414 __STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg, 415 void const * p_buffer, 416 uint32_t length, 417 uint32_t dest_addr); 418 419 /** 420 * @brief Function for setting read data into the peripheral register (without starting the process). 421 * 422 * @param[in] p_reg Pointer to the peripheral register structure. 423 * @param[out] p_buffer Pointer to the reading buffer. 424 * @param[in] length Length of the read data. 425 * @param[in] src_addr Address in memory to read from. 426 */ 427 __STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg, 428 void * p_buffer, 429 uint32_t length, 430 uint32_t src_addr); 431 432 /** 433 * @brief Function for setting erase data into the peripheral register (without starting the process). 434 * 435 * @param[in] p_reg Pointer to the peripheral register structure. 436 * @param[in] erase_addr Start address to erase. Address must have padding set to 4 bytes. 437 * @param[in] len Size of erasing area. 438 */ 439 __STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg, 440 uint32_t erase_addr, 441 nrf_qspi_erase_len_t len); 442 443 /** 444 * @brief Function for getting the peripheral status register. 445 * 446 * @param[in] p_reg Pointer to the peripheral register structure. 447 * 448 * @return Peripheral status register. 449 */ 450 __STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg); 451 452 /** 453 * @brief Function for getting the device status register stored in the peripheral status register. 454 * 455 * @param[in] p_reg Pointer to the peripheral register structure. 456 * 457 * @return Device status register (lower byte). 458 */ 459 __STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg); 460 461 /** 462 * @brief Function for checking if the peripheral is busy or not. 463 * 464 * @param[in] p_reg Pointer to the peripheral register structure. 465 * 466 * @retval true If QSPI is busy. 467 * @retval false If QSPI is ready. 468 */ 469 __STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg); 470 471 /** 472 * @brief Function for setting registers sending with custom instruction transmission. 473 * 474 * This function can be ommited when using NRF_QSPI_CINSTR_LEN_1B as the length argument 475 * (sending only opcode without data). 476 * 477 * @param[in] p_reg Pointer to the peripheral register structure. 478 * @param[in] length Length of the custom instruction data. 479 * @param[in] p_tx_data Pointer to the data to send with the custom instruction. 480 */ 481 __STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg, 482 nrf_qspi_cinstr_len_t length, 483 void const * p_tx_data); 484 485 /** 486 * @brief Function for getting data from register after custom instruction transmission. 487 * @param[in] p_reg Pointer to the peripheral register structure. 488 * @param[in] length Length of the custom instruction data. 489 * @param[in] p_rx_data Pointer to the reading buffer. 490 */ 491 __STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg, 492 nrf_qspi_cinstr_len_t length, 493 void * p_rx_data); 494 495 /** 496 * @brief Function for sending custom instruction to external memory. 497 * 498 * @param[in] p_reg Pointer to the peripheral register structure. 499 * @param[in] p_config Pointer to the custom instruction configuration structure. See @ref nrf_qspi_cinstr_conf_t. 500 */ 501 502 __STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg, 503 const nrf_qspi_cinstr_conf_t * p_config); 504 505 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 506 507 __STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task) 508 { 509 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; 510 } 511 512 __STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg, 513 nrf_qspi_task_t task) 514 { 515 return ((uint32_t)p_reg + (uint32_t)task); 516 } 517 518 __STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event) 519 { 520 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event)) = 0x0UL; 521 } 522 523 __STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event) 524 { 525 return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event); 526 } 527 528 __STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg, 529 nrf_qspi_event_t qspi_event) 530 { 531 return (uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event); 532 } 533 534 __STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask) 535 { 536 p_reg->INTENSET = qspi_int_mask; 537 } 538 539 __STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask) 540 { 541 p_reg->INTENCLR = qspi_int_mask; 542 } 543 544 __STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, 545 nrf_qspi_int_mask_t qspi_int) 546 { 547 return (bool)(p_reg->INTENSET & qspi_int); 548 } 549 550 __STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg) 551 { 552 p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Enabled << QSPI_ENABLE_ENABLE_Pos); 553 } 554 555 __STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg) 556 { 557 // Workaround for nRF52840 anomaly 122: Current consumption is too high. 558 *(volatile uint32_t *)0x40029054ul = 1ul; 559 560 p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Disabled << QSPI_ENABLE_ENABLE_Pos); 561 } 562 563 __STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, const nrf_qspi_pins_t * p_pins) 564 { 565 p_reg->PSEL.SCK = NRF_QSPI_PIN_VAL(p_pins->sck_pin); 566 p_reg->PSEL.CSN = NRF_QSPI_PIN_VAL(p_pins->csn_pin); 567 p_reg->PSEL.IO0 = NRF_QSPI_PIN_VAL(p_pins->io0_pin); 568 p_reg->PSEL.IO1 = NRF_QSPI_PIN_VAL(p_pins->io1_pin); 569 p_reg->PSEL.IO2 = NRF_QSPI_PIN_VAL(p_pins->io2_pin); 570 p_reg->PSEL.IO3 = NRF_QSPI_PIN_VAL(p_pins->io3_pin); 571 } 572 573 __STATIC_INLINE void nrf_qspi_xip_offset_set(NRF_QSPI_Type * p_reg, 574 uint32_t xip_offset) 575 { 576 p_reg->XIPOFFSET = xip_offset; 577 } 578 579 __STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg, 580 const nrf_qspi_prot_conf_t * p_config) 581 { 582 uint32_t config = p_config->readoc; 583 config |= ((uint32_t)p_config->writeoc) << QSPI_IFCONFIG0_WRITEOC_Pos; 584 config |= ((uint32_t)p_config->addrmode) << QSPI_IFCONFIG0_ADDRMODE_Pos; 585 config |= (p_config->dpmconfig ? 1U : 0U ) << QSPI_IFCONFIG0_DPMENABLE_Pos; 586 587 p_reg->IFCONFIG0 = config; 588 } 589 590 __STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg, 591 const nrf_qspi_phy_conf_t * p_config) 592 { 593 // IFCONFIG1 mask for reserved fields in the register. 594 uint32_t config = p_reg->IFCONFIG1 & 0x00FFFF00; 595 config |= p_config->sck_delay; 596 config |= (p_config->dpmen ? 1U : 0U) << QSPI_IFCONFIG1_DPMEN_Pos; 597 config |= ((uint32_t)(p_config->spi_mode)) << QSPI_IFCONFIG1_SPIMODE_Pos; 598 config |= ((uint32_t)(p_config->sck_freq)) << QSPI_IFCONFIG1_SCKFREQ_Pos; 599 600 p_reg->IFCONFIG1 = config; 601 } 602 603 __STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg, 604 const nrf_qspi_addrconfig_conf_t * p_config) 605 { 606 uint32_t config = p_config->opcode; 607 config |= ((uint32_t)p_config->byte0) << QSPI_ADDRCONF_BYTE0_Pos; 608 config |= ((uint32_t)p_config->byte1) << QSPI_ADDRCONF_BYTE1_Pos; 609 config |= ((uint32_t)(p_config->mode)) << QSPI_ADDRCONF_MODE_Pos; 610 config |= (p_config->wipwait ? 1U : 0U) << QSPI_ADDRCONF_WIPWAIT_Pos; 611 config |= (p_config->wren ? 1U : 0U) << QSPI_ADDRCONF_WREN_Pos; 612 613 p_reg->ADDRCONF = config; 614 } 615 616 __STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg, 617 void const * p_buffer, 618 uint32_t length, 619 uint32_t dest_addr) 620 { 621 p_reg->WRITE.DST = dest_addr; 622 p_reg->WRITE.SRC = (uint32_t) p_buffer; 623 p_reg->WRITE.CNT = length; 624 } 625 626 __STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg, 627 void * p_buffer, 628 uint32_t length, 629 uint32_t src_addr) 630 { 631 p_reg->READ.SRC = src_addr; 632 p_reg->READ.DST = (uint32_t) p_buffer; 633 p_reg->READ.CNT = length; 634 } 635 636 __STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg, 637 uint32_t erase_addr, 638 nrf_qspi_erase_len_t len) 639 { 640 p_reg->ERASE.PTR = erase_addr; 641 p_reg->ERASE.LEN = len; 642 } 643 644 __STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg) 645 { 646 return p_reg->STATUS; 647 } 648 649 __STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg) 650 { 651 return (uint8_t)(p_reg->STATUS & QSPI_STATUS_SREG_Msk) >> QSPI_STATUS_SREG_Pos; 652 } 653 654 __STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg) 655 { 656 return ((p_reg->STATUS & QSPI_STATUS_READY_Msk) >> 657 QSPI_STATUS_READY_Pos) == QSPI_STATUS_READY_BUSY; 658 } 659 660 __STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg, 661 nrf_qspi_cinstr_len_t length, 662 void const * p_tx_data) 663 { 664 uint32_t reg = 0; 665 uint8_t const *p_tx_data_8 = (uint8_t const *) p_tx_data; 666 667 // Load custom instruction. 668 switch (length) 669 { 670 case NRF_QSPI_CINSTR_LEN_9B: 671 reg |= ((uint32_t)p_tx_data_8[7]) << QSPI_CINSTRDAT1_BYTE7_Pos; 672 /* fall-through */ 673 case NRF_QSPI_CINSTR_LEN_8B: 674 reg |= ((uint32_t)p_tx_data_8[6]) << QSPI_CINSTRDAT1_BYTE6_Pos; 675 /* fall-through */ 676 case NRF_QSPI_CINSTR_LEN_7B: 677 reg |= ((uint32_t)p_tx_data_8[5]) << QSPI_CINSTRDAT1_BYTE5_Pos; 678 /* fall-through */ 679 case NRF_QSPI_CINSTR_LEN_6B: 680 reg |= ((uint32_t)p_tx_data_8[4]); 681 p_reg->CINSTRDAT1 = reg; 682 reg = 0; 683 /* fall-through */ 684 case NRF_QSPI_CINSTR_LEN_5B: 685 reg |= ((uint32_t)p_tx_data_8[3]) << QSPI_CINSTRDAT0_BYTE3_Pos; 686 /* fall-through */ 687 case NRF_QSPI_CINSTR_LEN_4B: 688 reg |= ((uint32_t)p_tx_data_8[2]) << QSPI_CINSTRDAT0_BYTE2_Pos; 689 /* fall-through */ 690 case NRF_QSPI_CINSTR_LEN_3B: 691 reg |= ((uint32_t)p_tx_data_8[1]) << QSPI_CINSTRDAT0_BYTE1_Pos; 692 /* fall-through */ 693 case NRF_QSPI_CINSTR_LEN_2B: 694 reg |= ((uint32_t)p_tx_data_8[0]); 695 p_reg->CINSTRDAT0 = reg; 696 /* fall-through */ 697 case NRF_QSPI_CINSTR_LEN_1B: 698 /* Send only opcode. Case to avoid compiler warnings. */ 699 break; 700 default: 701 break; 702 } 703 } 704 705 __STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg, 706 nrf_qspi_cinstr_len_t length, 707 void * p_rx_data) 708 { 709 uint8_t *p_rx_data_8 = (uint8_t *) p_rx_data; 710 711 uint32_t reg1 = p_reg->CINSTRDAT1; 712 uint32_t reg0 = p_reg->CINSTRDAT0; 713 switch (length) 714 { 715 case NRF_QSPI_CINSTR_LEN_9B: 716 p_rx_data_8[7] = (uint8_t)(reg1 >> QSPI_CINSTRDAT1_BYTE7_Pos); 717 /* fall-through */ 718 case NRF_QSPI_CINSTR_LEN_8B: 719 p_rx_data_8[6] = (uint8_t)(reg1 >> QSPI_CINSTRDAT1_BYTE6_Pos); 720 /* fall-through */ 721 case NRF_QSPI_CINSTR_LEN_7B: 722 p_rx_data_8[5] = (uint8_t)(reg1 >> QSPI_CINSTRDAT1_BYTE5_Pos); 723 /* fall-through */ 724 case NRF_QSPI_CINSTR_LEN_6B: 725 p_rx_data_8[4] = (uint8_t)(reg1); 726 /* fall-through */ 727 case NRF_QSPI_CINSTR_LEN_5B: 728 p_rx_data_8[3] = (uint8_t)(reg0 >> QSPI_CINSTRDAT0_BYTE3_Pos); 729 /* fall-through */ 730 case NRF_QSPI_CINSTR_LEN_4B: 731 p_rx_data_8[2] = (uint8_t)(reg0 >> QSPI_CINSTRDAT0_BYTE2_Pos); 732 /* fall-through */ 733 case NRF_QSPI_CINSTR_LEN_3B: 734 p_rx_data_8[1] = (uint8_t)(reg0 >> QSPI_CINSTRDAT0_BYTE1_Pos); 735 /* fall-through */ 736 case NRF_QSPI_CINSTR_LEN_2B: 737 p_rx_data_8[0] = (uint8_t)(reg0); 738 /* fall-through */ 739 case NRF_QSPI_CINSTR_LEN_1B: 740 /* Send only opcode. Case to avoid compiler warnings. */ 741 break; 742 default: 743 break; 744 } 745 } 746 747 __STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg, 748 const nrf_qspi_cinstr_conf_t * p_config) 749 { 750 p_reg->CINSTRCONF = (((uint32_t)p_config->opcode << QSPI_CINSTRCONF_OPCODE_Pos) | 751 ((uint32_t)p_config->length << QSPI_CINSTRCONF_LENGTH_Pos) | 752 ((uint32_t)p_config->io2_level << QSPI_CINSTRCONF_LIO2_Pos) | 753 ((uint32_t)p_config->io3_level << QSPI_CINSTRCONF_LIO3_Pos) | 754 ((uint32_t)p_config->wipwait << QSPI_CINSTRCONF_WIPWAIT_Pos) | 755 ((uint32_t)p_config->wren << QSPI_CINSTRCONF_WREN_Pos)); 756 } 757 758 #endif // SUPPRESS_INLINE_IMPLEMENTATION 759 760 /** @} */ 761 762 #ifdef __cplusplus 763 } 764 #endif 765 766 #endif // NRF_QSPI_H__ 767