Index: webserver/example/freeRTOSexample/Source/EnergyMeters/Meters.c =================================================================== --- webserver/example/freeRTOSexample/Source/EnergyMeters/Meters.c (revision 19) +++ webserver/example/freeRTOSexample/Source/EnergyMeters/Meters.c (revision 22) @@ -4,5 +4,5 @@ #include "task.h" -#define metersSTACK_SIZE configMINIMAL_STACK_SIZE +#define metersSTACK_SIZE configMINIMAL_STACK_SIZE+200 /* masks for RTC */ #define MASKSEC 0x3F // Second 00..59 00000000:00000000:00xxxxxx @@ -10,4 +10,7 @@ #define MASKHR 0x1F0000 // Hour 00..23 000xxxxx:00000000:00000000 +#include "MetersIncludes.h" + +extern xTickCount; /* tick counter (milliseconds) */ portBASE_TYPE Init_P2_0(void); @@ -21,5 +24,4 @@ portTickType xLastMeterTaskRunTime; /* keeps the last time the meter calculation ran */ -portTickType xMeterIdleRate = 1000; /* the rate (in ticks = ms) at which the calculation runs when no pulses triggered a calculation */ @@ -35,6 +37,4 @@ Init_P2_0(); /* init GPIO for meters */ - xLastMeterTaskRunTime = xTaskGetTickCount(); /* init last run time */ - for( ;; ) @@ -73,4 +73,5 @@ { + initMeterItems(); /* Spawn the task. */ xTaskCreate( vMeters_Task, ( signed portCHAR * ) "Meters", metersSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL ); @@ -106,2 +107,19 @@ } + +void initMeterItems(void) +{ + int i; + for (i = 0; i < NUMBER_OF_METERS; i++) + { + meterItems[i].meterEnabled = 0; // disable all meters + } + + // Init Gas meter + meterItems[METER_INDEX_GAS].meterEnabled = 1; /* 0: item not used, 1: meter enabled */ + meterItems[METER_INDEX_GAS].timeLastTick = getEpochTimeWithMs(); /* when did the last tick occur? epoch (seconds) */ + meterItems[METER_INDEX_GAS].timeBeforeLastTick = getEpochTimeWithMs(); /* when did the tick before last tick occur? epoch (seconds) */ + meterItems[METER_INDEX_GAS].valueLastTick = 0; /* what value did we have at the last tick? */ + meterItems[METER_INDEX_GAS].valueBeforeLastTick = 1; /* what value did we have at the tick before the last tick? */ + +} Index: webserver/example/freeRTOSexample/Source/EnergyMeters/Meters_ISRs.c =================================================================== --- webserver/example/freeRTOSexample/Source/EnergyMeters/Meters_ISRs.c (revision 19) +++ webserver/example/freeRTOSexample/Source/EnergyMeters/Meters_ISRs.c (revision 22) @@ -2,7 +2,10 @@ #include "semphr.h" #include "task.h" +#include "MetersIncludes.h" -extern basementGasReading; extern xMetersSemaphore; +extern xTickCount; /* millisecond tick counter */ + +void handleGasMeterTick(void); /* The interrupt entry point. */ @@ -19,5 +22,5 @@ if ((IO2_INT_STAT_R & (1 << 10)) != 0) /* P2.10 interrupt triggered */ { - basementGasReading++; + handleGasMeterTick(); } // else if ((IO2_INT_STAT_R & (1 << n)) != 0) /* some other interrupt triggered */ @@ -56,5 +59,10 @@ } +void handleGasMeterTick(void) +{ + meterItems[METER_INDEX_GAS].timeBeforeLastTick = meterItems[METER_INDEX_GAS].timeLastTick; /* when did the tick before the last tick occur? */ + meterItems[METER_INDEX_GAS].timeLastTick = getEpochTimeWithMs(); /* when did the last tick occur? epoch (seconds) */ + meterItems[METER_INDEX_GAS].valueLastTick = 0; /* what value did we have at the last tick? */ + meterItems[METER_INDEX_GAS].valueBeforeLastTick = 1; /* what value did we have at the tick before the last tick? */ +} - - Index: webserver/example/freeRTOSexample/Source/EnergyMeters/timeConversion.c =================================================================== --- webserver/example/freeRTOSexample/Source/EnergyMeters/timeConversion.c (revision 22) +++ webserver/example/freeRTOSexample/Source/EnergyMeters/timeConversion.c (revision 22) @@ -0,0 +1,92 @@ + +#include +#include "FreeRTOS.h" +#include "MetersIncludes.h" +#include "task.h" +#include "StackMacros.h" + +#define MASKSEC 0x3F // Second 00..59 00000000:00000000:00xxxxxx +#define MASKMIN 0x3F00 // Minute 00..59 00000000:00xxxxxx:00000000 +#define MASKHR 0x1F0000 // Hour 00..23 000xxxxx:00000000:00000000 + +extern xTickCount; /* tick counter (milliseconds) from FreeRTOS */ + +/* taken from Linux Kernel 2.6.30 */ +portLONG +mktime(const unsigned int year0, const unsigned int mon0, + const unsigned int day, const unsigned int hour, + const unsigned int min, const unsigned int sec); +unsigned long long getEpochTimeWithMs(void) +{ + /* get both registers while in critical section to eliminate the chance of inconsistencies when there are + * overflows of the SECONDS value. + */ + unsigned int timeHour; + unsigned int timeMin; + unsigned int timeSec; + unsigned int timeDay; + unsigned int timeMonth; + unsigned int timeYear; + unsigned long long tempTickTime; + portLONG cTIME0; + portLONG cTIME1; + +// portENTER_CRITICAL(); + cTIME0 = RTC_CTIME0; + cTIME1 = RTC_CTIME1; +// portEXIT_CRITICAL(); + + + timeHour = (cTIME0 & MASKHR)>>16; // Hour + timeMin = (cTIME0 & MASKMIN)>>8; // Minute + timeSec = cTIME0 & MASKSEC; // Second + timeDay = cTIME1 & 0xf; // Day + timeMonth = (cTIME1 >> 8) & 0xF; // Month + timeYear = (cTIME1 >> 16) & 0xFFF; // Year + + /* we get the epoch time, multiply it by 1000 and then add the milliseconds portion + of the Tick timer. This returns a millisecond time since epoch. + */ + tempTickTime = mktime(timeYear, timeMonth, timeDay, timeHour, timeMin, timeSec); + tempTickTime -= 3600 * 2; /* time zone adaptation (2 h) */ + tempTickTime = (tempTickTime * 1000) + (xTickCount % 1000); + return tempTickTime; +} + + +// mktime from linux kernel 2.6.30 kernel / time.c +/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. + * + * [For the Julian calendar (which was used in Russia before 1917, + * Britain & colonies before 1752, anywhere else before 1582, + * and is still in use by some communities) leave out the + * -year/100+year/400 terms, and add 10.] + * + * This algorithm was first published by Gauss (I think). + * + * WARNING: this function will overflow on 2106-02-07 06:28:16 on + * machines where long is 32-bit! (However, as time_t is signed, we + * will already get problems at other places on 2038-01-19 03:14:08) + */ +portLONG +mktime(const unsigned int year0, const unsigned int mon0, + const unsigned int day, const unsigned int hour, + const unsigned int min, const unsigned int sec) +{ + unsigned int mon = mon0, year = year0; + + /* 1..12 -> 11,12,1..10 */ + if (0 >= (int) (mon -= 2)) { + mon += 12; /* Puts Feb last since it has leap day */ + year -= 1; + } + + return ((((portLONG) + (year/4 - year/100 + year/400 + 367*mon/12 + day) + + year*365 - 719499 + )*24 + hour /* now have hours */ + )*60 + min /* now have minutes */ + )*60 + sec; /* finally seconds */ +} Index: webserver/example/freeRTOSexample/Source/EnergyMeters/MetersIncludes.h =================================================================== --- webserver/example/freeRTOSexample/Source/EnergyMeters/MetersIncludes.h (revision 22) +++ webserver/example/freeRTOSexample/Source/EnergyMeters/MetersIncludes.h (revision 22) @@ -0,0 +1,20 @@ + +void initMeterItems(void); +unsigned long long getEpochTimeWithMs(void); + +#define NUMBER_OF_METERS 10 /* the number of meters we use */ + +#define METER_INDEX_GAS 0 /* index of the gas meter data */ + + +typedef struct +{ + portSHORT meterEnabled; /* 0: item not used, 1: meter enabled */ + unsigned long long timeLastTick; /* when did the last tick occur? epoch time in seconds */ + unsigned long long timeBeforeLastTick; /* when did the tick before the last tick occur? epoch time in seconds */ + portLONG valueLastTick; /* what value did we have at the last tick? */ + portLONG valueBeforeLastTick; /* what value did we have at the tick before the last tick? */ +} meterItem; + +meterItem meterItems[NUMBER_OF_METERS]; /* the data for all the meters */ +