/////////////////////////////////////////////////////////////////////////////// // / // 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\IA / // R\Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\De / // bug\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug / // \List\ --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.s90 / // / // / /////////////////////////////////////////////////////////////////////////////// NAME time RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) EXTERN ?EPILOGUE_B7_L09 EXTERN ?L_MUL_L03 EXTERN ?PROLOGUE7_L09 EXTERN ?Register_R4_is_cg_reg EXTERN ?Register_R5_is_cg_reg EXTERN ?Register_R6_is_cg_reg EXTERN ?need_segment_init PUBWEAK `?` PUBWEAK `??TICK_ISR??INTVEC 28` PUBLIC TICK_ISR PUBLIC Time_Init PUBLIC Time_Left PUBLIC Time_Set PUBLIC Time_Start PUBLIC Time_Stop PUBWEAK _A_OCR0A PUBWEAK _A_OCR0B PUBWEAK _A_TCCR0A PUBWEAK _A_TCCR0B PUBWEAK _A_TIMSK PUBWEAK __?EEARH PUBWEAK __?EEARL PUBWEAK __?EECR PUBWEAK __?EEDR PUBLIC timeval TICK_ISR SYMBOL "TICK_ISR" `??TICK_ISR??INTVEC 28` SYMBOL "??INTVEC 28", TICK_ISR // 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 ASEGN ABSOLUTE:DATA:NOROOT,059H // volatile __io _A_TIMSK _A_TIMSK: DS 1 ASEGN ABSOLUTE:DATA:NOROOT,053H // volatile __io _A_TCCR0B _A_TCCR0B: DS 1 ASEGN ABSOLUTE:DATA:NOROOT,035H // volatile __io _A_TCCR0A _A_TCCR0A: DS 1 ASEGN ABSOLUTE:DATA:NOROOT,033H // volatile __io _A_OCR0A _A_OCR0A: DS 1 ASEGN ABSOLUTE:DATA:NOROOT,032H // volatile __io _A_OCR0B _A_OCR0B: DS 1 // 30 #include // 31 // 32 #include "enums.h" // 33 // 34 #include "main.h" // 35 #include "time.h" // 36 // 37 // 38 //****************************************************************************** // 39 // Variables // 40 //****************************************************************************** RSEG NEAR_Z:DATA:NOROOT(0) REQUIRE `?` // 41 unsigned long timeval[TIMERS]; //!< Contains the values for each timer. timeval: 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 RSEG CODE:CODE:NOROOT(1) // 58 __interrupt void TICK_ISR(void) TICK_ISR: // 59 { ST -Y, R31 ST -Y, R30 ST -Y, R0 ST -Y, R23 ST -Y, R22 ST -Y, R21 ST -Y, R20 ST -Y, R19 ST -Y, R18 ST -Y, R17 ST -Y, R16 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++) { LDI R16, 0 ??TICK_ISR_0: CPI R16, 4 BRCC ??TICK_ISR_1 // 64 if(timeval[i] > 0) { MOV R18, R16 LDI R19, 0 LSL R18 ROL R19 LSL R18 ROL R19 MOVW R31:R30, R19:R18 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 LD R20, Z LDD R21, Z+1 LDD R22, Z+2 LDD R23, Z+3 OR R20, R21 OR R20, R22 OR R20, R23 BREQ ??TICK_ISR_2 // 65 timeval[i]--; MOV R18, R16 LDI R19, 0 LSL R18 ROL R19 LSL R18 ROL R19 MOVW R31:R30, R19:R18 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 LD R20, Z LDD R21, Z+1 LDD R22, Z+2 LDD R23, Z+3 SUBI R20, 1 SBCI R21, 0 SBCI R22, 0 SBCI R23, 0 ST Z, R20 STD Z+1, R21 STD Z+2, R22 STD Z+3, R23 // 66 } // 67 } ??TICK_ISR_2: INC R16 RJMP ??TICK_ISR_0 // 68 } ??TICK_ISR_1: OUT 0x3F, R0 LD R16, Y+ LD R17, Y+ LD R18, Y+ LD R19, Y+ LD R20, Y+ LD R21, Y+ LD R22, Y+ LD R23, Y+ LD R0, Y+ LD R30, Y+ LD R31, Y+ 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 */ RSEG CODE:CODE:NOROOT(1) // 78 unsigned char Time_Left(unsigned char timer) Time_Left: // 79 { MOV R18, R16 // 80 if(timeval[timer] > 0) { MOV R16, R18 LDI R17, 0 LSL R16 ROL R17 LSL R16 ROL R17 MOVW R31:R30, R17:R16 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 LD R20, Z LDD R21, Z+1 LDD R22, Z+2 LDD R23, Z+3 OR R20, R21 OR R20, R22 OR R20, R23 BREQ ??Time_Left_0 // 81 return(TRUE); LDI R16, 1 RET // 82 } else { // 83 return(FALSE); ??Time_Left_0: LDI R16, 0 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 */ RSEG CODE:CODE:NOROOT(1) // 95 void Time_Set(unsigned char timer, unsigned int min, unsigned char sec, Time_Set: // 96 unsigned char ms) // 97 { RCALL ?PROLOGUE7_L09 REQUIRE ?Register_R4_is_cg_reg REQUIRE ?Register_R5_is_cg_reg REQUIRE ?Register_R6_is_cg_reg MOV R26, R16 MOVW R25:R24, R19:R18 MOV R6, R17 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; MOVW R21:R20, R25:R24 LDI R22, 0 LDI R23, 0 LDI R16, 96 LDI R17, 234 LDI R18, 0 LDI R19, 0 RCALL ?L_MUL_L03 MOV R20, R26 LDI R21, 0 LSL R20 ROL R21 LSL R20 ROL R21 MOVW R31:R30, R21:R20 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 ST Z, R16 STD Z+1, R17 STD Z+2, R18 STD Z+3, R19 // 104 timeval[timer] += 1000 * (unsigned long)sec; MOV R20, R6 LDI R21, 0 LDI R22, 0 LDI R23, 0 LDI R16, 232 LDI R17, 3 LDI R18, 0 LDI R19, 0 RCALL ?L_MUL_L03 MOV R20, R26 LDI R21, 0 LSL R20 ROL R21 LSL R20 ROL R21 MOVW R31:R30, R21:R20 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 LD R20, Z LDD R21, Z+1 LDD R22, Z+2 LDD R23, Z+3 ADD R20, R16 ADC R21, R17 ADC R22, R18 ADC R23, R19 ST Z, R20 STD Z+1, R21 STD Z+2, R22 STD Z+3, R23 // 105 timeval[timer] += 1 * (unsigned long)ms; CLR R5 MOVW R17:R16, R5:R4 LDI R18, 0 LDI R19, 0 MOV R20, R26 LDI R21, 0 LSL R20 ROL R21 LSL R20 ROL R21 MOVW R31:R30, R21:R20 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 LD R20, Z LDD R21, Z+1 LDD R22, Z+2 LDD R23, Z+3 ADD R20, R16 ADC R21, R17 ADC R22, R18 ADC R23, R19 ST Z, R20 STD Z+1, R21 STD Z+2, R22 STD Z+3, R23 // 106 } LDI R30, 7 RJMP ?EPILOGUE_B7_L09 // 107 // 108 // 109 /*! \brief Stops timers // 110 * // 111 * Sets timer0's clock source to none. // 112 */ RSEG CODE:CODE:NOROOT(1) // 113 void Time_Stop(void) Time_Stop: // 114 { // 115 TCCR0B = 0; LDI R16, 0 OUT 0x33, R16 // 116 } RET REQUIRE _A_TCCR0B // 117 // 118 // 119 /*! \brief Starts timers // 120 * // 121 * Sets timer0's clock source to system clock divided by 64. // 122 */ RSEG CODE:CODE:NOROOT(1) // 123 void Time_Start(void) Time_Start: // 124 { // 125 TCCR0B = (0<> 8 ST Z, R16 STD Z+1, R17 STD Z+2, R18 STD Z+3, R19 // 140 } INC R20 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: LDI R16, 125 OUT 0x13, R16 // 145 // 146 OCR0B = 0; // Doesn't matter, will run in normal mode. LDI R16, 0 OUT 0x12, R16 // 147 // 148 // TCCR0A = 0; // Normal 8-bit mode, no input capture. // 149 // 150 TCCR0A = (1<`: DW SFE(NEAR_Z) - SFB(NEAR_Z) DW SFB(NEAR_Z) DW 0 REQUIRE ?need_segment_init END // // 5 bytes in segment ABSOLUTE // 428 bytes in segment CODE // 6 bytes in segment INITTAB // 2 bytes in segment INTVEC // 16 bytes in segment NEAR_Z // // 428 bytes of CODE memory (+ 8 bytes shared) // 16 bytes of DATA memory (+ 5 bytes shared) // //Errors: none //Warnings: none