/**************************************************************************** * * 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. * * ****************************************************************************/ /* os_ship header files */ #include "os_task_api.h" #include "os_timer_api.h" /* iot common header files */ #include "iot_task_api.h" #include "iot_io_api.h" #include "iot_errno_api.h" #include "iot_pkt_api.h" #include "iot_utils_api.h" #include "iot_cp_socket.h" #include "iot_energe_meter_api_v2.h" #define CP_SOCKET_MODULE_VERSION "1.0.004" #define CP_SOCKET_MID IOT_GREE_APP_MID #ifndef CP_SOCKET_DEBUG #define CP_SOCKET_DEBUG (0) #endif /* stack size of task */ #define CP_SOCKET_TASK_STACK_SIZE (2048) /* the priority of charge pile socket */ #define CP_SOCKET_TASK_PRIO (7) /* message queue items count. */ #define CP_SOCKET_TASK_MSG_CNT (64) /* indicate data event periodically, units:ms */ #define CP_INFO_DATA_EVENT_PERIOD (1000) /* task message type defination. */ /* command message, ex: config, query.... */ #define CP_SOCKET_MSG_TYPE_COMMAND (1) /* timer to set message, cycle indicate data event. */ #define CP_SOCKET_MSG_TYPE_TIMER (2) /* message from cp socket internal. */ #define CP_SOCKET_MSG_TYPE_INTERNAL (3) /* internal type message id definition. */ /* start indaicate all data event to other task timer. */ #define CP_SOCKET_MSG_ID_DATA_EVENT_TIMER (1) /* start energy meter measure. */ #define CP_SOCKET_MSG_ID_START_ENERGY_METER (2) /* select only one plug socket*/ #define CP_SOCKET_SELECT_ONE (1) /* select all plug sockets */ #define CP_SOCKET_SELECT_ALL (4) /* abnormal when voltage exceed rated±abnormal_threshold.unit:100mv */ #define CP_SOCKET_RATED_VOLTAGE_ABNORMAL_TH (500) /* recovery normal when voltage between rated±recovery_threshold.unit:100mv */ #define CP_SOCKET_RATED_VOLTAGE_RECOVERY_TH (400) /* plugin when switch voltage above plugin_voltage.unit:100mv */ #define CP_SOCKET_PLUGIN_VOLTAGE (1700) /* plugout when switch voltage below plugout_voltage.unit:100mv */ #define CP_SOCKET_PLUGOUT_VOLTAGE (1500) /* overload recovery when current below overload-overload_recovery_th value. unit:mA */ #define CP_SOCKET_OVERCURRENT_RECOVERY_TH (200) /* charge recovery when charge current above chargrfull_current+recovery_threshold. unit:mA */ #define CP_SOCKET_CHARGE_RECOVERY_TH (20) /* leak protect recovery when lead current below leak_current+leak_recovery. unit:mA */ #define CP_SOCKET_LEAK_PROTECT_RECOVERY_TH (5) /* open circurt current without load, uint:mA */ #define CP_SOCKET_OPEN_CIRCUIT_CURRENT_VALUE (13) /* delay to process charge status when interrupt plugout, because current update is not timely. uint:count * 500ms */ #define CP_SOCKET_DELAY_COUNT_AFTER_CHARGED (3) /* the count charging status will take effect when the current status changes, the time is count*(sample_point/sample_freq) seconds, according to your parameter configuration, the sample_point maybe 1024, the sample_freq maybe 2232Hz. */ #define CP_SOCKET_CHARGING_COUNT (2) /* the count charge full status will take effect when the current status changes, the time is count*(sample_point/sample_freq) seconds, according to your parameter configuration, the sample_point maybe 1024, the sample_freq maybe 2232Hz. */ #define CP_SOCKET_CHARGE_FULL_COUNT (60) /* the count charging status will take effect when the current status changes, the time is count*(sample_point/sample_freq) seconds, according to your parameter configuration, the sample_point maybe 1024, the sample_freq maybe 2232Hz. */ #define CP_SOCKET_PLUGOUT_COUNT (2) /* overvoltage when the voltage exceed the highest alarm voltage continuouly, time unit is count*(sample_point/sample_freq) seconds */ #define CP_SOCKET_VOLT_HIGH_COUNT (1) /* undervoltage when the voltage lower than the minimum alarm voltage continuouly, time unit is count*(sample_point/sample_freq) seconds */ #define CP_SOCKET_VOLT_LOW_COUNT (6) /* normal voltage when the voltage is in the threshold range continuouly, time unit is count*(sample_point/sample_freq) seconds */ #define CP_SOCKET_VOLT_NORMAL_COUNT (3) /* default initialization value. */ /* the rated voltage, such as 110V or 220v, unit: 1V */ #define CP_SOCKET_DEFAULT_CFG_RATED_VOLT (220) /* the current value when charge full, unit:1mA (1~1000) */ #define CP_SOCKET_DEFAULT_CFG_CHARGE_FULL_CURRENT (100) /* the current value when load is over, unit:0.1A (1~160) */ #define CP_SOCKET_DEFAULT_CFG_OVERLOAD_CURRENT (30) /* the current value when leak,unit:1 mA (1~255) */ #define CP_SOCKET_DEFAULT_CFG_LEAK_CURRENT (20) /* the config value is invalid */ #define CP_SOCKET_CFG_INVALID_VALUE (0) /* convert 1wms to 0.01kwh. */ #define CP_SOCKET_UNIT_WMS_TO_KWH(mws) ((mws)/(3.6e+7)) /* register callback function according to phase id */ typedef struct _std_get_phase_id_cb_t { uint32_t phase_id; iot_em_phase_get_data_std_cb cb; } std_get_phase_id_cb_t; /* meter data information include all sockets */ typedef struct _meter_data_info_t { /* charging volt, unit: 100mV */ uint32_t volt; /* leak-current, unit: mA */ uint32_t leak_i; /* voltage frequnce, unit: 0.01HZ */ uint32_t freq; /* plug info data, inlcude meter data and event data */ cp_socket_plug_info_t plug_info[CP_SOCKET_ID_ALL]; /* total energy consumption as relay on, unit is 1mWs=1mW*1s. */ uint64_t pwr_consum_mws[CP_SOCKET_ID_ALL]; } meter_data_info_t; /* plugin or plugout process */ typedef struct _plug_in_t { /* multiple confirmation states to eliminate jitter error. */ uint8_t filter; /* keep previous plug status. */ bool_t is_plug_in; } plug_in_t; /* according to the charging current, the charging state can be judged, and the state of continuous multiple current takes effect in the same range. */ typedef struct _cp_socket_charge_state_t { /* count when charging. */ uint16_t charging_count; /* count when charge full. */ uint16_t charge_full_count; /* count when plugout. */ uint16_t plugout_count; } cp_socket_current_count_t; /* check if the charge status changes, and delay to detect current status */ typedef struct _charge_status_t { /* current charge status, -1:need send charge status when relay on, 0:off, 1:on */ int8_t is_charge_current; /* previous charge status, -1:need send charge status when relay on, 0:off, 1:on */ int8_t is_charge_previous; /* delay processing count value after relay is on, because meter update slowly after relay on. */ uint32_t delay_count_after_charged; /* current count for charge status. */ cp_socket_current_count_t current_count; } charge_status_t; /* voltage judge count */ typedef struct _cp_socket_volt_judge_count_t { uint16_t high_count; uint16_t low_count; uint16_t normal_count; } cp_socket_volt_judge_count_t; /* message used on cp socket. */ typedef struct _cp_socket_task_msg_t { /* standard iot_task message. */ iot_task_msg_t msg; /* pointer to message data. */ void * data; } cp_socket_task_msg_t; /* the command handle. */ typedef void(*cp_socket_cmd_handle_t)(cp_socket_cmd_arg_t *arg); /* the table of command handle. */ typedef struct _cp_socket_cmd_table_t { cp_socket_cmd_handle_t *handle; } cp_socket_cmd_table_t; typedef struct _cp_socket_command_t { /* command id and opcode */ cp_socket_hdr_t hdr; /* Indication current cmd need response cfm to cp task layer. */ bool_t need_ack; /* The table of command handle on charging pile socket. */ cp_socket_cmd_table_t table; } cp_socket_command_t; /* register callback struct */ typedef struct _cp_socket_cb_t { cp_socket_resp_cb cmd_resp_cb; } cp_socket_cb_t; /* the cp socket context. */ typedef struct _cp_socket_context_t { /* cp socket task handle. */ iot_task_h task_h; /* indacate plug info periodic */ timer_id_t data_event_tmr; /* Current cmd handling. */ cp_socket_command_t command; /* meter data saved in context. */ meter_data_info_t meter_data; /* voltage judge count. */ cp_socket_volt_judge_count_t volt_judge; /* save fault status previous */ cp_socket_fault_t last_fault_status[CP_SOCKET_ID_ALL]; /* event status saved in local. */ cp_socket_cmd_event_status_t event_status[CP_SOCKET_ID_ALL]; /* save previous plugin status. */ plug_in_t plug_in[CP_SOCKET_ID_ALL]; /* keep current and previous charge status. */ charge_status_t charge_status[CP_SOCKET_ID_ALL]; /* cfg param saved in local. */ cp_socket_cmd_cfg_param_t cfg_param[CP_SOCKET_ID_ALL]; /* cp task registered callback. */ cp_socket_cb_t cb; } cp_socket_context_t; /* The energy socket adapter context. */ static cp_socket_context_t cp_socket_context; /* post internal message to internal task to process */ static void cp_socket_post_internal_msg(uint16_t msg_type, uint16_t msg_id, void * data); /* send pkg to cp task. must be register callback function first. */ static void cp_socket_send_to_cp_task(iot_pkt_t *pkt); /* energy meter init. */ static void cp_socket_energe_meter_init(void); /* get config param from cp task . */ static uint32_t cp_socket_update_config_parm(cp_socket_cmd_cfg_param_t* config) { uint32_t ret = ERR_OK; cp_socket_cmd_cfg_param_t *local_config; local_config = &cp_socket_context.cfg_param[config->plug_id]; /* save config param to global variable. */ os_mem_cpy(local_config, config,sizeof(cp_socket_cmd_cfg_param_t)); if (local_config->rated_volt == CP_SOCKET_CFG_INVALID_VALUE) { local_config->rated_volt = CP_SOCKET_DEFAULT_CFG_RATED_VOLT; } if (local_config->charge_full_i_th == CP_SOCKET_CFG_INVALID_VALUE) { local_config->charge_full_i_th = CP_SOCKET_DEFAULT_CFG_CHARGE_FULL_CURRENT; } if (local_config->overload_i_th == CP_SOCKET_CFG_INVALID_VALUE) { local_config->overload_i_th = CP_SOCKET_DEFAULT_CFG_OVERLOAD_CURRENT; } if (local_config->leak_i_th == CP_SOCKET_CFG_INVALID_VALUE) { local_config->leak_i_th = CP_SOCKET_DEFAULT_CFG_LEAK_CURRENT; } if (local_config->discon_cur_th == CP_SOCKET_CFG_INVALID_VALUE) { local_config->discon_cur_th = CP_SOCKET_OPEN_CIRCUIT_CURRENT_VALUE; } return ret; } /* fullfill config param from global variable. plug_id = 0,1,2,3 */ static uint32_t cp_socket_fullfill_config_parm(uint8_t plug_id, cp_socket_cmd_cfg_param_t* config) { uint32_t ret = ERR_OK; if (plug_id < CP_SOCKET_ID_ALL) { //read param from global variable according to plug_id. os_mem_cpy(config, &cp_socket_context.cfg_param[plug_id], sizeof(cp_socket_cmd_cfg_param_t)); } else { return ERR_INVAL; } return ret; } /* fullfill event status from global variable. plug_id = 0,1,2,3 */ static uint32_t cp_socket_fullfill_event_status(uint8_t plug_id, cp_socket_cmd_event_status_t* p_event_status) { uint32_t ret = ERR_OK; cp_socket_cmd_event_status_t *_p_event_status; _p_event_status = &cp_socket_context.event_status[plug_id]; if (plug_id < CP_SOCKET_ID_ALL) { p_event_status->event_id = _p_event_status->event_id; p_event_status->plug_id = _p_event_status->plug_id; os_mem_cpy(&p_event_status->fault_src, &_p_event_status->fault_src, sizeof(cp_socket_fault_t)); p_event_status->is_plug_in = _p_event_status->is_plug_in; p_event_status->volt = _p_event_status->volt; p_event_status->leak_i = _p_event_status->leak_i; os_mem_cpy(&p_event_status->meter_data, &_p_event_status->meter_data, sizeof(cp_socket_plug_meter_data_t)); } else { return ERR_INVAL; } return ret; } /* target plug's ID, range from 0 to 3, 4 means target * plugs are all of the 4 plugs. plug_id = 0,1,2,3 or 4(all) */ static uint32_t cp_socket_fullfill_plug_info(uint8_t plug_id, cp_socket_cmd_plug_info_resp_t * plug_info_resp) { uint32_t ret = ERR_OK; uint8_t i; if (plug_id < CP_SOCKET_ID_ALL) { plug_info_resp->plug_cnt = CP_SOCKET_SELECT_ONE; os_mem_cpy(&plug_info_resp->plug_info[0], &cp_socket_context.meter_data.plug_info[plug_id], sizeof(cp_socket_plug_info_t)); } else if (plug_id == CP_SOCKET_ID_ALL) { plug_info_resp->plug_cnt = CP_SOCKET_SELECT_ALL; for (i = 0; i < plug_info_resp->plug_cnt; i++) { os_mem_cpy(&plug_info_resp->plug_info[i], &cp_socket_context.meter_data.plug_info[i], sizeof(cp_socket_plug_info_t)); } } else { return ERR_INVAL; } plug_info_resp->volt = cp_socket_context.meter_data.volt; plug_info_resp->leak_i = cp_socket_context.meter_data.leak_i; plug_info_resp->freq = cp_socket_context.meter_data.freq; return ret; } /* param config handle. support config or query. */ static void cp_socket_cmd_handle_config(cp_socket_cmd_arg_t *cmd_arg) { cp_socket_cmd_arg_t *p_cmd_resp; iot_pkt_t *p_cmd_resp_pkt; uint32_t resp_pkt_data_len; static bool_t is_init_energy_meter = false; static uint8_t plug_id_full_param_config = 0x00; switch (cmd_arg->hdr.opcode) { case CP_SOCKET_OP_CONFIG: { cp_socket_cmd_cfg_param_t *p_cfg_param; cp_socket_cmd_confirm_t *p_confirm; p_cfg_param = (cp_socket_cmd_cfg_param_t*)cmd_arg->arg; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s config param:pulg_id=%d, " "reted_voltage=%dV, charge_full_i_th=%d, overload_i_th=%d," "leak_i_th=%d.\n", __FUNCTION__, p_cfg_param->plug_id, p_cfg_param->rated_volt, p_cfg_param->charge_full_i_th, p_cfg_param->overload_i_th, p_cfg_param->leak_i_th); #endif resp_pkt_data_len = sizeof(cp_socket_cmd_confirm_t); p_cmd_resp_pkt = iot_pkt_alloc(sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len, CP_SOCKET_MID); if (NULL == p_cmd_resp_pkt) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_cmd_resp = (cp_socket_cmd_arg_t *)iot_pkt_put(p_cmd_resp_pkt, sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len); cp_socket_update_config_parm(p_cfg_param); p_confirm = (cp_socket_cmd_confirm_t *)p_cmd_resp->arg; p_confirm->reason = CP_SOCKET_NO_FAIL; p_confirm->result = CP_SOCKET_NO_FAIL; p_cmd_resp->hdr.cid = CP_SOCKET_CID_CONFIG; p_cmd_resp->hdr.opcode = CP_SOCKET_OP_CFM; p_cmd_resp->dlen = resp_pkt_data_len; p_cmd_resp->need_ack = 0; cp_socket_send_to_cp_task(p_cmd_resp_pkt); plug_id_full_param_config |= (1 << p_cfg_param->plug_id); /* when param config finished, then start energy meter measure, only first startup take effect. */ if (false == is_init_energy_meter && plug_id_full_param_config == 0x0F) { is_init_energy_meter = true; cp_socket_post_internal_msg(CP_SOCKET_MSG_TYPE_INTERNAL, CP_SOCKET_MSG_ID_START_ENERGY_METER, NULL); cp_socket_post_internal_msg(CP_SOCKET_MSG_TYPE_INTERNAL, CP_SOCKET_MSG_ID_DATA_EVENT_TIMER, NULL); } break; } case CP_SOCKET_OP_QUERY: { cp_socket_cmd_query_param_t *p_query_param; cp_socket_cmd_cfg_param_t *p_cfg_param; p_query_param = (cp_socket_cmd_query_param_t*)cmd_arg->arg; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s query param: pulg_id=%d.\n", __FUNCTION__, p_query_param->plug_id); #endif resp_pkt_data_len = sizeof(cp_socket_cmd_cfg_param_t); p_cmd_resp_pkt = iot_pkt_alloc(sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len, CP_SOCKET_MID); if (NULL == p_cmd_resp_pkt) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_cmd_resp = (cp_socket_cmd_arg_t *)iot_pkt_put(p_cmd_resp_pkt, sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len); p_cfg_param = (cp_socket_cmd_cfg_param_t *)p_cmd_resp->arg; cp_socket_fullfill_config_parm(p_query_param->plug_id, p_cfg_param); p_cmd_resp->hdr.cid = CP_SOCKET_CID_CONFIG; p_cmd_resp->hdr.opcode = CP_SOCKET_OP_RESPONSE; p_cmd_resp->dlen = resp_pkt_data_len; p_cmd_resp->need_ack = 0; break; } default: IOT_ASSERT(0); break; } } /* query plug info handle. support query. */ static void cp_socket_cmd_handle_pulg_info(cp_socket_cmd_arg_t *cmd_arg) { cp_socket_cmd_arg_t *p_cmd_resp; iot_pkt_t *p_cmd_resp_pkt; uint32_t resp_pkt_data_len = 0; switch (cmd_arg->hdr.opcode) { case CP_SOCKET_OP_QUERY: { cp_socket_cmd_query_param_t *p_query_param; cp_socket_cmd_plug_info_resp_t *p_plug_info_resp; p_query_param = (cp_socket_cmd_query_param_t*)cmd_arg->arg; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s query param: pulg_id=%d.\n", __FUNCTION__, p_query_param->plug_id); #endif if (p_query_param->plug_id < CP_SOCKET_ID_ALL) { resp_pkt_data_len = sizeof(cp_socket_cmd_plug_info_resp_t) + sizeof(cp_socket_plug_info_t) * CP_SOCKET_SELECT_ONE; } else if (p_query_param->plug_id == CP_SOCKET_ID_ALL) { resp_pkt_data_len = sizeof(cp_socket_cmd_plug_info_resp_t) + sizeof(cp_socket_plug_info_t) * CP_SOCKET_SELECT_ALL; } p_cmd_resp_pkt = iot_pkt_alloc(sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len, CP_SOCKET_MID); if (NULL == p_cmd_resp_pkt) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_cmd_resp = (cp_socket_cmd_arg_t *)iot_pkt_put(p_cmd_resp_pkt, sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len); p_plug_info_resp = (cp_socket_cmd_plug_info_resp_t *)p_cmd_resp->arg; cp_socket_fullfill_plug_info(p_query_param->plug_id, p_plug_info_resp); p_cmd_resp->hdr.cid = CP_SOCKET_CID_PLUG_INFO; p_cmd_resp->hdr.opcode = CP_SOCKET_OP_RESPONSE; p_cmd_resp->dlen = resp_pkt_data_len; p_cmd_resp->need_ack = 0; break; } default: IOT_ASSERT(0); break; } } /* query event status handle. support query. */ static void cp_socket_cmd_handle_event_status(cp_socket_cmd_arg_t *cmd_arg) { cp_socket_cmd_arg_t *p_cmd_resp; iot_pkt_t *p_cmd_resp_pkt; uint32_t resp_pkt_data_len = 0; switch (cmd_arg->hdr.opcode) { case CP_SOCKET_OP_QUERY: { cp_socket_cmd_query_param_t *p_query_param; cp_socket_cmd_event_status_t *p_event_status; p_query_param = (cp_socket_cmd_query_param_t*)cmd_arg->arg; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s query param: pulg_id=%d.\n", __FUNCTION__, p_query_param->plug_id); #endif resp_pkt_data_len = sizeof(cp_socket_cmd_event_status_t); p_cmd_resp_pkt = iot_pkt_alloc(sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len, CP_SOCKET_MID); if (NULL == p_cmd_resp_pkt) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_cmd_resp = (cp_socket_cmd_arg_t *)iot_pkt_put(p_cmd_resp_pkt, sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len); p_event_status = (cp_socket_cmd_event_status_t *)p_cmd_resp->arg; /* Fill actual data field in command response struct. */ cp_socket_fullfill_event_status(p_query_param->plug_id, p_event_status); #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s query event status response: pulg_id=%d, " "event_id = %d.\n", __FUNCTION__, p_event_status->plug_id, p_event_status->event_id); #endif p_cmd_resp->hdr.cid = CP_SOCKET_CID_STATUS_EVENT; p_cmd_resp->hdr.opcode = CP_SOCKET_OP_RESPONSE; p_cmd_resp->dlen = resp_pkt_data_len; p_cmd_resp->need_ack = 0; break; } case CP_SOCKET_OP_CFM: { #if CP_SOCKET_DEBUG cp_socket_cmd_confirm_t *p_cmd_confirm; p_cmd_confirm = (cp_socket_cmd_confirm_t*)cmd_arg->arg; iot_cus_printf("[cp_socket] %s report event status cfm: reason=%d, " "result=%d.\n", __FUNCTION__, p_cmd_confirm->reason, p_cmd_confirm->result); #endif break; } default: IOT_ASSERT(0); break; } } /* set relay state handle. support config */ static void cp_socket_cmd_handle_relay_state(cp_socket_cmd_arg_t *cmd_arg) { switch (cmd_arg->hdr.opcode) { case CP_SOCKET_OP_CONFIG: { cp_relay_state_t *p_relay_state; cp_socket_plug_info_t *p_plug_info; charge_status_t *p_charge_status; p_relay_state = (cp_relay_state_t*)cmd_arg->arg; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s relay_state:pulg_id=%d, state=%d\n", __FUNCTION__, p_relay_state->plug_id, p_relay_state->relay_state); #endif p_plug_info = &cp_socket_context.meter_data.plug_info[p_relay_state->plug_id]; p_charge_status = &cp_socket_context.charge_status[p_relay_state->plug_id]; p_plug_info->relay_state = p_relay_state->relay_state; if (true == p_plug_info->relay_state) { /* reset delay_count_after_charged value. */ p_charge_status->delay_count_after_charged = 0; p_charge_status->is_charge_current = -1; p_charge_status->is_charge_previous = -1; p_charge_status->current_count.charging_count = 0; p_charge_status->current_count.charge_full_count = 0; p_charge_status->current_count.plugout_count = 0; } break; } default: IOT_ASSERT(0); break; } } /* The table of cp socket command table. */ const static cp_socket_cmd_handle_t cmd_handle_table[] = { cp_socket_cmd_handle_config, /* CP_SOCKET_CID_CONFIG */ cp_socket_cmd_handle_pulg_info, /* CP_SOCKET_CID_PLUG_INFO */ cp_socket_cmd_handle_event_status, /* CP_SOCKET_CID_STATUS_EVENT */ NULL, /* CP_SOCKET_CID_DATA_EVENT */ cp_socket_cmd_handle_relay_state, /* CP_SOCKET_CID_RELAY_STATE */ }; /* send pkg to cp task. must be register callback function first. */ static void cp_socket_send_to_cp_task(iot_pkt_t *pkt) { if (NULL == pkt) { iot_cus_printf("[cp_socket][err] %s point null.\n", __FUNCTION__); IOT_ASSERT(0); return; } if (NULL != cp_socket_context.cb.cmd_resp_cb) { cp_socket_context.cb.cmd_resp_cb(pkt); } else { /* drop this command. */ iot_pkt_free(pkt); } } /* Report event to cp task layer. */ static void cp_socket_event_report_to_cp_task(uint8_t plug_id) { iot_pkt_t *p_cmd_resp_pkt; uint32_t resp_pkt_data_len; cp_socket_cmd_arg_t *p_cmd_resp; cp_socket_cmd_event_status_t *p_event_status; /* Prepare memory space used for response operation. */ resp_pkt_data_len = sizeof(cp_socket_cmd_event_status_t); p_cmd_resp_pkt = iot_pkt_alloc(sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len, CP_SOCKET_MID); if (NULL == p_cmd_resp_pkt) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_cmd_resp = (cp_socket_cmd_arg_t *)iot_pkt_put(p_cmd_resp_pkt, sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len); p_cmd_resp->hdr.cid = CP_SOCKET_CID_STATUS_EVENT; p_cmd_resp->hdr.opcode = CP_SOCKET_OP_INDICATION; p_cmd_resp->dlen = resp_pkt_data_len; p_cmd_resp->need_ack = 0; /* Fill actual data field in command response struct. */ p_event_status = (cp_socket_cmd_event_status_t *)p_cmd_resp->arg; cp_socket_fullfill_event_status(plug_id, p_event_status); #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s report event status: pulg_id=%d, " "event_id=%d, fault_src: overvolt=%d, overcur=%d, leak_cur_protec=%d, " "is_plug_in=%d.\n", __FUNCTION__, p_event_status->plug_id, p_event_status->event_id, p_event_status->fault_src.overvolt, p_event_status->fault_src.overcur, p_event_status->fault_src.leak_cur_protec, p_event_status->is_plug_in); #endif /* Report event record.*/ cp_socket_send_to_cp_task(p_cmd_resp_pkt); } /* Report data to cp task layer. */ static void cp_socket_data_report_to_cp_task(void) { iot_pkt_t *p_cmd_resp_pkt; uint32_t resp_pkt_data_len; cp_socket_cmd_arg_t *p_cmd_resp; cp_socket_cmd_plug_info_resp_t *p_plug_info_resp; /* Prepare memory space used for response operation. */ resp_pkt_data_len = sizeof(cp_socket_cmd_plug_info_resp_t) + sizeof(cp_socket_plug_info_t) * CP_SOCKET_ID_ALL; p_cmd_resp_pkt = iot_pkt_alloc(sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len, CP_SOCKET_MID); if (NULL == p_cmd_resp_pkt) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_cmd_resp = (cp_socket_cmd_arg_t *)iot_pkt_put(p_cmd_resp_pkt, sizeof(cp_socket_cmd_arg_t) + resp_pkt_data_len); p_cmd_resp->hdr.cid = CP_SOCKET_CID_DATA_EVENT; p_cmd_resp->hdr.opcode = CP_SOCKET_OP_INDICATION; p_cmd_resp->dlen = resp_pkt_data_len; p_cmd_resp->need_ack = 0; /* Fill actual data field in command response struct. */ p_plug_info_resp = (cp_socket_cmd_plug_info_resp_t *)p_cmd_resp->arg; cp_socket_fullfill_plug_info(CP_SOCKET_ID_ALL, p_plug_info_resp); #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]%s report_data:pulg_cnt=%d,rated_v=%d," "leak_i=%d,freq=%d.\n", __FUNCTION__, p_plug_info_resp->plug_cnt, p_plug_info_resp->volt, p_plug_info_resp->leak_i, p_plug_info_resp->freq); for (uint8_t i = 0; i < CP_SOCKET_ID_ALL; i++) { iot_cus_printf("plug_id:%d,relay_state:%d,is_plug_in:%d,plug_vol:%d," "charging_i:%d,power_rate:%d,pwr_consum:%d.\n", p_plug_info_resp->plug_info[i].plug_id, p_plug_info_resp->plug_info[i].relay_state, p_plug_info_resp->plug_info[i].is_plug_in, p_plug_info_resp->plug_info[i].incumbent_v, p_plug_info_resp->plug_info[i].meter_data.charging_i, p_plug_info_resp->plug_info[i].meter_data.power_rate, p_plug_info_resp->plug_info[i].meter_data.pwr_consum); } #endif /* Report event record.*/ cp_socket_send_to_cp_task(p_cmd_resp_pkt); } static void cp_socket_cmd_msg_handle(cp_socket_task_msg_t *task_msg) { uint8_t cid; cp_socket_cmd_arg_t *p_arg; iot_pkt_t *p_arg_pkt; if (!task_msg || !task_msg->data) { iot_cus_printf("[cp_socket][err] %s point null.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_arg_pkt = (iot_pkt_t *)task_msg->data; p_arg = (cp_socket_cmd_arg_t*)iot_pkt_data(p_arg_pkt); cid = p_arg->hdr.cid; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s cid=%d, op_code=%d\n", __FUNCTION__, cid, p_arg->hdr.opcode); #endif if (cid >= CP_SOCKET_CID_MAX) { iot_cus_printf("[cp_socket][err] %s arg fail.\n", __FUNCTION__); iot_pkt_free(p_arg_pkt); IOT_ASSERT(0); return; } cp_socket_context.command.hdr = p_arg->hdr; cp_socket_context.command.need_ack = (bool_t)p_arg->need_ack; cp_socket_context.command.table.handle[cid](p_arg); if (NULL != p_arg_pkt) { iot_pkt_free(p_arg_pkt); } } static void cp_socket_timer_msg_handle(cp_socket_task_msg_t *task_msg) { if (NULL == task_msg) { iot_cus_printf("[cp_socket][err] %s point null.\n", __FUNCTION__); IOT_ASSERT(0); return; } #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s msg_type=%d, msg_id=%d, msg process start.\n", __FUNCTION__, task_msg->msg.type, task_msg->msg.id); #endif switch (task_msg->msg.id) { case CP_SOCKET_MSG_ID_DATA_EVENT_TIMER: { cp_socket_data_report_to_cp_task(); break; } default: break; } } static void cp_socket_internal_msg_handle(cp_socket_task_msg_t *task_msg) { if (NULL == task_msg) { iot_cus_printf("[cp_socket][err] %s point null.\n", __FUNCTION__); IOT_ASSERT(0); return; } iot_cus_printf("[cp_socket] %s msg_type=%d, msg_id=%d.\n", __FUNCTION__, task_msg->msg.type, task_msg->msg.id); switch (task_msg->msg.id) { case CP_SOCKET_MSG_ID_DATA_EVENT_TIMER: { /* Start indicate data event timer. */ iot_cus_printf("[cp socket] %s start indicate data event timer!\n", __FUNCTION__); os_start_timer(cp_socket_context.data_event_tmr, CP_INFO_DATA_EVENT_PERIOD); break; } case CP_SOCKET_MSG_ID_START_ENERGY_METER: { /* Start energy meter measur. */ iot_cus_printf("[cp socket] %s start energy meter measure!\n", __FUNCTION__); /* energy meter open and register callback functions. */ cp_socket_energe_meter_init(); break; } default: IOT_ASSERT(0); break; } } /** * @brief cp_socket_msg_exe_func() - messages handle function. * @param task_h: handle of task. * @param p_msg: message that will be processed. */ static void cp_socket_msg_exe_func(iot_task_h task_h, iot_task_msg_t *msg) { cp_socket_task_msg_t *p_task_msg; if ((NULL == msg) || (task_h != cp_socket_context.task_h)) { iot_cus_printf("[cp_socket][err] %s point null.\n", __FUNCTION__); IOT_ASSERT(0); return; } p_task_msg = (cp_socket_task_msg_t *)msg; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket] %s msg_type=%d, msg_id=%d, msg process start.\n", __FUNCTION__, p_task_msg->msg.type, p_task_msg->msg.id); #endif switch (p_task_msg->msg.type) { case CP_SOCKET_MSG_TYPE_COMMAND: { cp_socket_cmd_msg_handle(p_task_msg); break; } case CP_SOCKET_MSG_TYPE_TIMER: { cp_socket_timer_msg_handle(p_task_msg); break; } case CP_SOCKET_MSG_TYPE_INTERNAL: { cp_socket_internal_msg_handle(p_task_msg); break; } default: break; } iot_task_free_msg(cp_socket_context.task_h, &p_task_msg->msg); } /** * @brief cp_socket_msg_cancel_func()-pull back messages that sent to this task. * @param task_h: handle of task. * @param p_msg: message that will be pull back. */ static void cp_socket_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *msg) { cp_socket_task_msg_t *p_task_msg; IOT_ASSERT(task_h == cp_socket_context.task_h); IOT_ASSERT(msg); p_task_msg = (cp_socket_task_msg_t *)msg; switch (p_task_msg->msg.type) { case CP_SOCKET_MSG_TYPE_COMMAND: case CP_SOCKET_MSG_TYPE_TIMER: case CP_SOCKET_MSG_TYPE_INTERNAL: { break; } default: IOT_ASSERT(0); break; } iot_task_free_msg(cp_socket_context.task_h, &p_task_msg->msg); } static void cp_socket_post_internal_msg(uint16_t msg_type, uint16_t msg_id, void *data) { cp_socket_task_msg_t *p_task_msg; if (cp_socket_context.task_h == NULL) { goto out; } p_task_msg = (cp_socket_task_msg_t *)iot_task_alloc_msg_with_reserved (cp_socket_context.task_h, 0); if (NULL == p_task_msg) { iot_cus_printf("[cp_socket][err] %s not enough momory.\n", __FUNCTION__); goto out; } p_task_msg->msg.type = msg_type; p_task_msg->msg.id = msg_id; p_task_msg->data = data; iot_task_queue_msg(cp_socket_context.task_h, &p_task_msg->msg, 0); return; out: if (data) { iot_pkt_free(data); } return; } uint32_t cp_socket_cmd_send_mssage(iot_pkt_t *arg) { if (NULL == arg) { iot_cus_printf("[cp_socket][err] %s point null.\n", __FUNCTION__); IOT_ASSERT(0); return ERR_FAIL; } cp_socket_post_internal_msg(CP_SOCKET_MSG_TYPE_COMMAND, 0, arg); return ERR_OK; } /* send pkg to cp task. register callback function. */ uint32_t cp_socket_register(cp_socket_resp_cb cb) { uint32_t ret = ERR_FAIL; if (cb) { cp_socket_context.cb.cmd_resp_cb = cb; ret = ERR_OK; } return ret; } static void cp_socket_data_event_tmr_cb(timer_id_t timer_id, void *arg) { (void)timer_id; (void)arg; cp_socket_post_internal_msg(CP_SOCKET_MSG_TYPE_TIMER, CP_SOCKET_MSG_ID_DATA_EVENT_TIMER, NULL); } /* cp socket meter hardware adc param config. */ static const iot_em_cust_info_t g_em_cps_info = { /*************************************************************************/ /* Charging pile customer info. * ADC0 and ADC1 module's channel-pin and phase table: * ----------------------------------------------------------------- * | module | channel-pin | phase | function | description | * | ADC0 | AD0_CH1 | phase0 | I0 | meter current | * | ADC0 | AD1_CH1 | phase1 | I1 | meter current | * | ADC0 | AD2_CH1 | unused | unused | unused | * | ADC0 | AD3_CH1 | phase3.0 | U3 | switch voltage | * | ADC0 | AD4_CH1 | phase3.1 | U2 | switch voltage | * | ADC0 | AD5_CH1 | phase3.2 | U1 | switch voltage | * | ADC0 | AD6_CH1 | phase3.3 | U0 | switch voltage | * | ADC0 | AD7_CH1 | phase2 | I2 | meter current | * | ADC1 | AD0_CH2 | phase0 | I3 | meter current | * | ADC1 | AD1_CH2 | phase1 | Up | meter voltage | * | ADC1 | AD2_CH2 | phase2 | Il | leak current | * | ADC1 | AD3_CH2 | phase2 | Il | leak current | * | ADC1 | AD4_CH2 | phase3.0 | GND | gnd | * | ADC1 | AD4_CH2 | phase3.1 | GND | gnd | * | ADC1 | AD4_CH2 | phase3.2 | GND | gnd | * | ADC1 | AD4_CH2 | phase3.3 | GND | gnd | * ----------------------------------------------------------------- */ /*************************************************************************/ /* Chip info. */ .chip_info.chip_type = IOT_EM_WQ3021, /*************************************************************************/ /*************************************************************************/ /* Control info. */ /* Customer id type. */ .ctrl_info.cust_id = CUST_CHARGE_PILE, /* Mark whether the customer's config is valid. */ .ctrl_info.cust_valid = true, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase0. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_0, .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 20mohm, * the scale = 1 * (1/(0.02)) = 50. * times this scale, the unit of current is A. * The numerator is 50, denominator is 1. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.scale_div_res_numer = 50, .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain, enlarge * or reduce the input signal to the adc reference voltage range. * Ex, reference voltage:0.35V, adc resolution was 0.1483mV. * When measure voltage, min voltage on ADC pin:0.2659mV, * 0.2659mV calculate method: 1V times scale of divider resistance, * 1V * 50 / (4*47*1000+50). * we should select the gain suitable for 0.2659mV voltage, * choose gain 1 is ok. * * When measure current, min voltage on ADC pin:0.01mV, * 0.01mV calculate method: current is 10mA, divider resistance is 1mohm, * 10mA * 1mohm = 10uV = 0.01mV, * so, should select the gain suitable for 0.01mV voltage, * choose gain 32 is ok. * In order to avoid using float data, V times 1000000, now unit is uV. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_2232HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.analy_method_type = EM_PHASE_ANALY_FREQ_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_INVALID, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.cali_param.scale_liner = 9913, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.cali_param.scale_offset = 7303, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.cali_param.scale_mul = 10000, /* Power scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.power_cali_param.scale_liner = 10210, /* Power scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.power_cali_param.scale_offset = 793, /* Power scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.power_cali_param.scale_mul = 10000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_0].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase1. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_1, .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 20mohm, * the scale = 1 * (1/(0.02)) = 50. * times this scale, the unit of current is A. * The numerator is 50, denominator is 1. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.scale_div_res_numer = 50, .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_2232HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.analy_method_type = EM_PHASE_ANALY_FREQ_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_INVALID, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.cali_param.scale_liner = 9950, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.cali_param.scale_offset = 11293, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.cali_param.scale_mul = 10000, /* Power scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.power_cali_param.scale_liner = 10227, /* Power scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.power_cali_param.scale_offset = 2054, /* Power scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.power_cali_param.scale_mul = 10000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_1].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase2. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_7, .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 20mohm, * the scale = 1 * (1/(0.02)) = 50. * times this scale, the unit of current is A. * The numerator is 50, denominator is 1. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.scale_div_res_numer = 50, .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_2232HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.analy_method_type = EM_PHASE_ANALY_FREQ_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_INVALID, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.cali_param.scale_liner = 9953, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.cali_param.scale_offset = 9023, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.cali_param.scale_mul = 10000, /* Power scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.power_cali_param.scale_liner = 10212, /* Power scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.power_cali_param.scale_offset = 2097, /* Power scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.power_cali_param.scale_mul = 10000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_2].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase3.0. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_3, .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.meter_type = EM_ADC_SAMP_METER_VOLTAGE, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.paired_phase = EM_ADC_DMA_PHASE_MAX_NUM, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * Meause voltage, use 4 resistors with 47K ohm and one resistor * with 50ohm, the scale = (4*47*1000+50)/50. * Times this scale, the unit of voltage is V. * The numerator: (4*47*1000+50); denominator: 50. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.scale_div_res_numer = (4*47*1000+50), .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.scale_div_res_denom = 50, /* Min voltage on ADC pin, used for calculate adc gain, enlarge * or reduce the input signal to the adc reference voltage range. * Ex, reference voltage:0.35V, adc resolution was 0.1483mV. * When measure voltage, min voltage on ADC pin:0.2659mV, * 0.2659mV calculate method: 1V times scale of divider resistance, * 1V * 50 / (4*47*1000+50). * we should select the gain suitable for 0.2659mV voltage, * choose gain 1 is ok. * * When measure current, min voltage on ADC pin:0.01mV, * 0.01mV calculate method: current is 10mA, divider resistance is 1mohm, * 10mA * 1mohm = 10uV = 0.01mV, * so, should select the gain suitable for 0.01mV voltage, * choose gain 32 is ok. * In order to avoid using float data, V times 1000000, now unit is uV. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.pin_min_volt_uv = 265, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.cali_param.scale_liner = 371, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.cali_param.scale_offset = -322, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_0].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase3.1. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_4, .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.meter_type = EM_ADC_SAMP_METER_VOLTAGE, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.paired_phase = EM_ADC_DMA_PHASE_MAX_NUM, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * Meause voltage, use 4 resistors with 47K ohm and one resistor * with 50ohm, the scale = (4*47*1000+50)/50. * Times this scale, the unit of voltage is V. * The numerator: (4*47*1000+50); denominator: 50. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.scale_div_res_numer = (4*47*1000+50), .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.scale_div_res_denom = 50, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.pin_min_volt_uv = 265, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.cali_param.scale_liner = 371, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.cali_param.scale_offset = -322, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_1].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase3.2. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_5, .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.meter_type = EM_ADC_SAMP_METER_VOLTAGE, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.paired_phase = EM_ADC_DMA_PHASE_MAX_NUM, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * Meause voltage, use 4 resistors with 47K ohm and one resistor * with 50ohm, the scale = (4*47*1000+50)/50. * Times this scale, the unit of voltage is V. * The numerator: (4*47*1000+50); denominator: 50. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.scale_div_res_numer = (4*47*1000+50), .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.scale_div_res_denom = 50, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.pin_min_volt_uv = 265, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.cali_param.scale_liner = 371, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.cali_param.scale_offset = -322, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_2].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc0 phase3.3. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH1_6, .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.meter_type = EM_ADC_SAMP_METER_VOLTAGE, /* ADC sample wire id. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.paired_phase = EM_ADC_DMA_PHASE_MAX_NUM, /* ADC sample wave type.*/ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * Meause voltage, use 4 resistors with 47K ohm and one resistor * with 50ohm, the scale = (4*47*1000+50)/50. * Times this scale, the unit of voltage is V. * The numerator: (4*47*1000+50); denominator: 50. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.scale_div_res_numer = (4*47*1000+50), .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.scale_div_res_denom = 50, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.pin_min_volt_uv = 265, /* Sample frequency. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.cali_param.scale_liner = 371, /* Scale offset. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.cali_param.scale_offset = -322, /* Scale multiple. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC0_DMA_PHASE_3_3].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase0. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH2_0, .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 20mohm, * the scale = 1 * (1/(0.02)) = 50. * times this scale, the unit of current is A. * The numerator is 50, denominator is 1. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.scale_div_res_numer = 50, .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_2232HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.analy_method_type = EM_PHASE_ANALY_FREQ_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_INVALID, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.cali_param.scale_liner = 9806, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.cali_param.scale_offset = 15688, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.cali_param.scale_mul = 10000, /* Power scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.power_cali_param.scale_liner = 9976, /* Power scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.power_cali_param.scale_offset = 3089, /* Power scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.power_cali_param.scale_mul = 10000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_0].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase1. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH2_1, .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.meter_type = EM_ADC_SAMP_METER_VOLTAGE, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_2, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * Meause voltage, use 4 resistors with 47K ohm and one resistor * with 50ohm, the scale = (4*47*1000+50)/50. * Times this scale, the unit of voltage is V. * The numerator: (4*47*1000+50); denominator: 50. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.scale_div_res_numer = (4*47*1000+50), .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.scale_div_res_denom = 50, /* Min voltage on ADC pin, used for calculate adc gain, enlarge * or reduce the input signal to the adc reference voltage range. * Ex, reference voltage:0.35V, adc resolution was 0.1483mV. * When measure voltage, min voltage on ADC pin:0.2659mV, * 0.2659mV calculate method: 1V times scale of divider resistance, * 1V * 50 / (4*47*1000+50). * we should select the gain suitable for 0.2659mV voltage, * choose gain 1 is ok. * * When measure current, min voltage on ADC pin:0.01mV, * 0.01mV calculate method: current is 10mA, divider resistance is 1mohm, * 10mA * 1mohm = 10uV = 0.01mV, * so, should select the gain suitable for 0.01mV voltage, * choose gain 32 is ok. * In order to avoid using float data, V times 1000000, now unit is uV. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.pin_min_volt_uv = 265, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_2232HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.analy_method_type = EM_PHASE_ANALY_FREQ_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_INVALID, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.cali_param.scale_liner = 10274, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.cali_param.scale_offset = 0, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.cali_param.scale_mul = 10000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_1].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase2. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].phase_valid = true, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.pin_sel = EM_ADC_PIN_DIFF_CH2_32, .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_DIFFERENTIAL, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.meter_type = EM_ADC_SAMP_METER_LEAK_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.paired_phase = EM_ADC0_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 200ohm, * current transformer ratio is 1000, the scale = 1000 * (1/(200)) = 5. * times this scale, the unit of current is A. * The numerator is 5 , denominator is 1. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.scale_div_res_numer = 5, .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain, enlarge * or reduce the input signal to the adc reference voltage range. * Ex, reference voltage:0.35V, adc resolution was 0.1483mV. * When measure voltage, min voltage on ADC pin:0.2659mV, * 0.2659mV calculate method: 1V times scale of divider resistance, * 1V * 50 / (4*47*1000+50). * we should select the gain suitable for 0.2659mV voltage, * choose gain 1 is ok. * * When measure current, min voltage on ADC pin:0.2mV, * 0.2mV calculate method: current is 1uA, divider resistance is 200ohm, * 1uA * 200ohm = 200uV = 0.2mV, * so, should select the gain suitable for 0.2mV voltage, * choose gain 1 is ok. * In order to avoid using float data, V times 1000000, now unit is uV. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.pin_min_volt_uv = 200, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_2232HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.cali_param.scale_liner = 363418, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.cali_param.scale_offset = -371, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_2].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase3.0. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].phase_valid = false, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH2_4, .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 1mohm, * the scale = 1 * (1/(0.001)) = 1000. * times this scale, the unit of current is A. * The numerator is 1000, denominator is 1. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.scale_div_res_numer = 1000, .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.cali_param.scale_liner = 1009, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.cali_param.scale_offset = 402, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_0].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase3.1. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].phase_valid = false, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH2_4, .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 1mohm, * the scale = 1 * (1/(0.001)) = 1000. * times this scale, the unit of current is A. * The numerator is 1000, denominator is 1. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.scale_div_res_numer = 1000, .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.cali_param.scale_liner = 1009, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.cali_param.scale_offset = 402, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_1].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase3.2. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].phase_valid = false, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH2_4, .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 1mohm, * the scale = 1 * (1/(0.001)) = 1000. * times this scale, the unit of current is A. * The numerator is 1000, denominator is 1. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.scale_div_res_numer = 1000, .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.cali_param.scale_liner = 1009, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.cali_param.scale_offset = 402, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_2].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ /*************************************************************************/ /* Profile information of adc1 phase3.3. */ /* Mark whether the pahse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].phase_on = false, /* Mark whether the pahse's config is valid. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].phase_valid = false, /*************************************************/ /* Hardware config of phase. */ /* ADC pin select. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.pin_sel = EM_ADC_PIN_SING_CH2_4, .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.signal_type = EM_ADC_PIN_SIGNAL_SINGLE_ENDED, /* ADC sample meter type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.meter_type = EM_ADC_SAMP_METER_CURRENT, /* ADC sample wire id. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.wire_id = EM_ADC_SAMP_WIRE_ID_UNUSE, /* Paired phase used for calculate power. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.paired_phase = EM_ADC1_DMA_PHASE_1, /* ADC sample wave type.*/ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.wave_type = EM_ADC_SAMP_WAVE_AC_SINE, /* Scale of divider resistance. * When measure current, may use 1 resistors with 1mohm, * the scale = 1 * (1/(0.001)) = 1000. * times this scale, the unit of current is A. * The numerator is 1000, denominator is 1. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.scale_div_res_numer = 1000, .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.scale_div_res_denom = 1, /* Min voltage on ADC pin, used for calculate adc gain. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.pin_min_volt_uv = 50, /* Sample frequency. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].hw_cfg.sample_freq = EM_ADC_SAMPLE_FREQ_558HZ, /*************************************************/ /* Software config of phase. */ /* Phase data analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.analy_method_type = EM_PHASE_ANALY_TIME_DOMAIN, /* Phase data time domain analysis method type. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.td_analy_method_type = EM_PHASE_ANALY_TD_PP, /* Harmonic analysis amplitude threshold. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.harmonic_ampl_thr = 0, /* Softdware calibration param. */ /* Scale liner. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.cali_param.scale_liner = 1009, /* Scale offset. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.cali_param.scale_offset = 402, /* Scale multiple. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.cali_param.scale_mul = 1000, /* Sample source threshold. */ /* Sampling meter/leak current, uint is mA; for meter voltage is mV. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.samp_src_thr.max = 0, .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.samp_src_thr.min = 0, /* Led pulse config. */ /* Mark whether the pahse led pulse is working. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.led_pulse.pulse_on = false, /* Config GPIO for led pulse. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.led_pulse.gpio = 43, /* Frequency of pulse per second. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.led_pulse.freq_hz = 0, /* Get Standard level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.data_std_cb = NULL, /* Get Professional level data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.data_pro_cb = NULL, /* Get Industrial grade data callback function. */ .phase_cfg[EM_ADC1_DMA_PHASE_3_3].sw_cfg.data_ind_cb = NULL, /*************************************************************************/ }; /* when receive socket current phase, then we can get current, power, energy, factor...we can save data info to golbal variable by plud_id, and chect data. */ static void cp_socket_meter_data_process(uint8_t plug_id, iot_em_phase_data_std_t *p_phase_data) { cp_socket_plug_info_t *p_plug_info; cp_socket_cmd_event_status_t *p_event_status; cp_socket_cmd_cfg_param_t *p_cfg_param; cp_socket_fault_t *p_last_fault_status; charge_status_t *p_charge_status; plug_in_t *p_plug_in; p_plug_info = &cp_socket_context.meter_data.plug_info[plug_id]; p_event_status = &cp_socket_context.event_status[plug_id]; p_cfg_param = &cp_socket_context.cfg_param[plug_id]; p_last_fault_status = &cp_socket_context.last_fault_status[plug_id]; p_charge_status = &cp_socket_context.charge_status[plug_id]; p_plug_in = &cp_socket_context.plug_in[plug_id]; p_plug_info->plug_id = plug_id; p_plug_info->meter_data.charging_i = p_phase_data->slide_current_ma; p_plug_info->meter_data.power_rate = p_phase_data->slide_power_mw / 1000; p_plug_info->meter_data.pwr_factor = p_phase_data->factor_perc; p_event_status->plug_id = plug_id; p_event_status->meter_data.charging_i = p_phase_data->current_ma; p_event_status->meter_data.power_rate = p_phase_data->power_mw / 1000; p_event_status->meter_data.pwr_factor = p_phase_data->factor_perc; /* if relay on, then start updating the energy vaule. */ if (p_plug_info->relay_state == true) { cp_socket_context.meter_data.pwr_consum_mws[plug_id] += p_phase_data->energy_inc_mws; p_plug_info->meter_data.pwr_consum = (uint32_t)(CP_SOCKET_UNIT_WMS_TO_KWH( cp_socket_context.meter_data.pwr_consum_mws[plug_id])); p_event_status->meter_data.pwr_consum = p_plug_info->meter_data.pwr_consum; } #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]plug_id=%d,charging_i_ma=%d,slide_charging_i_ma=%d," "power_rate_mw=%d,slide_power_rate_mw=%d,pwr_factor=%d,energy_inc_mws=%d," "pwr_consum_0_01kwh=%d,relay_state=%d.\n", plug_id, p_phase_data->current_ma, p_phase_data->slide_current_ma, p_phase_data->power_mw, p_phase_data->slide_power_mw, p_phase_data->factor_perc, p_phase_data->energy_inc_mws, p_plug_info->meter_data.pwr_consum, p_plug_info->relay_state); #endif /* if overload or overcurrent en, then check current is over or not. */ if (p_cfg_param->alarm.alarm_en_overload == true || p_cfg_param->alarm.alarm_en_overcur == true) { /* current is overload */ if (p_event_status->meter_data.charging_i > p_cfg_param->overload_i_th * 100) { p_event_status->fault_src.overcur = true; p_event_status->fault_src.overload = true; } else if (p_event_status->meter_data.charging_i + CP_SOCKET_OVERCURRENT_RECOVERY_TH < p_cfg_param->overload_i_th * 100) { p_event_status->fault_src.overcur = false; p_event_status->fault_src.overload = false; } /* when event changed, send event id and specific information. */ if (p_last_fault_status->overcur != p_event_status->fault_src.overcur) { /* update last fault status. */ p_last_fault_status->overcur = p_event_status->fault_src.overcur; /* fill information. */ p_event_status->event_id = CP_SOCKET_EVENT_ID_ABNORM_CURR; p_plug_info->fault_status.overcur = p_event_status->fault_src.overcur; p_plug_info->fault_status.overload = p_event_status->fault_src.overload; // send event to other task. cp_socket_event_report_to_cp_task(plug_id); } } /* when current is normal,we begin to process charge current. */ if (false == p_event_status->fault_src.overcur && p_plug_info->relay_state == true) { if (p_charge_status->delay_count_after_charged++ >= CP_SOCKET_DELAY_COUNT_AFTER_CHARGED) { p_charge_status->delay_count_after_charged = CP_SOCKET_DELAY_COUNT_AFTER_CHARGED; if (p_event_status->meter_data.charging_i > p_cfg_param->charge_full_i_th + CP_SOCKET_CHARGE_RECOVERY_TH) { p_charge_status->current_count.charging_count++; p_charge_status->current_count.charge_full_count = 0; p_charge_status->current_count.plugout_count = 0; if (p_charge_status->current_count.charging_count > CP_SOCKET_CHARGING_COUNT) { p_charge_status->current_count.charging_count = CP_SOCKET_CHARGING_COUNT; } } else if (p_event_status->meter_data.charging_i < p_cfg_param->discon_cur_th) { p_charge_status->current_count.plugout_count++; p_charge_status->current_count.charging_count = 0; p_charge_status->current_count.charge_full_count = 0; if (p_charge_status->current_count.plugout_count > CP_SOCKET_PLUGOUT_COUNT) { p_charge_status->current_count.plugout_count = CP_SOCKET_PLUGOUT_COUNT; } } else { p_charge_status->current_count.charge_full_count++; p_charge_status->current_count.charging_count = 0; p_charge_status->current_count.plugout_count = 0; if (p_charge_status->current_count.charge_full_count > CP_SOCKET_CHARGE_FULL_COUNT) { p_charge_status->current_count.charge_full_count = CP_SOCKET_CHARGE_FULL_COUNT; } } if (p_charge_status->current_count.charging_count == CP_SOCKET_CHARGING_COUNT) { /* current is charging */ p_charge_status->is_charge_current = true; } else if (p_charge_status->current_count.plugout_count == CP_SOCKET_PLUGOUT_COUNT) { /* plugout when charging. */ p_event_status->is_plug_in = false; /* charging status should be set to uncharged. */ p_charge_status->is_charge_current = false; } else if (p_charge_status->current_count.charge_full_count == CP_SOCKET_CHARGE_FULL_COUNT) { /* current is charging full */ p_charge_status->is_charge_current = false; } } /* when event changed, send event id and specific information. */ if (p_plug_in->is_plug_in != p_event_status->is_plug_in) { p_plug_in->is_plug_in = p_event_status->is_plug_in; p_event_status->event_id = CP_SOCKET_EVENT_ID_PLUG_IO; p_plug_info->is_plug_in = p_event_status->is_plug_in; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]plug_id=[%d],plugout:current_low %dmA.\n", plug_id, p_event_status->meter_data.charging_i); #endif // send event to other task. cp_socket_event_report_to_cp_task(plug_id); } else if (p_charge_status->is_charge_previous != p_charge_status->is_charge_current) { /* update last charge status. */ p_charge_status->is_charge_previous = p_charge_status->is_charge_current; if (true == p_charge_status->is_charge_current) { p_event_status->event_id = CP_SOCKET_EVENT_ID_CHARG_START_CFM; } else if (false == p_charge_status->is_charge_current) { p_event_status->event_id = CP_SOCKET_EVENT_ID_CHARG_STOP_CFM; } #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]plug_id=[%d],status:%s,current:%dmA.\n", plug_id, p_event_status->event_id == CP_SOCKET_EVENT_ID_CHARG_START_CFM ? "start charge" : "stop charge", p_event_status->meter_data.charging_i); #endif /* send event to other task. */ cp_socket_event_report_to_cp_task(plug_id); } } } /* when receive switch voltage phase, then we can get voltage... we can save data info to golbal variable by plud_id, check plugin or plugout. */ static void cp_socket_check_is_plugin_process(uint8_t plug_id, iot_em_phase_data_std_t *p_phase_data) { cp_socket_plug_info_t *p_plug_info; cp_socket_cmd_event_status_t *p_event_status; plug_in_t *p_plug_in; p_plug_info = &cp_socket_context.meter_data.plug_info[plug_id]; p_event_status = &cp_socket_context.event_status[plug_id]; p_plug_in = &cp_socket_context.plug_in[plug_id]; p_plug_info->plug_id = plug_id; p_plug_info->incumbent_v = p_phase_data->slide_voltage_mv / 100; p_event_status->plug_id = plug_id; p_event_status->incumbent_v = p_phase_data->voltage_mv / 100; if (p_plug_info->relay_state == 0) { /* when the detected voltage is above plugin_voltage, it's inserted */ /* misjudgement prevention */ if (p_event_status->incumbent_v > CP_SOCKET_PLUGIN_VOLTAGE) { p_plug_in->filter |= 0x01; /* the last bit set 1 */ } else if (p_event_status->incumbent_v < CP_SOCKET_PLUGOUT_VOLTAGE) { p_plug_in->filter &= 0xFE; /* the last bit set 0 */ } /* use last two bits to judge. */ if (0x03 == (p_plug_in->filter & 0x03)) { /* last two bits are 1 */ p_event_status->is_plug_in = true; } else if (0xFC == (p_plug_in->filter | 0xFC)) { /* last two bits are 0 */ p_event_status->is_plug_in = false; } if ((p_event_status->incumbent_v > CP_SOCKET_PLUGIN_VOLTAGE) || (p_event_status->incumbent_v < CP_SOCKET_PLUGOUT_VOLTAGE)) { p_plug_in->filter <<= 1; } /* when event changed, send event id and specific information. */ if (p_plug_in->is_plug_in != p_event_status->is_plug_in) { p_plug_in->is_plug_in = p_event_status->is_plug_in; p_event_status->event_id = CP_SOCKET_EVENT_ID_PLUG_IO; p_plug_info->is_plug_in = p_event_status->is_plug_in; // send event to other task. cp_socket_event_report_to_cp_task(plug_id); } } #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]plug_id=%d,plugin_voltage_mv=%d," "plugin_slide_voltage_mv=%d,is_plug_in=%d.\n", plug_id, p_phase_data->voltage_mv, p_phase_data->slide_voltage_mv, p_plug_info->is_plug_in); #endif } /* get socket 0 date:current, power, apparent power, energy, factor. */ static void cp_socket_get_meter_data_0_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_meter_data_process(CP_SOCKET_ID_0, p_phase_data); } /* get socket 1 date:current, power, apparent power, energy, factor. */ static void cp_socket_get_meter_data_1_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_meter_data_process(CP_SOCKET_ID_1, p_phase_data); } /* get socket 2 date:current, power, apparent power, energy, factor. */ static void cp_socket_get_meter_data_2_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_meter_data_process(CP_SOCKET_ID_2, p_phase_data); } /* get socket 3 date:current, power, apparent power, energy, factor. */ static void cp_socket_get_meter_data_3_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_meter_data_process(CP_SOCKET_ID_3, p_phase_data); } /* by voltage, check plug is in or out. */ static void cp_socket_check_is_plugin_3_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_check_is_plugin_process(CP_SOCKET_ID_3, p_phase_data); } /* by voltage, check plug is in or out. */ static void cp_socket_check_is_plugin_2_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_check_is_plugin_process(CP_SOCKET_ID_2, p_phase_data); } /* by voltage, check plug is in or out. */ static void cp_socket_check_is_plugin_1_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_check_is_plugin_process(CP_SOCKET_ID_1, p_phase_data); } /* by voltage, check plug is in or out. */ static void cp_socket_check_is_plugin_0_cb(iot_em_phase_data_std_t *p_phase_data) { cp_socket_check_is_plugin_process(CP_SOCKET_ID_0, p_phase_data); } /* get socket data: voltage, frequnce. check voltage is under-voltage or over-voltage. */ static void cp_socket_get_meter_data_common_cb( iot_em_phase_data_std_t *p_phase_data) { meter_data_info_t *p_meter_data; cp_socket_cmd_event_status_t *p_event_status; cp_socket_cmd_cfg_param_t *p_cfg_param; cp_socket_fault_t *p_last_fault_status; cp_socket_volt_judge_count_t *p_volt_judge; uint8_t plug_id = CP_SOCKET_ID_3; bool_t rpt_vol_abnormal = false; /* temporary use CP_SOCKET_ID_3 as plug_id. */ p_meter_data = &cp_socket_context.meter_data; p_event_status = &cp_socket_context.event_status[plug_id]; p_cfg_param = &cp_socket_context.cfg_param[plug_id]; p_last_fault_status = &cp_socket_context.last_fault_status[plug_id]; p_volt_judge = &cp_socket_context.volt_judge; p_meter_data->freq = p_phase_data->signal_freq_perc; p_meter_data->volt = p_phase_data->slide_voltage_mv / 100; p_event_status->volt = p_phase_data->voltage_mv / 100; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]voltage_mv=%d,slide_voltage_mv=%d\n", p_phase_data->voltage_mv, p_phase_data->slide_voltage_mv); #endif if (p_event_status->volt > p_cfg_param->rated_volt * 10 + CP_SOCKET_RATED_VOLTAGE_ABNORMAL_TH) { p_volt_judge->high_count++; p_volt_judge->low_count = 0; p_volt_judge->normal_count = 0; if (p_volt_judge->high_count >= CP_SOCKET_VOLT_HIGH_COUNT) { p_volt_judge->high_count = CP_SOCKET_VOLT_HIGH_COUNT; p_event_status->fault_src.overvolt = true; p_event_status->fault_src.undervolt = false; } } else if (p_event_status->volt + CP_SOCKET_RATED_VOLTAGE_ABNORMAL_TH < p_cfg_param->rated_volt * 10) { p_volt_judge->low_count++; p_volt_judge->high_count = 0; p_volt_judge->normal_count = 0; if (p_volt_judge->low_count >= CP_SOCKET_VOLT_LOW_COUNT) { p_volt_judge->low_count = CP_SOCKET_VOLT_LOW_COUNT; p_event_status->fault_src.overvolt = false; p_event_status->fault_src.undervolt = true; } } else if (p_event_status->volt < CP_SOCKET_RATED_VOLTAGE_RECOVERY_TH + p_cfg_param->rated_volt * 10 && p_event_status->volt + CP_SOCKET_RATED_VOLTAGE_RECOVERY_TH > p_cfg_param->rated_volt * 10) { p_volt_judge->normal_count++; p_volt_judge->high_count = 0; p_volt_judge->low_count = 0; if (p_volt_judge->normal_count >= CP_SOCKET_VOLT_NORMAL_COUNT) { p_volt_judge->normal_count = CP_SOCKET_VOLT_NORMAL_COUNT; p_event_status->fault_src.overvolt = false; p_event_status->fault_src.undervolt = false; } } /* over voltage check enable and over voltage state changed */ if (p_cfg_param->alarm.alarm_en_overvolt == true && p_last_fault_status->overvolt != p_event_status->fault_src.overvolt) { /* update last fault status. */ p_last_fault_status->overvolt = p_event_status->fault_src.overvolt; rpt_vol_abnormal = true; } /* under voltage check enable and under voltage state changed */ if (p_cfg_param->alarm.alarm_en_undervolt == true && p_last_fault_status->undervolt != p_event_status->fault_src.undervolt) { /* update last fault status. */ p_last_fault_status->undervolt = p_event_status->fault_src.undervolt; rpt_vol_abnormal = true; } /* send event id and specific information */ if (rpt_vol_abnormal) { p_event_status->event_id = CP_SOCKET_EVENT_ID_ABNORM_VOLT; p_meter_data->plug_info[plug_id].fault_status.overvolt = p_event_status->fault_src.overvolt; p_meter_data->plug_info[plug_id].fault_status.undervolt = p_event_status->fault_src.undervolt; // send event to other task. cp_socket_event_report_to_cp_task(plug_id); } } static void cp_socket_get_socket_leak_current_cb( iot_em_phase_data_std_t *p_phase_data) { meter_data_info_t *p_meter_data; cp_socket_cmd_event_status_t *p_event_status; cp_socket_cmd_cfg_param_t *p_cfg_param; cp_socket_fault_t *p_last_fault_status; uint8_t plug_id = CP_SOCKET_ID_3; //CP_SOCKET_ID_3 todo p_meter_data = &cp_socket_context.meter_data; p_event_status = &cp_socket_context.event_status[plug_id]; p_cfg_param = &cp_socket_context.cfg_param[plug_id]; p_last_fault_status = &cp_socket_context.last_fault_status[plug_id]; p_meter_data->leak_i = p_phase_data->slide_current_ma; p_event_status->plug_id = plug_id; p_event_status->leak_i = p_phase_data->current_ma; #if CP_SOCKET_DEBUG iot_cus_printf("[cp_socket]lead_current_ma=%d,slide_leak_current_ma=%d\n", p_phase_data->current_ma, p_phase_data->slide_current_ma); #endif /* if lead current check en, then check it. */ if (p_cfg_param->alarm.alarm_en_leak_cur == true) { if (p_event_status->leak_i > p_cfg_param->leak_i_th) { p_event_status->fault_src.leak_cur_protec = true; } else if (p_event_status->leak_i + CP_SOCKET_LEAK_PROTECT_RECOVERY_TH < p_cfg_param->leak_i_th) { p_event_status->fault_src.leak_cur_protec = false; } /* when event changed, send event id and specific information. */ if (p_last_fault_status->leak_cur_protec != p_event_status->fault_src.leak_cur_protec) { /* update last fault status. */ p_last_fault_status->leak_cur_protec = p_event_status->fault_src.leak_cur_protec; /* fill information. */ p_event_status->event_id = CP_SOCKET_EVENT_ID_LEAKAGE; p_meter_data->plug_info[plug_id].fault_status.leak_cur_protec = p_event_status->fault_src.leak_cur_protec; // send event to other task. cp_socket_event_report_to_cp_task(plug_id); } } } /* Phase corresponding callback function. register by iot_em_phase_get_data_cb_register_std() */ static const std_get_phase_id_cb_t std_get_phase_id_cb[] = { {EM_ADC0_DMA_PHASE_0, cp_socket_get_meter_data_0_cb}, {EM_ADC0_DMA_PHASE_1, cp_socket_get_meter_data_1_cb}, {EM_ADC0_DMA_PHASE_2, cp_socket_get_meter_data_2_cb}, {EM_ADC1_DMA_PHASE_0, cp_socket_get_meter_data_3_cb}, {EM_ADC0_DMA_PHASE_3_3, cp_socket_check_is_plugin_0_cb}, {EM_ADC0_DMA_PHASE_3_2, cp_socket_check_is_plugin_1_cb}, {EM_ADC0_DMA_PHASE_3_1, cp_socket_check_is_plugin_2_cb}, {EM_ADC0_DMA_PHASE_3_0, cp_socket_check_is_plugin_3_cb}, {EM_ADC1_DMA_PHASE_1, cp_socket_get_meter_data_common_cb}, {EM_ADC1_DMA_PHASE_2, cp_socket_get_socket_leak_current_cb}, }; /* init cp socket energe meter. */ static void cp_socket_energe_meter_init(void) { uint8_t i; iot_em_module_open((iot_em_cust_info_t *)&g_em_cps_info); for (i = 0; i < sizeof(std_get_phase_id_cb) / sizeof(std_get_phase_id_cb[i]); i++) { iot_em_phase_get_data_cb_register_std(std_get_phase_id_cb[i].phase_id, std_get_phase_id_cb[i].cb); } } uint32_t cp_socket_task_init(void) { uint32_t ret = ERR_OK; iot_task_config_t task_cfg; /* Task configration. */ os_mem_set(&task_cfg, 0x0, sizeof(task_cfg)); task_cfg.stack_size = CP_SOCKET_TASK_STACK_SIZE; task_cfg.task_prio = CP_SOCKET_TASK_PRIO; task_cfg.msg_size = sizeof(cp_socket_task_msg_t); task_cfg.msg_cnt = CP_SOCKET_TASK_MSG_CNT; task_cfg.queue_cnt = 1; task_cfg.queue_cfg[0].quota = 0; task_cfg.task_event_func = NULL; task_cfg.msg_exe_func = cp_socket_msg_exe_func; task_cfg.msg_cancel_func = cp_socket_msg_cancel_func; task_cfg.core_id = 0; os_mem_set(&cp_socket_context, 0x0, sizeof(cp_socket_context)); /* Create task. */ cp_socket_context.task_h = iot_task_create(CP_SOCKET_MID, &task_cfg); if (NULL == cp_socket_context.task_h) { iot_cus_printf("[cp_socket][err] %s create task failed.\n", __FUNCTION__); ret = ERR_FAIL; goto init_err_handle; } cp_socket_context.data_event_tmr = os_create_timer(CP_SOCKET_MID, true, cp_socket_data_event_tmr_cb, NULL); if (0 == cp_socket_context.data_event_tmr) { iot_cus_printf("[cp_socket][err] %s create indicate data event timer " "failed.\n", __FUNCTION__); ret = ERR_FAIL; goto init_err_handle; } cp_socket_context.command.table.handle = (cp_socket_cmd_handle_t *)cmd_handle_table; iot_cus_printf("[cp_socket] %s cp_socket module version:%s, initailized " "successfully!\n", __FUNCTION__, CP_SOCKET_MODULE_VERSION); goto out; init_err_handle: cp_socket_task_deinit(); out: return ret; } void cp_socket_task_deinit(void) { iot_cus_printf("[cp_socket] %s cp_socket module deinit!\n", __FUNCTION__); if (NULL != cp_socket_context.task_h) { iot_task_delete(cp_socket_context.task_h); cp_socket_context.task_h = NULL; } if (0 != cp_socket_context.data_event_tmr) { os_delete_timer(cp_socket_context.data_event_tmr); cp_socket_context.data_event_tmr = 0; } os_mem_set(&cp_socket_context, 0x0, sizeof(cp_socket_context)); }