~arthofer-thomas/flashlight-firmware/ramp-table

« back to all changes in this revision

Viewing changes to ToyKeeper/spaghetti-monster/anduril/anduril.c

  • Committer: Selene Scriven
  • Date: 2018-11-11 23:20:36 UTC
  • mfrom: (388.1.8 event-rework)
  • Revision ID: bzr@toykeeper.net-20181111232036-uvhk7fubpcq7tw2r
merged event-rework branch; reduces ROM size by ~700 bytes and simplifies event system

Show diffs side-by-side

added added

removed removed

Lines of Context:
146
146
#define MAX_BIKING_LEVEL 120  // should be 127 or less
147
147
#define USE_BATTCHECK
148
148
 
149
 
// determine the highest number of clicks to handle
150
 
#ifdef USE_INDICATOR_LED
151
 
#define MAX_CLICKS 7
152
 
#elif defined(USE_MUGGLE_MODE)
153
 
#define MAX_CLICKS 6
154
 
#else
155
 
#define MAX_CLICKS 5
156
 
#endif
157
 
 
158
149
#if defined(USE_MUGGLE_MODE)
159
150
#ifndef MUGGLE_FLOOR
160
151
#define MUGGLE_FLOOR 22
226
217
 
227
218
 
228
219
// FSM states
229
 
uint8_t off_state(EventPtr event, uint16_t arg);
 
220
uint8_t off_state(Event event, uint16_t arg);
230
221
// simple numeric entry config menu
231
 
uint8_t config_state_base(EventPtr event, uint16_t arg,
 
222
uint8_t config_state_base(Event event, uint16_t arg,
232
223
                          uint8_t num_config_steps,
233
224
                          void (*savefunc)());
234
225
#define MAX_CONFIG_VALUES 3
235
226
uint8_t config_state_values[MAX_CONFIG_VALUES];
236
227
// ramping mode and its related config mode
237
 
uint8_t steady_state(EventPtr event, uint16_t arg);
238
 
uint8_t ramp_config_state(EventPtr event, uint16_t arg);
 
228
uint8_t steady_state(Event event, uint16_t arg);
 
229
uint8_t ramp_config_state(Event event, uint16_t arg);
239
230
// party and tactical strobes
240
231
#ifdef USE_STROBE_STATE
241
 
uint8_t strobe_state(EventPtr event, uint16_t arg);
 
232
uint8_t strobe_state(Event event, uint16_t arg);
242
233
#endif
243
234
#ifdef USE_BATTCHECK
244
 
uint8_t battcheck_state(EventPtr event, uint16_t arg);
 
235
uint8_t battcheck_state(Event event, uint16_t arg);
245
236
#endif
246
237
#ifdef USE_THERMAL_REGULATION
247
 
uint8_t tempcheck_state(EventPtr event, uint16_t arg);
248
 
uint8_t thermal_config_state(EventPtr event, uint16_t arg);
 
238
uint8_t tempcheck_state(Event event, uint16_t arg);
 
239
uint8_t thermal_config_state(Event event, uint16_t arg);
249
240
#endif
250
241
// 1-hour ramp down from low, then automatic off
251
 
uint8_t goodnight_state(EventPtr event, uint16_t arg);
 
242
uint8_t goodnight_state(Event event, uint16_t arg);
252
243
// beacon mode and its related config mode
253
 
uint8_t beacon_state(EventPtr event, uint16_t arg);
254
 
uint8_t beacon_config_state(EventPtr event, uint16_t arg);
 
244
uint8_t beacon_state(Event event, uint16_t arg);
 
245
uint8_t beacon_config_state(Event event, uint16_t arg);
255
246
// soft lockout
256
247
#define MOON_DURING_LOCKOUT_MODE
257
 
uint8_t lockout_state(EventPtr event, uint16_t arg);
 
248
uint8_t lockout_state(Event event, uint16_t arg);
258
249
// momentary / signalling mode
259
 
uint8_t momentary_state(EventPtr event, uint16_t arg);
 
250
uint8_t momentary_state(Event event, uint16_t arg);
260
251
#ifdef USE_MUGGLE_MODE
261
252
// muggle mode, super-simple, hard to exit
262
 
uint8_t muggle_state(EventPtr event, uint16_t arg);
 
253
uint8_t muggle_state(Event event, uint16_t arg);
263
254
uint8_t muggle_mode_active = 0;
264
255
#endif
265
256
 
266
257
// general helper function for config modes
267
 
uint8_t number_entry_state(EventPtr event, uint16_t arg);
 
258
uint8_t number_entry_state(Event event, uint16_t arg);
268
259
// return value from number_entry_state()
269
260
volatile uint8_t number_entry_value;
270
261
 
387
378
volatile uint8_t beacon_seconds = 2;
388
379
 
389
380
 
390
 
uint8_t off_state(EventPtr event, uint16_t arg) {
 
381
uint8_t off_state(Event event, uint16_t arg) {
391
382
    // turn emitter off when entering state
392
383
    if (event == EV_enter_state) {
393
384
        set_level(0);
527
518
}
528
519
 
529
520
 
530
 
uint8_t steady_state(EventPtr event, uint16_t arg) {
 
521
uint8_t steady_state(Event event, uint16_t arg) {
531
522
    uint8_t mode_min = ramp_smooth_floor;
532
523
    uint8_t mode_max = ramp_smooth_ceil;
533
524
    uint8_t ramp_step_size = 1;
846
837
 
847
838
 
848
839
#ifdef USE_STROBE_STATE
849
 
uint8_t strobe_state(EventPtr event, uint16_t arg) {
 
840
uint8_t strobe_state(Event event, uint16_t arg) {
850
841
    // 'st' reduces ROM size by avoiding access to a volatile var
851
842
    // (maybe I should just make it nonvolatile?)
852
843
    strobe_mode_te st = strobe_type;
1059
1050
 
1060
1051
 
1061
1052
#ifdef USE_BATTCHECK
1062
 
uint8_t battcheck_state(EventPtr event, uint16_t arg) {
 
1053
uint8_t battcheck_state(Event event, uint16_t arg) {
1063
1054
    // 1 click: off
1064
1055
    if (event == EV_1click) {
1065
1056
        set_state(off_state, 0);
1076
1067
 
1077
1068
 
1078
1069
#ifdef USE_THERMAL_REGULATION
1079
 
uint8_t tempcheck_state(EventPtr event, uint16_t arg) {
 
1070
uint8_t tempcheck_state(Event event, uint16_t arg) {
1080
1071
    // 1 click: off
1081
1072
    if (event == EV_1click) {
1082
1073
        set_state(off_state, 0);
1097
1088
#endif
1098
1089
 
1099
1090
 
1100
 
uint8_t beacon_state(EventPtr event, uint16_t arg) {
 
1091
uint8_t beacon_state(Event event, uint16_t arg) {
1101
1092
    // 1 click: off
1102
1093
    if (event == EV_1click) {
1103
1094
        set_state(off_state, 0);
1124
1115
 
1125
1116
 
1126
1117
#define GOODNIGHT_TICKS_PER_STEPDOWN (GOODNIGHT_TIME*TICKS_PER_SECOND*60L/GOODNIGHT_LEVEL)
1127
 
uint8_t goodnight_state(EventPtr event, uint16_t arg) {
 
1118
uint8_t goodnight_state(Event event, uint16_t arg) {
1128
1119
    static uint16_t ticks_since_stepdown = 0;
1129
1120
    // blink on start
1130
1121
    if (event == EV_enter_state) {
1163
1154
}
1164
1155
 
1165
1156
 
1166
 
uint8_t lockout_state(EventPtr event, uint16_t arg) {
 
1157
uint8_t lockout_state(Event event, uint16_t arg) {
1167
1158
    #ifdef MOON_DURING_LOCKOUT_MODE
1168
1159
    // momentary(ish) moon mode during lockout
1169
 
    // not all presses will be counted;
1170
 
    // it depends on what is in the master event_sequences table
1171
 
    uint8_t last = 0;
1172
 
    for(uint8_t i=0; pgm_read_byte(event + i) && (i<EV_MAX_LEN); i++)
1173
 
        last = pgm_read_byte(event + i);
1174
 
    if (arg == 0) {  // Only turn on/off when button state changes
1175
 
        if ((last == A_PRESS) || (last == A_HOLD)) {
1176
 
            #ifdef LOCKOUT_MOON_LOWEST
1177
 
            // Use lowest moon configured
1178
 
            uint8_t lvl = ramp_smooth_floor;
1179
 
            if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
1180
 
            set_level(lvl);
1181
 
            #else
1182
 
            // Use moon from current ramp
1183
 
            set_level(nearest_level(1));
1184
 
            #endif
1185
 
        }
1186
 
        else if ((last == A_RELEASE) || (last == A_RELEASE_TIMEOUT)) {
1187
 
            set_level(0);
1188
 
        }
 
1160
    // button is being held
 
1161
    if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
 
1162
        #ifdef LOCKOUT_MOON_LOWEST
 
1163
        // Use lowest moon configured
 
1164
        uint8_t lvl = ramp_smooth_floor;
 
1165
        if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor;
 
1166
        set_level(lvl);
 
1167
        #else
 
1168
        // Use moon from current ramp
 
1169
        set_level(nearest_level(1));
 
1170
        #endif
 
1171
    }
 
1172
    // button was released
 
1173
    else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
 
1174
        set_level(0);
1189
1175
    }
1190
1176
    #endif
1191
1177
 
1278
1264
}
1279
1265
 
1280
1266
 
1281
 
uint8_t momentary_state(EventPtr event, uint16_t arg) {
 
1267
uint8_t momentary_state(Event event, uint16_t arg) {
1282
1268
    // TODO: momentary strobe here?  (for light painting)
1283
 
    if (event == EV_click1_press) {
 
1269
 
 
1270
    // light up when the button is pressed; go dark otherwise
 
1271
    // button is being held
 
1272
    if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
1284
1273
        set_level(memorized_level);
1285
 
        empty_event_sequence();  // don't attempt to parse multiple clicks
1286
1274
        return MISCHIEF_MANAGED;
1287
1275
    }
1288
 
 
1289
 
    else if (event == EV_release) {
 
1276
    // button was released
 
1277
    else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
1290
1278
        set_level(0);
1291
 
        empty_event_sequence();  // don't attempt to parse multiple clicks
1292
1279
        //go_to_standby = 1;  // sleep while light is off
1293
 
        // TODO: lighted button should use lockout config?
1294
1280
        return MISCHIEF_MANAGED;
1295
1281
    }
1296
1282
 
1302
1288
    else if ((event == EV_tick)  &&  (actual_level == 0)) {
1303
1289
        if (arg > TICKS_PER_SECOND*15) {  // sleep after 15 seconds
1304
1290
            go_to_standby = 1;  // sleep while light is off
 
1291
            // TODO: lighted button should use lockout config?
1305
1292
        }
1306
1293
        return MISCHIEF_MANAGED;
1307
1294
    }
1311
1298
 
1312
1299
 
1313
1300
#ifdef USE_MUGGLE_MODE
1314
 
uint8_t muggle_state(EventPtr event, uint16_t arg) {
 
1301
uint8_t muggle_state(Event event, uint16_t arg) {
1315
1302
    static int8_t ramp_direction;
1316
1303
    static int8_t muggle_off_mode;
1317
1304
 
1461
1448
 
1462
1449
 
1463
1450
// ask the user for a sequence of numbers, then save them and return to caller
1464
 
uint8_t config_state_base(EventPtr event, uint16_t arg,
 
1451
uint8_t config_state_base(Event event, uint16_t arg,
1465
1452
                          uint8_t num_config_steps,
1466
1453
                          void (*savefunc)()) {
1467
1454
    static uint8_t config_step;
1520
1507
    }
1521
1508
}
1522
1509
 
1523
 
uint8_t ramp_config_state(EventPtr event, uint16_t arg) {
 
1510
uint8_t ramp_config_state(Event event, uint16_t arg) {
1524
1511
    uint8_t num_config_steps;
1525
1512
    num_config_steps = 2 + ramp_style;
1526
1513
    return config_state_base(event, arg,
1548
1535
    if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
1549
1536
}
1550
1537
 
1551
 
uint8_t thermal_config_state(EventPtr event, uint16_t arg) {
 
1538
uint8_t thermal_config_state(Event event, uint16_t arg) {
1552
1539
    return config_state_base(event, arg,
1553
1540
                             2, thermal_config_save);
1554
1541
}
1563
1550
    }
1564
1551
}
1565
1552
 
1566
 
uint8_t beacon_config_state(EventPtr event, uint16_t arg) {
 
1553
uint8_t beacon_config_state(Event event, uint16_t arg) {
1567
1554
    return config_state_base(event, arg,
1568
1555
                             1, beacon_config_save);
1569
1556
}
1570
1557
 
1571
1558
 
1572
 
uint8_t number_entry_state(EventPtr event, uint16_t arg) {
 
1559
uint8_t number_entry_state(Event event, uint16_t arg) {
1573
1560
    static uint8_t value;
1574
1561
    static uint8_t blinks_left;
1575
1562
    static uint8_t entry_step;