Files
kunlun/app/led_ctrl_app/controller/iot_light_ctrl_drv.c
2024-09-28 14:24:04 +08:00

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, &param);
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