~gabe/flashlight-firmware/anduril2

« back to all changes in this revision

Viewing changes to dthoang/dth_Momentary_v1_1.c

  • Committer: Selene Scriven
  • Date: 2015-02-16 20:34:03 UTC
  • Revision ID: ubuntu@toykeeper.net-20150216203403-a9xpvclisgppyu32
Added dthoang's Olight Baton-like version of STAR_momentary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * dth Momentary version 1.1
 
3
 *
 
4
 * Created: 1/11/2015 7:15:48 PM
 
5
 *  Author: Dzung Hoang
 
6
 *
 
7
 * Firmware for NANJG 105C-based LED drivers using ATTINY13A MCU
 
8
 * using momentary switch for mode change.
 
9
 *
 
10
 * Portions of the code and the comment section below are based upon
 
11
 * STAR_momentary version 1.6.
 
12
 *
 
13
 * Flashlight Usage:
 
14
 *
 
15
 * From OFF:
 
16
 *   Short press turns ON to last mode.
 
17
 *   Long press turns ON to moon.
 
18
 *   Double press turn ON to turbo.
 
19
 *
 
20
 * From ON:
 
21
 *   Short press turns OFF.
 
22
 *   Long press cycles to next mode. Keep pressing to continue cycling.
 
23
 *   Double press cycles to previous mode. Keep pressing to continue cycling.
 
24
 *
 
25
 * Notes:
 
26
 *   There is no previous mode from moon. This is to prevent jarring transition from moon to turbo.
 
27
 */
 
28
 
 
29
 
 
30
/*
 
31
 * Changelog
 
32
 *
 
33
 * 1.0 Initial version
 
34
 * 1.1 Modified UI, added blink-on-power option from ToyKeeper, optimizations
 
35
 */
 
36
 
 
37
 
 
38
/*
 
39
 * NANJG 105C Diagram
 
40
 *           ---
 
41
 *         -|   |- VCC
 
42
 *  Star 4 -|   |- Voltage ADC
 
43
 *  Star 3 -|   |- PWM
 
44
 *         GND -|   |- Star 2
 
45
 *           ---
 
46
 *
 
47
 * FUSES
 
48
 *            I use these fuse settings
 
49
 *            Low:  0x75        (4.8MHz CPU without 8x divider, 9.4kHz phase-correct PWM or 18.75kHz fast-PWM)
 
50
 *            High: 0xff
 
51
 *
 
52
 *          For more details on these settings, visit http://github.com/JCapSolutions/blf-firmware/wiki/PWM-Frequency
 
53
 *
 
54
 * STARS
 
55
 *            Star 2 = Not used
 
56
 *            Star 3 = Not used
 
57
 *            Star 4 = Switch input
 
58
 *
 
59
 * VOLTAGE
 
60
 *            Resistor values for voltage divider (reference BLF-VLD README for more info)
 
61
 *            Reference voltage can be anywhere from 1.0 to 1.2, so this cannot be all that accurate
 
62
 *
 
63
 *               VCC
 
64
 *                |
 
65
 *               Vd (~.25 v drop from protection diode)
 
66
 *                |
 
67
 *              1912 (R1 19,100 ohms)
 
68
 *                |
 
69
 *                |---- PB2 from MCU
 
70
 *                |
 
71
 *              4701 (R2 4,700 ohms)
 
72
 *                |
 
73
 *               GND
 
74
 *
 
75
 *            ADC = ((V_bat - V_diode) * R2   * 255) / ((R1        + R2  ) * V_ref)
 
76
 *            125 = ((3.0   - .25        ) * 4700 * 255) / ((19100 + 4700) * 1.1  )
 
77
 *            121 = ((2.9   - .25        ) * 4700 * 255) / ((19100 + 4700) * 1.1  )
 
78
 *
 
79
 *            Well 125 and 121 were too close, so it shut off right after lowering to low mode, so I went with
 
80
 *            130 and 120
 
81
 *
 
82
 *            To find out what value to use, plug in the target voltage (V) to this equation
 
83
 *                value = (V * 4700 * 255) / (23800 * 1.1)
 
84
 *          
 
85
 */
 
86
 
 
87
 
 
88
/*
 
89
 * CPU configuration
 
90
 */
 
91
// clock frequency used in util/delay.h
 
92
#define F_CPU 4800000UL
 
93
 
 
94
 
 
95
/*
 
96
 * Feature configuration
 
97
 */
 
98
#define VOLTAGE_MON         1           // set to 0 to disable - ramp down and eventual shutoff when battery is low
 
99
#define TURBO_MODE          1           // enable turbo mode with ramp down after timeout
 
100
#define DEBOUNCE_BOTH   1           // set to 1 to debounce both press and release, else debounce only press
 
101
#define BLINK_ON_POWER  1           // blink once when power is received
 
102
 
 
103
 
 
104
/*
 
105
 * Pin layout
 
106
 */
 
107
#define ALT_PWM_PIN PB0
 
108
#define PWM_PIN         PB1
 
109
#define VOLTAGE_PIN PB2
 
110
#define SWITCH_PIN  PB3             // what pin the switch is connected to, which is Star 4
 
111
#define STAR3_PIN   PB4             // If not connected, will cycle L-H.  Connected, H-L
 
112
#define PWM_LVL         OCR0B           // OCR0B is the output compare register for PB1
 
113
 
 
114
 
 
115
/*
 
116
 * ADC configuration
 
117
 */
 
118
#define ADC_CHANNEL 0x01            // MUX 01 corresponds with PB2
 
119
#define ADC_DIDR        ADC1D           // Digital input disable bit corresponding with PB2
 
120
#define ADC_PRSCL   0x06            // clk/64
 
121
#define ADC_LOW         130             // When do we start ramping
 
122
#define ADC_CRIT        120             // When do we shut the light off
 
123
#define ADC_DELAY   188             // Delay in ticks between low-bat rampdowns (188 ~= 3s)
 
124
 
 
125
 
 
126
/*
 
127
 * PWM modes
 
128
 */
 
129
#define PWM_PHASE   0b00100001
 
130
#define PWM_FAST        0b00100011
 
131
 
 
132
 
 
133
/*
 
134
 * Switch debounce
 
135
 */
 
136
#define DB_PRES_DUR 0b00000001  // time before we consider the switch pressed (after first realizing it was pressed)
 
137
#define DB_REL_DUR  0b00000011  // time before we consider the switch released
 
138
 
 
139
 
 
140
/*
 
141
 * Switch and mode handling
 
142
 */
 
143
#define LONG_PRESS_DUR          32          // How many WDT ticks until we consider a press a long press. 32 is roughly 1/2 s
 
144
#define DOUBLE_PRESS_DUR        8           // How many WDT ticks below which we consider a press a double press
 
145
#define TURBO_TIMEOUT           3750        // How many WTD ticks before before dropping down (.016 sec each)
 
146
                                        // 90s  = 5625
 
147
                                        // 120s = 7500
 
148
#define SLEEP_TIMEOUT           125         // How many WTD ticks after switch released before entering sleep mode (.016 sec each)
 
149
 
 
150
 
 
151
/*
 
152
 * include header files
 
153
 */
 
154
#include <avr/pgmspace.h>
 
155
#include <avr/io.h>
 
156
#include <util/delay.h>
 
157
#include <avr/interrupt.h>
 
158
#include <avr/wdt.h>
 
159
#include <avr/eeprom.h>
 
160
#include <avr/sleep.h>
 
161
 
 
162
 
 
163
/*
 
164
 * Type definition
 
165
 */
 
166
 
 
167
 
 
168
// main state variables
 
169
typedef struct
 
170
{
 
171
        uint8_t on_off_state;                   // 0 = off, 1 = on
 
172
        uint8_t mode_idx;                       // brightness level: 0 to num_modes-1
 
173
        uint8_t ticks_until_sleep;              // number of ticks left before going to sleep
 
174
        uint8_t ticks_since_last_release;   // count number of ticks since last switch released
 
175
        uint8_t press_duration;                 // number of 16ms ticks that switch has been pressed
 
176
        uint8_t double_press_detected;          // detect double press
 
177
        uint8_t long_press_disable;             // disable long press detection
 
178
        uint8_t debounce_buffer;                // previous switch status used for debounce
 
179
#if TURBO_MODE
 
180
        uint16_t turbo_ticks;                   // number of ticks in TURBO mode
 
181
#endif
 
182
#if VOLTAGE_MON
 
183
        uint8_t adc_ticks;                      // count down timer used to check ADC
 
184
        uint8_t lowbatt_cnt;                    // counter used for low battery detection
 
185
#endif
 
186
} state_t;
 
187
 
 
188
 
 
189
 
 
190
 
 
191
/*
 
192
 * Mode configuration
 
193
 */
 
194
// put mode tables into EEPROM to save program memory
 
195
uint8_t EEMEM mode_level[] = {1, 4, 15, 42, 127, 255};
 
196
uint8_t EEMEM mode_phase[] = {PWM_PHASE, PWM_PHASE, PWM_FAST, PWM_FAST, PWM_FAST, PWM_PHASE};
 
197
uint8_t EEMEM mode_next[] = {1, 2, 3, 4, 5, 1};
 
198
uint8_t EEMEM mode_prev[] = {0, 5, 1, 2, 3, 4};
 
199
const uint8_t num_modes_minus1 = sizeof(mode_level) - 1;
 
200
#define START_MODE 1
 
201
 
 
202
 
 
203
/*
 
204
 * global variables
 
205
 */
 
206
// Use initializer here to reduce size of reset_state().
 
207
volatile state_t state =
 
208
{
 
209
        0,                      // on_off_state
 
210
        START_MODE,             // mode_idx
 
211
        SLEEP_TIMEOUT,          // ticks_until_sleep
 
212
        DOUBLE_PRESS_DUR,   // ticks_since_last_release
 
213
        1,                      // press_duration
 
214
        0,                      // double_press_detected
 
215
        0,                      // long_press_disable
 
216
        0xff,                   // debounce_buffer
 
217
#if TURBO_MODE
 
218
        0,                      // turbo_ticks
 
219
#endif
 
220
#if VOLTAGE_MON
 
221
        ADC_DELAY,              // adc_ticks
 
222
        0,                      // lowbatt_cnt
 
223
#endif
 
224
};
 
225
 
 
226
 
 
227
/*
 
228
 * HW configuration routines
 
229
 */
 
230
 
 
231
 
 
232
// Setup and enable watchdog timer to only interrupt, not reset, every 16ms.
 
233
inline void WDT_on()
 
234
{
 
235
        cli();                              // Disable interrupts
 
236
        wdt_reset();                        // Reset the WDT
 
237
        WDTCR |= (1<<WDCE) | (1<<WDE);  // Start timed sequence
 
238
        WDTCR = (1<<WDTIE);                 // Enable interrupt every 16ms
 
239
        sei();                              // Enable interrupts
 
240
}
 
241
 
 
242
 
 
243
// Disable watchdog timer
 
244
inline void WDT_off()
 
245
{
 
246
        cli();                              // Disable interrupts
 
247
        wdt_reset();                        // Reset the WDT
 
248
        MCUSR &= ~(1<<WDRF);                // Clear Watchdog reset flag
 
249
        WDTCR |= (1<<WDCE) | (1<<WDE);  // Start timed sequence
 
250
        WDTCR = 0x00;                       // Disable WDT
 
251
        sei();                              // Enable interrupts
 
252
}
 
253
 
 
254
 
 
255
#if VOLTAGE_MON
 
256
// Setup ADC for voltage monitoring
 
257
inline void ADC_on()
 
258
{
 
259
        ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
 
260
        DIDR0 |= (1 << ADC_DIDR);                               // disable digital input on ADC pin to reduce power consumption
 
261
        ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
 
262
}
 
263
#endif
 
264
 
 
265
 
 
266
// Disable ADC
 
267
inline void ADC_off()
 
268
{
 
269
        ADCSRA &= ~(1<<7); //ADC off
 
270
}
 
271
 
 
272
 
 
273
// Enable pin change interrupts
 
274
inline void PCINT_on() {
 
275
        GIMSK |= (1 << PCIE);
 
276
}
 
277
 
 
278
 
 
279
// Disable pin change interrupts
 
280
inline void PCINT_off() {
 
281
        GIMSK &= ~(1 << PCIE);
 
282
}
 
283
 
 
284
 
 
285
// set PWM mode
 
286
inline void set_pwm_mode()
 
287
{
 
288
        if (state.on_off_state)
 
289
        {
 
290
            // read mode phase and level from EEPROM
 
291
            TCCR0A = eeprom_read_byte(&mode_phase[state.mode_idx]);
 
292
            PWM_LVL = eeprom_read_byte(&mode_level[state.mode_idx]);
 
293
        }
 
294
        else
 
295
        {
 
296
            // use phase-accurate PWM mode with level 0 to get LED fully off
 
297
            TCCR0A = PWM_PHASE;
 
298
            PWM_LVL = 0;
 
299
        }
 
300
}
 
301
 
 
302
 
 
303
// Need an interrupt for when pin change is enabled to ONLY wake us from sleep.
 
304
// All logic of what to do when we wake up will be handled in the main loop.
 
305
EMPTY_INTERRUPT(PCINT0_vect);
 
306
 
 
307
 
 
308
// initialize MCU functions
 
309
inline void initialize_mcu()
 
310
{
 
311
        // turn off watchdog timer as a precaution
 
312
        WDT_off();
 
313
    
 
314
        // Set all ports to input, and turn pull-up resistors on for the inputs we are using
 
315
        DDRB = 0x00;
 
316
        PORTB = (1 << SWITCH_PIN);
 
317
 
 
318
 
 
319
        // Set the switch as an interrupt for when we turn pin change interrupts on
 
320
        PCMSK = (1 << SWITCH_PIN);
 
321
    
 
322
        // Set PWM pin to output
 
323
        DDRB = (1 << PWM_PIN);
 
324
 
 
325
 
 
326
        // Set timer to do PWM for correct output pin and set prescaler timing
 
327
        TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
 
328
 
 
329
 
 
330
        // Turn features on or off as needed
 
331
#if VOLTAGE_MON
 
332
        ADC_on();
 
333
#else
 
334
        ADC_off();
 
335
#endif
 
336
        ACSR   |=  (1<<7); //AC off
 
337
 
 
338
 
 
339
        // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
 
340
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
341
}
 
342
 
 
343
 
 
344
/*
 
345
 * Read state of switch with debounce
 
346
 */
 
347
uint8_t is_pressed()
 
348
{
 
349
        uint8_t debounce_pressed;
 
350
 
 
351
 
 
352
#if DEBOUNCE_BOTH
 
353
        // retrieve debounce_pressed from MSB of state.debounce_buffer
 
354
        debounce_pressed = state.debounce_buffer & 128;
 
355
#endif
 
356
 
 
357
 
 
358
        // Shift over and tack on the latest value, 0 being low for pressed, 1 for pulled-up for released
 
359
        state.debounce_buffer = ((state.debounce_buffer << 1) & 0x7f) | ((~(PINB >> SWITCH_PIN)) & 1);
 
360
 
 
361
 
 
362
#if DEBOUNCE_BOTH
 
363
        debounce_pressed = (debounce_pressed ? ((state.debounce_buffer & DB_REL_DUR) != 0) : ((state.debounce_buffer & DB_PRES_DUR) == DB_PRES_DUR)) ? 128 : 0;
 
364
        // store debounce_pressed in MSB of state.debounce_buffer
 
365
        state.debounce_buffer |= debounce_pressed;
 
366
#else
 
367
        debounce_pressed = (state.debounce_buffer & DB_REL_DUR);
 
368
#endif
 
369
 
 
370
 
 
371
        return debounce_pressed;
 
372
}
 
373
 
 
374
 
 
375
inline void next_mode()
 
376
{
 
377
        state.mode_idx = eeprom_read_byte(&mode_next[state.mode_idx]);
 
378
}
 
379
 
 
380
 
 
381
inline void prev_mode()
 
382
{
 
383
        state.mode_idx = eeprom_read_byte(&mode_prev[state.mode_idx]);
 
384
}
 
385
 
 
386
 
 
387
inline void reset_state()
 
388
{
 
389
        state.ticks_until_sleep = SLEEP_TIMEOUT;
 
390
 
 
391
 
 
392
        // start by simulating a key press
 
393
        state.debounce_buffer = 0xff;
 
394
        state.press_duration = 1;
 
395
        state.ticks_since_last_release = DOUBLE_PRESS_DUR;
 
396
}
 
397
 
 
398
 
 
399
void sleep_until_switch_press()
 
400
{
 
401
        // Turn the WDT off so it doesn't wake us from sleep
 
402
        // Will also ensure interrupts are on or we will never wake up
 
403
        WDT_off();
 
404
        // Enable a pin change interrupt to wake us up
 
405
        PCINT_on();
 
406
        // Now go to sleep
 
407
        sleep_mode();
 
408
        // Hey, someone must have pressed the switch!!
 
409
        // Disable pin change interrupt because it's only used to wake us up
 
410
        PCINT_off();
 
411
        // reset state and simulate a key press
 
412
        reset_state();
 
413
        // Turn the WDT back on to check for switch presses
 
414
        WDT_on();
 
415
        // Go back to main program
 
416
}
 
417
 
 
418
 
 
419
/*
 
420
 * Watchdog routine
 
421
 * The watchdog timer is called every 16ms.
 
422
 */
 
423
ISR(WDT_vect)
 
424
{
 
425
        if (state.ticks_until_sleep == 0)
 
426
        {
 
427
            // do nothing if we are in sleep mode
 
428
            return;
 
429
        }
 
430
 
 
431
 
 
432
        uint8_t change_pwm_mode = 0;            // signal when to change PWM mode
 
433
    
 
434
        // Process switch input and UI mode selection
 
435
        if (is_pressed())
 
436
        {
 
437
            // detect double press when switch is first pressed
 
438
            if ((state.press_duration++ == 0) && (state.ticks_since_last_release < DOUBLE_PRESS_DUR))
 
439
            {
 
440
                state.double_press_detected = 1;
 
441
                if (state.on_off_state)
 
442
                {
 
443
                    // turbo
 
444
                    state.mode_idx = num_modes_minus1;
 
445
                    // disable further long press actions
 
446
                    state.long_press_disable = 1;
 
447
                }
 
448
                else
 
449
                {
 
450
                    prev_mode();
 
451
                    state.on_off_state = 1;
 
452
                }
 
453
                change_pwm_mode = 1;
 
454
            }
 
455
 
 
456
 
 
457
            if ((state.press_duration == LONG_PRESS_DUR) && (state.double_press_detected == 0) && (state.on_off_state == 0))
 
458
            {
 
459
                // long press and previously off so turn on in lowest mode
 
460
                state.mode_idx = 0;
 
461
                state.on_off_state = 1;
 
462
                change_pwm_mode = 1;
 
463
                // disable further long press actions
 
464
                state.long_press_disable = 1;
 
465
            }
 
466
 
 
467
 
 
468
            if (!state.long_press_disable)
 
469
            {
 
470
                if ((state.press_duration == LONG_PRESS_DUR) || (state.press_duration == 2*LONG_PRESS_DUR))
 
471
                {
 
472
                    if (state.double_press_detected == 0)
 
473
                    {
 
474
                        next_mode();
 
475
                    }
 
476
                    else
 
477
                    {
 
478
                        prev_mode();
 
479
                    }
 
480
                    change_pwm_mode = 1;
 
481
                }
 
482
            }
 
483
 
 
484
 
 
485
            // detect really long key press and treat as a sequence of long key presses
 
486
            if (state.press_duration >= 2*LONG_PRESS_DUR)
 
487
            {
 
488
                state.press_duration = LONG_PRESS_DUR;
 
489
            }
 
490
 
 
491
 
 
492
            // reset relevant counters here
 
493
#if VOLTAGE_MON
 
494
            state.adc_ticks = ADC_DELAY;
 
495
#endif
 
496
            state.ticks_since_last_release = 0;
 
497
#if TURBO_MODE
 
498
            state.turbo_ticks = 0;
 
499
#endif
 
500
        }
 
501
        else
 
502
        {
 
503
            if (state.press_duration > 0 && state.press_duration < LONG_PRESS_DUR)
 
504
            {
 
505
                // short press
 
506
                if (!state.double_press_detected)
 
507
                {
 
508
                    // toggle on_off_state
 
509
                    state.on_off_state = state.on_off_state ^ 1;
 
510
                    change_pwm_mode = state.on_off_state;
 
511
                }
 
512
            }
 
513
            
 
514
            // we delay turning off until DOUBLE_PRESS_DUR has passed to avoid a blink when double press from ON
 
515
            if (state.on_off_state == 0 && state.ticks_since_last_release == DOUBLE_PRESS_DUR)
 
516
            {
 
517
                change_pwm_mode = 1;
 
518
            }
 
519
 
 
520
 
 
521
#if TURBO_MODE
 
522
            // Only do turbo check when switch isn't pressed and light is on
 
523
            if (state.on_off_state && state.mode_idx == num_modes_minus1)
 
524
            {
 
525
                if (++state.turbo_ticks > TURBO_TIMEOUT)
 
526
                {
 
527
                    --state.mode_idx;
 
528
                    change_pwm_mode = 1;
 
529
                }
 
530
            }
 
531
            else
 
532
            {
 
533
                state.turbo_ticks = 0;
 
534
            }
 
535
#endif
 
536
 
 
537
 
 
538
#if VOLTAGE_MON
 
539
            // Only do voltage monitoring when the switch isn't pressed and light is on
 
540
            if (state.on_off_state)
 
541
            {
 
542
                if (state.adc_ticks > 0)
 
543
                {
 
544
                    --state.adc_ticks;
 
545
                }
 
546
                else
 
547
                {
 
548
                    // See if conversion is done
 
549
                    if (ADCSRA & (1 << ADIF))
 
550
                    {
 
551
                        // See if voltage is lower than what we were looking for
 
552
                        state.lowbatt_cnt = ADCH < ((state.mode_idx == 0) ? ADC_CRIT : ADC_LOW) ? state.lowbatt_cnt+1 : 0;
 
553
                    }
 
554
                    // See if it's been low for a while
 
555
                    if (state.lowbatt_cnt >= 4)
 
556
                    {
 
557
                        if (state.mode_idx == 0)
 
558
                        {
 
559
                            state.on_off_state = 0;
 
560
                        }
 
561
                        else
 
562
                        {
 
563
                            --state.mode_idx;
 
564
                        }
 
565
                        state.lowbatt_cnt = 0;
 
566
                        state.adc_ticks = ADC_DELAY;
 
567
                        change_pwm_mode = 1;
 
568
                    }
 
569
                    // Make sure conversion is running for next time through
 
570
                    ADCSRA |= (1 << ADSC);
 
571
                }
 
572
            }
 
573
            else
 
574
            {
 
575
                state.lowbatt_cnt = 0;
 
576
                state.adc_ticks = ADC_DELAY;
 
577
            }
 
578
#endif
 
579
 
 
580
 
 
581
            // reset relevant counters here
 
582
            state.press_duration = 0;
 
583
            state.double_press_detected = 0;
 
584
            state.long_press_disable = 0;
 
585
            if (state.ticks_since_last_release < 255)
 
586
            {
 
587
                ++state.ticks_since_last_release;
 
588
            }
 
589
        }
 
590
    
 
591
        if (change_pwm_mode)
 
592
        {
 
593
            set_pwm_mode();
 
594
        }
 
595
    
 
596
        if (state.on_off_state)
 
597
        {
 
598
            state.ticks_until_sleep = SLEEP_TIMEOUT;
 
599
        }
 
600
        else if (state.ticks_until_sleep > 0)
 
601
        {
 
602
            --state.ticks_until_sleep;
 
603
        }
 
604
}
 
605
 
 
606
 
 
607
int main(void)
 
608
{
 
609
        initialize_mcu();
 
610
    
 
611
#if BLINK_ON_POWER
 
612
        TCCR0A = PWM_PHASE;
 
613
        PWM_LVL = eeprom_read_byte(&mode_level[num_modes_minus1]);
 
614
        _delay_ms(3);
 
615
        PWM_LVL = 0;
 
616
        _delay_ms(3);
 
617
#endif
 
618
 
 
619
 
 
620
        sleep_until_switch_press();
 
621
 
 
622
 
 
623
        while(1)
 
624
        {
 
625
            if (!state.ticks_until_sleep)
 
626
            {
 
627
                // Go to sleep
 
628
                sleep_until_switch_press();
 
629
            }
 
630
        }
 
631
}
 
 
b'\\ No newline at end of file'