1 ###############################################################################
\r
3 # IAR Atmel AVR C/C++ Compiler V4.30F/W32 13/Mar/2008 04:52:03 #
\r
4 # Copyright 1996-2007 IAR Systems. All rights reserved. #
\r
6 # Source file = C:\home\kevin\pub\src\bc100\IAR\time.c #
\r
7 # Command line = C:\home\kevin\pub\src\bc100\IAR\time.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\ti #
\r
33 # Object file = C:\home\kevin\pub\src\bc100\IAR\Release\Obj\tim #
\r
37 ###############################################################################
\r
39 C:\home\kevin\pub\src\bc100\IAR\time.c
\r
40 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
41 2 /*! \file *********************************************************************
\r
44 5 * Functions for timing
\r
46 7 * Contains functions to initialize, set, poll and stop timers.
\r
48 9 * \par Application note:
\r
49 10 * AVR458: Charging Li-Ion Batteries with BC100 \n
\r
50 11 * AVR463: Charging NiMH Batteries with BC100
\r
52 13 * \par Documentation
\r
53 14 * For comprehensive code documentation, supported compilers, compiler
\r
54 15 * settings and supported devices see readme.html
\r
57 18 * Atmel Corporation: http://www.atmel.com \n
\r
58 19 * Support email: avr@atmel.com
\r
62 23 * $Revision: 2299 $
\r
64 25 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/time.c $
\r
65 26 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
66 27 ******************************************************************************/
\r
68 29 #include <ioavr.h>
\r
70 \ In segment ABSOLUTE, at 0x59
\r
71 \ <unnamed> volatile __io _A_TIMSK
\r
75 \ In segment ABSOLUTE, at 0x53
\r
76 \ <unnamed> volatile __io _A_TCCR0B
\r
80 \ In segment ABSOLUTE, at 0x35
\r
81 \ <unnamed> volatile __io _A_TCCR0A
\r
85 \ In segment ABSOLUTE, at 0x33
\r
86 \ <unnamed> volatile __io _A_OCR0A
\r
90 \ In segment ABSOLUTE, at 0x32
\r
91 \ <unnamed> volatile __io _A_OCR0B
\r
94 30 #include <inavr.h>
\r
96 32 #include "enums.h"
\r
98 34 #include "main.h"
\r
99 35 #include "time.h"
\r
102 38 //******************************************************************************
\r
104 40 //******************************************************************************
\r
106 \ In segment NEAR_Z, align 1, keep-with-next
\r
107 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
108 41 unsigned long timeval[TIMERS]; //!< Contains the values for each timer.
\r
112 43 // timer runs at 1 MHz and overflow will occur every 255 / 1 Mz ~= 0.25 ms
\r
113 44 //#pragma vector = TIM0_OVF_vect
\r
116 47 //******************************************************************************
\r
118 49 //******************************************************************************
\r
119 50 /*! \brief Interrupt service routine for timer 0 overflow
\r
121 52 * Timer 0 runs at 125 kHz and compare match will occur every millisecond
\r
122 53 * (125 / 125 kHz = 1.0 ms), which will result in a call to this function.
\r
123 54 * When called, this function will decrement the time left for each timer,
\r
124 55 * unless they are already at zero.
\r
126 57 #pragma vector = TIM0_COMPA_vect
\r
128 \ In segment CODE, align 2, keep-with-next
\r
129 58 __interrupt void TICK_ISR(void)
\r
132 \ 00000000 93FA ST -Y, R31
\r
133 \ 00000002 93EA ST -Y, R30
\r
134 \ 00000004 937A ST -Y, R23
\r
135 \ 00000006 936A ST -Y, R22
\r
136 \ 00000008 935A ST -Y, R21
\r
137 \ 0000000A 934A ST -Y, R20
\r
138 \ 0000000C 931A ST -Y, R17
\r
139 \ 0000000E 930A ST -Y, R16
\r
140 \ 00000010 B71F IN R17, 0x3F
\r
141 60 unsigned char i;
\r
143 62 // 1 ms has passed, decrement all non-zero timers.
\r
144 63 for (i = 0; i < TIMERS; i++) {
\r
145 \ 00000012 .... LDI R30, LOW(timeval)
\r
146 \ 00000014 .... LDI R31, (timeval) >> 8
\r
147 \ 00000016 E004 LDI R16, 4
\r
148 64 if(timeval[i] > 0) {
\r
150 \ 00000018 8140 LD R20, Z
\r
151 \ 0000001A 8151 LDD R21, Z+1
\r
152 \ 0000001C 8162 LDD R22, Z+2
\r
153 \ 0000001E 8173 LDD R23, Z+3
\r
154 \ 00000020 2B45 OR R20, R21
\r
155 \ 00000022 2B46 OR R20, R22
\r
156 \ 00000024 2B47 OR R20, R23
\r
157 \ 00000026 F049 BREQ ??TICK_ISR_1
\r
159 \ 00000028 8140 LD R20, Z
\r
160 \ 0000002A 5041 SUBI R20, 1
\r
161 \ 0000002C 4050 SBCI R21, 0
\r
162 \ 0000002E 4060 SBCI R22, 0
\r
163 \ 00000030 4070 SBCI R23, 0
\r
164 \ 00000032 8340 ST Z, R20
\r
165 \ 00000034 8351 STD Z+1, R21
\r
166 \ 00000036 8362 STD Z+2, R22
\r
167 \ 00000038 8373 STD Z+3, R23
\r
171 \ 0000003A 9634 ADIW R31:R30, 4
\r
172 \ 0000003C 950A DEC R16
\r
173 \ 0000003E 2300 TST R16
\r
174 \ 00000040 F759 BRNE ??TICK_ISR_0
\r
176 \ 00000042 BF1F OUT 0x3F, R17
\r
177 \ 00000044 9109 LD R16, Y+
\r
178 \ 00000046 9119 LD R17, Y+
\r
179 \ 00000048 9149 LD R20, Y+
\r
180 \ 0000004A 9159 LD R21, Y+
\r
181 \ 0000004C 9169 LD R22, Y+
\r
182 \ 0000004E 9179 LD R23, Y+
\r
183 \ 00000050 91E9 LD R30, Y+
\r
184 \ 00000052 91F9 LD R31, Y+
\r
185 \ 00000054 9518 RETI
\r
188 71 /*! \brief Checks if a specified timer has expired
\r
190 73 * \param timer Specifies timer
\r
192 75 * \retval TRUE Timer still going.
\r
193 76 * \retval FALSE Timer has expired.
\r
196 \ In segment CODE, align 2, keep-with-next
\r
197 78 unsigned char Time_Left(unsigned char timer)
\r
200 80 if(timeval[timer] > 0) {
\r
201 \ 00000000 E010 LDI R17, 0
\r
202 \ 00000002 0F00 LSL R16
\r
203 \ 00000004 1F11 ROL R17
\r
204 \ 00000006 0F00 LSL R16
\r
205 \ 00000008 1F11 ROL R17
\r
206 \ 0000000A 01F8 MOVW R31:R30, R17:R16
\r
207 \ 0000000C .... SUBI R30, LOW((-(timeval) & 0xFFFF))
\r
208 \ 0000000E .... SBCI R31, (-(timeval) & 0xFFFF) >> 8
\r
209 \ 00000010 8100 LD R16, Z
\r
210 \ 00000012 8111 LDD R17, Z+1
\r
211 \ 00000014 8122 LDD R18, Z+2
\r
212 \ 00000016 8133 LDD R19, Z+3
\r
213 \ 00000018 2B01 OR R16, R17
\r
214 \ 0000001A 2B02 OR R16, R18
\r
215 \ 0000001C 2B03 OR R16, R19
\r
216 \ 0000001E F011 BREQ ??Time_Left_0
\r
218 \ 00000020 E001 LDI R16, 1
\r
219 \ 00000022 9508 RET
\r
223 \ 00000024 E000 LDI R16, 0
\r
224 \ 00000026 9508 RET
\r
229 88 /*! \brief Sets the specified timer
\r
231 90 * \param timer Specifies timer
\r
232 91 * \param min Minutes for timer to count down
\r
233 92 * \param sec Seconds for timer to count down
\r
234 93 * \param ms Milliseconds for timer to count down
\r
237 \ In segment CODE, align 2, keep-with-next
\r
238 95 void Time_Set(unsigned char timer, unsigned int min, unsigned char sec,
\r
240 96 unsigned char ms)
\r
242 \ 00000000 928A ST -Y, R8
\r
243 \ 00000002 926A ST -Y, R6
\r
244 \ 00000004 925A ST -Y, R5
\r
245 \ 00000006 924A ST -Y, R4
\r
246 \ 00000008 93BA ST -Y, R27
\r
247 \ 0000000A 93AA ST -Y, R26
\r
248 \ 0000000C 939A ST -Y, R25
\r
249 \ 0000000E 938A ST -Y, R24
\r
250 \ 00000010 REQUIRE ?Register_R4_is_cg_reg
\r
251 \ 00000010 REQUIRE ?Register_R5_is_cg_reg
\r
252 \ 00000010 REQUIRE ?Register_R6_is_cg_reg
\r
253 \ 00000010 REQUIRE ?Register_R8_is_cg_reg
\r
254 \ 00000010 2E40 MOV R4, R16
\r
255 \ 00000012 2E81 MOV R8, R17
\r
256 \ 00000014 2E64 MOV R6, R20
\r
257 98 // timeval[i] = 4 * (1000*(sec + 60*min) + ms); // about 4000 ticks per second
\r
258 99 // timeval[i] = 240000 * (unsigned long)min;
\r
259 100 // timeval[i] += 4000 * (unsigned long)sec;
\r
260 101 // timeval[i] += 4 * (unsigned long)ms;
\r
262 103 timeval[timer] = 60000 * (unsigned long)min;
\r
263 104 timeval[timer] += 1000 * (unsigned long)sec;
\r
264 105 timeval[timer] += 1 * (unsigned long)ms;
\r
265 \ 00000016 01A9 MOVW R21:R20, R19:R18
\r
266 \ 00000018 E060 LDI R22, 0
\r
267 \ 0000001A E070 LDI R23, 0
\r
268 \ 0000001C E600 LDI R16, 96
\r
269 \ 0000001E EE1A LDI R17, 234
\r
270 \ 00000020 E020 LDI R18, 0
\r
271 \ 00000022 E030 LDI R19, 0
\r
272 \ 00000024 .... RCALL ?L_MUL_L03
\r
273 \ 00000026 01C8 MOVW R25:R24, R17:R16
\r
274 \ 00000028 01D9 MOVW R27:R26, R19:R18
\r
275 \ 0000002A 2D48 MOV R20, R8
\r
276 \ 0000002C E050 LDI R21, 0
\r
277 \ 0000002E E060 LDI R22, 0
\r
278 \ 00000030 E070 LDI R23, 0
\r
279 \ 00000032 EE08 LDI R16, 232
\r
280 \ 00000034 E013 LDI R17, 3
\r
281 \ 00000036 E020 LDI R18, 0
\r
282 \ 00000038 E030 LDI R19, 0
\r
283 \ 0000003A .... RCALL ?L_MUL_L03
\r
284 \ 0000003C 0F08 ADD R16, R24
\r
285 \ 0000003E 1F19 ADC R17, R25
\r
286 \ 00000040 1F2A ADC R18, R26
\r
287 \ 00000042 1F3B ADC R19, R27
\r
288 \ 00000044 2D46 MOV R20, R6
\r
289 \ 00000046 E050 LDI R21, 0
\r
290 \ 00000048 E060 LDI R22, 0
\r
291 \ 0000004A E070 LDI R23, 0
\r
292 \ 0000004C 0F40 ADD R20, R16
\r
293 \ 0000004E 1F51 ADC R21, R17
\r
294 \ 00000050 1F62 ADC R22, R18
\r
295 \ 00000052 1F73 ADC R23, R19
\r
296 \ 00000054 2455 CLR R5
\r
297 \ 00000056 0C44 LSL R4
\r
298 \ 00000058 1C55 ROL R5
\r
299 \ 0000005A 0C44 LSL R4
\r
300 \ 0000005C 1C55 ROL R5
\r
301 \ 0000005E 01F2 MOVW R31:R30, R5:R4
\r
302 \ 00000060 .... SUBI R30, LOW((-(timeval) & 0xFFFF))
\r
303 \ 00000062 .... SBCI R31, (-(timeval) & 0xFFFF) >> 8
\r
304 \ 00000064 8340 ST Z, R20
\r
305 \ 00000066 8351 STD Z+1, R21
\r
306 \ 00000068 8362 STD Z+2, R22
\r
307 \ 0000006A 8373 STD Z+3, R23
\r
309 \ 0000006C 9189 LD R24, Y+
\r
310 \ 0000006E 9199 LD R25, Y+
\r
311 \ 00000070 91A9 LD R26, Y+
\r
312 \ 00000072 91B9 LD R27, Y+
\r
313 \ 00000074 9049 LD R4, Y+
\r
314 \ 00000076 9059 LD R5, Y+
\r
315 \ 00000078 9069 LD R6, Y+
\r
316 \ 0000007A 9089 LD R8, Y+
\r
317 \ 0000007C 9508 RET
\r
320 109 /*! \brief Stops timers
\r
322 111 * Sets timer0's clock source to none.
\r
325 \ In segment CODE, align 2, keep-with-next
\r
326 113 void Time_Stop(void)
\r
330 \ 00000000 E000 LDI R16, 0
\r
331 \ 00000002 BF03 OUT 0x33, R16
\r
333 \ 00000004 9508 RET
\r
334 \ 00000006 REQUIRE _A_TCCR0B
\r
337 119 /*! \brief Starts timers
\r
339 121 * Sets timer0's clock source to system clock divided by 64.
\r
342 \ In segment CODE, align 2, keep-with-next
\r
343 123 void Time_Start(void)
\r
346 125 TCCR0B = (0<<CS02)|(1<<CS01)|(1<<CS00); // CLKT0 = CLK/64 = 125 kHz.
\r
347 \ 00000000 E003 LDI R16, 3
\r
348 \ 00000002 BF03 OUT 0x33, R16
\r
350 \ 00000004 9508 RET
\r
351 \ 00000006 REQUIRE _A_TCCR0B
\r
354 129 /*! \brief Initializes timers
\r
356 131 * Resets all the timer values to 0, then sets up timer 0 for a compare match
\r
357 132 * every millisecond.
\r
360 \ In segment CODE, align 2, keep-with-next
\r
361 134 void Time_Init(void)
\r
364 136 unsigned char i;
\r
366 138 for (i = 0; i<<TIMERS; i++) {
\r
367 139 timeval[i] = 0;
\r
370 142 // OCR0A = 0; // Doesn't matter, will run in normal mode.
\r
372 144 OCR0A = 125; // Will give a compare match every ms.
\r
373 \ 00000000 E70D LDI R16, 125
\r
374 \ 00000002 BB03 OUT 0x13, R16
\r
376 146 OCR0B = 0; // Doesn't matter, will run in normal mode.
\r
377 \ 00000004 E000 LDI R16, 0
\r
378 \ 00000006 BB02 OUT 0x12, R16
\r
380 148 // TCCR0A = 0; // Normal 8-bit mode, no input capture.
\r
382 150 TCCR0A = (1<<WGM00); // 8-bit CTC mode.
\r
383 \ 00000008 E001 LDI R16, 1
\r
384 \ 0000000A BB05 OUT 0x15, R16
\r
386 152 // TCCR0B = (0<<CS02)|(1<<CS01)|(0<<CS00); // CLKT0 = CLK/8 = 1 MHz.
\r
388 154 TCCR0B = (0<<CS02)|(1<<CS01)|(1<<CS00); // CLKT0 = CLK/64 = 125 kHz.
\r
389 \ 0000000C E003 LDI R16, 3
\r
390 \ 0000000E BF03 OUT 0x33, R16
\r
392 156 // TIMSK |= (1<<TOIE0); // Overflow interrupt enabled.
\r
394 158 TIMSK |= (1<<OCIE0A); // Timer 0, Compare match A interrupt enabled.
\r
395 \ 00000010 B709 IN R16, 0x39
\r
396 \ 00000012 6100 ORI R16, 0x10
\r
397 \ 00000014 BF09 OUT 0x39, R16
\r
399 160 // Enable interrupts, just in case they weren't already.
\r
400 161 __enable_interrupt();
\r
401 \ 00000016 9478 SEI
\r
403 \ 00000018 9508 RET
\r
404 \ 0000001A REQUIRE _A_TIMSK
\r
405 \ 0000001A REQUIRE _A_TCCR0B
\r
406 \ 0000001A REQUIRE _A_TCCR0A
\r
407 \ 0000001A REQUIRE _A_OCR0A
\r
408 \ 0000001A REQUIRE _A_OCR0B
\r
410 \ In segment INTVEC, offset 0x1c, root
\r
411 \ `??TICK_ISR??INTVEC 28`:
\r
412 \ 0000001C .... RJMP TICK_ISR
\r
414 Maximum stack usage in bytes:
\r
416 Function CSTACK RSTACK
\r
417 -------- ------ ------
\r
426 Segment part sizes:
\r
428 Function/Label Bytes
\r
429 -------------- -----
\r
442 ??TICK_ISR??INTVEC 28 2
\r
446 5 bytes in segment ABSOLUTE
\r
447 290 bytes in segment CODE
\r
448 6 bytes in segment INITTAB
\r
449 2 bytes in segment INTVEC
\r
450 16 bytes in segment NEAR_Z
\r
452 290 bytes of CODE memory (+ 8 bytes shared)
\r
453 16 bytes of DATA memory (+ 5 bytes shared)
\r