homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

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