diff --git a/Bluetooth.h b/Bluetooth.h
index f28f02c..e7231a1 100644
--- a/Bluetooth.h
+++ b/Bluetooth.h
@@ -13,11 +13,24 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#if MCU_VARIANT == MCU_ESP32
#include "BluetoothSerial.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
+#elif MCU_VARIANT == MCU_NRF52
+#include
+#include
+#endif
+
+#if MCU_VARIANT == MCU_ESP32
BluetoothSerial SerialBT;
+#elif MCU_VARIANT == MCU_NRF52
+BLEUart SerialBT;
+BLEDis bledis;
+BLEBas blebas;
+#endif
+
#define BT_PAIRING_TIMEOUT 35000
uint32_t bt_pairing_started = 0;
@@ -138,4 +151,145 @@ char bt_devname[11];
}
}
+#elif MCU_VARIANT == MCU_NRF52
+uint8_t eeprom_read(uint32_t mapped_addr);
+
+void bt_stop() {
+ if (bt_state != BT_STATE_OFF) {
+ bt_allow_pairing = false;
+ bt_state = BT_STATE_OFF;
+ }
+}
+
+void bt_disable_pairing() {
+ bt_allow_pairing = false;
+ bt_ssp_pin = 0;
+ bt_state = BT_STATE_ON;
+}
+
+void bt_pairing_complete(uint16_t conn_handle, uint8_t auth_status) {
+ if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
+ bt_disable_pairing();
+ } else {
+ bt_ssp_pin = 0;
+ }
+}
+
+bool bt_passkey_callback(uint16_t conn_handle, uint8_t const passkey[6], bool match_request) {
+ for (int i = 0; i < 6; i++) {
+ // multiply by tens however many times needed to make numbers appear in order
+ bt_ssp_pin += ((int)passkey[i] - 48) * pow(10, 5-i);
+ }
+ kiss_indicate_btpin();
+ if (match_request) {
+ if (bt_allow_pairing) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void bt_connect_callback(uint16_t conn_handle) {
+ bt_state = BT_STATE_CONNECTED;
+ cable_state = CABLE_STATE_DISCONNECTED;
+}
+
+void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) {
+ bt_state = BT_STATE_ON;
+}
+
+bool bt_setup_hw() {
+ if (!bt_ready) {
+ #if HAS_EEPROM
+ if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
+ #else
+ if (eeprom_read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) {
+ #endif
+ bt_enabled = true;
+ } else {
+ bt_enabled = false;
+ }
+ Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
+ Bluefruit.autoConnLed(false);
+ if (Bluefruit.begin()) {
+ Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
+ Bluefruit.Security.setIOCaps(true, true, false);
+ Bluefruit.Security.setPairPasskeyCallback(bt_passkey_callback);
+ Bluefruit.Periph.setConnectCallback(bt_connect_callback);
+ Bluefruit.Periph.setDisconnectCallback(bt_disconnect_callback);
+ Bluefruit.Security.setIOCaps(true, true, false);
+ Bluefruit.Security.setPairCompleteCallback(bt_pairing_complete);
+ const ble_gap_addr_t gap_addr = Bluefruit.getAddr();
+ char *data = (char*)malloc(BT_DEV_ADDR_LEN+1);
+ for (int i = 0; i < BT_DEV_ADDR_LEN; i++) {
+ data[i] = gap_addr.addr[i];
+ }
+ #if HAS_EEPROM
+ data[BT_DEV_ADDR_LEN] = EEPROM.read(eeprom_addr(ADDR_SIGNATURE));
+ #else
+ data[BT_DEV_ADDR_LEN] = eeprom_read(eeprom_addr(ADDR_SIGNATURE));
+ #endif
+ unsigned char *hash = MD5::make_hash(data, BT_DEV_ADDR_LEN);
+ memcpy(bt_dh, hash, BT_DEV_HASH_LEN);
+ sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]);
+ free(data);
+
+ bt_ready = true;
+ return true;
+
+ } else { return false; }
+ } else { return false; }
+}
+
+void bt_start() {
+ if (bt_state == BT_STATE_OFF) {
+ Bluefruit.setName(bt_devname);
+ bledis.setManufacturer("Adafruit Industries");
+ bledis.setModel("Bluefruit Feather52");
+ // start device information service
+ bledis.begin();
+
+ SerialBT.begin();
+
+ blebas.begin();
+
+ // non-connectable advertising
+ Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
+ Bluefruit.Advertising.addTxPower();
+
+ // Include bleuart 128-bit uuid
+ Bluefruit.Advertising.addService(SerialBT);
+
+ // There is no room for Name in Advertising packet
+ // Use Scan response for Name
+ Bluefruit.ScanResponse.addName();
+
+ Bluefruit.Advertising.start(0);
+
+ bt_state = BT_STATE_ON;
+ }
+}
+
+bool bt_init() {
+ bt_state = BT_STATE_OFF;
+ if (bt_setup_hw()) {
+ if (bt_enabled && !console_active) bt_start();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void bt_enable_pairing() {
+ if (bt_state == BT_STATE_OFF) bt_start();
+ bt_allow_pairing = true;
+ bt_pairing_started = millis();
+ bt_state = BT_STATE_PAIRING;
+}
+
+void update_bt() {
+ if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) {
+ bt_disable_pairing();
+ }
+}
#endif
diff --git a/Config.h b/Config.h
index ce7aaad..e58094f 100644
--- a/Config.h
+++ b/Config.h
@@ -313,7 +313,7 @@
#if BOARD_MODEL == BOARD_RAK4630
#define HAS_EEPROM false
#define HAS_DISPLAY false // set for debugging
- #define HAS_BLUETOOTH false
+ #define HAS_BLUETOOTH true
#define HAS_CONSOLE false
#define HAS_PMU false
#define HAS_NP false
@@ -324,8 +324,9 @@
#define CONFIG_UART_BUFFER_SIZE 6144
#define CONFIG_QUEUE_SIZE 6144
#define CONFIG_QUEUE_MAX_LENGTH 200
- #define EEPROM_SIZE 4096
- #define EEPROM_OFFSET EEPROM_SIZE+0xED000-EEPROM_RESERVED
+ #define EEPROM_SIZE 200
+ //#define EEPROM_OFFSET EEPROM_SIZE+0xED000-EEPROM_RESERVED
+ #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
// following pins are for the sx1262
const int pin_rxen = 37;
diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino
index d18aa98..bb18d39 100644
--- a/RNode_Firmware.ino
+++ b/RNode_Firmware.ino
@@ -54,6 +54,12 @@ void setup() {
Serial.setRxBufferSize(CONFIG_UART_BUFFER_SIZE);
#endif
+ #if MCU_VARIANT == MCU_NRF52
+ if (!eeprom_begin()) {
+ Serial.write("EEPROM initialisation failed.\r\n");
+ }
+ #endif
+
// Seed the PRNG
randomSeed(analogRead(0));
@@ -140,7 +146,7 @@ void setup() {
update_display();
#endif
- #if MCU_VARIANT == MCU_ESP32
+ #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
#if HAS_PMU == true
pmu_ready = init_pmu();
#endif
diff --git a/Utilities.h b/Utilities.h
index df39762..3ed11da 100644
--- a/Utilities.h
+++ b/Utilities.h
@@ -18,8 +18,13 @@
#if HAS_EEPROM
#include
#elif PLATFORM == PLATFORM_NRF52
- #include "flash_nrf5x.h"
- int written_bytes = 0;
+ #include
+ #include
+ using namespace Adafruit_LittleFS_Namespace;
+ #define EEPROM_FILE "eeprom"
+ bool file_exists = false;
+ int written_bytes = 4;
+ File file(InternalFS);
#endif
#include
@@ -1104,10 +1109,33 @@ void promisc_disable() {
}
#if !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
+ bool eeprom_begin() {
+ InternalFS.begin();
+
+ file.open(EEPROM_FILE, FILE_O_READ);
+
+ // if file doesn't exist
+ if (!file) {
+ if (file.open(EEPROM_FILE, FILE_O_WRITE)) {
+ // initialise the file with empty content
+ uint8_t empty_content[EEPROM_SIZE] = {0};
+ file.write(empty_content, EEPROM_SIZE);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ file.close();
+ file.open(EEPROM_FILE, FILE_O_WRITE);
+ return true;
+ }
+ }
+
uint8_t eeprom_read(uint32_t mapped_addr) {
uint8_t byte;
void* byte_ptr = &byte;
- flash_nrf5x_read(byte_ptr, mapped_addr, 1);
+ file.seek(mapped_addr);
+ file.read(byte_ptr, 1);
return byte;
}
#endif
@@ -1176,23 +1204,31 @@ void eeprom_update(int mapped_addr, uint8_t byte) {
#elif !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
uint8_t read_byte;
void* read_byte_ptr = &read_byte;
- void const * byte_ptr = &byte;
- flash_nrf5x_read(read_byte_ptr, mapped_addr, 1);
+ file.seek(mapped_addr);
+ file.read(read_byte_ptr, 1);
+ file.seek(mapped_addr);
if (read_byte != byte) {
- flash_nrf5x_write(mapped_addr, byte_ptr, 1);
+ file.write(byte);
}
-
written_bytes++;
- // flush the cache every 4 bytes to make sure everything is synced
- if (written_bytes == 4) {
+ if (written_bytes >= 8) {
+ file.close();
+ file.open(EEPROM_FILE, FILE_O_WRITE);
written_bytes = 0;
- flash_nrf5x_flush();
}
#endif
-
}
+#if !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
+void eeprom_flush() {
+ // sync file contents to flash
+ file.close();
+ file.open(EEPROM_FILE, FILE_O_WRITE);
+ written_bytes = 0;
+}
+#endif
+
void eeprom_write(uint8_t addr, uint8_t byte) {
if (!eeprom_info_locked() && addr >= 0 && addr < EEPROM_RESERVED) {
eeprom_update(eeprom_addr(addr), byte);
@@ -1329,8 +1365,16 @@ bool eeprom_checksum_valid() {
void bt_conf_save(bool is_enabled) {
if (is_enabled) {
eeprom_update(eeprom_addr(ADDR_CONF_BT), BT_ENABLE_BYTE);
+ #if !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
+ // have to do a flush because we're only writing 1 byte and it syncs after 8
+ eeprom_flush();
+ #endif
} else {
eeprom_update(eeprom_addr(ADDR_CONF_BT), 0x00);
+ #if !HAS_EEPROM && MCU_VARIANT == MCU_NRF52
+ // have to do a flush because we're only writing 1 byte and it syncs after 8
+ eeprom_flush();
+ #endif
}
}
diff --git a/flash_cache.c b/flash_cache.c
deleted file mode 100644
index 50d69f7..0000000
--- a/flash_cache.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef NRF52840_XXAA
-#include
-#include "flash_cache.h"
-#include "common_func.h"
-#include "variant.h"
-#include "wiring_digital.h"
-
-//--------------------------------------------------------------------+
-// MACRO TYPEDEF CONSTANT ENUM DECLARATION
-//--------------------------------------------------------------------+
-static inline uint32_t page_addr_of (uint32_t addr)
-{
- return addr & ~(FLASH_CACHE_SIZE - 1);
-}
-
-static inline uint32_t page_offset_of (uint32_t addr)
-{
- return addr & (FLASH_CACHE_SIZE - 1);
-}
-
-int flash_cache_write (flash_cache_t* fc, uint32_t dst, void const * src, uint32_t len)
-{
- uint8_t const * src8 = (uint8_t const *) src;
- uint32_t remain = len;
-
- // Program up to page boundary each loop
- while ( remain )
- {
- uint32_t const page_addr = page_addr_of(dst);
- uint32_t const offset = page_offset_of(dst);
-
- uint32_t wr_bytes = FLASH_CACHE_SIZE - offset;
- wr_bytes = min32(remain, wr_bytes);
-
- // Page changes, flush old and update new cache
- if ( page_addr != fc->cache_addr )
- {
- flash_cache_flush(fc);
- fc->cache_addr = page_addr;
-
- // read a whole page from flash
- fc->read(fc->cache_buf, page_addr, FLASH_CACHE_SIZE);
- }
-
- memcpy(fc->cache_buf + offset, src8, wr_bytes);
-
- // adjust for next run
- src8 += wr_bytes;
- remain -= wr_bytes;
- dst += wr_bytes;
- }
-
- return len - remain;
-}
-
-void flash_cache_flush (flash_cache_t* fc)
-{
- if ( fc->cache_addr == FLASH_CACHE_INVALID_ADDR ) return;
-
- // skip erase & program if verify() exists, and memory matches
- if ( !(fc->verify && fc->verify(fc->cache_addr, fc->cache_buf, FLASH_CACHE_SIZE)) )
- {
- // indicator TODO allow to disable flash indicator
- ledOn(LED_BUILTIN);
-
- fc->erase(fc->cache_addr);
- fc->program(fc->cache_addr, fc->cache_buf, FLASH_CACHE_SIZE);
-
- ledOff(LED_BUILTIN);
- }
-
- fc->cache_addr = FLASH_CACHE_INVALID_ADDR;
-}
-
-int flash_cache_read (flash_cache_t* fc, void* dst, uint32_t addr, uint32_t count)
-{
- // there is no check for overflow / wraparound for dst + count, addr + count.
- // this might be a useful thing to add for at least debug builds.
-
- // overwrite with cache value if available
- if ( (fc->cache_addr != FLASH_CACHE_INVALID_ADDR) && // cache is not valid
- !(addr < fc->cache_addr && addr + count <= fc->cache_addr) && // starts before, ends before cache area
- !(addr >= fc->cache_addr + FLASH_CACHE_SIZE) ) // starts after end of cache area
- {
- // This block is entered only when the read overlaps the cache area by at least one byte.
- // If the read starts before the cache area, it's further guaranteed
- // that count is large enough to cause the read to enter
- // the cache area by at least 1 byte.
- uint32_t dst_off = 0;
- uint32_t src_off = 0;
- if (addr < fc->cache_addr)
- {
- dst_off = fc->cache_addr - addr;
- // Read the bytes prior to the cache address
- fc->read(dst, addr, dst_off);
- }
- else
- {
- src_off = addr - fc->cache_addr;
- }
-
- // Thus, after the above code block executes:
- // *** AT MOST ***, only one of src_off and dst_off are non-zero;
- // (Both may be zero when the read starts at the start of the cache area.)
- // dst_off corresponds to the number of bytes already read from PRIOR to the cache area.
- // src_off corresponds to the byte offset to start reading at, from WITHIN the cache area.
-
- // How many bytes to memcpy from flash area?
- // Remember that, AT MOST, one of src_off and dst_off are non-zero.
- // If src_off is non-zero, then dst_off is zero, representing that the
- // read starts inside the cache. In this case:
- // PARAM1 := FLASH_CACHE_SIZE - src_off == maximum possible bytes to read from cache
- // PARAM2 := count
- // Thus, taking the minimum of the two gives the number of bytes to read from cache,
- // in the range [ 1 .. FLASH_CACHE_SIZE-src_off ].
- // Else if dst_off is non-zero, then src_off is zero, representing that the
- // read started prior to the cache area. In this case:
- // PARAM1 := FLASH_CACHE_SIZE == full size of the cache
- // PARAM2 := count - dst_off == total bytes requested, minus the count of those already read
- // Because the original request is guaranteed to overlap the cache, the range for
- // PARAM2 is ensured to be [ 1 .. count-1 ].
- // Thus, taking the minimum of the two gives the number of bytes to read from cache,
- // in the range [ 1 .. FLASH_CACHE_SIZE ]
- // Else both src_off and dst_off are zero, representing that the read is starting
- // exactly aligned to the cache.
- // PARAM1 := FLASH_CACHE_SIZE
- // PARAM2 := count
- // Thus, taking the minimum of the two gives the number of bytes to read from cache,
- // in the range [ 1 .. FLASH_CACHE_SIZE ]
- //
- // Therefore, in all cases, there is assurance that cache_bytes
- // will be in the final range [1..FLASH_CACHE_SIZE].
- uint32_t cache_bytes = minof(FLASH_CACHE_SIZE-src_off, count - dst_off);
-
- // Use memcpy to read cached data into the buffer
- // If src_off is non-zero, then dst_off is zero, representing that the
- // read starts inside the cache. In this case:
- // PARAM1 := dst
- // PARAM2 := fc->cache_buf + src_off
- // PARAM3 := cache_bytes
- // Thus, all works as expected when starting in the midst of the cache.
- // Else if dst_off is non-zero, then src_off is zero, representing that the
- // read started prior to the cache. In this case:
- // PARAM1 := dst + dst_off == destination offset by number of bytes already read
- // PARAM2 := fc->cache_buf
- // PARAM3 := cache_bytes
- // Thus, all works as expected when starting prior to the cache.
- // Else both src_off and dst_off are zero, representing that the read is starting
- // exactly aligned to the cache.
- // PARAM1 := dst
- // PARAM2 := fc->cache_buf
- // PARAM3 := cache_bytes
- // Thus, all works as expected when starting exactly at the cache boundary
- //
- // Therefore, in all cases, there is assurance that cache_bytes
- // will be in the final range [1..FLASH_CACHE_SIZE].
- memcpy(dst + dst_off, fc->cache_buf + src_off, cache_bytes);
-
- // Read any final bytes from flash
- // As noted above, dst_off represents the count of bytes read prior to the cache
- // while cache_bytes represents the count of bytes read from the cache;
- // This code block is guaranteed to overlap the cache area by at least one byte.
- // Thus, copied will correspond to the total bytes already copied,
- // and is guaranteed to be in the range [ 1 .. count ].
- uint32_t copied = dst_off + cache_bytes;
-
- //
- if ( copied < count )
- {
- fc->read(dst + copied, addr + copied, count - copied);
- }
- }
- else
- {
- // not using the cache, so just forward to read from flash
- fc->read(dst, addr, count);
- }
-
- return (int) count;
-}
-#endif
diff --git a/flash_cache.h b/flash_cache.h
deleted file mode 100644
index ff585e5..0000000
--- a/flash_cache.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef NRF52840_XXAA
-#ifndef FLASH_CACHE_H_
-#define FLASH_CACHE_H_
-
-#include
-#include
-
-#define FLASH_CACHE_SIZE 4096 // must be a erasable page size
-#define FLASH_CACHE_INVALID_ADDR 0xffffffff
-
-typedef struct
-{
- bool (*erase) (uint32_t addr);
- uint32_t (*program) (uint32_t dst, void const * src, uint32_t len);
- uint32_t (*read) (void* dst, uint32_t src, uint32_t len);
- bool (*verify) (uint32_t addr, void const * buf, uint32_t len);
-
- uint32_t cache_addr;
- uint8_t* cache_buf;
-} flash_cache_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int flash_cache_write (flash_cache_t* fc, uint32_t dst, void const *src, uint32_t count);
-void flash_cache_flush (flash_cache_t* fc);
-int flash_cache_read (flash_cache_t* fc, void* dst, uint32_t addr, uint32_t count);
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* FLASH_CACHE_H_ */
-#endif
diff --git a/flash_nrf5x.c b/flash_nrf5x.c
deleted file mode 100644
index 0442a39..0000000
--- a/flash_nrf5x.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef NRF52840_XXAA
-#include "flash_nrf5x.h"
-#include "flash_cache.h"
-#include "nrf_sdm.h"
-#include "nrf_soc.h"
-#include "delay.h"
-#include "rtos.h"
-
-
-#ifdef NRF52840_XXAA
- #define BOOTLOADER_ADDR 0xF4000
-#else
- #define BOOTLOADER_ADDR 0x74000
-#endif
-
-// defined in linker script
-extern uint32_t __flash_arduino_start[];
-//extern uint32_t __flash_arduino_end[];
-
-//--------------------------------------------------------------------+
-// MACRO TYPEDEF CONSTANT ENUM DECLARATION
-//--------------------------------------------------------------------+
-static SemaphoreHandle_t _sem = NULL;
-
-void flash_nrf5x_event_cb (uint32_t event)
-{
-// if (event != NRF_EVT_FLASH_OPERATION_SUCCESS) LOG_LV1("IFLASH", "Flash op Failed");
- if ( _sem ) xSemaphoreGive(_sem);
-}
-
-// Flash Abstraction Layer
-static bool fal_erase (uint32_t addr);
-static uint32_t fal_program (uint32_t dst, void const * src, uint32_t len);
-static uint32_t fal_read (void* dst, uint32_t src, uint32_t len);
-static bool fal_verify (uint32_t addr, void const * buf, uint32_t len);
-
-static uint8_t _cache_buffer[FLASH_CACHE_SIZE] __attribute__((aligned(4)));
-
-static flash_cache_t _cache =
-{
- .erase = fal_erase,
- .program = fal_program,
- .read = fal_read,
- .verify = fal_verify,
-
- .cache_addr = FLASH_CACHE_INVALID_ADDR,
- .cache_buf = _cache_buffer
-};
-
-//--------------------------------------------------------------------+
-// Application API
-//--------------------------------------------------------------------+
-void flash_nrf5x_flush (void)
-{
- flash_cache_flush(&_cache);
-}
-
-int flash_nrf5x_write (uint32_t dst, void const * src, uint32_t len)
-{
- // Softdevice region
- VERIFY(dst >= ((uint32_t) __flash_arduino_start), -1);
-
- // Bootloader region
- VERIFY(dst < BOOTLOADER_ADDR, -1);
-
- return flash_cache_write(&_cache, dst, src, len);
-}
-
-int flash_nrf5x_read (void* dst, uint32_t src, uint32_t len)
-{
- return flash_cache_read(&_cache, dst, src, len);
-}
-
-bool flash_nrf5x_erase(uint32_t addr)
-{
- return fal_erase(addr);
-}
-
-//--------------------------------------------------------------------+
-// HAL for caching
-//--------------------------------------------------------------------+
-static bool fal_erase (uint32_t addr)
-{
- // Init semaphore for first call
- if ( _sem == NULL )
- {
- _sem = xSemaphoreCreateCounting(10, 0);
- VERIFY(_sem);
- }
-
- // retry if busy
- uint32_t err;
- while ( NRF_ERROR_BUSY == (err = sd_flash_page_erase(addr / FLASH_NRF52_PAGE_SIZE)) )
- {
- delay(1);
- }
- VERIFY_STATUS(err, false);
-
- // wait for async event if SD is enabled
- uint8_t sd_en = 0;
- (void) sd_softdevice_is_enabled(&sd_en);
-
- if ( sd_en ) xSemaphoreTake(_sem, portMAX_DELAY);
-
- return true;
-}
-
-static uint32_t fal_program (uint32_t dst, void const * src, uint32_t len)
-{
- // wait for async event if SD is enabled
- uint8_t sd_en = 0;
- (void) sd_softdevice_is_enabled(&sd_en);
-
- uint32_t err;
-
- // Somehow S140 v6.1.1 assert an error when writing a whole page
- // https://devzone.nordicsemi.com/f/nordic-q-a/40088/sd_flash_write-cause-nrf_fault_id_sd_assert
- // Workaround: write half page at a time.
-#if NRF52832_XXAA
- while ( NRF_ERROR_BUSY == (err = sd_flash_write((uint32_t*) dst, (uint32_t const *) src, len/4)) )
- {
- delay(1);
- }
- VERIFY_STATUS(err, 0);
-
- if ( sd_en ) xSemaphoreTake(_sem, portMAX_DELAY);
-#else
- while ( NRF_ERROR_BUSY == (err = sd_flash_write((uint32_t*) dst, (uint32_t const *) src, len/8)) )
- {
- delay(1);
- }
- VERIFY_STATUS(err, 0);
- if ( sd_en ) xSemaphoreTake(_sem, portMAX_DELAY);
-
- while ( NRF_ERROR_BUSY == (err = sd_flash_write((uint32_t*) (dst+ len/2), (uint32_t const *) (src + len/2), len/8)) )
- {
- delay(1);
- }
- VERIFY_STATUS(err, 0);
- if ( sd_en ) xSemaphoreTake(_sem, portMAX_DELAY);
-#endif
-
- return len;
-}
-
-static uint32_t fal_read (void* dst, uint32_t src, uint32_t len)
-{
- memcpy(dst, (void*) src, len);
- return len;
-}
-
-static bool fal_verify (uint32_t addr, void const * buf, uint32_t len)
-{
- return 0 == memcmp((void*) addr, buf, len);
-}
-#endif
diff --git a/flash_nrf5x.h b/flash_nrf5x.h
deleted file mode 100644
index 138cf9c..0000000
--- a/flash_nrf5x.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach for Adafruit Industries
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef NRF52840_XXAA
-#ifndef FLASH_NRF52_H_
-#define FLASH_NRF52_H_
-
-#include "common_inc.h"
-
-#define FLASH_NRF52_PAGE_SIZE 4096
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-void flash_nrf5x_flush (void);
-bool flash_nrf5x_erase(uint32_t addr);
-
-int flash_nrf5x_write (uint32_t dst, void const * src, uint32_t len);
-int flash_nrf5x_read (void* dst, uint32_t src, uint32_t len);
-
-//--------------------------------------------------------------------+
-// Write helper
-//--------------------------------------------------------------------+
-static inline int flash_nrf5x_write8 (uint32_t dst, uint8_t num)
-{
- return flash_nrf5x_write(dst, &num, sizeof(num));
-}
-
-static inline int flash_nrf5x_write16 (uint32_t dst, uint8_t num)
-{
- return flash_nrf5x_write(dst, &num, sizeof(num));
-}
-static inline int flash_nrf5x_write32 (uint32_t dst, uint8_t num)
-{
- return flash_nrf5x_write(dst, &num, sizeof(num));
-}
-
-//--------------------------------------------------------------------+
-// Read helper
-//--------------------------------------------------------------------+
-static inline uint8_t flash_nrf5x_read8 (uint32_t src)
-{
- uint8_t num;
- flash_nrf5x_read(&num, src, sizeof(num));
- return num;
-}
-
-static inline uint16_t flash_nrf5x_read16 (uint32_t src)
-{
- uint16_t num;
- flash_nrf5x_read(&num, src, sizeof(num));
- return num;
-}
-
-static inline uint16_t flash_nrf5x_read32 (uint32_t src)
-{
- uint32_t num;
- flash_nrf5x_read(&num, src, sizeof(num));
- return num;
-}
-
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* FLASH_NRF52_H_ */
-#endif