1 ###############################################################################
\r
3 # IAR Atmel AVR C/C++ Compiler V4.30F/W32 13/Mar/2008 04:52:02 #
\r
4 # Copyright 1996-2007 IAR Systems. All rights reserved. #
\r
6 # Source file = C:\home\kevin\pub\src\bc100\IAR\battery.c #
\r
7 # Command line = C:\home\kevin\pub\src\bc100\IAR\battery.c #
\r
8 # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc10 #
\r
9 # 0\IAR\Release\Obj\ -D NDEBUG -lCN #
\r
10 # C:\home\kevin\pub\src\bc100\IAR\Release\List\ #
\r
11 # -lB C:\home\kevin\pub\src\bc100\IAR\Release\Lis #
\r
12 # t\ --initializers_in_flash -s9 --no_cross_call #
\r
13 # --no_tbaa -DENABLE_BIT_DEFINITIONS -e -I #
\r
14 # "C:\Program Files\IAR Systems\Embedded #
\r
15 # Workbench 4.0\avr\INC\" -I "C:\Program #
\r
16 # Files\IAR Systems\Embedded Workbench #
\r
17 # 4.0\avr\INC\CLIB\" --eeprom_size 512 #
\r
18 # --misrac=5-9,11-12,14,16-17,19-21,24-26,29-32, #
\r
19 # 34-35,38-39,42-43,46,50,52-54,56-59,61-62, #
\r
20 # 64-65,68-80,83-84,87-91,94-95,98-100,103-110, #
\r
22 # Enabled MISRA C rules = 5-9,11-12,14,16-17,19-21,24-26,29-32,34-35, #
\r
23 # 38-39,42-43,46,50,52-54,56-59,61-62,64-65, #
\r
24 # 68-80,83-84,87-91,94-95,98-100,103-110,112-126 #
\r
25 # Checked = 5,7-9,11-12,14,17,19-21,24,29-32,34-35,38-39, #
\r
26 # 42,46,50,52-54,56-59,61-62,64,68-69,71-80, #
\r
27 # 83-84,87-89,91,94-95,98,100,104-105,108-109, #
\r
29 # Not checked = 6,16,25-26,43,65,70,90,99,103,106-107,110, #
\r
31 # List file = C:\home\kevin\pub\src\bc100\IAR\Release\List\ba #
\r
33 # Object file = C:\home\kevin\pub\src\bc100\IAR\Release\Obj\bat #
\r
37 ###############################################################################
\r
39 C:\home\kevin\pub\src\bc100\IAR\battery.c
\r
40 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
41 2 /*! \file *********************************************************************
\r
44 5 * Functions related to battery control and data acquisition.
\r
46 7 * Contains functions for enabling/disabling batteries, and looking up
\r
47 8 * their status and specifications using the ADC.
\r
49 10 * \par Application note:
\r
50 11 * AVR458: Charging Li-Ion Batteries with BC100 \n
\r
51 12 * AVR463: Charging NiMH Batteries with BC100
\r
54 15 * \par Documentation
\r
55 16 * For comprehensive code documentation, supported compilers, compiler
\r
56 17 * settings and supported devices see readme.html
\r
59 20 * Atmel Corporation: http://www.atmel.com \n
\r
60 21 * Support email: avr@atmel.com
\r
64 25 * $Revision: 2299 $
\r
66 27 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/battery.c $
\r
67 28 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
68 29 ******************************************************************************/
\r
70 31 #include <ioavr.h>
\r
72 \ In segment ABSOLUTE, at 0x4c
\r
73 \ <unnamed> volatile __io _A_OCR1B
\r
77 \ In segment ABSOLUTE, at 0x38
\r
78 \ <unnamed> volatile __io _A_PORTB
\r
81 32 #include <inavr.h>
\r
83 34 #include "structs.h"
\r
84 35 #include "enums.h"
\r
87 38 #include "battery.h"
\r
88 39 #include "main.h"
\r
90 41 #include "time.h"
\r
93 44 #include "NIMHspecs.h"
\r
97 48 #include "LIIONspecs.h"
\r
102 53 //******************************************************************************
\r
104 55 //******************************************************************************
\r
105 56 /* Control-struct for batteries */
\r
106 57 /*! \brief Holds control data for both batteries
\r
107 58 * \note Stored in EEPROM.
\r
110 \ In segment EEPROM_I, align 1, keep-with-next
\r
111 60 __eeprom Battery_t BattControl[2] = {{TRUE, TRUE, FALSE},
\r
113 \ 00000000 0303 DB 3, 3
\r
114 61 {TRUE, TRUE, FALSE}};
\r
116 63 /* Data-struct for battery */
\r
118 \ In segment NEAR_Z, align 1, keep-with-next
\r
119 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
120 64 Batteries_t BattData; //!< Holds data for the current battery
\r
125 67 /* Storage for battery EPROM */
\r
126 68 /*! \brief Storage space for data from the batteries' own EPROMs.
\r
127 69 * \note Stored in EEPROM.
\r
130 \ In segment EEPROM_I, align 1, keep-with-next
\r
131 71 __eeprom unsigned char BattEEPROM[4][32];
\r
133 \ 00000000 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
136 \ 00000010 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
139 \ 00000020 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
142 \ 00000030 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
145 \ 00000040 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
148 \ 00000050 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
151 \ 00000060 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
154 \ 00000070 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
159 74 //! Global that indicates current battery (0 = battery A, 1 = B)
\r
161 \ In segment NEAR_Z, align 1, keep-with-next
\r
162 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
163 75 unsigned char BattActive;
\r
168 78 /*! \brief RID lookup-table
\r
170 80 * Contains Resistor ID data specified by manufacturer.
\r
172 82 * \note Values have been calculated assuming a +/- 15% tolerance.
\r
175 \ In segment NEAR_I, align 1, keep-with-next
\r
176 \ 00000000 REQUIRE `?<Segment init: NEAR_I>`
\r
177 84 const RID_Lookup_t RID[RID_TABLE_SIZE] = {
\r
180 \ 00000038 REQUIRE `?<Initializer for RID>`
\r
181 85 {558, 659, 3900, 550, 260, 300, 10},
\r
182 86 {744, 843, 6800, 750, 360, 300, 14},
\r
183 87 {869, 958, 10000, 1000, 475, 300, 19},
\r
184 88 {1097, 1153, 24000, 2000, 475, 420, 38}
\r
188 92 /*! \brief NTC lookup-table
\r
190 94 * The first entry is 0 degrees. For every entry after, temperature increases
\r
191 95 * with 4 degrees. With 20 entries, the last one equals (20-1)*4 = 76 degrees.\n
\r
192 96 * It must be sorted in descending ADC order.
\r
194 98 * \note This was calculated for a Mitsubishi RH16-3H103FB NTC.
\r
196 100 * \note NTCLookUp() must be modified if this table is changed so that:
\r
197 101 * - first entry is no longer 0 degrees.
\r
198 102 * - temperature difference between entries is no longer 4 degrees.
\r
199 103 * - ADCsteps no longer specifies ADC steps per half degree.
\r
201 105 // FOR VARTA POLYFLEX NTC
\r
203 \ In segment NEAR_I, align 1, keep-with-next
\r
204 \ 00000000 REQUIRE `?<Segment init: NEAR_I>`
\r
205 106 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {
\r
208 \ 0000003C REQUIRE `?<Initializer for NTC>`
\r
209 107 {1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27},
\r
210 108 {742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24},
\r
211 109 {494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17},
\r
212 110 {310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10}
\r
216 114 // FOR MITSUBISHI NTC
\r
218 116 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {
\r
219 117 {1004, 24}, {954, 25}, {903, 26}, {850, 27}, {796, 27},
\r
220 118 {742, 27}, {689, 27}, {637, 26}, {587, 25}, {539, 24},
\r
221 119 {493, 22}, {451, 21}, {411, 20}, {374, 18}, {340, 17},
\r
222 120 {309, 15}, {281, 14}, {255, 13}, {232, 11}, {211, 10}
\r
227 125 //******************************************************************************
\r
229 127 //******************************************************************************
\r
230 128 /*! \brief Checks if battery has changed
\r
232 130 * Stores current capacity, then attempts to refresh battery status.\n
\r
233 131 * If the refresh is successful, old capacity is compared with the new one.
\r
235 133 * \retval FALSE Battery is disconnected, or capacity has changed.
\r
236 134 * \retval TRUE All OK.
\r
239 \ In segment CODE, align 2, keep-with-next
\r
240 136 unsigned char BatteryCheck(void)
\r
243 \ 00000000 93BA ST -Y, R27
\r
244 \ 00000002 93AA ST -Y, R26
\r
245 \ 00000004 938A ST -Y, R24
\r
246 138 unsigned char success = TRUE;
\r
247 \ 00000006 E081 LDI R24, 1
\r
248 139 unsigned int oldCapacity;
\r
250 141 // Save to see if battery data has changed.
\r
251 142 oldCapacity = BattData.Capacity;
\r
252 \ 00000008 .... LDI R30, LOW(BattData)
\r
253 \ 0000000A .... LDI R31, (BattData) >> 8
\r
254 \ 0000000C 81A4 LDD R26, Z+4
\r
255 \ 0000000E 81B5 LDD R27, Z+5
\r
257 144 if (!BatteryStatusRefresh()) {
\r
258 \ 00000010 .... RCALL BatteryStatusRefresh
\r
259 \ 00000012 2300 TST R16
\r
260 \ 00000014 F409 BRNE ??BatteryCheck_0
\r
261 145 success = FALSE; // Battery not present or RID was invalid.
\r
262 \ 00000016 E080 LDI R24, 0
\r
265 148 if (oldCapacity != BattData.Capacity) {
\r
266 \ ??BatteryCheck_0:
\r
267 \ 00000018 .... LDI R30, LOW(BattData)
\r
268 \ 0000001A .... LDI R31, (BattData) >> 8
\r
269 \ 0000001C 8104 LDD R16, Z+4
\r
270 \ 0000001E 8115 LDD R17, Z+5
\r
271 \ 00000020 17A0 CP R26, R16
\r
272 \ 00000022 07B1 CPC R27, R17
\r
273 \ 00000024 F009 BREQ ??BatteryCheck_1
\r
274 149 success = FALSE; // Battery configuration has changed.
\r
275 \ 00000026 E080 LDI R24, 0
\r
278 152 return(success);
\r
279 \ ??BatteryCheck_1:
\r
280 \ 00000028 2F08 MOV R16, R24
\r
281 \ 0000002A 9189 LD R24, Y+
\r
282 \ 0000002C 91A9 LD R26, Y+
\r
283 \ 0000002E 91B9 LD R27, Y+
\r
284 \ 00000030 9508 RET
\r
288 156 /*! \brief Refreshes battery status information
\r
290 158 * Refreshes battery status information, if it is present, based on
\r
291 159 * RID and NTC (read by ADC).\n
\r
292 160 * The battery must have been enabled and a complete set of ADC data must have
\r
293 161 * been collected before calling.\n
\r
295 163 * \retval FALSE No battery present.
\r
296 164 * \retval TRUE Battery present, status refreshed.
\r
298 166 * \note If ALLOW_NO_RID is defined, charging will NOT stop if no fitting entry
\r
299 167 * is found in the lookup table. Instead, default battery data will be used.
\r
302 \ In segment CODE, align 2, keep-with-next
\r
303 169 unsigned char BatteryStatusRefresh(void)
\r
304 \ BatteryStatusRefresh:
\r
306 \ 00000000 93BA ST -Y, R27
\r
307 \ 00000002 93AA ST -Y, R26
\r
308 \ 00000004 939A ST -Y, R25
\r
309 \ 00000006 938A ST -Y, R24
\r
310 171 // Assume the worst..
\r
311 172 unsigned char success = FALSE;
\r
313 174 BattData.Present = FALSE;
\r
314 175 BattData.Charged = FALSE;
\r
315 176 BattData.Low = TRUE;
\r
316 \ 00000008 .... LDI R26, LOW(BattData)
\r
317 \ 0000000A .... LDI R27, (BattData) >> 8
\r
318 \ 0000000C 910C LD R16, X
\r
319 \ 0000000E 7F0C ANDI R16, 0xFC
\r
320 \ 00000010 6004 ORI R16, 0x04
\r
321 \ 00000012 930C ST X, R16
\r
322 177 BattData.Circuit = OW_NONE;
\r
323 \ 00000014 E000 LDI R16, 0
\r
324 \ 00000016 01FD MOVW R31:R30, R27:R26
\r
325 \ 00000018 8301 STD Z+1, R16
\r
326 178 BattData.Temperature = 0;
\r
327 \ 0000001A 8302 STD Z+2, R16
\r
328 179 BattData.Capacity = 0;
\r
329 \ 0000001C 8304 STD Z+4, R16
\r
330 \ 0000001E 8305 STD Z+5, R16
\r
331 180 BattData.MaxCurrent = 0;
\r
332 \ 00000020 8306 STD Z+6, R16
\r
333 \ 00000022 8307 STD Z+7, R16
\r
334 181 BattData.MaxTime = 0;
\r
335 \ 00000024 8700 STD Z+8, R16
\r
336 \ 00000026 8701 STD Z+9, R16
\r
337 182 BattData.MinCurrent = 0;
\r
338 \ 00000028 8702 STD Z+10, R16
\r
339 \ 0000002A 8703 STD Z+11, R16
\r
342 \ 0000002C .... RCALL NTCLookUp
\r
343 185 BattData.HasRID = RIDLookUp();
\r
344 \ 0000002E .... RCALL RIDLookUp
\r
345 \ 00000030 2F10 MOV R17, R16
\r
346 \ 00000032 7011 ANDI R17, 0x01
\r
347 \ 00000034 FB10 BST R17, 0
\r
348 \ 00000036 910C LD R16, X
\r
349 \ 00000038 F904 BLD R16, 4
\r
350 \ 0000003A 930C ST X, R16
\r
352 187 // Is the battery voltage above minimum safe cell voltage?
\r
353 188 if (ADCS.VBAT >= BAT_VOLTAGE_MIN) {
\r
354 \ 0000003C .... LDI R30, LOW(ADCS)
\r
355 \ 0000003E .... LDI R31, (ADCS) >> 8
\r
356 \ 00000040 8502 LDD R16, Z+10
\r
357 \ 00000042 8513 LDD R17, Z+11
\r
358 \ 00000044 3600 CPI R16, 96
\r
359 \ 00000046 E029 LDI R18, 9
\r
360 \ 00000048 0712 CPC R17, R18
\r
361 \ 0000004A F018 BRCS ??BatteryStatusRefresh_0
\r
362 189 BattData.Low = FALSE;
\r
363 \ 0000004C 910C LD R16, X
\r
364 \ 0000004E 7F0B ANDI R16, 0xFB
\r
365 \ 00000050 930C ST X, R16
\r
368 192 // Is the battery charged?
\r
369 193 if (ADCS.VBAT >= BAT_VOLTAGE_LOW) {
\r
370 \ ??BatteryStatusRefresh_0:
\r
371 \ 00000052 8502 LDD R16, Z+10
\r
372 \ 00000054 3D02 CPI R16, 210
\r
373 \ 00000056 401F SBCI R17, 15
\r
374 \ 00000058 F018 BRCS ??BatteryStatusRefresh_1
\r
375 194 BattData.Charged = TRUE;
\r
376 \ 0000005A 910C LD R16, X
\r
377 \ 0000005C 6002 ORI R16, 0x02
\r
378 \ 0000005E 930C ST X, R16
\r
381 197 // If we are not charging, yet VBAT is above safe limit, battery is present.
\r
382 198 // If we are charging and there's a current flowing, the battery is present.
\r
384 200 /*! \todo If ABORT_IF_PWM_MAX is defined this last check battery presence
\r
385 201 * check is redundant since charging will be aborted due to low current at
\r
386 202 * max duty cycle. That is preferrable since the charge current reading is
\r
387 203 * not 100% proof.
\r
389 205 if (((OCR1B == 0) && (!BattData.Low)) ||
\r
390 206 ((OCR1B != 0) && (ADCS.avgIBAT > 0))) {
\r
391 \ ??BatteryStatusRefresh_1:
\r
392 \ 00000060 B50C IN R16, 0x2C
\r
393 \ 00000062 2300 TST R16
\r
394 \ 00000064 F419 BRNE ??BatteryStatusRefresh_2
\r
395 \ 00000066 910C LD R16, X
\r
396 \ 00000068 FF02 SBRS R16, 2
\r
397 \ 0000006A C008 RJMP ??BatteryStatusRefresh_3
\r
398 \ ??BatteryStatusRefresh_2:
\r
399 \ 0000006C B50C IN R16, 0x2C
\r
400 \ 0000006E 2300 TST R16
\r
401 \ 00000070 F051 BREQ ??BatteryStatusRefresh_4
\r
402 \ 00000072 8986 LDD R24, Z+22
\r
403 \ 00000074 8997 LDD R25, Z+23
\r
404 \ 00000076 3081 CPI R24, 1
\r
405 \ 00000078 4090 SBCI R25, 0
\r
406 \ 0000007A F02C BRLT ??BatteryStatusRefresh_4
\r
407 207 BattData.Present = TRUE;
\r
408 \ ??BatteryStatusRefresh_3:
\r
409 \ 0000007C 910C LD R16, X
\r
410 \ 0000007E 6001 ORI R16, 0x01
\r
411 \ 00000080 930C ST X, R16
\r
412 208 success = TRUE;
\r
413 \ 00000082 E001 LDI R16, 1
\r
414 \ 00000084 C004 RJMP ??BatteryStatusRefresh_5
\r
416 210 BattData.Low = FALSE; // (This is just a technicality..)
\r
417 \ ??BatteryStatusRefresh_4:
\r
418 \ 00000086 910C LD R16, X
\r
419 \ 00000088 7F0B ANDI R16, 0xFB
\r
420 \ 0000008A 930C ST X, R16
\r
421 211 success = FALSE;
\r
422 \ 0000008C E000 LDI R16, 0
\r
425 214 #ifndef ALLOW_NO_RID
\r
426 215 // Return FALSE if no valid RID entry was found, to stop charging.
\r
427 216 if(!BattData.HasRID) {
\r
428 \ ??BatteryStatusRefresh_5:
\r
429 \ 0000008E 911C LD R17, X
\r
430 \ 00000090 FF14 SBRS R17, 4
\r
431 217 success = FALSE;
\r
432 \ 00000092 E000 LDI R16, 0
\r
436 221 return(success);
\r
437 \ ??BatteryStatusRefresh_6:
\r
438 \ 00000094 9189 LD R24, Y+
\r
439 \ 00000096 9199 LD R25, Y+
\r
440 \ 00000098 91A9 LD R26, Y+
\r
441 \ 0000009A 91B9 LD R27, Y+
\r
442 \ 0000009C 9508 RET
\r
443 \ 0000009E REQUIRE _A_OCR1B
\r
447 225 /*! \brief Refreshes battery data in the EEPROM
\r
449 227 * Attempts to read 4 pages of 32 bytes each from the battery's EPROM and store
\r
450 228 * these data in on-chip EEPROM.\n
\r
451 229 * If unsuccessful (CRC doesn't check out), the on-chip EEPROM is cleared.
\r
453 231 * \todo Updating BattData with these data. Specs needed.
\r
455 233 * \retval FALSE Refresh failed.
\r
456 234 * \retval TRUE Refresh successful.
\r
459 \ In segment CODE, align 2, keep-with-next
\r
460 236 unsigned char BatteryDataRefresh(void)
\r
461 \ BatteryDataRefresh:
\r
463 \ 00000000 928A ST -Y, R8
\r
464 \ 00000002 927A ST -Y, R7
\r
465 \ 00000004 926A ST -Y, R6
\r
466 \ 00000006 925A ST -Y, R5
\r
467 \ 00000008 924A ST -Y, R4
\r
468 \ 0000000A 93BA ST -Y, R27
\r
469 \ 0000000C 93AA ST -Y, R26
\r
470 \ 0000000E 939A ST -Y, R25
\r
471 \ 00000010 938A ST -Y, R24
\r
472 \ 00000012 REQUIRE ?Register_R4_is_cg_reg
\r
473 \ 00000012 REQUIRE ?Register_R5_is_cg_reg
\r
474 \ 00000012 REQUIRE ?Register_R6_is_cg_reg
\r
475 \ 00000012 REQUIRE ?Register_R7_is_cg_reg
\r
476 \ 00000012 REQUIRE ?Register_R8_is_cg_reg
\r
477 238 unsigned char offset;
\r
478 239 unsigned char i, crc, family, temp, page;
\r
479 240 unsigned char success;
\r
481 242 // Look for EPROM and read 4 pages of 32 bytes each worth of data, if found.
\r
482 243 for (page = 0; page < 4; page++) {
\r
483 \ 00000012 E090 LDI R25, 0
\r
484 \ 00000014 .... LDI R26, LOW(BattEEPROM)
\r
485 \ 00000016 .... LDI R27, (BattEEPROM) >> 8
\r
486 244 success = FALSE;
\r
487 \ ??BatteryDataRefresh_0:
\r
488 \ 00000018 2477 CLR R7
\r
490 246 if (OWI_DetectPresence(OWIBUS) == OWIBUS) {
\r
491 \ 0000001A E001 LDI R16, 1
\r
492 \ 0000001C .... RCALL OWI_DetectPresence
\r
493 \ 0000001E 3001 CPI R16, 1
\r
494 \ 00000020 F009 BREQ $+2+2
\r
495 \ 00000022 C055 RJMP ??BatteryDataRefresh_1
\r
497 248 // Presence detected, check type and CRC.
\r
498 249 OWI_SendByte(OWI_ROM_READ, OWIBUS);
\r
499 \ 00000024 E011 LDI R17, 1
\r
500 \ 00000026 E303 LDI R16, 51
\r
501 \ 00000028 .... RCALL OWI_SendByte
\r
502 250 family = OWI_ReceiveByte(OWIBUS);
\r
503 \ 0000002A E001 LDI R16, 1
\r
504 \ 0000002C .... RCALL OWI_ReceiveByte
\r
505 \ 0000002E 2E50 MOV R5, R16
\r
506 251 crc = OWI_ComputeCRC8(family,0);
\r
507 \ 00000030 E010 LDI R17, 0
\r
508 \ 00000032 .... RCALL OWI_ComputeCRC8
\r
509 \ 00000034 2F80 MOV R24, R16
\r
511 253 for (i = 0; i < 6; i++) {
\r
512 \ 00000036 E006 LDI R16, 6
\r
513 \ 00000038 2E40 MOV R4, R16
\r
514 254 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc);
\r
515 \ ??BatteryDataRefresh_2:
\r
516 \ 0000003A E001 LDI R16, 1
\r
517 \ 0000003C .... RCALL OWI_ReceiveByte
\r
518 \ 0000003E 2F18 MOV R17, R24
\r
519 \ 00000040 .... RCALL OWI_ComputeCRC8
\r
520 \ 00000042 2F80 MOV R24, R16
\r
522 \ 00000044 944A DEC R4
\r
523 \ 00000046 F7C9 BRNE ??BatteryDataRefresh_2
\r
525 257 // CRC ok, device found.
\r
526 258 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
\r
527 \ 00000048 E001 LDI R16, 1
\r
528 \ 0000004A .... RCALL OWI_ReceiveByte
\r
529 \ 0000004C 2F18 MOV R17, R24
\r
530 \ 0000004E .... RCALL OWI_ComputeCRC8
\r
531 \ 00000050 2300 TST R16
\r
532 \ 00000052 F5E9 BRNE ??BatteryDataRefresh_1
\r
533 259 BattData.Circuit = family;
\r
534 \ 00000054 9250.... STS (BattData + 1), R5
\r
536 261 // For now, we only read data from DS2505 EPROMs.
\r
537 262 if (BattData.Circuit == OW_DS2505) {
\r
538 \ 00000058 9100.... LDS R16, (BattData + 1)
\r
539 \ 0000005C 3009 CPI R16, 9
\r
540 \ 0000005E F5B9 BRNE ??BatteryDataRefresh_1
\r
541 263 offset = page*32;
\r
542 \ 00000060 2E49 MOV R4, R25
\r
543 \ 00000062 9442 SWAP R4
\r
544 \ 00000064 EF00 LDI R16, 240
\r
545 \ 00000066 2240 AND R4, R16
\r
546 \ 00000068 0C44 LSL R4
\r
547 264 OWI_SendByte(DS2505_DATA_READ, OWIBUS); // Command: read data.
\r
548 \ 0000006A E011 LDI R17, 1
\r
549 \ 0000006C EC03 LDI R16, 195
\r
550 \ 0000006E .... RCALL OWI_SendByte
\r
551 265 OWI_SendByte(offset, OWIBUS); // Data: low address.
\r
552 \ 00000070 E011 LDI R17, 1
\r
553 \ 00000072 2D04 MOV R16, R4
\r
554 \ 00000074 .... RCALL OWI_SendByte
\r
555 266 OWI_SendByte(0, OWIBUS); // Data: high address.
\r
556 \ 00000076 E011 LDI R17, 1
\r
557 \ 00000078 E000 LDI R16, 0
\r
558 \ 0000007A .... RCALL OWI_SendByte
\r
560 268 // Calculate checksums.
\r
561 269 crc = OWI_ComputeCRC8(DS2505_DATA_READ,0);
\r
562 \ 0000007C E010 LDI R17, 0
\r
563 \ 0000007E EC03 LDI R16, 195
\r
564 \ 00000080 .... RCALL OWI_ComputeCRC8
\r
565 270 crc = OWI_ComputeCRC8(offset,crc);
\r
566 \ 00000082 2F10 MOV R17, R16
\r
567 \ 00000084 2D04 MOV R16, R4
\r
568 \ 00000086 .... RCALL OWI_ComputeCRC8
\r
569 271 crc = OWI_ComputeCRC8(0,crc);
\r
570 \ 00000088 2F10 MOV R17, R16
\r
571 \ 0000008A E000 LDI R16, 0
\r
572 \ 0000008C .... RCALL OWI_ComputeCRC8
\r
573 \ 0000008E 2F80 MOV R24, R16
\r
575 273 // Command received succesfully, now start reading data
\r
576 274 // and writing it to EEPROM.
\r
577 275 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
\r
578 \ 00000090 E001 LDI R16, 1
\r
579 \ 00000092 .... RCALL OWI_ReceiveByte
\r
580 \ 00000094 2F18 MOV R17, R24
\r
581 \ 00000096 .... RCALL OWI_ComputeCRC8
\r
582 \ 00000098 2300 TST R16
\r
583 \ 0000009A F4C9 BRNE ??BatteryDataRefresh_1
\r
585 \ 0000009C E080 LDI R24, 0
\r
587 278 // Fill page with data.
\r
588 279 for (i=0; i<32; i++) {
\r
589 \ 0000009E 012D MOVW R5:R4, R27:R26
\r
590 \ 000000A0 E200 LDI R16, 32
\r
591 \ 000000A2 2E60 MOV R6, R16
\r
592 280 temp = OWI_ReceiveByte(OWIBUS);
\r
593 \ ??BatteryDataRefresh_3:
\r
594 \ 000000A4 E001 LDI R16, 1
\r
595 \ 000000A6 .... RCALL OWI_ReceiveByte
\r
596 \ 000000A8 2E80 MOV R8, R16
\r
597 281 crc = OWI_ComputeCRC8(temp, crc);
\r
598 \ 000000AA 2F18 MOV R17, R24
\r
599 \ 000000AC .... RCALL OWI_ComputeCRC8
\r
600 \ 000000AE 2F80 MOV R24, R16
\r
601 282 BattEEPROM[page][i] = temp;
\r
602 \ 000000B0 2D08 MOV R16, R8
\r
603 \ 000000B2 01A2 MOVW R21:R20, R5:R4
\r
604 \ 000000B4 .... RCALL __eeput8_16
\r
606 \ 000000B6 E001 LDI R16, 1
\r
607 \ 000000B8 0E40 ADD R4, R16
\r
608 \ 000000BA 1C57 ADC R5, R7
\r
609 \ 000000BC 946A DEC R6
\r
610 \ 000000BE F791 BRNE ??BatteryDataRefresh_3
\r
612 285 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
\r
613 \ 000000C0 .... RCALL OWI_ReceiveByte
\r
614 \ 000000C2 2F18 MOV R17, R24
\r
615 \ 000000C4 .... RCALL OWI_ComputeCRC8
\r
616 \ 000000C6 2300 TST R16
\r
617 \ 000000C8 F411 BRNE ??BatteryDataRefresh_1
\r
618 286 success = TRUE; // Data read OK
\r
619 \ 000000CA 9473 INC R7
\r
620 \ 000000CC C008 RJMP ??BatteryDataRefresh_4
\r
622 288 } else { // Not able to start reading data.
\r
624 290 } else { // Wrong device type.
\r
626 292 } else { // No device found.
\r
628 294 } else { // No presence detected on one-wire bus.
\r
631 297 // Erase local EEPROM page if there were any errors during transfer.
\r
632 298 if (!success) {
\r
633 299 for (i=0; i<32; i++) {
\r
634 \ ??BatteryDataRefresh_1:
\r
635 \ 000000CE 01AD MOVW R21:R20, R27:R26
\r
636 \ 000000D0 E210 LDI R17, 32
\r
637 300 BattEEPROM[page][i] = 0;
\r
638 \ ??BatteryDataRefresh_5:
\r
639 \ 000000D2 E000 LDI R16, 0
\r
640 \ 000000D4 .... RCALL __eeput8_16
\r
642 \ 000000D6 5F4F SUBI R20, 255
\r
643 \ 000000D8 4F5F SBCI R21, 255
\r
644 \ 000000DA 951A DEC R17
\r
645 \ 000000DC F7D1 BRNE ??BatteryDataRefresh_5
\r
648 \ ??BatteryDataRefresh_4:
\r
649 \ 000000DE 9593 INC R25
\r
650 \ 000000E0 9690 ADIW R27:R26, 32
\r
651 \ 000000E2 3094 CPI R25, 4
\r
652 \ 000000E4 F408 BRCC $+2+2
\r
653 \ 000000E6 CF98 RJMP ??BatteryDataRefresh_0
\r
655 305 return(success);
\r
656 \ 000000E8 2D07 MOV R16, R7
\r
657 \ 000000EA 9189 LD R24, Y+
\r
658 \ 000000EC 9199 LD R25, Y+
\r
659 \ 000000EE 91A9 LD R26, Y+
\r
660 \ 000000F0 91B9 LD R27, Y+
\r
661 \ 000000F2 9049 LD R4, Y+
\r
662 \ 000000F4 9059 LD R5, Y+
\r
663 \ 000000F6 9069 LD R6, Y+
\r
664 \ 000000F8 9079 LD R7, Y+
\r
665 \ 000000FA 9089 LD R8, Y+
\r
666 \ 000000FC 9508 RET
\r
670 309 /*! \brief Enables specified battery
\r
672 311 * Updates \ref BattActive to specified battery, then sets PB4/PB5 and clears
\r
673 312 * PB5/PB4 in PORTB, depending on which battery is specified.\n
\r
674 313 * The function takes 100 ms to allow the port switch to settle.
\r
676 315 * \param bat Specifies which battery to enable (0 = battery A, 1 = B)
\r
679 \ In segment CODE, align 2, keep-with-next
\r
680 317 void EnableBattery(unsigned char bat)
\r
683 \ 00000000 938A ST -Y, R24
\r
684 \ 00000002 2F80 MOV R24, R16
\r
685 319 // Use general timer, set timeout to 100ms.
\r
686 320 Time_Set(TIMER_GEN,0,0,100);
\r
687 \ 00000004 E644 LDI R20, 100
\r
688 \ 00000006 E010 LDI R17, 0
\r
689 \ 00000008 E020 LDI R18, 0
\r
690 \ 0000000A E030 LDI R19, 0
\r
691 \ 0000000C E002 LDI R16, 2
\r
692 \ 0000000E .... RCALL Time_Set
\r
694 322 // Set specified battery as the active one.
\r
695 323 BattActive = bat;
\r
696 \ 00000010 9380.... STS BattActive, R24
\r
698 325 // Enable current battery in hardware, light LED & connect battery.
\r
699 326 PORTB |= (1 << (PB4+bat));
\r
700 \ 00000014 E001 LDI R16, 1
\r
701 \ 00000016 E010 LDI R17, 0
\r
702 \ 00000018 2F48 MOV R20, R24
\r
703 \ 0000001A 5F4C SUBI R20, 252
\r
704 \ 0000001C .... RCALL ?S_SHL_L02
\r
705 \ 0000001E B318 IN R17, 0x18
\r
706 \ 00000020 2B10 OR R17, R16
\r
707 \ 00000022 BB18 OUT 0x18, R17
\r
709 328 // Disconnect other battery.
\r
710 329 PORTB &= ~(1<<(PB5-bat));
\r
711 \ 00000024 E001 LDI R16, 1
\r
712 \ 00000026 E010 LDI R17, 0
\r
713 \ 00000028 E045 LDI R20, 5
\r
714 \ 0000002A 1B48 SUB R20, R24
\r
715 \ 0000002C .... RCALL ?S_SHL_L02
\r
716 \ 0000002E 9500 COM R16
\r
717 \ 00000030 B318 IN R17, 0x18
\r
718 \ 00000032 2310 AND R17, R16
\r
719 \ 00000034 BB18 OUT 0x18, R17
\r
721 331 do { // Let port switch settle.
\r
722 332 } while (Time_Left(TIMER_GEN));
\r
723 \ ??EnableBattery_0:
\r
724 \ 00000036 E002 LDI R16, 2
\r
725 \ 00000038 .... RCALL Time_Left
\r
726 \ 0000003A 2300 TST R16
\r
727 \ 0000003C F7E1 BRNE ??EnableBattery_0
\r
729 \ 0000003E 9189 LD R24, Y+
\r
730 \ 00000040 9508 RET
\r
731 \ 00000042 REQUIRE _A_PORTB
\r
734 336 /*! \brief Disables both batteries
\r
736 338 * Clears PB4 and PB5 in PORTB, disabling both batteries.
\r
739 \ In segment CODE, align 2, keep-with-next
\r
740 340 void DisableBatteries(void)
\r
741 \ DisableBatteries:
\r
743 342 // Turn off LEDs and disconnect batteries.
\r
744 343 PORTB &= ~((1<<PB4)|(1<<PB5));
\r
745 \ 00000000 B308 IN R16, 0x18
\r
746 \ 00000002 7C0F ANDI R16, 0xCF
\r
747 \ 00000004 BB08 OUT 0x18, R16
\r
749 \ 00000006 9508 RET
\r
750 \ 00000008 REQUIRE _A_PORTB
\r
753 347 /*! \brief Looks up battery data from RID table
\r
755 349 * Attempts to find data for the battery from the RID lookup-table.\n
\r
756 350 * If no valid entry is found, default data (defined in battery.h)
\r
759 353 * \retval TRUE Entry found, battery data updated.
\r
760 354 * \retval FALSE No entry found, using defaults for battery data.
\r
763 \ In segment CODE, align 2, keep-with-next
\r
764 356 unsigned char RIDLookUp (void)
\r
767 \ 00000000 2F3B MOV R19, R27
\r
768 \ 00000002 2E2A MOV R2, R26
\r
769 358 unsigned char i, found = FALSE;
\r
770 \ 00000004 E040 LDI R20, 0
\r
772 360 // Lookup in the RID-table. If measured RID is within the limits
\r
773 361 // of an entry, those data are used, and TRUE is returned.
\r
774 362 for (i = 0 ; i < RID_TABLE_SIZE; i++) {
\r
775 \ 00000006 .... LDI R30, LOW(RID)
\r
776 \ 00000008 .... LDI R31, (RID) >> 8
\r
777 \ 0000000A E024 LDI R18, 4
\r
778 \ 0000000C .... LDI R16, LOW(BattData)
\r
779 \ 0000000E .... LDI R17, (BattData) >> 8
\r
780 363 if (ADCS.rawRID >= RID[i].Low) {
\r
782 \ 00000010 .... LDI R26, LOW((ADCS + 2))
\r
783 \ 00000012 .... LDI R27, HIGH((ADCS + 2))
\r
784 \ 00000014 916D LD R22, X+
\r
785 \ 00000016 917C LD R23, X
\r
786 \ 00000018 8000 LD R0, Z
\r
787 \ 0000001A 8011 LDD R1, Z+1
\r
788 \ 0000001C 1560 CP R22, R0
\r
789 \ 0000001E 0571 CPC R23, R1
\r
790 \ 00000020 F0F0 BRCS ??RIDLookUp_1
\r
791 364 if (ADCS.rawRID <= RID[i].High) {
\r
792 \ 00000022 8002 LDD R0, Z+2
\r
793 \ 00000024 8013 LDD R1, Z+3
\r
794 \ 00000026 1606 CP R0, R22
\r
795 \ 00000028 0617 CPC R1, R23
\r
796 \ 0000002A F0C8 BRCS ??RIDLookUp_1
\r
797 365 BattData.Capacity = RID[i].Capacity;
\r
798 \ 0000002C 8146 LDD R20, Z+6
\r
799 \ 0000002E 8157 LDD R21, Z+7
\r
800 \ 00000030 01D8 MOVW R27:R26, R17:R16
\r
801 \ 00000032 9614 ADIW R27:R26, 4
\r
802 \ 00000034 934D ST X+, R20
\r
803 \ 00000036 935C ST X, R21
\r
804 366 BattData.MaxCurrent = RID[i].Icharge;
\r
805 \ 00000038 8540 LDD R20, Z+8
\r
806 \ 0000003A 8551 LDD R21, Z+9
\r
807 \ 0000003C 01D8 MOVW R27:R26, R17:R16
\r
808 \ 0000003E 9616 ADIW R27:R26, 6
\r
809 \ 00000040 934D ST X+, R20
\r
810 \ 00000042 935C ST X, R21
\r
811 367 BattData.MaxTime = RID[i].tCutOff;
\r
812 \ 00000044 8542 LDD R20, Z+10
\r
813 \ 00000046 8553 LDD R21, Z+11
\r
814 \ 00000048 01D8 MOVW R27:R26, R17:R16
\r
815 \ 0000004A 9618 ADIW R27:R26, 8
\r
816 \ 0000004C 934D ST X+, R20
\r
817 \ 0000004E 935C ST X, R21
\r
818 368 BattData.MinCurrent = RID[i].ICutOff;
\r
819 \ 00000050 8544 LDD R20, Z+12
\r
820 \ 00000052 8555 LDD R21, Z+13
\r
821 \ 00000054 01D8 MOVW R27:R26, R17:R16
\r
822 \ 00000056 961A ADIW R27:R26, 10
\r
823 \ 00000058 934D ST X+, R20
\r
824 \ 0000005A 935C ST X, R21
\r
827 \ 0000005C E041 LDI R20, 1
\r
832 \ 0000005E 963E ADIW R31:R30, 14
\r
833 \ 00000060 952A DEC R18
\r
834 \ 00000062 F6B1 BRNE ??RIDLookUp_0
\r
836 375 // If no valid entry is found, use defaults and return FALSE.
\r
838 \ 00000064 2344 TST R20
\r
839 \ 00000066 F451 BRNE ??RIDLookUp_2
\r
840 377 BattData.Capacity = DEF_BAT_CAPACITY;
\r
841 \ 00000068 E020 LDI R18, 0
\r
842 \ 0000006A 01F8 MOVW R31:R30, R17:R16
\r
843 \ 0000006C 8324 STD Z+4, R18
\r
844 \ 0000006E 8325 STD Z+5, R18
\r
845 378 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX;
\r
846 \ 00000070 8326 STD Z+6, R18
\r
847 \ 00000072 8327 STD Z+7, R18
\r
848 379 BattData.MaxTime = DEF_BAT_TIME_MAX;
\r
849 \ 00000074 8720 STD Z+8, R18
\r
850 \ 00000076 8721 STD Z+9, R18
\r
851 380 BattData.MinCurrent = DEF_BAT_CURRENT_MIN;
\r
852 \ 00000078 8722 STD Z+10, R18
\r
853 \ 0000007A 8723 STD Z+11, R18
\r
858 \ 0000007C 2F04 MOV R16, R20
\r
859 \ 0000007E 2DA2 MOV R26, R2
\r
860 \ 00000080 2FB3 MOV R27, R19
\r
861 \ 00000082 9508 RET
\r
865 387 /*! \brief Calculates temperature from a lookup table
\r
867 389 * Looks up the highest NTC value below or equal to the measured one.\n
\r
868 390 * With the current lookup table, temperature is calculated with the formula:\n
\r
869 391 * 4*(index of entry) - 2*(measured NTC - NTC from entry) / (ADCsteps of entry)
\r
871 393 * \note If the NTC-measurement is saturated, with the current lookup table,
\r
872 394 * the temperature will be reported as -1 C.
\r
874 396 * \note If no valid entry is found, battery temperature is set to 80.
\r
877 \ In segment CODE, align 2, keep-with-next
\r
878 398 void NTCLookUp (void)
\r
881 \ 00000000 93BA ST -Y, R27
\r
882 \ 00000002 2E3A MOV R3, R26
\r
883 \ 00000004 2E28 MOV R2, R24
\r
884 400 unsigned char i;
\r
885 401 unsigned char found = FALSE;
\r
886 \ 00000006 E000 LDI R16, 0
\r
888 403 // Lookup in the NTC-table. Use the first entry which is equal or below
\r
889 404 // sampled NTC. Calculate temperature by using the index number, and the
\r
890 405 // difference between the measured NTC value and the one in the entry.
\r
891 406 for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++) {
\r
892 \ 00000008 E080 LDI R24, 0
\r
893 \ 0000000A .... LDI R26, LOW(BattData)
\r
894 \ 0000000C .... LDI R27, (BattData) >> 8
\r
895 407 if (ADCS.rawNTC >= NTC[i].ADC) {
\r
897 \ 0000000E 2F48 MOV R20, R24
\r
898 \ 00000010 E050 LDI R21, 0
\r
899 \ 00000012 019A MOVW R19:R18, R21:R20
\r
900 \ 00000014 0F44 LSL R20
\r
901 \ 00000016 1F55 ROL R21
\r
902 \ 00000018 0F42 ADD R20, R18
\r
903 \ 0000001A 1F53 ADC R21, R19
\r
904 \ 0000001C .... LDI R18, LOW(NTC)
\r
905 \ 0000001E .... LDI R19, (NTC) >> 8
\r
906 \ 00000020 0F24 ADD R18, R20
\r
907 \ 00000022 1F35 ADC R19, R21
\r
908 \ 00000024 .... LDI R30, LOW(ADCS)
\r
909 \ 00000026 .... LDI R31, (ADCS) >> 8
\r
910 \ 00000028 8144 LDD R20, Z+4
\r
911 \ 0000002A 8155 LDD R21, Z+5
\r
912 \ 0000002C 01F9 MOVW R31:R30, R19:R18
\r
913 \ 0000002E 8160 LD R22, Z
\r
914 \ 00000030 8171 LDD R23, Z+1
\r
915 \ 00000032 1746 CP R20, R22
\r
916 \ 00000034 0757 CPC R21, R23
\r
917 \ 00000036 F0D0 BRCS ??NTCLookUp_1
\r
918 408 BattData.Temperature = (i<<2) ;
\r
919 \ 00000038 2F08 MOV R16, R24
\r
920 \ 0000003A 0F00 LSL R16
\r
921 \ 0000003C 0F00 LSL R16
\r
922 \ 0000003E 01FD MOVW R31:R30, R27:R26
\r
923 \ 00000040 8302 STD Z+2, R16
\r
924 409 BattData.ADCSteps = NTC[i].ADCsteps;
\r
925 \ 00000042 01F9 MOVW R31:R30, R19:R18
\r
926 \ 00000044 8142 LDD R20, Z+2
\r
927 \ 00000046 01FD MOVW R31:R30, R27:R26
\r
928 \ 00000048 8343 STD Z+3, R20
\r
929 410 BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps;
\r
930 \ 0000004A 9100.... LDS R16, (ADCS + 4)
\r
931 \ 0000004E 2F15 MOV R17, R21
\r
932 \ 00000050 01F9 MOVW R31:R30, R19:R18
\r
933 \ 00000052 8120 LD R18, Z
\r
934 \ 00000054 8131 LDD R19, Z+1
\r
935 \ 00000056 1B02 SUB R16, R18
\r
936 \ 00000058 0B13 SBC R17, R19
\r
937 \ 0000005A 0F00 LSL R16
\r
938 \ 0000005C 1F11 ROL R17
\r
939 \ 0000005E E050 LDI R21, 0
\r
940 \ 00000060 .... RCALL ?US_DIVMOD_L02
\r
941 \ 00000062 01FD MOVW R31:R30, R27:R26
\r
942 \ 00000064 8112 LDD R17, Z+2
\r
943 \ 00000066 1B10 SUB R17, R16
\r
944 \ 00000068 8312 STD Z+2, R17
\r
946 412 found = TRUE; // Could be done with a break, but that violates MISRA.
\r
947 \ 0000006A E001 LDI R16, 1
\r
951 \ 0000006C 9583 INC R24
\r
952 \ 0000006E 3184 CPI R24, 20
\r
953 \ 00000070 F410 BRCC ??NTCLookUp_2
\r
954 \ 00000072 2300 TST R16
\r
955 \ 00000074 F261 BREQ ??NTCLookUp_0
\r
957 416 // For safety, is temperature is greater than the NTC
\r
960 \ 00000076 2300 TST R16
\r
961 \ 00000078 F419 BRNE ??NTCLookUp_3
\r
962 418 BattData.Temperature = 80;
\r
963 \ 0000007A E500 LDI R16, 80
\r
964 \ 0000007C 9300.... STS (BattData + 2), R16
\r
968 \ 00000080 2D82 MOV R24, R2
\r
969 \ 00000082 2DA3 MOV R26, R3
\r
970 \ 00000084 91B9 LD R27, Y+
\r
971 \ 00000086 9508 RET
\r
973 \ In segment NEAR_ID, align 1, keep-with-next
\r
974 \ `?<Initializer for RID>`:
\r
975 \ 00000000 022E02930F3C DW 558, 659, 3900, 550, 260, 300, 10, 744, 843, 6800, 750, 360, 300, 14
\r
980 \ 0000001C 036503BE2710 DW 869, 958, 10000, 1000, 475, 300, 19, 1097, 1153, 24000, 2000, 475
\r
984 \ 00000034 01A40026 DW 420, 38
\r
986 \ In segment NEAR_ID, align 1, keep-with-next
\r
987 \ `?<Initializer for NTC>`:
\r
988 \ 00000000 03EA DW 1002
\r
989 \ 00000002 17 DB 23
\r
990 \ 00000003 03B9 DW 953
\r
991 \ 00000005 19 DB 25
\r
992 \ 00000006 0386 DW 902
\r
993 \ 00000008 1A DB 26
\r
994 \ 00000009 0351 DW 849
\r
995 \ 0000000B 1B DB 27
\r
996 \ 0000000C 031C DW 796
\r
997 \ 0000000E 1B DB 27
\r
998 \ 0000000F 02E6 DW 742
\r
999 \ 00000011 1B DB 27
\r
1000 \ 00000012 02B1 DW 689
\r
1001 \ 00000014 1A DB 26
\r
1002 \ 00000015 027D DW 637
\r
1003 \ 00000017 1A DB 26
\r
1004 \ 00000018 024B DW 587
\r
1005 \ 0000001A 19 DB 25
\r
1006 \ 0000001B 021B DW 539
\r
1007 \ 0000001D 18 DB 24
\r
1008 \ 0000001E 01EE DW 494
\r
1009 \ 00000020 16 DB 22
\r
1010 \ 00000021 01C3 DW 451
\r
1011 \ 00000023 15 DB 21
\r
1012 \ 00000024 019C DW 412
\r
1013 \ 00000026 13 DB 19
\r
1014 \ 00000027 0177 DW 375
\r
1015 \ 00000029 12 DB 18
\r
1016 \ 0000002A 0155 DW 341
\r
1017 \ 0000002C 11 DB 17
\r
1018 \ 0000002D 0136 DW 310
\r
1019 \ 0000002F 0F DB 15
\r
1020 \ 00000030 011A DW 282
\r
1021 \ 00000032 0E DB 14
\r
1022 \ 00000033 0100 DW 256
\r
1023 \ 00000035 0D DB 13
\r
1024 \ 00000036 00E9 DW 233
\r
1025 \ 00000038 0B DB 11
\r
1026 \ 00000039 00D4 DW 212
\r
1027 \ 0000003B 0A DB 10
\r
1029 Maximum stack usage in bytes:
\r
1031 Function CSTACK RSTACK
\r
1032 -------- ------ ------
\r
1034 -> BatteryStatusRefresh 3 2
\r
1035 BatteryDataRefresh 9 4
\r
1036 -> OWI_DetectPresence 9 2
\r
1037 -> OWI_SendByte 9 2
\r
1038 -> OWI_ReceiveByte 9 2
\r
1039 -> OWI_ComputeCRC8 9 2
\r
1040 -> OWI_ReceiveByte 9 2
\r
1041 -> OWI_ComputeCRC8 9 2
\r
1042 -> OWI_ReceiveByte 9 2
\r
1043 -> OWI_ComputeCRC8 9 2
\r
1044 -> OWI_SendByte 9 2
\r
1045 -> OWI_SendByte 9 2
\r
1046 -> OWI_SendByte 9 2
\r
1047 -> OWI_ComputeCRC8 9 2
\r
1048 -> OWI_ComputeCRC8 9 2
\r
1049 -> OWI_ComputeCRC8 9 2
\r
1050 -> OWI_ReceiveByte 9 2
\r
1051 -> OWI_ComputeCRC8 9 2
\r
1052 -> OWI_ReceiveByte 9 2
\r
1053 -> OWI_ComputeCRC8 9 2
\r
1054 -> OWI_ReceiveByte 9 2
\r
1055 -> OWI_ComputeCRC8 9 2
\r
1056 BatteryStatusRefresh 4 2
\r
1059 DisableBatteries 0 2
\r
1067 Segment part sizes:
\r
1069 Function/Label Bytes
\r
1070 -------------- -----
\r
1080 BatteryStatusRefresh 158
\r
1081 BatteryDataRefresh 254
\r
1083 DisableBatteries 8
\r
1086 ?<Initializer for RID> 56
\r
1087 ?<Initializer for NTC> 60
\r
1091 2 bytes in segment ABSOLUTE
\r
1092 804 bytes in segment CODE
\r
1093 130 bytes in segment EEPROM_I
\r
1094 12 bytes in segment INITTAB
\r
1095 116 bytes in segment NEAR_I
\r
1096 116 bytes in segment NEAR_ID
\r
1097 13 bytes in segment NEAR_Z
\r
1099 920 bytes of CODE memory (+ 12 bytes shared)
\r
1100 129 bytes of DATA memory (+ 2 bytes shared)
\r
1101 130 bytes of XDATA memory
\r