############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:38 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\battery.c # # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\battery.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\battery.l # # st # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\battery.r9 # # 0 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100_cal\IAR\battery.c 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ 2 /*! \file ********************************************************************* 3 * 4 * \brief 5 * Functions related to battery control and data acquisition. 6 * 7 * Contains functions for enabling/disabling batteries, and looking up 8 * their status and specifications using the ADC. 9 * 10 * \par Application note: 11 * AVR458: Charging Li-Ion Batteries with BC100 \n 12 * AVR463: Charging NiMH Batteries with BC100 13 14 * 15 * \par Documentation 16 * For comprehensive code documentation, supported compilers, compiler 17 * settings and supported devices see readme.html 18 * 19 * \author 20 * Atmel Corporation: http://www.atmel.com \n 21 * Support email: avr@atmel.com 22 * 23 * 24 * $Name$ 25 * $Revision: 2299 $ 26 * $RCSfile$ 27 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/battery.c $ 28 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n 29 ******************************************************************************/ 30 31 #include \ In segment ABSOLUTE, at 0x4c \ volatile __io _A_OCR1B \ _A_OCR1B: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x38 \ volatile __io _A_PORTB \ _A_PORTB: \ 00000000 DS 1 32 #include 33 34 #include "structs.h" 35 #include "enums.h" 36 37 #include "ADC.h" 38 #include "battery.h" 39 #include "main.h" 40 #include "OWI.h" 41 #include "time.h" 42 43 #ifdef NIMH 44 #include "NIMHspecs.h" 45 #endif // NIMH 46 47 #ifdef LIION 48 #include "LIIONspecs.h" 49 #endif // LIION 50 51 52 53 //****************************************************************************** 54 // Variables 55 //****************************************************************************** 56 /* Control-struct for batteries */ 57 /*! \brief Holds control data for both batteries 58 * \note Stored in EEPROM. 59 */ \ In segment EEPROM_I, align 1, keep-with-next 60 __eeprom Battery_t BattControl[2] = {{TRUE, TRUE, FALSE}, \ BattControl: \ 00000000 0303 DB 3, 3 61 {TRUE, TRUE, FALSE}}; 62 63 /* Data-struct for battery */ \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 64 Batteries_t BattData; //!< Holds data for the current battery \ BattData: \ 00000000 DS 12 65 66 67 /* Storage for battery EPROM */ 68 /*! \brief Storage space for data from the batteries' own EPROMs. 69 * \note Stored in EEPROM. 70 */ \ In segment EEPROM_I, align 1, keep-with-next 71 __eeprom unsigned char BattEEPROM[4][32]; \ BattEEPROM: \ 00000000 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000010 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000020 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000030 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000040 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000050 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000060 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 \ 00000070 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ 000000000000 \ 00000000 72 73 74 //! Global that indicates current battery (0 = battery A, 1 = B) \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 75 unsigned char BattActive; \ BattActive: \ 00000000 DS 1 76 77 78 /*! \brief RID lookup-table 79 * 80 * Contains Resistor ID data specified by manufacturer. 81 * 82 * \note Values have been calculated assuming a +/- 15% tolerance. 83 */ \ In segment NEAR_I, align 1, keep-with-next \ 00000000 REQUIRE `?` 84 const RID_Lookup_t RID[RID_TABLE_SIZE] = { \ RID: \ 00000000 DS 56 \ 00000038 REQUIRE `?` 85 {558, 659, 3900, 550, 260, 300, 10}, 86 {744, 843, 6800, 750, 360, 300, 14}, 87 {869, 958, 10000, 1000, 475, 300, 19}, 88 {1097, 1153, 24000, 2000, 475, 420, 38} 89 }; 90 91 92 /*! \brief NTC lookup-table 93 * 94 * The first entry is 0 degrees. For every entry after, temperature increases 95 * with 4 degrees. With 20 entries, the last one equals (20-1)*4 = 76 degrees.\n 96 * It must be sorted in descending ADC order. 97 * 98 * \note This was calculated for a Mitsubishi RH16-3H103FB NTC. 99 * 100 * \note NTCLookUp() must be modified if this table is changed so that: 101 * - first entry is no longer 0 degrees. 102 * - temperature difference between entries is no longer 4 degrees. 103 * - ADCsteps no longer specifies ADC steps per half degree. 104 */ 105 // FOR VARTA POLYFLEX NTC \ In segment NEAR_I, align 1, keep-with-next \ 00000000 REQUIRE `?` 106 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = { \ NTC: \ 00000000 DS 60 \ 0000003C REQUIRE `?` 107 {1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27}, 108 {742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24}, 109 {494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17}, 110 {310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10} 111 }; 112 113 114 // FOR MITSUBISHI NTC 115 /* 116 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = { 117 {1004, 24}, {954, 25}, {903, 26}, {850, 27}, {796, 27}, 118 {742, 27}, {689, 27}, {637, 26}, {587, 25}, {539, 24}, 119 {493, 22}, {451, 21}, {411, 20}, {374, 18}, {340, 17}, 120 {309, 15}, {281, 14}, {255, 13}, {232, 11}, {211, 10} 121 }; 122 */ 123 124 125 //****************************************************************************** 126 // Functions 127 //****************************************************************************** 128 /*! \brief Checks if battery has changed 129 * 130 * Stores current capacity, then attempts to refresh battery status.\n 131 * If the refresh is successful, old capacity is compared with the new one. 132 * 133 * \retval FALSE Battery is disconnected, or capacity has changed. 134 * \retval TRUE All OK. 135 */ \ In segment CODE, align 2, keep-with-next 136 unsigned char BatteryCheck(void) \ BatteryCheck: 137 { \ 00000000 .... RCALL ?PROLOGUE4_L09 138 unsigned char success = TRUE; \ 00000002 E081 LDI R24, 1 139 unsigned int oldCapacity; 140 141 // Save to see if battery data has changed. 142 oldCapacity = BattData.Capacity; \ 00000004 .... LDI R30, LOW(BattData) \ 00000006 .... LDI R31, (BattData) >> 8 \ 00000008 8104 LDD R16, Z+4 \ 0000000A 8115 LDD R17, Z+5 \ 0000000C 01D8 MOVW R27:R26, R17:R16 143 144 if (!BatteryStatusRefresh()) { \ 0000000E .... RCALL BatteryStatusRefresh \ 00000010 2300 TST R16 \ 00000012 F409 BRNE ??BatteryCheck_0 145 success = FALSE; // Battery not present or RID was invalid. \ 00000014 E080 LDI R24, 0 146 } 147 148 if (oldCapacity != BattData.Capacity) { \ ??BatteryCheck_0: \ 00000016 .... LDI R30, LOW(BattData) \ 00000018 .... LDI R31, (BattData) >> 8 \ 0000001A 8104 LDD R16, Z+4 \ 0000001C 8115 LDD R17, Z+5 \ 0000001E 17A0 CP R26, R16 \ 00000020 07B1 CPC R27, R17 \ 00000022 F009 BREQ ??BatteryCheck_1 149 success = FALSE; // Battery configuration has changed. \ 00000024 E080 LDI R24, 0 150 } 151 152 return(success); \ ??BatteryCheck_1: \ 00000026 2F08 MOV R16, R24 \ 00000028 E0E4 LDI R30, 4 \ 0000002A .... RJMP ?EPILOGUE_B4_L09 153 } 154 155 156 /*! \brief Refreshes battery status information 157 * 158 * Refreshes battery status information, if it is present, based on 159 * RID and NTC (read by ADC).\n 160 * The battery must have been enabled and a complete set of ADC data must have 161 * been collected before calling.\n 162 * 163 * \retval FALSE No battery present. 164 * \retval TRUE Battery present, status refreshed. 165 * 166 * \note If ALLOW_NO_RID is defined, charging will NOT stop if no fitting entry 167 * is found in the lookup table. Instead, default battery data will be used. 168 */ \ In segment CODE, align 2, keep-with-next 169 unsigned char BatteryStatusRefresh(void) \ BatteryStatusRefresh: 170 { \ 00000000 .... RCALL ?PROLOGUE4_L09 171 // Assume the worst.. 172 unsigned char success = FALSE; \ 00000002 E080 LDI R24, 0 173 174 BattData.Present = FALSE; \ 00000004 .... LDI R30, LOW(BattData) \ 00000006 .... LDI R31, (BattData) >> 8 \ 00000008 8100 LD R16, Z \ 0000000A 7F0E ANDI R16, 0xFE \ 0000000C 8300 ST Z, R16 175 BattData.Charged = FALSE; \ 0000000E .... LDI R30, LOW(BattData) \ 00000010 .... LDI R31, (BattData) >> 8 \ 00000012 8100 LD R16, Z \ 00000014 7F0D ANDI R16, 0xFD \ 00000016 8300 ST Z, R16 176 BattData.Low = TRUE; \ 00000018 .... LDI R30, LOW(BattData) \ 0000001A .... LDI R31, (BattData) >> 8 \ 0000001C 8100 LD R16, Z \ 0000001E 6004 ORI R16, 0x04 \ 00000020 8300 ST Z, R16 177 BattData.Circuit = OW_NONE; \ 00000022 E000 LDI R16, 0 \ 00000024 9300.... STS (BattData + 1), R16 178 BattData.Temperature = 0; \ 00000028 E000 LDI R16, 0 \ 0000002A 9300.... STS (BattData + 2), R16 179 BattData.Capacity = 0; \ 0000002E E000 LDI R16, 0 \ 00000030 E010 LDI R17, 0 \ 00000032 .... LDI R30, LOW(BattData) \ 00000034 .... LDI R31, (BattData) >> 8 \ 00000036 8304 STD Z+4, R16 \ 00000038 8315 STD Z+5, R17 180 BattData.MaxCurrent = 0; \ 0000003A E000 LDI R16, 0 \ 0000003C E010 LDI R17, 0 \ 0000003E .... LDI R30, LOW(BattData) \ 00000040 .... LDI R31, (BattData) >> 8 \ 00000042 8306 STD Z+6, R16 \ 00000044 8317 STD Z+7, R17 181 BattData.MaxTime = 0; \ 00000046 E000 LDI R16, 0 \ 00000048 E010 LDI R17, 0 \ 0000004A .... LDI R30, LOW(BattData) \ 0000004C .... LDI R31, (BattData) >> 8 \ 0000004E 8700 STD Z+8, R16 \ 00000050 8711 STD Z+9, R17 182 BattData.MinCurrent = 0; \ 00000052 E000 LDI R16, 0 \ 00000054 E010 LDI R17, 0 \ 00000056 .... LDI R30, LOW(BattData) \ 00000058 .... LDI R31, (BattData) >> 8 \ 0000005A 8702 STD Z+10, R16 \ 0000005C 8713 STD Z+11, R17 183 184 NTCLookUp(); \ 0000005E .... RCALL NTCLookUp 185 BattData.HasRID = RIDLookUp(); \ 00000060 .... RCALL RIDLookUp \ 00000062 2F10 MOV R17, R16 \ 00000064 7011 ANDI R17, 0x01 \ 00000066 .... LDI R30, LOW(BattData) \ 00000068 .... LDI R31, (BattData) >> 8 \ 0000006A FB10 BST R17, 0 \ 0000006C 8100 LD R16, Z \ 0000006E F904 BLD R16, 4 \ 00000070 8300 ST Z, R16 \ 00000072 E000 LDI R16, 0 \ 00000074 F900 BLD R16, 0 186 187 // Is the battery voltage above minimum safe cell voltage? 188 if (ADCS.VBAT >= BAT_VOLTAGE_MIN) { \ 00000076 .... LDI R30, LOW(ADCS) \ 00000078 .... LDI R31, (ADCS) >> 8 \ 0000007A 8502 LDD R16, Z+10 \ 0000007C 8513 LDD R17, Z+11 \ 0000007E 3600 CPI R16, 96 \ 00000080 E029 LDI R18, 9 \ 00000082 0712 CPC R17, R18 \ 00000084 F028 BRCS ??BatteryStatusRefresh_0 189 BattData.Low = FALSE; \ 00000086 .... LDI R30, LOW(BattData) \ 00000088 .... LDI R31, (BattData) >> 8 \ 0000008A 8100 LD R16, Z \ 0000008C 7F0B ANDI R16, 0xFB \ 0000008E 8300 ST Z, R16 190 } 191 192 // Is the battery charged? 193 if (ADCS.VBAT >= BAT_VOLTAGE_LOW) { \ ??BatteryStatusRefresh_0: \ 00000090 .... LDI R30, LOW(ADCS) \ 00000092 .... LDI R31, (ADCS) >> 8 \ 00000094 8502 LDD R16, Z+10 \ 00000096 8513 LDD R17, Z+11 \ 00000098 3D02 CPI R16, 210 \ 0000009A E02F LDI R18, 15 \ 0000009C 0712 CPC R17, R18 \ 0000009E F028 BRCS ??BatteryStatusRefresh_1 194 BattData.Charged = TRUE; \ 000000A0 .... LDI R30, LOW(BattData) \ 000000A2 .... LDI R31, (BattData) >> 8 \ 000000A4 8100 LD R16, Z \ 000000A6 6002 ORI R16, 0x02 \ 000000A8 8300 ST Z, R16 195 } 196 197 // If we are not charging, yet VBAT is above safe limit, battery is present. 198 // If we are charging and there's a current flowing, the battery is present. 199 200 /*! \todo If ABORT_IF_PWM_MAX is defined this last check battery presence 201 * check is redundant since charging will be aborted due to low current at 202 * max duty cycle. That is preferrable since the charge current reading is 203 * not 100% proof. 204 */ 205 if (((OCR1B == 0) && (!BattData.Low)) || 206 ((OCR1B != 0) && (ADCS.avgIBAT > 0))) { \ ??BatteryStatusRefresh_1: \ 000000AA B50C IN R16, 0x2C \ 000000AC 2300 TST R16 \ 000000AE F429 BRNE ??BatteryStatusRefresh_2 \ 000000B0 .... LDI R30, LOW(BattData) \ 000000B2 .... LDI R31, (BattData) >> 8 \ 000000B4 8100 LD R16, Z \ 000000B6 FF02 SBRS R16, 2 \ 000000B8 C00A RJMP ??BatteryStatusRefresh_3 \ ??BatteryStatusRefresh_2: \ 000000BA B50C IN R16, 0x2C \ 000000BC 2300 TST R16 \ 000000BE F071 BREQ ??BatteryStatusRefresh_4 \ 000000C0 .... LDI R26, LOW((ADCS + 22)) \ 000000C2 .... LDI R27, HIGH((ADCS + 22)) \ 000000C4 91ED LD R30, X+ \ 000000C6 91FC LD R31, X \ 000000C8 9711 SBIW R27:R26, 1 \ 000000CA 9731 SBIW R31:R30, 1 \ 000000CC F03C BRLT ??BatteryStatusRefresh_4 207 BattData.Present = TRUE; \ ??BatteryStatusRefresh_3: \ 000000CE .... LDI R30, LOW(BattData) \ 000000D0 .... LDI R31, (BattData) >> 8 \ 000000D2 8100 LD R16, Z \ 000000D4 6001 ORI R16, 0x01 \ 000000D6 8300 ST Z, R16 208 success = TRUE; \ 000000D8 E081 LDI R24, 1 \ 000000DA C006 RJMP ??BatteryStatusRefresh_5 209 } else { 210 BattData.Low = FALSE; // (This is just a technicality..) \ ??BatteryStatusRefresh_4: \ 000000DC .... LDI R30, LOW(BattData) \ 000000DE .... LDI R31, (BattData) >> 8 \ 000000E0 8100 LD R16, Z \ 000000E2 7F0B ANDI R16, 0xFB \ 000000E4 8300 ST Z, R16 211 success = FALSE; \ 000000E6 E080 LDI R24, 0 212 } 213 214 #ifndef ALLOW_NO_RID 215 // Return FALSE if no valid RID entry was found, to stop charging. 216 if(!BattData.HasRID) { \ ??BatteryStatusRefresh_5: \ 000000E8 .... LDI R30, LOW(BattData) \ 000000EA .... LDI R31, (BattData) >> 8 \ 000000EC 8100 LD R16, Z \ 000000EE FF04 SBRS R16, 4 217 success = FALSE; \ 000000F0 E080 LDI R24, 0 218 } 219 #endif 220 221 return(success); \ ??BatteryStatusRefresh_6: \ 000000F2 2F08 MOV R16, R24 \ 000000F4 E0E4 LDI R30, 4 \ 000000F6 .... RJMP ?EPILOGUE_B4_L09 \ 000000F8 REQUIRE _A_OCR1B 222 } 223 224 225 /*! \brief Refreshes battery data in the EEPROM 226 * 227 * Attempts to read 4 pages of 32 bytes each from the battery's EPROM and store 228 * these data in on-chip EEPROM.\n 229 * If unsuccessful (CRC doesn't check out), the on-chip EEPROM is cleared. 230 * 231 * \todo Updating BattData with these data. Specs needed. 232 * 233 * \retval FALSE Refresh failed. 234 * \retval TRUE Refresh successful. 235 */ \ In segment CODE, align 2, keep-with-next 236 unsigned char BatteryDataRefresh(void) \ BatteryDataRefresh: 237 { \ 00000000 .... RCALL ?PROLOGUE8_L09 \ 00000002 REQUIRE ?Register_R4_is_cg_reg \ 00000002 REQUIRE ?Register_R5_is_cg_reg \ 00000002 REQUIRE ?Register_R6_is_cg_reg \ 00000002 REQUIRE ?Register_R7_is_cg_reg 238 unsigned char offset; 239 unsigned char i, crc, family, temp, page; 240 unsigned char success; 241 242 // Look for EPROM and read 4 pages of 32 bytes each worth of data, if found. 243 for (page = 0; page < 4; page++) { \ 00000002 E090 LDI R25, 0 \ ??BatteryDataRefresh_0: \ 00000004 3094 CPI R25, 4 \ 00000006 F008 BRCS $+2+2 \ 00000008 C084 RJMP ??BatteryDataRefresh_1 244 success = FALSE; \ 0000000A E0B0 LDI R27, 0 245 246 if (OWI_DetectPresence(OWIBUS) == OWIBUS) { \ 0000000C E001 LDI R16, 1 \ 0000000E .... RCALL OWI_DetectPresence \ 00000010 3001 CPI R16, 1 \ 00000012 F009 BREQ $+2+2 \ 00000014 C065 RJMP ??BatteryDataRefresh_2 247 248 // Presence detected, check type and CRC. 249 OWI_SendByte(OWI_ROM_READ, OWIBUS); \ 00000016 E011 LDI R17, 1 \ 00000018 E303 LDI R16, 51 \ 0000001A .... RCALL OWI_SendByte 250 family = OWI_ReceiveByte(OWIBUS); \ 0000001C E001 LDI R16, 1 \ 0000001E .... RCALL OWI_ReceiveByte \ 00000020 2E60 MOV R6, R16 251 crc = OWI_ComputeCRC8(family,0); \ 00000022 E010 LDI R17, 0 \ 00000024 2D06 MOV R16, R6 \ 00000026 .... RCALL OWI_ComputeCRC8 \ 00000028 2E50 MOV R5, R16 252 253 for (i = 0; i < 6; i++) { \ 0000002A E080 LDI R24, 0 \ ??BatteryDataRefresh_3: \ 0000002C 3086 CPI R24, 6 \ 0000002E F438 BRCC ??BatteryDataRefresh_4 254 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc); \ 00000030 E001 LDI R16, 1 \ 00000032 .... RCALL OWI_ReceiveByte \ 00000034 2D15 MOV R17, R5 \ 00000036 .... RCALL OWI_ComputeCRC8 \ 00000038 2E50 MOV R5, R16 255 } \ 0000003A 9583 INC R24 \ 0000003C CFF7 RJMP ??BatteryDataRefresh_3 256 257 // CRC ok, device found. 258 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) { \ ??BatteryDataRefresh_4: \ 0000003E E001 LDI R16, 1 \ 00000040 .... RCALL OWI_ReceiveByte \ 00000042 2D15 MOV R17, R5 \ 00000044 .... RCALL OWI_ComputeCRC8 \ 00000046 2300 TST R16 \ 00000048 F009 BREQ $+2+2 \ 0000004A C04A RJMP ??BatteryDataRefresh_2 259 BattData.Circuit = family; \ 0000004C 9260.... STS (BattData + 1), R6 260 261 // For now, we only read data from DS2505 EPROMs. 262 if (BattData.Circuit == OW_DS2505) { \ 00000050 9100.... LDS R16, (BattData + 1) \ 00000054 3009 CPI R16, 9 \ 00000056 F009 BREQ $+2+2 \ 00000058 C043 RJMP ??BatteryDataRefresh_2 263 offset = page*32; \ 0000005A 2F09 MOV R16, R25 \ 0000005C 9502 SWAP R16 \ 0000005E 7F00 ANDI R16, 0xF0 \ 00000060 0F00 LSL R16 \ 00000062 2E40 MOV R4, R16 264 OWI_SendByte(DS2505_DATA_READ, OWIBUS); // Command: read data. \ 00000064 E011 LDI R17, 1 \ 00000066 EC03 LDI R16, 195 \ 00000068 .... RCALL OWI_SendByte 265 OWI_SendByte(offset, OWIBUS); // Data: low address. \ 0000006A E011 LDI R17, 1 \ 0000006C 2D04 MOV R16, R4 \ 0000006E .... RCALL OWI_SendByte 266 OWI_SendByte(0, OWIBUS); // Data: high address. \ 00000070 E011 LDI R17, 1 \ 00000072 E000 LDI R16, 0 \ 00000074 .... RCALL OWI_SendByte 267 268 // Calculate checksums. 269 crc = OWI_ComputeCRC8(DS2505_DATA_READ,0); \ 00000076 E010 LDI R17, 0 \ 00000078 EC03 LDI R16, 195 \ 0000007A .... RCALL OWI_ComputeCRC8 \ 0000007C 2E50 MOV R5, R16 270 crc = OWI_ComputeCRC8(offset,crc); \ 0000007E 2D15 MOV R17, R5 \ 00000080 2D04 MOV R16, R4 \ 00000082 .... RCALL OWI_ComputeCRC8 \ 00000084 2E50 MOV R5, R16 271 crc = OWI_ComputeCRC8(0,crc); \ 00000086 2D15 MOV R17, R5 \ 00000088 E000 LDI R16, 0 \ 0000008A .... RCALL OWI_ComputeCRC8 \ 0000008C 2E50 MOV R5, R16 272 273 // Command received succesfully, now start reading data 274 // and writing it to EEPROM. 275 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) { \ 0000008E E001 LDI R16, 1 \ 00000090 .... RCALL OWI_ReceiveByte \ 00000092 2D15 MOV R17, R5 \ 00000094 .... RCALL OWI_ComputeCRC8 \ 00000096 2300 TST R16 \ 00000098 F519 BRNE ??BatteryDataRefresh_2 276 crc = 0; \ 0000009A 2455 CLR R5 277 278 // Fill page with data. 279 for (i=0; i<32; i++) { \ 0000009C E080 LDI R24, 0 \ ??BatteryDataRefresh_5: \ 0000009E 3280 CPI R24, 32 \ 000000A0 F4C0 BRCC ??BatteryDataRefresh_6 280 temp = OWI_ReceiveByte(OWIBUS); \ 000000A2 E001 LDI R16, 1 \ 000000A4 .... RCALL OWI_ReceiveByte \ 000000A6 2E70 MOV R7, R16 281 crc = OWI_ComputeCRC8(temp, crc); \ 000000A8 2D15 MOV R17, R5 \ 000000AA 2D07 MOV R16, R7 \ 000000AC .... RCALL OWI_ComputeCRC8 \ 000000AE 2E50 MOV R5, R16 282 BattEEPROM[page][i] = temp; \ 000000B0 2F49 MOV R20, R25 \ 000000B2 E050 LDI R21, 0 \ 000000B4 E200 LDI R16, 32 \ 000000B6 E010 LDI R17, 0 \ 000000B8 .... RCALL ?S_MUL_L02 \ 000000BA .... LDI R20, LOW(BattEEPROM) \ 000000BC .... LDI R21, (BattEEPROM) >> 8 \ 000000BE 0F40 ADD R20, R16 \ 000000C0 1F51 ADC R21, R17 \ 000000C2 2F08 MOV R16, R24 \ 000000C4 E010 LDI R17, 0 \ 000000C6 0F40 ADD R20, R16 \ 000000C8 1F51 ADC R21, R17 \ 000000CA 2D07 MOV R16, R7 \ 000000CC .... RCALL __eeput8_16 283 } \ 000000CE 9583 INC R24 \ 000000D0 CFE6 RJMP ??BatteryDataRefresh_5 284 285 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) { \ ??BatteryDataRefresh_6: \ 000000D2 E001 LDI R16, 1 \ 000000D4 .... RCALL OWI_ReceiveByte \ 000000D6 2D15 MOV R17, R5 \ 000000D8 .... RCALL OWI_ComputeCRC8 \ 000000DA 2300 TST R16 \ 000000DC F409 BRNE ??BatteryDataRefresh_2 286 success = TRUE; // Data read OK \ 000000DE E0B1 LDI R27, 1 287 } 288 } else { // Not able to start reading data. 289 } 290 } else { // Wrong device type. 291 } 292 } else { // No device found. 293 } 294 } else { // No presence detected on one-wire bus. 295 } 296 297 // Erase local EEPROM page if there were any errors during transfer. 298 if (!success) { \ ??BatteryDataRefresh_2: \ 000000E0 23BB TST R27 \ 000000E2 F4A9 BRNE ??BatteryDataRefresh_7 299 for (i=0; i<32; i++) { \ 000000E4 E080 LDI R24, 0 \ ??BatteryDataRefresh_8: \ 000000E6 3280 CPI R24, 32 \ 000000E8 F490 BRCC ??BatteryDataRefresh_7 300 BattEEPROM[page][i] = 0; \ 000000EA E0A0 LDI R26, 0 \ 000000EC 2F49 MOV R20, R25 \ 000000EE E050 LDI R21, 0 \ 000000F0 E200 LDI R16, 32 \ 000000F2 E010 LDI R17, 0 \ 000000F4 .... RCALL ?S_MUL_L02 \ 000000F6 .... LDI R20, LOW(BattEEPROM) \ 000000F8 .... LDI R21, (BattEEPROM) >> 8 \ 000000FA 0F40 ADD R20, R16 \ 000000FC 1F51 ADC R21, R17 \ 000000FE 2F08 MOV R16, R24 \ 00000100 E010 LDI R17, 0 \ 00000102 0F40 ADD R20, R16 \ 00000104 1F51 ADC R21, R17 \ 00000106 2F0A MOV R16, R26 \ 00000108 .... RCALL __eeput8_16 301 } \ 0000010A 9583 INC R24 \ 0000010C CFEC RJMP ??BatteryDataRefresh_8 302 } 303 } \ ??BatteryDataRefresh_7: \ 0000010E 9593 INC R25 \ 00000110 CF79 RJMP ??BatteryDataRefresh_0 304 305 return(success); \ ??BatteryDataRefresh_1: \ 00000112 2F0B MOV R16, R27 \ 00000114 E0E8 LDI R30, 8 \ 00000116 .... RJMP ?EPILOGUE_B8_L09 306 } 307 308 309 /*! \brief Enables specified battery 310 * 311 * Updates \ref BattActive to specified battery, then sets PB4/PB5 and clears 312 * PB5/PB4 in PORTB, depending on which battery is specified.\n 313 * The function takes 100 ms to allow the port switch to settle. 314 * 315 * \param bat Specifies which battery to enable (0 = battery A, 1 = B) 316 */ \ In segment CODE, align 2, keep-with-next 317 void EnableBattery(unsigned char bat) \ EnableBattery: 318 { \ 00000000 938A ST -Y, R24 \ 00000002 2F80 MOV R24, R16 319 // Use general timer, set timeout to 100ms. 320 Time_Set(TIMER_GEN,0,0,100); \ 00000004 E644 LDI R20, 100 \ 00000006 E010 LDI R17, 0 \ 00000008 E020 LDI R18, 0 \ 0000000A E030 LDI R19, 0 \ 0000000C E002 LDI R16, 2 \ 0000000E .... RCALL Time_Set 321 322 // Set specified battery as the active one. 323 BattActive = bat; \ 00000010 9380.... STS BattActive, R24 324 325 // Enable current battery in hardware, light LED & connect battery. 326 PORTB |= (1 << (PB4+bat)); \ 00000014 E001 LDI R16, 1 \ 00000016 E010 LDI R17, 0 \ 00000018 2F48 MOV R20, R24 \ 0000001A 5F4C SUBI R20, 252 \ 0000001C .... RCALL ?S_SHL_L02 \ 0000001E B318 IN R17, 0x18 \ 00000020 2B10 OR R17, R16 \ 00000022 BB18 OUT 0x18, R17 327 328 // Disconnect other battery. 329 PORTB &= ~(1<<(PB5-bat)); \ 00000024 E001 LDI R16, 1 \ 00000026 E010 LDI R17, 0 \ 00000028 E045 LDI R20, 5 \ 0000002A 1B48 SUB R20, R24 \ 0000002C .... RCALL ?S_SHL_L02 \ 0000002E 9500 COM R16 \ 00000030 B318 IN R17, 0x18 \ 00000032 2310 AND R17, R16 \ 00000034 BB18 OUT 0x18, R17 330 331 do { // Let port switch settle. 332 } while (Time_Left(TIMER_GEN)); \ ??EnableBattery_0: \ 00000036 E002 LDI R16, 2 \ 00000038 .... RCALL Time_Left \ 0000003A 2300 TST R16 \ 0000003C F7E1 BRNE ??EnableBattery_0 333 } \ 0000003E 9189 LD R24, Y+ \ 00000040 9508 RET \ 00000042 REQUIRE _A_PORTB 334 335 336 /*! \brief Disables both batteries 337 * 338 * Clears PB4 and PB5 in PORTB, disabling both batteries. 339 */ \ In segment CODE, align 2, keep-with-next 340 void DisableBatteries(void) \ DisableBatteries: 341 { 342 // Turn off LEDs and disconnect batteries. 343 PORTB &= ~((1<= RID[i].Low) { \ 0000000C .... LDI R30, LOW(ADCS) \ 0000000E .... LDI R31, (ADCS) >> 8 \ 00000010 81A2 LDD R26, Z+2 \ 00000012 81B3 LDD R27, Z+3 \ 00000014 2F48 MOV R20, R24 \ 00000016 E050 LDI R21, 0 \ 00000018 E00E LDI R16, 14 \ 0000001A E010 LDI R17, 0 \ 0000001C .... RCALL ?S_MUL_L02 \ 0000001E 01F8 MOVW R31:R30, R17:R16 \ 00000020 .... SUBI R30, LOW((-(RID) & 0xFFFF)) \ 00000022 .... SBCI R31, (-(RID) & 0xFFFF) >> 8 \ 00000024 8100 LD R16, Z \ 00000026 8111 LDD R17, Z+1 \ 00000028 17A0 CP R26, R16 \ 0000002A 07B1 CPC R27, R17 \ 0000002C F408 BRCC $+2+2 \ 0000002E C04A RJMP ??RIDLookUp_2 364 if (ADCS.rawRID <= RID[i].High) { \ 00000030 2F48 MOV R20, R24 \ 00000032 E050 LDI R21, 0 \ 00000034 E00E LDI R16, 14 \ 00000036 E010 LDI R17, 0 \ 00000038 .... RCALL ?S_MUL_L02 \ 0000003A 01F8 MOVW R31:R30, R17:R16 \ 0000003C .... SUBI R30, LOW((-(RID) & 0xFFFF)) \ 0000003E .... SBCI R31, (-(RID) & 0xFFFF) >> 8 \ 00000040 8102 LDD R16, Z+2 \ 00000042 8113 LDD R17, Z+3 \ 00000044 .... LDI R30, LOW(ADCS) \ 00000046 .... LDI R31, (ADCS) >> 8 \ 00000048 8122 LDD R18, Z+2 \ 0000004A 8133 LDD R19, Z+3 \ 0000004C 1702 CP R16, R18 \ 0000004E 0713 CPC R17, R19 \ 00000050 F1C8 BRCS ??RIDLookUp_2 365 BattData.Capacity = RID[i].Capacity; \ 00000052 2F48 MOV R20, R24 \ 00000054 E050 LDI R21, 0 \ 00000056 E00E LDI R16, 14 \ 00000058 E010 LDI R17, 0 \ 0000005A .... RCALL ?S_MUL_L02 \ 0000005C 01F8 MOVW R31:R30, R17:R16 \ 0000005E .... SUBI R30, LOW((-(RID) & 0xFFFF)) \ 00000060 .... SBCI R31, (-(RID) & 0xFFFF) >> 8 \ 00000062 8106 LDD R16, Z+6 \ 00000064 8117 LDD R17, Z+7 \ 00000066 .... LDI R30, LOW(BattData) \ 00000068 .... LDI R31, (BattData) >> 8 \ 0000006A 8304 STD Z+4, R16 \ 0000006C 8315 STD Z+5, R17 366 BattData.MaxCurrent = RID[i].Icharge; \ 0000006E 2F48 MOV R20, R24 \ 00000070 E050 LDI R21, 0 \ 00000072 E00E LDI R16, 14 \ 00000074 E010 LDI R17, 0 \ 00000076 .... RCALL ?S_MUL_L02 \ 00000078 01F8 MOVW R31:R30, R17:R16 \ 0000007A .... SUBI R30, LOW((-(RID) & 0xFFFF)) \ 0000007C .... SBCI R31, (-(RID) & 0xFFFF) >> 8 \ 0000007E 8500 LDD R16, Z+8 \ 00000080 8511 LDD R17, Z+9 \ 00000082 .... LDI R30, LOW(BattData) \ 00000084 .... LDI R31, (BattData) >> 8 \ 00000086 8306 STD Z+6, R16 \ 00000088 8317 STD Z+7, R17 367 BattData.MaxTime = RID[i].tCutOff; \ 0000008A 2F48 MOV R20, R24 \ 0000008C E050 LDI R21, 0 \ 0000008E E00E LDI R16, 14 \ 00000090 E010 LDI R17, 0 \ 00000092 .... RCALL ?S_MUL_L02 \ 00000094 01F8 MOVW R31:R30, R17:R16 \ 00000096 .... SUBI R30, LOW((-(RID) & 0xFFFF)) \ 00000098 .... SBCI R31, (-(RID) & 0xFFFF) >> 8 \ 0000009A 8502 LDD R16, Z+10 \ 0000009C 8513 LDD R17, Z+11 \ 0000009E .... LDI R30, LOW(BattData) \ 000000A0 .... LDI R31, (BattData) >> 8 \ 000000A2 8700 STD Z+8, R16 \ 000000A4 8711 STD Z+9, R17 368 BattData.MinCurrent = RID[i].ICutOff; \ 000000A6 2F48 MOV R20, R24 \ 000000A8 E050 LDI R21, 0 \ 000000AA E00E LDI R16, 14 \ 000000AC E010 LDI R17, 0 \ 000000AE .... RCALL ?S_MUL_L02 \ 000000B0 01F8 MOVW R31:R30, R17:R16 \ 000000B2 .... SUBI R30, LOW((-(RID) & 0xFFFF)) \ 000000B4 .... SBCI R31, (-(RID) & 0xFFFF) >> 8 \ 000000B6 8504 LDD R16, Z+12 \ 000000B8 8515 LDD R17, Z+13 \ 000000BA .... LDI R30, LOW(BattData) \ 000000BC .... LDI R31, (BattData) >> 8 \ 000000BE 8702 STD Z+10, R16 \ 000000C0 8713 STD Z+11, R17 369 370 found = TRUE; \ 000000C2 E091 LDI R25, 1 371 } 372 } 373 } \ ??RIDLookUp_2: \ 000000C4 9583 INC R24 \ 000000C6 CF9F RJMP ??RIDLookUp_0 374 375 // If no valid entry is found, use defaults and return FALSE. 376 if (!found) { \ ??RIDLookUp_1: \ 000000C8 2399 TST R25 \ 000000CA F4C1 BRNE ??RIDLookUp_3 377 BattData.Capacity = DEF_BAT_CAPACITY; \ 000000CC E000 LDI R16, 0 \ 000000CE E010 LDI R17, 0 \ 000000D0 .... LDI R30, LOW(BattData) \ 000000D2 .... LDI R31, (BattData) >> 8 \ 000000D4 8304 STD Z+4, R16 \ 000000D6 8315 STD Z+5, R17 378 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX; \ 000000D8 E000 LDI R16, 0 \ 000000DA E010 LDI R17, 0 \ 000000DC .... LDI R30, LOW(BattData) \ 000000DE .... LDI R31, (BattData) >> 8 \ 000000E0 8306 STD Z+6, R16 \ 000000E2 8317 STD Z+7, R17 379 BattData.MaxTime = DEF_BAT_TIME_MAX; \ 000000E4 E000 LDI R16, 0 \ 000000E6 E010 LDI R17, 0 \ 000000E8 .... LDI R30, LOW(BattData) \ 000000EA .... LDI R31, (BattData) >> 8 \ 000000EC 8700 STD Z+8, R16 \ 000000EE 8711 STD Z+9, R17 380 BattData.MinCurrent = DEF_BAT_CURRENT_MIN; \ 000000F0 E000 LDI R16, 0 \ 000000F2 E010 LDI R17, 0 \ 000000F4 .... LDI R30, LOW(BattData) \ 000000F6 .... LDI R31, (BattData) >> 8 \ 000000F8 8702 STD Z+10, R16 \ 000000FA 8713 STD Z+11, R17 381 } 382 383 return(found); \ ??RIDLookUp_3: \ 000000FC 2F09 MOV R16, R25 \ 000000FE E0E4 LDI R30, 4 \ 00000100 .... RJMP ?EPILOGUE_B4_L09 384 } 385 386 387 /*! \brief Calculates temperature from a lookup table 388 * 389 * Looks up the highest NTC value below or equal to the measured one.\n 390 * With the current lookup table, temperature is calculated with the formula:\n 391 * 4*(index of entry) - 2*(measured NTC - NTC from entry) / (ADCsteps of entry) 392 * 393 * \note If the NTC-measurement is saturated, with the current lookup table, 394 * the temperature will be reported as -1 C. 395 * 396 * \note If no valid entry is found, battery temperature is set to 80. 397 */ \ In segment CODE, align 2, keep-with-next 398 void NTCLookUp (void) \ NTCLookUp: 399 { \ 00000000 .... RCALL ?PROLOGUE4_L09 400 unsigned char i; 401 unsigned char found = FALSE; \ 00000002 E090 LDI R25, 0 402 403 // Lookup in the NTC-table. Use the first entry which is equal or below 404 // sampled NTC. Calculate temperature by using the index number, and the 405 // difference between the measured NTC value and the one in the entry. 406 for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++) { \ 00000004 E080 LDI R24, 0 \ ??NTCLookUp_0: \ 00000006 3184 CPI R24, 20 \ 00000008 F008 BRCS $+2+2 \ 0000000A C043 RJMP ??NTCLookUp_1 \ 0000000C 2399 TST R25 \ 0000000E F009 BREQ $+2+2 \ 00000010 C040 RJMP ??NTCLookUp_1 407 if (ADCS.rawNTC >= NTC[i].ADC) { \ 00000012 .... LDI R30, LOW(ADCS) \ 00000014 .... LDI R31, (ADCS) >> 8 \ 00000016 81A4 LDD R26, Z+4 \ 00000018 81B5 LDD R27, Z+5 \ 0000001A 2F48 MOV R20, R24 \ 0000001C E050 LDI R21, 0 \ 0000001E E003 LDI R16, 3 \ 00000020 E010 LDI R17, 0 \ 00000022 .... RCALL ?S_MUL_L02 \ 00000024 01F8 MOVW R31:R30, R17:R16 \ 00000026 .... SUBI R30, LOW((-(NTC) & 0xFFFF)) \ 00000028 .... SBCI R31, (-(NTC) & 0xFFFF) >> 8 \ 0000002A 8100 LD R16, Z \ 0000002C 8111 LDD R17, Z+1 \ 0000002E 17A0 CP R26, R16 \ 00000030 07B1 CPC R27, R17 \ 00000032 F168 BRCS ??NTCLookUp_2 408 BattData.Temperature = (i<<2) ; \ 00000034 2F08 MOV R16, R24 \ 00000036 0F00 LSL R16 \ 00000038 0F00 LSL R16 \ 0000003A 9300.... STS (BattData + 2), R16 409 BattData.ADCSteps = NTC[i].ADCsteps; \ 0000003E 2F48 MOV R20, R24 \ 00000040 E050 LDI R21, 0 \ 00000042 E003 LDI R16, 3 \ 00000044 E010 LDI R17, 0 \ 00000046 .... RCALL ?S_MUL_L02 \ 00000048 01F8 MOVW R31:R30, R17:R16 \ 0000004A .... SUBI R30, LOW((-(NTC) & 0xFFFF)) \ 0000004C .... SBCI R31, (-(NTC) & 0xFFFF) >> 8 \ 0000004E 8102 LDD R16, Z+2 \ 00000050 9300.... STS (BattData + 3), R16 410 BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps; \ 00000054 .... LDI R30, LOW(ADCS) \ 00000056 .... LDI R31, (ADCS) >> 8 \ 00000058 81A4 LDD R26, Z+4 \ 0000005A 81B5 LDD R27, Z+5 \ 0000005C 2F48 MOV R20, R24 \ 0000005E E050 LDI R21, 0 \ 00000060 E003 LDI R16, 3 \ 00000062 E010 LDI R17, 0 \ 00000064 .... RCALL ?S_MUL_L02 \ 00000066 01F8 MOVW R31:R30, R17:R16 \ 00000068 .... SUBI R30, LOW((-(NTC) & 0xFFFF)) \ 0000006A .... SBCI R31, (-(NTC) & 0xFFFF) >> 8 \ 0000006C 8100 LD R16, Z \ 0000006E 8111 LDD R17, Z+1 \ 00000070 1BA0 SUB R26, R16 \ 00000072 0BB1 SBC R27, R17 \ 00000074 0FAA LSL R26 \ 00000076 1FBB ROL R27 \ 00000078 018D MOVW R17:R16, R27:R26 \ 0000007A 9140.... LDS R20, (BattData + 3) \ 0000007E E050 LDI R21, 0 \ 00000080 .... RCALL ?US_DIVMOD_L02 \ 00000082 .... LDI R30, LOW(BattData) \ 00000084 .... LDI R31, (BattData) >> 8 \ 00000086 8112 LDD R17, Z+2 \ 00000088 1B10 SUB R17, R16 \ 0000008A 8312 STD Z+2, R17 411 412 found = TRUE; // Could be done with a break, but that violates MISRA. \ 0000008C E091 LDI R25, 1 413 } 414 } \ ??NTCLookUp_2: \ 0000008E 9583 INC R24 \ 00000090 CFBA RJMP ??NTCLookUp_0 415 416 // For safety, is temperature is greater than the NTC 417 if (!found) { \ ??NTCLookUp_1: \ 00000092 2399 TST R25 \ 00000094 F419 BRNE ??NTCLookUp_3 418 BattData.Temperature = 80; \ 00000096 E500 LDI R16, 80 \ 00000098 9300.... STS (BattData + 2), R16 419 } 420 } \ ??NTCLookUp_3: \ 0000009C E0E4 LDI R30, 4 \ 0000009E .... RJMP ?EPILOGUE_B4_L09 \ In segment NEAR_ID, align 1, keep-with-next \ `?`: \ 00000000 022E02930F3C DW 558, 659, 3900, 550, 260, 300, 10, 744, 843, 6800, 750, 360, 300, 14 \ 02260104012C \ 000A02E8034B \ 1A9002EE0168 \ 012C000E \ 0000001C 036503BE2710 DW 869, 958, 10000, 1000, 475, 300, 19, 1097, 1153, 24000, 2000, 475 \ 03E801DB012C \ 001304490481 \ 5DC007D001DB \ 00000034 01A40026 DW 420, 38 \ In segment NEAR_ID, align 1, keep-with-next \ `?`: \ 00000000 03EA DW 1002 \ 00000002 17 DB 23 \ 00000003 03B9 DW 953 \ 00000005 19 DB 25 \ 00000006 0386 DW 902 \ 00000008 1A DB 26 \ 00000009 0351 DW 849 \ 0000000B 1B DB 27 \ 0000000C 031C DW 796 \ 0000000E 1B DB 27 \ 0000000F 02E6 DW 742 \ 00000011 1B DB 27 \ 00000012 02B1 DW 689 \ 00000014 1A DB 26 \ 00000015 027D DW 637 \ 00000017 1A DB 26 \ 00000018 024B DW 587 \ 0000001A 19 DB 25 \ 0000001B 021B DW 539 \ 0000001D 18 DB 24 \ 0000001E 01EE DW 494 \ 00000020 16 DB 22 \ 00000021 01C3 DW 451 \ 00000023 15 DB 21 \ 00000024 019C DW 412 \ 00000026 13 DB 19 \ 00000027 0177 DW 375 \ 00000029 12 DB 18 \ 0000002A 0155 DW 341 \ 0000002C 11 DB 17 \ 0000002D 0136 DW 310 \ 0000002F 0F DB 15 \ 00000030 011A DW 282 \ 00000032 0E DB 14 \ 00000033 0100 DW 256 \ 00000035 0D DB 13 \ 00000036 00E9 DW 233 \ 00000038 0B DB 11 \ 00000039 00D4 DW 212 \ 0000003B 0A DB 10 Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ BatteryCheck 4 2 -> BatteryStatusRefresh 4 2 BatteryDataRefresh 8 4 -> OWI_DetectPresence 8 2 -> OWI_SendByte 8 2 -> OWI_ReceiveByte 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ReceiveByte 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ReceiveByte 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_SendByte 8 2 -> OWI_SendByte 8 2 -> OWI_SendByte 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ReceiveByte 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ReceiveByte 8 2 -> OWI_ComputeCRC8 8 2 -> OWI_ReceiveByte 8 2 -> OWI_ComputeCRC8 8 2 BatteryStatusRefresh 4 2 -> NTCLookUp 4 2 -> RIDLookUp 4 2 DisableBatteries 0 2 EnableBattery 1 4 -> Time_Set 1 2 -> Time_Left 1 2 NTCLookUp 4 4 RIDLookUp 4 4 Segment part sizes: Function/Label Bytes -------------- ----- _A_OCR1B 1 _A_PORTB 1 BattControl 2 BattData 12 BattEEPROM 128 BattActive 1 RID 56 NTC 60 BatteryCheck 44 BatteryStatusRefresh 248 BatteryDataRefresh 280 EnableBattery 66 DisableBatteries 8 RIDLookUp 258 NTCLookUp 160 ? 56 ? 60 Others 12 2 bytes in segment ABSOLUTE 1 064 bytes in segment CODE 130 bytes in segment EEPROM_I 12 bytes in segment INITTAB 116 bytes in segment NEAR_I 116 bytes in segment NEAR_ID 13 bytes in segment NEAR_Z 1 180 bytes of CODE memory (+ 12 bytes shared) 129 bytes of DATA memory (+ 2 bytes shared) 130 bytes of XDATA memory Errors: none Warnings: none