From ba78bd9ba834260d035a9830726afc34fdad2a15 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 18 Oct 2009 23:32:54 +0200 Subject: import firmware from LEGO v1.05 --- ATmega48/Source/c_armcomm.c | 601 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 601 insertions(+) create mode 100644 ATmega48/Source/c_armcomm.c (limited to 'ATmega48/Source/c_armcomm.c') diff --git a/ATmega48/Source/c_armcomm.c b/ATmega48/Source/c_armcomm.c new file mode 100644 index 0000000..6d5853d --- /dev/null +++ b/ATmega48/Source/c_armcomm.c @@ -0,0 +1,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(); +} -- cgit v1.2.3