Browse Source

further developed ideasX interface

curiousmuch 4 years ago
parent
commit
7682554a0e

+ 1 - 1
Makefile

@@ -36,7 +36,7 @@ TARGET		?= ideasX_
 TARGET_LIB ?= ideasX.a
 
 # which modules (subdirectories) of the project to include in compiling
-USER_MODULES		= user driver gdbstub log hal interface include
+USER_MODULES		= user driver gdbstub log hal interface include mqtt
 USER_INC				= include
 USER_LIB				=
 

+ 7 - 0
README.md

@@ -18,3 +18,10 @@ The firmware is based on tuanpm's MQTT repository (thanks man!). It's been heavi
 
 
 You can learn more about IdeasX, Encoders, and the module [here](https://www.curiousmuch.org/ideasx).
+
+## Implementation Roadmap
+1. Develop flash interface to store / restore settings from flash (doesn't need to support OTA)
+2. Develop IdeasX interface
+
+## Werid Issues
+1. Make sure LSM6DS3 is properly setting the interrupt pin such that it will permit the SWA to still trigger an interrupt.

+ 21 - 3
hal/io.c

@@ -33,6 +33,7 @@ void ICACHE_FLASH_ATTR IO_InitIO(void)
     io_config.switch_a_cb = NULL;
     io_config.switch_b_cb = NULL;
     io_config.imu_cb = NULL;
+    io_config.debounce_timer = false;
 
     // setup as GPIO pins
     PIN_FUNC_SELECT(LDO_SHUTDOWN_MUX, LDO_SHUTDOWN_FUNC);
@@ -68,9 +69,15 @@ void ICACHE_FLASH_ATTR IO_SetIMUCallback(imu_function_t imu_cb)
  void ICACHE_FLASH_ATTR IO_EnableIOInterrupts(void)
  {
      ETS_GPIO_INTR_DISABLE();
+
+     // clear existing interrupt
+     uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
+     GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
+
      gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_ANYEDGE);
      gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);
      ETS_GPIO_INTR_ENABLE();
+     ESP_LOGV(TAG, "enabled interrupts");
  }
 
  void ICACHE_FLASH_ATTR IO_DisableIOInterrupts(void)
@@ -78,8 +85,15 @@ void ICACHE_FLASH_ATTR IO_SetIMUCallback(imu_function_t imu_cb)
      ETS_GPIO_INTR_DISABLE();
      gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_DISABLE);
      gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_DISABLE);
+     ESP_LOGV(TAG, "disabled interrupts");
+     ETS_GPIO_INTR_DISABLE();
  }
 
+void ICACHE_FLASH_ATTR IO_DisableDebounceTimer(void)
+{
+
+}
+
 void ICACHE_FLASH_ATTR IO_Shutdown(void)
 {
     GPIO_OUTPUT_SET(LDO_SHUTDOWN, 0);
@@ -110,14 +124,15 @@ void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
                     {
                         if (io_config.imu_cb != NULL)
                             io_config.imu_cb((IMU_Interrupt_et) imu_interrupt);
-                        gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);     // re-enable interrupts
+                        //gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);     // re-enable interrupts
 
                     }
                     else
                     {
                         if (io_config.switch_a_cb != NULL)
                             io_config.switch_a_cb();
-                        os_timer_arm(&io_config.switch_a_timer, io_config.debounce_delay, 0);
+                        if (io_config.debounce_timer)
+                            os_timer_arm(&io_config.switch_a_timer, io_config.debounce_delay, 0);
                     }
         		    break;
 				}
@@ -125,7 +140,8 @@ void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
                 {
                     if (io_config.switch_b_cb != NULL)
                         io_config.switch_b_cb();
-                    os_timer_arm(&io_config.switch_b_timer, io_config.debounce_delay, 0);
+                    if (io_config.debounce_timer)
+                        os_timer_arm(&io_config.switch_b_timer, io_config.debounce_delay, 0);
                     break;
 				}
 				default:
@@ -141,6 +157,7 @@ void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
 
 static void ICACHE_FLASH_ATTR switchA_debounce(void)
 {
+    ESP_LOGV(TAG, "switchA");
 	ETS_GPIO_INTR_DISABLE();
 
 	gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_ANYEDGE);
@@ -152,6 +169,7 @@ static void ICACHE_FLASH_ATTR switchA_debounce(void)
 
 static void ICACHE_FLASH_ATTR switchB_debounce(void)
 {
+    ESP_LOGV(TAG, "switchB");
 	ETS_GPIO_INTR_DISABLE();
 
 	gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);

+ 8 - 7
hal/lsm6ds3.c

@@ -148,13 +148,14 @@ void ICACHE_FLASH_ATTR LSM6DS3_Reset(void)
 
 void ICACHE_FLASH_ATTR LSM6DS3_EnableMotion(void)
 {
-	Sensor_IO_Set_Register(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN);						// disable gyro
-	Sensor_IO_Set_Register(LSM6DS3_CTRL1_XL, (LSM6DS3_ODR_XL_13Hz + LSM6DS3_FS_XL_2G));		// 208Hz 2g scale
-	Sensor_IO_Set_Register(LSM6DS3_TAP_CFG, LSM6DS3_LIR); 									// enable interuppt latch and slope filter
-	Sensor_IO_Set_Register(LSM6DS3_WAKE_UP_THS, 0x01); 									   // set thres 32/64*2G = 1G
-	Sensor_IO_Set_Register(LSM6DS3_WAKE_UP_DUR, 0x02); 									   // zero duration
-	Sensor_IO_Set_Register(LSM6DS3_MD1_CFG, LSM6DS3_INT1_WU);								// set interrupt for INTX (1 is connected to PBA)
-	Sensor_IO_Set_Register(LSM6DS3_CTRL3_C, LSM6DS3_H_LACTIVE);                             // set int lines active low
+    LSM6DS3_Reset();
+	Sensor_IO_Set_Register(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN);						     // disable gyro
+	Sensor_IO_Set_Register(LSM6DS3_CTRL1_XL, (LSM6DS3_ODR_XL_13Hz + LSM6DS3_FS_XL_2G));		     // 208Hz 2g scale
+    Sensor_IO_Set_Register(LSM6DS3_TAP_CFG, LSM6DS3_LIR); 									     // enable interuppt latch and slope filter
+	Sensor_IO_Set_Register(LSM6DS3_WAKE_UP_THS, 0x01); 									         // set thres 32/64*2G = 1G
+	Sensor_IO_Set_Register(LSM6DS3_WAKE_UP_DUR, 0x02); 									         // zero duration
+	Sensor_IO_Set_Register(LSM6DS3_MD1_CFG, LSM6DS3_INT1_WU);								     // set interrupt for INTX (1 is connected to PBA)
+	Sensor_IO_Set_Register(LSM6DS3_CTRL3_C, LSM6DS3_H_LACTIVE);                                  // set int lines active low
 
 }
 

+ 11 - 4
hal/ws2812.c

@@ -29,8 +29,8 @@ static void send_ws_0(void)
 {
 	uint8_t time;
 #if WS2811_COMPATIBLE
-	time = 7; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
-	time = 28; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
+	time = 6; while(time--)  GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
+	time = 10; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
 #else
 	time = 2; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
 	time = 3; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
@@ -41,8 +41,8 @@ static void send_ws_1(void)
 {
 	uint8_t time;
 #if WS2811_COMPATIBLE
-	time = 15; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
-	time = 16; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
+	time = 10; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
+	time = 6; while(time--)  GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
 #else
 
 	time = 5; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
@@ -72,6 +72,13 @@ void WS2812_OutBuffer(int8_t * buffer, uint16_t length)
 
 void ICACHE_FLASH_ATTR WS2812_SetColor(WS2812_COLOR_et color, WS2812_PATTERN_et pattern)
 {
+	// return if the color is already set
+	if (color == ws2812_config.color && pattern == ws2812_config.pattern)
+	{
+		return;
+	}
+
+
 	ws2812_config.color = color;			// store color
 	ws2812_config.pattern = pattern;		// store pattern
 	ws2812_config.led_state = 1; 			// reset led update timer state

+ 5 - 0
include/hal/io.h

@@ -39,11 +39,16 @@ typedef struct {
     switch_function_t switch_b_cb;
     imu_function_t imu_cb;
     uint32_t debounce_delay;
+    bool debounce_timer; 
 } IO_config_t;
 
 
 void ICACHE_FLASH_ATTR IO_InitIO(void);
 void ICACHE_FLASH_ATTR IO_Shutdown(void);
 void ICACHE_FLASH_ATTR IO_Restart(void);
+void ICACHE_FLASH_ATTR IO_DisableIOInterrupts(void);
+void ICACHE_FLASH_ATTR IO_EnableIOInterrupts(void);
+void ICACHE_FLASH_ATTR IO_SetSwitchCallback(switch_function_t, switch_function_t);
+void ICACHE_FLASH_ATTR IO_SetIMUCallback(imu_function_t);
 
 #endif

+ 8 - 3
include/interface/encoder_interface.h

@@ -1,5 +1,5 @@
-#ifndef ENCODER_INTERFACE_H
-#define ENCODER_INTERFACE_H
+#ifndef __ENCODER_INTERFACE_H__
+#define __ENCODER_INTERFACE_H__
 
 #include "esp_common.h"
 #include "log/esp_log.h"
@@ -14,8 +14,13 @@
 #define Encoder_EnableIOInterrupts IO_EnableIOInterrupts
 #define Encoder_SetIMUCallback IO_SetIMUCallback
 #define Encoder_SetSwitchCallback IO_SetSwitchCallback
-
+#define Encoder_DisableDebounceTimer IO_DisableDebounceTimer
 #define Encoder_EnableMotion LSM6DS3_EnableMotion
 #define Encoder_DisableMotion LSM6DS3_DisableMotion
+#define Encoder_GetVoltage max17043_getVoltage
+#define Encoder_GetSOC max17043_getSOC
+
+
+#define Encoder_InitUART uart_init
 
 #endif

+ 0 - 56
include/interface/ideasX_interface.h

@@ -1,56 +0,0 @@
-
-
-typedef struct {
- uint8_t topic = "hw_ver";
- uint8_t minor;
- uint8_t major;
-} hw_ver_t;
-
-typedef struct {
- uint8_t topic = "fw_ver";
- uint8_t minor;
- uint8_t major;
-} fw_ver_t;
-
-typedef struct {
- uint8_t topic = "alive";
- bool flag;
-} alive_t;
-
-typedef struct {
- uint8_t topic = "vcell";
- uint32_t vcell;
-} vcell_t;
-
-typedef struct {
-  uint8_t topic = "rom";
-  uint8_t rom;
-} rom_t;
-
-typedef struct {
-  uint8_t topic = "ota";
-  bool ota;
-} ota_t;
-
-typedef struct{
-  hw_ver_t hw_ver;
-  fw_ver_t fw_ver;
-  alive_t alive;
-  vcell_t vcell;
-  soc_t soc;
-  rom_t rom;
-  ota_t ota;
-  ssid_t ssid;
-  bssid_t bssid;
-  rssi_t rssi;
-} ideasX_topics_t;
-
-typedef struct {
-    uint8_t topic = "ota";
-    uint32_t* function;
-} ideasX_command_ota_t;
-
-typedef struct {
-    uint8_t topic = "shutdown";
-    uint32_t* function;
-} ideasX_command_shutdown_t; 

+ 134 - 0
include/interface/ideasx_interface.h

@@ -0,0 +1,134 @@
+#ifndef __IDEASX_INTERFACE_H__
+#define __IDEASX_INTERFACE_H__
+
+#include "esp_common.h"
+#include "mqtt/mqtt.h"
+#include "log/esp_log.h"
+#include "user_config.h"
+#include "interface/encoder_interface.h"
+
+/* Health Packet Topics and Payloads */
+
+typedef void (* ideasX_function_t)(void);
+
+typedef struct {
+    uint8_t topic[20];
+    uint8_t minor;
+    uint8_t major;
+} hw_ver_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint8_t minor;
+    uint8_t major;
+} fw_ver_t;
+
+typedef struct {
+    uint8_t topic[20];
+    bool flag;
+} alive_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint32_t value;
+} vcell_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint8_t value;
+} rom_t;
+
+typedef struct {
+    uint8_t topic[20];
+    bool flag;
+} ota_t;
+
+typedef struct {
+    uint8_t topic[20];
+    int8_t value;
+} rssi_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint8_t value[40];
+} ssid_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint8_t value[40];
+} bssid_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint32_t value;
+} soc_t;
+
+typedef struct{
+    hw_ver_t hw_ver;
+    fw_ver_t fw_ver;
+    alive_t alive;
+    vcell_t vcell;
+    soc_t soc;
+    rom_t rom;
+    ota_t ota;
+    ssid_t ssid;
+    bssid_t bssid;
+    rssi_t rssi;
+    os_timer_t health_timer;
+    uint32_t health_report_rate;
+} IdeasX_Health_t;
+
+typedef struct {
+    uint8_t     health_topic[40];
+    uint8_t     command_topic[40];
+    uint8_t     device_id[40];
+    uint8_t     mqtt_host[40];
+    uint32_t    mqtt_port;
+    uint8_t     mqtt_user[40];
+    uint8_t     mqtt_pass[40];
+    uint8_t     mqtt_client_id[40];
+    uint32_t    mqtt_keepalive;
+    os_timer_t  battery_timer;
+    ideasX_function_t   success_cb;
+    ideasX_function_t   fail_cb;
+}  IdeasX_Config_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint32_t* function;
+} command_ota_t;
+
+typedef struct {
+    uint8_t topic[20];
+    uint32_t* function;
+} command_shutdown_t;
+
+typedef struct {
+    command_ota_t       ota;
+    command_shutdown_t  shutdown;
+} IdeasX_Command_t;
+
+#define HW_VERSION_HEALTH_TOPIC    "hw_ver"
+#define FW_VERSION_HEALTH_TOPIC    "fw_ver"
+#define ALIVE_HEALTH_TOPIC         "alive"
+#define VCELL_HEALTH_TOPIC         "vcell"
+#define CHARGE_HEALTH_TOPIC        "charge"
+#define LBI_HEALTH_TOPIC           "lbi"
+#define SOC_HEALTH_TOPIC           "soc"
+#define ROM_HEALTH_TOPIC           "rom"
+#define OTA_HEALTH_TOPIC           "ota"
+#define SSID_HEALTH_TOPIC          "ssid"
+#define BSSID_HEALTH_TOPIC         "bssid"
+#define RSSI_HEALTH_TOPIC          "rssi"
+#define AUTH_HEALTH_TOPIC          "auth"
+
+
+#define HEALTH_QOS      0
+#define HEALTH_RETAIN   0
+#define HW_VERSION_MAJOR_DEFAULT    0
+#define HW_VERSION_MINOR_DEFAULT    0
+#define FW_VERSION_MAJOR_DEFAULT    0
+#define FW_VERSION_MINOR_DEFAULT    0
+#define HEALTH_REPORT_RATE_DEFAULT  120     // seconds
+
+#endif

+ 1 - 0
include/interface/light_interface.h

@@ -10,6 +10,7 @@
 #define Light_AccessPointSearching()        WS2812_SetColor(WS2812_GREEN, WS2812_PULSE)
 #define Light_AccessPointNoCredentials()    WS2812_SetColor(WS2812_GREEN, WS2812_SOLID)
 #define Light_BrokerFailure()               WS2812_SetColor(WS2812_BLUE, WS2812_PULSE)
+#define Light_AccessPointConnected()        WS2812_SetColor(WS2812_BLUE, WS2812_PULSE)
 #define Light_BrokerSuccess()               WS2812_SetColor(WS2812_BLUE, WS2812_SOLID)
 #define Light_AdaptiveIMU()                 WS2812_SetColor(WS2812_MAGENTA, WS2812_SOLID)
 #define Light_AdaptiveBar()                 WS2812_SetColor(WS2812_ORANGE, WS2812_SOLID)

+ 1 - 1
include/log/esp_log.h

@@ -78,7 +78,7 @@ uint32_t esp_log_timestamp(void);
 #define LOG_RESET_COLOR
 #endif //CONFIG_LOG_COLORS
 
-#define LOG_FORMAT(letter, format)  LOG_COLOR_ ## letter #letter " (%d) %s: " format LOG_RESET_COLOR "\n"
+#define LOG_FORMAT(letter, format)  LOG_COLOR_ ## letter #letter " (%u) %s: " format LOG_RESET_COLOR "\n"
 #define LOG_LOCAL_LEVEL  ((esp_log_level_t) CONFIG_LOG_DEFAULT_LEVEL)
 
 #define ESP_LOGE( tag, format, ... )  if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR)   { os_printf(LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }

+ 0 - 0
mqtt/include/debug.h → include/mqtt/debug.h


+ 1 - 1
mqtt/include/mqtt.h → include/mqtt/mqtt.h

@@ -30,7 +30,7 @@
 #ifndef USER_AT_MQTT_H_
 #define USER_AT_MQTT_H_
 #include "user_config.h"
-#include "mqtt_msg.h"
+#include "mqtt/mqtt_msg.h"
 #include "user_interface.h"
 
 #include "queue.h"

+ 0 - 0
mqtt/include/mqtt_msg.h → include/mqtt/mqtt_msg.h


+ 2 - 3
mqtt/include/proto.h → include/mqtt/proto.h

@@ -8,8 +8,8 @@
 #ifndef _PROTO_H_
 #define _PROTO_H_
 #include <stdlib.h>
-#include "typedef.h"
-#include "ringbuf.h"
+#include "mqtt/typedef.h"
+#include "mqtt/ringbuf.h"
 
 typedef void(PROTO_PARSE_CALLBACK)();
 
@@ -29,4 +29,3 @@ I16 ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const U8 *packet, I16 len);
 I8 ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, U8 value);
 I16 ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF *rb, U8 *bufOut, U16* len, U16 maxBufLen);
 #endif
-

+ 1 - 1
mqtt/include/queue.h → include/mqtt/queue.h

@@ -31,7 +31,7 @@
 #ifndef USER_QUEUE_H_
 #define USER_QUEUE_H_
 #include "os_type.h"
-#include "ringbuf.h"
+#include "mqtt/ringbuf.h"
 typedef struct {
   uint8_t *buf;
   RINGBUF rb;

+ 1 - 1
mqtt/include/ringbuf.h → include/mqtt/ringbuf.h

@@ -3,7 +3,7 @@
 
 #include <os_type.h>
 #include <stdlib.h>
-#include "typedef.h"
+#include "mqtt/typedef.h"
 
 typedef struct {
   U8* p_o;        /**< Original pointer */

+ 0 - 0
mqtt/include/typedef.h → include/mqtt/typedef.h


+ 0 - 0
mqtt/include/utils.h → include/mqtt/utils.h


+ 17 - 24
include/user_config.h

@@ -13,44 +13,37 @@
 #define STORED_APS 1
 
 /* MQTT DEFAULT CONFIGURATIONS */
-#define MQTT_HOST               "192.168.0.101" //or "mqtt.yourdomain.com"
-#define MQTT_PORT               1883
-#define MQTT_BUF_SIZE           1024
-#define QUEUE_BUFFER_SIZE       2048
-#define MQTT_RECONNECT_TIMEOUT  5 /*second*/
-#define DEFAULT_SECURITY        0
-#define PROTOCOL_NAMEv31  //MQTT version 3.1 compatible with Mosquitto v0.15
-//PROTOCOL_NAMEv311       //MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/
-
-#define MQTT_SSL_ENABLE
-#define MQTT_CLIENT_ID        "CLIENT_1234"
-#define MQTT_USER             "USER"
-#define MQTT_PASS             "PASS"
-#define MQTT_CLEAN_SESSION    1
+#define MQTT_HOST_DEFAULT               "10.42.0.1" //or "mqtt.yourdomain.com"
+#define MQTT_PORT_DEFAULT               1883
+#define MQTT_BUF_SIZE                   1024
+#define MQTT_KEEPALIVE_DEFAULT          120             // seconds
+#define MQTT_CLEAN_SESSION              1
+
+
+#define QUEUE_BUFFER_SIZE               2048
+#define MQTT_RECONNECT_TIMEOUT          5               // seconds
+#define DEFAULT_SECURITY                0
+#define PROTOCOL_NAMEv31
+//#define PROTOCOL_NAMEv311
+
+//#define MQTT_SSL_ENABLE
+//#define MQTT_USER_DEFAULT               "USER"
+//#define MQTT_PASS_DEFAULT               "PASS"
 
 /* OTA SETTINGS */
 #define OTA_HOST 	"fphx.duckdns.org"
 #define OTA_PORT 	2000
 #define OTA_ROM0 	"rom0.bin"
 #define OTA_ROM1 	"rom1.bin"
-// OTA_FILE is not required, but is part of the example
-// code for writing arbitrary files to flash
 #define OTA_FILE "file.bin"
-
-// general http header
 #define HTTP_HEADER "Connection: keep-alive\r\n\
 Cache-Control: no-cache\r\n\
 User-Agent: rBoot-Sample/1.0\r\n\
 Accept: */*\r\n\r\n"
-
-// timeout for the initial connect and each recv (in ms)
-#define OTA_NETWORK_TIMEOUT  10000
-
-
+#define OTA_NETWORK_TIMEOUT  10000 // ms
 
 // This needs to be changed to support a logging library
 #if defined(DEBUG_ON)
-
 #define INFO( format, ... ) os_printf( format, ## __VA_ARGS__ )
 #else
 #define INFO( format, ... )

+ 36 - 3
interface/encoder_interface.c

@@ -6,8 +6,17 @@ typedef struct {
     os_timer_t          motion_timer;
     uint32_t            motion_timeout;
     motion_function_t   motion_cb;
+    uint32_t            vcell;
+    uint32_t            soc;
+    os_timer_t          battery_timer;
+    uint32_t            battery_timeout;
 } Encoder_t;
 
+typedef struct {
+    uint32_t    vcell;
+    uint32_t    motion;
+} Encoder_Battery_t;
+
 static Encoder_t encoder;
 
 void ICACHE_FLASH_ATTR Encoder_Shutdown(void)
@@ -16,19 +25,43 @@ void ICACHE_FLASH_ATTR Encoder_Shutdown(void)
     IO_Shutdown();
 }
 
-void ICACHE_FLASH_ATTR Encoder_Motion_SetCallback(motion_function_t motion_cb)
+/* Motion Functions */
+
+void ICACHE_FLASH_ATTR Encoder_MotionSetCallback(motion_function_t motion_cb)
 {
     encoder.motion_cb = motion_cb;
     os_timer_setfn(&encoder.motion_timer, (os_timer_func_t *)encoder.motion_cb, NULL);
 }
 
-void ICACHE_FLASH_ATTR Encoder_Motion_StartTimer(uint32_t timeout)
+void ICACHE_FLASH_ATTR Encoder_MotionStartTimer(uint32_t timeout)
 {
     encoder.motion_timeout = timeout;
     os_timer_arm(&encoder.motion_timer, encoder.motion_timeout, false);
 }
 
-void ICACHE_FLASH_ATTR Encoder_Motion_StopTimer()
+void ICACHE_FLASH_ATTR Encoder_MotionStopTimer()
 {
     os_timer_disarm(&encoder.motion_timer);
 }
+
+/* Battery Monitor Functions */
+
+// static void ICACHE_FLASH_ATTR encoder_battery_monitor_cb(void)
+// {
+//
+// }
+//
+// void ICACHE_FLASH_ATTR Encoder_StartBatteryMonitor(uint32_t battery_monitor_rate)
+// {
+//
+// }
+//
+// void ICACHE_FLASH_ATTR Encoder_StopBatteryMonitor(void)
+// {
+//
+// }
+//
+// Encoder_Battery_t ICACHE_FLASH_ATTR Encoder_GetBatteryStatus(void)
+// {
+//
+// }

+ 179 - 0
interface/ideasx_interface.c

@@ -0,0 +1,179 @@
+#include "interface/ideasx_interface.h"
+
+static const char* TAG = "IdeasX";
+
+MQTT_Client mqttClient;
+static IdeasX_Config_t ideasX_config;
+static IdeasX_Health_t ideasX_health;
+static os_timer_t health_timer;
+
+
+static void ICACHE_FLASH_ATTR ideasX_publish_health(void)
+{
+    uint8_t topic[40], payload[40];
+    ideasX_health.vcell.value = Encoder_GetVoltage();
+    ideasX_health.soc.value = Encoder_GetSOC();
+    ideasX_health.rssi.value = wifi_station_get_rssi();
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.vcell.topic);
+    os_sprintf(payload, "%d", ideasX_health.vcell.value);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.soc.topic);
+    os_sprintf(payload, "%d", ideasX_health.soc.value);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.rssi.topic);
+    os_sprintf(payload, "%d", ideasX_health.rssi.value);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+}
+
+static void ICACHE_FLASH_ATTR ideasX_connected_cb(uint32_t *args)
+{
+    struct station_config stationConfig;
+    wifi_station_get_config(&stationConfig);
+    uint8_t topic[40], payload[40];
+
+    ESP_LOGI(TAG, "Connected to IdeasX");
+
+    if (ideasX_config.success_cb != NULL)
+        ideasX_config.success_cb();
+
+    // publish static health information
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.hw_ver.topic);
+    os_sprintf(payload, "%d,%d", ideasX_health.hw_ver.major, ideasX_health.hw_ver.minor);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.fw_ver.topic);
+    os_sprintf(payload, "%d,%d", ideasX_health.fw_ver.major, ideasX_health.fw_ver.minor);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.alive.topic);
+    os_sprintf(payload, "%d", ideasX_health.alive.flag);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(ideasX_health.ssid.value, "%s", stationConfig.ssid);
+    os_sprintf(ideasX_health.bssid.value, MACSTR, MAC2STR(stationConfig.bssid));
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.ssid.topic);
+    os_sprintf(payload, "%s", ideasX_health.ssid.value);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.bssid.topic);
+    os_sprintf(payload, "%s", ideasX_health.bssid.value);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.ota.topic);
+    os_sprintf(payload, "%d", ideasX_health.ota.flag);
+    MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
+
+    ideasX_publish_health();
+
+    // setup publish health timer
+    os_timer_disarm(&ideasX_health.health_timer);
+    os_timer_arm(&ideasX_health.health_timer, ideasX_health.health_report_rate*1000, true);   // change to system task
+}
+
+static void ICACHE_FLASH_ATTR ideasX_disconnected_cb(uint32_t *args)
+{
+    ESP_LOGI(TAG, "Disconnected from IdeasX");
+    os_timer_disarm(&ideasX_health.health_timer);
+    if (ideasX_config.fail_cb != NULL)
+        ideasX_config.fail_cb();
+}
+
+static void ICACHE_FLASH_ATTR ideasX_published_cb(uint32_t *args)
+{
+    // subscribe to command topics
+    ESP_LOGD(TAG, "Published Messaged");
+}
+
+void ICACHE_FLASH_ATTR IdeasX_Connect(void)
+{
+    MQTT_Connect(&mqttClient);
+}
+
+void ICACHE_FLASH_ATTR IdeasX_Disconnect(void)
+{
+    MQTT_Disconnect(&mqttClient);
+}
+
+void ICACHE_FLASH_ATTR ideasX_system_config_init()
+{
+    uint8_t mac_address[6];
+    wifi_get_macaddr(STATION_MODE, mac_address);
+    os_sprintf(ideasX_config.device_id, MACSTR, MAC2STR(mac_address));
+    os_sprintf(ideasX_config.mqtt_client_id, MACSTR, MAC2STR(mac_address));
+
+    os_sprintf(ideasX_config.command_topic, "encoder/%s/command/", ideasX_config.device_id);
+    os_sprintf(ideasX_config.health_topic, "encoder/%s/health/", ideasX_config.device_id);
+    os_sprintf(ideasX_config.mqtt_host, "%s", MQTT_HOST_DEFAULT);
+    ideasX_config.mqtt_port = MQTT_PORT_DEFAULT;
+    os_sprintf(ideasX_config.mqtt_user, "%s", "");
+    os_sprintf(ideasX_config.mqtt_pass, "%s", "");
+
+    #ifdef MQTT_USER_DEFAULT
+        os_sprintf(ideasX_config.mqtt_user, "%s", MQTT_USER_DEFAULT);
+        os_sprintf(ideasX_config.mqtt_pass, "%s", MQTT_PASS_DEFAULT);
+    #endif
+    ideasX_config.mqtt_keepalive = MQTT_KEEPALIVE_DEFAULT;
+
+    ideasX_config.success_cb = NULL;
+    ideasX_config.fail_cb = NULL;
+
+}
+
+void ICACHE_FLASH_ATTR ideasX_health_config_init()
+{
+    // setup ideasX topics
+    os_sprintf(ideasX_health.hw_ver.topic, "%s", HW_VERSION_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.fw_ver.topic, "%s", FW_VERSION_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.alive.topic, "%s", ALIVE_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.vcell.topic, "%s", VCELL_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.soc.topic, "%s", SOC_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.rom.topic, "%s", ROM_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.ota.topic, "%s", OTA_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.ssid.topic, "%s", SSID_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.bssid.topic, "%s", BSSID_HEALTH_TOPIC);
+    os_sprintf(ideasX_health.rssi.topic, "%s", RSSI_HEALTH_TOPIC);
+    ideasX_health.health_report_rate = HEALTH_REPORT_RATE_DEFAULT;
+
+    // load default values for static items
+    ideasX_health.hw_ver.minor = HW_VERSION_MINOR_DEFAULT;
+    ideasX_health.hw_ver.major = HW_VERSION_MAJOR_DEFAULT;
+    ideasX_health.fw_ver.minor = FW_VERSION_MINOR_DEFAULT;
+    ideasX_health.fw_ver.major = FW_VERSION_MAJOR_DEFAULT;
+    ideasX_health.alive.flag = true;
+    ideasX_health.ota.flag = false;
+
+    ideasX_health.health_timer = health_timer;
+    os_timer_disarm(&ideasX_health.health_timer);
+    os_timer_setfn(&ideasX_health.health_timer, (os_timer_func_t *)ideasX_publish_health, NULL);
+}
+
+void ICACHE_FLASH_ATTR IdeasX_UpdateBatteryStatus(uint16_t vcell, uint16_t soc)
+{
+    ideasX_health.soc.value = soc;
+    ideasX_health.vcell.value = vcell;
+}
+
+void ICACHE_FLASH_ATTR IdeasX_SetStatusCallbacks(ideasX_function_t success, ideasX_function_t fail)
+{
+    ideasX_config.success_cb = success;
+    ideasX_config.fail_cb = fail;
+}
+
+void ICACHE_FLASH_ATTR IdeasX_Init(void)
+{
+    ideasX_system_config_init();
+    ideasX_health_config_init();
+
+    MQTT_InitConnection(&mqttClient, ideasX_config.mqtt_host, ideasX_config.mqtt_port, DEFAULT_SECURITY);
+    MQTT_InitClient(&mqttClient, ideasX_config.mqtt_client_id, ideasX_config.mqtt_user, ideasX_config.mqtt_pass,
+        ideasX_config.mqtt_keepalive, MQTT_CLEAN_SESSION);
+    MQTT_InitLWT(&mqttClient, ideasX_health.alive.topic, "0", 0, 0);
+    MQTT_OnConnected(&mqttClient, ideasX_connected_cb);
+    MQTT_OnDisconnected(&mqttClient, ideasX_disconnected_cb);
+    //MQTT_OnPublished(&mqttClient, mqttPublishedCb);
+    //MQTT_OnData(&mqttClient, mqttDataCb);
+}

+ 7 - 0
interface/wifi_interface.c

@@ -269,6 +269,13 @@ static void ICACHE_FLASH_ATTR wifi_scan_done(void *arg, STATUS status)
     	struct bss_info *bss_link_next, *bss_link_curr, *bss_link_prev, *bss_link_head;
     	uint32_t i,numAP,j;
 
+		if (bss_link == NULL)
+		{
+			if (wifi_config.fail_cb != NULL)
+				wifi_config.fail_cb(WIFI_NO_AVAILABLE_APS_FAILURE);
+			return;
+		}
+
 		// copy linked list because SDK will end up destorying it
     	bss_link = copy_linked_list(bss_link);
     	bss_link_head = bss_link;

+ 5 - 5
mqtt/mqtt.c

@@ -34,15 +34,15 @@
 #include "espconn.h"
 #include "os_type.h"
 #include "mem.h"
-#include "mqtt_msg.h"
-#include "debug.h"
+#include "mqtt/mqtt_msg.h"
+#include "mqtt/debug.h"
 #include "user_config.h"
-#include "mqtt.h"
-#include "queue.h"
+#include "mqtt/mqtt.h"
+#include "mqtt/queue.h"
 
 #define MQTT_TASK_PRIO            2
 #define MQTT_TASK_QUEUE_SIZE      1
-#define MQTT_SEND_TIMOUT      5
+#define MQTT_SEND_TIMOUT          5
 
 #ifndef MQTT_SSL_SIZE
 #define MQTT_SSL_SIZE         5120

+ 1 - 1
mqtt/mqtt_msg.c

@@ -30,7 +30,7 @@
 */
 
 #include <string.h>
-#include "mqtt_msg.h"
+#include "mqtt/mqtt_msg.h"
 #include "user_config.h"
 #define MQTT_MAX_FIXED_HEADER_SIZE 3
 

+ 2 - 3
mqtt/proto.c

@@ -1,5 +1,5 @@
-#include "proto.h"
-#include "ringbuf.h"
+#include "mqtt/proto.h"
+#include "mqtt/ringbuf.h"
 I8 ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *completeCallback, U8 *buf, U16 bufSize)
 {
   parser->buf = buf;
@@ -126,4 +126,3 @@ I16 ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const U8 *packet, I16 len)
 
   return i;
 }
-

+ 3 - 3
mqtt/queue.c

@@ -27,13 +27,13 @@
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
-#include "queue.h"
+#include "mqtt/queue.h"
 
 #include "user_interface.h"
 #include "osapi.h"
 #include "os_type.h"
 #include "mem.h"
-#include "proto.h"
+#include "mqtt/proto.h"
 
 uint8_t *last_rb_p_r;
 uint8_t *last_rb_p_w;
@@ -47,7 +47,7 @@ void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize)
 int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len)
 {
   uint32_t ret;
-  
+
   last_rb_p_r = queue->rb.p_r;
   last_rb_p_w = queue->rb.p_w;
   last_fill_cnt = queue->rb.fill_cnt;

+ 1 - 1
mqtt/ringbuf.c

@@ -3,7 +3,7 @@
 *   Ring Buffer library
 */
 
-#include "ringbuf.h"
+#include "mqtt/ringbuf.h"
 
 
 /**

+ 1 - 2
mqtt/utils.c

@@ -35,7 +35,7 @@
 #include <ctype.h>
 #include <math.h>
 #include <stddef.h>
-#include "utils.h"
+#include "mqtt/utils.h"
 
 
 uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str)
@@ -146,4 +146,3 @@ uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s)
 
   return value;
 }
-

+ 50 - 8
user/user_main.c

@@ -50,9 +50,11 @@ static const char* TAG = "main.c";
 
 typedef struct {
     bool wifi_connected;
+    bool ideasX_connected;
     bool motion_detector;
 } system_config_t;
 
+
 static system_config_t system_config;
 
 void ICACHE_FLASH_ATTR imu_cb(IMU_Interrupt_et interrupt)
@@ -61,9 +63,10 @@ void ICACHE_FLASH_ATTR imu_cb(IMU_Interrupt_et interrupt)
     {
         case IMU_MOTION:
         {
-            system_config.motion_detector = false;
-            if (system_config.wifi_connected == false)
+            // the flag is hack because multiple significant motion interrupt are called
+            if (system_config.wifi_connected == false && system_config.motion_detector == true)
             {
+                system_config.motion_detector = false;
                 Encoder_DisableIOInterrupts();
                 Encoder_DisableMotion();
                 Light_AccessPointSearching();
@@ -78,15 +81,52 @@ void ICACHE_FLASH_ATTR imu_cb(IMU_Interrupt_et interrupt)
     }
 }
 
+void ICACHE_FLASH_ATTR switch_a_cb(void)
+{
+    if (system_config.wifi_connected == false)
+    {
+        system_config.motion_detector = false;
+        Encoder_DisableIOInterrupts();
+        Encoder_DisableMotion();
+        Light_AccessPointSearching();
+        WiFi_Connect(WIFI_TIMEOUT);
+    }
+}
+
+void ICACHE_FLASH_ATTR switch_b_cb(void)
+{
+    if (system_config.wifi_connected == false)
+    {
+        system_config.motion_detector = false;
+        Encoder_DisableIOInterrupts();
+        Encoder_DisableMotion();
+        Light_AccessPointSearching();
+        WiFi_Connect(WIFI_TIMEOUT);
+    }
+}
+
+void ICACHE_FLASH_ATTR ideasX_success_cb(void)
+{
+    Light_BrokerSuccess();
+}
+
+void ICACHE_FLASH_ATTR ideasX_fail_cb(void)
+{
+    Light_BrokerFailure();
+}
 
 void ICACHE_FLASH_ATTR wifi_success_cb(void)
 {
     system_config.wifi_connected = true;
+    Light_AccessPointConnected();
+    IdeasX_Connect();
+    //IdeasX_Init();
 }
 
 void ICACHE_FLASH_ATTR wifi_fail_cb(wifi_failure_et failure_code)
 {
     system_config.wifi_connected = false;
+    IdeasX_Disconnect();
 
     switch (failure_code)
     {
@@ -134,7 +174,7 @@ void ICACHE_FLASH_ATTR wifi_fail_cb(wifi_failure_et failure_code)
     }
 
     // re-enable motion detectors
-    system_config.motion_detector = true; 
+    system_config.motion_detector = true;
     Encoder_EnableMotion();
     Encoder_EnableIOInterrupts();
 }
@@ -148,21 +188,23 @@ void ICACHE_FLASH_ATTR wifi_fail_cb(wifi_failure_et failure_code)
 
 void user_init(void)
 {
-
-    uart_init(BIT_RATE_115200, BIT_RATE_115200, DISABLE_UART1); // this needs to be abstracted
+    Encoder_InitUART(BIT_RATE_115200, BIT_RATE_115200, DISABLE_UART1); // this needs to be abstracted
 
     os_printf("\n\n----------------------------------------------------------\n");
-    os_printf("\tIdeasX Encoder - Tyler Berezowsky\n");
+    os_printf("\tIdeasX Encoder - (curiousmuch.org)\n");
     os_printf("----------------------------------------------------------\n\n");
 
     // Intialize UART and Wi-Fi
     WiFi_Initialize();
+    IdeasX_Init();
     Encoder_InitIO();
     Encoder_DisableIOInterrupts();
-    IO_Shutdown();                       // set the shutdown pin for testing purporses
+    //IO_Shutdown();                       // set the shutdown pin for testing purporses
 
     WiFi_SetCallbacks(wifi_success_cb, wifi_fail_cb);
-    //Encoder_SetSwitchCallback(switch_a_cb, switch_b_cb);
+    IdeasX_SetStatusCallbacks(ideasX_success_cb, ideasX_fail_cb);
+    Encoder_SetSwitchCallback(switch_a_cb, switch_b_cb);
+    Encoder_DisableDebounceTimer();
     Encoder_SetIMUCallback(imu_cb);
 
     system_init_done_cb(app_init);

+ 0 - 1
util/config.c

@@ -105,7 +105,6 @@ void ICACHE_FLASH_ATTR cfg_load()
     if(sysCfg.cfg_holder != CFG_HOLDER){			// if sysCfg doesn't contain the proper check value
     os_memset(&sysCfg, 0x00, sizeof sysCfg);	// clear sysCfg
 
-
     sysCfg.cfg_holder = CFG_HOLDER;
 
     os_sprintf(sysCfg.sta_ssid[0], "%s", STA_SSID);				// load STA_SSID into sysCfg