############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:40 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\time.c # # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\time.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\time.lst # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\time.r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100_cal\IAR\time.c 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ 2 /*! \file ********************************************************************* 3 * 4 * \brief 5 * Functions for timing 6 * 7 * Contains functions to initialize, set, poll and stop timers. 8 * 9 * \par Application note: 10 * AVR458: Charging Li-Ion Batteries with BC100 \n 11 * AVR463: Charging NiMH Batteries with BC100 12 * 13 * \par Documentation 14 * For comprehensive code documentation, supported compilers, compiler 15 * settings and supported devices see readme.html 16 * 17 * \author 18 * Atmel Corporation: http://www.atmel.com \n 19 * Support email: avr@atmel.com 20 * 21 * 22 * $Name$ 23 * $Revision: 2299 $ 24 * $RCSfile$ 25 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/time.c $ 26 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n 27 ******************************************************************************/ 28 29 #include \ In segment ABSOLUTE, at 0x59 \ volatile __io _A_TIMSK \ _A_TIMSK: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x53 \ volatile __io _A_TCCR0B \ _A_TCCR0B: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x35 \ volatile __io _A_TCCR0A \ _A_TCCR0A: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x33 \ volatile __io _A_OCR0A \ _A_OCR0A: \ 00000000 DS 1 \ In segment ABSOLUTE, at 0x32 \ volatile __io _A_OCR0B \ _A_OCR0B: \ 00000000 DS 1 30 #include 31 32 #include "enums.h" 33 34 #include "main.h" 35 #include "time.h" 36 37 38 //****************************************************************************** 39 // Variables 40 //****************************************************************************** \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 41 unsigned long timeval[TIMERS]; //!< Contains the values for each timer. \ timeval: \ 00000000 DS 16 42 43 // timer runs at 1 MHz and overflow will occur every 255 / 1 Mz ~= 0.25 ms 44 //#pragma vector = TIM0_OVF_vect 45 46 47 //****************************************************************************** 48 // Functions 49 //****************************************************************************** 50 /*! \brief Interrupt service routine for timer 0 overflow 51 * 52 * Timer 0 runs at 125 kHz and compare match will occur every millisecond 53 * (125 / 125 kHz = 1.0 ms), which will result in a call to this function. 54 * When called, this function will decrement the time left for each timer, 55 * unless they are already at zero. 56 */ 57 #pragma vector = TIM0_COMPA_vect \ In segment CODE, align 2, keep-with-next 58 __interrupt void TICK_ISR(void) \ TICK_ISR: 59 { \ 00000000 93FA ST -Y, R31 \ 00000002 93EA ST -Y, R30 \ 00000004 920A ST -Y, R0 \ 00000006 937A ST -Y, R23 \ 00000008 936A ST -Y, R22 \ 0000000A 935A ST -Y, R21 \ 0000000C 934A ST -Y, R20 \ 0000000E 933A ST -Y, R19 \ 00000010 932A ST -Y, R18 \ 00000012 931A ST -Y, R17 \ 00000014 930A ST -Y, R16 \ 00000016 B60F IN R0, 0x3F 60 unsigned char i; 61 62 // 1 ms has passed, decrement all non-zero timers. 63 for (i = 0; i < TIMERS; i++) { \ 00000018 E000 LDI R16, 0 \ ??TICK_ISR_0: \ 0000001A 3004 CPI R16, 4 \ 0000001C F540 BRCC ??TICK_ISR_1 64 if(timeval[i] > 0) { \ 0000001E 2F20 MOV R18, R16 \ 00000020 E030 LDI R19, 0 \ 00000022 0F22 LSL R18 \ 00000024 1F33 ROL R19 \ 00000026 0F22 LSL R18 \ 00000028 1F33 ROL R19 \ 0000002A 01F9 MOVW R31:R30, R19:R18 \ 0000002C .... SUBI R30, LOW((-(timeval) & 0xFFFF)) \ 0000002E .... SBCI R31, (-(timeval) & 0xFFFF) >> 8 \ 00000030 8140 LD R20, Z \ 00000032 8151 LDD R21, Z+1 \ 00000034 8162 LDD R22, Z+2 \ 00000036 8173 LDD R23, Z+3 \ 00000038 2B45 OR R20, R21 \ 0000003A 2B46 OR R20, R22 \ 0000003C 2B47 OR R20, R23 \ 0000003E F0A9 BREQ ??TICK_ISR_2 65 timeval[i]--; \ 00000040 2F20 MOV R18, R16 \ 00000042 E030 LDI R19, 0 \ 00000044 0F22 LSL R18 \ 00000046 1F33 ROL R19 \ 00000048 0F22 LSL R18 \ 0000004A 1F33 ROL R19 \ 0000004C 01F9 MOVW R31:R30, R19:R18 \ 0000004E .... SUBI R30, LOW((-(timeval) & 0xFFFF)) \ 00000050 .... SBCI R31, (-(timeval) & 0xFFFF) >> 8 \ 00000052 8140 LD R20, Z \ 00000054 8151 LDD R21, Z+1 \ 00000056 8162 LDD R22, Z+2 \ 00000058 8173 LDD R23, Z+3 \ 0000005A 5041 SUBI R20, 1 \ 0000005C 4050 SBCI R21, 0 \ 0000005E 4060 SBCI R22, 0 \ 00000060 4070 SBCI R23, 0 \ 00000062 8340 ST Z, R20 \ 00000064 8351 STD Z+1, R21 \ 00000066 8362 STD Z+2, R22 \ 00000068 8373 STD Z+3, R23 66 } 67 } \ ??TICK_ISR_2: \ 0000006A 9503 INC R16 \ 0000006C CFD6 RJMP ??TICK_ISR_0 68 } \ ??TICK_ISR_1: \ 0000006E BE0F OUT 0x3F, R0 \ 00000070 9109 LD R16, Y+ \ 00000072 9119 LD R17, Y+ \ 00000074 9129 LD R18, Y+ \ 00000076 9139 LD R19, Y+ \ 00000078 9149 LD R20, Y+ \ 0000007A 9159 LD R21, Y+ \ 0000007C 9169 LD R22, Y+ \ 0000007E 9179 LD R23, Y+ \ 00000080 9009 LD R0, Y+ \ 00000082 91E9 LD R30, Y+ \ 00000084 91F9 LD R31, Y+ \ 00000086 9518 RETI 69 70 71 /*! \brief Checks if a specified timer has expired 72 * 73 * \param timer Specifies timer 74 * 75 * \retval TRUE Timer still going. 76 * \retval FALSE Timer has expired. 77 */ \ In segment CODE, align 2, keep-with-next 78 unsigned char Time_Left(unsigned char timer) \ Time_Left: 79 { \ 00000000 2F20 MOV R18, R16 80 if(timeval[timer] > 0) { \ 00000002 2F02 MOV R16, R18 \ 00000004 E010 LDI R17, 0 \ 00000006 0F00 LSL R16 \ 00000008 1F11 ROL R17 \ 0000000A 0F00 LSL R16 \ 0000000C 1F11 ROL R17 \ 0000000E 01F8 MOVW R31:R30, R17:R16 \ 00000010 .... SUBI R30, LOW((-(timeval) & 0xFFFF)) \ 00000012 .... SBCI R31, (-(timeval) & 0xFFFF) >> 8 \ 00000014 8140 LD R20, Z \ 00000016 8151 LDD R21, Z+1 \ 00000018 8162 LDD R22, Z+2 \ 0000001A 8173 LDD R23, Z+3 \ 0000001C 2B45 OR R20, R21 \ 0000001E 2B46 OR R20, R22 \ 00000020 2B47 OR R20, R23 \ 00000022 F011 BREQ ??Time_Left_0 81 return(TRUE); \ 00000024 E001 LDI R16, 1 \ 00000026 9508 RET 82 } else { 83 return(FALSE); \ ??Time_Left_0: \ 00000028 E000 LDI R16, 0 \ 0000002A 9508 RET 84 } 85 } 86 87 88 /*! \brief Sets the specified timer 89 * 90 * \param timer Specifies timer 91 * \param min Minutes for timer to count down 92 * \param sec Seconds for timer to count down 93 * \param ms Milliseconds for timer to count down 94 */ \ In segment CODE, align 2, keep-with-next 95 void Time_Set(unsigned char timer, unsigned int min, unsigned char sec, \ Time_Set: 96 unsigned char ms) 97 { \ 00000000 .... RCALL ?PROLOGUE7_L09 \ 00000002 REQUIRE ?Register_R4_is_cg_reg \ 00000002 REQUIRE ?Register_R5_is_cg_reg \ 00000002 REQUIRE ?Register_R6_is_cg_reg \ 00000002 2FA0 MOV R26, R16 \ 00000004 01C9 MOVW R25:R24, R19:R18 \ 00000006 2E61 MOV R6, R17 \ 00000008 2E44 MOV R4, R20 98 // timeval[i] = 4 * (1000*(sec + 60*min) + ms); // about 4000 ticks per second 99 // timeval[i] = 240000 * (unsigned long)min; 100 // timeval[i] += 4000 * (unsigned long)sec; 101 // timeval[i] += 4 * (unsigned long)ms; 102 103 timeval[timer] = 60000 * (unsigned long)min; \ 0000000A 01AC MOVW R21:R20, R25:R24 \ 0000000C E060 LDI R22, 0 \ 0000000E E070 LDI R23, 0 \ 00000010 E600 LDI R16, 96 \ 00000012 EE1A LDI R17, 234 \ 00000014 E020 LDI R18, 0 \ 00000016 E030 LDI R19, 0 \ 00000018 .... RCALL ?L_MUL_L03 \ 0000001A 2F4A MOV R20, R26 \ 0000001C E050 LDI R21, 0 \ 0000001E 0F44 LSL R20 \ 00000020 1F55 ROL R21 \ 00000022 0F44 LSL R20 \ 00000024 1F55 ROL R21 \ 00000026 01FA MOVW R31:R30, R21:R20 \ 00000028 .... SUBI R30, LOW((-(timeval) & 0xFFFF)) \ 0000002A .... SBCI R31, (-(timeval) & 0xFFFF) >> 8 \ 0000002C 8300 ST Z, R16 \ 0000002E 8311 STD Z+1, R17 \ 00000030 8322 STD Z+2, R18 \ 00000032 8333 STD Z+3, R19 104 timeval[timer] += 1000 * (unsigned long)sec; \ 00000034 2D46 MOV R20, R6 \ 00000036 E050 LDI R21, 0 \ 00000038 E060 LDI R22, 0 \ 0000003A E070 LDI R23, 0 \ 0000003C EE08 LDI R16, 232 \ 0000003E E013 LDI R17, 3 \ 00000040 E020 LDI R18, 0 \ 00000042 E030 LDI R19, 0 \ 00000044 .... RCALL ?L_MUL_L03 \ 00000046 2F4A MOV R20, R26 \ 00000048 E050 LDI R21, 0 \ 0000004A 0F44 LSL R20 \ 0000004C 1F55 ROL R21 \ 0000004E 0F44 LSL R20 \ 00000050 1F55 ROL R21 \ 00000052 01FA MOVW R31:R30, R21:R20 \ 00000054 .... SUBI R30, LOW((-(timeval) & 0xFFFF)) \ 00000056 .... SBCI R31, (-(timeval) & 0xFFFF) >> 8 \ 00000058 8140 LD R20, Z \ 0000005A 8151 LDD R21, Z+1 \ 0000005C 8162 LDD R22, Z+2 \ 0000005E 8173 LDD R23, Z+3 \ 00000060 0F40 ADD R20, R16 \ 00000062 1F51 ADC R21, R17 \ 00000064 1F62 ADC R22, R18 \ 00000066 1F73 ADC R23, R19 \ 00000068 8340 ST Z, R20 \ 0000006A 8351 STD Z+1, R21 \ 0000006C 8362 STD Z+2, R22 \ 0000006E 8373 STD Z+3, R23 105 timeval[timer] += 1 * (unsigned long)ms; \ 00000070 2455 CLR R5 \ 00000072 0182 MOVW R17:R16, R5:R4 \ 00000074 E020 LDI R18, 0 \ 00000076 E030 LDI R19, 0 \ 00000078 2F4A MOV R20, R26 \ 0000007A E050 LDI R21, 0 \ 0000007C 0F44 LSL R20 \ 0000007E 1F55 ROL R21 \ 00000080 0F44 LSL R20 \ 00000082 1F55 ROL R21 \ 00000084 01FA MOVW R31:R30, R21:R20 \ 00000086 .... SUBI R30, LOW((-(timeval) & 0xFFFF)) \ 00000088 .... SBCI R31, (-(timeval) & 0xFFFF) >> 8 \ 0000008A 8140 LD R20, Z \ 0000008C 8151 LDD R21, Z+1 \ 0000008E 8162 LDD R22, Z+2 \ 00000090 8173 LDD R23, Z+3 \ 00000092 0F40 ADD R20, R16 \ 00000094 1F51 ADC R21, R17 \ 00000096 1F62 ADC R22, R18 \ 00000098 1F73 ADC R23, R19 \ 0000009A 8340 ST Z, R20 \ 0000009C 8351 STD Z+1, R21 \ 0000009E 8362 STD Z+2, R22 \ 000000A0 8373 STD Z+3, R23 106 } \ 000000A2 E0E7 LDI R30, 7 \ 000000A4 .... RJMP ?EPILOGUE_B7_L09 107 108 109 /*! \brief Stops timers 110 * 111 * Sets timer0's clock source to none. 112 */ \ In segment CODE, align 2, keep-with-next 113 void Time_Stop(void) \ Time_Stop: 114 { 115 TCCR0B = 0; \ 00000000 E000 LDI R16, 0 \ 00000002 BF03 OUT 0x33, R16 116 } \ 00000004 9508 RET \ 00000006 REQUIRE _A_TCCR0B 117 118 119 /*! \brief Starts timers 120 * 121 * Sets timer0's clock source to system clock divided by 64. 122 */ \ In segment CODE, align 2, keep-with-next 123 void Time_Start(void) \ Time_Start: 124 { 125 TCCR0B = (0<> 8 \ 00000020 8300 ST Z, R16 \ 00000022 8311 STD Z+1, R17 \ 00000024 8322 STD Z+2, R18 \ 00000026 8333 STD Z+3, R19 140 } \ 00000028 9543 INC R20 \ 0000002A CFEB RJMP ??Time_Init_0 141 142 // OCR0A = 0; // Doesn't matter, will run in normal mode. 143 144 OCR0A = 125; // Will give a compare match every ms. \ ??Time_Init_1: \ 0000002C E70D LDI R16, 125 \ 0000002E BB03 OUT 0x13, R16 145 146 OCR0B = 0; // Doesn't matter, will run in normal mode. \ 00000030 E000 LDI R16, 0 \ 00000032 BB02 OUT 0x12, R16 147 148 // TCCR0A = 0; // Normal 8-bit mode, no input capture. 149 150 TCCR0A = (1<