homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 22:42:56 2013 +0000
Revision:
120:64a969984af2
Parent:
119:e14b0f6e97cb
Child:
121:c9d28cd59460
introduce a magnetron struct.

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