#include "plt.h" int n9_comm_init(int idx) { struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; comm_set_state(comm, COMMST_ERR); } int n9_comm_reset(int idx) { struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; comm_set_state(comm, COMMST_NORMAL); comm_set_dac_param_en(comm, 1); } int n9_set_dev_aps(int idx, int aps) { int ret = 0; struct n9_t *dev = &n9[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0x0D57; int nb = 1; short val = aps * 10; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, aps:%d, fail", __func__, idx, aps); } else { log_dbg("%s, idx:%d, aps:%d, ret:%d", __func__, idx, dev->pow.aps, ret); } return ret; } int n9_set_dev_startcmd(int idx) { int ret = 0; struct n9_t *dev = &n9[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0x0291; int nb = 1; int trycnt = 0; int val = 1; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } int n9_set_dev_stopcmd(int idx) { int ret = 0; struct n9_t *dev = &n9[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0x0291; int nb = 1; int trycnt = 0; int val = 0; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } // send fault reset cmd to pcs // 0:invalid 1:reset int n9_set_dev_resetcmd(int idx) { int ret = 0; struct n9_t *dev = &n9[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0x1400; int nb = 1; int trycnt = 0; unsigned short val = 0; chan_lock(chanidx); ret = chan_read_holdingregisters_with_retry(chanidx, addr, regaddr, 1, &val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, read fail", __func__, idx); return ret; } val |= ((unsigned short)1 << 15); // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } /* 1:offgrid 0:ongrid **/ int n9_set_dev_runmod(int idx, int val) { int ret = 0; struct n9_t *dev = &n9[idx]; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int regaddr = 0x5066; // modbus tcp connection, no delay chan_lock(chanidx); ret = chan_write_single_register_with_retry(chanidx, addr, regaddr, val); chan_unlock(chanidx); if (ret < 0) { log_dbg("%s, idx:%d, fail", __func__, idx); } return ret; } static void n9_comm_dac_0x6020(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 14; start = 0x6020; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->Uab = *((signed short *)(&tab_us[0x6020 - start])) / 10.0; dev->Ubc = *((signed short *)(&tab_us[0x6021 - start])) / 10.0; dev->Uca = *((signed short *)(&tab_us[0x6022 - start])) / 10.0; dev->Ua = *((signed short *)(&tab_us[0x6023 - start])) / 10.0; dev->Ub = *((signed short *)(&tab_us[0x6024 - start])) / 10.0; dev->Uc = *((signed short *)(&tab_us[0x6025 - start])) / 10.0; dev->Ia = *((signed short *)(&tab_us[0x6026 - start])) / 10.0; dev->Ib = *((signed short *)(&tab_us[0x6027 - start])) / 10.0; dev->Ic = *((signed short *)(&tab_us[0x6028 - start])) / 10.0; dev->Ila = *((signed short *)(&tab_us[0x6029 - start])) / 10.0; dev->Ilb = *((signed short *)(&tab_us[0x602A - start])) / 10.0; dev->Ilc = *((signed short *)(&tab_us[0x602B - start])) / 10.0; dev->gridf = *((signed short *)(&tab_us[0x602C - start])) / 100.0; dev->phase = *((signed short *)(&tab_us[0x602D - start])); } } static void n9_comm_dac_0x6030(int idx) { unsigned short tab_us[256] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 13; start = 0x6030; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->Pa = *((signed short *)(&tab_us[0x6030 - start])) / 10.0; dev->Pb = *((signed short *)(&tab_us[0x6031 - start])) / 10.0; dev->Pc = *((signed short *)(&tab_us[0x6032 - start])) / 10.0; dev->Sa = *((signed short *)(&tab_us[0x6033 - start])) / 10.0; dev->Sb = *((signed short *)(&tab_us[0x6034 - start])) / 10.0; dev->Sc = *((signed short *)(&tab_us[0x6035 - start])) / 10.0; dev->Qa = *((signed short *)(&tab_us[0x6036 - start])) / 10.0; dev->Qb = *((signed short *)(&tab_us[0x6037 - start])) / 10.0; dev->Qc = *((signed short *)(&tab_us[0x6038 - start])) / 10.0; dev->ap = *((signed short *)(&tab_us[0x6039 - start])) / 10.0; dev->Ssum = *((signed short *)(&tab_us[0x603A - start])) / 10.0; dev->Qsum = *((signed short *)(&tab_us[0x603B - start])) / 10.0; dev->Pfactor = *((signed short *)(&tab_us[0x603C - start])) / 100.0; static double ap_old = 0.0; if (fabs(ap_old - dev->ap) > 1e-5) { ap_old = dev->ap; log_info("%s, dev ap now : (%.1f)", __func__, dev->ap); } } } static void n9_comm_dac_0x6050(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 12; start = 0x6050; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->dc_v = *((signed short *)(&tab_us[0x6050 - start])) / 10.0; dev->dc_v_pos = *((signed short *)(&tab_us[0x6051 - start])) / 10.0; dev->dc_v_neg = *((signed short *)(&tab_us[0x6052 - start])) / 10.0; dev->bat_v = *((signed short *)(&tab_us[0x6053 - start])) / 10.0; dev->bat_c = *((signed short *)(&tab_us[0x6054 - start])) / 10.0; dev->dc_ap = *((signed short *)(&tab_us[0x6055 - start])) / 10.0; dev->dc_c = *((signed short *)(&tab_us[0x6056 - start])) / 10.0; dev->workmode = tab_us[0x6057 - start]; if ((dev->workmode & (unsigned short)1 << 0)) { dev->runstate = N9_RUNSTAT_RUN; if ((dev->workmode & (unsigned short)1 << 3)) { dev->cv = 1; } else { dev->cv = 0; } if ((dev->workmode & (unsigned short)1 << 8)) { dev->cc = 1; } else { dev->cc = 0; } strcpy(dev->runstate_str, "run"); } else if (dev->workmode & (1 << 6)) { dev->runstate = N9_RUNSTAT_ERROR; strcpy(dev->runstate_str, "error, check faults"); } else { dev->runstate = N9_RUNSTAT_IDLE; strcpy(dev->runstate_str, "idle"); } dev->t_igbt = tab_us[0x6058 - start] / 10.0; dev->t_env = *((signed short *)(&tab_us[0x6059 - start])) / 10.0; dev->c_dhg_mode = tab_us[0x605B - start]; if (dev->c_dhg_mode == 0) { strcpy(dev->c_dhg_mode_str, "bat constant voltage"); } else if (dev->c_dhg_mode == 1) { strcpy(dev->c_dhg_mode_str, "ongrid constant current"); } else if (dev->c_dhg_mode == 2) { strcpy(dev->c_dhg_mode_str, "bat constant current"); } } } static void n9_comm_dac_0x0D57(int idx) { unsigned short tab_us[256] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 2; start = 0x0D57; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->Pset = *((signed short *)(&tab_us[0x0D57 - start])) / 10.0; } } // 0x0E14 fault state word static void n9_comm_dac_0x6000(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 6; start = 0x6000; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->dsp_ver[0] = tab_us[0x6000 - start]; dev->dsp_ver[1] = tab_us[0x6001 - start]; dev->dsp_ver[2] = tab_us[0x6002 - start]; dev->cpld_ver[0] = tab_us[0x6003 - start]; dev->cpld_ver[1] = tab_us[0x6004 - start]; dev->cpld_ver[2] = tab_us[0x6005 - start]; } } static void n9_comm_dac_0x6010(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; unsigned int temp = 0; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 16; start = 0x6010; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ temp = tab_us[0x6010 - start]; temp = (temp << 16) + tab_us[0x6011 - start]; dev->chg_power_total_dc = temp; temp = tab_us[0x6012 - start]; temp = (temp << 16) + tab_us[0x6013 - start]; dev->chg_power_day_sum_dc = temp; temp = tab_us[0x6014 - start]; temp = (temp << 16) + tab_us[0x6015 - start]; dev->dhg_power_total_dc = temp; temp = tab_us[0x6016 - start]; temp = (temp << 16) + tab_us[0x6017 - start]; dev->dhg_power_day_sum_dc = temp; temp = tab_us[0x6018 - start]; temp = (temp << 16) + tab_us[0x6019 - start]; dev->chg_power_total_ac = temp; temp = tab_us[0x601A - start]; temp = (temp << 16) + tab_us[0x601B - start]; dev->chg_power_day_sum_ac = temp; temp = tab_us[0x601C - start]; temp = (temp << 16) + tab_us[0x601D - start]; dev->dhg_power_total_ac = temp; temp = tab_us[0x601E - start]; temp = (temp << 16) + tab_us[0x601F - start]; dev->dhg_power_day_sum_ac = temp; // log_info("%s,buf[%d,%d],sum:%d",__func__,tab_us[0x601C - start],tab_us[0x601D - start],dev->dhg_power_sum_ac); } } static void n9_comm_dac_0x1700(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 8; start = 0x1700; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->faults[0] = tab_us[0x1700 - start]; dev->faults[1] = tab_us[0x1701 - start]; dev->faults[2] = tab_us[0x1702 - start]; dev->faults[3] = tab_us[0x1703 - start]; dev->faults[4] = tab_us[0x1704 - start]; dev->faults[5] = tab_us[0x1705 - start]; dev->faults[6] = tab_us[0x1706 - start]; dev->faults[7] = tab_us[0x1707 - start]; static unsigned short faults[8] = {0}; if (dev->faults[0] != faults[0]) { faults[0] = dev->faults[0]; log_dbg("faults[0]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[0])); } if (dev->faults[1] != faults[1]) { faults[1] = dev->faults[1]; log_dbg("faults[1]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[1])); } if (dev->faults[2] != faults[2]) { faults[2] = dev->faults[2]; log_dbg("faults[2]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[2])); } if (dev->faults[3] != faults[3]) { faults[3] = dev->faults[3]; log_dbg("faults[3]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[3])); } if (dev->faults[4] != faults[4]) { faults[4] = dev->faults[4]; log_dbg("faults[4]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[4])); } if (dev->faults[5] != faults[5]) { faults[5] = dev->faults[5]; log_dbg("faults[5]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[5])); } if (dev->faults[6] != faults[6]) { faults[6] = dev->faults[6]; log_dbg("faults[6]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[6])); } if (dev->faults[7] != faults[7]) { faults[7] = dev->faults[7]; log_dbg("faults[7]: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(dev->faults[7])); } } } static void n9_comm_dac_0x1600(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 4; start = 0x1600; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->AC_ovp = tab_us[0x1600 - start] / 10.0; dev->AC_uvp = tab_us[0x1601 - start] / 10.0; dev->AC_ocp = tab_us[0x1603 - start] / 10.0; } } static void n9_comm_dac_0x1611(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 2; start = 0x1611; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->Ubus_ovp = tab_us[0x1611 - start] / 10.0; dev->Ubus_uvp = tab_us[0x1612 - start] / 10.0; } } static void n9_comm_dac_0x1620(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 1; start = 0x1620; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->module_otp = tab_us[0x1620 - start] / 10.0; } } static void n9_comm_dac_0x1640(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 1; start = 0x1640; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->Ubus_ocp = tab_us[0x1640 - start] / 10.0; } } static void n9_comm_dac_0x1633(int idx) { unsigned short tab_us[128] = {0}; struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; int chanidx = dev->comm.chanidx; int addr = dev->comm.adr; int start, nb, rc; if (comm_get_state(comm) != COMMST_NORMAL) { return; } nb = 2; start = 0x1633; chan_lock(chanidx); rc = chan_read_holdingregisters_with_retry(chanidx, addr, start, nb, tab_us); if (rc < 0) { comm_set_state(comm, COMMST_ERR); } chan_unlock(chanidx); if (rc == 0) { /* read ok */ dev->bat_ovp = tab_us[0x1633 - start] / 10.0; dev->bat_uvp = tab_us[0x1634 - start] / 10.0; } } void n9_comm_dac(int idx) { struct n9_t *dev = &n9[idx]; struct comm_t *comm = &dev->comm; unsigned short tab_us[128] = {0}; int start, nb; int chan_idx = dev->comm.chanidx; int addr = dev->comm.adr; int ret = 0; static int cnt = 0; if (comm_get_state(comm) != COMMST_NORMAL) { return; } comm_start_cal_dac_timing(comm); if (sm_get_state(&dev->sm) == SMST_READY && sm_get_step(&dev->sm) == 0) { log_dbg("%s, idx:%d, about to enter ready state, stop dac", __func__, idx); return; } if (comm_get_dac_param_en(comm) == 1) { comm_set_dac_param_en(comm, 0); n9_comm_dac_0x1600(idx); n9_comm_dac_0x1611(idx); n9_comm_dac_0x1620(idx); n9_comm_dac_0x1633(idx); n9_comm_dac_0x1640(idx); n9_comm_dac_0x6000(idx); // read protect params } if (++cnt > 10) { n9_comm_dac_0x6010(idx); cnt = 0; } n9_comm_dac_0x6020(idx); n9_comm_dac_0x6030(idx); n9_comm_dac_0x6050(idx); // n9_comm_dac_0x6000(idx); // n9_comm_dac_0x6010(idx); n9_comm_dac_0x1700(idx); // n9_comm_dac_0x0D57(idx); comm_stop_cal_dac_timing(comm); }