From b8e73852a54e1a8dab33e44c60fb87893bb58c29 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 17 Apr 2017 15:30:03 -0500 Subject: [PATCH] Flash storage fixes, and add ability to disable serial --- Makefile | 11 ++++------- pyaci/interactive_console.py | 6 ++++++ pyaci/sensei_cmd.py | 18 ++++++++++++++++++ src/app_cmd.c | 16 +++++++++++++++- src/app_cmd.h | 13 +++++++++++-- src/config.c | 35 +++++++++++++++++++++++++++++------ src/config.h | 5 ++++- src/main.c | 18 +++++++++++++----- 8 files changed, 100 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 7595a45..62546dc 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,6 @@ #TARGET_BOARD ?= BOARD_PCA10028 TARGET_BOARD ?= BOARD_SENSEI -USE_RBC_MESH_SERIAL ?= "yes" USE_DFU ?= "no" #------------------------------------------------------------------------------ @@ -27,6 +26,7 @@ RFD_LOADER := $(SIMBLEE_BASE)/RFDLoader_osx #SERIAL_PORT := /dev/cu.usbserial-DN00D34P # left SERIAL_PORT := /dev/cu.usbserial-DN00CSZ7 # right #SERIAL_PORT := /dev/cu.usbserial-A105RB12 +#SERIAL_PORT := /dev/cu.usbserial-FTZ86FTC ifeq ($(USE_RBC_MESH_SERIAL), "yes") SERIAL_STRING := "_serial" @@ -98,11 +98,9 @@ C_SOURCE_FILES += $(COMPONENTS)/libraries/timer/app_timer.c CXX_SOURCE_FILES += $(SIMBLEE_BASE)/libraries/SimbleeBLE/SimbleeBLE.cpp CXX_SOURCE_FILES += $(SIMBLEE_BASE)/variants/Simblee/variant.cpp -ifeq ($(USE_RBC_MESH_SERIAL), "yes") - CFLAGS += -D RBC_MESH_SERIAL=1 - C_SOURCE_FILES += $(RBC_MESH)/src/serial_handler_uart.c - C_SOURCE_FILES += $(RBC_MESH)/src/mesh_aci.c -endif +CFLAGS += -D RBC_MESH_SERIAL=1 +C_SOURCE_FILES += $(RBC_MESH)/src/serial_handler_uart.c +C_SOURCE_FILES += $(RBC_MESH)/src/mesh_aci.c ifeq ($(USE_DFU), "yes") CFLAGS += -D MESH_DFU=1 @@ -264,7 +262,6 @@ all: $(BUILD_DIRECTORIES) $(OBJECTS) @echo "build with: $(TOOLCHAIN_BASE)" @echo "build target: $(TARGET_BOARD)" @echo "build options --" - @echo " USE_RBC_MESH_SERIAL $(USE_RBC_MESH_SERIAL)" @echo " USE_DFU $(USE_DFU)" @echo "build products --" @echo " $(OUTPUT_NAME).elf" diff --git a/pyaci/interactive_console.py b/pyaci/interactive_console.py index 06ec9ae..6f2812e 100644 --- a/pyaci/interactive_console.py +++ b/pyaci/interactive_console.py @@ -79,6 +79,12 @@ def runCommand(self, command): def setTime(self): self.runCommand(sensei_cmd.SetTime()) + def setConfig(self, sensor_id, serial_enabled, mesh_channel): + self.runCommand(sensei_cmd.SetConfig(sensor_id, serial_enabled, mesh_channel)) + + def getConfig(self): + self.runCommand(sensei_cmd.GetConfig()) + def get_ipython_config(device): # import os, sys, IPython diff --git a/pyaci/sensei_cmd.py b/pyaci/sensei_cmd.py index 3ed89b3..ce9296c 100644 --- a/pyaci/sensei_cmd.py +++ b/pyaci/sensei_cmd.py @@ -1,4 +1,5 @@ import time +import struct class SetTime(object): OpCode = 0x02 @@ -14,3 +15,20 @@ def serialize(self): print("epoch = {epoch}".format(epoch=self.epoch)) #print("Waiting {ms}ms".format(ms=(1000-ms))) return bytearray([self.OpCode]) + int(self.epoch).to_bytes(4, byteorder='little') + ms.to_bytes(2, byteorder='little') + +class SetConfig(object): + OpCode = 0x03 + + def __init__(self, sensor_id=0, serial_enabled=False, mesh_channel=38): + self.sensor_id = sensor_id + self.serial_enabled = serial_enabled + self.mesh_channel=mesh_channel + + def serialize(self): + return struct.pack("BBBB", self.OpCode, self.sensor_id, self.serial_enabled, self.mesh_channel) + +class GetConfig(object): + OpCode = 0x04 + + def serialize(self): + return struct.pack("B", self.OpCode) diff --git a/src/app_cmd.c b/src/app_cmd.c index 168a2f5..7b8a25f 100644 --- a/src/app_cmd.c +++ b/src/app_cmd.c @@ -3,6 +3,7 @@ #include "nrf_error.h" #include "leds.h" #include "time_sync.h" +#include "config.h" uint16_t app_cmd_handler(uint8_t *data, uint8_t len, uint8_t *response, uint8_t *response_length) { @@ -11,13 +12,26 @@ uint16_t app_cmd_handler(uint8_t *data, uint8_t len, uint8_t *response, uint8_t uint16_t error_code; switch(cmd->opcode) { - case APP_CMD_OPCODE_SET_EPOCH_TIME: + case APP_CMD_OPCODE_SET_TIME: { set_clock_time(cmd->params.set_clock_time.epoch, cmd->params.set_clock_time.ms, CLOCK_SOURCE_SERIAL); error_code = NRF_SUCCESS; *response_length = 0; } break; + case APP_CMD_OPCODE_SET_CONFIG: + { + error_code = set_config(&cmd->params.set_config.config); + *response_length = 0; + } + break; + case APP_CMD_OPCODE_GET_CONFIG: + { + get_config((app_config_t*)response); + *response_length = sizeof(app_config_t); + error_code = NRF_SUCCESS; + } + break; default: error_code = NRF_ERROR_NOT_SUPPORTED; } diff --git a/src/app_cmd.h b/src/app_cmd.h index 45d8dcb..482dbef 100644 --- a/src/app_cmd.h +++ b/src/app_cmd.h @@ -3,10 +3,13 @@ #include #include "toolchain.h" +#include "config.h" typedef enum { - APP_CMD_OPCODE_SET_EPOCH_TIME = 0x02, + APP_CMD_OPCODE_SET_TIME = 0x02, + APP_CMD_OPCODE_SET_CONFIG = 0x03, + APP_CMD_OPCODE_GET_CONFIG = 0x04, } app_cmd_opcode_t; typedef __packed_armcc struct @@ -15,12 +18,18 @@ typedef __packed_armcc struct uint16_t ms; } __packed_gcc app_cmd_params_set_clock_time_t; +typedef __packed_armcc struct +{ + app_config_t config; +} __packed_gcc app_cmd_params_set_config_t; + typedef __packed_armcc struct { app_cmd_opcode_t opcode; __packed_armcc union { - app_cmd_params_set_clock_time_t set_clock_time; + app_cmd_params_set_clock_time_t set_clock_time; + app_cmd_params_set_config_t set_config; } __packed_gcc params; } __packed_gcc app_cmd_t; diff --git a/src/config.c b/src/config.c index 5db899f..3d95f66 100644 --- a/src/config.c +++ b/src/config.c @@ -2,9 +2,11 @@ #include "config.h" #include "nrf_error.h" #include +#include "leds.h" // Should be bigger than app_config_t -#define APP_CONFIG_BLOCK_SIZE 64 +#define APP_CONFIG_BLOCK_SIZE 32 +#define APP_CONFIG_BLOCK 0 #define APP_CONFIG_OFFSET 0 static pstorage_handle_t m_storage_handle; @@ -33,14 +35,27 @@ bool config_init() { return true; } +static void init_config_to_defaults() { + m_config.sensor_id = 0; + m_config.serial_enabled = 1; + m_config.mesh_channel = 38; +} + static bool ensure_config_loaded() { if (!m_loaded) { - if (pstorage_load((uint8_t*)&m_config, &m_storage_handle, sizeof(app_config_t), APP_CONFIG_OFFSET) != NRF_SUCCESS) { + static pstorage_handle_t block; + if (pstorage_block_identifier_get(&m_storage_handle, APP_CONFIG_BLOCK, &block) != NRF_SUCCESS) { + return false; + } + + if (pstorage_load((uint8_t*)&m_config, &block, sizeof(app_config_t), APP_CONFIG_OFFSET) != NRF_SUCCESS) { return false; } if (m_config.sensor_id == 0xff) { - // Flash has not been written yet - memset(&m_config, 0, sizeof(app_config_t)); + // Flash has not been written yet. Initialize config to default values + init_config_to_defaults(); + } else { + toggle_led(LED_GREEN); } m_loaded = true; } @@ -55,9 +70,17 @@ bool get_config(app_config_t *config) { return true; } -bool set_config(app_config_t *config) { +uint32_t set_config(app_config_t *config) { memcpy(&m_config, config, sizeof(app_config_t)); - return pstorage_store(&m_storage_handle, (uint8_t*)&m_config, sizeof(app_config_t), APP_CONFIG_OFFSET) == NRF_SUCCESS; + static pstorage_handle_t block; + uint32_t error_code; + error_code = pstorage_block_identifier_get(&m_storage_handle, APP_CONFIG_BLOCK, &block); + if (error_code != NRF_SUCCESS) { + return error_code; + } + // Size must be word-aligned + error_code = pstorage_store(&block, (uint8_t*)&m_config, ((sizeof(app_config_t)/16 + 1) * 16), APP_CONFIG_OFFSET); + return error_code; } uint8_t get_sensor_id() { diff --git a/src/config.h b/src/config.h index a10511d..9b27a76 100644 --- a/src/config.h +++ b/src/config.h @@ -8,6 +8,8 @@ typedef __packed_armcc struct { uint8_t sensor_id; + uint8_t serial_enabled; + uint8_t mesh_channel; } __packed_gcc app_config_t; // Returns true on success @@ -20,9 +22,10 @@ bool get_config(app_config_t *); // Stores config in flash, and updates ram copy for subsequent use // Returns true on success -bool set_config(app_config_t *); +uint32_t set_config(app_config_t *); // Shortcut for getting sensor id. Returns 0 on failure to load sensor id uint8_t get_sensor_id(); + #endif //__CONFIG_H__ diff --git a/src/main.c b/src/main.c index 8a857dd..64b3026 100644 --- a/src/main.c +++ b/src/main.c @@ -24,10 +24,10 @@ #define MESH_CHANNEL (38) #define MESH_CLOCK_SRC (NRF_CLOCK_LFCLKSRC_XTAL_75_PPM) - /** @brief General error handler. */ static inline void error_loop(void) { + toggle_led(LED_RED); __disable_irq(); while (true) { @@ -121,6 +121,7 @@ int main(void) LEDS_CONFIGURE(LEDS_MASK); + // if (NRF_CLOCK->LFCLKSRC == (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos)) { // toggle_led(LED_GREEN); // } @@ -133,18 +134,25 @@ int main(void) init_params.lfclksrc = MESH_CLOCK_SRC; init_params.tx_power = RBC_MESH_TXPOWER_0dBm; + uint32_t error_code; error_code = rbc_mesh_init(init_params); + if (error_code != NRF_SUCCESS) { + toggle_led(LED_GREEN); + } APP_ERROR_CHECK(error_code); + app_config_t app_config; config_init(); + get_config(&app_config); + time_sync_init(); /* Initialize serial ACI */ -#ifdef RBC_MESH_SERIAL - mesh_aci_init(); - mesh_aci_app_cmd_handler_set(app_cmd_handler); -#endif + if (app_config.serial_enabled) { + mesh_aci_init(); + mesh_aci_app_cmd_handler_set(app_cmd_handler); + } /* Enable handle 1 */ error_code = rbc_mesh_value_enable(1);