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(&current_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(&current_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(&current_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(&current_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(&current_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(&current_history, sizeof(current_history));

    pos = (slot*MULTIRATE_DAY_SCHEDULES + tariff)*sizeof(eeprom_history_t);
    res = iicEEPROM_write(EEPROM_START_HISTORIES_A + pos, (void *) &current_history, sizeof(current_history));
    res |= iicEEPROM_write(EEPROM_START_HISTORIES_B + pos, (void *) &current_history, sizeof(current_history));
    res |= iicEEPROM_write(EEPROM_START_HISTORIES_C + pos, (void *) &current_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 + -
显示快捷键?