homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 23:52:30 2013 +0000
Revision:
124:55c83dbeba2c
Parent:
123:c8ea8f59455b
Child:
125:6b3a86e3c883
snapshot

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gatedClock 0:fcca4db7b32a 1 /*----------------------------------------------//------------------------------
gatedClock 0:fcca4db7b32a 2 student : m-moore
gatedClock 0:fcca4db7b32a 3 class : rtos
gatedClock 10:2b0a9fc39109 4 directory : RTOS_HW_07
gatedClock 0:fcca4db7b32a 5 file : main.cpp
gatedClock 0:fcca4db7b32a 6 ----description---------------------------------//------------------------------
gatedClock 70:7c0743c28b11 7 gotchyas
gatedClock 70:7c0743c28b11 8 1. using pc.printf inside a ticker routine will freeze the routine.
gatedClock 71:4a5f256ecf7c 9 2. using queues (get, put) will not work within a ticker routine.
gatedClock 76:74c454c9d75b 10 3. Ticker has a bug. http://mbed.org/questions/1563/Mbed-Tickerfunction-hangs-system-from-re/
gatedClock 80:e3e1a2161435 11
gatedClock 80:e3e1a2161435 12 improvements
gatedClock 80:e3e1a2161435 13 countdown timer needs to be sync'd to start button press.
gatedClock 87:147e2b08fae6 14 this could not be done, use granularity setting instead.
gatedClock 80:e3e1a2161435 15
gatedClock 120:64a969984af2 16 global variables considerations (mutex)
gatedClock 120:64a969984af2 17 the global variables associated with joystick button presses are
gatedClock 120:64a969984af2 18 in the structure 'tButtons' (instance 'giButtons'). ISRs store that a
gatedClock 120:64a969984af2 19 button has been pressed in this struct, and since mutex can not be called
gatedClock 120:64a969984af2 20 within an interrupt, no mutex is used on these buttons.
gatedClock 120:64a969984af2 21 only the ISRs are 'authorized' to set those variables, and the bottom-half
gatedClock 120:64a969984af2 22 of the ISRs, 'threadButtonStateManager', is authorized to clear them once
gatedClock 120:64a969984af2 23 'threadButtonStateManager' has forwarded the fact that the buttons were
gatedClock 120:64a969984af2 24 pressed. I don't expect there to be any collision of writing the variables.
gatedClock 120:64a969984af2 25
gatedClock 123:c8ea8f59455b 26 some mutex's are in use, but I'm running out of time, --
gatedClock 120:64a969984af2 27
gatedClock 123:c8ea8f59455b 28 here are use cases & things tested
gatedClock 123:c8ea8f59455b 29
gatedClock 123:c8ea8f59455b 30 1.
gatedClock 123:c8ea8f59455b 31 * user sets maximum time.
gatedClock 123:c8ea8f59455b 32 * user hits button.
gatedClock 123:c8ea8f59455b 33 * LCD shows total time, remaining time, and calculated temperature.
gatedClock 123:c8ea8f59455b 34 * LEDs blink for magnetron and carousel.
gatedClock 123:c8ea8f59455b 35 * time runs out.
gatedClock 123:c8ea8f59455b 36 * beeper sounds for 3 seconds.
gatedClock 123:c8ea8f59455b 37 * idle state, total time is reset.
gatedClock 123:c8ea8f59455b 38
gatedClock 123:c8ea8f59455b 39 2.
gatedClock 123:c8ea8f59455b 40 * user sets maximum time.
gatedClock 123:c8ea8f59455b 41 * user hits start button.
gatedClock 123:c8ea8f59455b 42 * user opens door.
gatedClock 123:c8ea8f59455b 43 * -> magnetron/carousel off.
gatedClock 123:c8ea8f59455b 44 * -> countdown freezes.
gatedClock 123:c8ea8f59455b 45 * -> temperature freezes.
gatedClock 123:c8ea8f59455b 46 * user hits start button -> nothing happens.
gatedClock 123:c8ea8f59455b 47 * user closes door
gatedClock 123:c8ea8f59455b 48 * user hits start button
gatedClock 123:c8ea8f59455b 49 * -> remaining-time countdown, temperature resume.
gatedClock 123:c8ea8f59455b 50 * -> magnetron/carousel on.
gatedClock 123:c8ea8f59455b 51 * etc, ending as above.
gatedClock 123:c8ea8f59455b 52
gatedClock 123:c8ea8f59455b 53 3.
gatedClock 123:c8ea8f59455b 54 * user sets maximum time.
gatedClock 123:c8ea8f59455b 55 * user hits start button.
gatedClock 123:c8ea8f59455b 56 * user tries to adjust maximum time -> not allowed.
gatedClock 123:c8ea8f59455b 57 * not allowed until 'idle' state.
gatedClock 123:c8ea8f59455b 58
gatedClock 123:c8ea8f59455b 59 4.
gatedClock 123:c8ea8f59455b 60 * user sets maximum time.
gatedClock 123:c8ea8f59455b 61 * user hits start button.
gatedClock 123:c8ea8f59455b 62 * user hits stop button during (running, pause)
gatedClock 123:c8ea8f59455b 63 * -> magnetron off, temperature live, remaining time zero
gatedClock 123:c8ea8f59455b 64 * -> i.e. jump directly to idle state.
gatedClock 123:c8ea8f59455b 65
gatedClock 123:c8ea8f59455b 66 5.
gatedClock 123:c8ea8f59455b 67 * user does not set maximum time.
gatedClock 123:c8ea8f59455b 68 * user hits 'start'.
gatedClock 123:c8ea8f59455b 69 * nothing happens.
gatedClock 123:c8ea8f59455b 70
gatedClock 123:c8ea8f59455b 71
gatedClock 123:c8ea8f59455b 72 tour of software
gatedClock 123:c8ea8f59455b 73 * ISRs register button presses into global structure.
gatedClock 123:c8ea8f59455b 74 * debounce mechanism.
gatedClock 123:c8ea8f59455b 75 * ISRs share common bottom-half thread, which clears the
gatedClock 123:c8ea8f59455b 76 button-press structure values, and forards mail to other
gatedClock 123:c8ea8f59455b 77 threads of just-pressed button status.
gatedClock 123:c8ea8f59455b 78 * total time control thread handles setting total time, and
gatedClock 123:c8ea8f59455b 79 will suppress total time changes or clear total time based
gatedClock 123:c8ea8f59455b 80 on mail from the FSM thread.
gatedClock 123:c8ea8f59455b 81 * FSM thread defines/executes cook states:
gatedClock 123:c8ea8f59455b 82 IDLE, COOK, PAUSE, CONTINUE, DONE(beep)
gatedClock 123:c8ea8f59455b 83 states are based on current state plus button-press changes
gatedClock 123:c8ea8f59455b 84 plus countdown done.
gatedClock 123:c8ea8f59455b 85 * temperature thread reads physical temperature, or calculates
gatedClock 123:c8ea8f59455b 86 synthetic temperature at 1/6 degree increase per second,
gatedClock 123:c8ea8f59455b 87 upon commands from the FSM.
gatedClock 123:c8ea8f59455b 88 * LCD thread
gatedClock 120:64a969984af2 89
gatedClock 124:55c83dbeba2c 90 magnetron timing
gatedClock 124:55c83dbeba2c 91 * LED2 is used for magnetron control (non-blinking).
gatedClock 124:55c83dbeba2c 92 - front-end control is used to turn it off:
gatedClock 124:55c83dbeba2c 93 - it is turned off in the 'stop' button ISR for safety.
gatedClock 124:55c83dbeba2c 94 - it is turned OFF in the door-toggle ISR for safety.
gatedClock 124:55c83dbeba2c 95 - this ensures immediate magnetron off.
gatedClock 124:55c83dbeba2c 96
gatedClock 124:55c83dbeba2c 97 other timing
gatedClock 124:55c83dbeba2c 98 * the FSM thread has (if I counted right) six message get/puts worst
gatedClock 124:55c83dbeba2c 99 case in one loop, all with 1mS timeout, and the loop has a 1mS wait,
gatedClock 124:55c83dbeba2c 100 so it would be running on the order of once each 10mS.
gatedClock 124:55c83dbeba2c 101 this is the highest priority thread.
gatedClock 120:64a969984af2 102
gatedClock 80:e3e1a2161435 103
gatedClock 0:fcca4db7b32a 104 -----includes-----------------------------------//----------------------------*/
gatedClock 0:fcca4db7b32a 105 #include "mbed.h" // mbed class.
gatedClock 10:2b0a9fc39109 106 #include "rtos.h" // rtos class.
gatedClock 39:4e7e4d935a87 107 #include "LM75B.h" // thermometer class.
gatedClock 10:2b0a9fc39109 108 #include "C12832_lcd.h" // LCD class.
gatedClock 0:fcca4db7b32a 109 //---defines------------------------------------//------------------------------
gatedClock 9:cfdb9aa5857c 110 #define LCD1 lcd.locate(0, 0); // LCD line 1.
gatedClock 9:cfdb9aa5857c 111 #define LCD2 lcd.locate(0,11); // LCD line 2.
gatedClock 9:cfdb9aa5857c 112 #define LCD3 lcd.locate(0,22); // LCD line 3.
gatedClock 9:cfdb9aa5857c 113
gatedClock 10:2b0a9fc39109 114
gatedClock 66:4a0006fa5cc1 115 #define DEBOUNCEmS 16 // debounce wait in mS.
gatedClock 19:92b11e30aaaf 116 #define uS_TIMEOUT 100 // Timer uS timeout.
gatedClock 19:92b11e30aaaf 117 #define LBSIG 1 // left button signal code.
gatedClock 33:34c1bef3c4ff 118 #define PIPEuS 1000 // pipeline clock period.
gatedClock 19:92b11e30aaaf 119 #define SLOWCLOCKuS 500000 // slow-clock period.
gatedClock 39:4e7e4d935a87 120 #define TEMPCLOCKS 1 // temperature-measuring period in S.
gatedClock 26:bff592483cb1 121 #define PIPEDATASIZE 8 // dimension of tPipeData.
gatedClock 44:d16e813e61ef 122 #define THREAD_1_WAITmS 400 // thread 1 wait in mS.
gatedClock 99:a3e8344024c0 123 #define THREAD_2_WAITmS 40 // LCD thread wait.
gatedClock 67:1d9c85a4c3c1 124 #define THREAD_3_WAITmS 80 // thread 3 wait in mS.
gatedClock 66:4a0006fa5cc1 125 #define THREAD_4_WAITmS 1 // thread 4 wait in mS.
gatedClock 121:c9d28cd59460 126 #define THREAD_5_WAITmS 1 // FSM thread wait.
gatedClock 44:d16e813e61ef 127 #define HB_MODULO 1024 // heartbeat modulo divisor.
gatedClock 50:2928c3cbdcc3 128
gatedClock 54:b0e7352d2516 129 #define MSG_INC_TIME 0x01
gatedClock 54:b0e7352d2516 130 #define MSG_DEC_TIME 0x02
gatedClock 58:ec630b6dd9b1 131 #define MSG_START 0x04
gatedClock 58:ec630b6dd9b1 132 #define MSG_STOP 0x08
gatedClock 58:ec630b6dd9b1 133 #define MSG_OPEN 0x10
gatedClock 58:ec630b6dd9b1 134 #define MSG_CLOSED 0x20
gatedClock 57:0432c68ad232 135
gatedClock 78:7df160e0db7b 136 #define FSM_IDLE 0x01 // cook-state state-machine.
gatedClock 78:7df160e0db7b 137 #define FSM_COOK 0x02 // cook-state state-machine.
gatedClock 78:7df160e0db7b 138 #define FSM_PAUSE 0x04 // cook-state state-machine.
gatedClock 78:7df160e0db7b 139 #define FSM_CONTINUE 0x08 // cook-state state-machine.
gatedClock 78:7df160e0db7b 140 #define FSM_DONE 0x10 // cook-state state-machine.
gatedClock 65:e39360da5929 141
gatedClock 71:4a5f256ecf7c 142 #define RT_PRELOAD 0x01 // remaining-time preload.
gatedClock 71:4a5f256ecf7c 143 #define RT_DECREMENT 0x02 // remaining-time decrement.
gatedClock 71:4a5f256ecf7c 144 #define RT_PAUSE 0x03 // remaining-time don't change.
gatedClock 71:4a5f256ecf7c 145 #define RT_CLEAR 0x04 // remaining-time set to zero.
gatedClock 71:4a5f256ecf7c 146
gatedClock 97:ee840478d6b3 147 #define TEMP_READ 0x01 // temperature synthesizer control.
gatedClock 97:ee840478d6b3 148 #define TEMP_CALC 0x02 // temperature synthesizer control.
gatedClock 97:ee840478d6b3 149 #define TEMP_FREEZE 0x03 // temperature synthesizer control.
gatedClock 94:551b1df4b10c 150
gatedClock 86:388c2b4b7cf5 151 #define GRANULARITY 0x400 // 1-second countdown ticker granularity.
gatedClock 88:0b1b812945eb 152 #define MAXSECONDS 180 // maximum microwave-on time.
gatedClock 89:290c96cd027f 153 #define BEEPTIME 3 // beep duration in S.
gatedClock 94:551b1df4b10c 154 #define BEEPFREQ 300 // beep frequency in Hz.
gatedClock 86:388c2b4b7cf5 155
gatedClock 99:a3e8344024c0 156 #define TIMEINC 10 // time increment in seconds.
gatedClock 0:fcca4db7b32a 157 //--global_definitions--------------------------//------------------------------
gatedClock 26:bff592483cb1 158 struct tButtons // button ISR updates.
gatedClock 26:bff592483cb1 159 {
gatedClock 26:bff592483cb1 160 char cLeftButton; // cooktime +60S.
gatedClock 26:bff592483cb1 161 char cRightButton; // cooktime -60S.
gatedClock 26:bff592483cb1 162 char cTopButton; // start cook.
gatedClock 26:bff592483cb1 163 char cBottomButton; // stop cook.
gatedClock 58:ec630b6dd9b1 164 char cCenterButton; // center button pressed.
gatedClock 53:8c2baf5623c8 165 char cDoorOpen; // door open.
gatedClock 26:bff592483cb1 166 };
gatedClock 34:b449d2a7c786 167
gatedClock 71:4a5f256ecf7c 168 struct tRemainingTime // remaining time related.
gatedClock 71:4a5f256ecf7c 169 {
gatedClock 71:4a5f256ecf7c 170 char cControl; // countdown control.
gatedClock 110:a3b95ccfaed6 171 char cBeepEnable; // beep control.
gatedClock 120:64a969984af2 172 int dTotalTime; // initialize to this.
gatedClock 120:64a969984af2 173 int dRemainingTime; // the countdown value.
gatedClock 120:64a969984af2 174 };
gatedClock 120:64a969984af2 175
gatedClock 120:64a969984af2 176 struct tMagnetron // magnetron control.
gatedClock 120:64a969984af2 177 {
gatedClock 118:d0e057d79acc 178 char cMagnetron; // magnetron blink control.
gatedClock 118:d0e057d79acc 179 char cCarousel; // carousel blink control.
gatedClock 71:4a5f256ecf7c 180 };
gatedClock 71:4a5f256ecf7c 181
gatedClock 80:e3e1a2161435 182 struct tLCD // LCD related.
gatedClock 80:e3e1a2161435 183 {
gatedClock 80:e3e1a2161435 184 int dTotalCookTime; // display time in seconds.
gatedClock 80:e3e1a2161435 185 int dRemainingTime; // display time in seconds.
gatedClock 80:e3e1a2161435 186 float fCelsius; // temperature in celsius.
gatedClock 80:e3e1a2161435 187 };
gatedClock 80:e3e1a2161435 188
gatedClock 104:5e49dbe5038a 189 Queue<int, 1> queueModTotalTime; // modify total time.
gatedClock 104:5e49dbe5038a 190 Queue<int, 1> queueUpdateFSM; // tell FSM what button was pressed.
gatedClock 61:8026a9fc0cf1 191 Queue<int, 1> queueUpdateRemainingTime; // message to update remaining time.
gatedClock 71:4a5f256ecf7c 192 Queue<int, 1> queueSetRemainingTime; // tell countdown it's start time.
gatedClock 94:551b1df4b10c 193 Queue<int, 1> queueTemperatureControl; // control the temperature synthesizer.
gatedClock 97:ee840478d6b3 194 Queue<int, 1> queueSuppressTimeAdjust; // total time control.
gatedClock 98:156298be5ba2 195 Queue<int, 1> queueClearTotalTime; // total time control.
gatedClock 0:fcca4db7b32a 196 //--global_variables----------------------------//------------------------------
gatedClock 108:da479434bd7d 197 tButtons giButtons; // ISR button updates.
gatedClock 71:4a5f256ecf7c 198 tRemainingTime giRemainingTime; // structure instance.
gatedClock 120:64a969984af2 199 tMagnetron giMagnetron; // structure instance.
gatedClock 80:e3e1a2161435 200 tLCD giLCD; // structure instance.
gatedClock 0:fcca4db7b32a 201 //--global_instances----------------------------//------------------------------
gatedClock 55:17f3354da63a 202 Serial pc(USBTX, USBRX); // PuTTY terminal communication.
gatedClock 39:4e7e4d935a87 203 LM75B temperature(p28,p27); // on-board thermometer.
gatedClock 9:cfdb9aa5857c 204 C12832_LCD lcd; // LCD object.
gatedClock 124:55c83dbeba2c 205 DigitalOut led0(LED4); // magnetron enunciator (not magnatron control)
gatedClock 124:55c83dbeba2c 206 DigitalOut led1(LED3); // carousel enunciator (not carousel control)
gatedClock 124:55c83dbeba2c 207 DigitalOut led2(LED2); // magnetron CONTROL.
gatedClock 124:55c83dbeba2c 208 DigitalOut led3(LED1); // carousel CONTROL.
gatedClock 91:b54500888b67 209 DigitalOut speaker(p26); // speaker device.
gatedClock 0:fcca4db7b32a 210
gatedClock 0:fcca4db7b32a 211 InterruptIn iJoyStickUp (p15); // joystick up rising edge.
gatedClock 0:fcca4db7b32a 212 InterruptIn iJoyStickDown (p12); // joystick down rising edge.
gatedClock 0:fcca4db7b32a 213 InterruptIn iJoyStickLeft (p13); // joystick left rising edge.
gatedClock 0:fcca4db7b32a 214 InterruptIn iJoyStickRight (p16); // joystick right rising edge.
gatedClock 0:fcca4db7b32a 215 InterruptIn iJoyStickCenter(p14); // 1 if joystick middle pressed.
gatedClock 66:4a0006fa5cc1 216
gatedClock 66:4a0006fa5cc1 217 Timer debounceTimer; // button debounce timer.
gatedClock 89:290c96cd027f 218 Timer beepTimer; // beep-duration timer.
gatedClock 94:551b1df4b10c 219 Timer temperatureTimer; // how often to raise temperature.
gatedClock 106:5137c38345d3 220
gatedClock 50:2928c3cbdcc3 221 Ticker tickerButtonStateManager; // manage the button states.
gatedClock 101:33dc62b6b728 222 Ticker tickerCookCountdown; // remaining cook time.
gatedClock 101:33dc62b6b728 223 Ticker tickerBeep; // beeper ticker.
gatedClock 117:b9e18163c282 224 Ticker tickerBlinkMagnetron; // magnetron LED blinker.
gatedClock 117:b9e18163c282 225 Ticker tickerBlinkCarousel; // caroulsel LED blinker.
gatedClock 121:c9d28cd59460 226
gatedClock 121:c9d28cd59460 227 Mutex mutexControl; // for giRemainingTime.cControl.
gatedClock 0:fcca4db7b32a 228 //-------prototypes-----------------------------//------------------------------
gatedClock 49:56f790977983 229
gatedClock 19:92b11e30aaaf 230 void slowClock(); // 1Hz or thereabouts.
gatedClock 49:56f790977983 231
gatedClock 9:cfdb9aa5857c 232 void initialization(); // initialize settings.
gatedClock 13:21f27ba467c2 233
gatedClock 13:21f27ba467c2 234 void ISRleftButtonRising(); // cook-time increase.
gatedClock 13:21f27ba467c2 235 void ISRleftButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 236 void ISRrightButtonRising(); // cook-time decrease.
gatedClock 13:21f27ba467c2 237 void ISRrightButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 238 void ISRtopButtonRising(); // cook start.
gatedClock 13:21f27ba467c2 239 void ISRtopButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 240 void ISRbottomButtonRising(); // cook stop.
gatedClock 13:21f27ba467c2 241 void ISRbottomButtonFalling(); // button-release debounce.
gatedClock 13:21f27ba467c2 242 void ISRcenterButtonRising(); // door state toggle.
gatedClock 13:21f27ba467c2 243 void ISRcenterButtonFalling(); // button-release debounce.
gatedClock 16:db7f0b3b2605 244 void disableSignalWaiting(); // break from signal waiting.
gatedClock 39:4e7e4d935a87 245
gatedClock 54:b0e7352d2516 246 void threadButtonStateManager(void const *args);
gatedClock 50:2928c3cbdcc3 247 void threadTotalTimeControl(void const *args);
gatedClock 57:0432c68ad232 248 void threadCookStateFSM(void const *args);
gatedClock 71:4a5f256ecf7c 249 void tickCookRemainingTime(); // remaining time countdown.
gatedClock 50:2928c3cbdcc3 250
gatedClock 40:7afff79f0d8b 251 void temperatureThread(void const *args); // temperature measurement.
gatedClock 42:266d5bbbfd19 252 void LCDthread (void const *args); // LCD display thread.
gatedClock 103:c5e24ac35a25 253
gatedClock 101:33dc62b6b728 254 void tickerBeeper(); // beep oscillator.
gatedClock 117:b9e18163c282 255 void tickerMagnetron(); // blink magnetron LED.
gatedClock 117:b9e18163c282 256 void tickerCarousel(); // blink carousel LED.
gatedClock 0:fcca4db7b32a 257 //==============================================//==============================
gatedClock 0:fcca4db7b32a 258 int main(void)
gatedClock 0:fcca4db7b32a 259 {
gatedClock 16:db7f0b3b2605 260
gatedClock 112:465958b0e94e 261 initialization(); // initialize variables.
gatedClock 112:465958b0e94e 262
gatedClock 112:465958b0e94e 263 // ISR setup.
gatedClock 14:d3bb343cd5b2 264 iJoyStickLeft.rise (&ISRleftButtonRising);
gatedClock 14:d3bb343cd5b2 265 iJoyStickLeft.fall (&ISRleftButtonFalling);
gatedClock 9:cfdb9aa5857c 266
gatedClock 14:d3bb343cd5b2 267 iJoyStickRight.rise(&ISRrightButtonRising);
gatedClock 14:d3bb343cd5b2 268 iJoyStickRight.fall(&ISRrightButtonFalling);
gatedClock 14:d3bb343cd5b2 269
gatedClock 14:d3bb343cd5b2 270 iJoyStickUp.rise (&ISRtopButtonRising);
gatedClock 14:d3bb343cd5b2 271 iJoyStickUp.fall (&ISRtopButtonFalling);
gatedClock 9:cfdb9aa5857c 272
gatedClock 14:d3bb343cd5b2 273 iJoyStickDown.rise (&ISRbottomButtonRising);
gatedClock 14:d3bb343cd5b2 274 iJoyStickDown.fall (&ISRbottomButtonFalling);
gatedClock 7:9fbd1d540863 275
gatedClock 14:d3bb343cd5b2 276 iJoyStickCenter.rise(&ISRcenterButtonRising);
gatedClock 14:d3bb343cd5b2 277 iJoyStickCenter.fall(&ISRcenterButtonFalling);
gatedClock 9:cfdb9aa5857c 278
gatedClock 66:4a0006fa5cc1 279 debounceTimer.start(); // kick-off debounce timer.
gatedClock 66:4a0006fa5cc1 280
gatedClock 102:5735d9cbad00 281
gatedClock 112:465958b0e94e 282 // kick-off tickers.
gatedClock 112:465958b0e94e 283 tickerCookCountdown.attach_us(&tickCookRemainingTime,1000000/GRANULARITY);
gatedClock 112:465958b0e94e 284 tickerBeep.attach_us (&tickerBeeper ,2000);
gatedClock 117:b9e18163c282 285 tickerBlinkMagnetron.attach_us(&tickerMagnetron,250000);
gatedClock 117:b9e18163c282 286 tickerBlinkCarousel.attach_us(&tickerCarousel,250000);
gatedClock 64:255295f1d782 287
gatedClock 112:465958b0e94e 288 // kick-off threads.
gatedClock 124:55c83dbeba2c 289 Thread thread_1(temperatureThread ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 123:c8ea8f59455b 290 Thread thread_2(LCDthread ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 124:55c83dbeba2c 291 Thread thread_3(threadTotalTimeControl ,NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 123:c8ea8f59455b 292 Thread thread_4(threadButtonStateManager,NULL,osPriorityNormal,DEFAULT_STACK_SIZE,NULL);
gatedClock 124:55c83dbeba2c 293 Thread thread_5(threadCookStateFSM ,NULL,osPriorityHigh,DEFAULT_STACK_SIZE,NULL);
gatedClock 70:7c0743c28b11 294
gatedClock 52:8ba6a0c91a89 295
gatedClock 112:465958b0e94e 296 while(1) Thread::wait(10000); // execute microwave controller.
gatedClock 19:92b11e30aaaf 297 }
gatedClock 19:92b11e30aaaf 298 /*----------------------------------------------//----------------------------*/
gatedClock 59:5e45b5e4a874 299
gatedClock 59:5e45b5e4a874 300 // this serves as the bottom-half for all of the button-press IRSs.
gatedClock 59:5e45b5e4a874 301 // it sends button-status messages to other threads, and it also
gatedClock 59:5e45b5e4a874 302 // clears the button-state globals to prepare them for the next
gatedClock 59:5e45b5e4a874 303 // button press.
gatedClock 59:5e45b5e4a874 304
gatedClock 59:5e45b5e4a874 305
gatedClock 54:b0e7352d2516 306 void threadButtonStateManager(void const *args)
gatedClock 50:2928c3cbdcc3 307 {
gatedClock 56:18cff6eb91db 308 int dMessage; // message.
gatedClock 50:2928c3cbdcc3 309
gatedClock 54:b0e7352d2516 310 while(1) // thread loop.
gatedClock 67:1d9c85a4c3c1 311 {
gatedClock 54:b0e7352d2516 312 //--- // TOTAL TIME CONTROL.
gatedClock 56:18cff6eb91db 313
gatedClock 56:18cff6eb91db 314 // encoded integers will be sent,
gatedClock 56:18cff6eb91db 315 // not pointers.
gatedClock 50:2928c3cbdcc3 316
gatedClock 108:da479434bd7d 317 if (giButtons.cLeftButton) // total time increment button.
gatedClock 50:2928c3cbdcc3 318 {
gatedClock 54:b0e7352d2516 319 dMessage = MSG_INC_TIME; // set message.
gatedClock 120:64a969984af2 320 queueModTotalTime.put((int *) dMessage,1);
gatedClock 108:da479434bd7d 321 giButtons.cLeftButton = 0; // clear the button state.
gatedClock 50:2928c3cbdcc3 322 }
gatedClock 67:1d9c85a4c3c1 323
gatedClock 108:da479434bd7d 324 if (giButtons.cRightButton) // total time decrement button.
gatedClock 50:2928c3cbdcc3 325 {
gatedClock 54:b0e7352d2516 326 dMessage = MSG_DEC_TIME; // set message.
gatedClock 120:64a969984af2 327 queueModTotalTime.put((int *) dMessage,1);
gatedClock 108:da479434bd7d 328 giButtons.cRightButton = 0; // clear the button state.
gatedClock 50:2928c3cbdcc3 329 }
gatedClock 67:1d9c85a4c3c1 330
gatedClock 59:5e45b5e4a874 331 //--- // COOK-STATE FSM.
gatedClock 59:5e45b5e4a874 332
gatedClock 108:da479434bd7d 333 if (giButtons.cTopButton) // start-cook button.
gatedClock 58:ec630b6dd9b1 334 {
gatedClock 59:5e45b5e4a874 335 dMessage = MSG_START; // set message.
gatedClock 120:64a969984af2 336 queueUpdateFSM.put((int *) dMessage,1);
gatedClock 108:da479434bd7d 337 giButtons.cTopButton = 0; // clear the button state.
gatedClock 58:ec630b6dd9b1 338 }
gatedClock 67:1d9c85a4c3c1 339
gatedClock 108:da479434bd7d 340 if (giButtons.cBottomButton) // stop-cook button.
gatedClock 58:ec630b6dd9b1 341 {
gatedClock 59:5e45b5e4a874 342 dMessage = MSG_STOP; // set message.
gatedClock 120:64a969984af2 343 queueUpdateFSM.put((int *) dMessage,1);
gatedClock 108:da479434bd7d 344 giButtons.cBottomButton = 0; // clear the button state.
gatedClock 58:ec630b6dd9b1 345 }
gatedClock 67:1d9c85a4c3c1 346
gatedClock 108:da479434bd7d 347 if (giButtons.cCenterButton) // door-state-toggle.
gatedClock 58:ec630b6dd9b1 348 {
gatedClock 108:da479434bd7d 349 dMessage = giButtons.cDoorOpen; // determined in ISR.
gatedClock 120:64a969984af2 350 queueUpdateFSM.put((int *) dMessage,1);
gatedClock 108:da479434bd7d 351 giButtons.cCenterButton = 0; // clear the button state.
gatedClock 58:ec630b6dd9b1 352 }
gatedClock 59:5e45b5e4a874 353 //---
gatedClock 58:ec630b6dd9b1 354
gatedClock 54:b0e7352d2516 355 Thread::wait(THREAD_4_WAITmS); // multitasking.
gatedClock 54:b0e7352d2516 356 } // thread loop.
gatedClock 54:b0e7352d2516 357 } // threadButtonStateManager.
gatedClock 50:2928c3cbdcc3 358 /*----------------------------------------------//----------------------------*/
gatedClock 51:e5ec74c49b01 359 // total time controller.
gatedClock 51:e5ec74c49b01 360 void threadTotalTimeControl(void const *args)
gatedClock 50:2928c3cbdcc3 361 {
gatedClock 51:e5ec74c49b01 362 static int dTotalTime = 0; // total time variable.
gatedClock 60:e10bf95bbc96 363 int dMessage; // message.
gatedClock 97:ee840478d6b3 364 int dSuppress; // 1 to suppress operation.
gatedClock 51:e5ec74c49b01 365 osEvent queueEvent; // queue event.
gatedClock 115:6390d9b9be07 366
gatedClock 97:ee840478d6b3 367 dSuppress = 0; // initialize.
gatedClock 97:ee840478d6b3 368
gatedClock 50:2928c3cbdcc3 369 while(1) // thread loop.
gatedClock 50:2928c3cbdcc3 370 {
gatedClock 98:156298be5ba2 371 // if FSM tells this to clear
gatedClock 98:156298be5ba2 372 // the total time.
gatedClock 98:156298be5ba2 373 queueEvent = queueClearTotalTime.get(1);
gatedClock 98:156298be5ba2 374 if (queueEvent.status == osEventMessage)
gatedClock 98:156298be5ba2 375 {
gatedClock 98:156298be5ba2 376 dTotalTime = 0;
gatedClock 115:6390d9b9be07 377 queueSetRemainingTime.put((int *) dTotalTime,1);
gatedClock 98:156298be5ba2 378 giRemainingTime.dTotalTime = dTotalTime;
gatedClock 98:156298be5ba2 379 }
gatedClock 98:156298be5ba2 380
gatedClock 97:ee840478d6b3 381
gatedClock 97:ee840478d6b3 382 // suppression mail from FSM.
gatedClock 97:ee840478d6b3 383 queueEvent = queueSuppressTimeAdjust.get(1);
gatedClock 97:ee840478d6b3 384 if (queueEvent.status == osEventMessage)
gatedClock 97:ee840478d6b3 385 {
gatedClock 97:ee840478d6b3 386 dSuppress = (int) queueEvent.value.p;
gatedClock 97:ee840478d6b3 387 }
gatedClock 97:ee840478d6b3 388
gatedClock 113:8111b9cd15ce 389
gatedClock 55:17f3354da63a 390 queueEvent = queueModTotalTime.get(1); // get message.
gatedClock 51:e5ec74c49b01 391 if (queueEvent.status == osEventMessage)
gatedClock 51:e5ec74c49b01 392 {
gatedClock 56:18cff6eb91db 393 dMessage = (int) queueEvent.value.p; // interpret as integer, not pointer.
gatedClock 54:b0e7352d2516 394
gatedClock 97:ee840478d6b3 395 if (!dSuppress) // increment total time.
gatedClock 99:a3e8344024c0 396 if (dMessage == MSG_INC_TIME) dTotalTime += TIMEINC;
gatedClock 54:b0e7352d2516 397
gatedClock 97:ee840478d6b3 398 if (!dSuppress) // decrement total time.
gatedClock 99:a3e8344024c0 399 if (dMessage == MSG_DEC_TIME) dTotalTime -= TIMEINC;
gatedClock 65:e39360da5929 400
gatedClock 65:e39360da5929 401 // saturations.
gatedClock 65:e39360da5929 402 if (dTotalTime > 180) dTotalTime = 180;
gatedClock 65:e39360da5929 403 if (dTotalTime < 0) dTotalTime = 0;
gatedClock 65:e39360da5929 404
gatedClock 115:6390d9b9be07 405 queueSetRemainingTime.put((int *) dTotalTime,1);
gatedClock 75:c2894d531f42 406 giRemainingTime.dTotalTime = dTotalTime;
gatedClock 51:e5ec74c49b01 407 }
gatedClock 97:ee840478d6b3 408
gatedClock 81:12bc26973cb8 409
gatedClock 50:2928c3cbdcc3 410 Thread::wait(THREAD_3_WAITmS); // multitasking.
gatedClock 50:2928c3cbdcc3 411 } // thread loop.
gatedClock 50:2928c3cbdcc3 412 } // threadTotalTimeControl.
gatedClock 33:34c1bef3c4ff 413 /*----------------------------------------------//----------------------------*/
gatedClock 57:0432c68ad232 414 void threadCookStateFSM(void const *args) // cook-cycle FSM.
gatedClock 57:0432c68ad232 415 {
gatedClock 113:8111b9cd15ce 416 int dFSMstate = FSM_IDLE; // state of this FSM.
gatedClock 113:8111b9cd15ce 417 int dFSMstateLast = FSM_IDLE; // previous FSM state.
gatedClock 113:8111b9cd15ce 418 int dButtonState = 0; // received button state.
gatedClock 113:8111b9cd15ce 419 int dRemainingTime = 0; // received remaining time.
gatedClock 62:48e7c196e2a5 420
gatedClock 113:8111b9cd15ce 421 int dButtonStart = 0; // received button state.
gatedClock 113:8111b9cd15ce 422 int dButtonStop = 0; // received button state.
gatedClock 113:8111b9cd15ce 423 int dDoorOpen = 0; // received door state.
gatedClock 113:8111b9cd15ce 424
gatedClock 81:12bc26973cb8 425 osEvent queueEvent; // from button state manager.
gatedClock 113:8111b9cd15ce 426
gatedClock 89:290c96cd027f 427 beepTimer.start(); // run the beep timer.
gatedClock 106:5137c38345d3 428
gatedClock 113:8111b9cd15ce 429 // constantly read live temperature.
gatedClock 94:551b1df4b10c 430 queueTemperatureControl.put((int *) TEMP_READ,1);
gatedClock 94:551b1df4b10c 431
gatedClock 57:0432c68ad232 432 while(1) // thread loop.
gatedClock 57:0432c68ad232 433 {
gatedClock 113:8111b9cd15ce 434
gatedClock 74:4debb8f2e21d 435 switch (dFSMstate) // cook-mode state machine.
gatedClock 62:48e7c196e2a5 436 {
gatedClock 82:73fa3fe8a217 437 //---
gatedClock 73:44739860198b 438 case FSM_IDLE : // IDLE.
gatedClock 73:44739860198b 439 {
gatedClock 124:55c83dbeba2c 440 led2 = 0; // magnetron OFF.
gatedClock 124:55c83dbeba2c 441 led3 = 0; // carousel OFF.
gatedClock 124:55c83dbeba2c 442 giMagnetron.cMagnetron = 0; // ennunciator.
gatedClock 124:55c83dbeba2c 443 giMagnetron.cCarousel = 0; // ennunciator.
gatedClock 119:e14b0f6e97cb 444
gatedClock 75:c2894d531f42 445 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 114:fbe9ef1630c1 446 {
gatedClock 114:fbe9ef1630c1 447 // live read of temperature,
gatedClock 114:fbe9ef1630c1 448 // allow total time adjustments,
gatedClock 114:fbe9ef1630c1 449 // clear total time.
gatedClock 114:fbe9ef1630c1 450
gatedClock 94:551b1df4b10c 451 queueTemperatureControl.put((int *) TEMP_READ,1);
gatedClock 97:ee840478d6b3 452 queueSuppressTimeAdjust.put((int*) 0,1);
gatedClock 98:156298be5ba2 453 queueClearTotalTime.put ((int*) 1,1);
gatedClock 75:c2894d531f42 454 }
gatedClock 80:e3e1a2161435 455
gatedClock 119:e14b0f6e97cb 456
gatedClock 119:e14b0f6e97cb 457
gatedClock 114:fbe9ef1630c1 458 // set global LCD data.
gatedClock 80:e3e1a2161435 459 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 460 giLCD.dRemainingTime = 0; // suppress remaining time display.
gatedClock 114:fbe9ef1630c1 461
gatedClock 114:fbe9ef1630c1 462 // remaining time loaded with total time.
gatedClock 121:c9d28cd59460 463 mutexControl.lock();
gatedClock 121:c9d28cd59460 464 giRemainingTime.cControl = RT_PRELOAD;
gatedClock 121:c9d28cd59460 465 mutexControl.unlock();
gatedClock 76:74c454c9d75b 466 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 114:fbe9ef1630c1 467
gatedClock 114:fbe9ef1630c1 468 // to FSM_COOK if the start button was
gatedClock 114:fbe9ef1630c1 469 // pressed, the door is closed, and the
gatedClock 114:fbe9ef1630c1 470 // remaining time is more than zero.
gatedClock 114:fbe9ef1630c1 471
gatedClock 75:c2894d531f42 472 if ((dButtonStart == 1) && (dDoorOpen == 0) && (giRemainingTime.dTotalTime > 0)) dFSMstate = FSM_COOK;
gatedClock 73:44739860198b 473 break;
gatedClock 73:44739860198b 474 }
gatedClock 82:73fa3fe8a217 475 //---
gatedClock 73:44739860198b 476 case FSM_COOK : // COOK.
gatedClock 73:44739860198b 477 {
gatedClock 124:55c83dbeba2c 478 led2 = 1; // magnetron ON.
gatedClock 124:55c83dbeba2c 479 led3 = 1; // carousel ON.
gatedClock 124:55c83dbeba2c 480 giMagnetron.cMagnetron = 1; // ennunciator.
gatedClock 124:55c83dbeba2c 481 giMagnetron.cCarousel = 1; // ennunciator.
gatedClock 119:e14b0f6e97cb 482
gatedClock 75:c2894d531f42 483 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 75:c2894d531f42 484 {
gatedClock 119:e14b0f6e97cb 485
gatedClock 119:e14b0f6e97cb 486
gatedClock 114:fbe9ef1630c1 487 // start decrementing remaining time.
gatedClock 114:fbe9ef1630c1 488 // temperature synthesizer is now
gatedClock 114:fbe9ef1630c1 489 // calculating the temperature,
gatedClock 114:fbe9ef1630c1 490 // user can no longer adjust total time.
gatedClock 121:c9d28cd59460 491 mutexControl.lock();
gatedClock 75:c2894d531f42 492 giRemainingTime.cControl = RT_DECREMENT;
gatedClock 121:c9d28cd59460 493 mutexControl.unlock();
gatedClock 94:551b1df4b10c 494 queueTemperatureControl.put((int *) TEMP_CALC,1);
gatedClock 97:ee840478d6b3 495 queueSuppressTimeAdjust.put((int*) 1,1);
gatedClock 75:c2894d531f42 496 }
gatedClock 80:e3e1a2161435 497
gatedClock 114:fbe9ef1630c1 498 // update global LCD data.
gatedClock 80:e3e1a2161435 499 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 500 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 114:fbe9ef1630c1 501
gatedClock 80:e3e1a2161435 502
gatedClock 80:e3e1a2161435 503
gatedClock 76:74c454c9d75b 504
gatedClock 76:74c454c9d75b 505 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 114:fbe9ef1630c1 506
gatedClock 114:fbe9ef1630c1 507 // pause on door-open if remaining time.
gatedClock 114:fbe9ef1630c1 508
gatedClock 78:7df160e0db7b 509 if ((dDoorOpen == 1) && (dRemainingTime > 0)) dFSMstate = FSM_PAUSE;
gatedClock 78:7df160e0db7b 510 else
gatedClock 114:fbe9ef1630c1 511
gatedClock 114:fbe9ef1630c1 512 // stop button -> idle state.
gatedClock 76:74c454c9d75b 513 if (dButtonStop) dFSMstate = FSM_IDLE;
gatedClock 78:7df160e0db7b 514 else
gatedClock 114:fbe9ef1630c1 515
gatedClock 114:fbe9ef1630c1 516 // beeper state once countdown complete.
gatedClock 78:7df160e0db7b 517 if (dRemainingTime <= 0) dFSMstate = FSM_DONE;
gatedClock 73:44739860198b 518 break;
gatedClock 73:44739860198b 519 }
gatedClock 82:73fa3fe8a217 520 //---
gatedClock 73:44739860198b 521 case FSM_PAUSE : // PAUSE.
gatedClock 73:44739860198b 522 {
gatedClock 124:55c83dbeba2c 523 led2 = 0; // magnetron OFF.
gatedClock 124:55c83dbeba2c 524 led3 = 0; // carousel OFF.
gatedClock 124:55c83dbeba2c 525 giMagnetron.cMagnetron = 0; // ennunciator.
gatedClock 124:55c83dbeba2c 526 giMagnetron.cCarousel = 0; // ennunciator.
gatedClock 75:c2894d531f42 527
gatedClock 75:c2894d531f42 528 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 75:c2894d531f42 529 {
gatedClock 114:fbe9ef1630c1 530 // suspend synthesized temperature calculation.
gatedClock 97:ee840478d6b3 531 queueTemperatureControl.put((int *) TEMP_FREEZE,1);
gatedClock 75:c2894d531f42 532 }
gatedClock 80:e3e1a2161435 533
gatedClock 114:fbe9ef1630c1 534 // update LCD globals.
gatedClock 80:e3e1a2161435 535 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 536 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 80:e3e1a2161435 537
gatedClock 80:e3e1a2161435 538
gatedClock 121:c9d28cd59460 539 mutexControl.lock();
gatedClock 114:fbe9ef1630c1 540 giRemainingTime.cControl = RT_PAUSE;// pause remaining time countdown.
gatedClock 121:c9d28cd59460 541 mutexControl.unlock();
gatedClock 114:fbe9ef1630c1 542
gatedClock 114:fbe9ef1630c1 543 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 114:fbe9ef1630c1 544
gatedClock 114:fbe9ef1630c1 545
gatedClock 114:fbe9ef1630c1 546 // continue if user hits start button,
gatedClock 114:fbe9ef1630c1 547 // and the door is closed, and there
gatedClock 114:fbe9ef1630c1 548 // is some remaining time.
gatedClock 114:fbe9ef1630c1 549
gatedClock 78:7df160e0db7b 550 if ((dButtonStart == 1) && (dDoorOpen == 0) && (giRemainingTime.dTotalTime > 0)) dFSMstate = FSM_CONTINUE;
gatedClock 75:c2894d531f42 551 else
gatedClock 114:fbe9ef1630c1 552
gatedClock 114:fbe9ef1630c1 553 // to idle if user hits stop button.
gatedClock 78:7df160e0db7b 554 if (dButtonStop) dFSMstate = FSM_IDLE;
gatedClock 73:44739860198b 555 break;
gatedClock 73:44739860198b 556 }
gatedClock 78:7df160e0db7b 557
gatedClock 82:73fa3fe8a217 558 //---
gatedClock 79:4286319e48b4 559 case FSM_CONTINUE : // CONTINUE.
gatedClock 78:7df160e0db7b 560 {
gatedClock 124:55c83dbeba2c 561 led2 = 1; // magnetron ON.
gatedClock 124:55c83dbeba2c 562 led3 = 1; // carousel ON.
gatedClock 124:55c83dbeba2c 563 giMagnetron.cMagnetron = 1; // ennunciator.
gatedClock 124:55c83dbeba2c 564 giMagnetron.cCarousel = 1; // ennunciator.
gatedClock 78:7df160e0db7b 565
gatedClock 78:7df160e0db7b 566 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 78:7df160e0db7b 567 {
gatedClock 114:fbe9ef1630c1 568 // continue calculating synthetic temperature.
gatedClock 97:ee840478d6b3 569 queueTemperatureControl.put((int *) TEMP_CALC,1);
gatedClock 78:7df160e0db7b 570 }
gatedClock 80:e3e1a2161435 571
gatedClock 114:fbe9ef1630c1 572 // update LCD globals.
gatedClock 80:e3e1a2161435 573 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 574 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 114:fbe9ef1630c1 575
gatedClock 80:e3e1a2161435 576
gatedClock 114:fbe9ef1630c1 577 // continue decrementing time.
gatedClock 121:c9d28cd59460 578 mutexControl.lock();
gatedClock 78:7df160e0db7b 579 giRemainingTime.cControl = RT_DECREMENT;
gatedClock 121:c9d28cd59460 580 mutexControl.unlock();
gatedClock 114:fbe9ef1630c1 581
gatedClock 114:fbe9ef1630c1 582 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 114:fbe9ef1630c1 583
gatedClock 114:fbe9ef1630c1 584 // beep state when no more time.
gatedClock 114:fbe9ef1630c1 585
gatedClock 78:7df160e0db7b 586 if (dRemainingTime <= 0) dFSMstate = FSM_DONE;
gatedClock 78:7df160e0db7b 587 else
gatedClock 114:fbe9ef1630c1 588 // user stop causes jump to idle.
gatedClock 78:7df160e0db7b 589 if (dButtonStop) dFSMstate = FSM_IDLE;
gatedClock 79:4286319e48b4 590 else
gatedClock 114:fbe9ef1630c1 591 // back to pause if door open,
gatedClock 114:fbe9ef1630c1 592 // and there's remaining time.
gatedClock 79:4286319e48b4 593 if ((dDoorOpen == 1) && (dRemainingTime > 0)) dFSMstate = FSM_PAUSE;
gatedClock 78:7df160e0db7b 594 break;
gatedClock 78:7df160e0db7b 595 }
gatedClock 78:7df160e0db7b 596
gatedClock 78:7df160e0db7b 597
gatedClock 82:73fa3fe8a217 598 //---
gatedClock 73:44739860198b 599 case FSM_DONE : // DONE.
gatedClock 73:44739860198b 600 {
gatedClock 124:55c83dbeba2c 601 led2 = 0; // magnetron OFF.
gatedClock 124:55c83dbeba2c 602 led3 = 0; // carousel OFF.
gatedClock 124:55c83dbeba2c 603 giMagnetron.cMagnetron = 0; // ennunciator.
gatedClock 124:55c83dbeba2c 604 giMagnetron.cCarousel = 0; // ennunciator.
gatedClock 119:e14b0f6e97cb 605
gatedClock 75:c2894d531f42 606 if (dFSMstate != dFSMstateLast) // if just entered state.
gatedClock 75:c2894d531f42 607 {
gatedClock 114:fbe9ef1630c1 608 // freeze synthetic temperature.
gatedClock 97:ee840478d6b3 609 queueTemperatureControl.put((int *) TEMP_FREEZE,1);
gatedClock 114:fbe9ef1630c1 610 giRemainingTime.cBeepEnable = 1; // initiate beep.
gatedClock 89:290c96cd027f 611 beepTimer.reset(); // clear the beep timer.
gatedClock 75:c2894d531f42 612 }
gatedClock 80:e3e1a2161435 613
gatedClock 114:fbe9ef1630c1 614 // update LCD globals.
gatedClock 80:e3e1a2161435 615 giLCD.dTotalCookTime = giRemainingTime.dTotalTime;
gatedClock 80:e3e1a2161435 616 giLCD.dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 121:c9d28cd59460 617
gatedClock 121:c9d28cd59460 618 mutexControl.lock();
gatedClock 114:fbe9ef1630c1 619 giRemainingTime.cControl = RT_CLEAR;// clear remaining time. (needed?)
gatedClock 121:c9d28cd59460 620 mutexControl.unlock();
gatedClock 114:fbe9ef1630c1 621
gatedClock 114:fbe9ef1630c1 622 dFSMstateLast = dFSMstate; // determine next state.
gatedClock 80:e3e1a2161435 623
gatedClock 114:fbe9ef1630c1 624 // to idle once beeper is done.
gatedClock 110:a3b95ccfaed6 625 if (beepTimer.read() >= BEEPTIME) {dFSMstate = FSM_IDLE; giRemainingTime.cBeepEnable = 0;}
gatedClock 114:fbe9ef1630c1 626 else dFSMstate = FSM_DONE; // (else stay here).
gatedClock 73:44739860198b 627 break;
gatedClock 73:44739860198b 628 }
gatedClock 82:73fa3fe8a217 629 //---
gatedClock 73:44739860198b 630 default : {dFSMstate = FSM_IDLE; break;}
gatedClock 73:44739860198b 631
gatedClock 62:48e7c196e2a5 632 }
gatedClock 73:44739860198b 633
gatedClock 63:63f362bcc2ac 634
gatedClock 75:c2894d531f42 635
gatedClock 75:c2894d531f42 636 queueEvent = queueUpdateFSM.get(1); // threadButtonStateManager
gatedClock 60:e10bf95bbc96 637 if (queueEvent.status == osEventMessage)// update state variable.
gatedClock 60:e10bf95bbc96 638 {
gatedClock 61:8026a9fc0cf1 639 // interpret as integer, not pointer.
gatedClock 61:8026a9fc0cf1 640 dButtonState = (int) queueEvent.value.p;
gatedClock 63:63f362bcc2ac 641
gatedClock 63:63f362bcc2ac 642 if (dButtonState == MSG_START)
gatedClock 63:63f362bcc2ac 643 {
gatedClock 114:fbe9ef1630c1 644 dButtonStart = 1; // copy-in start info.
gatedClock 63:63f362bcc2ac 645 dButtonStop = 0;
gatedClock 114:fbe9ef1630c1 646 if (dDoorOpen) dButtonStart = 0; // cancel start if door open.
gatedClock 63:63f362bcc2ac 647 }
gatedClock 63:63f362bcc2ac 648 if (dButtonState == MSG_STOP)
gatedClock 63:63f362bcc2ac 649 {
gatedClock 114:fbe9ef1630c1 650 dButtonStart = 0; // copy-in stop state.
gatedClock 63:63f362bcc2ac 651 dButtonStop = 1;
gatedClock 114:fbe9ef1630c1 652 queueClearTotalTime.put((int*) 1,1);// clear total time on stop.
gatedClock 63:63f362bcc2ac 653 }
gatedClock 63:63f362bcc2ac 654
gatedClock 114:fbe9ef1630c1 655 if (dButtonState == MSG_OPEN) // if the door opens, clear current 'start' state.
gatedClock 114:fbe9ef1630c1 656 {
gatedClock 79:4286319e48b4 657 dDoorOpen = 1;
gatedClock 79:4286319e48b4 658 dButtonStart = 0;
gatedClock 63:63f362bcc2ac 659 }
gatedClock 63:63f362bcc2ac 660
gatedClock 114:fbe9ef1630c1 661 if (dButtonState == MSG_CLOSED) // detect door closed.
gatedClock 63:63f362bcc2ac 662 {
gatedClock 63:63f362bcc2ac 663 dDoorOpen = 0;
gatedClock 63:63f362bcc2ac 664 }
gatedClock 63:63f362bcc2ac 665
gatedClock 61:8026a9fc0cf1 666 }
gatedClock 90:d9bb516141f1 667 else // no queue update available.
gatedClock 90:d9bb516141f1 668 {
gatedClock 90:d9bb516141f1 669 dButtonStart = 0;
gatedClock 90:d9bb516141f1 670 dButtonStop = 0;
gatedClock 90:d9bb516141f1 671 }
gatedClock 75:c2894d531f42 672
gatedClock 75:c2894d531f42 673 // fetch from global scope.
gatedClock 75:c2894d531f42 674 dRemainingTime = giRemainingTime.dRemainingTime;
gatedClock 69:55b836e8ced7 675
gatedClock 57:0432c68ad232 676 Thread::wait(THREAD_5_WAITmS); // multitasking.
gatedClock 57:0432c68ad232 677 } // thread loop.
gatedClock 57:0432c68ad232 678 } // threadCookStateFSM.
gatedClock 57:0432c68ad232 679 /*----------------------------------------------//----------------------------*/
gatedClock 0:fcca4db7b32a 680 void initialization(void) // program initializations.
gatedClock 0:fcca4db7b32a 681 {
gatedClock 124:55c83dbeba2c 682 led0 = 0;
gatedClock 112:465958b0e94e 683 led1 = 0;
gatedClock 124:55c83dbeba2c 684 led2 = 0;
gatedClock 124:55c83dbeba2c 685 led3 = 0;
gatedClock 112:465958b0e94e 686 giButtons.cDoorOpen = 0; // initialize with door closed.
gatedClock 112:465958b0e94e 687 giRemainingTime.cBeepEnable =0;
gatedClock 120:64a969984af2 688 giMagnetron.cMagnetron = 0;
gatedClock 120:64a969984af2 689 giMagnetron.cCarousel = 0;
gatedClock 0:fcca4db7b32a 690 }
gatedClock 0:fcca4db7b32a 691 /*----------------------------------------------//----------------------------*/
gatedClock 26:bff592483cb1 692 void ISRleftButtonRising(void) // cooktime plus 60s.
gatedClock 1:9188d4668a88 693 {
gatedClock 66:4a0006fa5cc1 694 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 108:da479434bd7d 695 giButtons.cLeftButton = 1; // detect left button.
gatedClock 9:cfdb9aa5857c 696
gatedClock 66:4a0006fa5cc1 697 debounceTimer.reset(); // begin debounce period.
gatedClock 11:9cae003da12b 698 }
gatedClock 1:9188d4668a88 699 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 700 void ISRleftButtonFalling(void) // button-release debounce.
gatedClock 1:9188d4668a88 701 {
gatedClock 66:4a0006fa5cc1 702 debounceTimer.reset(); // begin debounce period.
gatedClock 11:9cae003da12b 703 }
gatedClock 2:665ffa57031f 704 /*----------------------------------------------//----------------------------*/
gatedClock 26:bff592483cb1 705 void ISRrightButtonRising(void) // cooktime -60s.
gatedClock 12:e40272e1fd8f 706 {
gatedClock 66:4a0006fa5cc1 707 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 108:da479434bd7d 708 giButtons.cRightButton = 1; // detect right button.
gatedClock 12:e40272e1fd8f 709
gatedClock 66:4a0006fa5cc1 710 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 711 }
gatedClock 12:e40272e1fd8f 712 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 713 void ISRrightButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 714 {
gatedClock 66:4a0006fa5cc1 715 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 716 }
gatedClock 12:e40272e1fd8f 717 /*----------------------------------------------//----------------------------*/
gatedClock 26:bff592483cb1 718 void ISRtopButtonRising(void) // cook start.
gatedClock 12:e40272e1fd8f 719 {
gatedClock 66:4a0006fa5cc1 720 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 108:da479434bd7d 721 giButtons.cTopButton = 1; // detect top button.
gatedClock 12:e40272e1fd8f 722
gatedClock 66:4a0006fa5cc1 723 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 724 }
gatedClock 12:e40272e1fd8f 725 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 726 void ISRtopButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 727 {
gatedClock 66:4a0006fa5cc1 728 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 729 }
gatedClock 12:e40272e1fd8f 730 /*----------------------------------------------//----------------------------*/
gatedClock 53:8c2baf5623c8 731 // front-end control of magnetron off.
gatedClock 53:8c2baf5623c8 732 // due to physical danger, the magnetron is turned off immediately
gatedClock 53:8c2baf5623c8 733 // upon off-button press, in the interrupt that it generates.
gatedClock 53:8c2baf5623c8 734
gatedClock 26:bff592483cb1 735 void ISRbottomButtonRising(void) // cook stop.
gatedClock 12:e40272e1fd8f 736 {
gatedClock 66:4a0006fa5cc1 737 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 66:4a0006fa5cc1 738 {
gatedClock 124:55c83dbeba2c 739 led2 = 0; // magnetron off.
gatedClock 108:da479434bd7d 740 giButtons.cBottomButton = 1; // detect bottom button.
gatedClock 66:4a0006fa5cc1 741 }
gatedClock 66:4a0006fa5cc1 742 debounceTimer.reset(); // begin debounce period.
gatedClock 66:4a0006fa5cc1 743 }
gatedClock 12:e40272e1fd8f 744 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 745 void ISRbottomButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 746 {
gatedClock 66:4a0006fa5cc1 747 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 748 }
gatedClock 12:e40272e1fd8f 749 /*----------------------------------------------//----------------------------*/
gatedClock 53:8c2baf5623c8 750 // front-end control of magnetron off.
gatedClock 53:8c2baf5623c8 751 // due to physical danger, the magnetron is turned off immediately
gatedClock 53:8c2baf5623c8 752 // upon detection of an open door.
gatedClock 53:8c2baf5623c8 753
gatedClock 26:bff592483cb1 754 void ISRcenterButtonRising(void) // toggle door state.
gatedClock 12:e40272e1fd8f 755 {
gatedClock 66:4a0006fa5cc1 756 if (debounceTimer.read_ms() > DEBOUNCEmS)
gatedClock 66:4a0006fa5cc1 757 {
gatedClock 108:da479434bd7d 758 if (giButtons.cDoorOpen == MSG_OPEN) // calculate door state.
gatedClock 108:da479434bd7d 759 giButtons.cDoorOpen = MSG_CLOSED;
gatedClock 66:4a0006fa5cc1 760 else
gatedClock 108:da479434bd7d 761 giButtons.cDoorOpen = MSG_OPEN;
gatedClock 53:8c2baf5623c8 762
gatedClock 59:5e45b5e4a874 763 // magnetron off.
gatedClock 124:55c83dbeba2c 764 if (giButtons.cDoorOpen == MSG_OPEN) led2 = 0;
gatedClock 58:ec630b6dd9b1 765
gatedClock 108:da479434bd7d 766 giButtons.cCenterButton = 1;
gatedClock 66:4a0006fa5cc1 767 }
gatedClock 66:4a0006fa5cc1 768 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 769 }
gatedClock 12:e40272e1fd8f 770 /*----------------------------------------------//----------------------------*/
gatedClock 15:5eaa2ab1d00d 771 void ISRcenterButtonFalling(void) // button-release debounce.
gatedClock 12:e40272e1fd8f 772 {
gatedClock 66:4a0006fa5cc1 773 debounceTimer.reset(); // begin debounce period.
gatedClock 12:e40272e1fd8f 774 }
gatedClock 115:6390d9b9be07 775 /*----------------------------------------------//----------------------------*/
gatedClock 115:6390d9b9be07 776
gatedClock 115:6390d9b9be07 777 // this will measure live temperature, or calculate it to be
gatedClock 115:6390d9b9be07 778 // increasing at 1/6 degree per second, or freeze it.
gatedClock 115:6390d9b9be07 779
gatedClock 115:6390d9b9be07 780
gatedClock 40:7afff79f0d8b 781 void temperatureThread(void const *args) // temperature measurement.
gatedClock 39:4e7e4d935a87 782 {
gatedClock 94:551b1df4b10c 783 int dTempControl = 0; // temperature control.
gatedClock 115:6390d9b9be07 784 float fLastMeasuredTemperature = 0.0; // last physically-measured temperature.
gatedClock 115:6390d9b9be07 785 float fCelsius; // synthetic temperature.
gatedClock 94:551b1df4b10c 786 osEvent queueEvent; // from button state manager.
gatedClock 94:551b1df4b10c 787
gatedClock 45:e3207684e841 788 while(1) // thread loop.
gatedClock 45:e3207684e841 789 {
gatedClock 94:551b1df4b10c 790 // obtain temperature command.
gatedClock 94:551b1df4b10c 791 queueEvent = queueTemperatureControl.get(1);
gatedClock 94:551b1df4b10c 792 if (queueEvent.status == osEventMessage)
gatedClock 94:551b1df4b10c 793 {
gatedClock 94:551b1df4b10c 794 dTempControl = (int) queueEvent.value.p;
gatedClock 94:551b1df4b10c 795 }
gatedClock 94:551b1df4b10c 796
gatedClock 94:551b1df4b10c 797 if (dTempControl == TEMP_READ)
gatedClock 95:7e391a5951d1 798 {
gatedClock 107:7de171a8464e 799 fCelsius = temperature.read(); // physical measurement.
gatedClock 107:7de171a8464e 800 fLastMeasuredTemperature = fCelsius;
gatedClock 95:7e391a5951d1 801 }
gatedClock 94:551b1df4b10c 802
gatedClock 115:6390d9b9be07 803 if (dTempControl == TEMP_CALC) // calculate synthetic temperature.
gatedClock 115:6390d9b9be07 804 fCelsius = ((float) (giRemainingTime.dTotalTime - giRemainingTime.dRemainingTime) /
gatedClock 115:6390d9b9be07 805 (float) 6.0) + fLastMeasuredTemperature;
gatedClock 97:ee840478d6b3 806
gatedClock 115:6390d9b9be07 807 giLCD.fCelsius = fCelsius; // to global scope for LCD.
gatedClock 97:ee840478d6b3 808
gatedClock 45:e3207684e841 809 Thread::wait(THREAD_1_WAITmS); // multitasking.
gatedClock 45:e3207684e841 810 } // thread loop.
gatedClock 45:e3207684e841 811 } // temperatureThread.
gatedClock 42:266d5bbbfd19 812 /*----------------------------------------------//----------------------------*/
gatedClock 42:266d5bbbfd19 813 void LCDthread(void const *args) // LCD display thread.
gatedClock 42:266d5bbbfd19 814 {
gatedClock 67:1d9c85a4c3c1 815
gatedClock 67:1d9c85a4c3c1 816 static int dLCDtotalCookTimeSec = 0; // sample current values.
gatedClock 67:1d9c85a4c3c1 817 static int dCookTimeRemainingSec = 0;
gatedClock 67:1d9c85a4c3c1 818 static float fLCDcelsius = 0.0;
gatedClock 67:1d9c85a4c3c1 819
gatedClock 67:1d9c85a4c3c1 820 // remember previous values.
gatedClock 67:1d9c85a4c3c1 821 static int dLCDtotalCookTimeSecLast = 0;
gatedClock 67:1d9c85a4c3c1 822 static int dCookTimeRemainingSecLast = 0;
gatedClock 67:1d9c85a4c3c1 823 static float fLCDcelsiusLast = 0.0;
gatedClock 67:1d9c85a4c3c1 824
gatedClock 44:d16e813e61ef 825 while(1) // thread loop.
gatedClock 44:d16e813e61ef 826 {
gatedClock 67:1d9c85a4c3c1 827 // don't allow the values to
gatedClock 67:1d9c85a4c3c1 828 // change in the middle of the
gatedClock 67:1d9c85a4c3c1 829 // below else the anti-blink
gatedClock 67:1d9c85a4c3c1 830 // code won't work.
gatedClock 80:e3e1a2161435 831 dLCDtotalCookTimeSec = giLCD.dTotalCookTime;
gatedClock 80:e3e1a2161435 832 dCookTimeRemainingSec = giLCD.dRemainingTime;
gatedClock 80:e3e1a2161435 833 fLCDcelsius = giLCD.fCelsius;
gatedClock 116:15084f54baf9 834
gatedClock 67:1d9c85a4c3c1 835 // clear display only when
gatedClock 67:1d9c85a4c3c1 836 // necessary, in order to avoid
gatedClock 67:1d9c85a4c3c1 837 // 'blinkieness'.
gatedClock 67:1d9c85a4c3c1 838 if (dLCDtotalCookTimeSec != dLCDtotalCookTimeSecLast ||
gatedClock 67:1d9c85a4c3c1 839 dCookTimeRemainingSec != dCookTimeRemainingSecLast ||
gatedClock 67:1d9c85a4c3c1 840 fLCDcelsius != fLCDcelsiusLast)
gatedClock 67:1d9c85a4c3c1 841 lcd.cls();
gatedClock 42:266d5bbbfd19 842
gatedClock 44:d16e813e61ef 843 LCD1; // line 1.
gatedClock 67:1d9c85a4c3c1 844 lcd.printf(" total cook time: %d",dLCDtotalCookTimeSec);
gatedClock 42:266d5bbbfd19 845
gatedClock 44:d16e813e61ef 846 LCD2; // line 2.
gatedClock 67:1d9c85a4c3c1 847 lcd.printf(" remaing cook time: %d",dCookTimeRemainingSec);
gatedClock 42:266d5bbbfd19 848
gatedClock 44:d16e813e61ef 849 LCD3; // line 3.
gatedClock 67:1d9c85a4c3c1 850 lcd.printf(" temperature : %5.3f",fLCDcelsius);
gatedClock 67:1d9c85a4c3c1 851
gatedClock 67:1d9c85a4c3c1 852 // pipeline variables.
gatedClock 67:1d9c85a4c3c1 853 dLCDtotalCookTimeSecLast = dLCDtotalCookTimeSec;
gatedClock 67:1d9c85a4c3c1 854 dCookTimeRemainingSecLast = dCookTimeRemainingSec;
gatedClock 67:1d9c85a4c3c1 855 fLCDcelsiusLast = fLCDcelsius;
gatedClock 42:266d5bbbfd19 856
gatedClock 44:d16e813e61ef 857 Thread::wait(THREAD_2_WAITmS); // multitasking.
gatedClock 44:d16e813e61ef 858 } // thread loop.
gatedClock 44:d16e813e61ef 859 } // LCDthread.
gatedClock 42:266d5bbbfd19 860 /*----------------------------------------------//----------------------------*/
gatedClock 71:4a5f256ecf7c 861
gatedClock 88:0b1b812945eb 862 // cook remaining time countdown counter.
gatedClock 88:0b1b812945eb 863 // possibly due to a bug in Ticker
gatedClock 88:0b1b812945eb 864 // http://mbed.org/questions/1563/Mbed-Tickerfunction-hangs-system-from-re/
gatedClock 88:0b1b812945eb 865 // I've been unable to detach/attach this routine in order to reset its phase
gatedClock 88:0b1b812945eb 866 // when I tried it at a 1s resolution. In order to provide the human perception
gatedClock 88:0b1b812945eb 867 // of an immediate restart, I've increased the ticker frequency by the factor
gatedClock 88:0b1b812945eb 868 // 'GRANULARITY' and likewise divide that factor out when this routine
gatedClock 88:0b1b812945eb 869 // promotes the remaining time to the global variable.
gatedClock 88:0b1b812945eb 870
gatedClock 104:5e49dbe5038a 871 // communication is via a global instance of struct tRemainingTime.
gatedClock 104:5e49dbe5038a 872
gatedClock 71:4a5f256ecf7c 873 void tickCookRemainingTime(void) // cook-cycle countdown.
gatedClock 71:4a5f256ecf7c 874 {
gatedClock 71:4a5f256ecf7c 875 static int dRemainingTime = 0; // remaining time in seconds.
gatedClock 88:0b1b812945eb 876 int dMaximum; // MAXSECONDS * GRANULARITY.
gatedClock 121:c9d28cd59460 877 char cControl; // local copy.
gatedClock 88:0b1b812945eb 878
gatedClock 88:0b1b812945eb 879 dMaximum = MAXSECONDS * GRANULARITY; // precalculate.
gatedClock 75:c2894d531f42 880
gatedClock 121:c9d28cd59460 881 mutexControl.lock();
gatedClock 121:c9d28cd59460 882 cControl = giRemainingTime.cControl;
gatedClock 121:c9d28cd59460 883 mutexControl.unlock();
gatedClock 121:c9d28cd59460 884
gatedClock 121:c9d28cd59460 885 switch (cControl) // control processing.
gatedClock 71:4a5f256ecf7c 886 {
gatedClock 88:0b1b812945eb 887
gatedClock 72:b4d0c0aa3c26 888 case RT_PRELOAD : // preload with total time.
gatedClock 71:4a5f256ecf7c 889 {
gatedClock 88:0b1b812945eb 890 // the 'GRANULARITY - 1' factor
gatedClock 88:0b1b812945eb 891 // compensates for integer division
gatedClock 88:0b1b812945eb 892 // dropping the right-of-decimal result,
gatedClock 88:0b1b812945eb 893 // that occuring at the bottom of this
gatedClock 88:0b1b812945eb 894 // routine.
gatedClock 88:0b1b812945eb 895 dRemainingTime = (giRemainingTime.dTotalTime * GRANULARITY) + (GRANULARITY - 1);
gatedClock 71:4a5f256ecf7c 896 break;
gatedClock 71:4a5f256ecf7c 897 }
gatedClock 88:0b1b812945eb 898
gatedClock 72:b4d0c0aa3c26 899 case RT_DECREMENT : // count-down.
gatedClock 71:4a5f256ecf7c 900 {
gatedClock 72:b4d0c0aa3c26 901 dRemainingTime--;
gatedClock 71:4a5f256ecf7c 902 break;
gatedClock 71:4a5f256ecf7c 903 }
gatedClock 71:4a5f256ecf7c 904
gatedClock 72:b4d0c0aa3c26 905 case RT_PAUSE : // suspend countdown.
gatedClock 69:55b836e8ced7 906 {
gatedClock 72:b4d0c0aa3c26 907 dRemainingTime = dRemainingTime;
gatedClock 71:4a5f256ecf7c 908 break;
gatedClock 71:4a5f256ecf7c 909 }
gatedClock 71:4a5f256ecf7c 910
gatedClock 72:b4d0c0aa3c26 911 case RT_CLEAR : // clear countdown.
gatedClock 71:4a5f256ecf7c 912 {
gatedClock 100:fd7006aa3d05 913 dRemainingTime = 0;
gatedClock 71:4a5f256ecf7c 914 break;
gatedClock 71:4a5f256ecf7c 915 }
gatedClock 69:55b836e8ced7 916
gatedClock 72:b4d0c0aa3c26 917 default : // saturate, just in case.
gatedClock 72:b4d0c0aa3c26 918 {
gatedClock 72:b4d0c0aa3c26 919 }
gatedClock 75:c2894d531f42 920 } // control processing.
gatedClock 71:4a5f256ecf7c 921
gatedClock 88:0b1b812945eb 922 // saturate value.
gatedClock 88:0b1b812945eb 923 if (dRemainingTime > dMaximum) dRemainingTime = dMaximum;
gatedClock 88:0b1b812945eb 924 if (dRemainingTime < 0) dRemainingTime = 0;
gatedClock 88:0b1b812945eb 925
gatedClock 75:c2894d531f42 926 // promote to global scope.
gatedClock 86:388c2b4b7cf5 927 giRemainingTime.dRemainingTime = dRemainingTime/GRANULARITY;
gatedClock 70:7c0743c28b11 928
gatedClock 70:7c0743c28b11 929 } // cookRemainingTime.
gatedClock 69:55b836e8ced7 930 /*----------------------------------------------//----------------------------*/
gatedClock 117:b9e18163c282 931 void tickerBeeper(void) // beep when giRemainingTime.
gatedClock 92:be8d69aba1fc 932 {
gatedClock 101:33dc62b6b728 933 static char cState = 0;
gatedClock 110:a3b95ccfaed6 934 if (giRemainingTime.cBeepEnable)
gatedClock 101:33dc62b6b728 935 {
gatedClock 101:33dc62b6b728 936 if (cState) {speaker = 1; cState = 0;}
gatedClock 101:33dc62b6b728 937 else {speaker = 0; cState = 1;}
gatedClock 101:33dc62b6b728 938 }
gatedClock 101:33dc62b6b728 939 }
gatedClock 101:33dc62b6b728 940 /*----------------------------------------------//----------------------------*/
gatedClock 124:55c83dbeba2c 941 // this is not magnetron control.
gatedClock 118:d0e057d79acc 942 void tickerMagnetron(void) // magnetron enunciator.
gatedClock 117:b9e18163c282 943 {
gatedClock 120:64a969984af2 944 if (giMagnetron.cMagnetron) led0 = !led0;
gatedClock 118:d0e057d79acc 945 else led0 = 0;
gatedClock 117:b9e18163c282 946 }
gatedClock 69:55b836e8ced7 947
gatedClock 117:b9e18163c282 948 /*----------------------------------------------//----------------------------*/
gatedClock 124:55c83dbeba2c 949 // this is not carousel control.
gatedClock 118:d0e057d79acc 950 void tickerCarousel(void) // carousel enunciator.
gatedClock 117:b9e18163c282 951 {
gatedClock 120:64a969984af2 952 if (giMagnetron.cCarousel) led1 = !led1;
gatedClock 118:d0e057d79acc 953 else led1 = 0;
gatedClock 117:b9e18163c282 954 }
gatedClock 117:b9e18163c282 955 /*----------------------------------------------//----------------------------*/
gatedClock 117:b9e18163c282 956
gatedClock 117:b9e18163c282 957
gatedClock 117:b9e18163c282 958
gatedClock 117:b9e18163c282 959
gatedClock 117:b9e18163c282 960
gatedClock 117:b9e18163c282 961
gatedClock 117:b9e18163c282 962
gatedClock 117:b9e18163c282 963
gatedClock 117:b9e18163c282 964
gatedClock 117:b9e18163c282 965
gatedClock 117:b9e18163c282 966
gatedClock 117:b9e18163c282 967
gatedClock 117:b9e18163c282 968
gatedClock 117:b9e18163c282 969
gatedClock 117:b9e18163c282 970
gatedClock 117:b9e18163c282 971
gatedClock 117:b9e18163c282 972
gatedClock 117:b9e18163c282 973