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 19) @@ -0,0 +1,107 @@ + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#define metersSTACK_SIZE configMINIMAL_STACK_SIZE +/* 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 + + +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 */ +portTickType xMeterIdleRate = 1000; /* the rate (in ticks = ms) at which the calculation runs when no pulses triggered a calculation */ + + + int rtcHOURS; + int rtcMINUTES; + int rtcSECONDS; +static portTASK_FUNCTION( vMeters_Task, pvParameters ) +{ + + + + vSemaphoreCreateBinary( xMetersSemaphore ); + + Init_P2_0(); /* init GPIO for meters */ + xLastMeterTaskRunTime = xTaskGetTickCount(); /* init last run time */ + + + 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 ) +{ + + /* 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) +{ + +} 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 19) @@ -0,0 +1,60 @@ +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +extern basementGasReading; +extern xMetersSemaphore; + +/* The interrupt entry point. */ +void vP2_0_ISR_Wrapper( void ) __attribute__((naked)); + +/* The function that actually performs the interrupt processing. This must be +separate to the wrapper to ensure the correct stack frame is set up. */ +void vP2_0_ISR_Handler( void ); + +void vP2_0_ISR_Handler( void ) +{ + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + if ((IO2_INT_STAT_R & (1 << 10)) != 0) /* P2.10 interrupt triggered */ + { + basementGasReading++; + } + // else if ((IO2_INT_STAT_R & (1 << n)) != 0) /* some other interrupt triggered */ + { + ; + } + + /* Clear the interrupt. */ + IO2_INT_CLR |= (1<<10); + VICVectAddr = 0; + + /* Unblock the Meters task as data has arrived. */ + xSemaphoreGiveFromISR( xMetersSemaphore, &xHigherPriorityTaskWoken ); + + if( xHigherPriorityTaskWoken ) + { + /* If the Meters task was unblocked then calling "Yield from ISR" here + will ensure the interrupt returns directly to the Meters task, if it + is the highest priority read task. */ + portYIELD_FROM_ISR(); + } +} +/*-----------------------------------------------------------*/ + +void vP2_0_ISR_Wrapper( void ) +{ + /* Save the context of the interrupted task. */ + portSAVE_CONTEXT(); + + /* Call the handler function. This must be separate from the wrapper + function to ensure the correct stack frame is set up. */ + vP2_0_ISR_Handler(); + + /* Restore the context of whichever task is going to run next. */ + portRESTORE_CONTEXT(); +} + + + +