// // 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(); }