Browse Source

re-wrote ws2812 driver

curiousmuch 6 years ago
parent
commit
a22d2ad355
9 changed files with 508 additions and 223 deletions
  1. 211 0
      hal/io.c
  2. 162 141
      hal/ws2812.c
  3. 1 0
      include/esp_common.h
  4. 38 0
      include/hal/io.h
  5. 1 1
      include/hal/lps25hb.h
  6. 45 10
      include/hal/ws2812.h
  7. 2 46
      include/util/wifi.h
  8. 1 1
      interface/uart_interface.c
  9. 47 24
      user/user_main.c

+ 211 - 0
hal/io.c

@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * IO Driver for IdeasX
+ * Author: curiousmuch
+ * Description: HAL layer for IdeasX v0.3.X encoders
+ * This lib has a couple functions
+ * 1) Provide SW interface for encoder hardware for the following functions:
+ *      reset, shutdown, enable / disable assistive switches
+ * 2) Provide the ability to attach custom ISR to assistive switch inputs
+      and INTR pin on LSM6DS3.
+ * Todo:
+*******************************************************************************/
+
+#include "hal/io.h"
+
+// debounce timers
+static Encoder_Timer_t encoder_timer;
+
+void ICACHE_FLASH_ATTR Encoder_InitIO(uint32_t debounce_delay, switch_function_t
+    switch_a_cb, switch_function_t switch_b_cb, switch_function_t imu_cb)
+{
+    ETS_GPIO_INTR_DISABLE();
+    gpio_init();
+
+    // setup as GPIO pins
+    PIN_FUNC_SELECT(LDO_SHUTDOWN_MUX, LDO_SHUTDOWN_FUNC);
+    PIN_FUNC_SELECT(SWITCH_A_MUX, SWITCH_A_FUNC);
+    PIN_FUNC_SELECT(SWITCH_B_MUX, SWITCH_B_FUNC);
+    PIN_FUNC_SELECT(STATUS_LED_MUX, STATUS_LED_FUNC);
+
+    // setup GPIO states
+    gpio_output_set(BIT(LDO_SHUTDOWN), BIT(STATUS_LED), (BIT(LDO_SHUTDOWN)|BIT(STATUS_LED)), (BIT(SWITCH_A)|BIT(SWITCH_B)));
+
+    // attach interrupts to switchs
+    gpio_pin_intr_state_set(GPIO_ID_PIN(SWTICH_A), GPIO_PIN_INTR_ANYEDGE);
+    gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);
+
+    os_timer_disarm(&encoder_timer.switch_a);
+    os_timer_disarm(&encoder_timer.switch_b);
+
+    os_timer_setfn(&timerA, (os_timer_func_t *)switchA_debounce, NULL);
+    os_timer_setfn(&timerB, (os_timer_func_t *)switchB_debounce, NULL);
+    ETS_GPIO_INTR_ENABLE();
+    return;
+}
+
+ void ICACHE_FLASH_ATTR Encoder_EnableAdaptiveSwitches(void)
+ {
+     gpio_pin_intr_state_set(GPIO_ID_PIN(SWTICH_A), GPIO_PIN_INTR_ANYEDGE);
+     gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);
+
+ }
+
+ void ICACHE_FLASH_ATTR Encoder_DisableAdaptiveSwitches(void)
+ {
+     gpio_pin_intr_state_set(GPIO_ID_PIN(SWTICH_A), GPIO_PIN_INTR_DISABLE);
+     gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_DISABLE);
+ }
+
+void ICACHE_FLASH_ATTR Encoder_ShutDown(void)
+{
+    GPIO_OUTPUT_SET(LDO_SHUTDOWN, 0);
+}
+
+void ICACHE_FLASH_ATTR Encoder_Restart(void)
+{
+    return;
+}
+
+void ICACHE_FLASH_ATTR Encoder_GPIO_Handler(void)
+{
+	uint8_t i;
+	uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);						// read interupt status of pins
+	uint32_t gpio_states = GPIO_REG_READ(GPIO_IN_ADDRESS);							// read pin status
+
+	ETS_GPIO_INTR_DISABLE();														// disable GPIO interrupts
+
+	for (i=0;i<GPIO_PIN_COUNT;i++)
+	{
+		if (BIT(i) & gpio_status)
+		{
+			gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_DISABLE);			// disable interrupt for pin
+			GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(i));			// clear interrupt status
+			#if MODULE_IO_DEBUG
+				os_printf("GPIO: Pin %d Interrupt\r\n", i);
+			#endif
+			switch(i)
+			{
+				case PBA: {
+					//os_printf("I'm here!\r\n");
+					if (sysCfg.module_state.connected == true) 								// if module is connected to Wi-Fi
+					{
+
+						uint8_t fifoFlags;
+						fifoFlags = lsm6ds3_fifo_getFlags();
+						os_printf("LSM6DS3: FIFO Flags %x\r\n", fifoFlags);
+						if (fifoFlags & (LSM6DS3_FIFO_OVER_RUN | LSM6DS3_FIFO_FULL ) )
+						{
+							os_printf("LSM6DS3: FIFO Full / Overrun\r\n");
+							lsm6ds3_reset();
+
+							os_printf("LSM6DS3: Reset IMU\r\n");
+							gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);		// re-enable pin interrupt
+
+							// shutdown LSM6DS3
+							// set error flag in health message
+						}
+						else if (fifoFlags & LSM6DS3_FIFO_THRESHOLD)
+						{
+							os_printf("LSM6DS3: FIFO Threshold\r\n");
+							publish_fifo_dump();
+							gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);		// re-enable pin interrupt
+
+						}
+						else if (fifoFlags & LSM6DS3_FIFO_EMPTY)
+						{
+							os_printf("LSM6DS3: FIFO Empty\r\n");
+							gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);		// re-enable pin interrupt
+
+						}
+						else
+						{
+							os_timer_arm(&pba_timer, DEBOUNCEDELAY, 0);	// arm SW timer
+						}
+
+					}
+					else if (sysCfg.module_state.connected == false && sysCfg.module_state.asleep == true)
+					{
+						sysCfg.module_state.asleep = false;									// indicate module is now awake
+						/*
+
+						 *	MODULE NEEDS TO WAKE FROM SLEEP HERE IF PLACED TO SLEEP BY WI-FI PROCESS
+
+						 */
+						lsm6ds3_read_motion();												// clear LSM6DS3 interrupt
+						start_wifi_process();												// start Wi-Fi process
+						gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);		// re-enable pin interrupt
+					}
+					else
+					{
+						//os_printf("WHY ARE WE HERE!!!!\r\n");
+						lsm6ds3_read_motion();
+						gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);		// re-enable pin interrupt
+
+					}
+					break;
+				}
+				case PBB: {
+					if (sysCfg.module_state.connected == true)								// if module is connected to Wi-Fi
+					{
+						os_timer_arm(&pbb_timer, DEBOUNCEDELAY, 0); 						// arm SW timer
+					}
+					else if (sysCfg.module_state.searching == false && sysCfg.module_state.connected == false && sysCfg.module_state.asleep == true)
+					{
+						sysCfg.module_state.asleep = false;									// indicate module is now awake
+						/*
+
+						 *	MODULE NEEDS TO WAKE FROM SLEEP HERE IF PLACED TO SLEEP BY WI-FI PROCESS
+
+						 */
+						start_wifi_process(); 												// start Wi-Fi process
+						gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE);		// re-enable pin interrupt
+					}
+					break;
+				}
+				default: {
+					#if MODULE_IO_DEBUG
+						os_printf("Help! Unknown Interrupt: %d\r\n", gpio_status);
+					#endif
+				}
+			}
+		}
+	}
+
+	/*
+
+		NOTE: This is slightly a hack. When the start_wifi_process function is called, it will disable I/O interrupts to insure
+		it is not called multiple times and schedule a Wi-Fi scan. The functions returns before the scan is started the following
+		line is called and therefore the LSM6DS3 is free to trigger the ISR multiple times on any motion. This line prevents this.
+		This could also be stopped by setting the INTS to INT2 when the first INT is called.
+	*/
+	if (sysCfg.module_state.searching == false)
+	{
+		ETS_GPIO_INTR_ENABLE();
+		os_printf("MODULE IO: I re-enabled interrupts..bitch.\r\n");
+	}
+}
+
+static void ICACHE_FLASH_ATTR switchA_debounce(void)
+{
+	ETS_GPIO_INTR_DISABLE();
+
+	uint32_t gpio_states = GPIO_REG_READ(GPIO_IN_ADDRESS);
+	//publish_button_state(gpio_states);
+	gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_ANYEDGE);
+	os_timer_disarm(&timerA);
+
+	ETS_GPIO_INTR_ENABLE();
+}
+
+
+static void ICACHE_FLASH_ATTR switchB_debounce(void)
+{
+	ETS_GPIO_INTR_DISABLE();
+
+	uint32_t gpio_states = GPIO_REG_READ(GPIO_IN_ADDRESS);
+	//publish_button_state(gpio_states);
+	gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);
+	os_timer_disarm(&timerB);
+
+	ETS_GPIO_INTR_ENABLE();
+}

+ 162 - 141
hal/ws2812.c

@@ -1,70 +1,29 @@
+/*******************************************************************************
+ * WS2812 Driver for IdeasX
+ * Author: curiousmuch
+ * Description: LED driver for v0.3.X encoder
+ * Todo: Improve pulse mode to use less CPU cycles and fluidity of cycle.
+*******************************************************************************/
+
 #include "hal/ws2812.h"
-#include "ets_sys.h"
-#include "osapi.h"
-#include "gpio.h"
-#include "math.h"
-
-#define LEDUPDATEDELAY 60
-
-//       	LOCAL const
-
-LOCAL uint8_t pulseBuffer[100] = { 127, 135, 143, 151, 159, 166, 174, 181, 188,
-								   195, 202, 208, 214, 220, 225, 230, 235, 239,
-								   242, 246, 248, 250, 252, 253, 254, 255, 254,
-								   253, 252, 250, 248, 246, 242, 239, 235, 230,
-								   225, 220, 214, 208, 202, 195, 188, 181, 174,
-								   166, 159, 151, 143, 135, 127, 119, 111, 103,
-								   95, 88, 80, 73, 66, 59, 52, 46, 40, 34, 29,
-								   24, 19, 15, 12, 8, 6, 4, 2, 1, 0, 0, 0, 1, 2,
-								   4, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52,
-								   59, 66, 73, 80, 88, 95, 103, 111, 119};
-
-
-// LOCAL uint8_t pulseBuffer[100] = { 50, 53, 56, 59, 62, 65, 68, 71,
-// 							  74, 76, 79, 81, 84, 86, 88, 90,
-// 							  92, 93, 95, 96, 97, 98, 99, 99,
-// 							  99, 100, 99, 99, 99, 98, 97, 96,
-// 							  95, 93, 92, 90, 88, 86, 84, 81,
-// 							  79, 76, 74, 71, 68, 65, 62, 59,
-// 							  56, 53, 50, 46, 43, 40, 37, 34,
-// 							  31, 28, 25, 23, 20, 18, 15, 13,
-// 							  11, 9, 7, 6, 4, 3, 2, 1, 0, 0,
-// 							  0, 0, 0, 0, 0, 1, 2, 3, 4, 6,
-// 							  7, 9, 11, 13, 15, 18, 20, 23,
-// 							  25, 28, 31, 34, 37, 40, 43, 46};
-
-// uint8_t pulseBuffer[100] = {68, 75, 83, 90, 99, 107, 116, 126,
-//  							135, 145, 155, 165, 175, 184, 194,
-//  							203, 212, 220, 228, 235, 240, 245,
-//  							249, 252, 254, 255, 254, 252, 249,
-//  							245, 240, 235, 228, 220, 212, 203,
-//  							194, 184, 175, 165, 155, 145, 135,
-//  							126, 116, 107, 99, 90, 83, 75, 68,
-//  							61, 55, 50, 44, 39, 35, 30, 27, 23,
-//  							20, 17, 14, 12, 10, 8, 6, 5, 3, 2,
-//  							2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2,
-//  							3, 5, 6, 8, 10, 12, 14, 17, 20, 23,
-//  							27, 30, 35, 39, 44, 50, 55, 61};
-// LOCAL uint8_t pulseBuffer[100] = {26, 29, 32, 35, 38, 42, 45, 49,
-// 								  53, 57, 60, 64, 68, 72, 76, 79,
-// 								  83, 86, 89, 92, 94, 96, 97, 99,
-// 								  99, 100, 99, 99, 97, 96, 94, 92,
-// 								  89, 86, 83, 79, 76, 72, 68, 64,
-// 								  60, 57, 53, 49, 45, 42, 38, 35,
-// 								  32, 29, 26, 24, 21, 19, 17, 15,
-// 								  13, 12, 10, 9, 7, 6, 5, 4, 4,
-// 								  3, 2, 2, 1, 1, 0, 0, 0, 0, 0,
-// 								  0, 0, 0, 0, 0, 0, 1, 1, 2, 2,
-// 								  3, 4, 4, 5, 6, 7, 9, 10, 12,
-// 								  13, 15, 17, 19, 21, 24};
-
-LOCAL uint8_t ledState;
-LOCAL os_timer_t statLEDTimer;
-
-
-//#define GPIO_OUTPUT_SET(gpio_no, bit_value)
-//	gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)
 
+static const char* TAG = "ws2812 driver";
+
+// static uint8_t pulseBuffer[100] = { 127, 135, 143, 151, 159, 166, 174, 181, 188,
+// 								   195, 202, 208, 214, 220, 225, 230, 235, 239,
+// 								   242, 246, 248, 250, 252, 253, 254, 255, 254,
+// 								   253, 252, 250, 248, 246, 242, 239, 235, 230,
+// 								   225, 220, 214, 208, 202, 195, 188, 181, 174,
+// 								   166, 159, 151, 143, 135, 127, 119, 111, 103,
+// 								   95, 88, 80, 73, 66, 59, 52, 46, 40, 34, 29,
+// 								   24, 19, 15, 12, 8, 6, 4, 2, 1, 0, 0, 0, 1, 2,
+// 								   4, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52,
+// 								   59, 66, 73, 80, 88, 95, 103, 111, 119};
+
+static os_timer_t ws2812_timer;
+static WS2812_CONFIG_t ws2812_config;
+static void ws2812_timer_cb(void);
+static  uint8_t init_buffer[3] = {0x00, 0x00, 0x00};
 
 static void send_ws_0(void)
 {
@@ -73,11 +32,8 @@ static void send_ws_0(void)
 	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 );
 #else
-	// time = 6; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
-	// time = 10; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
-	//os_printf("Hola\r\n");
-	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));
+	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));
 #endif
 }
 
@@ -88,77 +44,142 @@ static void send_ws_1(void)
 	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 );
 #else
-	// time = 10; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
-	// time = 6; 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));
-	//os_printf("Hermosa\r\n");
+
+	time = 5; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
+	time = 4; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
 #endif
 }
 
-// void ws2812_outBuffer( uint8_t * buffer, uint16_t length )
-// {
-// 	ETS_INTR_LOCK();							// why is this different than a normal disable interupts again?
-// 	uint16_t i;
-// 	GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);	// set gpio as output (redundent?)
-//
-//
-// 	for( i = 0; i < length; i++ )
-// 	{
-// 		uint8_t mask = 0x80;
-// 		uint8_t byte = buffer[i];
-// 		while (mask)
-// 		{
-// 			if( byte & mask ) send_ws_1(); else send_ws_0();
-// 			mask >>= 1;
-//         }
-// 	}
-//
-// 	ETS_INTR_LOCK();
-// }
-//
-// void updateLED(void)
-// {
-// 	uint8_t outBuffer[3] = {0, 0, 0};
-// 	uint8_t ledValue = pulseBuffer[ledState];
-//
-// 	if (sysCfg.module_state.searching == TRUE)
-// 	{
-// 		outBuffer[0] = ledValue;
-// 	}
-// 	else if (sysCfg.module_state.connected == TRUE)
-// 	{
-// 		outBuffer[2] = ledValue;
-// 	}
-// 	else
-// 	{
-// 		outBuffer[1] = ledValue;
-// 	}
-// 	ws2812_outBuffer(outBuffer, sizeof(outBuffer));
-// 	ledState++;
-// 	if (ledState == sizeof(pulseBuffer))
-// 		ledState = 0;
-// }
-//
-// void ws2812_shutdown(void)
-// {
-// 	os_timer_disarm(&statLEDTimer);
-// 	uint8_t i, outBuf[3] = {0x00, 0x00, 0x00};
-// 	for(i=0;i<6;i++)
-// 	{
-// 		outBuf[1] = outBuf[1] ^ 0xFF;
-// 		ws2812_outBuffer(outBuf, sizeof(outBuf));
-// 		os_delay_us(500000);
-// 	}
-// }
-//
-// void ws2812_init(void)
-// {
-// 	sin(0);
-// 	ledState = 0;
-// 	uint8_t initBuffer[3] = {0x00, 0x00, 0x00};
-// 	ws2812_outBuffer(initBuffer, sizeof(initBuffer));
-// 	os_timer_disarm(&statLEDTimer);												// disarm health publish timer
-// 	os_timer_setfn(&statLEDTimer, (os_timer_func_t *)updateLED, NULL);	// attach function for health publish
-// 	os_timer_arm(&statLEDTimer, LEDUPDATEDELAY, 1); 								// activate health packet timer
-// }
+void WS2812_OutBuffer(int8_t * buffer, uint16_t length)
+{
+	ETS_INTR_LOCK();							// why is this different than a normal disable interupts again?
+	uint16_t i;
+	GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);	// set gpio as output (redundent?)
+
+
+	for( i = 0; i < length; i++ )
+	{
+		uint8_t mask = 0x80;
+		uint8_t byte = buffer[i];
+		while (mask)
+		{
+			if( byte & mask ) send_ws_1(); else send_ws_0();
+			mask >>= 1;
+        }
+	}
+ 	ETS_INTR_UNLOCK();
+}
+
+void ICACHE_FLASH_ATTR WS2812_SetColor(WS2812_COLOR_et color, WS2812_PATTERN_et pattern)
+{
+	ws2812_config.color = color;			// store color
+	ws2812_config.pattern = pattern;		// store pattern
+	ws2812_config.led_state = 1; 			// reset led update timer state
+	ws2812_config.direction = WS2812_UP;	// set direction for pulse
+	os_timer_disarm(&ws2812_timer);			// disarm health publish timer
+
+	switch (ws2812_config.color)
+	{
+		case WS2812_OFF:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX]		= 0x00;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0x00;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0x00;
+			break;
+		}
+		case WS2812_RED:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX] 		= 0xFF;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0x00;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0x00;
+			break;
+		}
+		case WS2812_BLUE:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX] 		= 0x00;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0x00;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0xFF;
+			break;
+		}
+		case WS2812_GREEN:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX] 		= 0x00;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0xFF;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0x00;
+			break;
+		}
+		case WS2812_MAGENTA:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX] 		= 0xFF;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0x00;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0xFF;
+			break;
+		}
+		case WS2812_ORANGE:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX] 		= 0xFF;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0xA5;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0x00;
+			break;
+		}
+		default:
+		{
+			ws2812_config.color_mask[WS2812_RED_INDEX] 		= 0x00;
+			ws2812_config.color_mask[WS2812_GREEN_INDEX] 	= 0x00;
+			ws2812_config.color_mask[WS2812_BLUE_INDEX] 	= 0x00;
+			break;
+		}
+	}
+
+	switch (ws2812_config.pattern)
+	{
+		case(WS2812_SOLID):
+		{
+			//WS2812_OutBuffer(init_buffer, 3);
+			//os_delay_us(70);
+			WS2812_OutBuffer(ws2812_config.color_mask, 3);		//
+			break;
+		}
+		case(WS2812_PULSE):
+		{
+			os_timer_setfn(&ws2812_timer, (os_timer_func_t *)ws2812_timer_cb, NULL);
+			os_timer_arm(&ws2812_timer, WS2812_REFRESH_INTERVAL, 1);
+			break;
+		}
+		default:
+		{
+			break;
+		}
+	}
+	return;
+}
+
+void ws2812_timer_cb(void)
+{
+	// calculate color fade
+	uint8_t led_state = ws2812_config.led_state;
+	uint8_t tempBuffer[3] = {ws2812_config.color_mask[WS2812_GREEN_INDEX] / led_state,
+							 ws2812_config.color_mask[WS2812_RED_INDEX] / led_state,
+						 	 ws2812_config.color_mask[WS2812_BLUE_INDEX] / led_state};
+
+	// Debuging Information
+	//ESP_LOGV(TAG, "WS2812 Timer [led_state]: %d", ws2812_config.led_state);
+	//ESP_LOGV(TAG, "WS2812 Timer [tempBuffer] %d:%d:%d", tempBuffer[0], tempBuffer[1], tempBuffer[2]);
+
+	WS2812_OutBuffer(tempBuffer, 3);	// send color to LED
+
+	// increase / decrease scaling factor for LED color
+	if (ws2812_config.direction == WS2812_UP)
+	{
+		ws2812_config.led_state++;
+		if (ws2812_config.led_state == 50)
+			ws2812_config.direction = WS2812_DOWN;
+	}
+	else
+	{
+		ws2812_config.led_state--;
+		if (ws2812_config.led_state == 1)
+			ws2812_config.direction = WS2812_UP;
+	}
+
+}

+ 1 - 0
include/esp_common.h

@@ -13,5 +13,6 @@
 #include "user_interface.h"
 #include "mem.h"
 #include "osapi.h"
+#include "gpio.h"
 
 #endif

+ 38 - 0
include/hal/io.h

@@ -0,0 +1,38 @@
+#ifndef _IO_H
+#define _IO_H
+
+#include "esp_common.h"
+#include "driver/gpio16.h"
+
+#define STATUS_LED      0
+#define SWITCH_A        5
+#define SWITCH_B        2
+#define LDO_SHUTDOWN    4
+
+#define STATUS_LED_MUX      PERIPHS_IO_MUX_GPIO0_U
+#define SWITCH_A_MUX        PERIPHS_IO_MUX_GPIO5_U
+#define SWITCH_B_MUX        PERIPHS_IO_MUX_GPIO2_U
+#define LDO_SHUTDOWN_MUX    PERIPHS_IO_MUX_GPIO4_U
+
+#define STATUS_LED_FUNC     FUNC_GPIO0
+#define SWITCH_A_FUNC       FUNC_GPIO5
+#define SWITCH_B_FUNC       FUNC_GPIO2
+#define LDO_SHUTDOWN_FUNC   FUNC_GPIO4
+
+typedef void (* switch_function_t)(void);
+
+typedef struct {
+    os_timer_t switch_a;
+    os_timer_t switch_b;
+    switch_function_t switch_a_cb;
+    switch_function_t switch_b_cb;
+    switch_function_t imu_cb;
+    uint32_t debounce_delay; 
+} Encoder_Timer_t;
+
+
+void ICACHE_FLASH_ATTR Encoder_InitIO(void);
+void ICACHE_FLASH_ATTR Encoder_ShutDown(void);
+void ICACHE_FLASH_ATTR Encoder_Restart(void);
+
+#endif

+ 1 - 1
include/hal/lps25hb.h

@@ -178,7 +178,7 @@ typedef enum
  */
 typedef enum
 {
-  LPS25HB_PushPull = (uint8_t)0x00,
+LPS25HB_PushPull = (uint8_t)0x00,
 LPS25HB_OpenDrain  = (uint8_t)0x40
 }LPS25HB_OutputType_et;
 #define IS_LPS25HB_OutputType(MODE) ((MODE == LPS25HB_PushPull) || (MODE == LPS25HB_OpenDrain))

+ 45 - 10
include/hal/ws2812.h

@@ -7,29 +7,64 @@
 #include "user_interface.h"
 #include "ets_sys.h"
 #include "gpio.h"
+#include "ets_sys.h"
+#include "osapi.h"
+#include "math.h"
+#include "log/esp_log.h"
 
 /*------------------------------------------------------------------------------*/
-// Configuration Parameters 
+// Configuration Parameters
 /*------------------------------------------------------------------------------*/
-#define WS2811_COMPATIBLE 	0 	// set to make driver backwards compatable. 
+#define WS2811_COMPATIBLE 	0 	// set to make driver backwards compatable.
+#define WS2812_REFRESH_INTERVAL 60 // timer to update WS2812
+#define WS2812_RED_INDEX 1
+#define WS2812_GREEN_INDEX 0
+#define WS2812_BLUE_INDEX 2
+
+typedef enum {
+    WS2812_OFF = 0,
+    WS2812_RED,
+    WS2812_BLUE,
+    WS2812_GREEN,
+    WS2812_MAGENTA,
+    WS2812_ORANGE
+} WS2812_COLOR_et;
+
+typedef enum {
+    WS2812_SOLID = 0,
+    WS2812_PULSE
+} WS2812_PATTERN_et;
+
+typedef enum {
+    WS2812_UP = 0,
+    WS2812_DOWN
+} WS2812_DIRECTION_et;
+
+typedef struct {
+    WS2812_COLOR_et color;
+    WS2812_PATTERN_et pattern;
+    uint8_t  color_mask[3];
+    uint32_t led_state;
+    WS2812_DIRECTION_et direction;
+} WS2812_CONFIG_t;
 /*------------------------------------------------------------------------------*/
 //You will have to 	os_intr_lock();  	os_intr_unlock();
 
 
-/* 
+/*
 	NOTE: The first byte stored is the last byte sent. 50us is required for sent data to latch to all LEDS
-	Data is stored in the following format: 
+	Data is stored in the following format:
 	[ byte1: green, byte2: red, byte3: blue]
-	NOTE: Every function except ws2812_outBuffer is stored in Flash. 
+	NOTE: Every function except ws2812_outBuffer is stored in Flash.
 */
 /*------------------------------------------------------------------------------*/
 // Function Prototypes
 /*------------------------------------------------------------------------------*/
-void ws2812_outBuffer( uint8_t * buffer, uint16_t length );
-// void ws2812_green(void); 
-// void ws2812_red(void); 
-// void ws2812_blue(void); 
+void WS2812_OutBuffer(int8_t * buffer, uint16_t length);
+void WS2812_SetColor(WS2812_COLOR_et color, WS2812_PATTERN_et pattern);
+// void ws2812_green(void);
+// void ws2812_red(void);
+// void ws2812_blue(void);
 // void ws2812_clear(void);
 /*------------------------------------------------------------------------------*/
 #endif
-

+ 2 - 46
include/util/wifi.h

@@ -1,55 +1,11 @@
-// enum {
-// 	REASON_UNSPECIFIED              = 1,
-// 	REASON_AUTH_EXPIRE              = 2,
-// 	REASON_AUTH_LEAVE               = 3,
-// 	REASON_ASSOC_EXPIRE             = 4,
-// 	REASON_ASSOC_TOOMANY            = 5,
-// 	REASON_NOT_AUTHED               = 6,
-// 	REASON_NOT_ASSOCED              = 7,
-// 	REASON_ASSOC_LEAVE              = 8,
-// 	REASON_ASSOC_NOT_AUTHED         = 9,
-// 	REASON_DISASSOC_PWRCAP_BAD      = 10,  /* 11h */
-// 	REASON_DISASSOC_SUPCHAN_BAD     = 11,  /* 11h */
-// 	REASON_IE_INVALID               = 13,  /* 11i */
-// 	REASON_MIC_FAILURE              = 14,  /* 11i */
-// 	REASON_4WAY_HANDSHAKE_TIMEOUT   = 15,  /* 11i */
-// 	REASON_GROUP_KEY_UPDATE_TIMEOUT = 16,  /* 11i */
-// 	REASON_IE_IN_4WAY_DIFFERS       = 17,  /* 11i */
-// 	REASON_GROUP_CIPHER_INVALID     = 18,  /* 11i */
-// 	REASON_PAIRWISE_CIPHER_INVALID  = 19,  /* 11i */
-// 	REASON_AKMP_INVALID             = 20,  /* 11i */
-// 	REASON_UNSUPP_RSN_IE_VERSION    = 21,  /* 11i */
-// 	REASON_INVALID_RSN_IE_CAP       = 22,  /* 11i */
-// 	REASON_802_1X_AUTH_FAILED       = 23,  /* 11i */
-// 	REASON_CIPHER_SUITE_REJECTED    = 24,  /* 11i */
-
-// 	REASON_BEACON_TIMEOUT           = 200,
-// 	REASON_NO_AP_FOUND              = 201,
-// 	REASON_AUTH_FAIL				= 202,
-// 	REASON_ASSOC_FAIL				= 203,
-// 	REASON_HANDSHAKE_TIMEOUT		= 204,
-// };
-
-// enum {
-//     EVENT_STAMODE_CONNECTED = 0,
-//     EVENT_STAMODE_DISCONNECTED,
-//     EVENT_STAMODE_AUTHMODE_CHANGE,
-//     EVENT_STAMODE_GOT_IP,
-//     EVENT_STAMODE_DHCP_TIMEOUT,
-//     EVENT_SOFTAPMODE_STACONNECTED,
-// 	EVENT_SOFTAPMODE_STADISCONNECTED,
-// 	EVENT_SOFTAPMODE_PROBEREQRECVED,
-//     EVENT_MAX
-// };
-
 #ifndef USER_WIFI_H_
 #define USER_WIFI_H_
 #include "os_type.h"
 
 typedef struct{
-	bool 	ip_flag; 
+	bool 	ip_flag;
 	bool 	wifi_flag;
-	uint8_t wifi_count; 
+	uint8_t wifi_count;
 	uint8_t process_count;
 } WIFI_PROCESS_FLAGS;
 

+ 1 - 1
interface/uart_interface.c

@@ -102,7 +102,7 @@ static void show_info(void)
 
 void process_command(uint8_t *str)
 {
-    if (!strcmp(str, "AR+RST"))         // reset
+    if (!strcmp(str, "AT+RST"))         // reset
     {
         ESP_LOGI(TAG, "Manual Restarting...\n");
 		system_restart();

+ 47 - 24
user/user_main.c

@@ -39,33 +39,51 @@
 #include "hal/lsm6ds3.h"
 #include "hal/max17043.h"
 #include "hal/lps25hb.h"
+#include "hal/ws2812.h"
 
 #include "user_config.h"
 
 static const char* TAG = "main.c";
 
-void wifi_handle_event_cb(System_Event_t *evt)
-{
-    switch(evt->event)
-    {
-      case EVENT_STAMODE_CONNECTED:
-        break;
-      case EVENT_STAMODE_DISCONNECTED:
-        break;
-      case EVENT_STAMODE_AUTHMODE_CHANGE:
-        break;
-      case EVENT_STAMODE_GOT_IP:
-        break;
-      case EVENT_SOFTAPMODE_PROBEREQRECVED:
-        break;
-      case EVENT_SOFTAPMODE_STACONNECTED:
-        break;
-      case EVENT_SOFTAPMODE_STADISCONNECTED:
-        break;
-      default:
-        break;
-    }
-}
+// void wifi_handle_event_cb(System_Event_t *evt)
+// {
+//     switch(evt->event)
+//     {
+//       case EVENT_STAMODE_CONNECTED:
+//         break;
+//       case EVENT_STAMODE_DISCONNECTED:
+//         break;
+//       case EVENT_STAMODE_AUTHMODE_CHANGE:
+//         break;
+//       case EVENT_STAMODE_GOT_IP:
+//         break;
+//       case EVENT_SOFTAPMODE_PROBEREQRECVED:
+//         break;
+//       case EVENT_SOFTAPMODE_STACONNECTED:
+//         break;
+//       case EVENT_SOFTAPMODE_STADISCONNECTED:
+//         break;
+//       default:
+//         break;
+//     }
+// }
+
+#define DEBOUNCEDELAY 		10 		// ms
+
+#define SHDN_MUX 	PERIPHS_IO_MUX_GPIO4_U	// GPIO 4
+#define PBA_MUX	 	PERIPHS_IO_MUX_GPIO5_U	// GPIO 5
+#define PBB_MUX  	PERIPHS_IO_MUX_GPIO2_U	// GPIO 2
+#define STATLED_MUX	PERIPHS_IO_MUX_GPIO2_U	// GPIO 0
+
+#define SHDN_FUNC		FUNC_GPIO4
+#define PBA_FUNC 		FUNC_GPIO5
+#define PBB_FUNC 		FUNC_GPIO2
+#define STATLED_FUNC 	FUNC_GPIO0
+
+#define SHDN 		4
+#define PBA 		5
+#define PBB 		2
+#define STATLED		0
 
  void ICACHE_FLASH_ATTR app_init(void)
 {
@@ -84,12 +102,17 @@ void wifi_handle_event_cb(System_Event_t *evt)
         // uint8_t i;
         // for(i=0;i<8;i++)
         //     ESP_LOGI(TAG, "RX SPI Value: %x", data[i]);
-        os_delay_us(1000000);
+        //os_delay_us(1000000);
         system_soft_wdt_feed();
     }
 
-
+    //while(true)
     {
+        ESP_LOGI(TAG, "Setting WS2812B");
+        PIN_FUNC_SELECT(STATLED_MUX, STATLED_FUNC);
+        gpio_output_set(BIT(SHDN), BIT(STATLED), (BIT(SHDN)|BIT(STATLED)), (BIT(PBA)|BIT(PBB)));
+
+        WS2812_SetColor(WS2812_ORANGE, WS2812_PULSE);
 
     }