aboutsummaryrefslogtreecommitdiff
path: root/ATmega48/Source/c_armcomm.c
blob: 6d5853d463be18112acfb6b42085d86b805ea52b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
//
// Programmer      
//
// Date init       14.12.2004
//
// Reviser         $Author:: Dktochpe                                        $
//
// Revision date   $Date:: 10-11-05 15:35                                    $
//
// Filename        $Workfile:: c_armcomm.c                                   $
//
// Version         $Revision:: 17                                            $
//
// Archive         $Archive:: /LMS2006/Sys01/Ioctrl/Firmware/Source/c_armcom $
//
// Platform        C
//

/* Event                                        Function                                  State
---------------------------------------         -------------------------------------     -----------------------------------

Voltage > 4,3V, wakeup or reset button          Brake motor drivers                       RESET
                                                                                          POWERUP  
                                                Batt measument off                        POWERUP_CHECK_FOR_RECHARGEABLE
                                                Wait 10 mS
                                                Rechargeable if switch > 0,5V       
                                                Batt measurement on                       POWERUP_CHECK_VOLTAGE_FOR_ARM_ON
                                                Wait 10 mS                               
                                                Check voltage for ARM on <= 11,8V           
                                                Batt measument off                        POWERUP_DISABLE_AMP
                                                Wait 10 mS                               
                                                Turn ARM on                               POWERUP_TURN_ARM_ON
                                                Brake off
                                                Wait 500 mS                               POWERUP_ENABLE_AMP
                                                Batt measurement on                       
                                                Check voltage for ARM on >= 6,5V (rechg)  POWERUP_CHECK_RECHARGEABLE_VOLTAGE   
Samba active                                    Reset copyright timer                     ON
                                                Read all inputs and update buttons        ON_RUNNING
                                                Check ARM communicating
                                                Check for high voltage/samba button
                                                Control led (Batt measurement on/off)
                                                Check for ARM samba request
                                                Check for ARM powerdown request
                                                Check for ARM copyright invalid


High voltage (batt > 12,2V or samba button)     Turn of input current drive               ON_HIGH_VOLTAGE
                                                Turn off ARM
                                                Brake output drivers
                                                Batt measurement off                      ON_CHECK_BUTTON
                                                Check samba button


Power down request or copyright invalid                                                   POWERDOWN
                                                Batt measurement off                      POWERDOWN_DISABLE_AMP
                                                Wait 10 mS
                                                Turn ARM off                              POWERDOWN_TURN_ARM_OFF
                                                Wait 1 sec
Rechargeable < 6,5V                                                                       OFF
                                                                                          SLEEP


Samba button (long press) or samba request                                                SAMBA
                                                Wait 100 mS                               SAMBA_ACTIVATE
                                                Batt measurement forced high              SAMBA_TURN_ARM_OFF_AND_WAIT
                                                Batt measurement off
                                                Turn ARM off
                                                Wait 1 sec
                                                Turn ARM on                               SAMBA_TURN_ARM_ON_AND_WAIT
                                                Wait 10 sec
                                                Turn ARM off                              SAMBA_TURN_ARM_OFF_FOR_RESET
                                                Remove batt measurement force
                                                Wait 1 sec
                                                Turn ARM on                               SAMBA_TURN_ARM_ON
                                                                                          ON


*/

#include  "stdconst.h"
#include  "c_armcomm.h"
#include  "d_power.h"
#include  "d_output.h"
#include  "d_input.h"
#include  "d_button.h"
#include  "d_armcomm.h"
#include  "d_timer.h"


#define   INPUTPOWER_ONTIME             3000    // [uS] time between input A/D samples
#define   COPYRIGHT_TIME                300000L // [mS] time to power down if no copy right string found

#define   POWERUP_ENABLE_MEASURE_TIME   10      // [mS] time to enable voltage divider for measurement
#define   POWERUP_DISABLE_MEASURE_TIME  10      // [mS] time to disable voltage divider for measurement
#define   POWERUP_DISABLE_AMP_TIME      10      // [mS] time after amp is disenabled
#define   POWERUP_ENABLE_AMP_TIME       100     // [mS] time before amp is enabled
#define   POWERUP_RECHARGE_TEST_TIME    1000    // [mS] time testing voltage if rechargeable (to show low batt on display)
#define   ON_ARM_TIMEOUT_TIME           2000    // [mS] time between ARM communication (max)
#define   LED_TOGGLE_TIME               500     // [mS] time between led toggles on and off
#define   CHECK_TEST_BUTTON_TIME        2000    // [mS] time for stable button reading (samba activate)
#define   BUTTON_ACCEPT_TIME            200     // [mS] time from samba accept to actual active
#define   SAMBA_POWEROFF_TIME           1000    // [mS] time for ARM power to drop
#define   SAMBA_BOOT_TIME               10000   // [mS] time for copying samba boot loader
#define   POWEROFF_TIME                 1000    // [mS] time from ARM off to sleep

#define   RECHARGEABLE_SWITCH_VOLTAGE   500L    // [mV] trigger point for rechageable battery detect switch
#define   ARM_POWERUP_MAX_VOLTAGE       11800L  // [mV] maximum allowable voltage when turning on ARM
#define   ARM_ON_MAX_VOLTAGE            12200L  // [mV] maximum allowable voltage when running ARM
#define   ARM_ON_OK_VOLTAGE             10000L  // [mV] maximum allowable voltage when turning on ARM (after high voltage)      
#define   ARM_ON_MIN_VOLTAGE            6500L   // [mV] minimum allowable voltage when turning on ARM (rechargeable)      





// Use compiler to calculate ticks from time
#define   INPUTPOWER_ONTICK             (UBYTE)(((ULONG)TIMER_RESOLUTION / (1000000L / (ULONG)INPUTPOWER_ONTIME)))
#define   COPYRIGHT_TICK                (ULONG)(((ULONG)COPYRIGHT_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   POWERUP_ENABLE_MEASURE_TICK   (UWORD)(((ULONG)POWERUP_ENABLE_MEASURE_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   POWERUP_DISABLE_MEASURE_TICK  (UWORD)(((ULONG)POWERUP_DISABLE_MEASURE_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   POWERUP_DISABLE_AMP_TICK      (UWORD)(((ULONG)POWERUP_DISABLE_AMP_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   POWERUP_ENABLE_AMP_TICK       (UWORD)(((ULONG)POWERUP_ENABLE_AMP_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   POWERUP_RECHARGE_TEST_TICK    (UWORD)(((ULONG)POWERUP_RECHARGE_TEST_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   ON_ARM_TIMEOUT_TICK           (UWORD)(((ULONG)ON_ARM_TIMEOUT_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   LED_TOGGLE_TICK               (UWORD)(((ULONG)LED_TOGGLE_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   CHECK_TEST_BUTTON_TICK        (UWORD)(((ULONG)CHECK_TEST_BUTTON_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   SAMBA_POWEROFF_TICK           (UWORD)(((ULONG)SAMBA_POWEROFF_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   SAMBA_BOOT_TICK               (UWORD)(((ULONG)SAMBA_BOOT_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   BUTTON_ACCEPT_TICK            (UWORD)(((ULONG)BUTTON_ACCEPT_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)
#define   POWEROFF_TICK                 (UWORD)(((ULONG)POWEROFF_TIME * 1000L) / (ULONG)INPUTPOWER_ONTIME)


// Use compiler to calculate counts from voltage
#define   ADC_REFERENCE                 5000L   // [mv]
#define   ADC_RESOLUTION                1023L   // [Count]
#define   RESISTOR_HIGH                 22000L  // [ohm]
#define   RESISTOR_LOW                  12000L  // [ohm]  
#define   RECHARGEABLE_SWITCH_COUNT     (UWORD)(((((RECHARGEABLE_SWITCH_VOLTAGE * RESISTOR_LOW) / (RESISTOR_LOW + RESISTOR_HIGH)) * ADC_RESOLUTION) / ADC_REFERENCE))
#define   ARM_POWERUP_MAX_COUNT         (UWORD)(((((ARM_POWERUP_MAX_VOLTAGE * RESISTOR_LOW) / (RESISTOR_LOW + RESISTOR_HIGH)) * ADC_RESOLUTION) / ADC_REFERENCE))
#define   ARM_ON_MAX_COUNT              (UWORD)(((((ARM_ON_MAX_VOLTAGE * RESISTOR_LOW) / (RESISTOR_LOW + RESISTOR_HIGH)) * ADC_RESOLUTION) / ADC_REFERENCE))
#define   ARM_ON_OK_COUNT               (UWORD)(((((ARM_ON_OK_VOLTAGE * RESISTOR_LOW) / (RESISTOR_LOW + RESISTOR_HIGH)) * ADC_RESOLUTION) / ADC_REFERENCE))
#define   ARM_ON_MIN_COUNT              (UWORD)(((((ARM_ON_MIN_VOLTAGE * RESISTOR_LOW) / (RESISTOR_LOW + RESISTOR_HIGH)) * ADC_RESOLUTION) / ADC_REFERENCE))

#define   TEST_BUTTON_VALUE             (ADC_RESOLUTION - 10)

// State machine states
enum      
{
  RESET,
  POWERUP,
    POWERUP_CHECK_FOR_RECHARGEABLE,
    POWERUP_CHECK_VOLTAGE_FOR_ARM_ON,
    POWERUP_DISABLE_AMP,
    POWERUP_TURN_ARM_ON,
    POWERUP_ENABLE_AMP,
    POWERUP_CHECK_RECHARGEABLE_VOLTAGE,
  ON,
    ON_RUNNING,
    ON_HIGH_VOLTAGE,
    ON_CHECK_BUTTON,
  SAMBA,
    SAMBA_ACTIVATE,
    SAMBA_TURN_ARM_OFF_AND_WAIT,
    SAMBA_TURN_ARM_ON_AND_WAIT,
    SAMBA_TURN_ARM_OFF_FOR_RESET,
    SAMBA_TURN_ARM_ON,
  POWERDOWN,
    POWERDOWN_DISABLE_AMP,
    POWERDOWN_TURN_ARM_OFF,
  OFF,
  SLEEP
};


UBYTE     State;
UBYTE     OldState;
UBYTE     OverwriteFloat;
UWORD     StateTimer;
UBYTE     Rechargeable;
UWORD     ArmTimer;
UBYTE     ArmFucked;
UBYTE     LedState;
UWORD     ButtonTimer;
ULONG     CopyRightTimer;


void      cArmCommInit(void)
{
  dPowerInit();
  dOutputInit();
  dInputInit();
  dButtonInit();
  dArmCommInit();
  dTimerInit();

  State     = RESET;
  OldState  = ~State;
}


UBYTE     cArmCommCtrl(void)
{
  UBYTE   Result = TRUE;

  // Update state machine if timeout (or RESET)
  if ((dTimerRead() >= INPUTPOWER_ONTICK) || (State == RESET))
  {
    dTimerClear();

    // Maintain StateTimer (clear if state changes else increament)
    if (State != OldState)
    {
      OldState   = State;
      StateTimer = 0;
    }
    else
    {
      StateTimer++;
    }

    // STATE MACHINE
    switch (State)
    {

      case RESET :
      {
        if (!StateTimer)
        {
          OverwriteFloat = TRUE;
          State          = POWERUP;
        }
      }
      break;

      case POWERUP :
      {
        State = POWERUP_CHECK_FOR_RECHARGEABLE;
      }
      break;

      case POWERUP_CHECK_FOR_RECHARGEABLE :
      {
        if (!StateTimer)
        {
          dPowerDeselect();
        }
        if (StateTimer >= POWERUP_DISABLE_MEASURE_TICK)
        {
          if (dPowerConvert() > RECHARGEABLE_SWITCH_COUNT)
          {
            Rechargeable = TRUE;
          }
          dPowerRechargeable(Rechargeable);
          State = POWERUP_CHECK_VOLTAGE_FOR_ARM_ON;
        }
      }
      break;

      case POWERUP_CHECK_VOLTAGE_FOR_ARM_ON :
      {
        if (!StateTimer)
        {
          dPowerSelect();
        }
        if (StateTimer >= POWERUP_ENABLE_MEASURE_TICK)
        {
          if (dPowerConvert() <= ARM_POWERUP_MAX_COUNT)
          {
            State = POWERUP_DISABLE_AMP;
          }
        }
      }
      break;

      case POWERUP_DISABLE_AMP :
      {
        if (!StateTimer)
        {
          dPowerDeselect();
        }
        if (StateTimer >= POWERUP_DISABLE_AMP_TICK)
        {
          State = POWERUP_TURN_ARM_ON;
        }
      }
      break;

      case POWERUP_TURN_ARM_ON :
      {
        dPowerWriteOn(TRUE);
        OverwriteFloat = FALSE;
        State = POWERUP_ENABLE_AMP;
      }
      break;

      case POWERUP_ENABLE_AMP :
      {
        if (StateTimer >= POWERUP_ENABLE_AMP_TICK)
        {
          dPowerSelect();
          State = POWERUP_CHECK_RECHARGEABLE_VOLTAGE;
        }
      }
      break;

      case POWERUP_CHECK_RECHARGEABLE_VOLTAGE :
      {
        if (Rechargeable == TRUE)
        {
          if (dPowerConvert() < ARM_ON_MIN_COUNT)
          {
            if (StateTimer >= POWERUP_RECHARGE_TEST_TICK)
            {
              State = OFF;
            }
          }
          else
          {
            State = ON;
          }
        }
        else
        {
          State = ON;
        }
      }
      break;

      case ON :
      {
        CopyRightTimer = 0L;
        State          = ON_RUNNING;
      }
      break;

      case ON_RUNNING :
      {

        // Read all inputs
        dInputSelect(0);
        dInputConvert(0);
        dInputConvert(0);
        dInputDeselect(0);

        dInputSelect(1);
        dInputConvert(1);
        dInputConvert(1);
        dInputDeselect(1);

        dInputSelect(2);
        dInputConvert(2);
        dInputConvert(2);
        dInputDeselect(2);

        dInputSelect(3);
        dInputConvert(3);
        dInputConvert(3);
        dInputDeselect(3);

        // Update buttons
        dButtonUpdate();

        // Check for ARM communication
        if (dArmCommCheck() == TRUE)
        {
          ArmTimer = 0;
          ArmFucked = FALSE;
        }

        if (ArmTimer >= ON_ARM_TIMEOUT_TICK)
        {
          ArmFucked = TRUE;
        }
        else
        {
          ArmTimer++;
        }

        // Check for high voltage
        dPowerSelect();
        if (dPowerConvert() > ARM_ON_MAX_COUNT)
        {
          State = ON_HIGH_VOLTAGE;
        }

        // Control led
        if (ArmFucked == TRUE)
        {
          if (StateTimer >= LED_TOGGLE_TICK)
          {
            StateTimer = 0;
            if (LedState == TRUE)
            {
              LedState = FALSE;
            }
            else
            {
              LedState = TRUE;
            }
          }
        }
        else
        {
          LedState = TRUE;
        }

        if (LedState == FALSE)
        {
          dPowerDeselect();
        }

        // Check for SAMBA request
        if (dPowerReadBoot() == TRUE)
        {
          State = SAMBA;
        }

        // Check for POWERDOWN request
        if (dPowerReadOn() == FALSE)
        {
          State = POWERDOWN;        
        }

        // Check for CopyRight valid
        if (dArmCommCopyRight() != TRUE)
        {
          if (++CopyRightTimer >= COPYRIGHT_TICK)
          {
            State = POWERDOWN;
          }
        }
      }
      break;

      case ON_HIGH_VOLTAGE :
      {
        dInputInit();
        dPowerWriteOn(FALSE);             
        OverwriteFloat = TRUE;
        ButtonTimer = CHECK_TEST_BUTTON_TICK;
        State = ON_CHECK_BUTTON;
      }
      break;

      case ON_CHECK_BUTTON :
      {
        dPowerSelect();
        if (ButtonTimer)
        {
          dPowerDeselect();
          if (dPowerConvert() >= TEST_BUTTON_VALUE)
          {
            ButtonTimer++;
            if (ButtonTimer > (CHECK_TEST_BUTTON_TICK * 2))
            {
              dPowerSelect();
              State = SAMBA;
            }
          }
          else
          {
            ButtonTimer--; 
          }
        }
        else
        {
          if (dPowerConvert() <= ARM_ON_OK_COUNT)
          {
            State = RESET;
          }
        }
      }
      break;

      case POWERDOWN :
      {
        State = POWERDOWN_DISABLE_AMP;
      }
      break;

      case POWERDOWN_DISABLE_AMP :
      {
        if (!StateTimer)
        {
          dPowerDeselect();
        }
        if (StateTimer >= POWERUP_DISABLE_AMP_TICK)
        {
          State = POWERDOWN_TURN_ARM_OFF;
        }
      }
      break;

      case POWERDOWN_TURN_ARM_OFF :
      {
        if (!StateTimer)
        {
          dPowerWriteOn(FALSE);
        }
        if (StateTimer >= POWEROFF_TICK)
        {
          State = OFF;
        }
      }
      break;

      case OFF :
      {
        State = SLEEP;
      }
      break;

      case SAMBA :
      {
        State = SAMBA_ACTIVATE;
      }
      break;

      case SAMBA_ACTIVATE :
      {
        if (++StateTimer >= BUTTON_ACCEPT_TICK)
        {
          State = SAMBA_TURN_ARM_OFF_AND_WAIT;
        }
      }
      break;

      case SAMBA_TURN_ARM_OFF_AND_WAIT :
      {
        if (!StateTimer)
        {
          dPowerHigh();
          dPowerDeselect();
          dPowerWriteOn(FALSE);
        }
        if (++StateTimer >= SAMBA_POWEROFF_TICK)
        {
          State = SAMBA_TURN_ARM_ON_AND_WAIT;
        }
      }
      break;

      case SAMBA_TURN_ARM_ON_AND_WAIT :
      {
        if (!StateTimer)
        {
          dPowerWriteOn(TRUE);                
        }
        if (++StateTimer >= SAMBA_BOOT_TICK)
        {
          State = SAMBA_TURN_ARM_OFF_FOR_RESET;
        }
      }
      break;

      case SAMBA_TURN_ARM_OFF_FOR_RESET :
      {
        if (!StateTimer)
        {
          dPowerWriteOn(FALSE);                
          dPowerFloat();
        }
        if (++StateTimer >= SAMBA_POWEROFF_TICK)
        {
          State = SAMBA_TURN_ARM_ON;
        }
      }
      break;

      case SAMBA_TURN_ARM_ON :
      {
        dPowerWriteOn(TRUE);                
        State          = ON;
      }
      break;

      case SLEEP :
      {
        Result = FALSE;
      }
      break;

    }
  }

  // Update allways output
  dOutputUpdate(OverwriteFloat);

  return(Result);
}


void      cArmCommExit(void)
{
  dTimerExit();
  dArmCommExit();
  dButtonExit();
  dInputExit();
  dOutputExit();
  dPowerExit();
}