#include "FreeRTOS.h" #include "semphr.h" #include "task.h" #define metersSTACK_SIZE configMINIMAL_STACK_SIZE+200 /* masks for RTC */ #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 #include "MetersIncludes.h" extern xTickCount; /* tick counter (milliseconds) */ portBASE_TYPE Init_P2_0(void); void basementGasCalculation(void); portLONG basementGasReading = 0; portTickType basementGasLastTime = 0; /* The semaphore used to wake the Meters task when a pulse was received or the timer expired. */ xSemaphoreHandle xMetersSemaphore = NULL; portTickType xLastMeterTaskRunTime; /* keeps the last time the meter calculation ran */ int rtcHOURS; int rtcMINUTES; int rtcSECONDS; static portTASK_FUNCTION( vMeters_Task, pvParameters ) { vSemaphoreCreateBinary( xMetersSemaphore ); Init_P2_0(); /* init GPIO for meters */ for( ;; ) { basementGasCalculation(); portENTER_CRITICAL(); // example: do stuff portEXIT_CRITICAL(); /* We did not receive a pulse, and there was no periodic processing to perform. Block for a fixed period. If a pulse is received during this period we will be woken by the ISR giving us the Semaphore. */ xLastMeterTaskRunTime = xTaskGetTickCount(); /* update last run time */ rtcHOURS = (RTC_CTIME0 & MASKHR)>>16; // Read Hour rtcMINUTES = (RTC_CTIME0 & MASKMIN)>>8; // Read Minute rtcSECONDS = RTC_CTIME0 & MASKSEC; // Read Second xSemaphoreTake( xMetersSemaphore, 1000 ); /* timeout 1 sec */ /* Yield in case cooperative scheduling is being used. */ #if configUSE_PREEMPTION == 0 { taskYIELD(); } #endif } } void vStartMetersTask( unsigned portBASE_TYPE uxPriority ) { initMeterItems(); /* Spawn the task. */ xTaskCreate( vMeters_Task, ( signed portCHAR * ) "Meters", metersSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL ); } void vP2_0_ISR_Wrapper( void ); // configure port-pins for use with LAN-controller, // reset it and send the configuration-sequence portBASE_TYPE Init_P2_0(void) { // not needed yet : SCS |= 1; // Enable FAST GPIO portBASE_TYPE xReturn = 1; // return value /* Enable Pins. */ PINSEL4 &= 0xfffff3ff; /* reset bit 20 and 21, P2.10 = GPIO Port 2.10 */ PINMODE4 &= 0xfffff3ff; /* reset bit 20 and 21, enable on-chip pull-up resistor on Port 2.10 */ IO2_INT_EN_R |= (1<<10); /* enable rising edge interrupt for P2:10 */ IO2_INT_EN_F &= ~(1<<10); /* disable falling edge interrupt for P2:10 */ VICVectAddr17 = (portLONG) vP2_0_ISR_Wrapper; /* EINT-3 interrupt handler */ VICIntEnable |= (1<<17); /* Enable VIC index-17 (shared by EINT3 and GPIO) */ return xReturn; } void basementGasCalculation(void) { } 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? */ }