Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: net 1-wire lpc1768 crypto clock web fram log
program.c
00001 #include <stdint.h> 00002 #include <stdlib.h> 00003 #include <stdbool.h> 00004 00005 #include "rtc.h" 00006 #include "clktime.h" 00007 #include "clk.h" 00008 #include "log.h" 00009 #include "fram.h" 00010 #include "http.h" 00011 00012 #define PROGRAMS_COUNT 3 00013 #define TRANSITIONS_COUNT 4 00014 static int16_t programs[PROGRAMS_COUNT][TRANSITIONS_COUNT]; static int iPrograms; 00015 static char programDay[7]; static int iDay; 00016 static char programNewDayHour; static int iNewDayHour; 00017 00018 int ProgramGetDay (int i) { return (int) programDay[i]; } 00019 int ProgramGetNewDayHour() { return (int) programNewDayHour;} 00020 00021 void ProgramSetDay (int i, int value) { programDay [i] = (char)value; FramWrite(iDay + i, 1, &programDay [i]); } 00022 void ProgramSetNewDayHour( int value) { programNewDayHour = (char)value; FramWrite(iNewDayHour, 1, &programNewDayHour ); } 00023 00024 int ProgramInit() 00025 { 00026 char def1; 00027 int address; 00028 int programSize = PROGRAMS_COUNT * TRANSITIONS_COUNT * sizeof(int16_t); 00029 address = FramLoad(7, programDay, NULL); if (address < 0) return -1; iDay = address; 00030 address = FramLoad(programSize, programs, NULL); if (address < 0) return -1; iPrograms = address; //3 x 4 x 2 00031 def1 = 2; address = FramLoad(1, &programNewDayHour, &def1); if (address < 0) return -1; iNewDayHour = address; 00032 return 0; 00033 } 00034 00035 /* 00036 There are three programs available [0|1|2]; any of which can be allocated to a given day [0-6]. 00037 Each program contains four transitions with an index [0|1|2|3]. 00038 A transition is defined to be a short (16 bit) and consists of: 00039 +---------+--------+--------+---------+ 00040 | 15 - 13 | 12 | 11 | 10 - 00 | 00041 +---------+--------+--------+---------+ 00042 | | in use | switch | minute | 00043 | | yes/no | on/off | in day | 00044 | | 1/0 | 1/0 | 0-1439 | 00045 +---------+--------+--------+---------+ 00046 */ 00047 static int16_t encodeTransition(bool inuse, bool onoff, int minutes) 00048 { 00049 int16_t transition = minutes; 00050 transition &= 0x07FF; 00051 if (onoff) transition |= 0x0800; 00052 if (inuse) transition |= 0x1000; 00053 return transition; 00054 } 00055 static void decodeTransition(int16_t transition, bool* pinuse, bool* ponoff, int* pminutes) 00056 { 00057 *pinuse = transition & 0x1000; 00058 *ponoff = transition & 0x0800; 00059 *pminutes = transition & 0x07FF; 00060 } 00061 00062 static int compareTransition (const void * a, const void * b) //-ve a goes before b; 0 same; +ve a goes after b 00063 { 00064 bool inUseA, inUseB; 00065 bool onA, onB; 00066 int minutesA, minutesB; 00067 decodeTransition(*(int16_t*)a, &inUseA, &onA, &minutesA); 00068 decodeTransition(*(int16_t*)b, &inUseB, &onB, &minutesB); 00069 00070 if (!inUseA && !inUseB) return 0; 00071 if (!inUseA) return +1; 00072 if (!inUseB) return -1; 00073 00074 if (minutesA < programNewDayHour * 60) minutesA += 1440; 00075 if (minutesB < programNewDayHour * 60) minutesB += 1440; 00076 00077 if (minutesA < minutesB) return -1; 00078 if (minutesA > minutesB) return +1; 00079 return 0; 00080 } 00081 static void sort(int16_t* pProgram) 00082 { 00083 qsort (pProgram, 4, sizeof(int16_t), compareTransition); 00084 } 00085 00086 //[+|-][00-23][00-59]; 00087 void ProgramToString(int program, int buflen, char* buffer) 00088 { 00089 if (buflen < 25) return; 00090 char* p = buffer; 00091 for (int i = 0; i < TRANSITIONS_COUNT; i++) 00092 { 00093 int16_t transition = programs[program][i]; 00094 bool inuse; 00095 bool on; 00096 int minuteUnits; 00097 decodeTransition(transition, &inuse, &on, &minuteUnits); 00098 if (!inuse) continue; 00099 00100 int minuteTens = minuteUnits / 10; minuteUnits %= 10; 00101 int hourUnits = minuteTens / 6; minuteTens %= 6; 00102 int hourTens = hourUnits / 10; hourUnits %= 10; 00103 00104 if (p > buffer) *p++ = ' '; 00105 *p++ = on ? '+' : '-'; 00106 *p++ = hourTens + '0'; 00107 *p++ = hourUnits + '0'; 00108 *p++ = minuteTens + '0'; 00109 *p++ = minuteUnits + '0'; 00110 } 00111 *p = 0; 00112 } 00113 void ProgramSendAjax() 00114 { 00115 for (int program = 0; program < PROGRAMS_COUNT; program++) 00116 { 00117 for (int transition = 0; transition < TRANSITIONS_COUNT; transition++) 00118 { 00119 bool inuse; 00120 bool on; 00121 int minuteUnits; 00122 decodeTransition(programs[program][transition], &inuse, &on, &minuteUnits); 00123 if (!inuse) continue; 00124 00125 int minuteTens = minuteUnits / 10; minuteUnits %= 10; 00126 int hourUnits = minuteTens / 6; minuteTens %= 6; 00127 int hourTens = hourUnits / 10; hourUnits %= 10; 00128 00129 if (transition) HttpAddChar(' '); 00130 HttpAddChar(on ? '+' : '-'); 00131 HttpAddChar(hourTens + '0'); 00132 HttpAddChar(hourUnits + '0'); 00133 HttpAddChar(minuteTens + '0'); 00134 HttpAddChar(minuteUnits + '0'); 00135 } 00136 HttpAddChar('\n'); 00137 } 00138 } 00139 static void handleParseDelim(int program, int* pIndex, bool* pInUse, bool* pOn, int* pHourTens, int* pHourUnits, int* pMinuteTens, int* pMinuteUnits) 00140 { 00141 int hour = *pHourTens * 10 + *pHourUnits; 00142 if (hour < 0) *pInUse = false; 00143 if (hour > 23) *pInUse = false; 00144 00145 int minute = *pMinuteTens * 10 + *pMinuteUnits; 00146 if (minute < 0) *pInUse = false; 00147 if (minute > 59) *pInUse = false; 00148 00149 int minutes = hour * 60 + minute; 00150 00151 int16_t transition = encodeTransition(*pInUse, *pOn, minutes); 00152 programs[program][*pIndex] = transition; 00153 00154 *pIndex += 1; 00155 *pInUse = 0; 00156 *pOn = 0; 00157 *pHourTens = 0; 00158 *pHourUnits = 0; 00159 *pMinuteTens = 0; 00160 *pMinuteUnits = 0; 00161 00162 } 00163 void ProgramParse(int program, char* p) 00164 { 00165 int i = 0; 00166 bool inUse = 0; bool on = 0; 00167 int hourUnits = 0; int hourTens = 0; 00168 int minuteUnits = 0; int minuteTens = 0; 00169 while (*p && i < TRANSITIONS_COUNT) 00170 { 00171 if (*p == '+') { on = true ; } 00172 else if (*p == '-') { on = false; } 00173 else if (*p >= '0' && *p <= '9') { inUse = true; hourTens = hourUnits; hourUnits = minuteTens; minuteTens = minuteUnits; minuteUnits = *p - '0'; } 00174 else if (*p == ' ') { handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits); } 00175 p++; 00176 } 00177 while (i < TRANSITIONS_COUNT) handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits); 00178 sort(&programs[program][0]); 00179 FramWrite(iPrograms + program * 8, 8, &programs[program]); 00180 } 00181 00182 static bool readProgramTimerOutput() 00183 { 00184 00185 if (!ClkTimeIsSet()) return 0; 00186 00187 struct tm tm; 00188 ClkNowTmLocal(&tm); 00189 00190 int dayOfWeek = tm.tm_wday; 00191 int minutesNow = tm.tm_hour * 60 + tm.tm_min; 00192 if (tm.tm_hour < programNewDayHour) //Before 2am should be matched against yesterday's program. 00193 { 00194 dayOfWeek--; 00195 if (dayOfWeek < 0) dayOfWeek = 6; 00196 } 00197 00198 int program = programDay[dayOfWeek]; 00199 00200 bool calling = 0; 00201 for (int i = 0; i < TRANSITIONS_COUNT; i++) 00202 { 00203 int16_t transition = programs[program][i]; 00204 bool inuse; 00205 bool on; 00206 int minutes; 00207 decodeTransition(transition, &inuse, &on, &minutes); 00208 if (!inuse) continue; 00209 if (minutes <= minutesNow) calling = on; 00210 } 00211 00212 return calling; 00213 } 00214 00215 bool ProgramTimerOutput; 00216 00217 int ProgramMain() 00218 { 00219 ProgramTimerOutput = readProgramTimerOutput(); 00220 return 0; 00221 }
Generated on Tue Jul 12 2022 18:50:15 by
