emeter-communication.c
来自「msp430F437三相电表DEMO(编译器 IAR 3.42A)」· C语言 代码 · 共 896 行 · 第 1/3 页
C
896 行
}
void process_rx_message(serial_msg_t *rx_msg, int rx_len)
{
int i;
int32_t z;
int32_t z1;
#if !defined(SINGLE_PHASE)
struct phase_parms_s *phase;
#endif
uint16_t *last_flash_loc;
/* Messages with type 0x23 are custom messages we
use for calibration, password protection, etc.
All other message types go to a custom message
handler (if available). */
if (rx_msg->uint8[8] != 0x23)
{
#if CUSTOM_SERIAL_MESSAGE_SUPPORT
custom_serial_message_handler(&rx_msg, rx_msg_len);
#endif
return;
}
if ((rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] & 0x80))
{
/* This looks like one of our own messages, which has echoed back
to us */
return;
}
/* Only process messages if the password has been given correctly
(except for the password test message, of course). */
if (!(meter_status & PASSWORD_OK) && rx_msg->uint8[IEC1107_MSG_RX_START_BODY] != 0x60)
return;
switch (rx_msg->uint8[IEC1107_MSG_RX_START_BODY])
{
case HOST_CMD_GET_METER_CONFIGURATION:
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 2] = NUM_PHASES;
#if defined(NEUTRAL_MONITOR_SUPPORT)
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 3] = 1;
#else
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 3] = 0;
#endif
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 4] = 0
#if defined(LIMP_MODE_SUPPORT)
| 0x01
#endif
#if defined(PHASE_CORRECTION_SUPPORT)
| 0x02
#endif
#if defined(DYNAMIC_PHASE_CORRECTION_SUPPORT)
| 0x04
#endif
#if defined(RTC_SUPPORT)
| 0x08
#endif
#if defined(CORRECTED_RTC_SUPPORT)
| 0x10
#endif
#if defined(TEMPERATURE_SUPPORT)
| 0x20
#endif
#if SELF_TEST_SUPPORT
| 0x40
#endif
#if MULTI_RATE_SUPPORT
| 0x80
#endif
;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 5] = 0x01
#if REACTIVE_POWER_SUPPORT
| 0x02
#endif
#if defined(VA_POWER_SUPPORT)
| 0x04
#endif
#if defined(VRMS_SUPPORT)
| 0x08
#endif
#if defined(IRMS_SUPPORT)
| 0x10
#endif
#if defined(POWER_FACTOR_SUPPORT)
| 0x20
#endif
#if defined(MAINS_FREQUENCY_SUPPORT)
| 0x40
#endif
;
prepare_tx_message(6);
break;
case HOST_CMD_SET_METER_CONSUMPTION:
z = rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 1];
z |= (int32_t) rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 2] << 16;
z1 = rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 3];
z1 |= (int32_t) rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 4] << 16;
custom_set_consumption(z, z1);
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
prepare_tx_message(2);
case HOST_CMD_SET_RTC:
#if defined(RTC_SUPPORT)
rtc.year = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 2];
rtc.month = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 3];
rtc.day = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 4];
rtc.hour = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 5];
rtc.minute = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 6];
rtc.second = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 7];
set_rtc_sumcheck();
#endif
#if defined(CUSTOM_RTC_SUPPORT)
custom_rtc_set(rx_msg->uint8);
#endif
#if defined(MULTI_RATE_SUPPORT)
multirate_align_with_rtc();
#endif
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
prepare_tx_message(2);
break;
case HOST_CMD_GET_RTC:
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
#if defined(RTC_SUPPORT)
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 2] = rtc.year;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 3] = rtc.month;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 4] = rtc.day;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 5] = rtc.hour;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 6] = rtc.minute;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 7] = rtc.second;
#endif
#if defined(CUSTOM_RTC_SUPPORT)
custom_rtc_retrieve(tx_msg.uint8);
#endif
#if defined(TEMPERATURE_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 4] = temperature;
#endif
prepare_tx_message(10);
break;
case HOST_CMD_SET_PASSWORD:
/* Check the calibration password */
if (rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 1] == SERIAL_CALIBRATION_PASSWORD_1
&&
rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 2] == SERIAL_CALIBRATION_PASSWORD_2
&&
rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 3] == SERIAL_CALIBRATION_PASSWORD_3
&&
rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 4] == SERIAL_CALIBRATION_PASSWORD_4)
{
meter_status |= PASSWORD_OK;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
prepare_tx_message(2);
}
else
{
/* Only respond to a bad password, if the password was good before. That lets
us know we have unset the password OK, but doesn't give any information to
people trying to attack the meter. */
if ((meter_status & PASSWORD_OK))
{
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
prepare_tx_message(2);
}
meter_status &= ~PASSWORD_OK;
}
break;
case HOST_CMD_GET_READINGS_PHASE_1:
#if !defined(SINGLE_PHASE)
case HOST_CMD_GET_READINGS_PHASE_2:
case HOST_CMD_GET_READINGS_PHASE_3:
/* Exchange voltage, current and power readings (neutral).
frequency, power factor and reactive power readings. */
phase = &chan[rx_msg->uint8[IEC1107_MSG_RX_START_BODY] - 0x61];
#endif
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
#if defined(VRMS_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 1] = phase->V_rms;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 1] = 0;
#endif
#if defined(IRMS_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 2] = phase->current.I_rms;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 2] = 0;
#endif
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 3] = phase->current.power;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 4] = phase->current.power >> 16;
#if defined(REACTIVE_POWER_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 5] = phase->reactive_power;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 6] = phase->reactive_power >> 16;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 5] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 6] = 0;
#endif
#if defined(VA_POWER_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 7] = phase->VA_power;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 8] = phase->VA_power >> 16;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 7] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 8] = 0;
#endif
#if defined(POWER_FACTOR_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 9] = phase->power_factor;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 9] = 0;
#endif
#if defined(MAINS_FREQUENCY_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 10] = phase->frequency;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 10] = 0;
#endif
#if defined(LIMP_MODE_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 11] = phase->V_dc_estimate[0];
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 12] = phase->V_dc_estimate[0] >> 16;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 11] = phase->V_dc_estimate;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 12] = phase->V_dc_estimate >> 16;
#endif
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 13] = phase->current.I_dc_estimate[0];
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 14] = phase->current.I_dc_estimate[0] >> 16;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 30] = 0;
prepare_tx_message(31);
break;
#if defined(NEUTRAL_MONITOR_SUPPORT)
case HOST_CMD_GET_READINGS_NEUTRAL:
/* Exchange voltage, current and power readings (neutral).
frequency, power factor and reactive power readings. */
tx_msg.uint8[IEC1107_MSG_TX_START_BODY] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY];
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 1] = rx_msg->uint8[IEC1107_MSG_RX_START_BODY + 1] | 0x80;
#if defined(SINGLE_PHASE)
#if defined(VRMS_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 1] = phase->V_rms;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 1] = 0;
#endif
#if defined(IRMS_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 2] = phase->neutral.I_rms;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 2] = 0;
#endif
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 3] = phase->neutral.power;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 4] = phase->neutral.power >> 16;
#if REACTIVE_POWER_SUPPORT
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 5] = phase->reactive_power;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 6] = phase->reactive_power >> 16;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 5] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 6] = 0;
#endif
#if VA_POWER_SUPPORT
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 7] = phase->VA_power;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 8] = phase->VA_power >> 16;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 7] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 8] = 0;
#endif
#if defined(POWER_FACTOR_SUPPORT)
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 9] = phase->power_factor;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 9] = 0;
#endif
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 10] = phase->frequency;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 11] = phase->V_dc_estimate[1];
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 12] = phase->V_dc_estimate[1] >> 16;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 13] = phase->neutral.I_dc_estimate;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 14] = phase->neutral.I_dc_estimate >> 16;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 30] = 0;
#else
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 1] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 2] = neutral.I_rms;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 3] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 4] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 5] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 6] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 7] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 8] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 9] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 10] = phase->frequency;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 11] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 12] = 0;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 13] = phase->current.I_dc_estimate;
tx_msg.uint16[IEC1107_MSG_TX_START_BODY_W + 14] = phase->current.I_dc_estimate >> 16;
tx_msg.uint8[IEC1107_MSG_TX_START_BODY + 30] = 0;
#endif
prepare_tx_message(31);
break;
#endif
case HOST_CMD_ERASE_FLASH_SEGMENT:
/* Initialise flash data download, by erasing the area to be used, and setting the
write pointer. */
/* There is no checking here to ensure we do not erase inappropriate places. */
next_flash_loc = (uint16_t *) rx_msg->uint16[IEC1107_MSG_RX_START_BODY_W + 1];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?