homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 20:50:22 2013 +0000
Revision:
101:33dc62b6b728
Parent:
100:fd7006aa3d05
Child:
102:5735d9cbad00
switching to ticker beeper.

Who changed what in which revision?

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