homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 23:11:09 2013 +0000
Revision:
122:69e32460b543
Parent:
121:c9d28cd59460
buggy totalTime, back away from this.

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