From 9da67d42381862a0d1bfe15c475e71d7e6be32c0 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 24 Jun 2024 17:21:34 +0200 Subject: [PATCH] hw/mcu/nordic: Add common QSPI HAL --- hw/bsp/nordic_pca10056/src/hal_bsp.c | 2 +- hw/bsp/nordic_pca10059/src/hal_bsp.c | 2 +- hw/bsp/nordic_pca10095/src/hal_bsp.c | 2 +- hw/bsp/nordic_pca10121/src/hal_bsp.c | 2 +- hw/bsp/nordic_thingy53/src/hal_bsp.c | 2 +- hw/bsp/ublox_bmd_345/src/hal_bsp.c | 2 +- .../nordic/nrf52xxx/include/mcu/nrf52_hal.h | 2 - .../nrf52xxx/include/nrfx_config_nrf52840.h | 4 + hw/mcu/nordic/nrf52xxx/src/hal_qspi.c | 346 --------------- .../include/nrfx_config_nrf5340_application.h | 4 + hw/mcu/nordic/nrf5340/src/hal_qspi.c | 407 ------------------ hw/mcu/nordic/nrf91xx/include/mcu/nrf91_hal.h | 2 - hw/mcu/nordic/nrf_common/include/nrf_hal.h | 1 + .../{nrf91xx => nrf_common}/src/hal_qspi.c | 215 ++++----- 14 files changed, 126 insertions(+), 867 deletions(-) delete mode 100644 hw/mcu/nordic/nrf52xxx/src/hal_qspi.c delete mode 100644 hw/mcu/nordic/nrf5340/src/hal_qspi.c rename hw/mcu/nordic/{nrf91xx => nrf_common}/src/hal_qspi.c (57%) diff --git a/hw/bsp/nordic_pca10056/src/hal_bsp.c b/hw/bsp/nordic_pca10056/src/hal_bsp.c index c594858c2f..976e87d46f 100644 --- a/hw/bsp/nordic_pca10056/src/hal_bsp.c +++ b/hw/bsp/nordic_pca10056/src/hal_bsp.c @@ -51,7 +51,7 @@ hal_bsp_flash_dev(uint8_t id) } #if MYNEWT_VAL(QSPI_ENABLE) if (id == 1) { - return &nrf52k_qspi_dev; + return &nrf_qspi_dev; } #endif return NULL; diff --git a/hw/bsp/nordic_pca10059/src/hal_bsp.c b/hw/bsp/nordic_pca10059/src/hal_bsp.c index c594858c2f..976e87d46f 100644 --- a/hw/bsp/nordic_pca10059/src/hal_bsp.c +++ b/hw/bsp/nordic_pca10059/src/hal_bsp.c @@ -51,7 +51,7 @@ hal_bsp_flash_dev(uint8_t id) } #if MYNEWT_VAL(QSPI_ENABLE) if (id == 1) { - return &nrf52k_qspi_dev; + return &nrf_qspi_dev; } #endif return NULL; diff --git a/hw/bsp/nordic_pca10095/src/hal_bsp.c b/hw/bsp/nordic_pca10095/src/hal_bsp.c index f0ceef03b5..2defa454bb 100644 --- a/hw/bsp/nordic_pca10095/src/hal_bsp.c +++ b/hw/bsp/nordic_pca10095/src/hal_bsp.c @@ -57,7 +57,7 @@ hal_bsp_flash_dev(uint8_t id) } #if MYNEWT_VAL(QSPI_ENABLE) if (id == 1) { - return &nrf5340_qspi_dev; + return &nrf_qspi_dev; } #endif #if MYNEWT_VAL(IPC_NRF5340_FLASH_CLIENT) diff --git a/hw/bsp/nordic_pca10121/src/hal_bsp.c b/hw/bsp/nordic_pca10121/src/hal_bsp.c index e4487e59d2..336183ef79 100644 --- a/hw/bsp/nordic_pca10121/src/hal_bsp.c +++ b/hw/bsp/nordic_pca10121/src/hal_bsp.c @@ -58,7 +58,7 @@ hal_bsp_flash_dev(uint8_t id) } #if MYNEWT_VAL(QSPI_ENABLE) if (id == 1) { - return &nrf5340_qspi_dev; + return &nrf_qspi_dev; } #endif #if MYNEWT_VAL(IPC_NRF5340_FLASH_CLIENT) diff --git a/hw/bsp/nordic_thingy53/src/hal_bsp.c b/hw/bsp/nordic_thingy53/src/hal_bsp.c index f0ceef03b5..2defa454bb 100644 --- a/hw/bsp/nordic_thingy53/src/hal_bsp.c +++ b/hw/bsp/nordic_thingy53/src/hal_bsp.c @@ -57,7 +57,7 @@ hal_bsp_flash_dev(uint8_t id) } #if MYNEWT_VAL(QSPI_ENABLE) if (id == 1) { - return &nrf5340_qspi_dev; + return &nrf_qspi_dev; } #endif #if MYNEWT_VAL(IPC_NRF5340_FLASH_CLIENT) diff --git a/hw/bsp/ublox_bmd_345/src/hal_bsp.c b/hw/bsp/ublox_bmd_345/src/hal_bsp.c index b364a9af3a..e3566f9e19 100644 --- a/hw/bsp/ublox_bmd_345/src/hal_bsp.c +++ b/hw/bsp/ublox_bmd_345/src/hal_bsp.c @@ -52,7 +52,7 @@ hal_bsp_flash_dev(uint8_t id) } #if MYNEWT_VAL(QSPI_ENABLE) if (id == 1) { - return &nrf52k_qspi_dev; + return &nrf_qspi_dev; } #endif return NULL; diff --git a/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hal.h b/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hal.h index f66501f632..0fd0a6b647 100644 --- a/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hal.h +++ b/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hal.h @@ -40,8 +40,6 @@ struct nrf52_hal_i2c_cfg { uint32_t i2c_frequency; }; -extern const struct hal_flash nrf52k_qspi_dev; - /* SPI configuration (used for both master and slave) */ struct nrf52_hal_spi_cfg { uint8_t sck_pin; diff --git a/hw/mcu/nordic/nrf52xxx/include/nrfx_config_nrf52840.h b/hw/mcu/nordic/nrf52xxx/include/nrfx_config_nrf52840.h index 9d8f6fb816..7de6f64ea4 100644 --- a/hw/mcu/nordic/nrf52xxx/include/nrfx_config_nrf52840.h +++ b/hw/mcu/nordic/nrf52xxx/include/nrfx_config_nrf52840.h @@ -782,8 +782,12 @@ * Boolean. Accepted values: 0 and 1. */ #ifndef NRFX_QSPI_ENABLED +#if MYNEWT_VAL(QSPI_ENABLE) +#define NRFX_QSPI_ENABLED 1 +#else #define NRFX_QSPI_ENABLED 0 #endif +#endif /** * @brief NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_qspi.c b/hw/mcu/nordic/nrf52xxx/src/hal_qspi.c deleted file mode 100644 index f61d65b002..0000000000 --- a/hw/mcu/nordic/nrf52xxx/src/hal_qspi.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include "os/mynewt.h" -#if MYNEWT_VAL(QSPI_ENABLE) -#include -#include -#include "mcu/nrf52_hal.h" -#include "nrf.h" -#include - -#if MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) < 1 -#error QSPI_FLASH_SECTOR_SIZE must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE) < 1 -#error QSPI_FLASH_PAGE_SIZE must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) < 1 -#error QSPI_FLASH_SECTOR_COUNT must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_CS) < 0 -#error QSPI_PIN_CS must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_SCK) < 0 -#error QSPI_PIN_SCK must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO0) < 0 -#error QSPI_PIN_DIO0 must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO1) < 0 -#error QSPI_PIN_DIO1 must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO2) < 0 && (MYNEWT_VAL(QSPI_READOC) > 2 || MYNEWT_VAL(QSPI_WRITEOC) > 1) -#error QSPI_PIN_DIO2 must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO3) < 0 && (MYNEWT_VAL(QSPI_READOC) > 2 || MYNEWT_VAL(QSPI_WRITEOC) > 1) -#error QSPI_PIN_DIO3 must be set to the correct value in bsp syscfg.yml -#endif - -static int -nrf52k_qspi_read(const struct hal_flash *dev, uint32_t address, - void *dst, uint32_t num_bytes); -static int -nrf52k_qspi_write(const struct hal_flash *dev, uint32_t address, - const void *src, uint32_t num_bytes); -static int -nrf52k_qspi_erase_sector(const struct hal_flash *dev, - uint32_t sector_address); -static int -nrf52k_qspi_sector_info(const struct hal_flash *dev, int idx, - uint32_t *address, uint32_t *sz); -static int -nrf52k_qspi_init(const struct hal_flash *dev); -static int -nrf52k_qspi_erase(const struct hal_flash *dev, uint32_t address, - uint32_t size); - -static const struct hal_flash_funcs nrf52k_qspi_funcs = { - .hff_read = nrf52k_qspi_read, - .hff_write = nrf52k_qspi_write, - .hff_erase_sector = nrf52k_qspi_erase_sector, - .hff_sector_info = nrf52k_qspi_sector_info, - .hff_init = nrf52k_qspi_init, - .hff_erase = nrf52k_qspi_erase -}; - -const struct hal_flash nrf52k_qspi_dev = { - .hf_itf = &nrf52k_qspi_funcs, - .hf_base_addr = 0x00000000, - .hf_size = MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) * MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE), - .hf_sector_cnt = MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT), - .hf_align = 1, - .hf_erased_val = 0xff, -}; - -static int -nrf52k_qspi_read(const struct hal_flash *dev, uint32_t address, - void *dst, uint32_t num_bytes) -{ - uint32_t ram_buffer[4]; - uint8_t *ram_ptr = NULL; - uint32_t read_bytes; - - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0) - ; - - while (num_bytes != 0) { - /* - * If address or destination pointer are unaligned or - * number of bytes to read is less then 4 read using ram buffer. - */ - if (((address & 3) != 0) || - ((((uint32_t) dst) & 3) != 0) || - num_bytes < 4) { - uint32_t to_read = (num_bytes + (address & 3) + 3) & ~3; - if (to_read > sizeof(ram_buffer)) { - to_read = sizeof(ram_buffer); - } - ram_ptr = (uint8_t *)((uint32_t) ram_buffer + (address & 3)); - read_bytes = to_read - (address & 3); - if (read_bytes > num_bytes) { - read_bytes = num_bytes; - } - NRF_QSPI->READ.DST = (uint32_t) ram_buffer; - NRF_QSPI->READ.SRC = address & ~3; - NRF_QSPI->READ.CNT = to_read; - } else { - read_bytes = num_bytes & ~3; - NRF_QSPI->READ.DST = (uint32_t) dst; - NRF_QSPI->READ.SRC = address; - NRF_QSPI->READ.CNT = read_bytes; - } - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->TASKS_READSTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - if (ram_ptr != NULL) { - memcpy(dst, ram_ptr, read_bytes); - ram_ptr = NULL; - } - address += read_bytes; - dst = (void *) ((uint32_t) dst + read_bytes); - num_bytes -= read_bytes; - } - return 0; -} - -static int -nrf52k_qspi_write(const struct hal_flash *dev, uint32_t address, - const void *src, uint32_t num_bytes) -{ - uint32_t ram_buffer[4]; - uint8_t *ram_ptr = NULL; - uint32_t written_bytes; - const char src_not_in_ram = (((uint32_t) src) & 0xE0000000) != 0x20000000; - uint32_t page_limit; - - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0) - ; - - while (num_bytes != 0) { - page_limit = (address & ~(MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE) - 1)) + - MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE); - /* - * Use RAM buffer if src or address is not 4 bytes aligned, - * or number of bytes to write is less then 4 - * or src pointer is not from RAM. - */ - if (((address & 3) != 0) || - ((((uint32_t) src) & 3) != 0) || - num_bytes < 4 || - src_not_in_ram) { - uint32_t to_write; - if (address + num_bytes > page_limit) { - to_write = ((page_limit - address) + 3) & ~3; - } else { - to_write = (num_bytes + (address & 3) + 3) & ~3; - } - if (to_write > sizeof(ram_buffer)) { - to_write = sizeof(ram_buffer); - } - memset(ram_buffer, 0xFF, sizeof(ram_buffer)); - ram_ptr = (uint8_t *)((uint32_t) ram_buffer + (address & 3)); - - written_bytes = to_write - (address & 3); - if (written_bytes > num_bytes) { - written_bytes = num_bytes; - } - memcpy(ram_ptr, src, written_bytes); - - NRF_QSPI->WRITE.SRC = (uint32_t) ram_buffer; - NRF_QSPI->WRITE.DST = address & ~3; - NRF_QSPI->WRITE.CNT = to_write; - } else { - NRF_QSPI->WRITE.SRC = (uint32_t) src; - NRF_QSPI->WRITE.DST = address; - /* - * Limit write to single page. - */ - if (address + num_bytes > page_limit) { - written_bytes = page_limit - address; - } else { - written_bytes = num_bytes & ~3; - } - NRF_QSPI->WRITE.CNT = written_bytes; - } - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->TASKS_WRITESTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - - address += written_bytes; - src = (void *) ((uint32_t) src + written_bytes); - num_bytes -= written_bytes; - } - return 0; -} - -static void -erase_block(uint32_t starting_address, - nrf_qspi_erase_len_t block_size_type) -{ - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0) - ; - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->ERASE.PTR = starting_address; - NRF_QSPI->ERASE.LEN = block_size_type; - NRF_QSPI->TASKS_ERASESTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - -} - -static int -nrf52k_qspi_erase_sector(const struct hal_flash *dev, - uint32_t sector_address) -{ - int8_t erases; - - erases = MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) / 4096; - while (erases-- > 0) { - erase_block(sector_address, NRF_QSPI_ERASE_LEN_4KB); - sector_address += 4096; - } - - return 0; -} - -static int -nrf52k_qspi_erase(const struct hal_flash *dev, uint32_t address, - uint32_t size) -{ - - uint32_t end; - - address &= ~0xFFFU; - end = address + size; - - if (end == MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) * - MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE)) { - erase_block(0, NRF_QSPI_ERASE_LEN_ALL); - return 0; - } - - while (size) { - if ((address & 0xFFFFU) == 0 && (size >= 0x10000)) { - /* 64 KB erase if possible */ - erase_block(address, NRF_QSPI_ERASE_LEN_64KB); - address += 0x10000; - size -= 0x10000; - continue; - } - - erase_block(address, NRF_QSPI_ERASE_LEN_4KB); - address += 0x1000; - if (size > 0x1000) { - size -= 0x1000; - } else { - size = 0; - } - } - - return 0; -} - -static int -nrf52k_qspi_sector_info(const struct hal_flash *dev, int idx, - uint32_t *address, uint32_t *sz) -{ - *address = idx * MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE); - *sz = MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE); - - return 0; -} - -static int -nrf52k_qspi_init(const struct hal_flash *dev) -{ - const nrf_qspi_prot_conf_t config0 = { - .readoc = MYNEWT_VAL(QSPI_READOC), - .writeoc = MYNEWT_VAL(QSPI_WRITEOC), - .addrmode = MYNEWT_VAL(QSPI_ADDRMODE), - .dpmconfig = MYNEWT_VAL(QSPI_DPMCONFIG) - }; - const nrf_qspi_phy_conf_t config1 = { - .sck_delay = MYNEWT_VAL(QSPI_SCK_DELAY), - .dpmen = 0, - .spi_mode = MYNEWT_VAL(QSPI_SPI_MODE), - .sck_freq = MYNEWT_VAL(QSPI_SCK_FREQ), - }; - /* - * Configure pins - */ - NRF_QSPI->PSEL.CSN = MYNEWT_VAL(QSPI_PIN_CS); - NRF_QSPI->PSEL.SCK = MYNEWT_VAL(QSPI_PIN_SCK); - NRF_QSPI->PSEL.IO0 = MYNEWT_VAL(QSPI_PIN_DIO0); - NRF_QSPI->PSEL.IO1 = MYNEWT_VAL(QSPI_PIN_DIO1); - /* - * Setup only known fields of IFCONFIG0. Other bits may be set by erratas code. - */ - nrf_qspi_ifconfig0_set(NRF_QSPI, &config0); - nrf_qspi_ifconfig1_set(NRF_QSPI, &config1); - - NRF_QSPI->XIPOFFSET = 0x12000000; - - NRF_QSPI->ENABLE = 1; - NRF_QSPI->TASKS_ACTIVATE = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - -#if (MYNEWT_VAL(QSPI_READOC) > 2) || (MYNEWT_VAL(QSPI_WRITEOC) > 1) - NRF_QSPI->PSEL.IO2 = MYNEWT_VAL(QSPI_PIN_DIO2); - NRF_QSPI->PSEL.IO3 = MYNEWT_VAL(QSPI_PIN_DIO3); -#endif - - return 0; -} - -#endif diff --git a/hw/mcu/nordic/nrf5340/include/nrfx_config_nrf5340_application.h b/hw/mcu/nordic/nrf5340/include/nrfx_config_nrf5340_application.h index 5eda3f0c90..c393f4ecd2 100644 --- a/hw/mcu/nordic/nrf5340/include/nrfx_config_nrf5340_application.h +++ b/hw/mcu/nordic/nrf5340/include/nrfx_config_nrf5340_application.h @@ -989,8 +989,12 @@ * Boolean. Accepted values: 0 and 1. */ #ifndef NRFX_QSPI_ENABLED +#if MYNEWT_VAL(QSPI_ENABLE) +#define NRFX_QSPI_ENABLED 1 +#else #define NRFX_QSPI_ENABLED 0 #endif +#endif /** * @brief NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY diff --git a/hw/mcu/nordic/nrf5340/src/hal_qspi.c b/hw/mcu/nordic/nrf5340/src/hal_qspi.c deleted file mode 100644 index f5771e2ada..0000000000 --- a/hw/mcu/nordic/nrf5340/src/hal_qspi.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#if MYNEWT_VAL(QSPI_ENABLE) -#include -#include "mcu/nrf5340_hal.h" -#include "nrf.h" -#include - -#if MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) < 1 -#error QSPI_FLASH_SECTOR_SIZE must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE) < 1 -#error QSPI_FLASH_PAGE_SIZE must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) < 1 -#error QSPI_FLASH_SECTOR_COUNT must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_CS) < 0 -#error QSPI_PIN_CS must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_SCK) < 0 -#error QSPI_PIN_SCK must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO0) < 0 -#error QSPI_PIN_DIO0 must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO1) < 0 -#error QSPI_PIN_DIO1 must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO2) < 0 && (MYNEWT_VAL(QSPI_READOC) > 2 || MYNEWT_VAL(QSPI_WRITEOC) > 1) -#error QSPI_PIN_DIO2 must be set to the correct value in bsp syscfg.yml -#endif - -#if MYNEWT_VAL(QSPI_PIN_DIO3) < 0 && (MYNEWT_VAL(QSPI_READOC) > 2 || MYNEWT_VAL(QSPI_WRITEOC) > 1) -#error QSPI_PIN_DIO3 must be set to the correct value in bsp syscfg.yml -#endif - -#ifndef USE_MEMCPY_FOR_FLASH_READ -/* - * QSPI peripheral can be access for read just like internal flash in XIP. - * It is possible to read this flash with just memcpy, however mynewt implementation - * of memcpy() copies data from last byte to the first. For normal flash and RAM - * it may not be a problem but QSPI controller will not be able to do it optimally. - * Enable this only for testing or if flash size is image is critical. - */ -#define USE_MEMCPY_FOR_FLASH_READ 0 -#endif - -static int -nrf5340_qspi_read(const struct hal_flash *dev, uint32_t address, - void *dst, uint32_t num_bytes); -static int -nrf5340_qspi_write(const struct hal_flash *dev, uint32_t address, - const void *src, uint32_t num_bytes); -static int -nrf5340_qspi_erase_sector(const struct hal_flash *dev, - uint32_t sector_address); -static int -nrf5340_qspi_sector_info(const struct hal_flash *dev, int idx, - uint32_t *address, uint32_t *sz); -static int -nrf5340_qspi_init(const struct hal_flash *dev); -static int -nrf5340_qspi_erase(const struct hal_flash *dev, uint32_t address, - uint32_t size); - -static const struct hal_flash_funcs nrf5340_qspi_funcs = { - .hff_read = nrf5340_qspi_read, - .hff_write = nrf5340_qspi_write, - .hff_erase_sector = nrf5340_qspi_erase_sector, - .hff_sector_info = nrf5340_qspi_sector_info, - .hff_init = nrf5340_qspi_init, - .hff_erase = nrf5340_qspi_erase -}; - -const struct hal_flash nrf5340_qspi_dev = { - .hf_itf = &nrf5340_qspi_funcs, - .hf_base_addr = MYNEWT_VAL(QSPI_XIP_OFFSET), - .hf_size = MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) * MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE), - .hf_sector_cnt = MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT), - .hf_align = 1, - .hf_erased_val = 0xff, -}; - -static int -nrf5340_qspi_read(const struct hal_flash *dev, uint32_t address, - void *dst, uint32_t num_bytes) -{ -#if USE_MEMCPY_FOR_FLASH_READ - (void)dev; - memcpy(dst, (const void *)address, num_bytes); -#else - uint32_t ram_buffer[4]; - uint8_t *ram_ptr = NULL; - uint32_t read_bytes; - address -= dev->hf_base_addr; - - while (num_bytes != 0) { - /* - * If address or destination pointer are unaligned or - * number of bytes to read is less then 4 read using ram buffer. - */ - if (((address & 3) != 0) || - ((((uint32_t)dst) & 3) != 0) || - num_bytes < 4) { - uint32_t to_read = (num_bytes + (address & 3) + 3) & ~3; - if (to_read > sizeof(ram_buffer)) { - to_read = sizeof(ram_buffer); - } - ram_ptr = (uint8_t *)((uint32_t)ram_buffer + (address & 3)); - read_bytes = to_read - (address & 3); - if (read_bytes > num_bytes) { - read_bytes = num_bytes; - } - NRF_QSPI->READ.DST = (uint32_t)ram_buffer; - NRF_QSPI->READ.SRC = address & ~3; - NRF_QSPI->READ.CNT = to_read; - } else { - read_bytes = num_bytes & ~3; - NRF_QSPI->READ.DST = (uint32_t)dst; - NRF_QSPI->READ.SRC = address; - NRF_QSPI->READ.CNT = read_bytes; - } - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->TASKS_READSTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - if (ram_ptr != NULL) { - memcpy(dst, ram_ptr, read_bytes); - ram_ptr = NULL; - } - address += read_bytes; - dst = (void *)((uint32_t)dst + read_bytes); - num_bytes -= read_bytes; - } -#endif - - return 0; -} - -static int -nrf5340_qspi_write(const struct hal_flash *dev, uint32_t address, - const void *src, uint32_t num_bytes) -{ - uint32_t ram_buffer[4]; - uint8_t *ram_ptr = NULL; - uint32_t written_bytes; - const char src_not_in_ram = (((uint32_t)src) & 0xE0000000) != 0x20000000; - uint32_t page_limit; - uint32_t to_write; - - (void)dev; - - address -= MYNEWT_VAL(QSPI_XIP_OFFSET); - - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0) - ; - - while (num_bytes != 0) { - page_limit = (address & ~(MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE) - 1)) + - MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE); - /* - * Use RAM buffer if src or address is not 4 bytes aligned, - * or number of bytes to write is less then 4 - * or src pointer is not from RAM. - */ - if (((address & 3) != 0) || - ((((uint32_t)src) & 3) != 0) || - num_bytes < 4 || - src_not_in_ram) { - if (address + num_bytes > page_limit) { - to_write = ((page_limit - address) + 3) & ~3; - } else { - to_write = (num_bytes + (address & 3) + 3) & ~3; - } - if (to_write > sizeof(ram_buffer)) { - to_write = sizeof(ram_buffer); - } - memset(ram_buffer, 0xFF, sizeof(ram_buffer)); - ram_ptr = (uint8_t *)((uint32_t)ram_buffer + (address & 3)); - - written_bytes = to_write - (address & 3); - if (written_bytes > num_bytes) { - written_bytes = num_bytes; - } - memcpy(ram_ptr, src, written_bytes); - - NRF_QSPI->WRITE.SRC = (uint32_t)ram_buffer; - NRF_QSPI->WRITE.DST = address & ~3; - NRF_QSPI->WRITE.CNT = to_write; - } else { - NRF_QSPI->WRITE.SRC = (uint32_t)src; - NRF_QSPI->WRITE.DST = address; - /* - * Limit write to single page. - */ - if (address + num_bytes > page_limit) { - written_bytes = page_limit - address; - } else { - written_bytes = num_bytes & ~3; - } - NRF_QSPI->WRITE.CNT = written_bytes; - } - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->TASKS_WRITESTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - - address += written_bytes; - src = (void *)((uint32_t)src + written_bytes); - num_bytes -= written_bytes; - } - return 0; -} - -static void -erase_block(uint32_t starting_address, - nrf_qspi_erase_len_t block_size_type) -{ - starting_address -= MYNEWT_VAL(QSPI_XIP_OFFSET); - - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0) - ; - - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->ERASE.PTR = starting_address; - NRF_QSPI->ERASE.LEN = block_size_type; - NRF_QSPI->TASKS_ERASESTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; -} - -static int -nrf5340_qspi_erase_sector(const struct hal_flash *dev, - uint32_t sector_address) -{ - int8_t erases; - - (void)dev; - - erases = MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) / 4096; - while (erases-- > 0) { - erase_block(sector_address, NRF_QSPI_ERASE_LEN_4KB); - sector_address += 4096; - } - - return 0; -} - -static int -nrf5340_qspi_erase(const struct hal_flash *dev, uint32_t address, - uint32_t size) -{ - uint32_t end; - - (void)dev; - - address &= ~0xFFFU; - end = address + size; - - if (end == MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) * - MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE)) { - erase_block(0, NRF_QSPI_ERASE_LEN_ALL); - return 0; - } - - while (size) { - if ((address & 0xFFFFU) == 0 && (size >= 0x10000)) { - /* 64 KB erase if possible */ - erase_block(address, NRF_QSPI_ERASE_LEN_64KB); - address += 0x10000; - size -= 0x10000; - continue; - } - - erase_block(address, NRF_QSPI_ERASE_LEN_4KB); - address += 0x1000; - if (size > 0x1000) { - size -= 0x1000; - } else { - size = 0; - } - } - - return 0; -} - -static int -nrf5340_qspi_sector_info(const struct hal_flash *dev, int idx, - uint32_t *address, uint32_t *sz) -{ - (void)dev; - - *address = idx * MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE); - *sz = MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE); - - return 0; -} - -static void -nrf5340_set_pin_strength(int pin) -{ - NRF_GPIO_Type *port; - port = HAL_GPIO_PORT(pin); - - port->PIN_CNF[pin & 31] = (port->PIN_CNF[pin & 31] & ~GPIO_PIN_CNF_DRIVE_Msk) | - (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos); -} - -static int -nrf5340_qspi_init(const struct hal_flash *dev) -{ - const nrf_qspi_prot_conf_t config0 = { - .readoc = MYNEWT_VAL(QSPI_READOC), - .writeoc = MYNEWT_VAL(QSPI_WRITEOC), - .addrmode = MYNEWT_VAL(QSPI_ADDRMODE), - .dpmconfig = MYNEWT_VAL(QSPI_DPMCONFIG) - }; - const nrf_qspi_phy_conf_t config1 = { - .sck_delay = MYNEWT_VAL(QSPI_SCK_DELAY), - .dpmen = 0, - .spi_mode = MYNEWT_VAL(QSPI_SPI_MODE), - .sck_freq = MYNEWT_VAL(QSPI_SCK_FREQ), - }; - - (void)dev; - - /* - * Configure pins. - */ - NRF_QSPI->PSEL.CSN = MYNEWT_VAL(QSPI_PIN_CS); - NRF_QSPI->PSEL.SCK = MYNEWT_VAL(QSPI_PIN_SCK); - NRF_QSPI->PSEL.IO0 = MYNEWT_VAL(QSPI_PIN_DIO0); - NRF_QSPI->PSEL.IO1 = MYNEWT_VAL(QSPI_PIN_DIO1); - - /* - * QSPI pins need high drive. See 9.1 section of product specification. - */ - nrf5340_set_pin_strength(MYNEWT_VAL(QSPI_PIN_SCK)); - nrf5340_set_pin_strength(MYNEWT_VAL(QSPI_PIN_DIO0)); - nrf5340_set_pin_strength(MYNEWT_VAL(QSPI_PIN_DIO1)); - - /* - * Setup only known fields of IFCONFIG0. Other bits may be set by erratas code. - */ - nrf_qspi_ifconfig0_set(NRF_QSPI, &config0); - nrf_qspi_ifconfig1_set(NRF_QSPI, &config1); - - NRF_QSPI->XIPOFFSET = MYNEWT_VAL(QSPI_XIP_OFFSET); - -#if !defined(NRF_TRUSTZONE_NONSECURE) - /* Workaround for Errata 121: QSPI: Configuration of peripheral requires additional steps */ - if (nrf53_errata_121()) { - NRF_QSPI->IFTIMING = (NRF_QSPI->IFTIMING & ~(7 << 8)) | (6 << 8); - if (192000000u / MYNEWT_VAL(MCU_HFCLCK192_DIV) / (2u * (MYNEWT_VAL(QSPI_SCK_FREQ) + 1)) == 96000000u) { - NRF_QSPI->IFCONFIG0 |= (3 << 16); - } else if (192000000u / MYNEWT_VAL(MCU_HFCLCK192_DIV) / (2u * (MYNEWT_VAL(QSPI_SCK_FREQ) + 1)) >= 6000000u) { - NRF_QSPI->IFCONFIG0 &= ~(1 << 17); - NRF_QSPI->IFCONFIG0 |= (1 << 16); - } - } -#endif - -#if (MYNEWT_VAL(QSPI_READOC) > 2) || (MYNEWT_VAL(QSPI_WRITEOC) > 1) - NRF_QSPI->PSEL.IO2 = MYNEWT_VAL(QSPI_PIN_DIO2); - NRF_QSPI->PSEL.IO3 = MYNEWT_VAL(QSPI_PIN_DIO3); - nrf5340_set_pin_strength(MYNEWT_VAL(QSPI_PIN_DIO2)); - nrf5340_set_pin_strength(MYNEWT_VAL(QSPI_PIN_DIO3)); -#endif - - NRF_QSPI->ENABLE = 1; - NRF_QSPI->TASKS_ACTIVATE = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; - - return 0; -} - -#endif diff --git a/hw/mcu/nordic/nrf91xx/include/mcu/nrf91_hal.h b/hw/mcu/nordic/nrf91xx/include/mcu/nrf91_hal.h index b3f985a7d3..67cbbaff4f 100644 --- a/hw/mcu/nordic/nrf91xx/include/mcu/nrf91_hal.h +++ b/hw/mcu/nordic/nrf91xx/include/mcu/nrf91_hal.h @@ -40,8 +40,6 @@ struct nrf91_hal_i2c_cfg { uint32_t i2c_frequency; }; -extern const struct hal_flash nrf91k_qspi_dev; - /* SPI configuration (used for both master and slave) */ struct nrf91_hal_spi_cfg { uint8_t sck_pin; diff --git a/hw/mcu/nordic/nrf_common/include/nrf_hal.h b/hw/mcu/nordic/nrf_common/include/nrf_hal.h index 57656c7795..66eafc2ad5 100644 --- a/hw/mcu/nordic/nrf_common/include/nrf_hal.h +++ b/hw/mcu/nordic/nrf_common/include/nrf_hal.h @@ -40,6 +40,7 @@ struct hal_flash; extern const struct hal_flash nrf_flash_dev; +extern const struct hal_flash nrf_qspi_dev; #ifdef __cplusplus } diff --git a/hw/mcu/nordic/nrf91xx/src/hal_qspi.c b/hw/mcu/nordic/nrf_common/src/hal_qspi.c similarity index 57% rename from hw/mcu/nordic/nrf91xx/src/hal_qspi.c rename to hw/mcu/nordic/nrf_common/src/hal_qspi.c index eaaf61afa6..abc2d89032 100644 --- a/hw/mcu/nordic/nrf91xx/src/hal_qspi.c +++ b/hw/mcu/nordic/nrf_common/src/hal_qspi.c @@ -24,9 +24,8 @@ #if MYNEWT_VAL(QSPI_ENABLE) #include #include -#include "mcu/nrf91_hal.h" #include "nrf.h" -#include +#include #if MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) < 1 #error QSPI_FLASH_SECTOR_SIZE must be set to the correct value in bsp syscfg.yml @@ -65,30 +64,34 @@ #endif static int -nrf91k_qspi_read(const struct hal_flash *dev, uint32_t address, +nrf_qspi_read(const struct hal_flash *dev, uint32_t address, void *dst, uint32_t num_bytes); static int -nrf91k_qspi_write(const struct hal_flash *dev, uint32_t address, +nrf_qspi_write(const struct hal_flash *dev, uint32_t address, const void *src, uint32_t num_bytes); static int -nrf91k_qspi_erase_sector(const struct hal_flash *dev, +nrf_qspi_erase_sector(const struct hal_flash *dev, uint32_t sector_address); static int -nrf91k_qspi_sector_info(const struct hal_flash *dev, int idx, +nrf_qspi_sector_info(const struct hal_flash *dev, int idx, uint32_t *address, uint32_t *sz); static int -nrf91k_qspi_init(const struct hal_flash *dev); - -static const struct hal_flash_funcs nrf91k_qspi_funcs = { - .hff_read = nrf91k_qspi_read, - .hff_write = nrf91k_qspi_write, - .hff_erase_sector = nrf91k_qspi_erase_sector, - .hff_sector_info = nrf91k_qspi_sector_info, - .hff_init = nrf91k_qspi_init +nrf_qspi_init(const struct hal_flash *dev); +static int +nrf_qspi_erase(const struct hal_flash *dev, uint32_t address, + uint32_t size); + +static const struct hal_flash_funcs nrf_qspi_funcs = { + .hff_read = nrf_qspi_read, + .hff_write = nrf_qspi_write, + .hff_erase_sector = nrf_qspi_erase_sector, + .hff_sector_info = nrf_qspi_sector_info, + .hff_init = nrf_qspi_init, + .hff_erase = nrf_qspi_erase }; -const struct hal_flash nrf91k_qspi_dev = { - .hf_itf = &nrf91k_qspi_funcs, +const struct hal_flash nrf_qspi_dev = { + .hf_itf = &nrf_qspi_funcs, .hf_base_addr = 0x00000000, .hf_size = MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) * MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE), .hf_sector_cnt = MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT), @@ -97,16 +100,13 @@ const struct hal_flash nrf91k_qspi_dev = { }; static int -nrf91k_qspi_read(const struct hal_flash *dev, uint32_t address, +nrf_qspi_read(const struct hal_flash *dev, uint32_t address, void *dst, uint32_t num_bytes) { uint32_t ram_buffer[4]; uint8_t *ram_ptr = NULL; uint32_t read_bytes; - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0) - ; - while (num_bytes != 0) { /* * If address or destination pointer are unaligned or @@ -124,19 +124,11 @@ nrf91k_qspi_read(const struct hal_flash *dev, uint32_t address, if (read_bytes > num_bytes) { read_bytes = num_bytes; } - NRF_QSPI->READ.DST = (uint32_t) ram_buffer; - NRF_QSPI->READ.SRC = address & ~3; - NRF_QSPI->READ.CNT = to_read; + nrfx_qspi_read(ram_buffer, to_read, address & ~3); } else { read_bytes = num_bytes & ~3; - NRF_QSPI->READ.DST = (uint32_t) dst; - NRF_QSPI->READ.SRC = address; - NRF_QSPI->READ.CNT = read_bytes; + nrfx_qspi_read(dst, read_bytes, address); } - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->TASKS_READSTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; if (ram_ptr != NULL) { memcpy(dst, ram_ptr, read_bytes); ram_ptr = NULL; @@ -149,20 +141,14 @@ nrf91k_qspi_read(const struct hal_flash *dev, uint32_t address, } static int -nrf91k_qspi_write(const struct hal_flash *dev, uint32_t address, +nrf_qspi_write(const struct hal_flash *dev, uint32_t address, const void *src, uint32_t num_bytes) { uint32_t ram_buffer[4]; uint8_t *ram_ptr = NULL; uint32_t written_bytes; - const char src_not_in_ram = (((uint32_t) src) & 0xE0000000) != 0x20000000; - uint32_t page_limit; - - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0); while (num_bytes != 0) { - page_limit = (address & ~(MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE) - 1)) + - MYNEWT_VAL(QSPI_FLASH_PAGE_SIZE); /* * Use RAM buffer if src or address is not 4 bytes aligned, * or number of bytes to write is less then 4 @@ -171,13 +157,10 @@ nrf91k_qspi_write(const struct hal_flash *dev, uint32_t address, if (((address & 3) != 0) || ((((uint32_t) src) & 3) != 0) || num_bytes < 4 || - src_not_in_ram) { + !nrfx_is_in_ram(src)) { uint32_t to_write; - if (address + num_bytes > page_limit) { - to_write = ((page_limit - address) + 3) & ~3; - } else { - to_write = (num_bytes + (address & 3) + 3) & ~3; - } + + to_write = (num_bytes + (address & 3) + 3) & ~3; if (to_write > sizeof(ram_buffer)) { to_write = sizeof(ram_buffer); } @@ -189,27 +172,11 @@ nrf91k_qspi_write(const struct hal_flash *dev, uint32_t address, written_bytes = num_bytes; } memcpy(ram_ptr, src, written_bytes); - - NRF_QSPI->WRITE.SRC = (uint32_t) ram_buffer; - NRF_QSPI->WRITE.DST = address & ~3; - NRF_QSPI->WRITE.CNT = to_write; + nrfx_qspi_write(ram_buffer, to_write, address & ~3); } else { - NRF_QSPI->WRITE.SRC = (uint32_t) src; - NRF_QSPI->WRITE.DST = address; - /* - * Limit write to single page. - */ - if (address + num_bytes > page_limit) { - written_bytes = page_limit - address; - } else { - written_bytes = num_bytes & ~3; - } - NRF_QSPI->WRITE.CNT = written_bytes; + written_bytes = num_bytes & ~3; + nrfx_qspi_write(src, written_bytes, address); } - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->TASKS_WRITESTART = 1; - while (NRF_QSPI->EVENTS_READY == 0) - ; address += written_bytes; src = (void *) ((uint32_t) src + written_bytes); @@ -219,26 +186,58 @@ nrf91k_qspi_write(const struct hal_flash *dev, uint32_t address, } static int -nrf91k_qspi_erase_sector(const struct hal_flash *dev, +nrf_qspi_erase_sector(const struct hal_flash *dev, uint32_t sector_address) { int8_t erases; erases = MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) / 4096; while (erases-- > 0) { - while ((NRF_QSPI->STATUS & QSPI_STATUS_READY_Msk) == 0); - NRF_QSPI->EVENTS_READY = 0; - NRF_QSPI->ERASE.PTR = sector_address; - NRF_QSPI->ERASE.LEN = NRF_QSPI_ERASE_LEN_4KB; - NRF_QSPI->TASKS_ERASESTART = 1; - while (NRF_QSPI->EVENTS_READY == 0); + nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, sector_address); sector_address += 4096; } + return 0; } static int -nrf91k_qspi_sector_info(const struct hal_flash *dev, int idx, +nrf_qspi_erase(const struct hal_flash *dev, uint32_t address, + uint32_t size) +{ + uint32_t end; + + address &= ~0xFFFU; + end = address + size; + + if (end == MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT) * + MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE)) { + nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0); + return 0; + } + + while (size) { + if ((address & 0xFFFFU) == 0 && (size >= 0x10000)) { + /* 64 KB erase if possible */ + nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_64KB, address); + address += 0x10000; + size -= 0x10000; + continue; + } + + nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address); + address += 0x1000; + if (size > 0x1000) { + size -= 0x1000; + } else { + size = 0; + } + } + + return 0; +} + +static int +nrf_qspi_sector_info(const struct hal_flash *dev, int idx, uint32_t *address, uint32_t *sz) { *address = idx * MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE); @@ -248,43 +247,51 @@ nrf91k_qspi_sector_info(const struct hal_flash *dev, int idx, } static int -nrf91k_qspi_init(const struct hal_flash *dev) +nrf_qspi_init(const struct hal_flash *dev) { - const nrf_qspi_prot_conf_t config0 = { - .readoc = MYNEWT_VAL(QSPI_READOC), - .writeoc = MYNEWT_VAL(QSPI_WRITEOC), - .addrmode = MYNEWT_VAL(QSPI_ADDRMODE), - .dpmconfig = MYNEWT_VAL(QSPI_DPMCONFIG) - }; - const nrf_qspi_phy_conf_t config1 = { - .sck_delay = MYNEWT_VAL(QSPI_SCK_DELAY), - .dpmen = 0, - .spi_mode = MYNEWT_VAL(QSPI_SPI_MODE), - .sck_freq = MYNEWT_VAL(QSPI_SCK_FREQ), - }; - /* - * Configure pins - */ - NRF_QSPI->PSEL.CSN = MYNEWT_VAL(QSPI_PIN_CS); - NRF_QSPI->PSEL.SCK = MYNEWT_VAL(QSPI_PIN_SCK); - NRF_QSPI->PSEL.IO0 = MYNEWT_VAL(QSPI_PIN_DIO0); - NRF_QSPI->PSEL.IO1 = MYNEWT_VAL(QSPI_PIN_DIO1); - /* - * Setup only known fields of IFCONFIG0. Other bits may be set by erratas code. - */ - nrf_qspi_ifconfig0_set(NRF_QSPI, &config0); - nrf_qspi_ifconfig1_set(NRF_QSPI, &config1); - - NRF_QSPI->XIPOFFSET = 0x12000000; - - NRF_QSPI->ENABLE = 1; - NRF_QSPI->TASKS_ACTIVATE = 1; - while (NRF_QSPI->EVENTS_READY == 0); - + int rc; + + nrfx_qspi_config_t config = { + .pins = { + .csn_pin = MYNEWT_VAL(QSPI_PIN_CS), + .sck_pin = MYNEWT_VAL(QSPI_PIN_SCK), + .io0_pin = MYNEWT_VAL(QSPI_PIN_DIO0), + .io1_pin = MYNEWT_VAL(QSPI_PIN_DIO1), #if (MYNEWT_VAL(QSPI_READOC) > 2) || (MYNEWT_VAL(QSPI_WRITEOC) > 1) - NRF_QSPI->PSEL.IO2 = MYNEWT_VAL(QSPI_PIN_DIO2); - NRF_QSPI->PSEL.IO3 = MYNEWT_VAL(QSPI_PIN_DIO3); + .io2_pin = MYNEWT_VAL(QSPI_PIN_DIO2), + .io3_pin = MYNEWT_VAL(QSPI_PIN_DIO3), +#else + .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, #endif + }, + .prot_if = { + .readoc = MYNEWT_VAL(QSPI_READOC), + .writeoc = MYNEWT_VAL(QSPI_WRITEOC), + .addrmode = MYNEWT_VAL(QSPI_ADDRMODE), + .dpmconfig = MYNEWT_VAL(QSPI_DPMCONFIG) + }, + .phy_if = { + .sck_delay = MYNEWT_VAL(QSPI_SCK_DELAY), + .dpmen = 0, + .spi_mode = MYNEWT_VAL(QSPI_SPI_MODE), + .sck_freq = MYNEWT_VAL(QSPI_SCK_FREQ), + }, + .xip_offset = MYNEWT_VAL(QSPI_XIP_OFFSET), + .timeout = 0, + .skip_gpio_cfg = true, + .skip_psel_cfg = false, + }; + + rc = nrfx_qspi_init(&config, NULL, NULL); + if (rc != NRFX_SUCCESS) { + return -1; + } + + rc = nrfx_qspi_activate(true); + if (rc != NRFX_SUCCESS) { + return -1; + } return 0; }