homework 7

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

Committer:
gatedClock
Date:
Thu Sep 12 18:13:12 2013 +0000
Revision:
93:0e93e4a23f2b
Parent:
92:be8d69aba1fc
Child:
94:551b1df4b10c
beeps at end of cook cycle.

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