emeter-multirate.c
来自「msp430F437三相电表DEMO(编译器 IAR 3.42A)」· C语言 代码 · 共 655 行 · 第 1/2 页
C
655 行
iicEEPROM_read(EEPROM_START_HISTORIES_A + pos, (void *) &history[0], sizeof(history[0]));
iicEEPROM_read(EEPROM_START_HISTORIES_B + pos, (void *) &history[1], sizeof(history[1]));
iicEEPROM_read(EEPROM_START_HISTORIES_C + pos, (void *) &history[2], sizeof(history[2]));
/* Check the sumcheck of each copy */
for (i = 0; i < 3; i++)
ok[i] = test_sumcheck(&history[i], sizeof(history[0]));
if (ok[0] && ok[1])
{
if (memcmp(&history[0], &history[1], sizeof(history[0])) == 0)
{
/* Use the first copy */
memcpy(¤t_history, &history[0], sizeof(current_history));
return 0;
}
}
if (ok[1] && ok[2])
{
if (memcmp(&history[1], &history[2], sizeof(history[1])) == 0)
{
/* Use the second copy */
memcpy(¤t_history, &history[1], sizeof(current_history));
return 0;
}
}
if (ok[0] && ok[2])
{
if (memcmp(&history[0], &history[2], sizeof(history[0])) == 0)
{
/* Use the first copy */
memcpy(¤t_history, &history[0], sizeof(current_history));
return 0;
}
}
/* We don't have two matching copies, so we need to look for something
who's sumcheck looks OK. */
for (i = 0; i < 3; i++)
{
if (ok[i])
{
/* At least this one doesn't look corrupt. Use it. */
memcpy(¤t_history, &history[i], sizeof(current_history));
return 0;
}
}
/* Very bad - we can't find anything which looks reasonable */
/* I guess we have to use something, so use the first copy. There is some
hope the error is something not too serious. */
memcpy(¤t_history, &history[0], sizeof(current_history));
return -1;
}
int write_history_slot(int slot, int tariff)
{
int res;
int pos;
if (current_tariff >= MULTIRATE_DAY_SCHEDULES)
return -1;
/* Write all three copies in the EEPROM, setting the sumcheck before writing. */
add_sumcheck(¤t_history, sizeof(current_history));
pos = (slot*MULTIRATE_DAY_SCHEDULES + tariff)*sizeof(eeprom_history_t);
res = iicEEPROM_write(EEPROM_START_HISTORIES_A + pos, (void *) ¤t_history, sizeof(current_history));
res |= iicEEPROM_write(EEPROM_START_HISTORIES_B + pos, (void *) ¤t_history, sizeof(current_history));
res |= iicEEPROM_write(EEPROM_START_HISTORIES_C + pos, (void *) ¤t_history, sizeof(current_history));
current_history_dirty = FALSE;
return res;
}
void tariff_management(void)
{
if ((tariff_flags & TARIFF_NEW_DAY))
{
new_tariff_day();
tariff_flags &= ~TARIFF_NEW_DAY;
}
if ((tariff_flags & TARIFF_NEW_MINUTE))
{
new_tariff_minute();
tariff_flags &= ~TARIFF_NEW_MINUTE;
}
}
void tariff_initialise(void)
{
int i;
/* Initial tariff information after starting from reset */
if ((i = find_next_cutoff_date()) < 0)
i = find_previous_cutoff_date();
current_history_slot = i;
new_tariff_day();
new_tariff_minute();
}
void multirate_align_with_rtc(void)
{
int i;
/* The RTC has just been changed, so we need to align the multi-rate actiivities
with the new time and date. */
/* We may have hopped between cutoff dates. We need a full re-alignment with
the new date. */
if ((i = find_next_cutoff_date()) < 0)
i = find_previous_cutoff_date();
current_history_slot = i;
/* Treat this like any new day, to pull the rest of the information into line. */
new_tariff_day();
new_tariff_minute();
}
int multirate_put(uint8_t *msg)
{
switch (msg[1])
{
case 0x00:
{
eeprom_day_schedule_timeslot_t tariff;
if (msg[2] >= MULTIRATE_DAY_SCHEDULES || msg[3] >= MULTIRATE_DAY_SCHEDULE_TIMESLOTS)
break;
tariff.start_hour = msg[4];
tariff.start_minute = msg[5];
tariff.tariff = msg[6];
return iicEEPROM_write(EEPROM_START_DAY_SCHEDULES + (msg[2]*MULTIRATE_DAY_SCHEDULE_TIMESLOTS + msg[3])*sizeof(eeprom_day_schedule_timeslot_t), (void *) &tariff, sizeof(tariff));
}
case 0x01:
{
eeprom_holiday_t holiday;
if (msg[2] >= MULTIRATE_MAX_HOLIDAYS)
break;
holiday.year = msg[4];
holiday.month = msg[5];
holiday.day = msg[6];
holiday.day_type = msg[7];
holiday.spare = 0;
return iicEEPROM_write(EEPROM_START_HOLIDAYS + msg[2]*sizeof(eeprom_holiday_t), (void *) &holiday, sizeof(holiday));
}
case 0x02:
{
uint8_t weekdays[4];
weekdays[0] = msg[2] | (msg[3] << 4);
weekdays[1] = msg[4] | (msg[5] << 4);
weekdays[2] = msg[6] | (msg[7] << 4);
weekdays[3] = msg[8] | (msg[9] << 4);
return iicEEPROM_write(EEPROM_START_WEEKDAYS, (void *) weekdays, 4);
}
case 0x03:
{
eeprom_cutoff_date_t cutoff_date;
if (msg[2] >= MULTIRATE_MAX_CUTOFF_DATES)
break;
cutoff_date.year = msg[4];
cutoff_date.month = msg[5];
cutoff_date.day = msg[6];
cutoff_date.spare = 0;
return iicEEPROM_write(EEPROM_START_CUTOFF_DATES + msg[2]*sizeof(eeprom_cutoff_date_t), (void *) &cutoff_date, sizeof(cutoff_date));
}
}
return 0;
}
int multirate_get(uint8_t *msg, uint8_t *txmsg)
{
txmsg[0] = 0xC1;
txmsg[1] = 0x80;
txmsg[2] = msg[2];
txmsg[3] = msg[3];
switch (msg[1])
{
case 0x00:
{
eeprom_day_schedule_timeslot_t tariff;
if (msg[2] >= MULTIRATE_DAY_SCHEDULES || msg[3] >= MULTIRATE_DAY_SCHEDULE_TIMESLOTS)
break;
if (iicEEPROM_read(EEPROM_START_DAY_SCHEDULES + (msg[2]*MULTIRATE_DAY_SCHEDULE_TIMESLOTS + msg[3])*sizeof(eeprom_day_schedule_timeslot_t), (void *) &tariff, sizeof(tariff)))
{
txmsg[4] = tariff.start_hour;
txmsg[5] = tariff.start_minute;
txmsg[6] = tariff.tariff;
txmsg[7] = 0;
return 8;
}
}
break;
case 0x01:
{
eeprom_holiday_t holiday;
if (msg[2] >= MULTIRATE_MAX_HOLIDAYS)
break;
if (iicEEPROM_read(EEPROM_START_HOLIDAYS + msg[2]*sizeof(eeprom_holiday_t), (void *) &holiday, sizeof(holiday)))
{
txmsg[4] = holiday.year;
txmsg[5] = holiday.month;
txmsg[6] = holiday.day;
txmsg[7] = holiday.day_type;
return 8;
}
}
break;
case 0x02:
{
uint8_t weekdays[4];
if (iicEEPROM_read(EEPROM_START_WEEKDAYS, (void *) weekdays, 4))
{
txmsg[2] = weekdays[0] & 0x0F;
txmsg[3] = (weekdays[0] >> 4) & 0x0F;
txmsg[4] = weekdays[1] & 0x0F;
txmsg[5] = (weekdays[1] >> 4) & 0x0F;
txmsg[6] = weekdays[2] & 0x0F;
txmsg[7] = (weekdays[2] >> 4) & 0x0F;
txmsg[8] = weekdays[3] & 0x0F;
txmsg[9] = (weekdays[3] >> 4) & 0x0F;
return 10;
}
}
break;
case 0x03:
{
eeprom_cutoff_date_t cutoff_date;
if (msg[2] >= MULTIRATE_MAX_CUTOFF_DATES)
break;
if (iicEEPROM_read(EEPROM_START_CUTOFF_DATES + msg[2]*sizeof(eeprom_cutoff_date_t), (void *) &cutoff_date, sizeof(cutoff_date)))
{
txmsg[4] = cutoff_date.year;
txmsg[5] = cutoff_date.month;
txmsg[6] = cutoff_date.day;
txmsg[7] = 0;
return 8;
}
}
break;
}
txmsg[1] = 0x81;
return 4;
}
int multirate_clear_usage(uint8_t *msg)
{
static const int base[3] =
{
EEPROM_START_HISTORIES_A,
EEPROM_START_HISTORIES_B,
EEPROM_START_HISTORIES_C
};
switch (msg[1])
{
case 0x00:
{
eeprom_daily_peak_t daily_peak;
if (msg[2] >= MULTIRATE_MAX_DAILY_PEAKS)
break;
memset(&daily_peak, 0, sizeof(daily_peak));
return iicEEPROM_write(EEPROM_START_PEAKS + msg[2]*sizeof(eeprom_daily_peak_t), (void *) &daily_peak, sizeof(daily_peak));
}
case 0x01:
{
eeprom_history_t history;
if (msg[2] >= MULTIRATE_MAX_CUTOFF_DATES || msg[3] >= MULTIRATE_DAY_SCHEDULES)
break;
memset(&history, 0, sizeof(history));
return iicEEPROM_write(base[0] + (msg[2]*MULTIRATE_DAY_SCHEDULES + msg[3])*sizeof(eeprom_history_t), (void *) &history, sizeof(history));
}
}
return 0;
}
int multirate_get_usage(uint8_t *msg, uint8_t *txmsg)
{
static const int base[3] =
{
EEPROM_START_HISTORIES_A,
EEPROM_START_HISTORIES_B,
EEPROM_START_HISTORIES_C
};
txmsg[0] = 0xC3;
txmsg[1] = 0x80;
txmsg[2] = msg[2];
txmsg[3] = msg[3];
switch (msg[1])
{
case 0x00:
{
eeprom_daily_peak_t daily_peak;
if (msg[2] >= MULTIRATE_MAX_DAILY_PEAKS)
break;
if (iicEEPROM_read(EEPROM_START_PEAKS + msg[2]*sizeof(eeprom_daily_peak_t), (void *) &daily_peak, sizeof(daily_peak)))
{
((uint32_t *) txmsg)[1] = daily_peak.usage;
txmsg[8] = daily_peak.hour;
txmsg[9] = daily_peak.minute;
return 10;
}
}
break;
case 0x01:
{
eeprom_history_t history;
if (msg[2] >= MULTIRATE_MAX_CUTOFF_DATES || msg[3] >= MULTIRATE_DAY_SCHEDULES)
break;
if (iicEEPROM_read(base[0] + (msg[2]*MULTIRATE_DAY_SCHEDULES + msg[3])*sizeof(eeprom_history_t), (void *) &history, sizeof(history)))
{
txmsg[2] = 0;
txmsg[3] = 0;
((uint32_t *) txmsg)[1] = history.energy_hi;
((uint32_t *) txmsg)[2] = history.energy_lo;
return 12;
}
}
break;
}
txmsg[1] = 0x81;
return 4;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?