homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 22:13:51 2013 +0000
Revision:
119:e14b0f6e97cb
Parent:
118:d0e057d79acc
Child:
120:64a969984af2
mag/car blinking ok.

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