############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:39 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\statefunc.c # # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\statefunc.c # # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IAR # # \Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debu # # g\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Li # # st\ --initializers_in_flash -z2 --no_cse --no_inline # # --no_code_motion --no_cross_call --no_clustering # # --no_tbaa --debug -DENABLE_BIT_DEFINITIONS -e # # --require_prototypes -I "C:\Program Files\IAR # # Systems\Embedded Workbench 4.0\avr\INC\" -I "C:\Program # # Files\IAR Systems\Embedded Workbench 4.0\avr\INC\CLIB\" # # --eeprom_size 512 # # List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\statefunc # # .lst # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\statefunc. # # r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100_cal\IAR\statefunc.c 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ 2 /*! \file ********************************************************************* 3 * 4 * \brief 5 * State functions 6 * 7 * Contains the functions related to the states defined in menu.h.\n 8 * Also contains related functions, i.e. for checking jumpers, setting 9 * error flags and "dozing". 10 * 11 * \note The state function Charge() is in a separate file since it 12 * should easily be changed with regard to battery type. 13 * 14 * \par Application note: 15 * AVR458: Charging Li-Ion Batteries with BC100 \n 16 * AVR463: Charging NiMH Batteries with BC100 17 * 18 * \par Documentation 19 * For comprehensive code documentation, supported compilers, compiler 20 * settings and supported devices see readme.html 21 * 22 * \author 23 * Atmel Corporation: http://www.atmel.com \n 24 * Support email: avr@atmel.com 25 * 26 * 27 * $Name$ 28 * $Revision: 2299 $ 29 * $RCSfile$ 30 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/statefunc.c $ 31 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n 32 ******************************************************************************/ 33 34 #include \ In segment ABSOLUTE, at 0x55 \ volatile __io _A_MCUCR \ _A_MCUCR: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x54 \ volatile __io _A_MCUSR \ _A_MCUSR: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x48 \ volatile __io _A_CLKPR \ _A_CLKPR: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x41 \ volatile __io _A_WDTCR \ _A_WDTCR: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x37 \ volatile __io _A_DDRB \ _A_DDRB: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x26 \ volatile __io _A_ADCSRA \ _A_ADCSRA: \ 00000000 DS 1 35 #include 36 #include 37 38 #include "structs.h" 39 #include "enums.h" 40 41 #include "ADC.h" 42 #include "statefunc.h" 43 #include "battery.h" 44 #include "charge.h" 45 #include "main.h" 46 #include "menu.h" 47 #include "OWI.h" 48 #include "PWM.h" 49 #include "time.h" 50 #include "USI.h" 51 52 53 //****************************************************************************** 54 // Variables 55 //****************************************************************************** \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 56 unsigned char ErrorFlags; //!< \brief Holds error flags. \ ErrorFlags: \ 00000000 DS 1 57 //!< \note See statefunc.h for definitions of flags. 58 59 //! \brief Holds the state in which latest error flag was set. 60 //! \note See menu.h for definitions of states. \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 61 unsigned char ErrorState; \ ErrorState: \ 00000000 DS 1 62 63 64 //****************************************************************************** 65 // Functions 66 //****************************************************************************** 67 /*! \brief Initialization 68 * 69 * - Sets the system clock prescaler to 1 (run at 8 MHz) 70 * - Initializes the one-wire interface 71 * - Clears on-chip EEPROM 72 * - Sets battery enable pins as outputs, then disables batteries 73 * - Initializes SPI according to \ref SPIMODE 74 * - Initializes ADC 75 * - Initializes timers 76 * - Reads battery data from both battery inputs (via ADC) 77 * - Disables batteries again 78 * - Sets battery A as the current one (\ref BattActive = 0) 79 * - Clears ErrorFlags 80 * 81 * \param inp Not used. 82 * 83 * \retval ST_BATCON Next state in the sequence. 84 */ \ In segment CODE, align 2, keep-with-next 85 unsigned char Initialize(unsigned char inp) \ Initialize: 86 { \ 00000000 .... RCALL ?PROLOGUE4_L09 \ 00000002 2FB0 MOV R27, R16 87 unsigned char i, page; 88 89 // Disable interrupts while setting prescaler. 90 __disable_interrupt(); \ 00000004 94F8 CLI 91 92 CLKPR = (1< 8 MHz clock frequency. \ 0000000A E000 LDI R16, 0 \ 0000000C BD08 OUT 0x28, R16 94 95 // Init 1-Wire(R) interface. 96 OWI_Init(OWIBUS); \ 0000000E E001 LDI R16, 1 \ 00000010 .... RCALL OWI_Init 97 98 // Clear on-chip EEPROM. 99 for (page = 0; page < 4; page++) { \ 00000012 E090 LDI R25, 0 \ ??Initialize_0: \ 00000014 3094 CPI R25, 4 \ 00000016 F4B8 BRCC ??Initialize_1 100 for (i = 0; i < 32; i++) { \ 00000018 E080 LDI R24, 0 \ ??Initialize_2: \ 0000001A 3280 CPI R24, 32 \ 0000001C F490 BRCC ??Initialize_3 101 BattEEPROM[page][i] = 0; \ 0000001E E0A0 LDI R26, 0 \ 00000020 2F49 MOV R20, R25 \ 00000022 E050 LDI R21, 0 \ 00000024 E200 LDI R16, 32 \ 00000026 E010 LDI R17, 0 \ 00000028 .... RCALL ?S_MUL_L02 \ 0000002A .... LDI R20, LOW(BattEEPROM) \ 0000002C .... LDI R21, (BattEEPROM) >> 8 \ 0000002E 0F40 ADD R20, R16 \ 00000030 1F51 ADC R21, R17 \ 00000032 2F08 MOV R16, R24 \ 00000034 E010 LDI R17, 0 \ 00000036 0F40 ADD R20, R16 \ 00000038 1F51 ADC R21, R17 \ 0000003A 2F0A MOV R16, R26 \ 0000003C .... RCALL __eeput8_16 102 } \ 0000003E 9583 INC R24 \ 00000040 CFEC RJMP ??Initialize_2 103 } \ ??Initialize_3: \ 00000042 9593 INC R25 \ 00000044 CFE7 RJMP ??Initialize_0 104 105 DDRB = (1<> 8 \ 00000012 .... RCALL __eeget8_16 \ 00000014 7001 ANDI R16, 0x01 \ 00000016 2300 TST R16 \ 00000018 F451 BRNE ??BatteryControl_2 \ 0000001A .... LDI R20, LOW((BattControl + 1)) \ 0000001C .... LDI R21, HIGH((BattControl + 1)) \ 0000001E .... RCALL __eeget8_16 \ 00000020 7001 ANDI R16, 0x01 \ 00000022 2300 TST R16 \ 00000024 F421 BRNE ??BatteryControl_2 156 SetErrorFlag(ERR_NO_BATTERIES_ENABLED); \ 00000026 E002 LDI R16, 2 \ 00000028 .... RCALL SetErrorFlag 157 158 return(ST_ERROR); \ 0000002A E50A LDI R16, 90 \ 0000002C C01E RJMP ??BatteryControl_1 159 } 160 161 // Get ADC-readings, try to read EPROM, and start prequalification 162 // of any uncharged battery. 163 for (i = 0; i < 2; i++) { \ ??BatteryControl_2: \ 0000002E E080 LDI R24, 0 \ ??BatteryControl_3: \ 00000030 3082 CPI R24, 2 \ 00000032 F4C8 BRCC ??BatteryControl_4 164 if (BattControl[i].Enabled) { \ 00000034 E090 LDI R25, 0 \ 00000036 .... LDI R20, LOW(BattControl) \ 00000038 .... LDI R21, (BattControl) >> 8 \ 0000003A 0F48 ADD R20, R24 \ 0000003C 1F59 ADC R21, R25 \ 0000003E .... RCALL __eeget8_16 \ 00000040 7001 ANDI R16, 0x01 \ 00000042 2300 TST R16 \ 00000044 F071 BREQ ??BatteryControl_5 165 EnableBattery(i); \ 00000046 2F08 MOV R16, R24 \ 00000048 .... RCALL EnableBattery 166 ADC_Wait(); \ 0000004A .... RCALL ADC_Wait 167 168 if (BatteryStatusRefresh()) { \ 0000004C .... RCALL BatteryStatusRefresh \ 0000004E 2300 TST R16 \ 00000050 F041 BREQ ??BatteryControl_5 169 if (!BattData.Charged) { \ 00000052 .... LDI R30, LOW(BattData) \ 00000054 .... LDI R31, (BattData) >> 8 \ 00000056 8100 LD R16, Z \ 00000058 FD01 SBRC R16, 1 \ 0000005A C003 RJMP ??BatteryControl_5 170 BatteryDataRefresh(); \ 0000005C .... RCALL BatteryDataRefresh 171 172 return(ST_PREQUAL); \ 0000005E E10E LDI R16, 30 \ 00000060 C004 RJMP ??BatteryControl_1 173 } 174 } 175 } 176 } \ ??BatteryControl_5: \ 00000062 9583 INC R24 \ 00000064 CFE5 RJMP ??BatteryControl_3 177 178 // If we end up here, one or two batteries are found and fully charged. 179 // Disconnect, so we don't drain them, and go to sleep. 180 DisableBatteries(); \ ??BatteryControl_4: \ 00000066 .... RCALL DisableBatteries 181 182 return(ST_SLEEP); \ 00000068 E208 LDI R16, 40 \ ??BatteryControl_1: \ 0000006A E0E3 LDI R30, 3 \ 0000006C .... RJMP ?EPILOGUE_B3_L09 183 } 184 185 186 /*! \brief Start running on batteries 187 * 188 * \todo Run on batteries, if battery voltage high enough. 189 * \todo Jump here when mains voltage drops below threshold 190 * 191 */ \ In segment CODE, align 2, keep-with-next 192 unsigned char Discharge(unsigned char inp) \ Discharge: 193 { \ 00000000 2F10 MOV R17, R16 194 return(ST_BATCON); // Supply voltage restored, start charging \ 00000002 E104 LDI R16, 20 \ 00000004 9508 RET 195 } 196 197 198 /*! \brief Sleeps until either battery needs charging 199 * 200 * Calls Doze(), then refreshes the status for both batteries on wakeup. If 201 * connected batteries are both charged, the function will loop. If not, it's 202 * back to ST_BATCON. 203 * 204 * \param inp Not used. 205 * 206 * \retval ST_BATCON Next state if a connected battery isn't fully charged. 207 */ \ In segment CODE, align 2, keep-with-next 208 unsigned char Sleep(unsigned char inp) \ `Sleep`: 209 { \ 00000000 .... RCALL ?PROLOGUE2_L09 \ 00000002 2F90 MOV R25, R16 210 unsigned char i; 211 212 do { 213 Doze(); // Take a nap (~8 seconds). \ ??Sleep_0: \ 00000004 .... RCALL Doze 214 215 // If any batteries need charging, go to ST_BATCON. 216 // Otherwise, keep sleeping. 217 for (i = 0; i < 2; i++) { \ 00000006 E080 LDI R24, 0 \ ??Sleep_1: \ 00000008 3082 CPI R24, 2 \ 0000000A F478 BRCC ??Sleep_2 218 EnableBattery(i); \ 0000000C 2F08 MOV R16, R24 \ 0000000E .... RCALL EnableBattery 219 ADC_Wait(); \ 00000010 .... RCALL ADC_Wait 220 if ((BatteryStatusRefresh()) && (!BattData.Charged)) { \ 00000012 .... RCALL BatteryStatusRefresh \ 00000014 2300 TST R16 \ 00000016 F039 BREQ ??Sleep_3 \ 00000018 .... LDI R30, LOW(BattData) \ 0000001A .... LDI R31, (BattData) >> 8 \ 0000001C 8100 LD R16, Z \ 0000001E FD01 SBRC R16, 1 \ 00000020 C002 RJMP ??Sleep_3 221 return(ST_BATCON); \ 00000022 E104 LDI R16, 20 \ 00000024 C004 RJMP ??Sleep_4 \ ??Sleep_3: \ 00000026 9583 INC R24 \ 00000028 CFEF RJMP ??Sleep_1 222 } 223 } 224 225 DisableBatteries(); // Disable both batteries before Doze()! \ ??Sleep_2: \ 0000002A .... RCALL DisableBatteries 226 } while (TRUE); \ 0000002C CFEB RJMP ??Sleep_0 \ ??Sleep_4: \ 0000002E E0E2 LDI R30, 2 \ 00000030 .... RJMP ?EPILOGUE_B2_L09 227 } 228 229 230 /*! \brief Doze off for approx. 8 seconds (Vcc = 5 V) 231 * 232 * Waits for ADC-cycles to complete, disables the ADC, then sleeps for 233 * approx. 8 seconds (Vcc = 5 V) using the watchdog timer. 234 * On wakeup, ADC is re-enabled. 235 */ \ In segment CODE, align 2, keep-with-next 236 void Doze(void) \ Doze: 237 { 238 // Wait for this ADC cycle to complete, then halt after the next one. 239 ADC_Wait(); \ 00000000 .... RCALL ADC_Wait 240 ADCS.Halt = TRUE; \ 00000002 .... LDI R30, LOW(ADCS) \ 00000004 .... LDI R31, (ADCS) >> 8 \ 00000006 8100 LD R16, Z \ 00000008 6800 ORI R16, 0x80 \ 0000000A 8300 ST Z, R16 241 ADCS.Flag = FALSE; \ 0000000C .... LDI R30, LOW(ADCS) \ 0000000E .... LDI R31, (ADCS) >> 8 \ 00000010 8100 LD R16, Z \ 00000012 7D0F ANDI R16, 0xDF \ 00000014 8300 ST Z, R16 242 243 do { 244 } while (ADCS.Flag == FALSE); \ ??Doze_0: \ 00000016 .... LDI R30, LOW(ADCS) \ 00000018 .... LDI R31, (ADCS) >> 8 \ 0000001A 8100 LD R16, Z \ 0000001C FF05 SBRS R16, 5 \ 0000001E CFFB RJMP ??Doze_0 245 246 WDTCR = (1<> 8 \ 00000048 8100 LD R16, Z \ 0000004A 770F ANDI R16, 0x7F \ 0000004C 8300 ST Z, R16 257 ADCSRA |= (1<> 8 \ 0000003E 8110 LD R17, Z \ 00000040 2310 AND R17, R16 \ 00000042 8310 ST Z, R17 305 JumperCheck(); \ 00000044 .... RCALL JumperCheck \ 00000046 C03A RJMP ??Error_3 306 break; 307 308 309 case ERR_NO_BATTERIES_ENABLED: 310 // Clear if any battery gets enabled. 311 if ((BattControl[0].Enabled) || (BattControl[1].Enabled)) { \ ??Error_5: \ 00000048 .... LDI R20, LOW(BattControl) \ 0000004A .... LDI R21, (BattControl) >> 8 \ 0000004C .... RCALL __eeget8_16 \ 0000004E 7001 ANDI R16, 0x01 \ 00000050 2300 TST R16 \ 00000052 F431 BRNE ??Error_9 \ 00000054 .... LDI R20, LOW((BattControl + 1)) \ 00000056 .... LDI R21, HIGH((BattControl + 1)) \ 00000058 .... RCALL __eeget8_16 \ 0000005A 7001 ANDI R16, 0x01 \ 0000005C 2300 TST R16 \ 0000005E F171 BREQ ??Error_3 312 ErrorFlags &= ~i; \ ??Error_9: \ 00000060 2F08 MOV R16, R24 \ 00000062 9500 COM R16 \ 00000064 .... LDI R30, LOW(ErrorFlags) \ 00000066 .... LDI R31, (ErrorFlags) >> 8 \ 00000068 8110 LD R17, Z \ 0000006A 2310 AND R17, R16 \ 0000006C 8310 ST Z, R17 \ 0000006E C026 RJMP ??Error_3 313 } 314 break; 315 316 317 case ERR_PWM_CONTROL: 318 // Clear flag. 319 ErrorFlags &= ~i; \ ??Error_6: \ 00000070 2F08 MOV R16, R24 \ 00000072 9500 COM R16 \ 00000074 .... LDI R30, LOW(ErrorFlags) \ 00000076 .... LDI R31, (ErrorFlags) >> 8 \ 00000078 8110 LD R17, Z \ 0000007A 2310 AND R17, R16 \ 0000007C 8310 ST Z, R17 \ 0000007E C01E RJMP ??Error_3 320 break; 321 322 323 case ERR_BATTERY_TEMPERATURE: 324 // Clear flag. 325 ErrorFlags &= ~i; \ ??Error_7: \ 00000080 2F08 MOV R16, R24 \ 00000082 9500 COM R16 \ 00000084 .... LDI R30, LOW(ErrorFlags) \ 00000086 .... LDI R31, (ErrorFlags) >> 8 \ 00000088 8110 LD R17, Z \ 0000008A 2310 AND R17, R16 \ 0000008C 8310 ST Z, R17 \ 0000008E C016 RJMP ??Error_3 326 break; 327 328 329 case ERR_BATTERY_EXHAUSTED: 330 // Try the other battery. 331 BattData.Exhausted = FALSE; \ ??Error_8: \ 00000090 .... LDI R30, LOW(BattData) \ 00000092 .... LDI R31, (BattData) >> 8 \ 00000094 8100 LD R16, Z \ 00000096 7F07 ANDI R16, 0xF7 \ 00000098 8300 ST Z, R16 332 BattActive = (BattActive + 1) % 2; \ 0000009A 91E0.... LDS R30, BattActive \ 0000009E E0F0 LDI R31, 0 \ 000000A0 9631 ADIW R31:R30, 1 \ 000000A2 018F MOVW R17:R16, R31:R30 \ 000000A4 E042 LDI R20, 2 \ 000000A6 E050 LDI R21, 0 \ 000000A8 .... RCALL ?SS_DIVMOD_L02 \ 000000AA 9340.... STS BattActive, R20 333 ErrorFlags &= ~i; \ 000000AE 2F08 MOV R16, R24 \ 000000B0 9500 COM R16 \ 000000B2 .... LDI R30, LOW(ErrorFlags) \ 000000B4 .... LDI R31, (ErrorFlags) >> 8 \ 000000B6 8110 LD R17, Z \ 000000B8 2310 AND R17, R16 \ 000000BA 8310 ST Z, R17 334 break; 335 336 337 default: 338 break; 339 } 340 } 341 } \ ??Error_3: \ 000000BC 0F88 LSL R24 \ 000000BE CFA6 RJMP ??Error_1 342 } while (ErrorFlags); \ ??Error_2: \ 000000C0 9100.... LDS R16, ErrorFlags \ 000000C4 2300 TST R16 \ 000000C6 F009 BREQ $+2+2 \ 000000C8 CF9F RJMP ??Error_0 343 344 return(ST_INIT); \ 000000CA E00A LDI R16, 10 \ 000000CC E0E2 LDI R30, 2 \ 000000CE .... RJMP ?EPILOGUE_B2_L09 345 } 346 347 348 /*! \brief Sets the specified error-flag and saves the current state 349 * 350 * Updates \ref ErrorFlags and \ref ErrorState. 351 * 352 * \note Error flags are specified in statefunc.h. 353 * 354 * \param Flag Specifies what error to flag. 355 */ \ In segment CODE, align 2, keep-with-next 356 void SetErrorFlag(unsigned char Flag) \ SetErrorFlag: 357 { 358 ErrorFlags |= Flag; \ 00000000 .... LDI R30, LOW(ErrorFlags) \ 00000002 .... LDI R31, (ErrorFlags) >> 8 \ 00000004 8110 LD R17, Z \ 00000006 2B10 OR R17, R16 \ 00000008 8310 ST Z, R17 359 ErrorState = CurrentState; \ 0000000A 9110.... LDS R17, CurrentState \ 0000000E 9310.... STS ErrorState, R17 360 } \ 00000012 9508 RET 361 362 363 /*! \brief Checks on-board jumpers. 364 * 365 * Checks on-board jumpers by disconnecting all loads, engaging the PWM and 366 * increasing the duty cycle until conditioned output voltage equals conditioned 367 * input voltage. At low PWM duty and no load buck output should be zero and, 368 * when increasing PWM duty, should quickly jump to steady state output roughly 369 * equal to input voltage. Will disable and leave disabled all batteries. 370 * 371 * \retval FALSE If jumper or load mismatch. 372 * \retval TRUE If everything OK. 373 */ \ In segment CODE, align 2, keep-with-next 374 unsigned char JumperCheck(void) \ JumperCheck: 375 { 376 DisableBatteries(); // Disconnect, or loads may be destroyed! \ 00000000 .... RCALL DisableBatteries 377 378 PWM_Start(); // Start PWM (controls the buck charger). \ 00000002 .... RCALL PWM_Start 379 380 // Use general timer: shouldn't take longer than (6 x 255) / 2500 ~= 0.62s. 381 Time_Set(TIMER_GEN,0,1,0); \ 00000004 E040 LDI R20, 0 \ 00000006 E011 LDI R17, 1 \ 00000008 E020 LDI R18, 0 \ 0000000A E030 LDI R19, 0 \ 0000000C E002 LDI R16, 2 \ 0000000E .... RCALL Time_Set 382 383 do { 384 // If the PWM output voltage saturates the ADC, stop PWM output and 385 // report a failure. 386 if (ADCS.rawVBAT == 1023) { \ ??JumperCheck_0: \ 00000010 .... LDI R30, LOW(ADCS) \ 00000012 .... LDI R31, (ADCS) >> 8 \ 00000014 8106 LDD R16, Z+6 \ 00000016 8117 LDD R17, Z+7 \ 00000018 3F0F CPI R16, 255 \ 0000001A E023 LDI R18, 3 \ 0000001C 0712 CPC R17, R18 \ 0000001E F419 BRNE ??JumperCheck_1 387 PWM_Stop(); \ 00000020 .... RCALL PWM_Stop 388 return(FALSE); \ 00000022 E000 LDI R16, 0 \ 00000024 9508 RET 389 } 390 391 // If the absolute difference between measured (VIN - VBAT) and the 392 // typical value are below our set maximum, everything is OK. 393 if (abs((signed int)(ADCS.VIN - VIN_VBAT_DIFF_TYP - ADCS.VBAT)) < 394 VIN_VBAT_DIFF_MAX ) { \ ??JumperCheck_1: \ 00000026 .... LDI R30, LOW(ADCS) \ 00000028 .... LDI R31, (ADCS) >> 8 \ 0000002A 8500 LDD R16, Z+8 \ 0000002C 8511 LDD R17, Z+9 \ 0000002E 5508 SUBI R16, 88 \ 00000030 4012 SBCI R17, 2 \ 00000032 .... LDI R30, LOW(ADCS) \ 00000034 .... LDI R31, (ADCS) >> 8 \ 00000036 8522 LDD R18, Z+10 \ 00000038 8533 LDD R19, Z+11 \ 0000003A 1B02 SUB R16, R18 \ 0000003C 0B13 SBC R17, R19 \ 0000003E .... RCALL abs \ 00000040 3F04 CPI R16, 244 \ 00000042 E021 LDI R18, 1 \ 00000044 0712 CPC R17, R18 \ 00000046 F41C BRGE ??JumperCheck_2 395 396 PWM_Stop(); \ 00000048 .... RCALL PWM_Stop 397 return(TRUE); \ 0000004A E001 LDI R16, 1 \ 0000004C 9508 RET 398 } 399 400 // Charge current is too high -> check load and jumper J405 and J406. 401 if (abs(ADCS.IBAT) > 100) { \ ??JumperCheck_2: \ 0000004E .... LDI R30, LOW(ADCS) \ 00000050 .... LDI R31, (ADCS) >> 8 \ 00000052 8504 LDD R16, Z+12 \ 00000054 8515 LDD R17, Z+13 \ 00000056 .... RCALL abs \ 00000058 3605 CPI R16, 101 \ 0000005A E020 LDI R18, 0 \ 0000005C 0712 CPC R17, R18 \ 0000005E F01C BRLT ??JumperCheck_3 402 PWM_Stop(); \ 00000060 .... RCALL PWM_Stop 403 return(FALSE); \ 00000062 E000 LDI R16, 0 \ 00000064 9508 RET 404 } 405 406 // If the PWM output can't be increased high enough -> check jumpers 407 // J400-J404, J407 and J408. 408 if (!PWM_IncrementDutyCycle()) { \ ??JumperCheck_3: \ 00000066 .... RCALL PWM_IncrementDutyCycle \ 00000068 2300 TST R16 \ 0000006A F419 BRNE ??JumperCheck_4 409 PWM_Stop(); \ 0000006C .... RCALL PWM_Stop 410 return(FALSE); \ 0000006E E000 LDI R16, 0 \ 00000070 9508 RET 411 } 412 413 // Wait for ADC conversions to complete 414 ADC_Wait(); \ ??JumperCheck_4: \ 00000072 .... RCALL ADC_Wait 415 } while (Time_Left(TIMER_GEN)); \ 00000074 E002 LDI R16, 2 \ 00000076 .... RCALL Time_Left \ 00000078 2300 TST R16 \ 0000007A F651 BRNE ??JumperCheck_0 416 417 418 // If we end up here, the measurements took too long. 419 PWM_Stop(); \ 0000007C .... RCALL PWM_Stop 420 return(FALSE); \ 0000007E E000 LDI R16, 0 \ 00000080 9508 RET 421 } Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ BatteryControl 3 4 -> JumperCheck 3 2 -> SetErrorFlag 3 2 -> EnableBattery 3 2 -> ADC_Wait 3 2 -> BatteryStatusRefresh 3 2 -> BatteryDataRefresh 3 2 -> DisableBatteries 3 2 Discharge 0 2 Doze 0 2 -> ADC_Wait 0 2 -> ADC_Wait 0 2 Error 2 4 -> PWM_Stop 2 2 -> DisableBatteries 2 2 -> Doze 2 2 -> JumperCheck 2 2 Initialize 4 4 -> OWI_Init 4 2 -> DisableBatteries 4 2 -> SPI_Init 4 2 -> ADC_Init 4 2 -> Time_Init 4 2 -> EnableBattery 4 2 -> ADC_Wait 4 2 -> BatteryStatusRefresh 4 2 -> DisableBatteries 4 2 JumperCheck 0 2 -> DisableBatteries 0 2 -> PWM_Start 0 2 -> Time_Set 0 2 -> PWM_Stop 0 2 -> abs 0 2 -> PWM_Stop 0 2 -> abs 0 2 -> PWM_Stop 0 2 -> PWM_IncrementDutyCycle 0 2 -> PWM_Stop 0 2 -> ADC_Wait 0 2 -> Time_Left 0 2 -> PWM_Stop 0 2 SetErrorFlag 0 2 Sleep 2 2 -> Doze 2 2 -> EnableBattery 2 2 -> ADC_Wait 2 2 -> BatteryStatusRefresh 2 2 -> DisableBatteries 2 2 Segment part sizes: Function/Label Bytes -------------- ----- _A_MCUCR 1 _A_MCUSR 1 _A_CLKPR 1 _A_WDTCR 1 _A_DDRB 1 _A_ADCSRA 1 ErrorFlags 1 ErrorState 1 Initialize 122 BatteryControl 110 Discharge 6 Sleep 50 Doze 88 Error 208 SetErrorFlag 20 JumperCheck 130 Others 6 6 bytes in segment ABSOLUTE 734 bytes in segment CODE 6 bytes in segment INITTAB 2 bytes in segment NEAR_Z 734 bytes of CODE memory (+ 6 bytes shared) 2 bytes of DATA memory (+ 6 bytes shared) Errors: none Warnings: none