2667 lines
		
	
	
		
			85 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			2667 lines
		
	
	
		
			85 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | 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
 | ||
|  | 
 |