This is an automated email from the ASF dual-hosted git repository.

mgorecki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 5f8038e757fc452789497918903872ba9eb1952c
Author: Michal Gorecki <[email protected]>
AuthorDate: Mon Jun 24 17:21:34 2024 +0200

    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 +-
 hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hal.h     |   2 -
 .../nordic/nrf52xxx/include/nrfx_config_nrf52840.h |   4 +
 hw/mcu/nordic/nrf52xxx/src/hal_qspi.c              | 346 ------------------
 hw/mcu/nordic/nrf52xxx/syscfg.yml                  |   3 +
 .../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 +
 .../nordic/{nrf91xx => nrf_common}/src/hal_qspi.c  | 235 ++++++------
 15 files changed, 136 insertions(+), 880 deletions(-)

diff --git a/hw/bsp/nordic_pca10056/src/hal_bsp.c 
b/hw/bsp/nordic_pca10056/src/hal_bsp.c
index dea15a696..2b668260f 100644
--- a/hw/bsp/nordic_pca10056/src/hal_bsp.c
+++ b/hw/bsp/nordic_pca10056/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/bsp/nordic_pca10059/src/hal_bsp.c 
b/hw/bsp/nordic_pca10059/src/hal_bsp.c
index dea15a696..2b668260f 100644
--- a/hw/bsp/nordic_pca10059/src/hal_bsp.c
+++ b/hw/bsp/nordic_pca10059/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/bsp/nordic_pca10095/src/hal_bsp.c 
b/hw/bsp/nordic_pca10095/src/hal_bsp.c
index c46b2ae10..c39b96a1c 100644
--- a/hw/bsp/nordic_pca10095/src/hal_bsp.c
+++ b/hw/bsp/nordic_pca10095/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_pca10121/src/hal_bsp.c 
b/hw/bsp/nordic_pca10121/src/hal_bsp.c
index 57d4512b3..300c901bc 100644
--- a/hw/bsp/nordic_pca10121/src/hal_bsp.c
+++ b/hw/bsp/nordic_pca10121/src/hal_bsp.c
@@ -59,7 +59,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 c46b2ae10..c39b96a1c 100644
--- a/hw/bsp/nordic_thingy53/src/hal_bsp.c
+++ b/hw/bsp/nordic_thingy53/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/ublox_bmd_345/src/hal_bsp.c 
b/hw/bsp/ublox_bmd_345/src/hal_bsp.c
index 84aab2967..09f3b8455 100644
--- a/hw/bsp/ublox_bmd_345/src/hal_bsp.c
+++ b/hw/bsp/ublox_bmd_345/src/hal_bsp.c
@@ -53,7 +53,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 f66501f63..0fd0a6b64 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 9d8f6fb81..7de6f64ea 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 f61d65b00..000000000
--- 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 <string.h>
-#include <assert.h>
-#include <stdint.h>
-#include "os/mynewt.h"
-#if MYNEWT_VAL(QSPI_ENABLE)
-#include <mcu/cmsis_nvic.h>
-#include <hal/hal_flash_int.h>
-#include "mcu/nrf52_hal.h"
-#include "nrf.h"
-#include <hal/nrf_qspi.h>
-
-#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/nrf52xxx/syscfg.yml 
b/hw/mcu/nordic/nrf52xxx/syscfg.yml
index d28e2d8d7..fe2477198 100644
--- a/hw/mcu/nordic/nrf52xxx/syscfg.yml
+++ b/hw/mcu/nordic/nrf52xxx/syscfg.yml
@@ -430,6 +430,9 @@ syscfg.defs:
     QSPI_PIN_DIO3:
         description: 'DIO3 pin for QSPI'
         value: -1
+    QSPI_XIP_OFFSET:
+        description: 'Base address flash memory for MCU memory access'
+        value: 0x10000000
 
     NFC_PINS_AS_GPIO:
         description: 'Use NFC pins as GPIOs instead of NFC functionality'
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 5eda3f0c9..c393f4ecd 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 f5771e2ad..000000000
--- 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 <string.h>
-#include <assert.h>
-#include <stdint.h>
-#include <syscfg/syscfg.h>
-#if MYNEWT_VAL(QSPI_ENABLE)
-#include <hal/hal_flash_int.h>
-#include "mcu/nrf5340_hal.h"
-#include "nrf.h"
-#include <hal/nrf_qspi.h>
-
-#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 b3f985a7d..67cbbaff4 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 57656c779..66eafc2ad 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 52%
rename from hw/mcu/nordic/nrf91xx/src/hal_qspi.c
rename to hw/mcu/nordic/nrf_common/src/hal_qspi.c
index eaaf61afa..6a2b8eb3b 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 <mcu/cmsis_nvic.h>
 #include <hal/hal_flash_int.h>
-#include "mcu/nrf91_hal.h"
 #include "nrf.h"
-#include <hal/nrf_qspi.h>
+#include <nrfx_qspi.h>
 
 #if MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) < 1
 #error QSPI_FLASH_SECTOR_SIZE must be set to the correct value in bsp 
syscfg.yml
@@ -64,31 +63,29 @@
 #error QSPI_PIN_DIO3 must be set to the correct value in bsp syscfg.yml
 #endif
 
-static int
-nrf91k_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,
-                  const void *src, uint32_t num_bytes);
-static int
-nrf91k_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,
-                        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
+static int nrf_qspi_read(const struct hal_flash *dev, uint32_t address,
+                         void *dst, uint32_t num_bytes);
+static int nrf_qspi_write(const struct hal_flash *dev, uint32_t address,
+                          const void *src, uint32_t num_bytes);
+static int nrf_qspi_erase_sector(const struct hal_flash *dev,
+                                 uint32_t sector_address);
+static int nrf_qspi_sector_info(const struct hal_flash *dev, int idx,
+                                uint32_t *address, uint32_t *sz);
+static int 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 +94,13 @@ const struct hal_flash nrf91k_qspi_dev = {
 };
 
 static int
-nrf91k_qspi_read(const struct hal_flash *dev, uint32_t address,
-                 void *dst, uint32_t num_bytes)
+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 +118,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 +135,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,
-                  const void *src, uint32_t num_bytes)
+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 +151,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 +166,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,27 +180,59 @@ nrf91k_qspi_write(const struct hal_flash *dev, uint32_t 
address,
 }
 
 static int
-nrf91k_qspi_erase_sector(const struct hal_flash *dev,
-                         uint32_t sector_address)
+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,
-                        uint32_t *address, uint32_t *sz)
+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);
     *sz = MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE);
@@ -248,43 +241,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;
 }


Reply via email to