1 ###############################################################################
\r
3 # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:38 #
\r
4 # Copyright 1996-2007 IAR Systems. All rights reserved. #
\r
6 # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\battery.c #
\r
7 # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\battery.c #
\r
8 # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IAR #
\r
9 # \Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debu #
\r
10 # g\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Li #
\r
11 # st\ --initializers_in_flash -z2 --no_cse --no_inline #
\r
12 # --no_code_motion --no_cross_call --no_clustering #
\r
13 # --no_tbaa --debug -DENABLE_BIT_DEFINITIONS -e #
\r
14 # --require_prototypes -I "C:\Program Files\IAR #
\r
15 # Systems\Embedded Workbench 4.0\avr\INC\" -I "C:\Program #
\r
16 # Files\IAR Systems\Embedded Workbench 4.0\avr\INC\CLIB\" #
\r
17 # --eeprom_size 512 #
\r
18 # List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\battery.l #
\r
20 # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\battery.r9 #
\r
24 ###############################################################################
\r
26 C:\home\kevin\pub\src\bc100_cal\IAR\battery.c
\r
27 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
28 2 /*! \file *********************************************************************
\r
31 5 * Functions related to battery control and data acquisition.
\r
33 7 * Contains functions for enabling/disabling batteries, and looking up
\r
34 8 * their status and specifications using the ADC.
\r
36 10 * \par Application note:
\r
37 11 * AVR458: Charging Li-Ion Batteries with BC100 \n
\r
38 12 * AVR463: Charging NiMH Batteries with BC100
\r
41 15 * \par Documentation
\r
42 16 * For comprehensive code documentation, supported compilers, compiler
\r
43 17 * settings and supported devices see readme.html
\r
46 20 * Atmel Corporation: http://www.atmel.com \n
\r
47 21 * Support email: avr@atmel.com
\r
51 25 * $Revision: 2299 $
\r
53 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
54 28 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
55 29 ******************************************************************************/
\r
57 31 #include <ioavr.h>
\r
59 \ In segment ABSOLUTE, at 0x4c
\r
60 \ <unnamed> volatile __io _A_OCR1B
\r
64 \ In segment ABSOLUTE, at 0x38
\r
65 \ <unnamed> volatile __io _A_PORTB
\r
68 32 #include <inavr.h>
\r
70 34 #include "structs.h"
\r
71 35 #include "enums.h"
\r
74 38 #include "battery.h"
\r
75 39 #include "main.h"
\r
77 41 #include "time.h"
\r
80 44 #include "NIMHspecs.h"
\r
84 48 #include "LIIONspecs.h"
\r
89 53 //******************************************************************************
\r
91 55 //******************************************************************************
\r
92 56 /* Control-struct for batteries */
\r
93 57 /*! \brief Holds control data for both batteries
\r
94 58 * \note Stored in EEPROM.
\r
97 \ In segment EEPROM_I, align 1, keep-with-next
\r
98 60 __eeprom Battery_t BattControl[2] = {{TRUE, TRUE, FALSE},
\r
100 \ 00000000 0303 DB 3, 3
\r
101 61 {TRUE, TRUE, FALSE}};
\r
103 63 /* Data-struct for battery */
\r
105 \ In segment NEAR_Z, align 1, keep-with-next
\r
106 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
107 64 Batteries_t BattData; //!< Holds data for the current battery
\r
112 67 /* Storage for battery EPROM */
\r
113 68 /*! \brief Storage space for data from the batteries' own EPROMs.
\r
114 69 * \note Stored in EEPROM.
\r
117 \ In segment EEPROM_I, align 1, keep-with-next
\r
118 71 __eeprom unsigned char BattEEPROM[4][32];
\r
120 \ 00000000 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
123 \ 00000010 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
126 \ 00000020 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
129 \ 00000030 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
132 \ 00000040 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
135 \ 00000050 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
138 \ 00000060 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
141 \ 00000070 000000000000 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
146 74 //! Global that indicates current battery (0 = battery A, 1 = B)
\r
148 \ In segment NEAR_Z, align 1, keep-with-next
\r
149 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
150 75 unsigned char BattActive;
\r
155 78 /*! \brief RID lookup-table
\r
157 80 * Contains Resistor ID data specified by manufacturer.
\r
159 82 * \note Values have been calculated assuming a +/- 15% tolerance.
\r
162 \ In segment NEAR_I, align 1, keep-with-next
\r
163 \ 00000000 REQUIRE `?<Segment init: NEAR_I>`
\r
164 84 const RID_Lookup_t RID[RID_TABLE_SIZE] = {
\r
167 \ 00000038 REQUIRE `?<Initializer for RID>`
\r
168 85 {558, 659, 3900, 550, 260, 300, 10},
\r
169 86 {744, 843, 6800, 750, 360, 300, 14},
\r
170 87 {869, 958, 10000, 1000, 475, 300, 19},
\r
171 88 {1097, 1153, 24000, 2000, 475, 420, 38}
\r
175 92 /*! \brief NTC lookup-table
\r
177 94 * The first entry is 0 degrees. For every entry after, temperature increases
\r
178 95 * with 4 degrees. With 20 entries, the last one equals (20-1)*4 = 76 degrees.\n
\r
179 96 * It must be sorted in descending ADC order.
\r
181 98 * \note This was calculated for a Mitsubishi RH16-3H103FB NTC.
\r
183 100 * \note NTCLookUp() must be modified if this table is changed so that:
\r
184 101 * - first entry is no longer 0 degrees.
\r
185 102 * - temperature difference between entries is no longer 4 degrees.
\r
186 103 * - ADCsteps no longer specifies ADC steps per half degree.
\r
188 105 // FOR VARTA POLYFLEX NTC
\r
190 \ In segment NEAR_I, align 1, keep-with-next
\r
191 \ 00000000 REQUIRE `?<Segment init: NEAR_I>`
\r
192 106 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {
\r
195 \ 0000003C REQUIRE `?<Initializer for NTC>`
\r
196 107 {1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27},
\r
197 108 {742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24},
\r
198 109 {494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17},
\r
199 110 {310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10}
\r
203 114 // FOR MITSUBISHI NTC
\r
205 116 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {
\r
206 117 {1004, 24}, {954, 25}, {903, 26}, {850, 27}, {796, 27},
\r
207 118 {742, 27}, {689, 27}, {637, 26}, {587, 25}, {539, 24},
\r
208 119 {493, 22}, {451, 21}, {411, 20}, {374, 18}, {340, 17},
\r
209 120 {309, 15}, {281, 14}, {255, 13}, {232, 11}, {211, 10}
\r
214 125 //******************************************************************************
\r
216 127 //******************************************************************************
\r
217 128 /*! \brief Checks if battery has changed
\r
219 130 * Stores current capacity, then attempts to refresh battery status.\n
\r
220 131 * If the refresh is successful, old capacity is compared with the new one.
\r
222 133 * \retval FALSE Battery is disconnected, or capacity has changed.
\r
223 134 * \retval TRUE All OK.
\r
226 \ In segment CODE, align 2, keep-with-next
\r
227 136 unsigned char BatteryCheck(void)
\r
230 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
231 138 unsigned char success = TRUE;
\r
232 \ 00000002 E081 LDI R24, 1
\r
233 139 unsigned int oldCapacity;
\r
235 141 // Save to see if battery data has changed.
\r
236 142 oldCapacity = BattData.Capacity;
\r
237 \ 00000004 .... LDI R30, LOW(BattData)
\r
238 \ 00000006 .... LDI R31, (BattData) >> 8
\r
239 \ 00000008 8104 LDD R16, Z+4
\r
240 \ 0000000A 8115 LDD R17, Z+5
\r
241 \ 0000000C 01D8 MOVW R27:R26, R17:R16
\r
243 144 if (!BatteryStatusRefresh()) {
\r
244 \ 0000000E .... RCALL BatteryStatusRefresh
\r
245 \ 00000010 2300 TST R16
\r
246 \ 00000012 F409 BRNE ??BatteryCheck_0
\r
247 145 success = FALSE; // Battery not present or RID was invalid.
\r
248 \ 00000014 E080 LDI R24, 0
\r
251 148 if (oldCapacity != BattData.Capacity) {
\r
252 \ ??BatteryCheck_0:
\r
253 \ 00000016 .... LDI R30, LOW(BattData)
\r
254 \ 00000018 .... LDI R31, (BattData) >> 8
\r
255 \ 0000001A 8104 LDD R16, Z+4
\r
256 \ 0000001C 8115 LDD R17, Z+5
\r
257 \ 0000001E 17A0 CP R26, R16
\r
258 \ 00000020 07B1 CPC R27, R17
\r
259 \ 00000022 F009 BREQ ??BatteryCheck_1
\r
260 149 success = FALSE; // Battery configuration has changed.
\r
261 \ 00000024 E080 LDI R24, 0
\r
264 152 return(success);
\r
265 \ ??BatteryCheck_1:
\r
266 \ 00000026 2F08 MOV R16, R24
\r
267 \ 00000028 E0E4 LDI R30, 4
\r
268 \ 0000002A .... RJMP ?EPILOGUE_B4_L09
\r
272 156 /*! \brief Refreshes battery status information
\r
274 158 * Refreshes battery status information, if it is present, based on
\r
275 159 * RID and NTC (read by ADC).\n
\r
276 160 * The battery must have been enabled and a complete set of ADC data must have
\r
277 161 * been collected before calling.\n
\r
279 163 * \retval FALSE No battery present.
\r
280 164 * \retval TRUE Battery present, status refreshed.
\r
282 166 * \note If ALLOW_NO_RID is defined, charging will NOT stop if no fitting entry
\r
283 167 * is found in the lookup table. Instead, default battery data will be used.
\r
286 \ In segment CODE, align 2, keep-with-next
\r
287 169 unsigned char BatteryStatusRefresh(void)
\r
288 \ BatteryStatusRefresh:
\r
290 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
291 171 // Assume the worst..
\r
292 172 unsigned char success = FALSE;
\r
293 \ 00000002 E080 LDI R24, 0
\r
295 174 BattData.Present = FALSE;
\r
296 \ 00000004 .... LDI R30, LOW(BattData)
\r
297 \ 00000006 .... LDI R31, (BattData) >> 8
\r
298 \ 00000008 8100 LD R16, Z
\r
299 \ 0000000A 7F0E ANDI R16, 0xFE
\r
300 \ 0000000C 8300 ST Z, R16
\r
301 175 BattData.Charged = FALSE;
\r
302 \ 0000000E .... LDI R30, LOW(BattData)
\r
303 \ 00000010 .... LDI R31, (BattData) >> 8
\r
304 \ 00000012 8100 LD R16, Z
\r
305 \ 00000014 7F0D ANDI R16, 0xFD
\r
306 \ 00000016 8300 ST Z, R16
\r
307 176 BattData.Low = TRUE;
\r
308 \ 00000018 .... LDI R30, LOW(BattData)
\r
309 \ 0000001A .... LDI R31, (BattData) >> 8
\r
310 \ 0000001C 8100 LD R16, Z
\r
311 \ 0000001E 6004 ORI R16, 0x04
\r
312 \ 00000020 8300 ST Z, R16
\r
313 177 BattData.Circuit = OW_NONE;
\r
314 \ 00000022 E000 LDI R16, 0
\r
315 \ 00000024 9300.... STS (BattData + 1), R16
\r
316 178 BattData.Temperature = 0;
\r
317 \ 00000028 E000 LDI R16, 0
\r
318 \ 0000002A 9300.... STS (BattData + 2), R16
\r
319 179 BattData.Capacity = 0;
\r
320 \ 0000002E E000 LDI R16, 0
\r
321 \ 00000030 E010 LDI R17, 0
\r
322 \ 00000032 .... LDI R30, LOW(BattData)
\r
323 \ 00000034 .... LDI R31, (BattData) >> 8
\r
324 \ 00000036 8304 STD Z+4, R16
\r
325 \ 00000038 8315 STD Z+5, R17
\r
326 180 BattData.MaxCurrent = 0;
\r
327 \ 0000003A E000 LDI R16, 0
\r
328 \ 0000003C E010 LDI R17, 0
\r
329 \ 0000003E .... LDI R30, LOW(BattData)
\r
330 \ 00000040 .... LDI R31, (BattData) >> 8
\r
331 \ 00000042 8306 STD Z+6, R16
\r
332 \ 00000044 8317 STD Z+7, R17
\r
333 181 BattData.MaxTime = 0;
\r
334 \ 00000046 E000 LDI R16, 0
\r
335 \ 00000048 E010 LDI R17, 0
\r
336 \ 0000004A .... LDI R30, LOW(BattData)
\r
337 \ 0000004C .... LDI R31, (BattData) >> 8
\r
338 \ 0000004E 8700 STD Z+8, R16
\r
339 \ 00000050 8711 STD Z+9, R17
\r
340 182 BattData.MinCurrent = 0;
\r
341 \ 00000052 E000 LDI R16, 0
\r
342 \ 00000054 E010 LDI R17, 0
\r
343 \ 00000056 .... LDI R30, LOW(BattData)
\r
344 \ 00000058 .... LDI R31, (BattData) >> 8
\r
345 \ 0000005A 8702 STD Z+10, R16
\r
346 \ 0000005C 8713 STD Z+11, R17
\r
349 \ 0000005E .... RCALL NTCLookUp
\r
350 185 BattData.HasRID = RIDLookUp();
\r
351 \ 00000060 .... RCALL RIDLookUp
\r
352 \ 00000062 2F10 MOV R17, R16
\r
353 \ 00000064 7011 ANDI R17, 0x01
\r
354 \ 00000066 .... LDI R30, LOW(BattData)
\r
355 \ 00000068 .... LDI R31, (BattData) >> 8
\r
356 \ 0000006A FB10 BST R17, 0
\r
357 \ 0000006C 8100 LD R16, Z
\r
358 \ 0000006E F904 BLD R16, 4
\r
359 \ 00000070 8300 ST Z, R16
\r
360 \ 00000072 E000 LDI R16, 0
\r
361 \ 00000074 F900 BLD R16, 0
\r
363 187 // Is the battery voltage above minimum safe cell voltage?
\r
364 188 if (ADCS.VBAT >= BAT_VOLTAGE_MIN) {
\r
365 \ 00000076 .... LDI R30, LOW(ADCS)
\r
366 \ 00000078 .... LDI R31, (ADCS) >> 8
\r
367 \ 0000007A 8502 LDD R16, Z+10
\r
368 \ 0000007C 8513 LDD R17, Z+11
\r
369 \ 0000007E 3600 CPI R16, 96
\r
370 \ 00000080 E029 LDI R18, 9
\r
371 \ 00000082 0712 CPC R17, R18
\r
372 \ 00000084 F028 BRCS ??BatteryStatusRefresh_0
\r
373 189 BattData.Low = FALSE;
\r
374 \ 00000086 .... LDI R30, LOW(BattData)
\r
375 \ 00000088 .... LDI R31, (BattData) >> 8
\r
376 \ 0000008A 8100 LD R16, Z
\r
377 \ 0000008C 7F0B ANDI R16, 0xFB
\r
378 \ 0000008E 8300 ST Z, R16
\r
381 192 // Is the battery charged?
\r
382 193 if (ADCS.VBAT >= BAT_VOLTAGE_LOW) {
\r
383 \ ??BatteryStatusRefresh_0:
\r
384 \ 00000090 .... LDI R30, LOW(ADCS)
\r
385 \ 00000092 .... LDI R31, (ADCS) >> 8
\r
386 \ 00000094 8502 LDD R16, Z+10
\r
387 \ 00000096 8513 LDD R17, Z+11
\r
388 \ 00000098 3D02 CPI R16, 210
\r
389 \ 0000009A E02F LDI R18, 15
\r
390 \ 0000009C 0712 CPC R17, R18
\r
391 \ 0000009E F028 BRCS ??BatteryStatusRefresh_1
\r
392 194 BattData.Charged = TRUE;
\r
393 \ 000000A0 .... LDI R30, LOW(BattData)
\r
394 \ 000000A2 .... LDI R31, (BattData) >> 8
\r
395 \ 000000A4 8100 LD R16, Z
\r
396 \ 000000A6 6002 ORI R16, 0x02
\r
397 \ 000000A8 8300 ST Z, R16
\r
400 197 // If we are not charging, yet VBAT is above safe limit, battery is present.
\r
401 198 // If we are charging and there's a current flowing, the battery is present.
\r
403 200 /*! \todo If ABORT_IF_PWM_MAX is defined this last check battery presence
\r
404 201 * check is redundant since charging will be aborted due to low current at
\r
405 202 * max duty cycle. That is preferrable since the charge current reading is
\r
406 203 * not 100% proof.
\r
408 205 if (((OCR1B == 0) && (!BattData.Low)) ||
\r
409 206 ((OCR1B != 0) && (ADCS.avgIBAT > 0))) {
\r
410 \ ??BatteryStatusRefresh_1:
\r
411 \ 000000AA B50C IN R16, 0x2C
\r
412 \ 000000AC 2300 TST R16
\r
413 \ 000000AE F429 BRNE ??BatteryStatusRefresh_2
\r
414 \ 000000B0 .... LDI R30, LOW(BattData)
\r
415 \ 000000B2 .... LDI R31, (BattData) >> 8
\r
416 \ 000000B4 8100 LD R16, Z
\r
417 \ 000000B6 FF02 SBRS R16, 2
\r
418 \ 000000B8 C00A RJMP ??BatteryStatusRefresh_3
\r
419 \ ??BatteryStatusRefresh_2:
\r
420 \ 000000BA B50C IN R16, 0x2C
\r
421 \ 000000BC 2300 TST R16
\r
422 \ 000000BE F071 BREQ ??BatteryStatusRefresh_4
\r
423 \ 000000C0 .... LDI R26, LOW((ADCS + 22))
\r
424 \ 000000C2 .... LDI R27, HIGH((ADCS + 22))
\r
425 \ 000000C4 91ED LD R30, X+
\r
426 \ 000000C6 91FC LD R31, X
\r
427 \ 000000C8 9711 SBIW R27:R26, 1
\r
428 \ 000000CA 9731 SBIW R31:R30, 1
\r
429 \ 000000CC F03C BRLT ??BatteryStatusRefresh_4
\r
430 207 BattData.Present = TRUE;
\r
431 \ ??BatteryStatusRefresh_3:
\r
432 \ 000000CE .... LDI R30, LOW(BattData)
\r
433 \ 000000D0 .... LDI R31, (BattData) >> 8
\r
434 \ 000000D2 8100 LD R16, Z
\r
435 \ 000000D4 6001 ORI R16, 0x01
\r
436 \ 000000D6 8300 ST Z, R16
\r
437 208 success = TRUE;
\r
438 \ 000000D8 E081 LDI R24, 1
\r
439 \ 000000DA C006 RJMP ??BatteryStatusRefresh_5
\r
441 210 BattData.Low = FALSE; // (This is just a technicality..)
\r
442 \ ??BatteryStatusRefresh_4:
\r
443 \ 000000DC .... LDI R30, LOW(BattData)
\r
444 \ 000000DE .... LDI R31, (BattData) >> 8
\r
445 \ 000000E0 8100 LD R16, Z
\r
446 \ 000000E2 7F0B ANDI R16, 0xFB
\r
447 \ 000000E4 8300 ST Z, R16
\r
448 211 success = FALSE;
\r
449 \ 000000E6 E080 LDI R24, 0
\r
452 214 #ifndef ALLOW_NO_RID
\r
453 215 // Return FALSE if no valid RID entry was found, to stop charging.
\r
454 216 if(!BattData.HasRID) {
\r
455 \ ??BatteryStatusRefresh_5:
\r
456 \ 000000E8 .... LDI R30, LOW(BattData)
\r
457 \ 000000EA .... LDI R31, (BattData) >> 8
\r
458 \ 000000EC 8100 LD R16, Z
\r
459 \ 000000EE FF04 SBRS R16, 4
\r
460 217 success = FALSE;
\r
461 \ 000000F0 E080 LDI R24, 0
\r
465 221 return(success);
\r
466 \ ??BatteryStatusRefresh_6:
\r
467 \ 000000F2 2F08 MOV R16, R24
\r
468 \ 000000F4 E0E4 LDI R30, 4
\r
469 \ 000000F6 .... RJMP ?EPILOGUE_B4_L09
\r
470 \ 000000F8 REQUIRE _A_OCR1B
\r
474 225 /*! \brief Refreshes battery data in the EEPROM
\r
476 227 * Attempts to read 4 pages of 32 bytes each from the battery's EPROM and store
\r
477 228 * these data in on-chip EEPROM.\n
\r
478 229 * If unsuccessful (CRC doesn't check out), the on-chip EEPROM is cleared.
\r
480 231 * \todo Updating BattData with these data. Specs needed.
\r
482 233 * \retval FALSE Refresh failed.
\r
483 234 * \retval TRUE Refresh successful.
\r
486 \ In segment CODE, align 2, keep-with-next
\r
487 236 unsigned char BatteryDataRefresh(void)
\r
488 \ BatteryDataRefresh:
\r
490 \ 00000000 .... RCALL ?PROLOGUE8_L09
\r
491 \ 00000002 REQUIRE ?Register_R4_is_cg_reg
\r
492 \ 00000002 REQUIRE ?Register_R5_is_cg_reg
\r
493 \ 00000002 REQUIRE ?Register_R6_is_cg_reg
\r
494 \ 00000002 REQUIRE ?Register_R7_is_cg_reg
\r
495 238 unsigned char offset;
\r
496 239 unsigned char i, crc, family, temp, page;
\r
497 240 unsigned char success;
\r
499 242 // Look for EPROM and read 4 pages of 32 bytes each worth of data, if found.
\r
500 243 for (page = 0; page < 4; page++) {
\r
501 \ 00000002 E090 LDI R25, 0
\r
502 \ ??BatteryDataRefresh_0:
\r
503 \ 00000004 3094 CPI R25, 4
\r
504 \ 00000006 F008 BRCS $+2+2
\r
505 \ 00000008 C084 RJMP ??BatteryDataRefresh_1
\r
506 244 success = FALSE;
\r
507 \ 0000000A E0B0 LDI R27, 0
\r
509 246 if (OWI_DetectPresence(OWIBUS) == OWIBUS) {
\r
510 \ 0000000C E001 LDI R16, 1
\r
511 \ 0000000E .... RCALL OWI_DetectPresence
\r
512 \ 00000010 3001 CPI R16, 1
\r
513 \ 00000012 F009 BREQ $+2+2
\r
514 \ 00000014 C065 RJMP ??BatteryDataRefresh_2
\r
516 248 // Presence detected, check type and CRC.
\r
517 249 OWI_SendByte(OWI_ROM_READ, OWIBUS);
\r
518 \ 00000016 E011 LDI R17, 1
\r
519 \ 00000018 E303 LDI R16, 51
\r
520 \ 0000001A .... RCALL OWI_SendByte
\r
521 250 family = OWI_ReceiveByte(OWIBUS);
\r
522 \ 0000001C E001 LDI R16, 1
\r
523 \ 0000001E .... RCALL OWI_ReceiveByte
\r
524 \ 00000020 2E60 MOV R6, R16
\r
525 251 crc = OWI_ComputeCRC8(family,0);
\r
526 \ 00000022 E010 LDI R17, 0
\r
527 \ 00000024 2D06 MOV R16, R6
\r
528 \ 00000026 .... RCALL OWI_ComputeCRC8
\r
529 \ 00000028 2E50 MOV R5, R16
\r
531 253 for (i = 0; i < 6; i++) {
\r
532 \ 0000002A E080 LDI R24, 0
\r
533 \ ??BatteryDataRefresh_3:
\r
534 \ 0000002C 3086 CPI R24, 6
\r
535 \ 0000002E F438 BRCC ??BatteryDataRefresh_4
\r
536 254 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc);
\r
537 \ 00000030 E001 LDI R16, 1
\r
538 \ 00000032 .... RCALL OWI_ReceiveByte
\r
539 \ 00000034 2D15 MOV R17, R5
\r
540 \ 00000036 .... RCALL OWI_ComputeCRC8
\r
541 \ 00000038 2E50 MOV R5, R16
\r
543 \ 0000003A 9583 INC R24
\r
544 \ 0000003C CFF7 RJMP ??BatteryDataRefresh_3
\r
546 257 // CRC ok, device found.
\r
547 258 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
\r
548 \ ??BatteryDataRefresh_4:
\r
549 \ 0000003E E001 LDI R16, 1
\r
550 \ 00000040 .... RCALL OWI_ReceiveByte
\r
551 \ 00000042 2D15 MOV R17, R5
\r
552 \ 00000044 .... RCALL OWI_ComputeCRC8
\r
553 \ 00000046 2300 TST R16
\r
554 \ 00000048 F009 BREQ $+2+2
\r
555 \ 0000004A C04A RJMP ??BatteryDataRefresh_2
\r
556 259 BattData.Circuit = family;
\r
557 \ 0000004C 9260.... STS (BattData + 1), R6
\r
559 261 // For now, we only read data from DS2505 EPROMs.
\r
560 262 if (BattData.Circuit == OW_DS2505) {
\r
561 \ 00000050 9100.... LDS R16, (BattData + 1)
\r
562 \ 00000054 3009 CPI R16, 9
\r
563 \ 00000056 F009 BREQ $+2+2
\r
564 \ 00000058 C043 RJMP ??BatteryDataRefresh_2
\r
565 263 offset = page*32;
\r
566 \ 0000005A 2F09 MOV R16, R25
\r
567 \ 0000005C 9502 SWAP R16
\r
568 \ 0000005E 7F00 ANDI R16, 0xF0
\r
569 \ 00000060 0F00 LSL R16
\r
570 \ 00000062 2E40 MOV R4, R16
\r
571 264 OWI_SendByte(DS2505_DATA_READ, OWIBUS); // Command: read data.
\r
572 \ 00000064 E011 LDI R17, 1
\r
573 \ 00000066 EC03 LDI R16, 195
\r
574 \ 00000068 .... RCALL OWI_SendByte
\r
575 265 OWI_SendByte(offset, OWIBUS); // Data: low address.
\r
576 \ 0000006A E011 LDI R17, 1
\r
577 \ 0000006C 2D04 MOV R16, R4
\r
578 \ 0000006E .... RCALL OWI_SendByte
\r
579 266 OWI_SendByte(0, OWIBUS); // Data: high address.
\r
580 \ 00000070 E011 LDI R17, 1
\r
581 \ 00000072 E000 LDI R16, 0
\r
582 \ 00000074 .... RCALL OWI_SendByte
\r
584 268 // Calculate checksums.
\r
585 269 crc = OWI_ComputeCRC8(DS2505_DATA_READ,0);
\r
586 \ 00000076 E010 LDI R17, 0
\r
587 \ 00000078 EC03 LDI R16, 195
\r
588 \ 0000007A .... RCALL OWI_ComputeCRC8
\r
589 \ 0000007C 2E50 MOV R5, R16
\r
590 270 crc = OWI_ComputeCRC8(offset,crc);
\r
591 \ 0000007E 2D15 MOV R17, R5
\r
592 \ 00000080 2D04 MOV R16, R4
\r
593 \ 00000082 .... RCALL OWI_ComputeCRC8
\r
594 \ 00000084 2E50 MOV R5, R16
\r
595 271 crc = OWI_ComputeCRC8(0,crc);
\r
596 \ 00000086 2D15 MOV R17, R5
\r
597 \ 00000088 E000 LDI R16, 0
\r
598 \ 0000008A .... RCALL OWI_ComputeCRC8
\r
599 \ 0000008C 2E50 MOV R5, R16
\r
601 273 // Command received succesfully, now start reading data
\r
602 274 // and writing it to EEPROM.
\r
603 275 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
\r
604 \ 0000008E E001 LDI R16, 1
\r
605 \ 00000090 .... RCALL OWI_ReceiveByte
\r
606 \ 00000092 2D15 MOV R17, R5
\r
607 \ 00000094 .... RCALL OWI_ComputeCRC8
\r
608 \ 00000096 2300 TST R16
\r
609 \ 00000098 F519 BRNE ??BatteryDataRefresh_2
\r
611 \ 0000009A 2455 CLR R5
\r
613 278 // Fill page with data.
\r
614 279 for (i=0; i<32; i++) {
\r
615 \ 0000009C E080 LDI R24, 0
\r
616 \ ??BatteryDataRefresh_5:
\r
617 \ 0000009E 3280 CPI R24, 32
\r
618 \ 000000A0 F4C0 BRCC ??BatteryDataRefresh_6
\r
619 280 temp = OWI_ReceiveByte(OWIBUS);
\r
620 \ 000000A2 E001 LDI R16, 1
\r
621 \ 000000A4 .... RCALL OWI_ReceiveByte
\r
622 \ 000000A6 2E70 MOV R7, R16
\r
623 281 crc = OWI_ComputeCRC8(temp, crc);
\r
624 \ 000000A8 2D15 MOV R17, R5
\r
625 \ 000000AA 2D07 MOV R16, R7
\r
626 \ 000000AC .... RCALL OWI_ComputeCRC8
\r
627 \ 000000AE 2E50 MOV R5, R16
\r
628 282 BattEEPROM[page][i] = temp;
\r
629 \ 000000B0 2F49 MOV R20, R25
\r
630 \ 000000B2 E050 LDI R21, 0
\r
631 \ 000000B4 E200 LDI R16, 32
\r
632 \ 000000B6 E010 LDI R17, 0
\r
633 \ 000000B8 .... RCALL ?S_MUL_L02
\r
634 \ 000000BA .... LDI R20, LOW(BattEEPROM)
\r
635 \ 000000BC .... LDI R21, (BattEEPROM) >> 8
\r
636 \ 000000BE 0F40 ADD R20, R16
\r
637 \ 000000C0 1F51 ADC R21, R17
\r
638 \ 000000C2 2F08 MOV R16, R24
\r
639 \ 000000C4 E010 LDI R17, 0
\r
640 \ 000000C6 0F40 ADD R20, R16
\r
641 \ 000000C8 1F51 ADC R21, R17
\r
642 \ 000000CA 2D07 MOV R16, R7
\r
643 \ 000000CC .... RCALL __eeput8_16
\r
645 \ 000000CE 9583 INC R24
\r
646 \ 000000D0 CFE6 RJMP ??BatteryDataRefresh_5
\r
648 285 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {
\r
649 \ ??BatteryDataRefresh_6:
\r
650 \ 000000D2 E001 LDI R16, 1
\r
651 \ 000000D4 .... RCALL OWI_ReceiveByte
\r
652 \ 000000D6 2D15 MOV R17, R5
\r
653 \ 000000D8 .... RCALL OWI_ComputeCRC8
\r
654 \ 000000DA 2300 TST R16
\r
655 \ 000000DC F409 BRNE ??BatteryDataRefresh_2
\r
656 286 success = TRUE; // Data read OK
\r
657 \ 000000DE E0B1 LDI R27, 1
\r
659 288 } else { // Not able to start reading data.
\r
661 290 } else { // Wrong device type.
\r
663 292 } else { // No device found.
\r
665 294 } else { // No presence detected on one-wire bus.
\r
668 297 // Erase local EEPROM page if there were any errors during transfer.
\r
669 298 if (!success) {
\r
670 \ ??BatteryDataRefresh_2:
\r
671 \ 000000E0 23BB TST R27
\r
672 \ 000000E2 F4A9 BRNE ??BatteryDataRefresh_7
\r
673 299 for (i=0; i<32; i++) {
\r
674 \ 000000E4 E080 LDI R24, 0
\r
675 \ ??BatteryDataRefresh_8:
\r
676 \ 000000E6 3280 CPI R24, 32
\r
677 \ 000000E8 F490 BRCC ??BatteryDataRefresh_7
\r
678 300 BattEEPROM[page][i] = 0;
\r
679 \ 000000EA E0A0 LDI R26, 0
\r
680 \ 000000EC 2F49 MOV R20, R25
\r
681 \ 000000EE E050 LDI R21, 0
\r
682 \ 000000F0 E200 LDI R16, 32
\r
683 \ 000000F2 E010 LDI R17, 0
\r
684 \ 000000F4 .... RCALL ?S_MUL_L02
\r
685 \ 000000F6 .... LDI R20, LOW(BattEEPROM)
\r
686 \ 000000F8 .... LDI R21, (BattEEPROM) >> 8
\r
687 \ 000000FA 0F40 ADD R20, R16
\r
688 \ 000000FC 1F51 ADC R21, R17
\r
689 \ 000000FE 2F08 MOV R16, R24
\r
690 \ 00000100 E010 LDI R17, 0
\r
691 \ 00000102 0F40 ADD R20, R16
\r
692 \ 00000104 1F51 ADC R21, R17
\r
693 \ 00000106 2F0A MOV R16, R26
\r
694 \ 00000108 .... RCALL __eeput8_16
\r
696 \ 0000010A 9583 INC R24
\r
697 \ 0000010C CFEC RJMP ??BatteryDataRefresh_8
\r
700 \ ??BatteryDataRefresh_7:
\r
701 \ 0000010E 9593 INC R25
\r
702 \ 00000110 CF79 RJMP ??BatteryDataRefresh_0
\r
704 305 return(success);
\r
705 \ ??BatteryDataRefresh_1:
\r
706 \ 00000112 2F0B MOV R16, R27
\r
707 \ 00000114 E0E8 LDI R30, 8
\r
708 \ 00000116 .... RJMP ?EPILOGUE_B8_L09
\r
712 309 /*! \brief Enables specified battery
\r
714 311 * Updates \ref BattActive to specified battery, then sets PB4/PB5 and clears
\r
715 312 * PB5/PB4 in PORTB, depending on which battery is specified.\n
\r
716 313 * The function takes 100 ms to allow the port switch to settle.
\r
718 315 * \param bat Specifies which battery to enable (0 = battery A, 1 = B)
\r
721 \ In segment CODE, align 2, keep-with-next
\r
722 317 void EnableBattery(unsigned char bat)
\r
725 \ 00000000 938A ST -Y, R24
\r
726 \ 00000002 2F80 MOV R24, R16
\r
727 319 // Use general timer, set timeout to 100ms.
\r
728 320 Time_Set(TIMER_GEN,0,0,100);
\r
729 \ 00000004 E644 LDI R20, 100
\r
730 \ 00000006 E010 LDI R17, 0
\r
731 \ 00000008 E020 LDI R18, 0
\r
732 \ 0000000A E030 LDI R19, 0
\r
733 \ 0000000C E002 LDI R16, 2
\r
734 \ 0000000E .... RCALL Time_Set
\r
736 322 // Set specified battery as the active one.
\r
737 323 BattActive = bat;
\r
738 \ 00000010 9380.... STS BattActive, R24
\r
740 325 // Enable current battery in hardware, light LED & connect battery.
\r
741 326 PORTB |= (1 << (PB4+bat));
\r
742 \ 00000014 E001 LDI R16, 1
\r
743 \ 00000016 E010 LDI R17, 0
\r
744 \ 00000018 2F48 MOV R20, R24
\r
745 \ 0000001A 5F4C SUBI R20, 252
\r
746 \ 0000001C .... RCALL ?S_SHL_L02
\r
747 \ 0000001E B318 IN R17, 0x18
\r
748 \ 00000020 2B10 OR R17, R16
\r
749 \ 00000022 BB18 OUT 0x18, R17
\r
751 328 // Disconnect other battery.
\r
752 329 PORTB &= ~(1<<(PB5-bat));
\r
753 \ 00000024 E001 LDI R16, 1
\r
754 \ 00000026 E010 LDI R17, 0
\r
755 \ 00000028 E045 LDI R20, 5
\r
756 \ 0000002A 1B48 SUB R20, R24
\r
757 \ 0000002C .... RCALL ?S_SHL_L02
\r
758 \ 0000002E 9500 COM R16
\r
759 \ 00000030 B318 IN R17, 0x18
\r
760 \ 00000032 2310 AND R17, R16
\r
761 \ 00000034 BB18 OUT 0x18, R17
\r
763 331 do { // Let port switch settle.
\r
764 332 } while (Time_Left(TIMER_GEN));
\r
765 \ ??EnableBattery_0:
\r
766 \ 00000036 E002 LDI R16, 2
\r
767 \ 00000038 .... RCALL Time_Left
\r
768 \ 0000003A 2300 TST R16
\r
769 \ 0000003C F7E1 BRNE ??EnableBattery_0
\r
771 \ 0000003E 9189 LD R24, Y+
\r
772 \ 00000040 9508 RET
\r
773 \ 00000042 REQUIRE _A_PORTB
\r
776 336 /*! \brief Disables both batteries
\r
778 338 * Clears PB4 and PB5 in PORTB, disabling both batteries.
\r
781 \ In segment CODE, align 2, keep-with-next
\r
782 340 void DisableBatteries(void)
\r
783 \ DisableBatteries:
\r
785 342 // Turn off LEDs and disconnect batteries.
\r
786 343 PORTB &= ~((1<<PB4)|(1<<PB5));
\r
787 \ 00000000 B308 IN R16, 0x18
\r
788 \ 00000002 7C0F ANDI R16, 0xCF
\r
789 \ 00000004 BB08 OUT 0x18, R16
\r
791 \ 00000006 9508 RET
\r
792 \ 00000008 REQUIRE _A_PORTB
\r
795 347 /*! \brief Looks up battery data from RID table
\r
797 349 * Attempts to find data for the battery from the RID lookup-table.\n
\r
798 350 * If no valid entry is found, default data (defined in battery.h)
\r
801 353 * \retval TRUE Entry found, battery data updated.
\r
802 354 * \retval FALSE No entry found, using defaults for battery data.
\r
805 \ In segment CODE, align 2, keep-with-next
\r
806 356 unsigned char RIDLookUp (void)
\r
809 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
810 358 unsigned char i, found = FALSE;
\r
811 \ 00000002 E090 LDI R25, 0
\r
813 360 // Lookup in the RID-table. If measured RID is within the limits
\r
814 361 // of an entry, those data are used, and TRUE is returned.
\r
815 362 for (i = 0 ; i < RID_TABLE_SIZE; i++) {
\r
816 \ 00000004 E080 LDI R24, 0
\r
818 \ 00000006 3084 CPI R24, 4
\r
819 \ 00000008 F008 BRCS $+2+2
\r
820 \ 0000000A C05E RJMP ??RIDLookUp_1
\r
821 363 if (ADCS.rawRID >= RID[i].Low) {
\r
822 \ 0000000C .... LDI R30, LOW(ADCS)
\r
823 \ 0000000E .... LDI R31, (ADCS) >> 8
\r
824 \ 00000010 81A2 LDD R26, Z+2
\r
825 \ 00000012 81B3 LDD R27, Z+3
\r
826 \ 00000014 2F48 MOV R20, R24
\r
827 \ 00000016 E050 LDI R21, 0
\r
828 \ 00000018 E00E LDI R16, 14
\r
829 \ 0000001A E010 LDI R17, 0
\r
830 \ 0000001C .... RCALL ?S_MUL_L02
\r
831 \ 0000001E 01F8 MOVW R31:R30, R17:R16
\r
832 \ 00000020 .... SUBI R30, LOW((-(RID) & 0xFFFF))
\r
833 \ 00000022 .... SBCI R31, (-(RID) & 0xFFFF) >> 8
\r
834 \ 00000024 8100 LD R16, Z
\r
835 \ 00000026 8111 LDD R17, Z+1
\r
836 \ 00000028 17A0 CP R26, R16
\r
837 \ 0000002A 07B1 CPC R27, R17
\r
838 \ 0000002C F408 BRCC $+2+2
\r
839 \ 0000002E C04A RJMP ??RIDLookUp_2
\r
840 364 if (ADCS.rawRID <= RID[i].High) {
\r
841 \ 00000030 2F48 MOV R20, R24
\r
842 \ 00000032 E050 LDI R21, 0
\r
843 \ 00000034 E00E LDI R16, 14
\r
844 \ 00000036 E010 LDI R17, 0
\r
845 \ 00000038 .... RCALL ?S_MUL_L02
\r
846 \ 0000003A 01F8 MOVW R31:R30, R17:R16
\r
847 \ 0000003C .... SUBI R30, LOW((-(RID) & 0xFFFF))
\r
848 \ 0000003E .... SBCI R31, (-(RID) & 0xFFFF) >> 8
\r
849 \ 00000040 8102 LDD R16, Z+2
\r
850 \ 00000042 8113 LDD R17, Z+3
\r
851 \ 00000044 .... LDI R30, LOW(ADCS)
\r
852 \ 00000046 .... LDI R31, (ADCS) >> 8
\r
853 \ 00000048 8122 LDD R18, Z+2
\r
854 \ 0000004A 8133 LDD R19, Z+3
\r
855 \ 0000004C 1702 CP R16, R18
\r
856 \ 0000004E 0713 CPC R17, R19
\r
857 \ 00000050 F1C8 BRCS ??RIDLookUp_2
\r
858 365 BattData.Capacity = RID[i].Capacity;
\r
859 \ 00000052 2F48 MOV R20, R24
\r
860 \ 00000054 E050 LDI R21, 0
\r
861 \ 00000056 E00E LDI R16, 14
\r
862 \ 00000058 E010 LDI R17, 0
\r
863 \ 0000005A .... RCALL ?S_MUL_L02
\r
864 \ 0000005C 01F8 MOVW R31:R30, R17:R16
\r
865 \ 0000005E .... SUBI R30, LOW((-(RID) & 0xFFFF))
\r
866 \ 00000060 .... SBCI R31, (-(RID) & 0xFFFF) >> 8
\r
867 \ 00000062 8106 LDD R16, Z+6
\r
868 \ 00000064 8117 LDD R17, Z+7
\r
869 \ 00000066 .... LDI R30, LOW(BattData)
\r
870 \ 00000068 .... LDI R31, (BattData) >> 8
\r
871 \ 0000006A 8304 STD Z+4, R16
\r
872 \ 0000006C 8315 STD Z+5, R17
\r
873 366 BattData.MaxCurrent = RID[i].Icharge;
\r
874 \ 0000006E 2F48 MOV R20, R24
\r
875 \ 00000070 E050 LDI R21, 0
\r
876 \ 00000072 E00E LDI R16, 14
\r
877 \ 00000074 E010 LDI R17, 0
\r
878 \ 00000076 .... RCALL ?S_MUL_L02
\r
879 \ 00000078 01F8 MOVW R31:R30, R17:R16
\r
880 \ 0000007A .... SUBI R30, LOW((-(RID) & 0xFFFF))
\r
881 \ 0000007C .... SBCI R31, (-(RID) & 0xFFFF) >> 8
\r
882 \ 0000007E 8500 LDD R16, Z+8
\r
883 \ 00000080 8511 LDD R17, Z+9
\r
884 \ 00000082 .... LDI R30, LOW(BattData)
\r
885 \ 00000084 .... LDI R31, (BattData) >> 8
\r
886 \ 00000086 8306 STD Z+6, R16
\r
887 \ 00000088 8317 STD Z+7, R17
\r
888 367 BattData.MaxTime = RID[i].tCutOff;
\r
889 \ 0000008A 2F48 MOV R20, R24
\r
890 \ 0000008C E050 LDI R21, 0
\r
891 \ 0000008E E00E LDI R16, 14
\r
892 \ 00000090 E010 LDI R17, 0
\r
893 \ 00000092 .... RCALL ?S_MUL_L02
\r
894 \ 00000094 01F8 MOVW R31:R30, R17:R16
\r
895 \ 00000096 .... SUBI R30, LOW((-(RID) & 0xFFFF))
\r
896 \ 00000098 .... SBCI R31, (-(RID) & 0xFFFF) >> 8
\r
897 \ 0000009A 8502 LDD R16, Z+10
\r
898 \ 0000009C 8513 LDD R17, Z+11
\r
899 \ 0000009E .... LDI R30, LOW(BattData)
\r
900 \ 000000A0 .... LDI R31, (BattData) >> 8
\r
901 \ 000000A2 8700 STD Z+8, R16
\r
902 \ 000000A4 8711 STD Z+9, R17
\r
903 368 BattData.MinCurrent = RID[i].ICutOff;
\r
904 \ 000000A6 2F48 MOV R20, R24
\r
905 \ 000000A8 E050 LDI R21, 0
\r
906 \ 000000AA E00E LDI R16, 14
\r
907 \ 000000AC E010 LDI R17, 0
\r
908 \ 000000AE .... RCALL ?S_MUL_L02
\r
909 \ 000000B0 01F8 MOVW R31:R30, R17:R16
\r
910 \ 000000B2 .... SUBI R30, LOW((-(RID) & 0xFFFF))
\r
911 \ 000000B4 .... SBCI R31, (-(RID) & 0xFFFF) >> 8
\r
912 \ 000000B6 8504 LDD R16, Z+12
\r
913 \ 000000B8 8515 LDD R17, Z+13
\r
914 \ 000000BA .... LDI R30, LOW(BattData)
\r
915 \ 000000BC .... LDI R31, (BattData) >> 8
\r
916 \ 000000BE 8702 STD Z+10, R16
\r
917 \ 000000C0 8713 STD Z+11, R17
\r
920 \ 000000C2 E091 LDI R25, 1
\r
925 \ 000000C4 9583 INC R24
\r
926 \ 000000C6 CF9F RJMP ??RIDLookUp_0
\r
928 375 // If no valid entry is found, use defaults and return FALSE.
\r
931 \ 000000C8 2399 TST R25
\r
932 \ 000000CA F4C1 BRNE ??RIDLookUp_3
\r
933 377 BattData.Capacity = DEF_BAT_CAPACITY;
\r
934 \ 000000CC E000 LDI R16, 0
\r
935 \ 000000CE E010 LDI R17, 0
\r
936 \ 000000D0 .... LDI R30, LOW(BattData)
\r
937 \ 000000D2 .... LDI R31, (BattData) >> 8
\r
938 \ 000000D4 8304 STD Z+4, R16
\r
939 \ 000000D6 8315 STD Z+5, R17
\r
940 378 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX;
\r
941 \ 000000D8 E000 LDI R16, 0
\r
942 \ 000000DA E010 LDI R17, 0
\r
943 \ 000000DC .... LDI R30, LOW(BattData)
\r
944 \ 000000DE .... LDI R31, (BattData) >> 8
\r
945 \ 000000E0 8306 STD Z+6, R16
\r
946 \ 000000E2 8317 STD Z+7, R17
\r
947 379 BattData.MaxTime = DEF_BAT_TIME_MAX;
\r
948 \ 000000E4 E000 LDI R16, 0
\r
949 \ 000000E6 E010 LDI R17, 0
\r
950 \ 000000E8 .... LDI R30, LOW(BattData)
\r
951 \ 000000EA .... LDI R31, (BattData) >> 8
\r
952 \ 000000EC 8700 STD Z+8, R16
\r
953 \ 000000EE 8711 STD Z+9, R17
\r
954 380 BattData.MinCurrent = DEF_BAT_CURRENT_MIN;
\r
955 \ 000000F0 E000 LDI R16, 0
\r
956 \ 000000F2 E010 LDI R17, 0
\r
957 \ 000000F4 .... LDI R30, LOW(BattData)
\r
958 \ 000000F6 .... LDI R31, (BattData) >> 8
\r
959 \ 000000F8 8702 STD Z+10, R16
\r
960 \ 000000FA 8713 STD Z+11, R17
\r
965 \ 000000FC 2F09 MOV R16, R25
\r
966 \ 000000FE E0E4 LDI R30, 4
\r
967 \ 00000100 .... RJMP ?EPILOGUE_B4_L09
\r
971 387 /*! \brief Calculates temperature from a lookup table
\r
973 389 * Looks up the highest NTC value below or equal to the measured one.\n
\r
974 390 * With the current lookup table, temperature is calculated with the formula:\n
\r
975 391 * 4*(index of entry) - 2*(measured NTC - NTC from entry) / (ADCsteps of entry)
\r
977 393 * \note If the NTC-measurement is saturated, with the current lookup table,
\r
978 394 * the temperature will be reported as -1 C.
\r
980 396 * \note If no valid entry is found, battery temperature is set to 80.
\r
983 \ In segment CODE, align 2, keep-with-next
\r
984 398 void NTCLookUp (void)
\r
987 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
988 400 unsigned char i;
\r
989 401 unsigned char found = FALSE;
\r
990 \ 00000002 E090 LDI R25, 0
\r
992 403 // Lookup in the NTC-table. Use the first entry which is equal or below
\r
993 404 // sampled NTC. Calculate temperature by using the index number, and the
\r
994 405 // difference between the measured NTC value and the one in the entry.
\r
995 406 for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++) {
\r
996 \ 00000004 E080 LDI R24, 0
\r
998 \ 00000006 3184 CPI R24, 20
\r
999 \ 00000008 F008 BRCS $+2+2
\r
1000 \ 0000000A C043 RJMP ??NTCLookUp_1
\r
1001 \ 0000000C 2399 TST R25
\r
1002 \ 0000000E F009 BREQ $+2+2
\r
1003 \ 00000010 C040 RJMP ??NTCLookUp_1
\r
1004 407 if (ADCS.rawNTC >= NTC[i].ADC) {
\r
1005 \ 00000012 .... LDI R30, LOW(ADCS)
\r
1006 \ 00000014 .... LDI R31, (ADCS) >> 8
\r
1007 \ 00000016 81A4 LDD R26, Z+4
\r
1008 \ 00000018 81B5 LDD R27, Z+5
\r
1009 \ 0000001A 2F48 MOV R20, R24
\r
1010 \ 0000001C E050 LDI R21, 0
\r
1011 \ 0000001E E003 LDI R16, 3
\r
1012 \ 00000020 E010 LDI R17, 0
\r
1013 \ 00000022 .... RCALL ?S_MUL_L02
\r
1014 \ 00000024 01F8 MOVW R31:R30, R17:R16
\r
1015 \ 00000026 .... SUBI R30, LOW((-(NTC) & 0xFFFF))
\r
1016 \ 00000028 .... SBCI R31, (-(NTC) & 0xFFFF) >> 8
\r
1017 \ 0000002A 8100 LD R16, Z
\r
1018 \ 0000002C 8111 LDD R17, Z+1
\r
1019 \ 0000002E 17A0 CP R26, R16
\r
1020 \ 00000030 07B1 CPC R27, R17
\r
1021 \ 00000032 F168 BRCS ??NTCLookUp_2
\r
1022 408 BattData.Temperature = (i<<2) ;
\r
1023 \ 00000034 2F08 MOV R16, R24
\r
1024 \ 00000036 0F00 LSL R16
\r
1025 \ 00000038 0F00 LSL R16
\r
1026 \ 0000003A 9300.... STS (BattData + 2), R16
\r
1027 409 BattData.ADCSteps = NTC[i].ADCsteps;
\r
1028 \ 0000003E 2F48 MOV R20, R24
\r
1029 \ 00000040 E050 LDI R21, 0
\r
1030 \ 00000042 E003 LDI R16, 3
\r
1031 \ 00000044 E010 LDI R17, 0
\r
1032 \ 00000046 .... RCALL ?S_MUL_L02
\r
1033 \ 00000048 01F8 MOVW R31:R30, R17:R16
\r
1034 \ 0000004A .... SUBI R30, LOW((-(NTC) & 0xFFFF))
\r
1035 \ 0000004C .... SBCI R31, (-(NTC) & 0xFFFF) >> 8
\r
1036 \ 0000004E 8102 LDD R16, Z+2
\r
1037 \ 00000050 9300.... STS (BattData + 3), R16
\r
1038 410 BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps;
\r
1039 \ 00000054 .... LDI R30, LOW(ADCS)
\r
1040 \ 00000056 .... LDI R31, (ADCS) >> 8
\r
1041 \ 00000058 81A4 LDD R26, Z+4
\r
1042 \ 0000005A 81B5 LDD R27, Z+5
\r
1043 \ 0000005C 2F48 MOV R20, R24
\r
1044 \ 0000005E E050 LDI R21, 0
\r
1045 \ 00000060 E003 LDI R16, 3
\r
1046 \ 00000062 E010 LDI R17, 0
\r
1047 \ 00000064 .... RCALL ?S_MUL_L02
\r
1048 \ 00000066 01F8 MOVW R31:R30, R17:R16
\r
1049 \ 00000068 .... SUBI R30, LOW((-(NTC) & 0xFFFF))
\r
1050 \ 0000006A .... SBCI R31, (-(NTC) & 0xFFFF) >> 8
\r
1051 \ 0000006C 8100 LD R16, Z
\r
1052 \ 0000006E 8111 LDD R17, Z+1
\r
1053 \ 00000070 1BA0 SUB R26, R16
\r
1054 \ 00000072 0BB1 SBC R27, R17
\r
1055 \ 00000074 0FAA LSL R26
\r
1056 \ 00000076 1FBB ROL R27
\r
1057 \ 00000078 018D MOVW R17:R16, R27:R26
\r
1058 \ 0000007A 9140.... LDS R20, (BattData + 3)
\r
1059 \ 0000007E E050 LDI R21, 0
\r
1060 \ 00000080 .... RCALL ?US_DIVMOD_L02
\r
1061 \ 00000082 .... LDI R30, LOW(BattData)
\r
1062 \ 00000084 .... LDI R31, (BattData) >> 8
\r
1063 \ 00000086 8112 LDD R17, Z+2
\r
1064 \ 00000088 1B10 SUB R17, R16
\r
1065 \ 0000008A 8312 STD Z+2, R17
\r
1067 412 found = TRUE; // Could be done with a break, but that violates MISRA.
\r
1068 \ 0000008C E091 LDI R25, 1
\r
1072 \ 0000008E 9583 INC R24
\r
1073 \ 00000090 CFBA RJMP ??NTCLookUp_0
\r
1075 416 // For safety, is temperature is greater than the NTC
\r
1078 \ 00000092 2399 TST R25
\r
1079 \ 00000094 F419 BRNE ??NTCLookUp_3
\r
1080 418 BattData.Temperature = 80;
\r
1081 \ 00000096 E500 LDI R16, 80
\r
1082 \ 00000098 9300.... STS (BattData + 2), R16
\r
1086 \ 0000009C E0E4 LDI R30, 4
\r
1087 \ 0000009E .... RJMP ?EPILOGUE_B4_L09
\r
1089 \ In segment NEAR_ID, align 1, keep-with-next
\r
1090 \ `?<Initializer for RID>`:
\r
1091 \ 00000000 022E02930F3C DW 558, 659, 3900, 550, 260, 300, 10, 744, 843, 6800, 750, 360, 300, 14
\r
1096 \ 0000001C 036503BE2710 DW 869, 958, 10000, 1000, 475, 300, 19, 1097, 1153, 24000, 2000, 475
\r
1100 \ 00000034 01A40026 DW 420, 38
\r
1102 \ In segment NEAR_ID, align 1, keep-with-next
\r
1103 \ `?<Initializer for NTC>`:
\r
1104 \ 00000000 03EA DW 1002
\r
1105 \ 00000002 17 DB 23
\r
1106 \ 00000003 03B9 DW 953
\r
1107 \ 00000005 19 DB 25
\r
1108 \ 00000006 0386 DW 902
\r
1109 \ 00000008 1A DB 26
\r
1110 \ 00000009 0351 DW 849
\r
1111 \ 0000000B 1B DB 27
\r
1112 \ 0000000C 031C DW 796
\r
1113 \ 0000000E 1B DB 27
\r
1114 \ 0000000F 02E6 DW 742
\r
1115 \ 00000011 1B DB 27
\r
1116 \ 00000012 02B1 DW 689
\r
1117 \ 00000014 1A DB 26
\r
1118 \ 00000015 027D DW 637
\r
1119 \ 00000017 1A DB 26
\r
1120 \ 00000018 024B DW 587
\r
1121 \ 0000001A 19 DB 25
\r
1122 \ 0000001B 021B DW 539
\r
1123 \ 0000001D 18 DB 24
\r
1124 \ 0000001E 01EE DW 494
\r
1125 \ 00000020 16 DB 22
\r
1126 \ 00000021 01C3 DW 451
\r
1127 \ 00000023 15 DB 21
\r
1128 \ 00000024 019C DW 412
\r
1129 \ 00000026 13 DB 19
\r
1130 \ 00000027 0177 DW 375
\r
1131 \ 00000029 12 DB 18
\r
1132 \ 0000002A 0155 DW 341
\r
1133 \ 0000002C 11 DB 17
\r
1134 \ 0000002D 0136 DW 310
\r
1135 \ 0000002F 0F DB 15
\r
1136 \ 00000030 011A DW 282
\r
1137 \ 00000032 0E DB 14
\r
1138 \ 00000033 0100 DW 256
\r
1139 \ 00000035 0D DB 13
\r
1140 \ 00000036 00E9 DW 233
\r
1141 \ 00000038 0B DB 11
\r
1142 \ 00000039 00D4 DW 212
\r
1143 \ 0000003B 0A DB 10
\r
1145 Maximum stack usage in bytes:
\r
1147 Function CSTACK RSTACK
\r
1148 -------- ------ ------
\r
1150 -> BatteryStatusRefresh 4 2
\r
1151 BatteryDataRefresh 8 4
\r
1152 -> OWI_DetectPresence 8 2
\r
1153 -> OWI_SendByte 8 2
\r
1154 -> OWI_ReceiveByte 8 2
\r
1155 -> OWI_ComputeCRC8 8 2
\r
1156 -> OWI_ReceiveByte 8 2
\r
1157 -> OWI_ComputeCRC8 8 2
\r
1158 -> OWI_ReceiveByte 8 2
\r
1159 -> OWI_ComputeCRC8 8 2
\r
1160 -> OWI_SendByte 8 2
\r
1161 -> OWI_SendByte 8 2
\r
1162 -> OWI_SendByte 8 2
\r
1163 -> OWI_ComputeCRC8 8 2
\r
1164 -> OWI_ComputeCRC8 8 2
\r
1165 -> OWI_ComputeCRC8 8 2
\r
1166 -> OWI_ReceiveByte 8 2
\r
1167 -> OWI_ComputeCRC8 8 2
\r
1168 -> OWI_ReceiveByte 8 2
\r
1169 -> OWI_ComputeCRC8 8 2
\r
1170 -> OWI_ReceiveByte 8 2
\r
1171 -> OWI_ComputeCRC8 8 2
\r
1172 BatteryStatusRefresh 4 2
\r
1175 DisableBatteries 0 2
\r
1183 Segment part sizes:
\r
1185 Function/Label Bytes
\r
1186 -------------- -----
\r
1196 BatteryStatusRefresh 248
\r
1197 BatteryDataRefresh 280
\r
1199 DisableBatteries 8
\r
1202 ?<Initializer for RID> 56
\r
1203 ?<Initializer for NTC> 60
\r
1207 2 bytes in segment ABSOLUTE
\r
1208 1 064 bytes in segment CODE
\r
1209 130 bytes in segment EEPROM_I
\r
1210 12 bytes in segment INITTAB
\r
1211 116 bytes in segment NEAR_I
\r
1212 116 bytes in segment NEAR_ID
\r
1213 13 bytes in segment NEAR_Z
\r
1215 1 180 bytes of CODE memory (+ 12 bytes shared)
\r
1216 129 bytes of DATA memory (+ 2 bytes shared)
\r
1217 130 bytes of XDATA memory
\r