Commit a6c0873a authored by Johny Mattsson's avatar Johny Mattsson
Browse files

Upgrade to SDK 1.5.0 + Espressif's Open LWIP 1.5.0.

Removed earlier TCP port randomisation fix - the new SDK has its own fix
even though Espressif told me they wouldn't fix it. Yay?
parent 1462d00e
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_json.c
*
* Description: JSON format set up and parse.
* Check your hardware transmation while use this data format.
*
* Modification history:
* 2014/5/09, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "os_type.h"
#include "mem.h"
#include "user_json.h"
LOCAL char *json_buf;
LOCAL int pos;
LOCAL int size;
/******************************************************************************
* FunctionName : find_json_path
* Description : find the JSON format tree's path
* Parameters : json -- A pointer to a JSON set up
* path -- A pointer to the JSON format tree's path
* Returns : A pointer to the JSON format tree
*******************************************************************************/
struct jsontree_value *ICACHE_FLASH_ATTR
find_json_path(struct jsontree_context *json, const char *path)
{
struct jsontree_value *v;
const char *start;
const char *end;
int len;
v = json->values[0];
start = path;
do {
end = (const char *)os_strstr(start, "/");
if (end == start) {
break;
}
if (end != NULL) {
len = end - start;
end++;
} else {
len = os_strlen(start);
}
if (v->type != JSON_TYPE_OBJECT) {
v = NULL;
} else {
struct jsontree_object *o;
int i;
o = (struct jsontree_object *)v;
v = NULL;
for (i = 0; i < o->count; i++) {
if (os_strncmp(start, o->pairs[i].name, len) == 0) {
v = o->pairs[i].value;
json->index[json->depth] = i;
json->depth++;
json->values[json->depth] = v;
json->index[json->depth] = 0;
break;
}
}
}
start = end;
} while (end != NULL && *end != '\0' && v != NULL);
json->callback_state = 0;
return v;
}
/******************************************************************************
* FunctionName : json_putchar
* Description : write the value to the JSON format tree
* Parameters : c -- the value which write the JSON format tree
* Returns : result
*******************************************************************************/
int ICACHE_FLASH_ATTR
json_putchar(int c)
{
if (json_buf != NULL && pos <= size) {
json_buf[pos++] = c;
return c;
}
return 0;
}
/******************************************************************************
* FunctionName : json_ws_send
* Description : set up the JSON format tree for string
* Parameters : tree -- A pointer to the JSON format tree
* path -- A pointer to the JSON format tree's path
* pbuf -- A pointer for the data sent
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
json_ws_send(struct jsontree_value *tree, const char *path, char *pbuf)
{
struct jsontree_context json;
/* maxsize = 128 bytes */
json_buf = (char *)os_malloc(jsonSize);
/* reset state and set max-size */
/* NOTE: packet will be truncated at 512 bytes */
pos = 0;
size = jsonSize;
json.values[0] = (struct jsontree_value *)tree;
jsontree_reset(&json);
find_json_path(&json, path);
json.path = json.depth;
json.putchar = json_putchar;
while (jsontree_print_next(&json) && json.path <= json.depth);
json_buf[pos] = 0;
os_memcpy(pbuf, json_buf, pos);
os_free(json_buf);
}
/******************************************************************************
* FunctionName : json_parse
* Description : parse the data as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* ptrJSONMessage -- A pointer to the data
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
json_parse(struct jsontree_context *json, char *ptrJSONMessage)
{
/* Set value */
struct jsontree_value *v;
struct jsontree_callback *c;
struct jsontree_callback *c_bak = NULL;
while ((v = jsontree_find_next(json, JSON_TYPE_CALLBACK)) != NULL) {
c = (struct jsontree_callback *)v;
if (c == c_bak) {
continue;
}
c_bak = c;
if (c->set != NULL) {
struct jsonparse_state js;
jsonparse_setup(&js, ptrJSONMessage, os_strlen(ptrJSONMessage));
c->set(json, &js);
}
}
}
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_light.c
*
* Description: light demo's function realization
*
* Modification history:
* 2014/5/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "os_type.h"
#include "mem.h"
#include "user_interface.h"
#include "user_light.h"
#include "pwm.h"
#if LIGHT_DEVICE
struct light_saved_param light_param;
/******************************************************************************
* FunctionName : user_light_get_duty
* Description : get duty of each channel
* Parameters : uint8 channel : LIGHT_RED/LIGHT_GREEN/LIGHT_BLUE
* Returns : NONE
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR
user_light_get_duty(uint8 channel)
{
return light_param.pwm_duty[channel];
}
/******************************************************************************
* FunctionName : user_light_set_duty
* Description : set each channel's duty params
* Parameters : uint8 duty : 0 ~ PWM_DEPTH
* uint8 channel : LIGHT_RED/LIGHT_GREEN/LIGHT_BLUE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_light_set_duty(uint32 duty, uint8 channel)
{
if (duty != light_param.pwm_duty[channel]) {
pwm_set_duty(duty, channel);
light_param.pwm_duty[channel] = pwm_get_duty(channel);
}
}
/******************************************************************************
* FunctionName : user_light_get_period
* Description : get pwm period
* Parameters : NONE
* Returns : uint32 : pwm period
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR
user_light_get_period(void)
{
return light_param.pwm_period;
}
/******************************************************************************
* FunctionName : user_light_set_duty
* Description : set pwm frequency
* Parameters : uint16 freq : 100hz typically
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_light_set_period(uint32 period)
{
if (period != light_param.pwm_period) {
pwm_set_period(period);
light_param.pwm_period = pwm_get_period();
}
}
void ICACHE_FLASH_ATTR
user_light_restart(void)
{
spi_flash_erase_sector(PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE);
spi_flash_write((PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE) * SPI_FLASH_SEC_SIZE,
(uint32 *)&light_param, sizeof(struct light_saved_param));
pwm_start();
}
/******************************************************************************
* FunctionName : user_light_init
* Description : light demo init, mainy init pwm
* Parameters : none
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_light_init(void)
{
spi_flash_read((PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE) * SPI_FLASH_SEC_SIZE,
(uint32 *)&light_param, sizeof(struct light_saved_param));
if(light_param.pwm_period>10000 || light_param.pwm_period <1000){
light_param.pwm_period = 1000;
}
uint32 io_info[][3] = { {PWM_0_OUT_IO_MUX,PWM_0_OUT_IO_FUNC,PWM_0_OUT_IO_NUM},
{PWM_1_OUT_IO_MUX,PWM_1_OUT_IO_FUNC,PWM_1_OUT_IO_NUM},
{PWM_2_OUT_IO_MUX,PWM_2_OUT_IO_FUNC,PWM_2_OUT_IO_NUM},
{PWM_3_OUT_IO_MUX,PWM_3_OUT_IO_FUNC,PWM_3_OUT_IO_NUM},
{PWM_4_OUT_IO_MUX,PWM_4_OUT_IO_FUNC,PWM_4_OUT_IO_NUM},
};
uint32 pwm_duty_init[PWM_CHANNEL] = {0};
/*PIN FUNCTION INIT FOR PWM OUTPUT*/
pwm_init(light_param.pwm_period, pwm_duty_init ,PWM_CHANNEL,io_info);
os_printf("LIGHT PARAM: R: %d \r\n",light_param.pwm_duty[LIGHT_RED]);
os_printf("LIGHT PARAM: G: %d \r\n",light_param.pwm_duty[LIGHT_GREEN]);
os_printf("LIGHT PARAM: B: %d \r\n",light_param.pwm_duty[LIGHT_BLUE]);
if(PWM_CHANNEL>LIGHT_COLD_WHITE){
os_printf("LIGHT PARAM: CW: %d \r\n",light_param.pwm_duty[LIGHT_COLD_WHITE]);
os_printf("LIGHT PARAM: WW: %d \r\n",light_param.pwm_duty[LIGHT_WARM_WHITE]);
}
os_printf("LIGHT PARAM: P: %d \r\n",light_param.pwm_period);
uint32 light_init_target[8]={0};
os_memcpy(light_init_target,light_param.pwm_duty,sizeof(light_param.pwm_duty));
light_set_aim(
light_init_target[LIGHT_RED],
light_init_target[LIGHT_GREEN],
light_init_target[LIGHT_BLUE],
light_init_target[LIGHT_COLD_WHITE],
light_init_target[LIGHT_WARM_WHITE],
light_param.pwm_period);
set_pwm_debug_en(0);//disable debug print in pwm driver
os_printf("PWM version : %08x \r\n",get_pwm_version());
}
#endif
#include "ets_sys.h"
#include "osapi.h"
#include "os_type.h"
#include "mem.h"
#include "user_interface.h"
#include "user_light.h"
#include "user_light_adj.h"
#include "pwm.h"
#define ABS_MINUS(x,y) (x<y?(y-x):(x-y))
uint8 light_sleep_flg = 0;
uint16 min_ms = 15;
uint32 current_duty[PWM_CHANNEL] = {0};
bool change_finish=true;
os_timer_t timer_pwm_adj;
static u32 duty_now[PWM_CHANNEL] = {0};
//-----------------------------------Light para storage---------------------------
#define LIGHT_EVT_QNUM (40)
static struct pwm_param LightEvtArr[LIGHT_EVT_QNUM];
static u8 CurFreeLightEvtIdx = 0;
static u8 TotalUsedLightEvtNum = 0;
static u8 CurEvtIdxToBeUse = 0;
static struct pwm_param *LightEvtMalloc(void)
{
struct pwm_param *tmp = NULL;
TotalUsedLightEvtNum++;
if(TotalUsedLightEvtNum > LIGHT_EVT_QNUM ){
TotalUsedLightEvtNum--;
}
else{
tmp = &(LightEvtArr[CurFreeLightEvtIdx]);
CurFreeLightEvtIdx++;
if( CurFreeLightEvtIdx > (LIGHT_EVT_QNUM-1) )
CurFreeLightEvtIdx = 0;
}
os_printf("malloc:%u\n",TotalUsedLightEvtNum);
return tmp;
}
static void ICACHE_FLASH_ATTR LightEvtFree(void)
{
TotalUsedLightEvtNum--;
os_printf("free:%u\n",TotalUsedLightEvtNum);
}
//------------------------------------------------------------------------------------
static void ICACHE_FLASH_ATTR light_pwm_smooth_adj_proc(void);
void ICACHE_FLASH_ATTR
light_save_target_duty()
{
extern struct light_saved_param light_param;
os_memcpy(light_param.pwm_duty,current_duty,sizeof(light_param.pwm_duty));
light_param.pwm_period = pwm_get_period();
#if SAVE_LIGHT_PARAM
spi_flash_erase_sector(PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE);
spi_flash_write((PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE) * SPI_FLASH_SEC_SIZE,
(uint32 *)&light_param, sizeof(struct light_saved_param));
#endif
}
void ICACHE_FLASH_ATTR
light_set_aim_r(uint32 r)
{
current_duty[LIGHT_RED]=r;
light_pwm_smooth_adj_proc();
}
void ICACHE_FLASH_ATTR
light_set_aim_g(uint32 g)
{
current_duty[LIGHT_GREEN]=g;
light_pwm_smooth_adj_proc();
}
void ICACHE_FLASH_ATTR
light_set_aim_b(uint32 b)
{
current_duty[LIGHT_BLUE]=b;
light_pwm_smooth_adj_proc();
}
void ICACHE_FLASH_ATTR
light_set_aim_cw(uint32 cw)
{
current_duty[LIGHT_COLD_WHITE]=cw;
light_pwm_smooth_adj_proc();
}
void ICACHE_FLASH_ATTR
light_set_aim_ww(uint32 ww)
{
current_duty[LIGHT_WARM_WHITE]=ww;
light_pwm_smooth_adj_proc();
}
LOCAL bool ICACHE_FLASH_ATTR
check_pwm_current_duty_diff()
{
int i;
for(i=0;i<PWM_CHANNEL;i++){
if(pwm_get_duty(i) != current_duty[i]){
return true;
}
}
return false;
}
void light_dh_pwm_adj_proc(void *Targ)
{
uint8 i;
for(i=0;i<PWM_CHANNEL;i++){
duty_now[i] = (duty_now[i]*15 + current_duty[i])>>4;
if( ABS_MINUS(duty_now[i],current_duty[i])<20 )
duty_now[i] = current_duty[i];
user_light_set_duty(duty_now[i],i);
}
//os_printf("duty:%u,%u,%u\r\n", pwm.duty[0],pwm.duty[1],pwm.duty[2] );
pwm_start();
if(check_pwm_current_duty_diff()){
change_finish = 0;
os_timer_disarm(&timer_pwm_adj);
os_timer_setfn(&timer_pwm_adj, (os_timer_func_t *)light_dh_pwm_adj_proc, NULL);
os_timer_arm(&timer_pwm_adj, min_ms, 0);
}
else{
os_printf("finish\n");
change_finish = 1;
//light_save_target_duty();
os_timer_disarm(&timer_pwm_adj);
light_pwm_smooth_adj_proc();
}
}
LOCAL bool ICACHE_FLASH_ATTR
check_pwm_duty_zero()
{
int i;
for(i=0;i<PWM_CHANNEL;i++){
if(pwm_get_duty(i) != 0){
return false;
}
}
return true;
}
static void ICACHE_FLASH_ATTR light_pwm_smooth_adj_proc(void)
{
if( TotalUsedLightEvtNum>0 ){
user_light_set_period( LightEvtArr[CurEvtIdxToBeUse].period );
os_memcpy(current_duty,LightEvtArr[CurEvtIdxToBeUse].duty,sizeof(current_duty));
CurEvtIdxToBeUse++;
if(CurEvtIdxToBeUse > (LIGHT_EVT_QNUM-1) ){
CurEvtIdxToBeUse = 0;
}
LightEvtFree();
if(change_finish){
light_dh_pwm_adj_proc(NULL);
}
}
if(change_finish){
light_save_target_duty();
if(check_pwm_duty_zero()){
if(light_sleep_flg==0){
os_printf("light sleep en\r\n");
wifi_set_sleep_type(LIGHT_SLEEP_T);
light_sleep_flg = 1;
}
}
}
}
#if LIGHT_CURRENT_LIMIT
uint32 light_get_cur(uint32 duty , uint8 channel, uint32 period)
{
uint32 duty_max_limit = (period*1000/45);
uint32 duty_mapped = duty*22727/duty_max_limit;
switch(channel){
case LIGHT_RED :
if(duty_mapped>=0 && duty_mapped<23000){
return (duty_mapped*151000/22727);
}
break;
case LIGHT_GREEN:
if(duty_mapped>=0 && duty_mapped<23000){
return (duty_mapped*82000/22727);
}
break;
case LIGHT_BLUE:
if(duty_mapped>=0 && duty_mapped<23000){
return (duty_mapped*70000/22727);
}
break;
case LIGHT_COLD_WHITE:
case LIGHT_WARM_WHITE:
if(duty_mapped>=0 && duty_mapped<23000){
return (duty_mapped*115000/22727);
}
break;
default:
os_printf("CHANNEL ERROR IN GET_CUR\r\n");
break;
}
}
#endif
void ICACHE_FLASH_ATTR
light_set_aim(uint32 r,uint32 g,uint32 b,uint32 cw,uint32 ww,uint32 period)
{
struct pwm_param *tmp = LightEvtMalloc();
if(tmp != NULL){
tmp->period = (period<10000?period:10000);
uint32 duty_max_limit = (period*1000/45);
tmp->duty[LIGHT_RED] = (r<duty_max_limit?r:duty_max_limit);
tmp->duty[LIGHT_GREEN] = (g<duty_max_limit?g:duty_max_limit);
tmp->duty[LIGHT_BLUE] = (b<duty_max_limit?b:duty_max_limit);
tmp->duty[LIGHT_COLD_WHITE] = (cw<duty_max_limit?cw:duty_max_limit);
tmp->duty[LIGHT_WARM_WHITE] = (ww<duty_max_limit?ww:duty_max_limit);//chg
#if LIGHT_CURRENT_LIMIT
uint32 cur_r,cur_g,cur_b,cur_rgb;
//if(cw>0 || ww>0){
cur_r = light_get_cur(tmp->duty[LIGHT_RED] , LIGHT_RED, tmp->period);
cur_g = light_get_cur(tmp->duty[LIGHT_GREEN] , LIGHT_GREEN, tmp->period);
cur_b = light_get_cur(tmp->duty[LIGHT_BLUE] , LIGHT_BLUE, tmp->period);
cur_rgb = (cur_r+cur_g+cur_b);
//}
uint32 cur_cw = light_get_cur( tmp->duty[LIGHT_COLD_WHITE],LIGHT_COLD_WHITE, tmp->period);
uint32 cur_ww = light_get_cur( tmp->duty[LIGHT_WARM_WHITE],LIGHT_WARM_WHITE, tmp->period);
uint32 cur_remain,cur_mar;
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN);
cur_mar = LIGHT_CURRENT_MARGIN;
/*
if((cur_cw < 50000) || (cur_ww < 50000)){
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN);
cur_mar = LIGHT_CURRENT_MARGIN;
}else if((cur_cw < 99000) || (cur_ww < 99000)){
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN_L2);
cur_mar = LIGHT_CURRENT_MARGIN_L2;
}else{
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN_L3);
cur_mar = LIGHT_CURRENT_MARGIN_L2;
}
*/
/*
if((LIGHT_TOTAL_CURRENT_MAX-cur_rgb)>120){
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN);
cur_mar = LIGHT_CURRENT_MARGIN;
}else if((LIGHT_TOTAL_CURRENT_MAX-cur_rgb)>100){
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN_L2);
cur_mar = LIGHT_CURRENT_MARGIN_L2;
}else{
cur_remain = (LIGHT_TOTAL_CURRENT_MAX - cur_rgb -LIGHT_CURRENT_MARGIN_L3);
cur_mar = LIGHT_CURRENT_MARGIN_L2;
}
*/
os_printf("cur_remain: %d \r\n",cur_remain);
while((cur_cw+cur_ww) > cur_remain){
tmp->duty[LIGHT_COLD_WHITE] = tmp->duty[LIGHT_COLD_WHITE] * 9 / 10;
tmp->duty[LIGHT_WARM_WHITE] = tmp->duty[LIGHT_WARM_WHITE] * 9 / 10;
cur_cw = light_get_cur( tmp->duty[LIGHT_COLD_WHITE],LIGHT_COLD_WHITE, tmp->period);
cur_ww = light_get_cur( tmp->duty[LIGHT_WARM_WHITE],LIGHT_WARM_WHITE, tmp->period);
}
os_printf("debug : %d %d %d %d %d\r\n",cur_r/1000,cur_g/1000,cur_b/1000,cur_cw/1000,cur_ww/1000);
os_printf("debug:total current after adj : %d + %d mA \r\n",(cur_cw+cur_ww+cur_r+cur_g+cur_b)/1000,cur_mar/1000);
#endif
os_printf("prd:%u r : %u g: %u b: %u cw: %u ww: %u \r\n",period,
tmp->duty[0],tmp->duty[1],tmp->duty[2],tmp->duty[3],tmp->duty[4]);
light_pwm_smooth_adj_proc();
}
else{
os_printf("light para full\n");
}
}
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_main.c
*
* Description: entry file of user application
*
* Modification history:
* 2014/1/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "user_devicefind.h"
#include "user_webserver.h"
#if ESP_PLATFORM
#include "user_esp_platform.h"
#endif
void user_rf_pre_init(void)
{
}
/******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
os_printf("SDK version:%s\n", system_get_sdk_version());
#if ESP_PLATFORM
/*Initialization of the peripheral drivers*/
/*For light demo , it is user_light_init();*/
/* Also check whether assigned ip addr by the router.If so, connect to ESP-server */
user_esp_platform_init();
#endif
/*Establish a udp socket to receive local device detect info.*/
/*Listen to the port 1025, as well as udp broadcast.
/*If receive a string of device_find_request, it rely its IP address and MAC.*/
user_devicefind_init();
/*Establish a TCP server for http(with JSON) POST or GET command to communicate with the device.*/
/*You can find the command in "2B-SDK-Espressif IoT Demo.pdf" to see the details.*/
/*the JSON command for curl is like:*/
/*3 Channel mode: curl -X POST -H "Content-Type:application/json" -d "{\"period\":1000,\"rgb\":{\"red\":16000,\"green\":16000,\"blue\":16000}}" http://192.168.4.1/config?command=light */
/*5 Channel mode: curl -X POST -H "Content-Type:application/json" -d "{\"period\":1000,\"rgb\":{\"red\":16000,\"green\":16000,\"blue\":16000,\"cwhite\":3000,\"wwhite\",3000}}" http://192.168.4.1/config?command=light */
#ifdef SERVER_SSL_ENABLE
user_webserver_init(SERVER_SSL_PORT);
#else
user_webserver_init(SERVER_PORT);
#endif
}
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_plug.c
*
* Description: plug demo's function realization
*
* Modification history:
* 2014/5/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "os_type.h"
#include "mem.h"
#include "user_interface.h"
#include "user_plug.h"
#if PLUG_DEVICE
LOCAL struct plug_saved_param plug_param;
LOCAL struct keys_param keys;
LOCAL struct single_key_param *single_key[PLUG_KEY_NUM];
LOCAL os_timer_t link_led_timer;
LOCAL uint8 link_led_level = 0;
/******************************************************************************
* FunctionName : user_plug_get_status
* Description : get plug's status, 0x00 or 0x01
* Parameters : none
* Returns : uint8 - plug's status
*******************************************************************************/
uint8 ICACHE_FLASH_ATTR
user_plug_get_status(void)
{
return plug_param.status;
}
/******************************************************************************
* FunctionName : user_plug_set_status
* Description : set plug's status, 0x00 or 0x01
* Parameters : uint8 - status
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_plug_set_status(bool status)
{
if (status != plug_param.status) {
if (status > 1) {
os_printf("error status input!\n");
return;
}
plug_param.status = status;
PLUG_STATUS_OUTPUT(PLUG_RELAY_LED_IO_NUM, status);
}
}
/******************************************************************************
* FunctionName : user_plug_short_press
* Description : key's short press function, needed to be installed
* Parameters : none
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_plug_short_press(void)
{
user_plug_set_status((~plug_param.status) & 0x01);
spi_flash_erase_sector(PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE);
spi_flash_write((PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE) * SPI_FLASH_SEC_SIZE,
(uint32 *)&plug_param, sizeof(struct plug_saved_param));
}
/******************************************************************************
* FunctionName : user_plug_long_press
* Description : key's long press function, needed to be installed
* Parameters : none
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_plug_long_press(void)
{
user_esp_platform_set_active(0);
system_restore();
system_restart();
}
LOCAL void ICACHE_FLASH_ATTR
user_link_led_init(void)
{
PIN_FUNC_SELECT(PLUG_LINK_LED_IO_MUX, PLUG_LINK_LED_IO_FUNC);
}
void ICACHE_FLASH_ATTR
user_link_led_output(uint8 level)
{
GPIO_OUTPUT_SET(GPIO_ID_PIN(PLUG_LINK_LED_IO_NUM), level);
}
LOCAL void ICACHE_FLASH_ATTR
user_link_led_timer_cb(void)
{
link_led_level = (~link_led_level) & 0x01;
GPIO_OUTPUT_SET(GPIO_ID_PIN(PLUG_LINK_LED_IO_NUM), link_led_level);
}
void ICACHE_FLASH_ATTR
user_link_led_timer_init(void)
{
os_timer_disarm(&link_led_timer);
os_timer_setfn(&link_led_timer, (os_timer_func_t *)user_link_led_timer_cb, NULL);
os_timer_arm(&link_led_timer, 50, 1);
link_led_level = 0;
GPIO_OUTPUT_SET(GPIO_ID_PIN(PLUG_LINK_LED_IO_NUM), link_led_level);
}
void ICACHE_FLASH_ATTR
user_link_led_timer_done(void)
{
os_timer_disarm(&link_led_timer);
GPIO_OUTPUT_SET(GPIO_ID_PIN(PLUG_LINK_LED_IO_NUM), 0);
}
/******************************************************************************
* FunctionName : user_plug_init
* Description : init plug's key function and relay output
* Parameters : none
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_plug_init(void)
{
user_link_led_init();
wifi_status_led_install(PLUG_WIFI_LED_IO_NUM, PLUG_WIFI_LED_IO_MUX, PLUG_WIFI_LED_IO_FUNC);
single_key[0] = key_init_single(PLUG_KEY_0_IO_NUM, PLUG_KEY_0_IO_MUX, PLUG_KEY_0_IO_FUNC,
user_plug_long_press, user_plug_short_press);
keys.key_num = PLUG_KEY_NUM;
keys.single_key = single_key;
key_init(&keys);
spi_flash_read((PRIV_PARAM_START_SEC + PRIV_PARAM_SAVE) * SPI_FLASH_SEC_SIZE,
(uint32 *)&plug_param, sizeof(struct plug_saved_param));
PIN_FUNC_SELECT(PLUG_RELAY_LED_IO_MUX, PLUG_RELAY_LED_IO_FUNC);
// no used SPI Flash
if (plug_param.status == 0xff) {
plug_param.status = 1;
}
PLUG_STATUS_OUTPUT(PLUG_RELAY_LED_IO_NUM, plug_param.status);
}
#endif
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_humiture.c
*
* Description: humiture demo's function realization
*
* Modification history:
* 2014/5/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "os_type.h"
#include "user_interface.h"
#if SENSOR_DEVICE
#include "user_sensor.h"
LOCAL struct keys_param keys;
LOCAL struct single_key_param *single_key[SENSOR_KEY_NUM];
LOCAL os_timer_t sensor_sleep_timer;
LOCAL os_timer_t link_led_timer;
LOCAL uint8 link_led_level = 0;
LOCAL uint32 link_start_time;
#if HUMITURE_SUB_DEVICE
#include "driver/i2c_master.h"
#define MVH3004_Addr 0x88
LOCAL uint8 humiture_data[4];
/******************************************************************************
* FunctionName : user_mvh3004_burst_read
* Description : burst read mvh3004's internal data
* Parameters : uint8 addr - mvh3004's address
* uint8 *pData - data point to put read data
* uint16 len - read length
* Returns : bool - true or false
*******************************************************************************/
LOCAL bool ICACHE_FLASH_ATTR
user_mvh3004_burst_read(uint8 addr, uint8 *pData, uint16 len)
{
uint8 ack;
uint16 i;
i2c_master_start();
i2c_master_writeByte(addr);
ack = i2c_master_getAck();
if (ack) {
os_printf("addr not ack when tx write cmd \n");
i2c_master_stop();
return false;
}
i2c_master_stop();
i2c_master_wait(40000);
i2c_master_start();
i2c_master_writeByte(addr + 1);
ack = i2c_master_getAck();
if (ack) {
os_printf("addr not ack when tx write cmd \n");
i2c_master_stop();
return false;
}
for (i = 0; i < len; i++) {
pData[i] = i2c_master_readByte();
i2c_master_setAck((i == (len - 1)) ? 1 : 0);
}
i2c_master_stop();
return true;
}
/******************************************************************************
* FunctionName : user_mvh3004_read_th
* Description : read mvh3004's humiture data
* Parameters : uint8 *data - where data to put
* Returns : bool - ture or false
*******************************************************************************/
bool ICACHE_FLASH_ATTR
user_mvh3004_read_th(uint8 *data)
{
return user_mvh3004_burst_read(MVH3004_Addr, data, 4);
}
/******************************************************************************
* FunctionName : user_mvh3004_init
* Description : init mvh3004, mainly i2c master gpio
* Parameters : none
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_mvh3004_init(void)
{
i2c_master_gpio_init();
}
uint8 *ICACHE_FLASH_ATTR
user_mvh3004_get_poweron_th(void)
{
return humiture_data;
}
#endif
/******************************************************************************
* FunctionName : user_humiture_long_press
* Description : humiture key's function, needed to be installed
* Parameters : none
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_sensor_long_press(void)
{
user_esp_platform_set_active(0);
system_restore();
system_restart();
}
LOCAL void ICACHE_FLASH_ATTR
user_link_led_init(void)
{
PIN_FUNC_SELECT(SENSOR_LINK_LED_IO_MUX, SENSOR_LINK_LED_IO_FUNC);
PIN_FUNC_SELECT(SENSOR_UNUSED_LED_IO_MUX, SENSOR_UNUSED_LED_IO_FUNC);
GPIO_OUTPUT_SET(GPIO_ID_PIN(SENSOR_UNUSED_LED_IO_NUM), 0);
}
void ICACHE_FLASH_ATTR
user_link_led_output(uint8 level)
{
GPIO_OUTPUT_SET(GPIO_ID_PIN(SENSOR_LINK_LED_IO_NUM), level);
}
LOCAL void ICACHE_FLASH_ATTR
user_link_led_timer_cb(void)
{
link_led_level = (~link_led_level) & 0x01;
GPIO_OUTPUT_SET(GPIO_ID_PIN(SENSOR_LINK_LED_IO_NUM), link_led_level);
}
void ICACHE_FLASH_ATTR
user_link_led_timer_init(void)
{
link_start_time = system_get_time();
os_timer_disarm(&link_led_timer);
os_timer_setfn(&link_led_timer, (os_timer_func_t *)user_link_led_timer_cb, NULL);
os_timer_arm(&link_led_timer, 50, 1);
link_led_level = 0;
GPIO_OUTPUT_SET(GPIO_ID_PIN(SENSOR_LINK_LED_IO_NUM), link_led_level);
}
void ICACHE_FLASH_ATTR
user_link_led_timer_done(void)
{
os_timer_disarm(&link_led_timer);
GPIO_OUTPUT_SET(GPIO_ID_PIN(SENSOR_LINK_LED_IO_NUM), 0);
}
void ICACHE_FLASH_ATTR
user_sensor_deep_sleep_enter(void)
{
system_deep_sleep(SENSOR_DEEP_SLEEP_TIME > link_start_time \
? SENSOR_DEEP_SLEEP_TIME - link_start_time : 30000000);
}
void ICACHE_FLASH_ATTR
user_sensor_deep_sleep_disable(void)
{
os_timer_disarm(&sensor_sleep_timer);
}
void ICACHE_FLASH_ATTR
user_sensor_deep_sleep_init(uint32 time)
{
os_timer_disarm(&sensor_sleep_timer);
os_timer_setfn(&sensor_sleep_timer, (os_timer_func_t *)user_sensor_deep_sleep_enter, NULL);
os_timer_arm(&sensor_sleep_timer, time, 0);
}
/******************************************************************************
* FunctionName : user_humiture_init
* Description : init humiture function, include key and mvh3004
* Parameters : none
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_sensor_init(uint8 active)
{
user_link_led_init();
wifi_status_led_install(SENSOR_WIFI_LED_IO_NUM, SENSOR_WIFI_LED_IO_MUX, SENSOR_WIFI_LED_IO_FUNC);
if (wifi_get_opmode() != SOFTAP_MODE) {
single_key[0] = key_init_single(SENSOR_KEY_IO_NUM, SENSOR_KEY_IO_MUX, SENSOR_KEY_IO_FUNC,
user_sensor_long_press, NULL);
keys.key_num = SENSOR_KEY_NUM;
keys.single_key = single_key;
key_init(&keys);
if (GPIO_INPUT_GET(GPIO_ID_PIN(SENSOR_KEY_IO_NUM)) == 0) {
user_sensor_long_press();
}
}
#if HUMITURE_SUB_DEVICE
user_mvh3004_init();
user_mvh3004_read_th(humiture_data);
#endif
#ifdef SENSOR_DEEP_SLEEP
if (wifi_get_opmode() != STATIONAP_MODE) {
if (active == 1) {
user_sensor_deep_sleep_init(SENSOR_DEEP_SLEEP_TIME / 1000 );
} else {
user_sensor_deep_sleep_init(SENSOR_DEEP_SLEEP_TIME / 1000 / 3 * 2);
}
}
#endif
}
#endif
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_webserver.c
*
* Description: The web server mode configration.
* Check your hardware connection with the host while use this mode.
* Modification history:
* 2014/3/12, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
#include "user_iot_version.h"
#include "espconn.h"
#include "user_json.h"
#include "user_webserver.h"
#include "upgrade.h"
#if ESP_PLATFORM
#include "user_esp_platform.h"
#endif
#ifdef SERVER_SSL_ENABLE
#include "ssl/cert.h"
#include "ssl/private_key.h"
#endif
#if LIGHT_DEVICE
#include "user_light.h"
#endif
LOCAL struct station_config *sta_conf;
LOCAL struct softap_config *ap_conf;
//LOCAL struct secrty_server_info *sec_server;
//LOCAL struct upgrade_server_info *server;
//struct lewei_login_info *login_info;
LOCAL scaninfo *pscaninfo;
struct bss_info *bss;
struct bss_info *bss_temp;
struct bss_info *bss_head;
extern u16 scannum;
LOCAL uint32 PostCmdNeeRsp = 1;
uint8 upgrade_lock = 0;
LOCAL os_timer_t app_upgrade_10s;
LOCAL os_timer_t upgrade_check_timer;
/******************************************************************************
* FunctionName : device_get
* Description : set up the device information parmer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
device_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
if (os_strncmp(path, "manufacture", 11) == 0) {
jsontree_write_string(js_ctx, "Espressif Systems");
} else if (os_strncmp(path, "product", 7) == 0) {
#if SENSOR_DEVICE
#if HUMITURE_SUB_DEVICE
jsontree_write_string(js_ctx, "Humiture");
#elif FLAMMABLE_GAS_SUB_DEVICE
jsontree_write_string(js_ctx, "Flammable Gas");
#endif
#endif
#if PLUG_DEVICE
jsontree_write_string(js_ctx, "Plug");
#endif
#if LIGHT_DEVICE
jsontree_write_string(js_ctx, "Light");
#endif
}
return 0;
}
LOCAL struct jsontree_callback device_callback =
JSONTREE_CALLBACK(device_get, NULL);
/******************************************************************************
* FunctionName : userbin_get
* Description : get up the user bin paramer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
userbin_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
char string[32];
if (os_strncmp(path, "status", 8) == 0) {
os_sprintf(string, "200");
} else if (os_strncmp(path, "user_bin", 8) == 0) {
if (system_upgrade_userbin_check() == 0x00) {
os_sprintf(string, "user1.bin");
} else if (system_upgrade_userbin_check() == 0x01) {
os_sprintf(string, "user2.bin");
} else{
return 0;
}
}
jsontree_write_string(js_ctx, string);
return 0;
}
LOCAL struct jsontree_callback userbin_callback =
JSONTREE_CALLBACK(userbin_get, NULL);
JSONTREE_OBJECT(userbin_tree,
JSONTREE_PAIR("status", &userbin_callback),
JSONTREE_PAIR("user_bin", &userbin_callback));
JSONTREE_OBJECT(userinfo_tree,JSONTREE_PAIR("user_info",&userbin_tree));
/******************************************************************************
* FunctionName : version_get
* Description : set up the device version paramer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
version_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
char string[32];
if (os_strncmp(path, "hardware", 8) == 0) {
#if SENSOR_DEVICE
os_sprintf(string, "0.3");
#else
os_sprintf(string, "0.1");
#endif
} else if (os_strncmp(path, "sdk_version", 11) == 0) {
os_sprintf(string, "%s", system_get_sdk_version());
} else if (os_strncmp(path, "iot_version", 11) == 0) {
os_sprintf(string,"%s%d.%d.%dt%d(%s)",VERSION_TYPE,IOT_VERSION_MAJOR,\
IOT_VERSION_MINOR,IOT_VERSION_REVISION,device_type,UPGRADE_FALG);
}
jsontree_write_string(js_ctx, string);
return 0;
}
LOCAL struct jsontree_callback version_callback =
JSONTREE_CALLBACK(version_get, NULL);
JSONTREE_OBJECT(device_tree,
JSONTREE_PAIR("product", &device_callback),
JSONTREE_PAIR("manufacturer", &device_callback));
JSONTREE_OBJECT(version_tree,
JSONTREE_PAIR("hardware", &version_callback),
JSONTREE_PAIR("sdk_version", &version_callback),
JSONTREE_PAIR("iot_version", &version_callback),
);
JSONTREE_OBJECT(info_tree,
JSONTREE_PAIR("Version", &version_tree),
JSONTREE_PAIR("Device", &device_tree));
JSONTREE_OBJECT(INFOTree,
JSONTREE_PAIR("info", &info_tree));
LOCAL int ICACHE_FLASH_ATTR
connect_status_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
if (os_strncmp(path, "status", 8) == 0) {
jsontree_write_int(js_ctx, user_esp_platform_get_connect_status());
}
return 0;
}
LOCAL struct jsontree_callback connect_status_callback =
JSONTREE_CALLBACK(connect_status_get, NULL);
JSONTREE_OBJECT(status_sub_tree,
JSONTREE_PAIR("status", &connect_status_callback));
JSONTREE_OBJECT(connect_status_tree,
JSONTREE_PAIR("Status", &status_sub_tree));
JSONTREE_OBJECT(con_status_tree,
JSONTREE_PAIR("info", &connect_status_tree));
#if PLUG_DEVICE
/******************************************************************************
* FunctionName : status_get
* Description : set up the device status as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
status_get(struct jsontree_context *js_ctx)
{
if (user_plug_get_status() == 1) {
jsontree_write_int(js_ctx, 1);
} else {
jsontree_write_int(js_ctx, 0);
}
return 0;
}
/******************************************************************************
* FunctionName : status_set
* Description : parse the device status parmer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* parser -- A pointer to a JSON parser state
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
status_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
while ((type = jsonparse_next(parser)) != 0) {
if (type == JSON_TYPE_PAIR_NAME) {
if (jsonparse_strcmp_value(parser, "status") == 0) {
uint8 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
user_plug_set_status(status);
}
}
}
return 0;
}
LOCAL struct jsontree_callback status_callback =
JSONTREE_CALLBACK(status_get, status_set);
JSONTREE_OBJECT(status_tree,
JSONTREE_PAIR("status", &status_callback));
JSONTREE_OBJECT(response_tree,
JSONTREE_PAIR("Response", &status_tree));
JSONTREE_OBJECT(StatusTree,
JSONTREE_PAIR("switch", &response_tree));
#endif
#if LIGHT_DEVICE
LOCAL int ICACHE_FLASH_ATTR
light_status_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
if (os_strncmp(path, "red", 3) == 0) {
jsontree_write_int(js_ctx, user_light_get_duty(LIGHT_RED));
} else if (os_strncmp(path, "green", 5) == 0) {
jsontree_write_int(js_ctx, user_light_get_duty(LIGHT_GREEN));
} else if (os_strncmp(path, "blue", 4) == 0) {
jsontree_write_int(js_ctx, user_light_get_duty(LIGHT_BLUE));
} else if (os_strncmp(path, "wwhite", 6) == 0) {
if(PWM_CHANNEL>LIGHT_WARM_WHITE){
jsontree_write_int(js_ctx, user_light_get_duty(LIGHT_WARM_WHITE));
}else{
jsontree_write_int(js_ctx, 0);
}
} else if (os_strncmp(path, "cwhite", 6) == 0) {
if(PWM_CHANNEL>LIGHT_COLD_WHITE){
jsontree_write_int(js_ctx, user_light_get_duty(LIGHT_COLD_WHITE));
}else{
jsontree_write_int(js_ctx, 0);
}
} else if (os_strncmp(path, "period", 6) == 0) {
jsontree_write_int(js_ctx, user_light_get_period());
}
return 0;
}
LOCAL int ICACHE_FLASH_ATTR
light_status_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
static uint32 r,g,b,cw,ww,period;
period = 1000;
cw=0;
ww=0;
extern uint8 light_sleep_flg;
while ((type = jsonparse_next(parser)) != 0) {
if (type == JSON_TYPE_PAIR_NAME) {
if (jsonparse_strcmp_value(parser, "red") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
r=status;
os_printf("R: %d \n",status);
//user_light_set_duty(status, LIGHT_RED);
//light_set_aim_r( r);
} else if (jsonparse_strcmp_value(parser, "green") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
g=status;
os_printf("G: %d \n",status);
//user_light_set_duty(status, LIGHT_GREEN);
//light_set_aim_g( g);
} else if (jsonparse_strcmp_value(parser, "blue") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
b=status;
os_printf("B: %d \n",status);
//user_light_set_duty(status, LIGHT_BLUE);
//set_aim_b( b);
} else if (jsonparse_strcmp_value(parser, "cwhite") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
cw=status;
os_printf("CW: %d \n",status);
//user_light_set_duty(status, LIGHT_BLUE);
//set_aim_b( b);
} else if (jsonparse_strcmp_value(parser, "wwhite") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
ww=status;
os_printf("WW: %d \n",status);
//user_light_set_duty(status, LIGHT_BLUE);
//set_aim_b( b);
} else if (jsonparse_strcmp_value(parser, "period") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
os_printf("PERIOD: %d \n",status);
period=status;
//user_light_set_period(status);
}else if (jsonparse_strcmp_value(parser, "response") == 0) {
uint32 status;
jsonparse_next(parser);
jsonparse_next(parser);
status = jsonparse_get_value_as_int(parser);
os_printf("rspneed: %d \n",status);
PostCmdNeeRsp = status;
}
}
}
if((r|g|b|ww|cw) == 0){
if(light_sleep_flg==0){
}
}else{
if(light_sleep_flg==1){
os_printf("modem sleep en\r\n");
wifi_set_sleep_type(MODEM_SLEEP_T);
light_sleep_flg =0;
}
}
light_set_aim(r,g,b,cw,ww,period);
return 0;
}
LOCAL struct jsontree_callback light_callback =
JSONTREE_CALLBACK(light_status_get, light_status_set);
JSONTREE_OBJECT(rgb_tree,
JSONTREE_PAIR("red", &light_callback),
JSONTREE_PAIR("green", &light_callback),
JSONTREE_PAIR("blue", &light_callback),
JSONTREE_PAIR("cwhite", &light_callback),
JSONTREE_PAIR("wwhite", &light_callback),
);
JSONTREE_OBJECT(sta_tree,
JSONTREE_PAIR("period", &light_callback),
JSONTREE_PAIR("rgb", &rgb_tree));
JSONTREE_OBJECT(PwmTree,
JSONTREE_PAIR("light", &sta_tree));
#endif
/******************************************************************************
* FunctionName : wifi_station_get
* Description : set up the station paramer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
wifi_station_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
struct ip_info ipconfig;
uint8 buf[20];
os_bzero(buf, sizeof(buf));
wifi_station_get_config(sta_conf);
wifi_get_ip_info(STATION_IF, &ipconfig);
if (os_strncmp(path, "ssid", 4) == 0) {
jsontree_write_string(js_ctx, sta_conf->ssid);
} else if (os_strncmp(path, "password", 8) == 0) {
jsontree_write_string(js_ctx, sta_conf->password);
} else if (os_strncmp(path, "ip", 2) == 0) {
os_sprintf(buf, IPSTR, IP2STR(&ipconfig.ip));
jsontree_write_string(js_ctx, buf);
} else if (os_strncmp(path, "mask", 4) == 0) {
os_sprintf(buf, IPSTR, IP2STR(&ipconfig.netmask));
jsontree_write_string(js_ctx, buf);
} else if (os_strncmp(path, "gw", 2) == 0) {
os_sprintf(buf, IPSTR, IP2STR(&ipconfig.gw));
jsontree_write_string(js_ctx, buf);
}
return 0;
}
/******************************************************************************
* FunctionName : wifi_station_set
* Description : parse the station parmer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* parser -- A pointer to a JSON parser state
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
wifi_station_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
uint8 station_tree;
while ((type = jsonparse_next(parser)) != 0) {
if (type == JSON_TYPE_PAIR_NAME) {
char buffer[64];
os_bzero(buffer, 64);
if (jsonparse_strcmp_value(parser, "Station") == 0) {
station_tree = 1;
} else if (jsonparse_strcmp_value(parser, "Softap") == 0) {
station_tree = 0;
}
if (station_tree) {
if (jsonparse_strcmp_value(parser, "ssid") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, buffer, sizeof(buffer));
os_memcpy(sta_conf->ssid, buffer, os_strlen(buffer));
} else if (jsonparse_strcmp_value(parser, "password") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, buffer, sizeof(buffer));
os_memcpy(sta_conf->password, buffer, os_strlen(buffer));
}
#if ESP_PLATFORM
else if (jsonparse_strcmp_value(parser, "token") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, buffer, sizeof(buffer));
user_esp_platform_set_token(buffer);
}
#endif
}
}
}
return 0;
}
LOCAL struct jsontree_callback wifi_station_callback =
JSONTREE_CALLBACK(wifi_station_get, wifi_station_set);
JSONTREE_OBJECT(get_station_config_tree,
JSONTREE_PAIR("ssid", &wifi_station_callback),
JSONTREE_PAIR("password", &wifi_station_callback));
JSONTREE_OBJECT(set_station_config_tree,
JSONTREE_PAIR("ssid", &wifi_station_callback),
JSONTREE_PAIR("password", &wifi_station_callback),
JSONTREE_PAIR("token", &wifi_station_callback));
JSONTREE_OBJECT(ip_tree,
JSONTREE_PAIR("ip", &wifi_station_callback),
JSONTREE_PAIR("mask", &wifi_station_callback),
JSONTREE_PAIR("gw", &wifi_station_callback));
JSONTREE_OBJECT(get_station_tree,
JSONTREE_PAIR("Connect_Station", &get_station_config_tree),
JSONTREE_PAIR("Ipinfo_Station", &ip_tree));
JSONTREE_OBJECT(set_station_tree,
JSONTREE_PAIR("Connect_Station", &set_station_config_tree));
//JSONTREE_OBJECT(get_wifi_station_info_tree,
// JSONTREE_PAIR("Station", &get_station_tree));
//JSONTREE_OBJECT(set_wifi_station_info_tree,
// JSONTREE_PAIR("station", &set_station_tree));
/******************************************************************************
* FunctionName : wifi_softap_get
* Description : set up the softap paramer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
wifi_softap_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
struct ip_info ipconfig;
uint8 buf[20];
os_bzero(buf, sizeof(buf));
wifi_softap_get_config(ap_conf);
wifi_get_ip_info(SOFTAP_IF, &ipconfig);
if (os_strncmp(path, "ssid", 4) == 0) {
jsontree_write_string(js_ctx, ap_conf->ssid);
} else if (os_strncmp(path, "password", 8) == 0) {
jsontree_write_string(js_ctx, ap_conf->password);
} else if (os_strncmp(path, "channel", 7) == 0) {
jsontree_write_int(js_ctx, ap_conf->channel);
} else if (os_strncmp(path, "authmode", 8) == 0) {
switch (ap_conf->authmode) {
case AUTH_OPEN:
jsontree_write_string(js_ctx, "OPEN");
break;
case AUTH_WEP:
jsontree_write_string(js_ctx, "WEP");
break;
case AUTH_WPA_PSK:
jsontree_write_string(js_ctx, "WPAPSK");
break;
case AUTH_WPA2_PSK:
jsontree_write_string(js_ctx, "WPA2PSK");
break;
case AUTH_WPA_WPA2_PSK:
jsontree_write_string(js_ctx, "WPAPSK/WPA2PSK");
break;
default :
jsontree_write_int(js_ctx, ap_conf->authmode);
break;
}
} else if (os_strncmp(path, "ip", 2) == 0) {
os_sprintf(buf, IPSTR, IP2STR(&ipconfig.ip));
jsontree_write_string(js_ctx, buf);
} else if (os_strncmp(path, "mask", 4) == 0) {
os_sprintf(buf, IPSTR, IP2STR(&ipconfig.netmask));
jsontree_write_string(js_ctx, buf);
} else if (os_strncmp(path, "gw", 2) == 0) {
os_sprintf(buf, IPSTR, IP2STR(&ipconfig.gw));
jsontree_write_string(js_ctx, buf);
}
return 0;
}
/******************************************************************************
* FunctionName : wifi_softap_set
* Description : parse the softap parmer as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* parser -- A pointer to a JSON parser state
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
wifi_softap_set(struct jsontree_context *js_ctx, struct jsonparse_state *parser)
{
int type;
uint8 softap_tree;
while ((type = jsonparse_next(parser)) != 0) {
if (type == JSON_TYPE_PAIR_NAME) {
char buffer[64];
os_bzero(buffer, 64);
if (jsonparse_strcmp_value(parser, "Station") == 0) {
softap_tree = 0;
} else if (jsonparse_strcmp_value(parser, "Softap") == 0) {
softap_tree = 1;
}
if (softap_tree) {
if (jsonparse_strcmp_value(parser, "authmode") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, buffer, sizeof(buffer));
// other mode will be supported later...
if (os_strcmp(buffer, "OPEN") == 0) {
ap_conf->authmode = AUTH_OPEN;
} else if (os_strcmp(buffer, "WPAPSK") == 0) {
ap_conf->authmode = AUTH_WPA_PSK;
os_printf("%d %s\n", ap_conf->authmode, buffer);
} else if (os_strcmp(buffer, "WPA2PSK") == 0) {
ap_conf->authmode = AUTH_WPA2_PSK;
} else if (os_strcmp(buffer, "WPAPSK/WPA2PSK") == 0) {
ap_conf->authmode = AUTH_WPA_WPA2_PSK;
} else {
ap_conf->authmode = AUTH_OPEN;
return 0;
}
}
if (jsonparse_strcmp_value(parser, "channel") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
ap_conf->channel = jsonparse_get_value_as_int(parser);
} else if (jsonparse_strcmp_value(parser, "ssid") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, buffer, sizeof(buffer));
os_memcpy(ap_conf->ssid, buffer, os_strlen(buffer));
} else if (jsonparse_strcmp_value(parser, "password") == 0) {
jsonparse_next(parser);
jsonparse_next(parser);
jsonparse_copy_value(parser, buffer, sizeof(buffer));
os_memcpy(ap_conf->password, buffer, os_strlen(buffer));
}
}
}
}
return 0;
}
LOCAL struct jsontree_callback wifi_softap_callback =
JSONTREE_CALLBACK(wifi_softap_get, wifi_softap_set);
JSONTREE_OBJECT(softap_config_tree,
JSONTREE_PAIR("authmode", &wifi_softap_callback),
JSONTREE_PAIR("channel", &wifi_softap_callback),
JSONTREE_PAIR("ssid", &wifi_softap_callback),
JSONTREE_PAIR("password", &wifi_softap_callback));
JSONTREE_OBJECT(softap_ip_tree,
JSONTREE_PAIR("ip", &wifi_softap_callback),
JSONTREE_PAIR("mask", &wifi_softap_callback),
JSONTREE_PAIR("gw", &wifi_softap_callback));
JSONTREE_OBJECT(get_softap_tree,
JSONTREE_PAIR("Connect_Softap", &softap_config_tree),
JSONTREE_PAIR("Ipinfo_Softap", &softap_ip_tree));
JSONTREE_OBJECT(set_softap_tree,
JSONTREE_PAIR("Ipinfo_Softap", &softap_config_tree));
JSONTREE_OBJECT(get_wifi_tree,
JSONTREE_PAIR("Station", &get_station_tree),
JSONTREE_PAIR("Softap", &get_softap_tree));
JSONTREE_OBJECT(set_wifi_tree,
JSONTREE_PAIR("Station", &set_station_tree),
JSONTREE_PAIR("Softap", &set_softap_tree));
JSONTREE_OBJECT(wifi_response_tree,
JSONTREE_PAIR("Response", &get_wifi_tree));
JSONTREE_OBJECT(wifi_request_tree,
JSONTREE_PAIR("Request", &set_wifi_tree));
JSONTREE_OBJECT(wifi_info_tree,
JSONTREE_PAIR("wifi", &wifi_response_tree));
JSONTREE_OBJECT(wifi_req_tree,
JSONTREE_PAIR("wifi", &wifi_request_tree));
/******************************************************************************
* FunctionName : scan_get
* Description : set up the scan data as a JSON format
* Parameters : js_ctx -- A pointer to a JSON set up
* Returns : result
*******************************************************************************/
LOCAL int ICACHE_FLASH_ATTR
scan_get(struct jsontree_context *js_ctx)
{
const char *path = jsontree_path_name(js_ctx, js_ctx->depth - 1);
// STAILQ_HEAD(, bss_info) *pbss = scanarg;
// LOCAL struct bss_info *bss;
if (os_strncmp(path, "TotalPage", 9) == 0) {
jsontree_write_int(js_ctx, pscaninfo->totalpage);
} else if (os_strncmp(path, "PageNum", 7) == 0) {
jsontree_write_int(js_ctx, pscaninfo->pagenum);
} else if (os_strncmp(path, "bssid", 5) == 0) {
if( bss == NULL )
bss = bss_head;
u8 buffer[32];
//if (bss != NULL){
os_memset(buffer, 0, sizeof(buffer));
os_sprintf(buffer, MACSTR, MAC2STR(bss->bssid));
jsontree_write_string(js_ctx, buffer);
//}
} else if (os_strncmp(path, "ssid", 4) == 0) {
//if (bss != NULL)
jsontree_write_string(js_ctx, bss->ssid);
} else if (os_strncmp(path, "rssi", 4) == 0) {
//if (bss != NULL)
jsontree_write_int(js_ctx, -(bss->rssi));
} else if (os_strncmp(path, "channel", 7) == 0) {
//if (bss != NULL)
jsontree_write_int(js_ctx, bss->channel);
} else if (os_strncmp(path, "authmode", 8) == 0) {
//if (bss != NULL){
switch (bss->authmode) {
case AUTH_OPEN:
jsontree_write_string(js_ctx, "OPEN");
break;
case AUTH_WEP:
jsontree_write_string(js_ctx, "WEP");
break;
case AUTH_WPA_PSK:
jsontree_write_string(js_ctx, "WPAPSK");
break;
case AUTH_WPA2_PSK:
jsontree_write_string(js_ctx, "WPA2PSK");
break;
case AUTH_WPA_WPA2_PSK:
jsontree_write_string(js_ctx, "WPAPSK/WPA2PSK");
break;
default :
jsontree_write_int(js_ctx, bss->authmode);
break;
}
bss = STAILQ_NEXT(bss, next);
// os_free(bss);
//}
}
return 0;
}
LOCAL struct jsontree_callback scan_callback =
JSONTREE_CALLBACK(scan_get, NULL);
JSONTREE_OBJECT(scaninfo_tree,
JSONTREE_PAIR("bssid", &scan_callback),
JSONTREE_PAIR("ssid", &scan_callback),
JSONTREE_PAIR("rssi", &scan_callback),
JSONTREE_PAIR("channel", &scan_callback),
JSONTREE_PAIR("authmode", &scan_callback));
JSONTREE_ARRAY(scanrslt_tree,
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree),
JSONTREE_PAIR_ARRAY(&scaninfo_tree));
JSONTREE_OBJECT(scantree,
JSONTREE_PAIR("TotalPage", &scan_callback),
JSONTREE_PAIR("PageNum", &scan_callback),
JSONTREE_PAIR("ScanResult", &scanrslt_tree));
JSONTREE_OBJECT(scanres_tree,
JSONTREE_PAIR("Response", &scantree));
JSONTREE_OBJECT(scan_tree,
JSONTREE_PAIR("scan", &scanres_tree));
/******************************************************************************
* FunctionName : parse_url
* Description : parse the received data from the server
* Parameters : precv -- the received data
* purl_frame -- the result of parsing the url
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
parse_url(char *precv, URL_Frame *purl_frame)
{
char *str = NULL;
uint8 length = 0;
char *pbuffer = NULL;
char *pbufer = NULL;
if (purl_frame == NULL || precv == NULL) {
return;
}
pbuffer = (char *)os_strstr(precv, "Host:");
if (pbuffer != NULL) {
length = pbuffer - precv;
pbufer = (char *)os_zalloc(length + 1);
pbuffer = pbufer;
os_memcpy(pbuffer, precv, length);
os_memset(purl_frame->pSelect, 0, URLSize);
os_memset(purl_frame->pCommand, 0, URLSize);
os_memset(purl_frame->pFilename, 0, URLSize);
if (os_strncmp(pbuffer, "GET ", 4) == 0) {
purl_frame->Type = GET;
pbuffer += 4;
} else if (os_strncmp(pbuffer, "POST ", 5) == 0) {
purl_frame->Type = POST;
pbuffer += 5;
}
pbuffer ++;
str = (char *)os_strstr(pbuffer, "?");
if (str != NULL) {
length = str - pbuffer;
os_memcpy(purl_frame->pSelect, pbuffer, length);
str ++;
pbuffer = (char *)os_strstr(str, "=");
if (pbuffer != NULL) {
length = pbuffer - str;
os_memcpy(purl_frame->pCommand, str, length);
pbuffer ++;
str = (char *)os_strstr(pbuffer, "&");
if (str != NULL) {
length = str - pbuffer;
os_memcpy(purl_frame->pFilename, pbuffer, length);
} else {
str = (char *)os_strstr(pbuffer, " HTTP");
if (str != NULL) {
length = str - pbuffer;
os_memcpy(purl_frame->pFilename, pbuffer, length);
}
}
}
}
os_free(pbufer);
} else {
return;
}
}
LOCAL char *precvbuffer;
static uint32 dat_sumlength = 0;
LOCAL bool ICACHE_FLASH_ATTR
save_data(char *precv, uint16 length)
{
bool flag = false;
char length_buf[10] = {0};
char *ptemp = NULL;
char *pdata = NULL;
uint16 headlength = 0;
static uint32 totallength = 0;
ptemp = (char *)os_strstr(precv, "\r\n\r\n");
if (ptemp != NULL) {
length -= ptemp - precv;
length -= 4;
totallength += length;
headlength = ptemp - precv + 4;
pdata = (char *)os_strstr(precv, "Content-Length: ");
if (pdata != NULL) {
pdata += 16;
precvbuffer = (char *)os_strstr(pdata, "\r\n");
if (precvbuffer != NULL) {
os_memcpy(length_buf, pdata, precvbuffer - pdata);
dat_sumlength = atoi(length_buf);
}
} else {
if (totallength != 0x00){
totallength = 0;
dat_sumlength = 0;
return false;
}
}
if ((dat_sumlength + headlength) >= 1024) {
precvbuffer = (char *)os_zalloc(headlength + 1);
os_memcpy(precvbuffer, precv, headlength + 1);
} else {
precvbuffer = (char *)os_zalloc(dat_sumlength + headlength + 1);
os_memcpy(precvbuffer, precv, os_strlen(precv));
}
} else {
if (precvbuffer != NULL) {
totallength += length;
os_memcpy(precvbuffer + os_strlen(precvbuffer), precv, length);
} else {
totallength = 0;
dat_sumlength = 0;
return false;
}
}
if (totallength == dat_sumlength) {
totallength = 0;
dat_sumlength = 0;
return true;
} else {
return false;
}
}
LOCAL bool ICACHE_FLASH_ATTR
check_data(char *precv, uint16 length)
{
//bool flag = true;
char length_buf[10] = {0};
char *ptemp = NULL;
char *pdata = NULL;
char *tmp_precvbuffer;
uint16 tmp_length = length;
uint32 tmp_totallength = 0;
ptemp = (char *)os_strstr(precv, "\r\n\r\n");
if (ptemp != NULL) {
tmp_length -= ptemp - precv;
tmp_length -= 4;
tmp_totallength += tmp_length;
pdata = (char *)os_strstr(precv, "Content-Length: ");
if (pdata != NULL){
pdata += 16;
tmp_precvbuffer = (char *)os_strstr(pdata, "\r\n");
if (tmp_precvbuffer != NULL){
os_memcpy(length_buf, pdata, tmp_precvbuffer - pdata);
dat_sumlength = atoi(length_buf);
os_printf("A_dat:%u,tot:%u,lenght:%u\n",dat_sumlength,tmp_totallength,tmp_length);
if(dat_sumlength != tmp_totallength){
return false;
}
}
}
}
return true;
}
LOCAL os_timer_t *restart_10ms;
LOCAL rst_parm *rstparm;
/******************************************************************************
* FunctionName : restart_10ms_cb
* Description : system restart or wifi reconnected after a certain time.
* Parameters : arg -- Additional argument to pass to the function
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
restart_10ms_cb(void *arg)
{
if (rstparm != NULL && rstparm->pespconn != NULL) {
switch (rstparm->parmtype) {
case WIFI:
//if (rstparm->pespconn->state == ESPCONN_CLOSE) {
if (sta_conf->ssid[0] != 0x00) {
wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
user_esp_platform_check_ip(1);
}
if (ap_conf->ssid[0] != 0x00) {
wifi_softap_set_config(ap_conf);
system_restart();
}
os_free(ap_conf);
ap_conf = NULL;
os_free(sta_conf);
sta_conf = NULL;
os_free(rstparm);
rstparm = NULL;
os_free(restart_10ms);
restart_10ms = NULL;
//} else {
// os_timer_arm(restart_10ms, 10, 0);
//}
break;
case DEEP_SLEEP:
case REBOOT:
if (rstparm->pespconn->state == ESPCONN_CLOSE) {
wifi_set_opmode(STATION_MODE);
if (rstparm->parmtype == DEEP_SLEEP) {
#if SENSOR_DEVICE
system_deep_sleep(SENSOR_DEEP_SLEEP_TIME);
#endif
}
} else {
os_timer_arm(restart_10ms, 10, 0);
}
break;
default:
break;
}
}
}
/******************************************************************************
* FunctionName : data_send
* Description : processing the data as http format and send to the client or server
* Parameters : arg -- argument to set for client or server
* responseOK -- true or false
* psend -- The send data
* Returns :
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
data_send(void *arg, bool responseOK, char *psend)
{
uint16 length = 0;
char *pbuf = NULL;
char httphead[256];
struct espconn *ptrespconn = arg;
os_memset(httphead, 0, 256);
if (responseOK) {
os_sprintf(httphead,
"HTTP/1.0 200 OK\r\nContent-Length: %d\r\nServer: lwIP/1.4.0\r\n",
psend ? os_strlen(psend) : 0);
if (psend) {
os_sprintf(httphead + os_strlen(httphead),
"Content-type: application/json\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n");
length = os_strlen(httphead) + os_strlen(psend);
pbuf = (char *)os_zalloc(length + 1);
os_memcpy(pbuf, httphead, os_strlen(httphead));
os_memcpy(pbuf + os_strlen(httphead), psend, os_strlen(psend));
} else {
os_sprintf(httphead + os_strlen(httphead), "\n");
length = os_strlen(httphead);
}
} else {
os_sprintf(httphead, "HTTP/1.0 400 BadRequest\r\n\
Content-Length: 0\r\nServer: lwIP/1.4.0\r\n\n");
length = os_strlen(httphead);
}
if (psend) {
#ifdef SERVER_SSL_ENABLE
espconn_secure_sent(ptrespconn, pbuf, length);
#else
espconn_sent(ptrespconn, pbuf, length);
#endif
} else {
#ifdef SERVER_SSL_ENABLE
espconn_secure_sent(ptrespconn, httphead, length);
#else
espconn_sent(ptrespconn, httphead, length);
#endif
}
if (pbuf) {
os_free(pbuf);
pbuf = NULL;
}
}
/******************************************************************************
* FunctionName : json_send
* Description : processing the data as json format and send to the client or server
* Parameters : arg -- argument to set for client or server
* ParmType -- json format type
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
json_send(void *arg, ParmType ParmType)
{
char *pbuf = NULL;
pbuf = (char *)os_zalloc(jsonSize);
struct espconn *ptrespconn = arg;
switch (ParmType) {
#if LIGHT_DEVICE
case LIGHT_STATUS:
json_ws_send((struct jsontree_value *)&PwmTree, "light", pbuf);
break;
#endif
#if PLUG_DEVICE
case SWITCH_STATUS:
json_ws_send((struct jsontree_value *)&StatusTree, "switch", pbuf);
break;
#endif
case INFOMATION:
json_ws_send((struct jsontree_value *)&INFOTree, "info", pbuf);
break;
case WIFI:
json_ws_send((struct jsontree_value *)&wifi_info_tree, "wifi", pbuf);
break;
case CONNECT_STATUS:
json_ws_send((struct jsontree_value *)&con_status_tree, "info", pbuf);
break;
case USER_BIN:
json_ws_send((struct jsontree_value *)&userinfo_tree, "user_info", pbuf);
break;
case SCAN: {
u8 i = 0;
u8 scancount = 0;
struct bss_info *bss = NULL;
// bss = STAILQ_FIRST(pscaninfo->pbss);
bss = bss_head;
if (bss == NULL) {
os_free(pscaninfo);
pscaninfo = NULL;
os_sprintf(pbuf, "{\n\"successful\": false,\n\"data\": null\n}");
} else {
do {
if (pscaninfo->page_sn == pscaninfo->pagenum) {
pscaninfo->page_sn = 0;
os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"repeated page\"\n}");
break;
}
scancount = scannum - (pscaninfo->pagenum - 1) * 8;
if (scancount >= 8) {
pscaninfo->data_cnt += 8;
pscaninfo->page_sn = pscaninfo->pagenum;
if (pscaninfo->data_cnt > scannum) {
pscaninfo->data_cnt -= 8;
os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"error page\"\n}");
break;
}
json_ws_send((struct jsontree_value *)&scan_tree, "scan", pbuf);
} else {
pscaninfo->data_cnt += scancount;
pscaninfo->page_sn = pscaninfo->pagenum;
if (pscaninfo->data_cnt > scannum) {
pscaninfo->data_cnt -= scancount;
os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"error page\"\n}");
break;
}
char *ptrscanbuf = (char *)os_zalloc(jsonSize);
char *pscanbuf = ptrscanbuf;
os_sprintf(pscanbuf, ",\n\"ScanResult\": [\n");
pscanbuf += os_strlen(pscanbuf);
for (i = 0; i < scancount; i ++) {
JSONTREE_OBJECT(page_tree,
JSONTREE_PAIR("page", &scaninfo_tree));
json_ws_send((struct jsontree_value *)&page_tree, "page", pscanbuf);
os_sprintf(pscanbuf + os_strlen(pscanbuf), ",\n");
pscanbuf += os_strlen(pscanbuf);
}
os_sprintf(pscanbuf - 2, "]\n");
JSONTREE_OBJECT(scantree,
JSONTREE_PAIR("TotalPage", &scan_callback),
JSONTREE_PAIR("PageNum", &scan_callback));
JSONTREE_OBJECT(scanres_tree,
JSONTREE_PAIR("Response", &scantree));
JSONTREE_OBJECT(scan_tree,
JSONTREE_PAIR("scan", &scanres_tree));
json_ws_send((struct jsontree_value *)&scan_tree, "scan", pbuf);
os_memcpy(pbuf + os_strlen(pbuf) - 4, ptrscanbuf, os_strlen(ptrscanbuf));
os_sprintf(pbuf + os_strlen(pbuf), "}\n}");
os_free(ptrscanbuf);
}
} while (0);
}
break;
}
default :
break;
}
data_send(ptrespconn, true, pbuf);
os_free(pbuf);
pbuf = NULL;
}
/******************************************************************************
* FunctionName : response_send
* Description : processing the send result
* Parameters : arg -- argument to set for client or server
* responseOK -- true or false
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
response_send(void *arg, bool responseOK)
{
struct espconn *ptrespconn = arg;
data_send(ptrespconn, responseOK, NULL);
}
/******************************************************************************
* FunctionName : json_scan_cb
* Description : processing the scan result
* Parameters : arg -- Additional argument to pass to the callback function
* status -- scan status
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR json_scan_cb(void *arg, STATUS status)
{
pscaninfo->pbss = arg;
if (scannum % 8 == 0) {
pscaninfo->totalpage = scannum / 8;
} else {
pscaninfo->totalpage = scannum / 8 + 1;
}
JSONTREE_OBJECT(totaltree,
JSONTREE_PAIR("TotalPage", &scan_callback));
JSONTREE_OBJECT(totalres_tree,
JSONTREE_PAIR("Response", &totaltree));
JSONTREE_OBJECT(total_tree,
JSONTREE_PAIR("total", &totalres_tree));
bss_temp = bss_head;
while(bss_temp !=NULL) {
bss_head = bss_temp->next.stqe_next;
os_free(bss_temp);
bss_temp = bss_head;
}
bss_head = NULL;
bss_temp = NULL;
bss = STAILQ_FIRST(pscaninfo->pbss);
while(bss != NULL) {
if(bss_temp == NULL){
bss_temp = (struct bss_info *)os_zalloc(sizeof(struct bss_info));
bss_head = bss_temp;
} else {
bss_temp->next.stqe_next = (struct bss_info *)os_zalloc(sizeof(struct bss_info));
bss_temp = bss_temp->next.stqe_next;
}
if(bss_temp == NULL) {
os_printf("malloc scan info failed\n");
break;
} else{
os_memcpy(bss_temp->bssid,bss->bssid,sizeof(bss->bssid));
os_memcpy(bss_temp->ssid,bss->ssid,sizeof(bss->ssid));
bss_temp->authmode = bss->authmode;
bss_temp->rssi = bss->rssi;
bss_temp->channel = bss->channel;
}
bss = STAILQ_NEXT(bss,next);
}
char *pbuf = NULL;
pbuf = (char *)os_zalloc(jsonSize);
json_ws_send((struct jsontree_value *)&total_tree, "total", pbuf);
data_send(pscaninfo->pespconn, true, pbuf);
os_free(pbuf);
}
void ICACHE_FLASH_ATTR
upgrade_check_func(void *arg)
{
struct espconn *ptrespconn = arg;
os_timer_disarm(&upgrade_check_timer);
if(system_upgrade_flag_check() == UPGRADE_FLAG_START) {
response_send(ptrespconn, false);
system_upgrade_deinit();
system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
upgrade_lock = 0;
os_printf("local upgrade failed\n");
} else if( system_upgrade_flag_check() == UPGRADE_FLAG_FINISH ) {
os_printf("local upgrade success\n");
response_send(ptrespconn, true);
upgrade_lock = 0;
} else {
}
}
/******************************************************************************
* FunctionName : upgrade_deinit
* Description : disconnect the connection with the host
* Parameters : bin -- server number
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
LOCAL local_upgrade_deinit(void)
{
if (system_upgrade_flag_check() != UPGRADE_FLAG_START) {
os_printf("system upgrade deinit\n");
system_upgrade_deinit();
}
}
/******************************************************************************
* FunctionName : upgrade_download
* Description : Processing the upgrade data from the host
* Parameters : bin -- server number
* pusrdata -- The upgrade data (or NULL when the connection has been closed!)
* length -- The length of upgrade data
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
local_upgrade_download(void * arg,char *pusrdata, unsigned short length)
{
char *ptr = NULL;
char *ptmp2 = NULL;
char lengthbuffer[32];
static uint32 totallength = 0;
static uint32 sumlength = 0;
static uint32 erase_length = 0;
char A_buf[2] = {0xE9 ,0x03}; char B_buf[2] = {0xEA,0x04};
struct espconn *pespconn = arg;
if (totallength == 0 && (ptr = (char *)os_strstr(pusrdata, "\r\n\r\n")) != NULL &&
(ptr = (char *)os_strstr(pusrdata, "Content-Length")) != NULL) {
ptr = (char *)os_strstr(pusrdata, "Content-Length: ");
if (ptr != NULL) {
ptr += 16;
ptmp2 = (char *)os_strstr(ptr, "\r\n");
if (ptmp2 != NULL) {
os_memset(lengthbuffer, 0, sizeof(lengthbuffer));
os_memcpy(lengthbuffer, ptr, ptmp2 - ptr);
sumlength = atoi(lengthbuffer);
if (sumlength == 0) {
os_timer_disarm(&upgrade_check_timer);
os_timer_setfn(&upgrade_check_timer, (os_timer_func_t *)upgrade_check_func, pespconn);
os_timer_arm(&upgrade_check_timer, 10, 0);
return;
}
} else {
os_printf("sumlength failed\n");
}
} else {
os_printf("Content-Length: failed\n");
}
if (sumlength != 0) {
if (sumlength >= LIMIT_ERASE_SIZE){
system_upgrade_erase_flash(0xFFFF);
erase_length = sumlength - LIMIT_ERASE_SIZE;
} else {
system_upgrade_erase_flash(sumlength);
erase_length = 0;
}
}
ptr = (char *)os_strstr(pusrdata, "\r\n\r\n");
length -= ptr - pusrdata;
length -= 4;
totallength += length;
os_printf("upgrade file download start.\n");
system_upgrade(ptr + 4, length);
} else {
totallength += length;
if (erase_length >= LIMIT_ERASE_SIZE){
system_upgrade_erase_flash(0xFFFF);
erase_length -= LIMIT_ERASE_SIZE;
} else {
system_upgrade_erase_flash(erase_length);
erase_length = 0;
}
system_upgrade(pusrdata, length);
}
if (totallength == sumlength) {
os_printf("upgrade file download finished.\n");
system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
totallength = 0;
sumlength = 0;
upgrade_check_func(pespconn);
os_timer_disarm(&app_upgrade_10s);
os_timer_setfn(&app_upgrade_10s, (os_timer_func_t *)local_upgrade_deinit, NULL);
os_timer_arm(&app_upgrade_10s, 10, 0);
}
}
/******************************************************************************
* FunctionName : webserver_recv
* Description : Processing the received data from the server
* Parameters : arg -- Additional argument to pass to the callback function
* pusrdata -- The received data (or NULL when the connection has been closed!)
* length -- The length of received data
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
webserver_recv(void *arg, char *pusrdata, unsigned short length)
{
URL_Frame *pURL_Frame = NULL;
char *pParseBuffer = NULL;
bool parse_flag = false;
struct espconn *ptrespconn = arg;
if(upgrade_lock == 0){
os_printf("len:%u\n",length);
if(check_data(pusrdata, length) == false)
{
os_printf("goto\n");
goto _temp_exit;
}
parse_flag = save_data(pusrdata, length);
if (parse_flag == false) {
response_send(ptrespconn, false);
}
// os_printf(precvbuffer);
pURL_Frame = (URL_Frame *)os_zalloc(sizeof(URL_Frame));
parse_url(precvbuffer, pURL_Frame);
switch (pURL_Frame->Type) {
case GET:
os_printf("We have a GET request.\n");
if (os_strcmp(pURL_Frame->pSelect, "client") == 0 &&
os_strcmp(pURL_Frame->pCommand, "command") == 0) {
if (os_strcmp(pURL_Frame->pFilename, "info") == 0) {
json_send(ptrespconn, INFOMATION);
}
if (os_strcmp(pURL_Frame->pFilename, "status") == 0) {
json_send(ptrespconn, CONNECT_STATUS);
} else if (os_strcmp(pURL_Frame->pFilename, "scan") == 0) {
char *strstr = NULL;
strstr = (char *)os_strstr(pusrdata, "&");
if (strstr == NULL) {
if (pscaninfo == NULL) {
pscaninfo = (scaninfo *)os_zalloc(sizeof(scaninfo));
}
pscaninfo->pespconn = ptrespconn;
pscaninfo->pagenum = 0;
pscaninfo->page_sn = 0;
pscaninfo->data_cnt = 0;
wifi_station_scan(NULL, json_scan_cb);
} else {
strstr ++;
if (os_strncmp(strstr, "page", 4) == 0) {
if (pscaninfo != NULL) {
pscaninfo->pagenum = *(strstr + 5);
pscaninfo->pagenum -= 0x30;
if (pscaninfo->pagenum > pscaninfo->totalpage || pscaninfo->pagenum == 0) {
response_send(ptrespconn, false);
} else {
json_send(ptrespconn, SCAN);
}
} else {
response_send(ptrespconn, false);
}
} else if(os_strncmp(strstr, "finish", 6) == 0){
bss_temp = bss_head;
while(bss_temp != NULL) {
bss_head = bss_temp->next.stqe_next;
os_free(bss_temp);
bss_temp = bss_head;
}
bss_head = NULL;
bss_temp = NULL;
response_send(ptrespconn, true);
} else {
response_send(ptrespconn, false);
}
}
} else {
response_send(ptrespconn, false);
}
} else if (os_strcmp(pURL_Frame->pSelect, "config") == 0 &&
os_strcmp(pURL_Frame->pCommand, "command") == 0) {
if (os_strcmp(pURL_Frame->pFilename, "wifi") == 0) {
ap_conf = (struct softap_config *)os_zalloc(sizeof(struct softap_config));
sta_conf = (struct station_config *)os_zalloc(sizeof(struct station_config));
json_send(ptrespconn, WIFI);
os_free(sta_conf);
os_free(ap_conf);
sta_conf = NULL;
ap_conf = NULL;
}
#if PLUG_DEVICE
else if (os_strcmp(pURL_Frame->pFilename, "switch") == 0) {
json_send(ptrespconn, SWITCH_STATUS);
}
#endif
#if LIGHT_DEVICE
else if (os_strcmp(pURL_Frame->pFilename, "light") == 0) {
json_send(ptrespconn, LIGHT_STATUS);
}
#endif
else if (os_strcmp(pURL_Frame->pFilename, "reboot") == 0) {
json_send(ptrespconn, REBOOT);
} else {
response_send(ptrespconn, false);
}
} else if (os_strcmp(pURL_Frame->pSelect, "upgrade") == 0 &&
os_strcmp(pURL_Frame->pCommand, "command") == 0) {
if (os_strcmp(pURL_Frame->pFilename, "getuser") == 0) {
json_send(ptrespconn , USER_BIN);
}
} else {
response_send(ptrespconn, false);
}
break;
case POST:
os_printf("We have a POST request.\n");
pParseBuffer = (char *)os_strstr(precvbuffer, "\r\n\r\n");
if (pParseBuffer == NULL) {
break;
}
pParseBuffer += 4;
if (os_strcmp(pURL_Frame->pSelect, "config") == 0 &&
os_strcmp(pURL_Frame->pCommand, "command") == 0) {
#if SENSOR_DEVICE
if (os_strcmp(pURL_Frame->pFilename, "sleep") == 0) {
#else
if (os_strcmp(pURL_Frame->pFilename, "reboot") == 0) {
#endif
if (pParseBuffer != NULL) {
if (restart_10ms != NULL) {
os_timer_disarm(restart_10ms);
}
if (rstparm == NULL) {
rstparm = (rst_parm *)os_zalloc(sizeof(rst_parm));
}
rstparm->pespconn = ptrespconn;
#if SENSOR_DEVICE
rstparm->parmtype = DEEP_SLEEP;
#else
rstparm->parmtype = REBOOT;
#endif
if (restart_10ms == NULL) {
restart_10ms = (os_timer_t *)os_malloc(sizeof(os_timer_t));
}
os_timer_setfn(restart_10ms, (os_timer_func_t *)restart_10ms_cb, NULL);
os_timer_arm(restart_10ms, 10, 0); // delay 10ms, then do
response_send(ptrespconn, true);
} else {
response_send(ptrespconn, false);
}
} else if (os_strcmp(pURL_Frame->pFilename, "wifi") == 0) {
if (pParseBuffer != NULL) {
struct jsontree_context js;
user_esp_platform_set_connect_status(DEVICE_CONNECTING);
if (restart_10ms != NULL) {
os_timer_disarm(restart_10ms);
}
if (ap_conf == NULL) {
ap_conf = (struct softap_config *)os_zalloc(sizeof(struct softap_config));
}
if (sta_conf == NULL) {
sta_conf = (struct station_config *)os_zalloc(sizeof(struct station_config));
}
jsontree_setup(&js, (struct jsontree_value *)&wifi_req_tree, json_putchar);
json_parse(&js, pParseBuffer);
if (rstparm == NULL) {
rstparm = (rst_parm *)os_zalloc(sizeof(rst_parm));
}
rstparm->pespconn = ptrespconn;
rstparm->parmtype = WIFI;
if (sta_conf->ssid[0] != 0x00 || ap_conf->ssid[0] != 0x00) {
ap_conf->ssid_hidden = 0;
ap_conf->max_connection = 4;
if (restart_10ms == NULL) {
restart_10ms = (os_timer_t *)os_malloc(sizeof(os_timer_t));
}
os_timer_disarm(restart_10ms);
os_timer_setfn(restart_10ms, (os_timer_func_t *)restart_10ms_cb, NULL);
os_timer_arm(restart_10ms, 10, 0); // delay 10ms, then do
} else {
os_free(ap_conf);
os_free(sta_conf);
os_free(rstparm);
sta_conf = NULL;
ap_conf = NULL;
rstparm =NULL;
}
response_send(ptrespconn, true);
} else {
response_send(ptrespconn, false);
}
}
#if PLUG_DEVICE
else if (os_strcmp(pURL_Frame->pFilename, "switch") == 0) {
if (pParseBuffer != NULL) {
struct jsontree_context js;
jsontree_setup(&js, (struct jsontree_value *)&StatusTree, json_putchar);
json_parse(&js, pParseBuffer);
response_send(ptrespconn, true);
} else {
response_send(ptrespconn, false);
}
}
#endif
#if LIGHT_DEVICE
else if (os_strcmp(pURL_Frame->pFilename, "light") == 0) {
if (pParseBuffer != NULL) {
struct jsontree_context js;
jsontree_setup(&js, (struct jsontree_value *)&PwmTree, json_putchar);
json_parse(&js, pParseBuffer);
os_printf("rsp1:%u\n",PostCmdNeeRsp);
if(PostCmdNeeRsp == 0)
PostCmdNeeRsp = 1;
else
response_send(ptrespconn, true);
} else {
response_send(ptrespconn, false);
}
}
else if (os_strcmp(pURL_Frame->pFilename, "reset") == 0) {
response_send(ptrespconn, true);
extern struct esp_platform_saved_param esp_param;
esp_param.activeflag = 0;
system_param_save_with_protect(ESP_PARAM_START_SEC, &esp_param, sizeof(esp_param));
system_restore();
system_restart();
}
#endif
else {
response_send(ptrespconn, false);
}
}
else if(os_strcmp(pURL_Frame->pSelect, "upgrade") == 0 &&
os_strcmp(pURL_Frame->pCommand, "command") == 0){
if (os_strcmp(pURL_Frame->pFilename, "start") == 0){
response_send(ptrespconn, true);
os_printf("local upgrade start\n");
upgrade_lock = 1;
system_upgrade_init();
system_upgrade_flag_set(UPGRADE_FLAG_START);
os_timer_disarm(&upgrade_check_timer);
os_timer_setfn(&upgrade_check_timer, (os_timer_func_t *)upgrade_check_func, NULL);
os_timer_arm(&upgrade_check_timer, 120000, 0);
} else if (os_strcmp(pURL_Frame->pFilename, "reset") == 0) {
response_send(ptrespconn, true);
os_printf("local upgrade restart\n");
system_upgrade_reboot();
} else {
response_send(ptrespconn, false);
}
}else {
response_send(ptrespconn, false);
}
break;
}
if (precvbuffer != NULL){
os_free(precvbuffer);
precvbuffer = NULL;
}
os_free(pURL_Frame);
pURL_Frame = NULL;
_temp_exit:
;
}
else if(upgrade_lock == 1){
local_upgrade_download(ptrespconn,pusrdata, length);
if (precvbuffer != NULL){
os_free(precvbuffer);
precvbuffer = NULL;
}
os_free(pURL_Frame);
pURL_Frame = NULL;
}
}
/******************************************************************************
* FunctionName : webserver_recon
* Description : the connection has been err, reconnection
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL ICACHE_FLASH_ATTR
void webserver_recon(void *arg, sint8 err)
{
struct espconn *pesp_conn = arg;
os_printf("webserver's %d.%d.%d.%d:%d err %d reconnect\n", pesp_conn->proto.tcp->remote_ip[0],
pesp_conn->proto.tcp->remote_ip[1],pesp_conn->proto.tcp->remote_ip[2],
pesp_conn->proto.tcp->remote_ip[3],pesp_conn->proto.tcp->remote_port, err);
}
/******************************************************************************
* FunctionName : webserver_recon
* Description : the connection has been err, reconnection
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL ICACHE_FLASH_ATTR
void webserver_discon(void *arg)
{
struct espconn *pesp_conn = arg;
os_printf("webserver's %d.%d.%d.%d:%d disconnect\n", pesp_conn->proto.tcp->remote_ip[0],
pesp_conn->proto.tcp->remote_ip[1],pesp_conn->proto.tcp->remote_ip[2],
pesp_conn->proto.tcp->remote_ip[3],pesp_conn->proto.tcp->remote_port);
}
/******************************************************************************
* FunctionName : user_accept_listen
* Description : server listened a connection successfully
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
webserver_listen(void *arg)
{
struct espconn *pesp_conn = arg;
espconn_regist_recvcb(pesp_conn, webserver_recv);
espconn_regist_reconcb(pesp_conn, webserver_recon);
espconn_regist_disconcb(pesp_conn, webserver_discon);
}
/******************************************************************************
* FunctionName : user_webserver_init
* Description : parameter initialize as a server
* Parameters : port -- server port
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_webserver_init(uint32 port)
{
LOCAL struct espconn esp_conn;
LOCAL esp_tcp esptcp;
esp_conn.type = ESPCONN_TCP;
esp_conn.state = ESPCONN_NONE;
esp_conn.proto.tcp = &esptcp;
esp_conn.proto.tcp->local_port = port;
espconn_regist_connectcb(&esp_conn, webserver_listen);
#ifdef SERVER_SSL_ENABLE
espconn_secure_set_default_certificate(default_certificate, default_certificate_len);
espconn_secure_set_default_private_key(default_private_key, default_private_key_len);
espconn_secure_accept(&esp_conn);
#else
espconn_accept(&esp_conn);
#endif
}
Notice: AT added some functions so it's larger than before, if you want to compile it, please compile it as 1024KB or larger flash in compilation STEP 5.
1compile options
(1) COMPILE
Possible value: gcc
Default value:
If not set, use xt-xcc by default.
(2) BOOT
Possible value: none/old/new
none: no need boot
old: use boot_v1.1
new: use boot_v1.2+
Default value: none
(3) APP
Possible value: 0/1/2
0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin
1: generate user1
2: generate user2
Default value: 0
(3) SPI_SPEED
Possible value: 20/26.7/40/80
Default value: 40
(4) SPI_MODE
Possible value: QIO/QOUT/DIO/DOUT
Default value: QIO
(4) SPI_SIZE
Possible value: 0/2/3/4/5/6
Default value: 0
For example:
make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0
2You can also use gen_misc to make and generate specific bin you needed.
Linux: ./gen_misc.sh
Windows: gen_misc.bat
Follow the tips and steps.
\ No newline at end of file
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of object file images to be generated ()
# GEN_BINS - list of binaries to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
TARGET = eagle
#FLAVOR = release
FLAVOR = debug
#EXTRA_CCFLAGS += -u
ifndef PDIR # {
GEN_IMAGES= eagle.app.v6.out
GEN_BINS= eagle.app.v6.bin
SPECIAL_MKTARGETS=$(APP_MKTARGETS)
SUBDIRS= \
user
ifdef AT_OPEN_SRC
SUBDIRS += \
at
endif
endif # } PDIR
APPDIR = .
LDDIR = ../ld
CCFLAGS += -Os
TARGET_LDFLAGS = \
-nostdlib \
-Wl,-EL \
--longcalls \
--text-section-literals
ifeq ($(FLAVOR),debug)
TARGET_LDFLAGS += -g -O2
endif
ifeq ($(FLAVOR),release)
TARGET_LDFLAGS += -g -O0
endif
COMPONENTS_eagle.app.v6 = \
user/libuser.a
ifdef AT_OPEN_SRC
COMPONENTS_eagle.app.v6 += \
at/libat.a
endif
LINKFLAGS_eagle.app.v6 = \
-L../lib \
-nostdlib \
-T$(LD_FILE) \
-Wl,--no-check-sections \
-u call_user_start \
-Wl,-static \
-Wl,--start-group \
-lc \
-lgcc \
-lhal \
-lphy \
-lpp \
-lnet80211 \
-llwip \
-lwpa \
-lmain \
-ljson \
-lupgrade \
-lsmartconfig \
$(DEP_LIBS_eagle.app.v6)
ifndef AT_OPEN_SRC
LINKFLAGS_eagle.app.v6 += \
-lat
endif
LINKFLAGS_eagle.app.v6 += \
-Wl,--end-group
DEPENDS_eagle.app.v6 = \
$(LD_FILE) \
$(LDDIR)/eagle.rom.addr.v6.ld
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#UNIVERSAL_TARGET_DEFINES = \
# Other potential configuration flags include:
# -DTXRX_TXBUF_DEBUG
# -DTXRX_RXBUF_DEBUG
# -DWLAN_CONFIG_CCX
CONFIGURATION_DEFINES = -DICACHE_FLASH
ifdef AT_OPEN_SRC
CONFIGURATION_DEFINES += \
-DAT_OPEN_SRC
endif
ifeq ($(APP),0)
else
CONFIGURATION_DEFINES += \
-DAT_UPGRADE_SUPPORT
endif
DEFINES += \
$(UNIVERSAL_TARGET_DEFINES) \
$(CONFIGURATION_DEFINES)
DDEFINES += \
$(UNIVERSAL_TARGET_DEFINES) \
$(CONFIGURATION_DEFINES)
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
.PHONY: FORCE
FORCE:
@echo off
echo gen_misc.bat version 20150511
echo .
echo Please follow below steps(1-5) to generate specific bin(s):
echo STEP 1: choose boot version(0=boot_v1.1, 1=boot_v1.2+, 2=none)
set input=default
set /p input=enter(0/1/2, default 2):
if %input% equ 0 (
set boot=old
) else (
if %input% equ 1 (
set boot=new
) else (
set boot=none
)
)
echo boot mode: %boot%
echo.
echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)
set input=default
set /p input=enter (0/1/2, default 0):
if %input% equ 1 (
if %boot% equ none (
set app=0
echo choose no boot before
echo generate bin: eagle.flash.bin+eagle.irom0text.bin
) else (
set app=1
echo generate bin: user1.bin
)
) else (
if %input% equ 2 (
if %boot% equ none (
set app=0
echo choose no boot before
echo generate bin: eagle.flash.bin+eagle.irom0text.bin
) else (
set app=2
echo generate bin: user2.bin
)
) else (
if %boot% neq none (
set boot=none
echo ignore boot
)
set app=0
echo generate bin: eagle.flash.bin+eagle.irom0text.bin
))
echo.
echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)
set input=default
set /p input=enter (0/1/2/3, default 2):
if %input% equ 0 (
set spi_speed=20
) else (
if %input% equ 1 (
set spi_speed=26.7
) else (
if %input% equ 3 (
set spi_speed=80
) else (
set spi_speed=40
)))
echo spi speed: %spi_speed% MHz
echo.
echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)
set input=default
set /p input=enter (0/1/2/3, default 0):
if %input% equ 1 (
set spi_mode=QOUT
) else (
if %input% equ 2 (
set spi_mode=DIO
) else (
if %input% equ 3 (
set spi_mode=DOUT
) else (
set spi_mode=QIO
)))
echo spi mode: %spi_mode%
echo.
echo STEP 5: choose flash size and map
echo 0= 512KB( 256KB+ 256KB)
echo 2=1024KB( 512KB+ 512KB)
echo 3=2048KB( 512KB+ 512KB)
echo 4=4096KB( 512KB+ 512KB)
echo 5=2048KB(1024KB+1024KB)
echo 6=4096KB(1024KB+1024KB)
set input=default
set /p input=enter (0/1/2/3/4/5/6, default 0):
if %input% equ 2 (
set spi_size_map=2
echo spi size: 1024KB
echo spi ota map: 512KB + 512KB
) else (
if %input% equ 3 (
set spi_size_map=3
echo spi size: 2048KB
echo spi ota map: 512KB + 512KB
) else (
if %input% equ 4 (
set spi_size_map=4
echo spi size: 4096KB
echo spi ota map: 512KB + 512KB
) else (
if %input% equ 5 (
set spi_size_map=5
echo spi size: 2048KB
echo spi ota map: 1024KB + 1024KB
) else (
if %input% equ 6 (
set spi_size_map=6
echo spi size: 4096KB
echo spi ota map: 1024KB + 1024KB
) else (
set spi_size_map=0
echo spi size: 512KB
echo spi ota map: 256KB + 256KB
)
)
)
)
)
touch user/user_main.c
echo.
echo start...
echo.
make BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE=%spi_size_map%
#!/bin/bash
echo "gen_misc.sh version 20150511"
echo ""
echo "Please follow below steps(1-5) to generate specific bin(s):"
echo "STEP 1: choose boot version(0=boot_v1.1, 1=boot_v1.2+, 2=none)"
echo "enter(0/1/2, default 2):"
read input
if [ -z "$input" ]; then
boot=none
elif [ $input == 0 ]; then
boot=old
elif [ $input == 1 ]; then
boot=new
else
boot=none
fi
echo "boot mode: $boot"
echo ""
echo "STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)"
echo "enter (0/1/2, default 0):"
read input
if [ -z "$input" ]; then
if [ $boot != none ]; then
boot=none
echo "ignore boot"
fi
app=0
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
elif [ $input == 1 ]; then
if [ $boot == none ]; then
app=0
echo "choose no boot before"
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
else
app=1
echo "generate bin: user1.bin"
fi
elif [ $input == 2 ]; then
if [ $boot == none ]; then
app=0
echo "choose no boot before"
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
else
app=2
echo "generate bin: user2.bin"
fi
else
if [ $boot != none ]; then
boot=none
echo "ignore boot"
fi
app=0
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
fi
echo ""
echo "STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)"
echo "enter (0/1/2/3, default 2):"
read input
if [ -z "$input" ]; then
spi_speed=40
elif [ $input == 0 ]; then
spi_speed=20
elif [ $input == 1 ]; then
spi_speed=26.7
elif [ $input == 3 ]; then
spi_speed=80
else
spi_speed=40
fi
echo "spi speed: $spi_speed MHz"
echo ""
echo "STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)"
echo "enter (0/1/2/3, default 0):"
read input
if [ -z "$input" ]; then
spi_mode=QIO
elif [ $input == 1 ]; then
spi_mode=QOUT
elif [ $input == 2 ]; then
spi_mode=DIO
elif [ $input == 3 ]; then
spi_mode=DOUT
else
spi_mode=QIO
fi
echo "spi mode: $spi_mode"
echo ""
echo "STEP 5: choose spi size and map"
echo " 0= 512KB( 256KB+ 256KB)"
echo " 2=1024KB( 512KB+ 512KB)"
echo " 3=2048KB( 512KB+ 512KB)"
echo " 4=4096KB( 512KB+ 512KB)"
echo " 5=2048KB(1024KB+1024KB)"
echo " 6=4096KB(1024KB+1024KB)"
echo "enter (0/2/3/4/5/6, default 0):"
read input
if [ -z "$input" ]; then
spi_size_map=0
echo "spi size: 512KB"
echo "spi ota map: 256KB + 256KB"
elif [ $input == 2 ]; then
spi_size_map=2
echo "spi size: 1024KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 3 ]; then
spi_size_map=3
echo "spi size: 2048KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 4 ]; then
spi_size_map=4
echo "spi size: 4096KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 5 ]; then
spi_size_map=5
echo "spi size: 2048KB"
echo "spi ota map: 1024KB + 1024KB"
elif [ $input == 6 ]; then
spi_size_map=6
echo "spi size: 4096KB"
echo "spi ota map: 1024KB + 1024KB"
else
spi_size_map=0
echo "spi size: 512KB"
echo "spi ota map: 256KB + 256KB"
fi
echo ""
touch user/user_main.c
echo ""
echo "start..."
echo ""
make COMPILE=gcc BOOT=$boot APP=$app SPI_SPEED=$spi_speed SPI_MODE=$spi_mode SPI_SIZE_MAP=$spi_size_map
#ifndef __USER_CONFIG_H__
#define __USER_CONFIG_H__
#define AT_CUSTOM_UPGRADE
#ifdef AT_CUSTOM_UPGRADE
#ifndef AT_UPGRADE_SUPPORT
#error "upgrade is not supported when eagle.flash.bin+eagle.irom0text.bin!!!"
#endif
#endif
#endif
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libuser.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../../include/ets
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
/******************************************************************************
* Copyright 2015-2018 Espressif Systems (Wuxi)
*
* FileName: user_main.c
*
* Description: entry file of user application
*
* Modification history:
* 2015/3/06, v1.0 create this file.
*******************************************************************************/
#include "c_types.h"
#include "user_interface.h"
#include "espconn.h"
#include "mem.h"
#include "osapi.h"
#include "upgrade.h"
#ifdef AT_UPGRADE_SUPPORT
#ifdef AT_CUSTOM_UPGRADE
#define UPGRADE_FRAME "{\"path\": \"/v1/messages/\", \"method\": \"POST\", \"meta\": {\"Authorization\": \"token %s\"},\
\"get\":{\"action\":\"%s\"},\"body\":{\"pre_rom_version\":\"%s\",\"rom_version\":\"%s\"}}\n"
#define pheadbuffer "Connection: keep-alive\r\n\
Cache-Control: no-cache\r\n\
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 \r\n\
Accept: */*\r\n\
Accept-Encoding: gzip,deflate\r\n\
Accept-Language: zh-CN,eb-US;q=0.8\r\n\r\n"
/**/
struct espconn *pespconn = NULL;
struct upgrade_server_info *upServer = NULL;
static os_timer_t at_delay_check;
static struct espconn *pTcpServer = NULL;
static ip_addr_t host_ip;
/******************************************************************************
* FunctionName : user_esp_platform_upgrade_cb
* Description : Processing the downloaded data from the server
* Parameters : pespconn -- the espconn used to connetion with the host
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
at_upDate_rsp(void *arg)
{
struct upgrade_server_info *server = arg;
if(server->upgrade_flag == true)
{
os_printf("device_upgrade_success\r\n");
at_response_ok();
system_upgrade_reboot();
}
else
{
os_printf("device_upgrade_failed\r\n");
at_response_error();
}
os_free(server->url);
server->url = NULL;
os_free(server);
server = NULL;
}
/**
* @brief Tcp client disconnect success callback function.
* @param arg: contain the ip link information
* @retval None
*/
static void ICACHE_FLASH_ATTR
at_upDate_discon_cb(void *arg)
{
struct espconn *pespconn = (struct espconn *)arg;
uint8_t idTemp = 0;
if(pespconn->proto.tcp != NULL)
{
os_free(pespconn->proto.tcp);
}
if(pespconn != NULL)
{
os_free(pespconn);
}
os_printf("disconnect\r\n");
if(system_upgrade_start(upServer) == false)
{
at_response_error();
}
else
{
at_port_print("+CIPUPDATE:4\r\n");
}
}
/**
* @brief Udp server receive data callback function.
* @param arg: contain the ip link information
* @retval None
*/
LOCAL void ICACHE_FLASH_ATTR
at_upDate_recv(void *arg, char *pusrdata, unsigned short len)
{
struct espconn *pespconn = (struct espconn *)arg;
char temp[32] = {0};
uint8_t user_bin[12] = {0};
uint8_t i = 0;
os_timer_disarm(&at_delay_check);
at_port_print("+CIPUPDATE:3\r\n");
upServer = (struct upgrade_server_info *)os_zalloc(sizeof(struct upgrade_server_info));
upServer->upgrade_version[5] = '\0';
upServer->pespconn = pespconn;
os_memcpy(upServer->ip, pespconn->proto.tcp->remote_ip, 4);
upServer->port = pespconn->proto.tcp->remote_port;
upServer->check_cb = at_upDate_rsp;
upServer->check_times = 60000;
if(upServer->url == NULL)
{
upServer->url = (uint8 *) os_zalloc(1024);
}
if(system_upgrade_userbin_check() == UPGRADE_FW_BIN1)
{
os_memcpy(user_bin, "user2.bin", 10);
}
else if(system_upgrade_userbin_check() == UPGRADE_FW_BIN2)
{
os_memcpy(user_bin, "user1.bin", 10);
}
os_sprintf(upServer->url,
"GET /%s HTTP/1.1\r\nHost: "IPSTR"\r\n"pheadbuffer"",
user_bin, IP2STR(upServer->ip));
}
LOCAL void ICACHE_FLASH_ATTR
at_upDate_wait(void *arg)
{
struct espconn *pespconn = arg;
os_timer_disarm(&at_delay_check);
if(pespconn != NULL)
{
espconn_disconnect(pespconn);
}
else
{
at_response_error();
}
}
/******************************************************************************
* FunctionName : user_esp_platform_sent_cb
* Description : Data has been sent successfully and acknowledged by the remote host.
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
at_upDate_sent_cb(void *arg)
{
struct espconn *pespconn = arg;
os_timer_disarm(&at_delay_check);
os_timer_setfn(&at_delay_check, (os_timer_func_t *)at_upDate_wait, pespconn);
os_timer_arm(&at_delay_check, 5000, 0);
os_printf("at_upDate_sent_cb\r\n");
}
/**
* @brief Tcp client connect success callback function.
* @param arg: contain the ip link information
* @retval None
*/
static void ICACHE_FLASH_ATTR
at_upDate_connect_cb(void *arg)
{
struct espconn *pespconn = (struct espconn *)arg;
uint8_t user_bin[9] = {0};
char *temp = NULL;
at_port_print("+CIPUPDATE:2\r\n");
espconn_regist_disconcb(pespconn, at_upDate_discon_cb);
espconn_regist_recvcb(pespconn, at_upDate_recv);////////
espconn_regist_sentcb(pespconn, at_upDate_sent_cb);
temp = (uint8 *) os_zalloc(512);
os_sprintf(temp,"GET /v1/device/rom/?is_format_simple=true HTTP/1.0\r\nHost: "IPSTR"\r\n"pheadbuffer"",
IP2STR(pespconn->proto.tcp->remote_ip));
espconn_sent(pespconn, temp, os_strlen(temp));
os_free(temp);
}
/**
* @brief Tcp client connect repeat callback function.
* @param arg: contain the ip link information
* @retval None
*/
static void ICACHE_FLASH_ATTR
at_upDate_recon_cb(void *arg, sint8 errType)
{
struct espconn *pespconn = (struct espconn *)arg;
at_response_error();
if(pespconn->proto.tcp != NULL)
{
os_free(pespconn->proto.tcp);
}
os_free(pespconn);
os_printf("disconnect\r\n");
if(upServer != NULL)
{
os_free(upServer);
upServer = NULL;
}
at_response_error();
}
/******************************************************************************
* FunctionName : upServer_dns_found
* Description : dns found callback
* Parameters : name -- pointer to the name that was looked up.
* ipaddr -- pointer to an ip_addr_t containing the IP address of
* the hostname, or NULL if the name could not be found (or on any
* other error).
* callback_arg -- a user-specified callback argument passed to
* dns_gethostbyname
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upServer_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
{
struct espconn *pespconn = (struct espconn *) arg;
// char temp[32];
if(ipaddr == NULL)
{
at_response_error();
return;
}
at_port_print("+CIPUPDATE:1\r\n");
if(host_ip.addr == 0 && ipaddr->addr != 0)
{
if(pespconn->type == ESPCONN_TCP)
{
os_memcpy(pespconn->proto.tcp->remote_ip, &ipaddr->addr, 4);
espconn_regist_connectcb(pespconn, at_upDate_connect_cb);
espconn_regist_reconcb(pespconn, at_upDate_recon_cb);
espconn_connect(pespconn);
}
}
}
void ICACHE_FLASH_ATTR
at_exeCmdCiupdate(uint8_t id)
{
pespconn = (struct espconn *)os_zalloc(sizeof(struct espconn));
pespconn->type = ESPCONN_TCP;
pespconn->state = ESPCONN_NONE;
pespconn->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
pespconn->proto.tcp->local_port = espconn_port();
pespconn->proto.tcp->remote_port = 80;
host_ip.addr = ipaddr_addr("192.168.10.9");
at_port_print("+CIPUPDATE:1\r\n");
os_memcpy(pespconn->proto.tcp->remote_ip, &host_ip.addr, 4);
espconn_regist_connectcb(pespconn, at_upDate_connect_cb);
espconn_regist_reconcb(pespconn, at_upDate_recon_cb);
espconn_connect(pespconn);
}
#endif
#endif
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: user_main.c
*
* Description: entry file of user application
*
* Modification history:
* 2015/1/23, v1.0 create this file.
*******************************************************************************/
#include "osapi.h"
#include "at_custom.h"
#include "user_interface.h"
// test :AT+TEST=1,"abc"<,3>
void ICACHE_FLASH_ATTR
at_setupCmdTest(uint8_t id, char *pPara)
{
int result = 0, err = 0, flag = 0;
uint8 buffer[32] = {0};
pPara++; // skip '='
//get the first parameter
// digit
flag = at_get_next_int_dec(&pPara, &result, &err);
// flag must be ture because there are more parameter
if (flag == FALSE) {
at_response_error();
return;
}
if (*pPara++ != ',') { // skip ','
at_response_error();
return;
}
os_sprintf(buffer, "the first parameter:%d\r\n", result);
at_port_print(buffer);
//get the second parameter
// string
at_data_str_copy(buffer, &pPara, 10);
at_port_print("the second parameter:");
at_port_print(buffer);
at_port_print("\r\n");
if (*pPara == ',') {
pPara++; // skip ','
result = 0;
//there is the third parameter
// digit
flag = at_get_next_int_dec(&pPara, &result, &err);
// we donot care of flag
os_sprintf(buffer, "the third parameter:%d\r\n", result);
at_port_print(buffer);
}
if (*pPara != '\r') {
at_response_error();
return;
}
at_response_ok();
}
void ICACHE_FLASH_ATTR
at_testCmdTest(uint8_t id)
{
uint8 buffer[32] = {0};
os_sprintf(buffer, "%s\r\n", "at_testCmdTest");
at_port_print(buffer);
at_response_ok();
}
void ICACHE_FLASH_ATTR
at_queryCmdTest(uint8_t id)
{
uint8 buffer[32] = {0};
os_sprintf(buffer, "%s\r\n", "at_queryCmdTest");
at_port_print(buffer);
at_response_ok();
}
void ICACHE_FLASH_ATTR
at_exeCmdTest(uint8_t id)
{
uint8 buffer[32] = {0};
os_sprintf(buffer, "%s\r\n", "at_exeCmdTest");
at_port_print(buffer);
at_response_ok();
}
extern void at_exeCmdCiupdate(uint8_t id);
at_funcationType at_custom_cmd[] = {
{"+TEST", 5, at_testCmdTest, at_queryCmdTest, at_setupCmdTest, at_exeCmdTest},
#ifdef AT_UPGRADE_SUPPORT
{"+CIUPDATE", 9, NULL, NULL, NULL, at_exeCmdCiupdate}
#endif
};
void user_rf_pre_init(void)
{
}
void user_init(void)
{
char buf[64] = {0};
at_customLinkMax = 5;
at_init();
os_sprintf(buf,"compile time:%s %s",__DATE__,__TIME__);
at_set_custom_info(buf);
at_port_print("\r\nready\r\n");
at_cmd_array_regist(&at_custom_cmd[0], sizeof(at_custom_cmd)/sizeof(at_custom_cmd[0]));
}
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libdriver.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#include "ets_sys.h"
#include "osapi.h"
#include "driver/gpio16.h"
void ICACHE_FLASH_ATTR
gpio16_output_conf(void)
{
WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
(READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1); // mux configuration for XPD_DCDC to output rtc_gpio0
WRITE_PERI_REG(RTC_GPIO_CONF,
(READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); //mux configuration for out enable
WRITE_PERI_REG(RTC_GPIO_ENABLE,
(READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe) | (uint32)0x1); //out enable
}
void ICACHE_FLASH_ATTR
gpio16_output_set(uint8 value)
{
WRITE_PERI_REG(RTC_GPIO_OUT,
(READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(value & 1));
}
void ICACHE_FLASH_ATTR
gpio16_input_conf(void)
{
WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
(READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
WRITE_PERI_REG(RTC_GPIO_CONF,
(READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); //mux configuration for out enable
WRITE_PERI_REG(RTC_GPIO_ENABLE,
READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe); //out disable
}
uint8 ICACHE_FLASH_ATTR
gpio16_input_get(void)
{
return (uint8)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1);
}
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: hw_timer.c
*
* Description: hw_timer driver
*
* Modification history:
* 2014/5/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#define US_TO_RTC_TIMER_TICKS(t) \
((t) ? \
(((t) > 0x35A) ? \
(((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000)) : \
(((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \
0)
#define FRC1_ENABLE_TIMER BIT7
#define FRC1_AUTO_LOAD BIT6
//TIMER PREDIVED MODE
typedef enum {
DIVDED_BY_1 = 0, //timer clock
DIVDED_BY_16 = 4, //divided by 16
DIVDED_BY_256 = 8, //divided by 256
} TIMER_PREDIVED_MODE;
typedef enum { //timer interrupt mode
TM_LEVEL_INT = 1, // level interrupt
TM_EDGE_INT = 0, //edge interrupt
} TIMER_INT_MODE;
typedef enum {
FRC1_SOURCE = 0,
NMI_SOURCE = 1,
} FRC1_TIMER_SOURCE_TYPE;
/******************************************************************************
* FunctionName : hw_timer_arm
* Description : set a trigger timer delay for this timer.
* Parameters : uint32 val :
in autoload mode
50 ~ 0x7fffff; for FRC1 source.
100 ~ 0x7fffff; for NMI source.
in non autoload mode:
10 ~ 0x7fffff;
* Returns : NONE
*******************************************************************************/
void hw_timer_arm(u32 val)
{
RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val));
}
static void (* user_hw_timer_cb)(void) = NULL;
/******************************************************************************
* FunctionName : hw_timer_set_func
* Description : set the func, when trigger timer is up.
* Parameters : void (* user_hw_timer_cb_set)(void):
timer callback function,
* Returns : NONE
*******************************************************************************/
void hw_timer_set_func(void (* user_hw_timer_cb_set)(void))
{
user_hw_timer_cb = user_hw_timer_cb_set;
}
static void hw_timer_isr_cb(void)
{
if (user_hw_timer_cb != NULL) {
(*(user_hw_timer_cb))();
}
}
/******************************************************************************
* FunctionName : hw_timer_init
* Description : initilize the hardware isr timer
* Parameters :
FRC1_TIMER_SOURCE_TYPE source_type:
FRC1_SOURCE, timer use frc1 isr as isr source.
NMI_SOURCE, timer use nmi isr as isr source.
u8 req:
0, not autoload,
1, autoload mode,
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR hw_timer_init(FRC1_TIMER_SOURCE_TYPE source_type, u8 req)
{
if (req == 1) {
RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
} else {
RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
}
if (source_type == NMI_SOURCE) {
ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_isr_cb);
} else {
ETS_FRC_TIMER1_INTR_ATTACH(hw_timer_isr_cb, NULL);
}
TM1_EDGE_INT_ENABLE();
ETS_FRC1_INTR_ENABLE();
}
//-------------------------------Test Code Below--------------------------------------
#if 0
void hw_test_timer_cb(void)
{
static uint16 j = 0;
j++;
if ((WDEV_NOW() - tick_now2) >= 1000000) {
static u32 idx = 1;
tick_now2 = WDEV_NOW();
os_printf("b%u:%d\n", idx++, j);
j = 0;
}
//hw_timer_arm(50);
}
void ICACHE_FLASH_ATTR user_init(void)
{
hw_timer_init(FRC1_SOURCE, 1);
hw_timer_set_func(hw_test_timer_cb);
hw_timer_arm(100);
}
#endif
/*
NOTE:
1 if use nmi source, for autoload timer , the timer setting val can't be less than 100.
2 if use nmi source, this timer has highest priority, can interrupt other isr.
3 if use frc1 source, this timer can't interrupt other isr.
*/
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: i2c_master.c
*
* Description: i2c master API
*
* Modification history:
* 2014/3/12, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#include "driver/i2c_master.h"
LOCAL uint8 m_nLastSDA;
LOCAL uint8 m_nLastSCL;
/******************************************************************************
* FunctionName : i2c_master_setDC
* Description : Internal used function -
* set i2c SDA and SCL bit value for half clk cycle
* Parameters : uint8 SDA
* uint8 SCL
* Returns : NONE
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
i2c_master_setDC(uint8 SDA, uint8 SCL)
{
SDA &= 0x01;
SCL &= 0x01;
m_nLastSDA = SDA;
m_nLastSCL = SCL;
if ((0 == SDA) && (0 == SCL)) {
I2C_MASTER_SDA_LOW_SCL_LOW();
} else if ((0 == SDA) && (1 == SCL)) {
I2C_MASTER_SDA_LOW_SCL_HIGH();
} else if ((1 == SDA) && (0 == SCL)) {
I2C_MASTER_SDA_HIGH_SCL_LOW();
} else {
I2C_MASTER_SDA_HIGH_SCL_HIGH();
}
}
/******************************************************************************
* FunctionName : i2c_master_getDC
* Description : Internal used function -
* get i2c SDA bit value
* Parameters : NONE
* Returns : uint8 - SDA bit value
*******************************************************************************/
LOCAL uint8 ICACHE_FLASH_ATTR
i2c_master_getDC(void)
{
uint8 sda_out;
sda_out = GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO));
return sda_out;
}
/******************************************************************************
* FunctionName : i2c_master_init
* Description : initilize I2C bus to enable i2c operations
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_init(void)
{
uint8 i;
i2c_master_setDC(1, 0);
i2c_master_wait(5);
// when SCL = 0, toggle SDA to clear up
i2c_master_setDC(0, 0) ;
i2c_master_wait(5);
i2c_master_setDC(1, 0) ;
i2c_master_wait(5);
// set data_cnt to max value
for (i = 0; i < 28; i++) {
i2c_master_setDC(1, 0);
i2c_master_wait(5); // sda 1, scl 0
i2c_master_setDC(1, 1);
i2c_master_wait(5); // sda 1, scl 1
}
// reset all
i2c_master_stop();
return;
}
/******************************************************************************
* FunctionName : i2c_master_gpio_init
* Description : config SDA and SCL gpio to open-drain output mode,
* mux and gpio num defined in i2c_master.h
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_gpio_init(void)
{
ETS_GPIO_INTR_DISABLE() ;
// ETS_INTR_LOCK();
PIN_FUNC_SELECT(I2C_MASTER_SDA_MUX, I2C_MASTER_SDA_FUNC);
PIN_FUNC_SELECT(I2C_MASTER_SCL_MUX, I2C_MASTER_SCL_FUNC);
GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain;
GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_MASTER_SDA_GPIO));
GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain;
GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_MASTER_SCL_GPIO));
I2C_MASTER_SDA_HIGH_SCL_HIGH();
ETS_GPIO_INTR_ENABLE() ;
// ETS_INTR_UNLOCK();
i2c_master_init();
}
/******************************************************************************
* FunctionName : i2c_master_start
* Description : set i2c to send state
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_start(void)
{
i2c_master_setDC(1, m_nLastSCL);
i2c_master_wait(5);
i2c_master_setDC(1, 1);
i2c_master_wait(5); // sda 1, scl 1
i2c_master_setDC(0, 1);
i2c_master_wait(5); // sda 0, scl 1
}
/******************************************************************************
* FunctionName : i2c_master_stop
* Description : set i2c to stop sending state
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_stop(void)
{
i2c_master_wait(5);
i2c_master_setDC(0, m_nLastSCL);
i2c_master_wait(5); // sda 0
i2c_master_setDC(0, 1);
i2c_master_wait(5); // sda 0, scl 1
i2c_master_setDC(1, 1);
i2c_master_wait(5); // sda 1, scl 1
}
/******************************************************************************
* FunctionName : i2c_master_setAck
* Description : set ack to i2c bus as level value
* Parameters : uint8 level - 0 or 1
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_setAck(uint8 level)
{
i2c_master_setDC(m_nLastSDA, 0);
i2c_master_wait(5);
i2c_master_setDC(level, 0);
i2c_master_wait(5); // sda level, scl 0
i2c_master_setDC(level, 1);
i2c_master_wait(8); // sda level, scl 1
i2c_master_setDC(level, 0);
i2c_master_wait(5); // sda level, scl 0
i2c_master_setDC(1, 0);
i2c_master_wait(5);
}
/******************************************************************************
* FunctionName : i2c_master_getAck
* Description : confirm if peer send ack
* Parameters : NONE
* Returns : uint8 - ack value, 0 or 1
*******************************************************************************/
uint8 ICACHE_FLASH_ATTR
i2c_master_getAck(void)
{
uint8 retVal;
i2c_master_setDC(m_nLastSDA, 0);
i2c_master_wait(5);
i2c_master_setDC(1, 0);
i2c_master_wait(5);
i2c_master_setDC(1, 1);
i2c_master_wait(5);
retVal = i2c_master_getDC();
i2c_master_wait(5);
i2c_master_setDC(1, 0);
i2c_master_wait(5);
return retVal;
}
/******************************************************************************
* FunctionName : i2c_master_checkAck
* Description : get dev response
* Parameters : NONE
* Returns : true : get ack ; false : get nack
*******************************************************************************/
bool ICACHE_FLASH_ATTR
i2c_master_checkAck(void)
{
if(i2c_master_getAck()){
return FALSE;
}else{
return TRUE;
}
}
/******************************************************************************
* FunctionName : i2c_master_send_ack
* Description : response ack
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_send_ack(void)
{
i2c_master_setAck(0x0);
}
/******************************************************************************
* FunctionName : i2c_master_send_nack
* Description : response nack
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_send_nack(void)
{
i2c_master_setAck(0x1);
}
/******************************************************************************
* FunctionName : i2c_master_readByte
* Description : read Byte from i2c bus
* Parameters : NONE
* Returns : uint8 - readed value
*******************************************************************************/
uint8 ICACHE_FLASH_ATTR
i2c_master_readByte(void)
{
uint8 retVal = 0;
uint8 k, i;
i2c_master_wait(5);
i2c_master_setDC(m_nLastSDA, 0);
i2c_master_wait(5); // sda 1, scl 0
for (i = 0; i < 8; i++) {
i2c_master_wait(5);
i2c_master_setDC(1, 0);
i2c_master_wait(5); // sda 1, scl 0
i2c_master_setDC(1, 1);
i2c_master_wait(5); // sda 1, scl 1
k = i2c_master_getDC();
i2c_master_wait(5);
if (i == 7) {
i2c_master_wait(3); ////
}
k <<= (7 - i);
retVal |= k;
}
i2c_master_setDC(1, 0);
i2c_master_wait(5); // sda 1, scl 0
return retVal;
}
/******************************************************************************
* FunctionName : i2c_master_writeByte
* Description : write wrdata value(one byte) into i2c
* Parameters : uint8 wrdata - write value
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_writeByte(uint8 wrdata)
{
uint8 dat;
sint8 i;
i2c_master_wait(5);
i2c_master_setDC(m_nLastSDA, 0);
i2c_master_wait(5);
for (i = 7; i >= 0; i--) {
dat = wrdata >> i;
i2c_master_setDC(dat, 0);
i2c_master_wait(5);
i2c_master_setDC(dat, 1);
i2c_master_wait(5);
if (i == 0) {
i2c_master_wait(3); ////
}
i2c_master_setDC(dat, 0);
i2c_master_wait(5);
}
}
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: key.c
*
* Description: key driver, now can use different gpio and install different function
*
* Modification history:
* 2014/5/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "gpio.h"
#include "user_interface.h"
#include "driver/key.h"
LOCAL void key_intr_handler(struct keys_param *keys);
/******************************************************************************
* FunctionName : key_init_single
* Description : init single key's gpio and register function
* Parameters : uint8 gpio_id - which gpio to use
* uint32 gpio_name - gpio mux name
* uint32 gpio_func - gpio function
* key_function long_press - long press function, needed to install
* key_function short_press - short press function, needed to install
* Returns : single_key_param - single key parameter, needed by key init
*******************************************************************************/
struct single_key_param *ICACHE_FLASH_ATTR
key_init_single(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func, key_function long_press, key_function short_press)
{
struct single_key_param *single_key = (struct single_key_param *)os_zalloc(sizeof(struct single_key_param));
single_key->gpio_id = gpio_id;
single_key->gpio_name = gpio_name;
single_key->gpio_func = gpio_func;
single_key->long_press = long_press;
single_key->short_press = short_press;
return single_key;
}
/******************************************************************************
* FunctionName : key_init
* Description : init keys
* Parameters : key_param *keys - keys parameter, which inited by key_init_single
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
key_init(struct keys_param *keys)
{
uint8 i;
ETS_GPIO_INTR_ATTACH(key_intr_handler, keys);
ETS_GPIO_INTR_DISABLE();
for (i = 0; i < keys->key_num; i++) {
keys->single_key[i]->key_level = 1;
PIN_FUNC_SELECT(keys->single_key[i]->gpio_name, keys->single_key[i]->gpio_func);
gpio_output_set(0, 0, 0, GPIO_ID_PIN(keys->single_key[i]->gpio_id));
gpio_register_set(GPIO_PIN_ADDR(keys->single_key[i]->gpio_id), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
| GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
| GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));
//clear gpio14 status
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(keys->single_key[i]->gpio_id));
//enable interrupt
gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_NEGEDGE);
}
ETS_GPIO_INTR_ENABLE();
}
/******************************************************************************
* FunctionName : key_5s_cb
* Description : long press 5s timer callback
* Parameters : single_key_param *single_key - single key parameter
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
key_5s_cb(struct single_key_param *single_key)
{
os_timer_disarm(&single_key->key_5s);
// low, then restart
if (0 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
if (single_key->long_press) {
single_key->long_press();
}
}
}
/******************************************************************************
* FunctionName : key_50ms_cb
* Description : 50ms timer callback to check it's a real key push
* Parameters : single_key_param *single_key - single key parameter
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
key_50ms_cb(struct single_key_param *single_key)
{
os_timer_disarm(&single_key->key_50ms);
// high, then key is up
if (1 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
os_timer_disarm(&single_key->key_5s);
single_key->key_level = 1;
gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_NEGEDGE);
if (single_key->short_press) {
single_key->short_press();
}
} else {
gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_POSEDGE);
}
}
/******************************************************************************
* FunctionName : key_intr_handler
* Description : key interrupt handler
* Parameters : key_param *keys - keys parameter, which inited by key_init_single
* Returns : none
*******************************************************************************/
LOCAL void
key_intr_handler(struct keys_param *keys)
{
uint8 i;
uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
for (i = 0; i < keys->key_num; i++) {
if (gpio_status & BIT(keys->single_key[i]->gpio_id)) {
//disable interrupt
gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_DISABLE);
//clear interrupt status
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(keys->single_key[i]->gpio_id));
if (keys->single_key[i]->key_level == 1) {
// 5s, restart & enter softap mode
os_timer_disarm(&keys->single_key[i]->key_5s);
os_timer_setfn(&keys->single_key[i]->key_5s, (os_timer_func_t *)key_5s_cb, keys->single_key[i]);
os_timer_arm(&keys->single_key[i]->key_5s, 5000, 0);
keys->single_key[i]->key_level = 0;
gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_POSEDGE);
} else {
// 50ms, check if this is a real key up
os_timer_disarm(&keys->single_key[i]->key_50ms);
os_timer_setfn(&keys->single_key[i]->key_50ms, (os_timer_func_t *)key_50ms_cb, keys->single_key[i]);
os_timer_arm(&keys->single_key[i]->key_50ms, 50, 0);
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment