2667 lines
85 KiB
C
Executable File
2667 lines
85 KiB
C
Executable File
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
|
|
/* iot common header files */
|
|
#include "iot_io_api.h"
|
|
#include "iot_module_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_pkt_api.h"
|
|
#include "iot_ipc_api.h"
|
|
#include "iot_sg_ext_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "os_utils_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_i2c_api.h"
|
|
#include "iot_pwm_api.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "os_timer_api.h"
|
|
#include "iot_plc_api.h"
|
|
#include "iot_grapp.h"
|
|
#include "iot_proto_ge.h"
|
|
|
|
#include "iot_light_ctrl_drv.h"
|
|
#include "iot_proto_common.h"
|
|
#include "iot_adc_api.h"
|
|
#include "iot_energe_meter_api.h"
|
|
#include "iot_version_api.h"
|
|
#include "iot_ntoh_api.h"
|
|
|
|
#if IOT_LED_CTRL_APP_ENABLE && PLC_SUPPORT_STA_ROLE
|
|
|
|
#define IOT_LIGHT_MODULE_ID IOT_GREE_APP_MID
|
|
|
|
#if (HW_PLATFORM == HW_PLATFORM_SIMU)
|
|
#define ENABLE_LED_CTRL_HARDWARE (0)
|
|
#define IOT_LIGHT_CTRL_ADC_MODULE_ENABLE (0)
|
|
#else
|
|
#define ENABLE_LED_CTRL_HARDWARE (1)
|
|
#if IOT_ENERGE_METER_ENABLE
|
|
#define IOT_LIGHT_CTRL_ADC_MODULE_ENABLE (1)
|
|
#else
|
|
#define IOT_LIGHT_CTRL_ADC_MODULE_ENABLE (0)
|
|
#endif
|
|
#endif
|
|
|
|
#define IOT_LED_TIMMING_RELAY_ON_DELAY 50 /* 50ms delay after power up */
|
|
#define IOT_LED_TIMMING_POWERON_DELAY 1000 /* 1000ms delay after power up */
|
|
|
|
#define IOT_LIGHT_CURRENT_IN_THRESHOLD_MIN 50 /* 50mA */
|
|
|
|
/* GPIO config for power_on & relay */
|
|
#define IOT_LIGHT_GPIO_POWER 28
|
|
#define IOT_LIGHT_GPIO_RELAY 36
|
|
|
|
/* PWM output gpio, only A valid */
|
|
#define IOT_LIGHT_GPIO_PWM_A 23
|
|
#define IOT_LIGHT_GPIO_PWM_B 255
|
|
/* PWM channel */
|
|
#define IOT_LIGHT_PWM_CHANNEL 0
|
|
#define IOT_LIGHT_PWM_PERIOD 4000 /* unit is 1Hz */
|
|
|
|
/* when IIC slaver stays in power on/off, the gpio level 0/1 */
|
|
#define IOT_LIGHT_GPIO_VAL_POWER_ON 1
|
|
#define IOT_LIGHT_GPIO_VAL_POWER_OFF 0
|
|
|
|
/* when relay makes led light stays in working/off, the gpio level 0/1 */
|
|
#define IOT_LIGHT_GPIO_VAL_LED_ON 0
|
|
#define IOT_LIGHT_GPIO_VAL_LED_OFF 1
|
|
|
|
/* for new data check logic. */
|
|
#define IOT_LED_CTRL_DATA_CHECK_SAMPLE_MAX_LEN 6
|
|
#define IOT_LED_CTRL_DATA_CHECK_DELTA_MAX_LEN 6
|
|
#define iot_led_drv_get_delta_val(a, b) \
|
|
((a) > (b) ? ((a) - (b)) : ((b) - (a)))
|
|
/* this will not over IOT_LED_CTRL_DATA_CHECK_SAMPLE_MAX_LEN && bigger than 2. */
|
|
#define IOT_LED_CTRL_DATA_CHECK_SAMPLE_LEN_METER 6 /* meter data input */
|
|
#define IOT_LED_CTRL_DATA_CHECK_SAMPLE_LEN_LEAKAGE 6 /* leakage current */
|
|
/* this will not over IOT_LED_CTRL_DATA_CHECK_DELTA_MAX_LEN */
|
|
#define IOT_LED_CTRL_DATA_CHECK_DELTA_LEN_METER 3 /* meter data input */
|
|
#define IOT_LED_CTRL_DATA_CHECK_DELTA_LEN_LEAKAGE 3 /* leakage current */
|
|
/* delta value */
|
|
#define IOT_LED_CTRL_DATA_CHECK_DELTA_VALUE_METER 40000 /* 40V */
|
|
#define IOT_LED_CTRL_DATA_CHECK_DELTA_VALUE_LEAKAGE 20 /* 20mA */
|
|
|
|
#if (IOT_PSRAM_ENABLE)
|
|
/* number of messages pending in queue. */
|
|
#define IOT_LED_CTRL_TASK_POOL_SIZE (128)
|
|
/* stack size of task */
|
|
#define IOT_LED_CTRL_TASK_STACK_SIZE 1024
|
|
#else
|
|
/* number of messages pending in queue. */
|
|
#define IOT_LED_CTRL_TASK_POOL_SIZE (64)
|
|
/* stack size of task */
|
|
#define IOT_LED_CTRL_TASK_STACK_SIZE 512
|
|
#endif
|
|
|
|
/* message type */
|
|
#define IOT_LED_CTRL_MSG_DATA (0)
|
|
#define IOT_LED_CTRL_MSG_TIMER (1)
|
|
#define IOT_LED_CTRL_MSG_INTERNAL (2)
|
|
|
|
/* message id for IOT_LED_CTRL_MSG_DATA */
|
|
#define IOT_LED_CTRL_MSG_ID_UART_DATA (0)
|
|
#define IOT_LED_CTRL_MSG_ID_PLC_DATA (1)
|
|
#define IOT_LED_CTRL_MSG_ID_PLC_CCO_MAC (2)
|
|
|
|
/* message id for IOT_LED_CTRL_MSG_TIMER */
|
|
#define IOT_LED_CTRL_MSG_ID_TMR_TIMEOUT (2)
|
|
|
|
/* message id for IOT_LED_CTRL_MSG_TIMER */
|
|
#define IOT_LED_CTRL_MSG_ID_REPORT_TMR_TIMEOUT (3)
|
|
|
|
/* message id for IOT_LED_CTRL_MSG_INTERNAL */
|
|
#define IOT_LED_CTRL_MSG_INTERNAL_LEAKAGE_CURRENT (1)
|
|
#define IOT_LED_CTRL_MSG_INTERNAL_IN_METER_PARAM (2)
|
|
#define IOT_LED_CTRL_MSG_INTERNAL_UPDATE_CCO_MAC (3)
|
|
|
|
/* timer interval, ms */
|
|
#define IOT_LED_TIMER_INTERVAL (100)
|
|
|
|
/* Openloop check time */
|
|
#define IOT_LED_OPENLOOP_CHECK_TIME 1000
|
|
|
|
/* input voltage abnormal check time */
|
|
#define IOT_LED_IN_VOL_ABNOR_CHECK_TIME 5000
|
|
|
|
/* report timer interval, ms */
|
|
#define IOT_LED_REPORT_TIMER_INTERVAL (5 * 1000) /* 5s */
|
|
|
|
/* wati report ack time */
|
|
#define IOT_LED_WAIT_REPORT_ACK_INTERVAL (10 * 1000) /* 10s */
|
|
|
|
/* no ack report Max count */
|
|
#define IOT_LED_REPORT_MAX_COUNT (5)
|
|
|
|
/* Leakage current threshold, unit is mA. */
|
|
#define IOT_LIGHT_CTRL_LEAKAGE_CURRENT_THR (30)
|
|
|
|
/* the correction result, successful or fail */
|
|
enum _correction_result_e {
|
|
IOT_LIGHT_CORRECTION_SUCCESS = 1,
|
|
IOT_LIGHT_CORRECTION_FAIL = 2,
|
|
};
|
|
|
|
/* light state check bit */
|
|
enum _iot_light_state_check_e{
|
|
IOT_LIGHT_CHECK_POWER_STATE = 0,
|
|
IOT_LIGHT_CHECK_UNDER_VOLTAGE = 1,
|
|
IOT_LIGHT_CHECK_OVER_VOLTAGE = 2,
|
|
IOT_LIGHT_CHECK_OVER_POWER = 3,
|
|
IOT_LIGHT_CHECK_OPEN_LOOP = 4,
|
|
IOT_LIGHT_CHECK_SHORT_CIRCUIT = 5,
|
|
IOT_LIGHT_CHECK_UN_START = 6,
|
|
IOT_LIGHT_CHECK_LOW_TEMPERATURE = 7,
|
|
IOT_LIGHT_CHECK_OVER_TEMPERATURE = 8,
|
|
IOT_LIGHT_CHECK_OVER_LEAKCURRENT = 9,
|
|
};
|
|
|
|
//TODO: will be change according to customer needs
|
|
#define IOT_LIGHT_VOLTAGE_MIN (1760) /* 0.1V */
|
|
#define IOT_LIGHT_VOLTAGE_MAX (2640) /* 0.1V */
|
|
#define IOT_LIGHT_POWER_MAX (4000) /* 0.1W */
|
|
|
|
/* type of function send pkt data to ge. */
|
|
typedef uint8_t(*data_send_to_ge)(uint8_t *buf, uint16_t buf_len);
|
|
|
|
typedef struct _iot_led_ctrl_data_check_t {
|
|
uint32_t first_run; /* if this first run this check */
|
|
uint32_t delta_value; /* delta value compare with new coming data. */
|
|
uint8_t sample_cnt; /* sample count of this check */
|
|
uint8_t delta_cnt; /* delta count of this check */
|
|
uint8_t delta_index; /* current index of data in delta queue */
|
|
int32_t sample_queue[IOT_LED_CTRL_DATA_CHECK_SAMPLE_MAX_LEN];/* queue for sample data */
|
|
int32_t delta_queue[IOT_LED_CTRL_DATA_CHECK_DELTA_MAX_LEN]; /* queue for delta data */
|
|
}iot_led_ctrl_data_check_t;
|
|
|
|
/** led controller task message */
|
|
typedef struct _iot_led_ctrl_msg {
|
|
/* iot task message */
|
|
iot_task_msg_t task_msg;
|
|
/* pointer to message data */
|
|
void *data;
|
|
/* another data field */
|
|
uint32_t data2;
|
|
} iot_led_ctrl_msg_t;
|
|
|
|
/* function type of command. */
|
|
typedef void (*iot_light_fn_t)(void *data, uint32_t d_len);
|
|
|
|
typedef struct _iot_light_controller_handle_t {
|
|
/* command code. */
|
|
uint32_t command;
|
|
/* function handle of command code. */
|
|
iot_light_fn_t fn_command;
|
|
} iot_light_ctrl_handle_t;
|
|
|
|
/* param of power. */
|
|
typedef struct _iot_light_power_param_t {
|
|
/* device type. Reference to DEV_TYPE_LED_xxxW */
|
|
uint8_t device_type;
|
|
/* temperature of power device. */
|
|
int8_t temperature;
|
|
/* power factor of output power. */
|
|
uint8_t factor;
|
|
/* brightness level of channel a LED light. */
|
|
uint8_t light_level_a;
|
|
/* brightness level of channel b LED light. */
|
|
uint8_t light_level_b;
|
|
/* leakage */
|
|
uint8_t leakage;
|
|
/* if power up */
|
|
uint8_t power_up;
|
|
/* if open loop */
|
|
uint8_t open_loop;
|
|
/* voltage of input, over range */
|
|
uint8_t vol_abnormal;
|
|
/* voltage of input. 0.1V */
|
|
uint16_t voltage_in;
|
|
/* current of input. 1mA */
|
|
uint16_t current_in;
|
|
/* voltage of output. 0.1V */
|
|
uint16_t voltage_out;
|
|
/* current of output. 1mA */
|
|
uint16_t current_out;
|
|
/* active power of input. 0.1W */
|
|
uint16_t power_in;
|
|
/* current of leakage. 1mA */
|
|
int16_t leakage_current;
|
|
/*
|
|
* power state.
|
|
* BIT : 9 8 7 6 5 4 3 2 1 0
|
|
* FUN : OLC OT LT US SC OL OP OV UV PS
|
|
* OLC : Over LeakCurrent, see IOT_LIGHT_CTRL_LEAKAGE_CURRENT_THR defined
|
|
* OT : Over Temperature, 1 over, 0 normal.
|
|
* LT : Low Temperature, 1 low, 0 normal.
|
|
* US : Un Start, 1 cannot start, 0 normal.
|
|
* SC : Short Circuit, 1 short circuit, 0 normal.
|
|
* OL : Open Loop, 1 looped, 0 normal.
|
|
* OP : Over Power, 1 over, 0 normal.
|
|
* OV : Over Voltage, 1 over, 0 normal.
|
|
* UV : Under Voltage, 1 low, 0 normal. 165~265V
|
|
* PS : Power State , 1 on, 0 off.
|
|
*/
|
|
uint16_t power_state;
|
|
} iot_light_power_param_t;
|
|
|
|
typedef struct _iot_light_object_t {
|
|
/* Group this device belongs to. */
|
|
uint8_t group;
|
|
/* to control 3386c to reset. */
|
|
uint8_t gpio_power_on;
|
|
/* to control relay to protect led from over current. */
|
|
uint8_t gpio_relay;
|
|
/* param of this power. */
|
|
iot_light_power_param_t param;
|
|
} iot_light_object_t;
|
|
|
|
typedef struct _iot_led_controller_t {
|
|
/* task handle */
|
|
iot_task_h task;
|
|
/* timer handle */
|
|
timer_id_t timer;
|
|
/* function to send data to ge */
|
|
data_send_to_ge data_to_ge_fn;
|
|
/* led struct. */
|
|
iot_light_object_t led;
|
|
/* led light mac address. */
|
|
uint8_t local_mac[IOT_MAC_ADDR_LEN];
|
|
/* module ok? */
|
|
uint32_t module_ready;
|
|
/* timer handle for report state */
|
|
timer_id_t report_timer;
|
|
/* voltage check timer counter */
|
|
uint8_t vol_abnormal_check_cnt;
|
|
/* report count without receive ack */
|
|
uint8_t report_count;
|
|
/* save power state changes for report */
|
|
uint16_t report_power_state;
|
|
/* flash info */
|
|
iot_led_pib_info_t pib_info;
|
|
/* Leakage & meter data input check. */
|
|
iot_led_ctrl_data_check_t check_leakage_current;
|
|
iot_led_ctrl_data_check_t check_meter_voltage;
|
|
} iot_led_ctrl_t;
|
|
|
|
/* This is the output current & voltage & pwm value on each brightness. */
|
|
typedef struct _iot_led_param_table_on_brightness_t {
|
|
uint16_t i; /* current of output. 1mA */
|
|
uint16_t v; /* voltage of output. 0.1V */
|
|
uint16_t pwm; /* PWM , 1% */
|
|
}iot_led_param_on_brightness_t;
|
|
|
|
#ifndef min
|
|
#define min(a, b) ((a) > (b) ? (b) : (a))
|
|
#endif
|
|
|
|
#ifndef max
|
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
|
#endif
|
|
|
|
static iot_led_ctrl_t iot_led_controller;
|
|
|
|
#define IOT_LIGHT_DATA_DUMP
|
|
|
|
void iot_light_save_led_info(void);
|
|
|
|
/* input : vol 1mV, cur 1mA, pow 1mW, fac 0.01% */
|
|
#define iot_light_set_msg_meter_par(vol, cur, pow, fac, pmsg)\
|
|
do{\
|
|
(pmsg)->data = (void *)(((((fac) / 100) & 0xFFFF) << 16) \
|
|
| (((pow) / 100) & 0xFFFF));\
|
|
(pmsg)->data2 = (cur) & 0xFFFF;\
|
|
(pmsg)->data2 |= (((vol) / 100) & 0xFFFF) << 16;\
|
|
}while(0)
|
|
|
|
/* output : vol 0.1V, cur 1mA, pow 0.1W, fac 1% */
|
|
#define iot_light_get_msg_meter_par(vol, cur, pow, fac, pmsg)\
|
|
do{\
|
|
(fac) = ((uint32_t)(pmsg)->data) >> 16;\
|
|
(pow) = ((uint32_t)(pmsg)->data) & 0xFFFF;\
|
|
(cur) = (pmsg)->data2 & 0xFFFF;\
|
|
(vol) = ((pmsg)->data2) >> 16;\
|
|
}while(0)
|
|
|
|
#ifdef IOT_LIGHT_DATA_DUMP
|
|
extern void iot_common_bin_dump(uint8_t *data, uint32_t dlen);
|
|
#define iot_light_data_dump(buf, len) \
|
|
iot_common_bin_dump((uint8_t *)buf, (uint32_t)len)
|
|
#else
|
|
#define iot_light_data_dump(buf, len)
|
|
#endif
|
|
|
|
void iot_led_crtl_msg_post_to_ge(iot_pkt_t* resp_pkt);
|
|
|
|
#if (!ENABLE_LED_CTRL_HARDWARE)
|
|
/**
|
|
* @brief iot_light_drv_set_led_brightness() - driver to set brightness of led.
|
|
* @param channel: A or B or A&B channel to control.
|
|
* @param percent: percent of brightness, 0~100 -> 0%~100%.
|
|
*/
|
|
void iot_light_drv_set_led_brightness(uint32_t channel, uint32_t percent)
|
|
{
|
|
(void)channel;
|
|
(void)percent;
|
|
}
|
|
#else
|
|
|
|
#define IOT_LIGHT_BRITNESS_TABLE_POINTS_CNT 11 /* 0% ~ 100% */
|
|
#define IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS 10 /* 10% between 2 points */
|
|
/* param value from 0% to 100% on brightness */
|
|
const static iot_led_param_on_brightness_t iot_led_param_tb[IOT_LIGHT_BRITNESS_TABLE_POINTS_CNT] = {
|
|
{0, 0, 0},
|
|
{40, 3600, 4},
|
|
{75, 3640, 6},
|
|
{113, 3680, 9},
|
|
{158, 3780, 11},
|
|
{195, 3840, 14},
|
|
{229, 3890, 18},
|
|
{269, 3950, 24},
|
|
{304, 3990, 30},
|
|
{337, 4030, 41},
|
|
{365, 4070, 78}
|
|
};
|
|
|
|
/**
|
|
* @brief iot_light_drv_get_param_tb() - Get param table on given brightness value.
|
|
* @param brightness: percent of brightness, 0~100 -> 0%~100%.
|
|
* @param param_tb: table to return.
|
|
*/
|
|
static void iot_light_drv_get_param_tb(uint32_t brightness, iot_led_param_on_brightness_t *param_tb)
|
|
{
|
|
uint32_t delta, percent, last_idx, next_idx;
|
|
|
|
percent = min(brightness, IOT_LIGHT_BRIGHTNESS_MAX_LEVEL_THRESHOLD);
|
|
|
|
/* Get the indexes of table before and after the brightness we want. */
|
|
last_idx = (percent / IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS);
|
|
next_idx = (0 == (percent % IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS)) ? last_idx : (last_idx + 1);
|
|
|
|
/* Get param from brightness mapping table. */
|
|
if (last_idx == next_idx) {
|
|
/* the brightness just on one of tables. */
|
|
param_tb->pwm = iot_led_param_tb[last_idx].pwm;
|
|
param_tb->i = iot_led_param_tb[last_idx].i;
|
|
param_tb->v = iot_led_param_tb[last_idx].v;
|
|
} else {
|
|
/* the brightness between 2 tables. */
|
|
/* Get pwm */
|
|
delta = iot_led_param_tb[next_idx].pwm - iot_led_param_tb[last_idx].pwm;
|
|
param_tb->pwm = iot_led_param_tb[last_idx].pwm + ((percent % IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS)
|
|
* delta / IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS);
|
|
|
|
/* Get current */
|
|
delta = iot_led_param_tb[next_idx].i - iot_led_param_tb[last_idx].i;
|
|
param_tb->i = iot_led_param_tb[last_idx].i + ((percent % IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS)
|
|
* delta / IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS);
|
|
|
|
/* Get voltage */
|
|
delta = iot_led_param_tb[next_idx].v - iot_led_param_tb[last_idx].v;
|
|
param_tb->v = iot_led_param_tb[last_idx].v + ((percent % IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS)
|
|
* delta / IOT_LIGHT_BRITNESS_STEP_LEN_ON_POINTS);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_set_control_param() - Set PWM duty & update volgate-out/current-out
|
|
* by brightness value.
|
|
* @param brightness: percent of brightness, 0~100 -> 0%~100%.
|
|
*/
|
|
static void iot_light_drv_set_control_param(uint32_t brightness)
|
|
{
|
|
iot_led_param_on_brightness_t param;
|
|
|
|
/* Get param from brightness mapping table. */
|
|
iot_light_drv_get_param_tb(brightness, ¶m);
|
|
|
|
iot_pwm_set_duty(IOT_LIGHT_PWM_CHANNEL, param.pwm * 100);
|
|
|
|
/* Update v & i from table into led status. */
|
|
iot_led_controller.led.param.current_out = param.i;
|
|
iot_led_controller.led.param.voltage_out = param.v;
|
|
|
|
iot_cus_printf("[LIGHT_DRV]Set PWM duty as %d%%. v_out=%d(0.1v), i_out=%d(1mA).\n",
|
|
param.pwm, param.v, param.i);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_set_relay_on() - control the relay to enable led.
|
|
* @param relay_on: true -> enable led, false -> disable led.
|
|
*/
|
|
static void iot_light_drv_set_relay_on(uint32_t relay_on)
|
|
{
|
|
int val = relay_on ? IOT_LIGHT_GPIO_VAL_LED_ON : IOT_LIGHT_GPIO_VAL_LED_OFF;
|
|
|
|
if (ERR_OK != iot_gpio_value_set(iot_led_controller.led.gpio_relay, val)) {
|
|
iot_cus_printf("[LIGHT_DRV]write relay failed.\n");
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_set_pi_on() - control the pi chip.
|
|
* @param pi_on: true -> power up, false -> power down.
|
|
*/
|
|
static void iot_light_drv_set_pi_on(uint32_t pi_on)
|
|
{
|
|
int val = pi_on ? IOT_LIGHT_GPIO_VAL_POWER_ON : IOT_LIGHT_GPIO_VAL_POWER_OFF;
|
|
|
|
if (ERR_OK != iot_gpio_value_set(iot_led_controller.led.gpio_power_on, val)) {
|
|
iot_cus_printf("[LIGHT_DRV]write power failed.\n");
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_poweroff() - power off led.
|
|
*/
|
|
static void iot_light_drv_poweroff(void)
|
|
{
|
|
/* Set poweroff. */
|
|
iot_led_controller.led.param.power_up = false;
|
|
|
|
/* shutdown pi chip */
|
|
iot_light_drv_set_pi_on(false);
|
|
|
|
/* set power off */
|
|
iot_light_drv_set_control_param(0);
|
|
|
|
/* Set PWM as low */
|
|
if (ERR_OK != iot_gpio_open_as_output(IOT_LIGHT_GPIO_PWM_A)) {
|
|
iot_gpio_close(IOT_LIGHT_GPIO_PWM_A);
|
|
/* do not care about return. open an gpio will cut the signal off. */
|
|
iot_gpio_open_as_output(IOT_LIGHT_GPIO_PWM_A);
|
|
}
|
|
iot_gpio_value_set(IOT_LIGHT_GPIO_PWM_A, 0); /* Pull low */
|
|
|
|
iot_cus_printf("[LIGHT_DRV]iot_light_drv_poweroff.\n");
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_protect() - protect device.
|
|
*/
|
|
void iot_light_drv_protect(void)
|
|
{
|
|
/* disable relay */
|
|
iot_light_drv_set_relay_on(false);
|
|
|
|
/* power off led */
|
|
iot_light_drv_poweroff();
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_powerup() - power up led.
|
|
*/
|
|
static void iot_light_drv_powerup(uint32_t brightness)
|
|
{
|
|
/* enable relay && delay */
|
|
iot_light_drv_set_relay_on(true);
|
|
os_delay(IOT_LED_TIMMING_RELAY_ON_DELAY);
|
|
|
|
/* powerup pi chip && delay */
|
|
iot_light_drv_set_pi_on(true);
|
|
os_delay(IOT_LED_TIMMING_POWERON_DELAY);
|
|
|
|
/* set pwm */
|
|
iot_light_drv_set_control_param(brightness);
|
|
|
|
/* Close gpio pin, config it to link PWM signal. */
|
|
iot_gpio_close(IOT_LIGHT_GPIO_PWM_A);
|
|
iot_pwm_gpio_config(IOT_LIGHT_PWM_CHANNEL, IOT_LIGHT_GPIO_PWM_A, IOT_LIGHT_GPIO_PWM_B);
|
|
|
|
iot_cus_printf("[LIGHT_DRV]iot_light_drv_powerup.\n");
|
|
|
|
/* Set powerup */
|
|
iot_led_controller.led.param.power_up = true;
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_set_led_brightness() - driver to set brightness of led.
|
|
* @param channel: A or B or A&B channel to control.
|
|
* @param percent: percent of brightness, 0~100 -> 0%~100%.
|
|
*/
|
|
void iot_light_drv_set_led_brightness(uint32_t channel, uint32_t percent)
|
|
{
|
|
if (iot_led_controller.led.param.leakage) {
|
|
if(IOT_LIGHT_BRIGHTNESS_SHUTDOWN_THRESHOLD > percent) {
|
|
/* Clear leakage when shutdown. */
|
|
iot_led_controller.led.param.leakage = false;
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]Cannot control LED when leakage.\n");
|
|
}
|
|
} else if (iot_led_controller.led.param.vol_abnormal) {
|
|
iot_cus_printf("[LIGHT_DRV]Cannot control LED when voltage abnormal.\n");
|
|
} else if (IOT_LIGHT_BRIGHTNESS_SHUTDOWN_THRESHOLD > percent) {
|
|
iot_light_drv_poweroff();
|
|
iot_cus_printf("[LIGHT_DRV]Poweroff LED.\n");
|
|
} else if (!iot_led_controller.led.param.power_up) {
|
|
iot_light_drv_powerup(percent);
|
|
iot_cus_printf("[LIGHT_DRV]Powerup LED.\n");
|
|
} else {
|
|
iot_light_drv_set_control_param(percent);
|
|
iot_cus_printf("[LIGHT_DRV]Control brightness of LED as %d%%.\n", percent);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_initialize_pwm() - To initialize PWM module.
|
|
*/
|
|
static void iot_light_drv_initialize_pwm(void)
|
|
{
|
|
uint32_t pwm_clk;
|
|
iot_gpio_open_as_output(IOT_LIGHT_GPIO_PWM_A);
|
|
|
|
iot_gpio_value_set(IOT_LIGHT_GPIO_PWM_A, 0); /* Pull low */
|
|
|
|
/* init pwm */
|
|
iot_pwm_hw_init(IOT_PWM_CHANNEL_0);
|
|
|
|
pwm_clk = iot_pwm_get_ch_clk(IOT_PWM_CHANNEL_0);
|
|
|
|
iot_pwm_set_period(IOT_PWM_CHANNEL_0, pwm_clk / IOT_LIGHT_PWM_PERIOD);
|
|
|
|
return;
|
|
}
|
|
|
|
static uint16_t iot_light_drv_get_current_in(void)
|
|
{
|
|
/* TODO : get current from ADC */
|
|
return iot_led_controller.led.param.current_in;
|
|
}
|
|
|
|
static void iot_light_drv_open_loop_check(void)
|
|
{
|
|
static uint32_t glance_wait = 0;
|
|
|
|
/* Wait for 1S */
|
|
if (++glance_wait < (IOT_LED_OPENLOOP_CHECK_TIME / IOT_LED_TIMER_INTERVAL)) {
|
|
return;
|
|
}
|
|
|
|
glance_wait = 0;
|
|
|
|
/* Power off */
|
|
if (!iot_led_controller.led.param.power_up) {
|
|
/* No need to restore the brightness */
|
|
iot_led_controller.led.param.open_loop = false;
|
|
return;
|
|
}
|
|
|
|
/* Check current */
|
|
if (iot_light_drv_get_current_in() < IOT_LIGHT_CURRENT_IN_THRESHOLD_MIN) {
|
|
/* Abnormal. Set PWM as lowest. Check again at last time. */
|
|
iot_led_controller.led.param.open_loop = true;
|
|
iot_light_drv_set_control_param(IOT_LIGHT_BRIGHTNESS_OPENLOOP_THRESHOLD);
|
|
return;
|
|
}
|
|
|
|
/* In open loop state already.. */
|
|
if (iot_led_controller.led.param.open_loop) {
|
|
/* Normal. Clear state && Restore brightness level */
|
|
iot_led_controller.led.param.open_loop = false;
|
|
iot_light_drv_set_led_brightness(IOT_LIGHT_CHAN_ALL,
|
|
iot_led_controller.led.param.light_level_a / 2);
|
|
} else {
|
|
/* Do nothing. It's normal. */
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_voltage_abnormal_check() - To check if input-volgate
|
|
* over range.
|
|
*/
|
|
static void iot_light_drv_voltage_abnormal_check(void)
|
|
{
|
|
uint32_t abnormal = false;
|
|
|
|
/* Wait for 5S */
|
|
if (++iot_led_controller.vol_abnormal_check_cnt
|
|
< (IOT_LED_IN_VOL_ABNOR_CHECK_TIME / IOT_LED_TIMER_INTERVAL)) {
|
|
return;
|
|
}
|
|
|
|
iot_led_controller.vol_abnormal_check_cnt = 0;
|
|
|
|
/* check if voltage abnormal. */
|
|
if ((iot_led_controller.led.param.voltage_in < IOT_LIGHT_VOLTAGE_MIN)
|
|
|| (iot_led_controller.led.param.voltage_in > IOT_LIGHT_VOLTAGE_MAX)){
|
|
abnormal = true;
|
|
}
|
|
|
|
if (abnormal) {
|
|
if (iot_led_controller.led.param.vol_abnormal) {
|
|
iot_cus_printf("[LIGHT_DRV]check voltage, stay in abnormal.\n");
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]check voltage, run into abnormal.\n");
|
|
/* do protect */
|
|
iot_light_drv_protect();
|
|
iot_led_controller.led.param.vol_abnormal = true;
|
|
}
|
|
} else {
|
|
if (iot_led_controller.led.param.vol_abnormal) {
|
|
iot_cus_printf("[LIGHT_DRV]check voltage, restore from abnormal.\n");
|
|
iot_led_controller.led.param.vol_abnormal = false;
|
|
/* restore brightness. */
|
|
iot_light_drv_set_led_brightness(IOT_LIGHT_CHAN_ALL,
|
|
iot_led_controller.led.param.light_level_a / 2);
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]check voltage, stay in normal.\n");
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_initialize_hardware() - initialize hardware of
|
|
* this module.
|
|
* @return ERR_FAIL - Operation failed, ERR_OK - Operation Successful
|
|
*/
|
|
uint32_t iot_light_drv_initialize_hardware(void)
|
|
{
|
|
if (ERR_OK != iot_gpio_open_as_output(iot_led_controller.led.gpio_power_on)) {
|
|
iot_cus_printf("[LIGHT_DRV]open gpio for power failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
/* power down pi chip */
|
|
iot_light_drv_set_pi_on(false);
|
|
|
|
if (ERR_OK != iot_gpio_open_as_output(iot_led_controller.led.gpio_relay)) {
|
|
iot_cus_printf("[LIGHT_DRV]open gpio for relay failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
/* set relay on */
|
|
iot_light_drv_set_relay_on(true);
|
|
|
|
iot_light_drv_initialize_pwm();
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @brief iot_light_drv_set_light_level() - To set the brightness level of light
|
|
* on given channel.
|
|
* @param channel: A or B or A&B channel to control.
|
|
* @param level: level between 0 ~ 200.
|
|
*/
|
|
static void iot_light_drv_set_light_level(uint8_t channel, uint8_t level)
|
|
{
|
|
uint8_t save_flag = 0;
|
|
|
|
iot_cus_printf("[LIGHT_DRV]Set level from a=%d b=%d to %d.\n",
|
|
iot_led_controller.led.param.light_level_a,
|
|
iot_led_controller.led.param.light_level_b, level);
|
|
|
|
/*
|
|
* Do not care about channel, this controller just has a single led light.
|
|
*/
|
|
if (iot_led_controller.led.param.light_level_a != level ||
|
|
iot_led_controller.led.param.light_level_b != level) {
|
|
save_flag = 1;
|
|
iot_led_controller.led.param.light_level_a = level;
|
|
iot_led_controller.led.param.light_level_b = level;
|
|
|
|
iot_led_controller.pib_info.level_a = level;
|
|
iot_led_controller.pib_info.level_b = level;
|
|
}
|
|
|
|
iot_light_drv_set_led_brightness(channel, level / 2);
|
|
|
|
if (save_flag)
|
|
iot_light_save_led_info();
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_check_power_state_changed() check power state changed
|
|
* @return false - no change, true - changed.
|
|
*/
|
|
static bool_t iot_light_check_power_state_changed()
|
|
{
|
|
uint16_t check_bit = 0;
|
|
|
|
/* check Under Voltage */
|
|
check_bit |= 1 << IOT_LIGHT_CHECK_UNDER_VOLTAGE;
|
|
/* check Over Voltage */
|
|
check_bit |= 1 << IOT_LIGHT_CHECK_OVER_VOLTAGE;
|
|
/* check Over Power */
|
|
check_bit |= 1 << IOT_LIGHT_CHECK_OVER_POWER;
|
|
/* check Open Loop */
|
|
check_bit |= 1 << IOT_LIGHT_CHECK_OPEN_LOOP;
|
|
/* check Un Start */
|
|
check_bit |= 1 << IOT_LIGHT_CHECK_UN_START;
|
|
/* check Over LeakCurrent */
|
|
check_bit |= 1 << IOT_LIGHT_CHECK_OVER_LEAKCURRENT;
|
|
|
|
if ((iot_led_controller.report_power_state & check_bit) !=
|
|
(iot_led_controller.led.param.power_state &check_bit)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_report_power_state_handle() - report power state handle
|
|
*/
|
|
static void iot_light_drv_report_power_state_handle()
|
|
{
|
|
/* save last state */
|
|
iot_led_controller.report_power_state =
|
|
iot_led_controller.led.param.power_state;
|
|
if (iot_led_controller.report_count <= IOT_LED_REPORT_MAX_COUNT) {
|
|
/* Generate random time */
|
|
uint32_t delay = os_rand() % IOT_LED_REPORT_TIMER_INTERVAL;
|
|
iot_led_controller.report_count++;
|
|
|
|
#if ENABLE_LED_CTRL_HARDWARE
|
|
/* set a report timer */
|
|
os_start_timer(iot_led_controller.report_timer, delay);
|
|
#endif
|
|
iot_cus_printf("[LIGHT_DRV]report timer started, %d ms state=%X\n",
|
|
delay, iot_led_controller.report_power_state);
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]report count is %d\n",
|
|
iot_led_controller.report_count);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_drv_update_power_param() - timer trigger this to update
|
|
* param of power.
|
|
*/
|
|
static void iot_light_drv_update_power_param()
|
|
{
|
|
static uint8_t cnt = 0;
|
|
|
|
/* check power state */
|
|
if (iot_led_controller.led.param.power_up) {
|
|
iot_led_controller.led.param.power_state |=
|
|
1 << IOT_LIGHT_CHECK_POWER_STATE;
|
|
} else {
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_POWER_STATE);
|
|
}
|
|
|
|
/* check voltage in */
|
|
if (iot_led_controller.led.param.voltage_in < IOT_LIGHT_VOLTAGE_MIN) {
|
|
iot_led_controller.led.param.power_state |=
|
|
1 << IOT_LIGHT_CHECK_UNDER_VOLTAGE;
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_OVER_VOLTAGE);
|
|
} else if (iot_led_controller.led.param.voltage_in > IOT_LIGHT_VOLTAGE_MAX) {
|
|
iot_led_controller.led.param.power_state |=
|
|
1 << IOT_LIGHT_CHECK_OVER_VOLTAGE;
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_UNDER_VOLTAGE);
|
|
} else {
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_OVER_VOLTAGE);
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_UNDER_VOLTAGE);
|
|
}
|
|
|
|
/* check power in */
|
|
if (iot_led_controller.led.param.power_in > IOT_LIGHT_POWER_MAX) {
|
|
iot_led_controller.led.param.power_state |=
|
|
1 << IOT_LIGHT_CHECK_OVER_POWER;
|
|
} else {
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_OVER_POWER);
|
|
}
|
|
|
|
/* check open loop */
|
|
if (iot_led_controller.led.param.open_loop) {
|
|
iot_led_controller.led.param.power_state |=
|
|
1 << IOT_LIGHT_CHECK_OPEN_LOOP;
|
|
} else {
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_OPEN_LOOP);
|
|
}
|
|
|
|
/* check over leakage current */
|
|
if (iot_led_controller.led.param.leakage) {
|
|
iot_led_controller.led.param.power_state |=
|
|
1 << IOT_LIGHT_CHECK_OVER_LEAKCURRENT;
|
|
} else {
|
|
iot_led_controller.led.param.power_state &=
|
|
~(1 << IOT_LIGHT_CHECK_OVER_LEAKCURRENT);
|
|
}
|
|
|
|
iot_cus_printf("[LIGHT_DRV]update_power_param power_state=0x%X\n",
|
|
iot_led_controller.led.param.power_state);
|
|
|
|
cnt++;
|
|
if (iot_led_controller.module_ready) {
|
|
if (iot_light_check_power_state_changed()) {
|
|
cnt = 0;
|
|
iot_led_controller.report_count = 0;
|
|
iot_light_drv_report_power_state_handle();
|
|
} else if ((iot_led_controller.report_count > 0) &&
|
|
(iot_led_controller.report_count <
|
|
IOT_LED_REPORT_MAX_COUNT) &&
|
|
(cnt % (IOT_LED_WAIT_REPORT_ACK_INTERVAL / IOT_LED_TIMER_INTERVAL)
|
|
== 0)){
|
|
cnt = 0;
|
|
/* have no received report ack after 10sec, retry report state */
|
|
iot_light_drv_report_power_state_handle();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_process_response() - pass responsing data to remote cco.
|
|
* @param resp_pkt: pkt for responsing.
|
|
*/
|
|
static void iot_light_process_response(iot_pkt_t *resp_pkt) {
|
|
|
|
iot_led_crtl_msg_post_to_ge(resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_calcuate_checksum() - Caculate the check-sum of frame.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
* @return : check-sum.
|
|
*/
|
|
static uint8_t iot_light_calcuate_checksum(void *frame, uint32_t frame_len)
|
|
{
|
|
uint8_t check_sum = 0, *p_byte_val = (uint8_t *)frame;
|
|
uint32_t byte_idx;
|
|
|
|
for (byte_idx = 0; byte_idx < frame_len - 1; byte_idx++) {
|
|
check_sum += *p_byte_val++;
|
|
}
|
|
|
|
return check_sum;
|
|
}
|
|
|
|
#define iot_light_check_checksum_invalid(frame, frame_len, checksum) \
|
|
(iot_light_calcuate_checksum(frame, frame_len) == (checksum) ? false : true)
|
|
/* Get checksum byte from tail of frame */
|
|
#define iot_light_check_checksum_invalid_by_raw_data(frame, frame_len) \
|
|
(iot_light_calcuate_checksum(frame, frame_len) \
|
|
== (*((char *)frame + (frame_len - 1))) ? false : true)
|
|
|
|
/**
|
|
* @brief iot_light_command_get_param() - Command handle for getting
|
|
* param of this led power.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_get_param(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_cmd_frm_get_param_t *p_cmd_frame = frame;
|
|
iot_resp_frm_get_param_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
iot_light_power_param_t *p_param = &iot_led_controller.led.param;
|
|
|
|
/* Check-sum check. */
|
|
if (iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
/* Prepare for responsing. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_resp_frm_get_param_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->opcode = RESP_GET_PARAM;
|
|
p_resp_frame->device_type = p_param->device_type;
|
|
p_resp_frame->temperature = p_param->temperature;
|
|
p_resp_frame->voltage_in_h = (p_param->voltage_in >> 8) & 0xFF;
|
|
p_resp_frame->voltage_in_l = p_param->voltage_in & 0xFF;
|
|
p_resp_frame->current_in_h = (p_param->current_in >> 8) & 0xFF;
|
|
p_resp_frame->current_in_l = p_param->current_in & 0xFF;
|
|
p_resp_frame->voltage_out_h = (p_param->voltage_out >> 8) & 0xFF;
|
|
p_resp_frame->voltage_out_l = p_param->voltage_out & 0xFF;
|
|
p_resp_frame->current_out_h = (p_param->current_out >> 8) & 0xFF;
|
|
p_resp_frame->current_out_l = p_param->current_out & 0xFF;
|
|
p_resp_frame->power_in_h = (p_param->power_in >> 8) & 0xFF;
|
|
p_resp_frame->power_in_l = p_param->power_in & 0xFF;
|
|
p_resp_frame->factor = p_param->factor;
|
|
p_resp_frame->level = p_param->light_level_a;
|
|
p_resp_frame->power_state_h = (p_param->power_state >> 8) & 0xFF;
|
|
p_resp_frame->power_state_l = p_param->power_state & 0xFF;
|
|
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_report_power_state() - Command handle for report power
|
|
* state to cco.
|
|
* @param power_state: the changed power state which will report to cco.
|
|
*/
|
|
static void iot_light_report_power_state(uint16_t power_state)
|
|
{
|
|
iot_light_report_power_state_t *p_report_frame;
|
|
iot_pkt_t *p_report_pkt;
|
|
/* Prepare for responsing. */
|
|
if (NULL == (p_report_pkt = iot_pkt_alloc(sizeof(*p_report_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_report_frame));
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
|
|
p_report_frame = (iot_light_report_power_state_t *)iot_pkt_put(p_report_pkt,
|
|
sizeof(*p_report_frame));
|
|
|
|
iot_printf("[LIGHT_DRV]report power state=%X\n", power_state);
|
|
/* Fill the response frame filed. */
|
|
p_report_frame->opcode = REPORT_POWER_STATE;
|
|
p_report_frame->power_state_h = (power_state >> 8) & 0xFF;
|
|
p_report_frame->power_state_l = power_state & 0xFF;
|
|
|
|
p_report_frame->check_sum = iot_light_calcuate_checksum(p_report_frame,
|
|
sizeof(*p_report_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_report_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_level_a() - Command handle for setting
|
|
* brightness level of channel A LED lights.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_level_a(void *frame, uint32_t frame_len)
|
|
{
|
|
uint8_t level;
|
|
iot_cmd_frm_set_light_level_a_t *p_cmd_frame = frame;
|
|
iot_resp_frm_set_light_level_a_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
uint32_t tmp_time;
|
|
|
|
/* Check-sum check. */
|
|
if (iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]set_level_a checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
/* Get the brightness level. */
|
|
level = min(IOT_LIGHT_BRIGHTNESS_RAW_LEVEL_MAX, p_cmd_frame->level);
|
|
|
|
tmp_time = os_boot_time32();
|
|
|
|
/* Set brightness level. */
|
|
iot_light_drv_set_light_level(IOT_LIGHT_CHAN_A, level);
|
|
|
|
iot_cus_printf("[LIGHT_DRV]set light use time=%d\n",
|
|
os_boot_time32() - tmp_time);
|
|
|
|
/* Prepare for responsing. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_resp_frm_set_light_level_a_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->opcode = RESP_SET_LIGHT_LEVEL_A;
|
|
p_resp_frame->level = level;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_level_b() - Command handle for setting
|
|
* brightness level of channel B LED lights.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_level_b(void *frame, uint32_t frame_len)
|
|
{
|
|
uint8_t level;
|
|
iot_cmd_frm_set_light_level_b_t *p_cmd_frame = frame;
|
|
iot_resp_frm_set_light_level_b_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
|
|
/* Check-sum check. */
|
|
if (iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]set_level_b checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
/* Get the brightness level. */
|
|
level = min(IOT_LIGHT_BRIGHTNESS_RAW_LEVEL_MAX, p_cmd_frame->level);
|
|
|
|
/* Set brightness level. */
|
|
iot_light_drv_set_light_level(IOT_LIGHT_CHAN_B, level);
|
|
|
|
/* Prepare for responsing. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_resp_frm_set_light_level_b_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->opcode = RESP_SET_LIGHT_LEVEL_B;
|
|
p_resp_frame->level = level;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_level_ab() - Command handle for setting
|
|
* brightness level of both A & B LED lights.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_level_ab(void *frame, uint32_t frame_len)
|
|
{
|
|
uint8_t level;
|
|
iot_cmd_frm_set_light_level_ab_t *p_cmd_frame = frame;
|
|
iot_resp_frm_set_light_level_ab_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
|
|
/* Check-sum check. */
|
|
if (iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]set_level_ab checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
/* Get the brightness level. */
|
|
level = min(IOT_LIGHT_BRIGHTNESS_RAW_LEVEL_MAX, p_cmd_frame->level);
|
|
|
|
/* Set brightness level. */
|
|
iot_light_drv_set_light_level(IOT_LIGHT_CHAN_ALL, level);
|
|
|
|
/* Prepare for responsing. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_resp_frm_set_light_level_ab_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->opcode = RESP_SET_LIGHT_LEVEL_AB;
|
|
p_resp_frame->level = level;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_level_group() - Command handle for setting
|
|
* brightness level of LED light in given group.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_level_group(void *frame, uint32_t frame_len)
|
|
{
|
|
uint8_t level, group, channel;
|
|
iot_cmd_frm_set_light_level_grp_t *p_cmd_frame = frame;
|
|
|
|
/* Check-sum check. */
|
|
if (iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]set_level_group checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
level = p_cmd_frame->level;
|
|
group = p_cmd_frame->group;
|
|
channel = p_cmd_frame->channel;
|
|
|
|
level = min(IOT_LIGHT_BRIGHTNESS_RAW_LEVEL_MAX, level);
|
|
|
|
/* Check if this command is broadcast or for our group. */
|
|
if (group == 0 || group == iot_led_controller.led.group) {
|
|
iot_light_drv_set_light_level(channel, level);
|
|
}
|
|
|
|
/* Broadcast command frame does not need a responsing. */
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_private_command_subopcode_alloc_packet() -
|
|
* Alloc packet buffer with reservd bytes for private used when sub-command response.
|
|
* @param length: length of buffer sub-command need to response..
|
|
* @return packet buffer or NULL if failed.
|
|
*/
|
|
static iot_pkt_t * iot_light_private_command_subopcode_alloc_packet
|
|
(uint32_t length)
|
|
{
|
|
iot_pkt_t *p_pkt;
|
|
uint32_t pkt_length;
|
|
|
|
/* total length of packet. */
|
|
pkt_length = length + CMD_PRIVATE_RESPONSE_RESV_BY_HEAD +
|
|
CMD_PRIVATE_RESPONSE_RESV_BY_TAIL;
|
|
|
|
if (NULL == (p_pkt = iot_pkt_alloc(pkt_length, IOT_LIGHT_MODULE_ID))) {
|
|
return NULL;
|
|
}
|
|
/* reserved for CMD_PRIVATE_RESPONSE_RESV_BY_HEAD */
|
|
iot_pkt_reserve(p_pkt, CMD_PRIVATE_RESPONSE_RESV_BY_HEAD);
|
|
|
|
return p_pkt;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_private_command_sub_get_leakage_current() -
|
|
* sub command handle for private using, to get current of leakage.
|
|
* @param subfrm_data: data for processing.
|
|
* @param subfrm_dlen: length of data, just subframe data,
|
|
* no subopcode, no checksum.
|
|
* @return resp pkt for this sub command.
|
|
*/
|
|
static iot_pkt_t * iot_light_private_command_sub_get_leakage_current
|
|
(void *subfrm_data, uint32_t subfrm_dlen)
|
|
{
|
|
iot_pkt_t *p_pkt;
|
|
iot_resp_frm_prv_sub_get_leakage_current_t *p_frm_leakage_data;
|
|
|
|
(void)subfrm_data;
|
|
(void)subfrm_dlen;
|
|
|
|
if (NULL == (p_pkt = iot_light_private_command_subopcode_alloc_packet
|
|
(sizeof(*p_frm_leakage_data)))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_frm_leakage_data));
|
|
return NULL;
|
|
}
|
|
|
|
p_frm_leakage_data = (iot_resp_frm_prv_sub_get_leakage_current_t*)
|
|
iot_pkt_put(p_pkt, sizeof(*p_frm_leakage_data));
|
|
/* Fill the current. */
|
|
p_frm_leakage_data->current_h = iot_led_controller.led.param.leakage_current >> 8;
|
|
p_frm_leakage_data->current_l = iot_led_controller.led.param.leakage_current & 0xFF;
|
|
|
|
return p_pkt;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_private_command_sub_get_dev_info() -
|
|
* sub command handle for private using, to get information of device.
|
|
* @param subfrm_data: data for processing.
|
|
* @param subfrm_dlen: length of data, just subframe data,
|
|
* no subopcode, no checksum.
|
|
* @return resp pkt for this sub command.
|
|
*/
|
|
static iot_pkt_t * iot_light_private_command_sub_get_dev_info
|
|
(void *subfrm_data, uint32_t subfrm_dlen)
|
|
{
|
|
iot_pkt_t *p_pkt;
|
|
|
|
iot_resp_frm_prv_sub_get_dev_info_t *p_frm_version_data;
|
|
|
|
(void)subfrm_data;
|
|
(void)subfrm_dlen;
|
|
|
|
if (NULL == (p_pkt = iot_light_private_command_subopcode_alloc_packet
|
|
(sizeof(*p_frm_version_data)))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_frm_version_data));
|
|
return NULL;
|
|
}
|
|
|
|
p_frm_version_data = (iot_resp_frm_prv_sub_get_dev_info_t *)
|
|
iot_pkt_put(p_pkt, sizeof(*p_frm_version_data));
|
|
|
|
/* Fill the version and mac. */
|
|
p_frm_version_data->fw_ver = iot_htonl(iot_version_hex());
|
|
iot_mac_addr_cpy(p_frm_version_data->local_mac, iot_led_controller.local_mac);
|
|
|
|
return p_pkt;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_private_command() - Command handle for private using.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_private_command(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_cmd_frm_private_command_t *p_cmd_private = frame;
|
|
iot_resp_frm_private_command_t *p_resp_private;
|
|
iot_pkt_t *p_resp_pkt = NULL;
|
|
void *subfrm_data;
|
|
uint32_t subfrm_dlen;
|
|
uint8_t *p_data, cs;
|
|
|
|
if (iot_light_check_checksum_invalid_by_raw_data(frame, frame_len)) {
|
|
iot_cus_printf("[LIGHT_DRV]private_command checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
iot_cus_printf("[LIGHT_DRV]Private command subopcode - 0x%x.\n",
|
|
p_cmd_private->sub_opcode);
|
|
|
|
/* command frame : OPCODE SUBOPCODE D0 ~ Dn CHECKSUM, subframe include D0 ~ Dn. */
|
|
subfrm_data = p_cmd_private->data;
|
|
/* the data length of sub command, D0 ~ Dn. */
|
|
subfrm_dlen = frame_len - CMD_PRIVATE_RESPONSE_RESV_BY_HEAD - CMD_PRIVATE_RESPONSE_RESV_BY_TAIL;
|
|
|
|
switch (p_cmd_private->sub_opcode)
|
|
{
|
|
case SUBCMD_GET_LEAKAGE_CURRENT:
|
|
p_resp_pkt = iot_light_private_command_sub_get_leakage_current(
|
|
subfrm_data, subfrm_dlen);
|
|
break;
|
|
case SUBCMD_GET_DEV_INFO:
|
|
p_resp_pkt = iot_light_private_command_sub_get_dev_info(
|
|
subfrm_data, subfrm_dlen);
|
|
break;
|
|
default:
|
|
iot_cus_printf("[LIGHT_DRV]Unknown subopcode\n");
|
|
/* Do not ASSERT here. */
|
|
break;
|
|
}
|
|
|
|
/* This will extend sub response data up to a response frame. */
|
|
if (NULL != p_resp_pkt) {
|
|
/* Fill opcode && subopcode into packet. */
|
|
p_resp_private = (iot_resp_frm_private_command_t *)
|
|
iot_pkt_push(p_resp_pkt, CMD_PRIVATE_RESPONSE_RESV_BY_HEAD);
|
|
|
|
p_resp_private->opcode = RESP_PRIVATE_COMMAND;
|
|
p_resp_private->sub_opcode = p_cmd_private->sub_opcode;
|
|
|
|
/* put 1 byte checksum. */
|
|
p_data = iot_pkt_put(p_resp_pkt, CMD_PRIVATE_RESPONSE_RESV_BY_TAIL);
|
|
|
|
/* calculate checksum */
|
|
cs = iot_light_calcuate_checksum(p_data, iot_pkt_data_len(p_resp_pkt));
|
|
/* point to the tail, the checksum byte */
|
|
p_data += iot_pkt_data_len(p_resp_pkt) - 1;
|
|
/* Fill checksum byte. */
|
|
*p_data = cs;
|
|
|
|
/* response */
|
|
iot_light_process_response(p_resp_pkt);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_group() - Command handle for setting group of
|
|
* this device/led controller.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_group(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_cmd_frm_set_group_t *p_cmd_frame = frame;
|
|
iot_resp_frm_set_group_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
uint8_t save_flag = 0;
|
|
|
|
/* Check-sum check. */
|
|
if (iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]set_group checksum invalid.\n");
|
|
return;
|
|
}
|
|
|
|
/* Set the group. */
|
|
if (iot_led_controller.led.group != p_cmd_frame->group) {
|
|
iot_led_controller.led.group = p_cmd_frame->group;
|
|
iot_led_controller.pib_info.group = iot_led_controller.led.group;
|
|
save_flag = 1;
|
|
}
|
|
|
|
/* Prepare for responsing. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_resp_frm_set_group_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->opcode = RESP_SET_GROUP;
|
|
p_resp_frame->group = iot_led_controller.led.group;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
if (save_flag)
|
|
iot_light_save_led_info();
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_report_power_state_ack() - Command handle for report power
|
|
* state ack.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_report_power_state_ack(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_light_cmd_frame_report_ack_t *p_cmd_frame = frame;
|
|
/* Check-sum check. */
|
|
if (frame_len != sizeof(*p_cmd_frame)
|
|
|| iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]power_state_ack check fail.\n");
|
|
return;
|
|
}
|
|
|
|
iot_led_controller.report_count = 0;
|
|
iot_cus_printf("[LIGHT_DRV]recv ack result=%d\n", p_cmd_frame->result);
|
|
return;
|
|
}
|
|
|
|
void iot_light_save_led_info(void)
|
|
{
|
|
iot_proto_custom_pib_info_save(&iot_led_controller.pib_info,
|
|
sizeof(iot_led_pib_info_t));
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_correction_resp() - Command handle for set
|
|
* correction response
|
|
* @param subfn: correction subfn: input power/voltage/current, output current.
|
|
* @param result: correction ack result.
|
|
*/
|
|
static void iot_light_command_correction_resp(uint8_t subfn, uint8_t result)
|
|
{
|
|
iot_light_resp_set_correction_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
|
|
/* Prepare for response. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc correction_resp pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_light_resp_set_correction_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->header.cmd_type = RESP_SET_CORRECTION_DATA;
|
|
p_resp_frame->header.subfn = subfn;
|
|
p_resp_frame->result = result;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(
|
|
p_resp_frame, sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_correction() - Command handle set correction
|
|
* input power, voltage, current and output current table.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_correction(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_light_correction_header_t *header = frame;
|
|
bool_t save_flag = false;
|
|
uint8_t result = IOT_LIGHT_CORRECTION_FAIL;
|
|
if (frame_len >= 3) {
|
|
/* check correction subfn */
|
|
switch (header->subfn) {
|
|
case SUBCMD_SET_COR_DATA_IN_POWER:
|
|
{
|
|
iot_light_correction_input_power_t *p_cmd_frame = frame;
|
|
|
|
iot_led_controller.pib_info.input_power = 1;
|
|
iot_led_controller.pib_info.input_power_slope =
|
|
(float)p_cmd_frame->input_power_slope;
|
|
iot_led_controller.pib_info.input_power_intercept =
|
|
(float)p_cmd_frame->input_power_intercept;
|
|
save_flag = true;
|
|
result = IOT_LIGHT_CORRECTION_SUCCESS;
|
|
break;
|
|
}
|
|
case SUBCMD_SET_COR_DATA_IN_VOLTAGE:
|
|
{
|
|
iot_light_correction_input_voltage_t *p_cmd_frame = frame;
|
|
|
|
iot_led_controller.pib_info.input_voltage = 1;
|
|
iot_led_controller.pib_info.input_vol_slope =
|
|
(float)p_cmd_frame->input_voltage_slope;
|
|
iot_led_controller.pib_info.input_vol_intercept =
|
|
(float)p_cmd_frame->input_voltage_intercept;
|
|
save_flag = true;
|
|
result = IOT_LIGHT_CORRECTION_SUCCESS;
|
|
break;
|
|
}
|
|
case SUBCMD_SET_COR_DATA_IN_CURRENT:
|
|
{
|
|
iot_light_correction_input_current_t *p_cmd_frame = frame;
|
|
|
|
iot_led_controller.pib_info.input_current = 1;
|
|
iot_led_controller.pib_info.input_cur_slope =
|
|
(float)p_cmd_frame->input_current_slope;
|
|
iot_led_controller.pib_info.input_cur_intercept =
|
|
(float)p_cmd_frame->input_current_intercept;
|
|
save_flag = true;
|
|
result = IOT_LIGHT_CORRECTION_SUCCESS;
|
|
break;
|
|
}
|
|
case SUBCMD_SET_COR_DATA_OUTPUT_CURRENT:
|
|
{
|
|
iot_light_correction_output_current_t *p_cmd_frame = frame;
|
|
uint8_t index = 0;
|
|
|
|
/* set_cur must be multiple of 10 */
|
|
if (p_cmd_frame->set_cur > 0 &&
|
|
(p_cmd_frame->set_cur % 10 == 0)) {
|
|
index = (p_cmd_frame->set_cur / 10) - 1;
|
|
if (index == 9){
|
|
iot_led_controller.pib_info.output_current = 1;
|
|
}
|
|
iot_led_controller.pib_info.cor_param[index] =
|
|
p_cmd_frame->real_cur;
|
|
save_flag = true;
|
|
result = IOT_LIGHT_CORRECTION_SUCCESS;
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]set output cur_val=%d err\n",
|
|
p_cmd_frame->set_cur);
|
|
iot_light_command_correction_resp(header->subfn, result);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (save_flag) {
|
|
/* save flash */
|
|
iot_light_save_led_info();
|
|
/* response */
|
|
iot_light_command_correction_resp(header->subfn, result);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_get_cor_param() - Command handle for get correction
|
|
* parameter.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_get_cor_param(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_light_get_correction_param_t *p_cmd_frame = frame;
|
|
iot_light_resp_get_cor_param_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
if ((SUBCMD_GET_COR_PARAM_METER != p_cmd_frame->header.subfn) ||
|
|
frame_len != sizeof(*p_cmd_frame)
|
|
|| iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]get_cor_param check fail.\n");
|
|
return;
|
|
}
|
|
|
|
/* Prepare for response. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_light_resp_get_cor_param_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->header.cmd_type = RESP_GET_CORRECTION_PARAM;
|
|
p_resp_frame->header.subfn = SUBCMD_GET_COR_PARAM_METER;
|
|
p_resp_frame->result = IOT_LIGHT_CORRECTION_SUCCESS;
|
|
p_resp_frame->power = iot_led_controller.led.param.power_in;
|
|
p_resp_frame->voltage = iot_led_controller.led.param.voltage_in;
|
|
p_resp_frame->current = iot_led_controller.led.param.current_in;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_set_cor_param() - Command handle for set correction
|
|
* light level.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
*/
|
|
static void iot_light_command_set_cor_param(void *frame, uint32_t frame_len)
|
|
{
|
|
iot_light_set_correction_param_t *p_cmd_frame = frame;
|
|
iot_light_resp_set_cor_param_t *p_resp_frame;
|
|
iot_pkt_t *p_resp_pkt;
|
|
|
|
if ((SUBCMD_SET_COR_PARAM_LIGHT_LEVEL != p_cmd_frame->header.subfn) ||
|
|
frame_len != sizeof(*p_cmd_frame) ||
|
|
iot_light_check_checksum_invalid(frame, frame_len,
|
|
p_cmd_frame->check_sum)) {
|
|
iot_cus_printf("[LIGHT_DRV]set_cor_param check fail.\n");
|
|
return;
|
|
}
|
|
|
|
iot_light_drv_set_led_brightness(IOT_LIGHT_CHAN_ALL,
|
|
p_cmd_frame->level / 2);
|
|
|
|
/* Prepare for response. */
|
|
if (NULL == (p_resp_pkt = iot_pkt_alloc(sizeof(*p_resp_frame),
|
|
IOT_LIGHT_MODULE_ID))) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed len #%d.\n",
|
|
sizeof(*p_resp_frame));
|
|
return;
|
|
}
|
|
|
|
p_resp_frame = (iot_light_resp_set_cor_param_t *)iot_pkt_put(p_resp_pkt,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* Fill the response frame filed. */
|
|
p_resp_frame->header.cmd_type = RESP_SET_CORRECTION_PARAM;
|
|
p_resp_frame->header.subfn = SUBCMD_SET_COR_PARAM_LIGHT_LEVEL;
|
|
p_resp_frame->result = IOT_LIGHT_CORRECTION_SUCCESS;
|
|
p_resp_frame->check_sum = iot_light_calcuate_checksum(p_resp_frame,
|
|
sizeof(*p_resp_frame));
|
|
|
|
/* response to cco */
|
|
iot_light_process_response(p_resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_command_handle_list[] - Command processing handle list.
|
|
*/
|
|
static iot_light_ctrl_handle_t iot_light_command_handle_list[] = {
|
|
{CMD_GET_PARAM, iot_light_command_get_param},
|
|
{CMD_SET_LIGHT_LEVEL_AB, iot_light_command_set_level_ab},
|
|
{CMD_SET_LIGHT_LEVEL_GRP, iot_light_command_set_level_group},
|
|
{CMD_SET_LIGHT_LEVEL_A, iot_light_command_set_level_a},
|
|
{CMD_SET_LIGHT_LEVEL_B, iot_light_command_set_level_b},
|
|
{CMD_SET_GROUP, iot_light_command_set_group},
|
|
{CMD_PRIVATE_COMMAND, iot_light_private_command},
|
|
{CMD_REPORT_POWER_STATE_ACK,iot_light_report_power_state_ack},
|
|
{CMD_SET_CORRECTION_DATA, iot_light_command_set_correction},
|
|
{CMD_GET_CORRECTION_PARAM, iot_light_command_get_cor_param},
|
|
{CMD_SET_CORRECTION_PARAM, iot_light_command_set_cor_param},
|
|
};
|
|
|
|
#define iot_light_cmd_list_size() \
|
|
(sizeof(iot_light_command_handle_list) /\
|
|
sizeof(iot_light_command_handle_list[0]))
|
|
|
|
/**
|
|
* @brief iot_light_get_command_handle() - Return the command handle from given
|
|
* command code.
|
|
* @param command: command code.
|
|
* @return NULL - No matchable handle, else related handle.
|
|
*/
|
|
static iot_light_ctrl_handle_t *iot_light_get_command_handle(uint32_t command) {
|
|
uint32_t cmd_idx;
|
|
iot_light_ctrl_handle_t *handle = NULL;
|
|
|
|
for (cmd_idx = 0; cmd_idx < iot_light_cmd_list_size(); cmd_idx++) {
|
|
if (iot_light_command_handle_list[cmd_idx].command == command) {
|
|
handle = &iot_light_command_handle_list[cmd_idx];
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* return NULL if no command found. */
|
|
return handle;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_light_process_command() - The main entrance for processing led
|
|
* control frame.
|
|
* @param frame: frame buffer for processing include check-sum byte.
|
|
* @param frame_len: length of this frame include check-sum byte.
|
|
* @return ERR_FAIL - Operation failed, ERR_OK - Operation Successful
|
|
*/
|
|
static uint32_t iot_light_process_command(void *frame, uint32_t frame_len)
|
|
{
|
|
uint32_t command;
|
|
iot_light_ctrl_handle_t *handle;
|
|
|
|
/* Check param */
|
|
if (NULL == frame || frame_len < IOT_LIGHT_MIN_FRAME_LEN) {
|
|
iot_cus_printf("[LIGHT_DRV]param invalid, frame %p len #%d.\n", frame,
|
|
frame_len);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
/* get command byte from frame. */
|
|
command = iot_light_get_cmd(frame);
|
|
|
|
iot_light_data_dump(frame, frame_len);
|
|
|
|
/* find function handle by command */
|
|
if (NULL == (handle = iot_light_get_command_handle(command))) {
|
|
iot_cus_printf("[LIGHT_DRV]no command handle for 0x#%x.\n", command);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_cus_printf("[LIGHT_DRV]process command 0x#%x, command_fn=%p.\n",
|
|
command, handle->fn_command);
|
|
|
|
/* execute this command. */
|
|
handle->fn_command(frame, frame_len);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_data_check_with_delta()- check new data with data_check logic.
|
|
* @pcheck : data_check infor for this new data.
|
|
* @new_data : new data for checking.
|
|
* @out_data : final out data for checking.
|
|
* @return : true - data changed, else - not changed.
|
|
*/
|
|
static uint32_t iot_led_ctrl_data_check_with_delta(iot_led_ctrl_data_check_t *pcheck,
|
|
uint32_t new_data, uint32_t *out_data)
|
|
{
|
|
uint32_t i, avg = 0, ret;
|
|
|
|
if ((NULL == pcheck)
|
|
|| (NULL == out_data)
|
|
|| (0 == pcheck->sample_cnt)
|
|
|| (0 == pcheck->delta_cnt)){
|
|
return false;
|
|
}
|
|
|
|
/* First running, fill sample queue with new data. */
|
|
if (pcheck->first_run) {
|
|
pcheck->first_run = false;
|
|
for (i = 0; i < pcheck->sample_cnt; i++) {
|
|
pcheck->sample_queue[i] = new_data;
|
|
}
|
|
pcheck->delta_index = 0;
|
|
*out_data = new_data;
|
|
ret = false;
|
|
goto out;
|
|
}
|
|
|
|
/* Get average of sample queue. */
|
|
for (i = 0, avg = 0; i < pcheck->sample_cnt; i++) {
|
|
avg += pcheck->sample_queue[i];
|
|
}
|
|
avg /= i;
|
|
|
|
/* Check if new data has a delta over delta_value */
|
|
if (iot_led_drv_get_delta_val(avg, new_data) <= pcheck->delta_value) {
|
|
/* This is a normal sample data. */
|
|
/* 1. Clear delta queue */
|
|
pcheck->delta_index = 0;
|
|
/* 2. Store this new data at the tail of sample queue */
|
|
os_mem_cpy(&pcheck->sample_queue[0], &pcheck->sample_queue[1],
|
|
(pcheck->sample_cnt - 1) * sizeof(pcheck->sample_queue[0]));
|
|
pcheck->sample_queue[pcheck->sample_cnt - 1] = new_data;
|
|
*out_data = new_data;
|
|
ret = false;
|
|
goto out;
|
|
}
|
|
|
|
/* Check if delta queue full */
|
|
if (pcheck->delta_index + 1 >= pcheck->delta_cnt) {
|
|
/* This delta queue full, that means data chenged. */
|
|
/* 1. flush delta queue into sample queue. */
|
|
pcheck->delta_queue[pcheck->delta_cnt - 1] = new_data;
|
|
/* Get the len of data need to copy. */
|
|
i = min(pcheck->delta_cnt, pcheck->sample_cnt);
|
|
/* move tail to head */
|
|
os_mem_cpy(pcheck->sample_queue, pcheck->sample_queue + i,
|
|
(pcheck->sample_cnt - i) * sizeof(pcheck->sample_queue[0]));
|
|
/* copy delta queue into sample queue */
|
|
os_mem_cpy(pcheck->sample_queue + (pcheck->sample_cnt - i),
|
|
pcheck->delta_queue, i * sizeof(pcheck->sample_queue[0]));
|
|
/* 2. Clear delta queue */
|
|
pcheck->delta_index = 0;
|
|
|
|
*out_data = new_data;
|
|
ret = true;
|
|
goto out;
|
|
}
|
|
|
|
/* Store new data into delta queue */
|
|
pcheck->delta_queue[pcheck->delta_index++] = new_data;
|
|
|
|
/* return last normal sample data for this time. */
|
|
*out_data = pcheck->sample_queue[pcheck->sample_cnt - 1];
|
|
ret = false;
|
|
|
|
out:
|
|
|
|
iot_cus_printf("[LIGHT_DRV]sample: delta %d, avg %d, new data %d, out data %d, ret %d.\n",
|
|
pcheck->delta_value, avg, new_data, *out_data, ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_handle_uart_data_msg() - process the data from uart port.
|
|
* @msg : message from uart port.
|
|
*/
|
|
static void iot_led_ctrl_handle_uart_data_msg(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
/* TODO : STA has nothing to do with uart data for now. */
|
|
iot_pkt_free((iot_pkt_t *)msg->data);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_handle_plc_data_msg() - process the data from PLC.
|
|
* @msg : message from remote device by PLC.
|
|
*/
|
|
static void iot_led_ctrl_handle_plc_data_msg(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
iot_pkt_t *p_pkt;
|
|
uint8_t *frame_buf;
|
|
uint32_t frame_len;
|
|
|
|
if ((NULL == msg) || (NULL == (p_pkt = (iot_pkt_t *)msg->data))) {
|
|
iot_cus_printf("[LIGHT_DRV]invalid param.\n");
|
|
return;
|
|
}
|
|
|
|
frame_buf = iot_pkt_data(p_pkt);
|
|
frame_len = iot_pkt_data_len(p_pkt);
|
|
|
|
iot_cus_printf("[LIGHT_DRV]plc received pkt #%p, frame #%p, length #%d.\n",
|
|
p_pkt, frame_buf, frame_len);
|
|
|
|
if (ERR_OK != iot_light_process_command(frame_buf, frame_len)) {
|
|
iot_cus_printf("[LIGHT_DRV]process command failed.\n");
|
|
}
|
|
|
|
iot_pkt_free(p_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_handle_plc_data_msg() - process the data from PLC.
|
|
* @msg : message from remote device by PLC.
|
|
*/
|
|
static void iot_led_ctrl_handle_plc_cco_mac_msg(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
iot_pkt_t *p_pkt;
|
|
uint8_t *frame_buf;
|
|
|
|
if ((NULL == msg) || (NULL == (p_pkt = (iot_pkt_t *)msg->data))) {
|
|
iot_cus_printf("[LIGHT_DRV]invalid param.\n");
|
|
return;
|
|
}
|
|
|
|
frame_buf = iot_pkt_data(p_pkt);
|
|
|
|
iot_cus_printf("[LIGHT_DRV]join cco[%x:%x:%x:%x:%x:%x].\n",
|
|
frame_buf[0], frame_buf[1], frame_buf[2], frame_buf[3],
|
|
frame_buf[4], frame_buf[5]);
|
|
|
|
iot_led_crtl_set_mac(frame_buf);
|
|
|
|
iot_pkt_free(p_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_led_crtl_msg_post(uint16_t msg_type, uint16_t msg_id, iot_pkt_t * data)
|
|
{
|
|
iot_task_msg_t *msg;
|
|
iot_led_ctrl_msg_t *task_msg;
|
|
msg = iot_task_alloc_msg_with_reserved(iot_led_controller.task, 0);
|
|
if (NULL == msg) {
|
|
if (NULL != data) {
|
|
iot_pkt_free(data);
|
|
}
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
|
|
task_msg = (iot_led_ctrl_msg_t*)msg;
|
|
task_msg->task_msg.type = msg_type;
|
|
task_msg->task_msg.id = msg_id;
|
|
task_msg->data = data;
|
|
task_msg->data2 = 0;
|
|
iot_task_queue_msg(iot_led_controller.task, &task_msg->task_msg, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_crtl_leakage_evt_func() - check leakage current callback
|
|
* function.
|
|
* @current : read current value, 1mA.
|
|
*/
|
|
void iot_led_crtl_leakage_evt_func(uint32_t current)
|
|
{
|
|
uint32_t r_cur, changed;
|
|
iot_led_ctrl_msg_t *msg;
|
|
|
|
changed = iot_led_ctrl_data_check_with_delta
|
|
(&iot_led_controller.check_leakage_current, current, &r_cur);
|
|
|
|
(void)r_cur; /* NOT used. */
|
|
|
|
if (changed) {
|
|
iot_cus_printf("[LIGHT_DRV]leak changed: I %d(mA).\n", current);
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]leak not change: I %d(mA).\n", current);
|
|
}
|
|
|
|
/* Keep the value for updating param. */
|
|
iot_led_controller.led.param.leakage_current = (int16_t)current;
|
|
|
|
if (((current >= IOT_LIGHT_CTRL_LEAKAGE_CURRENT_THR)
|
|
|| (changed && iot_led_controller.led.param.power_up))
|
|
&& (!iot_led_controller.led.param.leakage))
|
|
{
|
|
msg = (iot_led_ctrl_msg_t *)iot_task_alloc_msg(iot_led_controller.task);
|
|
if (msg) {
|
|
msg->task_msg.type = IOT_LED_CTRL_MSG_INTERNAL;
|
|
msg->task_msg.id = IOT_LED_CTRL_MSG_INTERNAL_LEAKAGE_CURRENT;
|
|
msg->data2 = current;
|
|
iot_task_queue_msg(iot_led_controller.task, &msg->task_msg, 0);
|
|
} else {
|
|
IOT_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_input_in_meter_param()
|
|
input meter data callback
|
|
* @voltage : read voltage value, 1mV.
|
|
* @current : read current value, 1mA.
|
|
* @power : read power value, 1mW.
|
|
* @factor : factor value, 0.01%.
|
|
*/
|
|
void iot_led_ctrl_input_in_meter_param(uint32_t voltage, uint32_t current,
|
|
uint32_t power, uint32_t factor)
|
|
{
|
|
uint32_t r_vol;
|
|
iot_led_ctrl_msg_t *msg;
|
|
|
|
iot_led_ctrl_data_check_with_delta
|
|
(&iot_led_controller.check_meter_voltage, voltage, &r_vol);
|
|
|
|
/* This meter data is abnormal, drop. */
|
|
if (voltage != r_vol) {
|
|
iot_cus_printf("[LIGHT_DRV]meter data dropped:V %d(mV)," \
|
|
"I %d(mA),P %d(mW), F %d%%(0.01%%).\n",
|
|
voltage, current, power, factor);
|
|
return;
|
|
}
|
|
|
|
iot_cus_printf("[LIGHT_DRV]meter data confirmed:V %d(mV)," \
|
|
"I %d(mA),P %d(mW), F %d%%(0.01%%).\n",
|
|
voltage, current, power, factor);
|
|
|
|
msg = (iot_led_ctrl_msg_t *)iot_task_alloc_msg(iot_led_controller.task);
|
|
|
|
if (msg) {
|
|
msg->task_msg.type = IOT_LED_CTRL_MSG_INTERNAL;
|
|
msg->task_msg.id = IOT_LED_CTRL_MSG_INTERNAL_IN_METER_PARAM;
|
|
iot_light_set_msg_meter_par(voltage, current, power, factor, msg);
|
|
iot_task_queue_msg(iot_led_controller.task, &msg->task_msg, 0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#if IOT_LIGHT_CTRL_ADC_MODULE_ENABLE
|
|
static void iot_light_ctrl_leakage_current_process(int32_t leakage_current)
|
|
{
|
|
/* leakage protect. */
|
|
iot_light_drv_protect();
|
|
|
|
/* set flag */
|
|
iot_led_controller.led.param.leakage = true;
|
|
|
|
iot_cus_printf("[LIGHT_DRV]leakage_current:%d(mA), " \
|
|
"large than threshold, close relay!\n", leakage_current);
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_handle_data_msg() - process data from current/other task.
|
|
* @msg : message.
|
|
*/
|
|
static void iot_led_ctrl_handle_data_msg(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
switch (msg->task_msg.id) {
|
|
case IOT_LED_CTRL_MSG_ID_UART_DATA:
|
|
{
|
|
iot_led_ctrl_handle_uart_data_msg(msg);
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_ID_PLC_DATA:
|
|
{
|
|
iot_led_ctrl_handle_plc_data_msg(msg);
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_ID_PLC_CCO_MAC:
|
|
{
|
|
iot_led_ctrl_handle_plc_cco_mac_msg(msg);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_cus_printf("[LIGHT_DRV]unknown message id #%d.\n",
|
|
msg->task_msg.id);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_handle_timer_msg() - process data from local timer.
|
|
* @msg : message.
|
|
*/
|
|
static void iot_led_ctrl_handle_timer_msg(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
switch (msg->task_msg.id) {
|
|
case IOT_LED_CTRL_MSG_ID_TMR_TIMEOUT:
|
|
{
|
|
if (mac_addr_is_valid_addr(iot_led_controller.local_mac)) {
|
|
iot_light_drv_update_power_param();
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]local mac is invalid.\n");
|
|
}
|
|
#if (ENABLE_LED_CTRL_HARDWARE)
|
|
iot_light_drv_voltage_abnormal_check();
|
|
iot_light_drv_open_loop_check();
|
|
#endif
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_ID_REPORT_TMR_TIMEOUT:
|
|
{
|
|
/* report power state to cco */
|
|
iot_light_report_power_state(*(uint16_t*)msg->data);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_cus_printf("[LIGHT_DRV]unknown message id #%d.\n",
|
|
msg->task_msg.id);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_update_input_meter_param() - update input meter data.
|
|
* @msg : message.
|
|
*/
|
|
static void iot_led_ctrl_update_input_meter_param(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
uint16_t cur, pow, vol, fac;
|
|
|
|
iot_light_get_msg_meter_par(vol, cur, pow, fac, msg);
|
|
|
|
iot_led_controller.led.param.current_in = cur;
|
|
iot_led_controller.led.param.voltage_in = vol;
|
|
iot_led_controller.led.param.power_in = pow;
|
|
iot_led_controller.led.param.factor = (uint8_t)fac;
|
|
|
|
iot_cus_printf("[LIGHT_DRV]Update meter : I %d(1mA), V %d(0.1V), P %d(0.1W), F %d(1%%).\n",
|
|
cur, vol, pow, fac);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_handle_internal_msg() - process data from intrnal.
|
|
* @msg : message.
|
|
*/
|
|
static void iot_led_ctrl_handle_internal_msg(iot_led_ctrl_msg_t *msg)
|
|
{
|
|
switch (msg->task_msg.id) {
|
|
case IOT_LED_CTRL_MSG_INTERNAL_LEAKAGE_CURRENT:
|
|
{
|
|
#if IOT_LIGHT_CTRL_ADC_MODULE_ENABLE
|
|
iot_light_ctrl_leakage_current_process((int32_t)msg->data2);
|
|
#endif
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_INTERNAL_IN_METER_PARAM:
|
|
{
|
|
iot_led_ctrl_update_input_meter_param(msg);
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_INTERNAL_UPDATE_CCO_MAC:
|
|
{
|
|
uint8_t *cco_mac = iot_pkt_data((iot_pkt_t *)msg->data);
|
|
/* only disconnect net can update */
|
|
if (!iot_led_controller.module_ready &&
|
|
iot_mac_addr_valid(cco_mac)) {
|
|
iot_cus_printf("[LIGHT_DRV]update cco mac\n");
|
|
iot_mac_addr_cpy(iot_led_controller.pib_info.cco_mac, cco_mac);
|
|
}
|
|
|
|
iot_pkt_free((iot_pkt_t *)msg->data);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_cus_printf("[LIGHT_DRV]unknown message id #%d.\n",
|
|
msg->task_msg.id);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_task_timer_exe() - timer timeout callback function.
|
|
* @timer_id : timer id with that timer who causes this api-call.
|
|
* @arg : param past to this callback api.
|
|
*/
|
|
void iot_led_ctrl_task_timer_exe(timer_id_t timer_id, void * arg)
|
|
{
|
|
(void)timer_id;
|
|
(void)arg;
|
|
|
|
iot_led_crtl_msg_post(IOT_LED_CTRL_MSG_TIMER,
|
|
IOT_LED_CTRL_MSG_ID_TMR_TIMEOUT, NULL);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_report_timer_exe() - report timer timeout callback
|
|
* function.
|
|
* @timer_id : timer id with that timer who causes this api-call.
|
|
* @arg : param past to this callback api.
|
|
*/
|
|
void iot_led_ctrl_report_timer_exe(timer_id_t timer_id, void * arg)
|
|
{
|
|
(void)timer_id;
|
|
|
|
iot_led_crtl_msg_post(IOT_LED_CTRL_MSG_TIMER,
|
|
IOT_LED_CTRL_MSG_ID_REPORT_TMR_TIMEOUT, arg);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_task_msg_exe() - message process callback function.
|
|
* @task_h : task id with that task who causes this api-call.
|
|
* @msg : message past to this callback api.
|
|
*/
|
|
static void iot_led_ctrl_task_msg_exe(iot_task_h task_h, iot_task_msg_t *msg)
|
|
{
|
|
iot_led_ctrl_msg_t *task_msg = (iot_led_ctrl_msg_t*)msg;
|
|
|
|
switch (task_msg->task_msg.type) {
|
|
case IOT_LED_CTRL_MSG_DATA:
|
|
{
|
|
iot_led_ctrl_handle_data_msg(task_msg);
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_TIMER:
|
|
{
|
|
iot_led_ctrl_handle_timer_msg(task_msg);
|
|
break;
|
|
}
|
|
case IOT_LED_CTRL_MSG_INTERNAL:
|
|
{
|
|
iot_led_ctrl_handle_internal_msg(task_msg);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_cus_printf("[LIGHT_DRV]unknown message type #%d.\n",
|
|
task_msg->task_msg.type);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
iot_task_free_msg(task_h, msg);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_task_msg_cancel() - message cancel callback function.
|
|
* @task_h : task id with that task who causes this api-call.
|
|
* @msg : message past to this callback api.
|
|
*/
|
|
static void iot_led_ctrl_task_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
|
|
{
|
|
iot_led_ctrl_msg_t *task_msg = (iot_led_ctrl_msg_t *)msg;
|
|
|
|
switch(task_msg->task_msg.type)
|
|
{
|
|
case IOT_LED_CTRL_MSG_DATA:
|
|
case IOT_LED_CTRL_MSG_TIMER:
|
|
{
|
|
iot_pkt_free(task_msg->data);
|
|
}
|
|
default:
|
|
{
|
|
iot_cus_printf("[LIGHT_DRV]unknown message type #%d.\n",
|
|
task_msg->task_msg.type);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
iot_task_free_msg(task_h, msg);
|
|
|
|
return;
|
|
}
|
|
|
|
static uint32_t iot_led_ctrl_ge_handle_connect_ind(uint8_t *p_pkt_data)
|
|
{
|
|
uint8_t *p_buffer;
|
|
iot_pkt_t *p_pkt;
|
|
ge_frame_conn_ind_rpt_set_subfn9_t *p_frame;
|
|
|
|
p_frame = (ge_frame_conn_ind_rpt_set_subfn9_t *)p_pkt_data;
|
|
|
|
if ((PROTO_GE_PLC_SET_CMD != p_frame->hdr.hdr.fn)
|
|
|| (PROTO_CONN_IND_RPT_CMD != p_frame->hdr.subfn)) {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
p_pkt = iot_pkt_alloc(IOT_MAC_ADDR_LEN, IOT_LIGHT_MODULE_ID);
|
|
|
|
if (NULL == p_pkt) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
p_buffer = iot_pkt_put(p_pkt, IOT_MAC_ADDR_LEN);
|
|
|
|
os_mem_cpy(p_buffer, p_frame->mac, IOT_MAC_ADDR_LEN);
|
|
|
|
iot_led_crtl_msg_post(IOT_LED_CTRL_MSG_DATA,
|
|
IOT_LED_CTRL_MSG_ID_PLC_CCO_MAC, p_pkt);
|
|
|
|
return ERR_OK;
|
|
|
|
}
|
|
|
|
static uint32_t iot_led_ctrl_ge_handle_data_recv(uint8_t *p_pkt_data)
|
|
{
|
|
iot_pkt_t *p_pkt;
|
|
uint8_t *p_buffer;
|
|
ge_frame_data_send_set_subfn160_t *p_frame;
|
|
uint8_t data_len = 0;
|
|
|
|
p_frame = (ge_frame_data_send_set_subfn160_t *)p_pkt_data;
|
|
|
|
if ((PROTO_GE_PLC_SET_CMD != p_frame->hdr.hdr.fn)
|
|
|| (PROTO_GE_DATA_CMD != p_frame->hdr.subfn)
|
|
|| (p_frame->hdr.hdr.data_len <= IOT_MAC_ADDR_LEN * 2)) {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if (!iot_mac_addr_valid(iot_led_controller.pib_info.cco_mac)) {
|
|
iot_cus_printf("[LIGHT_DRV][war]cco mac is invalid, drop\n");
|
|
return ERR_FAIL;
|
|
} else if (!iot_mac_addr_cmp(iot_led_controller.pib_info.cco_mac,
|
|
p_frame->data)) {
|
|
iot_cus_printf("[LIGHT_DRV][war]recv data from %02X:%02X:%02X:%02X:"
|
|
"%02X:%02X, drop\n", p_frame->data[0], p_frame->data[1],
|
|
p_frame->data[2], p_frame->data[3],
|
|
p_frame->data[4], p_frame->data[5]);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
/* IOT_MAC_ADDR_LEN * 2 for src & dst MAC. */
|
|
data_len = p_frame->hdr.hdr.data_len - IOT_MAC_ADDR_LEN * 2;
|
|
|
|
p_pkt = iot_pkt_alloc(data_len, IOT_LIGHT_MODULE_ID);
|
|
|
|
if (NULL == p_pkt) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
p_buffer = iot_pkt_put(p_pkt, data_len);
|
|
|
|
/* skip 6 bytes src mac, we do not care about. */
|
|
os_mem_cpy(p_buffer, p_frame->data + IOT_MAC_ADDR_LEN, data_len);
|
|
|
|
iot_led_crtl_msg_post(IOT_LED_CTRL_MSG_DATA,
|
|
IOT_LED_CTRL_MSG_ID_PLC_DATA, p_pkt);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* register to proto to update cco mac */
|
|
uint32_t iot_led_ctrl_update_cco_mac(uint8_t *cco_mac)
|
|
{
|
|
iot_pkt_t *p_pkt = iot_pkt_alloc(IOT_MAC_ADDR_LEN, IOT_LIGHT_MODULE_ID);
|
|
|
|
if (NULL == p_pkt) {
|
|
iot_cus_printf("[LIGHT_DRV]alloc pkt failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
iot_mac_addr_cpy(iot_pkt_data(p_pkt), cco_mac);
|
|
iot_pkt_put(p_pkt, IOT_MAC_ADDR_LEN);
|
|
|
|
iot_led_crtl_msg_post(IOT_LED_CTRL_MSG_INTERNAL,
|
|
IOT_LED_CTRL_MSG_INTERNAL_UPDATE_CCO_MAC, p_pkt);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t iot_led_ctrl_ge_handle_data_send(iot_pkt_t* resp_pkt)
|
|
{
|
|
ge_frame_data_send_set_subfn160_t *p_frame_hdr;
|
|
ge_frm_tail_t *p_frame_tl;
|
|
iot_pkt_t *p_frame_pkt;
|
|
uint8_t *p_start;
|
|
uint32_t frame_len, resp_data_len;
|
|
|
|
/* attach 6bytes src mac in front of data. */
|
|
resp_data_len = iot_pkt_data_len(resp_pkt) + IOT_MAC_ADDR_LEN;
|
|
|
|
frame_len = resp_data_len + sizeof(*p_frame_hdr) + sizeof(*p_frame_tl);
|
|
|
|
if (NULL == (p_frame_pkt = iot_pkt_alloc(frame_len, IOT_LIGHT_MODULE_ID))) {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
p_start = iot_pkt_data(p_frame_pkt);
|
|
iot_pkt_put(p_frame_pkt, frame_len);
|
|
|
|
p_frame_hdr = (ge_frame_data_send_set_subfn160_t *)p_start;
|
|
|
|
/* Fill frame header. */
|
|
p_frame_hdr->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
p_frame_hdr->hdr.hdr.data_len = (uint8_t)(resp_data_len + IOT_MAC_ADDR_LEN);
|
|
p_frame_hdr->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
|
|
p_frame_hdr->hdr.subfn = PROTO_GE_DATA_CMD;
|
|
|
|
/* Send to cco */
|
|
iot_mac_addr_cpy(p_frame_hdr->dest_mac,
|
|
iot_led_controller.pib_info.cco_mac);
|
|
|
|
/* Fill frame body. */
|
|
p_frame_hdr->force_tx_connless = 0;
|
|
p_frame_hdr->force_noaggr = 0;
|
|
p_frame_hdr->resv = 0;
|
|
p_frame_hdr->data_type = 0;
|
|
|
|
iot_mac_addr_cpy(p_frame_hdr->data, iot_led_controller.local_mac);
|
|
|
|
os_mem_cpy(p_frame_hdr->data + IOT_MAC_ADDR_LEN, iot_pkt_data(resp_pkt),
|
|
resp_data_len - IOT_MAC_ADDR_LEN);
|
|
|
|
p_frame_tl = (ge_frm_tail_t *)(p_frame_hdr->data + resp_data_len);
|
|
|
|
p_frame_tl->check_sum = (uint16_t)ge_frm_checksum_calc(p_start,
|
|
(uint16_t)(resp_data_len + sizeof(*p_frame_hdr)));
|
|
p_frame_tl->tail = 0xFF;
|
|
|
|
iot_cus_printf("[LIGHT_DRV]frame send to GE.\n");
|
|
iot_light_data_dump(iot_pkt_data(p_frame_pkt),
|
|
iot_pkt_data_len(p_frame_pkt));
|
|
|
|
/* TODO : send to ge */
|
|
|
|
if (NULL != iot_led_controller.data_to_ge_fn) {
|
|
iot_led_controller.data_to_ge_fn(iot_pkt_data(p_frame_pkt),
|
|
(uint16_t)iot_pkt_data_len(p_frame_pkt));
|
|
} else {
|
|
iot_cus_printf("[LIGHT_DRV]no function for send data.\n");
|
|
}
|
|
|
|
iot_pkt_free(p_frame_pkt);
|
|
iot_pkt_free(resp_pkt);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* get a valid ge frame from the data, return the frame header */
|
|
ge_extend_fn_hdr_t *iot_ge_frame_format_check(uint8_t *data,
|
|
uint32_t data_len)
|
|
{
|
|
ge_extend_fn_hdr_t *hdr = NULL;
|
|
uint16_t crc_data;
|
|
uint32_t pos = 0;
|
|
|
|
while(pos < data_len) {
|
|
|
|
if (pos + GE_FRM_CHECK_SUM_FIELD_POS > data_len) {
|
|
/* frame length error */
|
|
break;
|
|
}
|
|
hdr = (ge_extend_fn_hdr_t*)(data + pos);
|
|
if (hdr->hdr.preamble == GE_FRM_PREAMBLE_CODE &&
|
|
hdr->hdr.data_len <= GE_FRM_PLD_MAX_LEN &&
|
|
pos + hdr->hdr.data_len + GE_FRM_MIN_LEN <= data_len) {
|
|
/* crc check */
|
|
crc_data = iot_gree_get_crc_byte(
|
|
&data[pos + hdr->hdr.data_len + GE_FRM_CHECK_SUM_FIELD_POS]);
|
|
if (crc_data == ge_frm_checksum_calc(data + pos, hdr->hdr.data_len +
|
|
GE_FRM_CHECK_SUM_FIELD_POS) && GE_FRM_TAIL_CODE ==
|
|
data[pos + hdr->hdr.data_len + GE_FRM_TAIL_CODE_FIELD_POS]) {
|
|
return hdr;
|
|
}
|
|
}
|
|
pos++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint32_t iot_led_crtl_msg_post_to_led(iot_pkt_t *p_pkt_frame)
|
|
{
|
|
|
|
iot_cus_printf("[LIGHT_DRV]frame receive from GE.\n");
|
|
uint8_t *pkt_data = iot_pkt_data(p_pkt_frame);
|
|
uint32_t pkt_data_len = iot_pkt_data_len(p_pkt_frame);
|
|
ge_extend_fn_hdr_t *hdr = NULL;
|
|
uint32_t fe_cnt = 0;
|
|
|
|
iot_light_data_dump(pkt_data, pkt_data_len);
|
|
|
|
while (pkt_data_len > 0) {
|
|
hdr = iot_ge_frame_format_check(pkt_data, pkt_data_len);
|
|
if (hdr == NULL) {
|
|
/* have not find vaild frame */
|
|
break;
|
|
}
|
|
if ((PROTO_GE_PLC_SET_CMD == hdr->hdr.fn) &&
|
|
(PROTO_CONN_IND_RPT_CMD == hdr->subfn)) {
|
|
iot_led_ctrl_ge_handle_connect_ind((uint8_t*)hdr);
|
|
} else if ((PROTO_GE_PLC_SET_CMD == hdr->hdr.fn) &&
|
|
(PROTO_GE_DATA_CMD == hdr->subfn)) {
|
|
iot_led_ctrl_ge_handle_data_recv((uint8_t*)hdr);
|
|
} else {
|
|
/* we donot need this frame. */
|
|
iot_cus_printf("[LIGHT_DRV]unknown %02X-%02X, dropped.\n",
|
|
hdr->hdr.fn, hdr->subfn);
|
|
}
|
|
fe_cnt = (uint8_t*)hdr - pkt_data;
|
|
pkt_data_len -= (fe_cnt + hdr->hdr.data_len + GE_FRM_MIN_LEN);
|
|
pkt_data = (uint8_t*)hdr + hdr->hdr.data_len + GE_FRM_MIN_LEN;
|
|
}
|
|
|
|
iot_pkt_free(p_pkt_frame);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
void iot_led_crtl_msg_post_to_ge(iot_pkt_t* resp_pkt)
|
|
{
|
|
if (ERR_OK == iot_led_ctrl_ge_handle_data_send(resp_pkt)) {
|
|
return;
|
|
}
|
|
|
|
iot_pkt_free(resp_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_led_crtl_set_mac(uint8_t *cco)
|
|
{
|
|
if (NULL != cco) {
|
|
os_mem_cpy(iot_led_controller.pib_info.cco_mac, cco, IOT_MAC_ADDR_LEN);
|
|
iot_light_save_led_info();
|
|
}
|
|
|
|
if (mac_addr_is_valid_addr(iot_led_controller.pib_info.cco_mac)
|
|
&& (!iot_led_controller.module_ready)) {
|
|
iot_led_controller.module_ready = true;
|
|
iot_led_controller.report_count = 0;
|
|
iot_led_controller.report_power_state = 0;
|
|
}
|
|
|
|
if ((!mac_addr_is_valid_addr(iot_led_controller.pib_info.cco_mac))
|
|
&& iot_led_controller.module_ready) {
|
|
iot_led_controller.module_ready = false;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_led_ctrl_register_get_data_fn(void *fn)
|
|
{
|
|
if (NULL != fn) {
|
|
iot_led_controller.data_to_ge_fn = (data_send_to_ge)fn;
|
|
}
|
|
}
|
|
|
|
uint32_t iot_led_ctrl_task_init(void)
|
|
{
|
|
iot_task_config_t task_cfg;
|
|
iot_oem_base_cfg_t *oem_base_cfg;
|
|
|
|
/* Clear led object. */
|
|
os_mem_set(&iot_led_controller, 0x0, sizeof(iot_led_controller));
|
|
|
|
/* gpio pin config. */
|
|
iot_led_controller.led.gpio_power_on = IOT_LIGHT_GPIO_POWER;
|
|
iot_led_controller.led.gpio_relay = IOT_LIGHT_GPIO_RELAY;
|
|
|
|
/* Set led type for default */
|
|
iot_led_controller.led.param.device_type = DEV_TYPE_LED_150W;
|
|
|
|
/* TODO : set unready. */
|
|
iot_led_controller.module_ready = false;
|
|
#if (ENABLE_LED_CTRL_HARDWARE)
|
|
/* initialize hardware for this module. */
|
|
if (ERR_OK != iot_light_drv_initialize_hardware()) {
|
|
iot_cus_printf("[LIGHT_DRV]initialize hardware failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
#endif
|
|
|
|
iot_oem_get_base_cfg(&oem_base_cfg);
|
|
|
|
iot_mac_addr_cpy(iot_led_controller.local_mac, oem_base_cfg->module_mac);
|
|
|
|
iot_cus_printf("[LIGHT_DRV]local cco[%x:%x:%x:%x:%x:%x].\n",
|
|
iot_led_controller.local_mac[0], iot_led_controller.local_mac[1],
|
|
iot_led_controller.local_mac[2], iot_led_controller.local_mac[3],
|
|
iot_led_controller.local_mac[4], iot_led_controller.local_mac[5]);
|
|
|
|
/* create task */
|
|
os_mem_set(&task_cfg, 0x0, sizeof(task_cfg));
|
|
task_cfg.stack_size = IOT_LED_CTRL_TASK_STACK_SIZE;
|
|
task_cfg.task_prio = IOT_GRAPP_PROTO_TASK_PRIO;
|
|
task_cfg.msg_size = sizeof(iot_led_ctrl_msg_t);
|
|
task_cfg.msg_cnt = IOT_LED_CTRL_TASK_POOL_SIZE;
|
|
task_cfg.queue_cnt = 1;
|
|
task_cfg.queue_cfg[0].quota = 0;
|
|
task_cfg.msg_exe_func = iot_led_ctrl_task_msg_exe;
|
|
task_cfg.msg_cancel_func = iot_led_ctrl_task_msg_cancel;
|
|
|
|
iot_led_controller.task = iot_task_create(IOT_LIGHT_MODULE_ID, &task_cfg);
|
|
|
|
if (NULL == iot_led_controller.task) {
|
|
iot_cus_printf("[LIGHT_DRV]create task failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_led_controller.timer = os_create_timer
|
|
(IOT_LIGHT_MODULE_ID, true, iot_led_ctrl_task_timer_exe, NULL);
|
|
|
|
if (0 == iot_led_controller.timer) {
|
|
iot_cus_printf("[LIGHT_DRV]create timer failed.\n");
|
|
iot_task_delete(iot_led_controller.task);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
os_start_timer(iot_led_controller.timer, IOT_LED_TIMER_INTERVAL);
|
|
|
|
iot_led_controller.report_timer = os_create_timer
|
|
(IOT_LIGHT_MODULE_ID, false, iot_led_ctrl_report_timer_exe,
|
|
(void*)&iot_led_controller.report_power_state);
|
|
if (0 == iot_led_controller.report_timer) {
|
|
iot_cus_printf("[LIGHT_DRV]create report_timer failed.\n");
|
|
iot_task_delete(iot_led_controller.task);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_proto_custom_pib_info_load(&iot_led_controller.pib_info,
|
|
sizeof(iot_led_pib_info_t));
|
|
iot_led_controller.led.group = iot_led_controller.pib_info.group;
|
|
iot_led_controller.led.param.light_level_a =
|
|
iot_led_controller.pib_info.level_a;
|
|
iot_led_controller.led.param.light_level_b =
|
|
iot_led_controller.pib_info.level_b;
|
|
iot_cus_printf("[LIGHT_DRV]load group=%d level_a=%d level_b=%d\n",
|
|
iot_led_controller.led.group,
|
|
iot_led_controller.led.param.light_level_a,
|
|
iot_led_controller.led.param.light_level_b);
|
|
iot_proto_register_update_cco_mac_to_uplayer(
|
|
iot_led_ctrl_update_cco_mac);
|
|
|
|
/* init data check. */
|
|
iot_led_controller.check_leakage_current.first_run = true;
|
|
iot_led_controller.check_leakage_current.delta_cnt =
|
|
IOT_LED_CTRL_DATA_CHECK_DELTA_LEN_LEAKAGE;
|
|
iot_led_controller.check_leakage_current.sample_cnt =
|
|
IOT_LED_CTRL_DATA_CHECK_SAMPLE_LEN_LEAKAGE;
|
|
iot_led_controller.check_leakage_current.delta_value =
|
|
IOT_LED_CTRL_DATA_CHECK_DELTA_VALUE_LEAKAGE;
|
|
|
|
iot_led_controller.check_meter_voltage.first_run = true;
|
|
iot_led_controller.check_meter_voltage.delta_cnt =
|
|
IOT_LED_CTRL_DATA_CHECK_DELTA_LEN_METER;
|
|
iot_led_controller.check_meter_voltage.sample_cnt =
|
|
IOT_LED_CTRL_DATA_CHECK_SAMPLE_LEN_METER;
|
|
iot_led_controller.check_meter_voltage.delta_value =
|
|
IOT_LED_CTRL_DATA_CHECK_DELTA_VALUE_METER;
|
|
|
|
/* TODO : Disable ADC feature. Wait ADC code from iot2.2. */
|
|
#if (0)//IOT_LIGHT_CTRL_ADC_MODULE_ENABLE
|
|
/* Register leak current callback function. */
|
|
iot_energe_meter_leak_curr_cb_register(iot_led_crtl_leakage_evt_func);
|
|
/* Register get meter data callback function. */
|
|
iot_energe_meter_get_meter_data_cb_register(iot_led_ctrl_input_in_meter_param);
|
|
#endif
|
|
|
|
/* power up at 100% */
|
|
iot_light_drv_set_light_level(IOT_LIGHT_CHAN_ALL, IOT_LIGHT_BRIGHTNESS_RAW_LEVEL_MAX);
|
|
|
|
|
|
iot_cus_printf("[LIGHT_DRV]led control task create successfully.\n");
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
#endif
|
|
|