RTOS homework 4

Dependencies:   C12832_lcd mbed

Committer:
gatedClock
Date:
Sun Aug 18 19:02:25 2013 +0000
Revision:
14:fb4c76ac43a1
Parent:
13:d380d4ec3c5d
Child:
15:7c0a94d2a439
here I tried putting the ticker which times the display into its own thread and starting the thread, but still the display output is not seen.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gatedClock 0:1013288b8e43 1 /*----------------------------------------------//------------------------------
gatedClock 0:1013288b8e43 2 student : m-moore
gatedClock 0:1013288b8e43 3 class : rtos
gatedClock 1:5f41e2df0e85 4 directory : RTOS_HW_04
gatedClock 0:1013288b8e43 5 file : main.cpp
gatedClock 0:1013288b8e43 6 ----description---------------------------------//------------------------------
gatedClock 0:1013288b8e43 7 Joystick-Controlled Metronome
gatedClock 0:1013288b8e43 8
gatedClock 0:1013288b8e43 9 features:
gatedClock 0:1013288b8e43 10 1. post-initialization functionality all timer-driven.
gatedClock 0:1013288b8e43 11 2. IRSs contain no blocking functions.
gatedClock 0:1013288b8e43 12 3. LED shows the metronome beat.
gatedClock 0:1013288b8e43 13 4. metronome speed controlled with up/down joystick.
gatedClock 0:1013288b8e43 14 5. rate-of-speed-change depends on how long the up/down has been active.
gatedClock 0:1013288b8e43 15 6. Beat-Per-Minute (BPM) shown on LCD display.
gatedClock 0:1013288b8e43 16
gatedClock 0:1013288b8e43 17 controls:
gatedClock 0:1013288b8e43 18 1. joystick-up - increase metronome rate.
gatedClock 0:1013288b8e43 19 2. joystick-down - decrease metronome rate.
gatedClock 0:1013288b8e43 20 3. joystick-center - set metronome to 60BPM.
gatedClock 0:1013288b8e43 21
gatedClock 0:1013288b8e43 22 notes:
gatedClock 0:1013288b8e43 23
gatedClock 0:1013288b8e43 24 testing:
gatedClock 0:1013288b8e43 25 1. confirm ease of being able to adjust one BPM rate with joystick up/down.
gatedClock 0:1013288b8e43 26 2. confirm three joystick up/down change rates, if keeping the stick pressed.
gatedClock 0:1013288b8e43 27 3. confirm max/min BPS saturation & display.
gatedClock 0:1013288b8e43 28 4. confirm joystick up/down control works to change display & LED BPM.
gatedClock 0:1013288b8e43 29 5. confirm joystick center-press sets rate to 60BPM immediately.
gatedClock 0:1013288b8e43 30 6. confirm long-test does not result in a crash.
gatedClock 0:1013288b8e43 31 -> all items confirmed.
gatedClock 0:1013288b8e43 32
gatedClock 0:1013288b8e43 33 -----includes-----------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 34 #include "mbed.h" // mbed class.
gatedClock 14:fb4c76ac43a1 35 #include "C12832_lcd.h" // LCD class.
gatedClock 13:d380d4ec3c5d 36 #include "rtos.h"
gatedClock 0:1013288b8e43 37 //---defines------------------------------------//------------------------------
gatedClock 0:1013288b8e43 38 #define LCD1 lcd.locate(0, 0); // LCD line 1.
gatedClock 0:1013288b8e43 39 #define LCD2 lcd.locate(0,11); // LCD line 2.
gatedClock 0:1013288b8e43 40 #define LCD3 lcd.locate(0,22); // LCD line 3.
gatedClock 7:562f136c7681 41
gatedClock 0:1013288b8e43 42 #define METROMAX 800 // max. beats per minute.
gatedClock 0:1013288b8e43 43 #define METROMIN 8 // min. beats per minute.
gatedClock 0:1013288b8e43 44 #define UDSAMPLERATE 0.1 // how often to sample U/D joystick.
gatedClock 0:1013288b8e43 45 #define LCDSAMPLERATE 0.1 // how often to redraw the LCD.
gatedClock 0:1013288b8e43 46 #define PULSELENGTH 0.0625 // how long the LED-on-time is.
gatedClock 10:4f2fa66cc430 47 #define DEBOUNCE 0.16 // debounce pause duration in S.
gatedClock 0:1013288b8e43 48 //--global_definitions--------------------------//------------------------------
gatedClock 0:1013288b8e43 49 //--global_variables----------------------------//------------------------------
gatedClock 0:1013288b8e43 50 float fMetroDelay; // time between ticks, in seconds.
gatedClock 0:1013288b8e43 51 float fMetroDuty; // duration of metro high, in seconds.
gatedClock 0:1013288b8e43 52 int dMetroBPM; // master parameter.
gatedClock 0:1013288b8e43 53 long lUpDownHowMany; // count how long up/down joystick pressed.
gatedClock 12:fab8e658ae76 54 char cMetronomeOn; // 1 = allow blink.
gatedClock 0:1013288b8e43 55 //--global_instances----------------------------//------------------------------
gatedClock 0:1013288b8e43 56 C12832_LCD lcd; // LCD object.
gatedClock 0:1013288b8e43 57
gatedClock 7:562f136c7681 58 InterruptIn iJoyStickUp (p15); // joystick up rising edge.
gatedClock 7:562f136c7681 59 InterruptIn iJoyStickDown (p12); // joystick down rising edge.
gatedClock 7:562f136c7681 60 InterruptIn iJoyStickLeft (p13); // joystick left rising edge.
gatedClock 7:562f136c7681 61 InterruptIn iJoyStickRight (p16); // joystick right rising edge.
gatedClock 7:562f136c7681 62 InterruptIn iJoyStickCenter(p14); // 1 if joystick middle pressed.
gatedClock 3:8ff0c9c853be 63
gatedClock 8:95f4f470ae28 64 DigitalIn dJoyStickUp (p15); // joystick up sample.
gatedClock 8:95f4f470ae28 65 DigitalIn dJoyStickDown (p12); // joystick down sample.
gatedClock 8:95f4f470ae28 66 DigitalIn dJoyStickLeft (p13); // joystick left sample.
gatedClock 8:95f4f470ae28 67 DigitalIn dJoyStickRight (p16); // joystick right sample.
gatedClock 8:95f4f470ae28 68 DigitalIn dJoyStickCenter(p14); // joystick center sample.
gatedClock 0:1013288b8e43 69
gatedClock 0:1013288b8e43 70 DigitalOut led3(LED1); // leftmost LED.
gatedClock 0:1013288b8e43 71
gatedClock 0:1013288b8e43 72 Ticker tickerMetronome; // blinking LED.
gatedClock 0:1013288b8e43 73 Ticker tickerJoystickUD; // joystick up/down sample.
gatedClock 0:1013288b8e43 74 Ticker tickerLCD; // display ticker.
gatedClock 0:1013288b8e43 75 Timeout timeoutDutyCycle; // LED duty cycle delay.
gatedClock 12:fab8e658ae76 76 Timeout timeoutMetronome;
gatedClock 0:1013288b8e43 77 //-------prototypes-----------------------------//------------------------------
gatedClock 0:1013288b8e43 78 void initialization(); // initialize settings.
gatedClock 0:1013288b8e43 79 void lcd_display(); // display on LCD.
gatedClock 0:1013288b8e43 80 void interrupt_service_M(); // metronome tick.
gatedClock 0:1013288b8e43 81 void interrupt_service_UD(); // joystick up/down sample.
gatedClock 0:1013288b8e43 82 void led3_off(); // attachable LED control.
gatedClock 0:1013288b8e43 83 void led3_on(); // attachable LED control.
gatedClock 1:5f41e2df0e85 84 void ISR_up();
gatedClock 1:5f41e2df0e85 85 void ISR_down();
gatedClock 10:4f2fa66cc430 86 void ISR_right_rising();
gatedClock 10:4f2fa66cc430 87 void ISR_right_falling();
gatedClock 11:e764ed79553a 88 void ISR_left_rising();
gatedClock 11:e764ed79553a 89 void ISR_left_falling();
gatedClock 1:5f41e2df0e85 90 void ISR_center();
gatedClock 12:fab8e658ae76 91 void turn_off_metronome();
gatedClock 14:fb4c76ac43a1 92 void thread_start_display(void const *);
gatedClock 0:1013288b8e43 93 //==============================================//==============================
gatedClock 0:1013288b8e43 94 int main(void)
gatedClock 0:1013288b8e43 95 {
gatedClock 3:8ff0c9c853be 96 iJoyStickUp.rise(&ISR_up);
gatedClock 5:faa6d8a04501 97 iJoyStickDown.rise(&ISR_down);
gatedClock 11:e764ed79553a 98
gatedClock 11:e764ed79553a 99 iJoyStickLeft.rise(&ISR_left_rising);
gatedClock 11:e764ed79553a 100 iJoyStickLeft.fall(&ISR_left_falling);
gatedClock 10:4f2fa66cc430 101
gatedClock 10:4f2fa66cc430 102 iJoyStickRight.rise(&ISR_right_rising);
gatedClock 10:4f2fa66cc430 103 iJoyStickRight.fall(&ISR_right_falling);
gatedClock 10:4f2fa66cc430 104
gatedClock 5:faa6d8a04501 105 iJoyStickCenter.rise(&ISR_center);
gatedClock 6:bb5f989e3425 106
gatedClock 6:bb5f989e3425 107 initialization();
gatedClock 6:bb5f989e3425 108
gatedClock 6:bb5f989e3425 109 // metronome ticker.
gatedClock 14:fb4c76ac43a1 110 // tickerMetronome.attach(&interrupt_service_M,fMetroDelay);
gatedClock 6:bb5f989e3425 111
gatedClock 14:fb4c76ac43a1 112 Thread threadDisplay(thread_start_display);
gatedClock 14:fb4c76ac43a1 113
gatedClock 14:fb4c76ac43a1 114
gatedClock 6:bb5f989e3425 115
gatedClock 6:bb5f989e3425 116 while(1)
gatedClock 6:bb5f989e3425 117 {
gatedClock 6:bb5f989e3425 118
gatedClock 6:bb5f989e3425 119 wait(10.0);
gatedClock 6:bb5f989e3425 120 }
gatedClock 2:1a3acbc4d799 121
gatedClock 0:1013288b8e43 122 }
gatedClock 0:1013288b8e43 123 /*----------------------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 124 void initialization(void) // program initializations.
gatedClock 0:1013288b8e43 125 {
gatedClock 0:1013288b8e43 126 dMetroBPM = 60; // initialize to 60BPM.
gatedClock 0:1013288b8e43 127 fMetroDelay = 60.0 / (float) (dMetroBPM);
gatedClock 0:1013288b8e43 128 fMetroDuty = PULSELENGTH; // initialize LED on-duration.
gatedClock 0:1013288b8e43 129 lUpDownHowMany = 0;
gatedClock 12:fab8e658ae76 130 cMetronomeOn = 1;
gatedClock 0:1013288b8e43 131 }
gatedClock 0:1013288b8e43 132 /*----------------------------------------------//----------------------------*/
gatedClock 11:e764ed79553a 133 void ISR_left_rising(void) // increase BPM.
gatedClock 1:5f41e2df0e85 134 {
gatedClock 11:e764ed79553a 135 __disable_irq();
gatedClock 11:e764ed79553a 136
gatedClock 11:e764ed79553a 137 dMetroBPM++; // increase BPM.
gatedClock 11:e764ed79553a 138
gatedClock 12:fab8e658ae76 139 // saturate metronome BPM.
gatedClock 12:fab8e658ae76 140 if (dMetroBPM > METROMAX) dMetroBPM = METROMAX;
gatedClock 12:fab8e658ae76 141 if (dMetroBPM < METROMIN) dMetroBPM = METROMIN;
gatedClock 12:fab8e658ae76 142
gatedClock 11:e764ed79553a 143 wait(DEBOUNCE); // debounce time.
gatedClock 11:e764ed79553a 144
gatedClock 11:e764ed79553a 145 __enable_irq();
gatedClock 1:5f41e2df0e85 146 }
gatedClock 1:5f41e2df0e85 147 /*----------------------------------------------//----------------------------*/
gatedClock 11:e764ed79553a 148 void ISR_left_falling(void) // ignore rising after falling edge.
gatedClock 11:e764ed79553a 149 {
gatedClock 11:e764ed79553a 150 __disable_irq();
gatedClock 11:e764ed79553a 151
gatedClock 11:e764ed79553a 152 wait(DEBOUNCE); // debounce time.
gatedClock 11:e764ed79553a 153
gatedClock 11:e764ed79553a 154 __enable_irq();
gatedClock 11:e764ed79553a 155 }
gatedClock 11:e764ed79553a 156 /*----------------------------------------------//----------------------------*/
gatedClock 11:e764ed79553a 157
gatedClock 10:4f2fa66cc430 158 void ISR_right_rising(void) // decrease BPM.
gatedClock 4:67d958cc00e8 159 {
gatedClock 10:4f2fa66cc430 160 __disable_irq();
gatedClock 10:4f2fa66cc430 161
gatedClock 10:4f2fa66cc430 162 dMetroBPM--; // decrease BPM.
gatedClock 4:67d958cc00e8 163
gatedClock 12:fab8e658ae76 164 // saturate metronome BPM.
gatedClock 12:fab8e658ae76 165 if (dMetroBPM > METROMAX) dMetroBPM = METROMAX;
gatedClock 12:fab8e658ae76 166 if (dMetroBPM < METROMIN) dMetroBPM = METROMIN;
gatedClock 12:fab8e658ae76 167
gatedClock 10:4f2fa66cc430 168 wait(DEBOUNCE); // debounce time.
gatedClock 9:ea97a69b9b93 169
gatedClock 10:4f2fa66cc430 170 __enable_irq();
gatedClock 12:fab8e658ae76 171
gatedClock 10:4f2fa66cc430 172 }
gatedClock 10:4f2fa66cc430 173 /*----------------------------------------------//----------------------------*/
gatedClock 10:4f2fa66cc430 174 void ISR_right_falling(void) // ignore rising after falling edge.
gatedClock 10:4f2fa66cc430 175 {
gatedClock 10:4f2fa66cc430 176 __disable_irq();
gatedClock 10:4f2fa66cc430 177
gatedClock 10:4f2fa66cc430 178 wait(DEBOUNCE); // debounce time.
gatedClock 10:4f2fa66cc430 179
gatedClock 10:4f2fa66cc430 180 __enable_irq();
gatedClock 4:67d958cc00e8 181 }
gatedClock 4:67d958cc00e8 182 /*----------------------------------------------//----------------------------*/
gatedClock 4:67d958cc00e8 183 void ISR_up(void)
gatedClock 1:5f41e2df0e85 184 {
gatedClock 1:5f41e2df0e85 185 }
gatedClock 1:5f41e2df0e85 186 /*----------------------------------------------//----------------------------*/
gatedClock 4:67d958cc00e8 187 void ISR_down(void)
gatedClock 1:5f41e2df0e85 188 {
gatedClock 12:fab8e658ae76 189 cMetronomeOn = 1;
gatedClock 12:fab8e658ae76 190 timeoutMetronome.detach();
gatedClock 12:fab8e658ae76 191 timeoutMetronome.attach(&turn_off_metronome,10.0);
gatedClock 1:5f41e2df0e85 192 }
gatedClock 1:5f41e2df0e85 193 /*----------------------------------------------//----------------------------*/
gatedClock 3:8ff0c9c853be 194 void ISR_center(void) // set BPM = 60.
gatedClock 1:5f41e2df0e85 195 {
gatedClock 8:95f4f470ae28 196 dMetroBPM = 60;
gatedClock 4:67d958cc00e8 197
gatedClock 1:5f41e2df0e85 198 }
gatedClock 1:5f41e2df0e85 199 /*----------------------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 200 void lcd_display(void) // display metronome info.
gatedClock 0:1013288b8e43 201 {
gatedClock 0:1013288b8e43 202 lcd.cls(); // clear display.
gatedClock 0:1013288b8e43 203
gatedClock 0:1013288b8e43 204 LCD1; // line 1.
gatedClock 0:1013288b8e43 205 lcd.printf(" METRONOME");
gatedClock 0:1013288b8e43 206
gatedClock 0:1013288b8e43 207 LCD2; // line 2.
gatedClock 0:1013288b8e43 208
gatedClock 0:1013288b8e43 209 if (dMetroBPM == METROMIN) // BPM, with saturation notification.
gatedClock 0:1013288b8e43 210 lcd.printf(" %5.2d BPM minimum",dMetroBPM);
gatedClock 0:1013288b8e43 211 else
gatedClock 0:1013288b8e43 212 if (dMetroBPM == METROMAX)
gatedClock 0:1013288b8e43 213 lcd.printf(" %5.2d BPM maximum",dMetroBPM);
gatedClock 0:1013288b8e43 214 else
gatedClock 0:1013288b8e43 215 lcd.printf(" %5.2d BPM",dMetroBPM);
gatedClock 0:1013288b8e43 216
gatedClock 0:1013288b8e43 217 LCD3; // line 3.
gatedClock 0:1013288b8e43 218
gatedClock 8:95f4f470ae28 219 lcd.printf(" RTOS HW 4");
gatedClock 0:1013288b8e43 220 }
gatedClock 0:1013288b8e43 221 /*----------------------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 222 // this metronome tick ISR will self-adjust to the current user-selected
gatedClock 0:1013288b8e43 223 // metronome rate. that has to be done here, and at the start of the function,
gatedClock 0:1013288b8e43 224 // in order to maintain a constant phase and to prevent a beat-skip.
gatedClock 0:1013288b8e43 225
gatedClock 0:1013288b8e43 226 void interrupt_service_M() // metronome tick.
gatedClock 0:1013288b8e43 227 {
gatedClock 12:fab8e658ae76 228 if (cMetronomeOn)
gatedClock 12:fab8e658ae76 229 {
gatedClock 12:fab8e658ae76 230 tickerMetronome.detach(); // only one attachment.
gatedClock 12:fab8e658ae76 231 tickerMetronome.attach(&interrupt_service_M,fMetroDelay);
gatedClock 12:fab8e658ae76 232 led3_on();
gatedClock 12:fab8e658ae76 233 timeoutDutyCycle.attach(&led3_off,fMetroDuty);
gatedClock 12:fab8e658ae76 234 } else led3_off();
gatedClock 12:fab8e658ae76 235 }
gatedClock 12:fab8e658ae76 236 /*----------------------------------------------//----------------------------*/
gatedClock 12:fab8e658ae76 237 void turn_off_metronome(void)
gatedClock 12:fab8e658ae76 238 {
gatedClock 12:fab8e658ae76 239 cMetronomeOn = 0;
gatedClock 0:1013288b8e43 240 }
gatedClock 0:1013288b8e43 241 /*----------------------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 242 // this routine measures the number of seconds for which the joystick is
gatedClock 0:1013288b8e43 243 // in the up or down position. for three ranges of time, three different
gatedClock 0:1013288b8e43 244 // BPM rates-of-change are used. This means that as the user controls the
gatedClock 0:1013288b8e43 245 // metronome rate using the joystick, at first it will change slowly, then
gatedClock 0:1013288b8e43 246 // it will change at a moderate speed, then it will change quickly.
gatedClock 0:1013288b8e43 247 // additionally, pressing the center joystick button will bring the metronome
gatedClock 0:1013288b8e43 248 // back to 60BPM immediately, breaking BPM phase continuity.
gatedClock 0:1013288b8e43 249 void interrupt_service_UD(void) // joystick up/down sample
gatedClock 0:1013288b8e43 250 {
gatedClock 0:1013288b8e43 251 int dPressedSeconds; // how many seconds joystick pressed.
gatedClock 0:1013288b8e43 252 int dMultiCount; // slow count rate.
gatedClock 0:1013288b8e43 253 char cDiscontinuity; // 1 = break phase & change BPM now.
gatedClock 0:1013288b8e43 254
gatedClock 0:1013288b8e43 255 cDiscontinuity = 0; // don't break phase.
gatedClock 0:1013288b8e43 256
gatedClock 0:1013288b8e43 257 // calculate slow rate period.
gatedClock 0:1013288b8e43 258 dMultiCount = (int) ((float) (1.0 / ((float) UDSAMPLERATE)));
gatedClock 0:1013288b8e43 259
gatedClock 3:8ff0c9c853be 260 if (dJoyStickUp) // joystick up.
gatedClock 0:1013288b8e43 261 {
gatedClock 0:1013288b8e43 262 // rate-range calculations.
gatedClock 0:1013288b8e43 263 dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE);
gatedClock 0:1013288b8e43 264 if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM ++;}
gatedClock 0:1013288b8e43 265 else
gatedClock 0:1013288b8e43 266 if (dPressedSeconds < 10) dMetroBPM++;
gatedClock 0:1013288b8e43 267 else dMetroBPM += 5;
gatedClock 0:1013288b8e43 268 lUpDownHowMany++; // joystick holddown time.
gatedClock 0:1013288b8e43 269 }
gatedClock 0:1013288b8e43 270 else
gatedClock 3:8ff0c9c853be 271 if (dJoyStickDown) // joystick down.
gatedClock 0:1013288b8e43 272 {
gatedClock 0:1013288b8e43 273 // rate-range calculations.
gatedClock 0:1013288b8e43 274 dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE);
gatedClock 0:1013288b8e43 275 if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM --;}
gatedClock 0:1013288b8e43 276 else
gatedClock 0:1013288b8e43 277 if (dPressedSeconds < 10) dMetroBPM--;
gatedClock 0:1013288b8e43 278 else dMetroBPM -= 5;
gatedClock 0:1013288b8e43 279 lUpDownHowMany++; // joystick holddown time.
gatedClock 0:1013288b8e43 280 }
gatedClock 0:1013288b8e43 281 else lUpDownHowMany = 0; // clear when not up or down.
gatedClock 0:1013288b8e43 282
gatedClock 3:8ff0c9c853be 283 if (dJoyStickCenter)
gatedClock 0:1013288b8e43 284 {
gatedClock 0:1013288b8e43 285 dMetroBPM = 60; // center-button -> 60BPM.
gatedClock 0:1013288b8e43 286 cDiscontinuity = 1; // pending phase-break.
gatedClock 0:1013288b8e43 287 }
gatedClock 0:1013288b8e43 288 // saturate metronome BPM.
gatedClock 0:1013288b8e43 289 if (dMetroBPM > METROMAX) dMetroBPM = METROMAX;
gatedClock 0:1013288b8e43 290 if (dMetroBPM < METROMIN) dMetroBPM = METROMIN;
gatedClock 0:1013288b8e43 291
gatedClock 0:1013288b8e43 292 fMetroDelay = 60.0 / (float) (dMetroBPM); // calculate Ticker delay time.
gatedClock 0:1013288b8e43 293
gatedClock 0:1013288b8e43 294 if (cDiscontinuity) // implement 60BPS now.
gatedClock 0:1013288b8e43 295 {
gatedClock 0:1013288b8e43 296 tickerMetronome.detach(); // only one attachment.
gatedClock 0:1013288b8e43 297 tickerMetronome.attach(&interrupt_service_M,fMetroDelay);
gatedClock 0:1013288b8e43 298 }
gatedClock 0:1013288b8e43 299
gatedClock 0:1013288b8e43 300 }
gatedClock 0:1013288b8e43 301 /*----------------------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 302 void led3_off(void) {led3 = 0;} // turn off the LED.
gatedClock 0:1013288b8e43 303 /*----------------------------------------------//----------------------------*/
gatedClock 0:1013288b8e43 304 void led3_on( void) {led3 = 1;} // turn on the led.
gatedClock 14:fb4c76ac43a1 305 /*----------------------------------------------//----------------------------*/
gatedClock 14:fb4c76ac43a1 306 void thread_start_display(void const *)
gatedClock 14:fb4c76ac43a1 307 {
gatedClock 14:fb4c76ac43a1 308 // LCD ticker.
gatedClock 14:fb4c76ac43a1 309 tickerLCD.attach(&lcd_display,LCDSAMPLERATE);
gatedClock 14:fb4c76ac43a1 310
gatedClock 14:fb4c76ac43a1 311 }
gatedClock 14:fb4c76ac43a1 312 /*----------------------------------------------//----------------------------*/
gatedClock 14:fb4c76ac43a1 313