/////////////////////////////////////////////////////////////////////////////// // / // IAR Atmel AVR C/C++ Compiler V4.30F/W32 13/Mar/2008 04:52:03 / // Copyright 1996-2007 IAR Systems. All rights reserved. / // / // Source file = C:\home\kevin\pub\src\bc100\IAR\time.c / // Command line = C:\home\kevin\pub\src\bc100\IAR\time.c / // --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc1 / // 00\IAR\Release\Obj\ -D NDEBUG -lCN / // C:\home\kevin\pub\src\bc100\IAR\Release\List\ / // -lB C:\home\kevin\pub\src\bc100\IAR\Release\Li / // st\ --initializers_in_flash -s9 / // --no_cross_call --no_tbaa / // -DENABLE_BIT_DEFINITIONS -e -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 --misrac=5-9,11-12,14,16-17, / // 19-21,24-26,29-32,34-35,38-39,42-43,46,50, / // 52-54,56-59,61-62,64-65,68-80,83-84,87-91, / // 94-95,98-100,103-110,112-126 / // Enabled MISRA C rules = 5-9,11-12,14,16-17,19-21,24-26,29-32,34-35, / // 38-39,42-43,46,50,52-54,56-59,61-62,64-65, / // 68-80,83-84,87-91,94-95,98-100,103-110,112-126 / // Checked = 5,7-9,11-12,14,17,19-21,24,29-32,34-35,38-39, / // 42,46,50,52-54,56-59,61-62,64,68-69,71-80, / // 83-84,87-89,91,94-95,98,100,104-105,108-109, / // 112-115,118-126 / // Not checked = 6,16,25-26,43,65,70,90,99,103,106-107,110, / // 116-117 / // List file = C:\home\kevin\pub\src\bc100\IAR\Release\List\t / // ime.s90 / // / // / /////////////////////////////////////////////////////////////////////////////// NAME time RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) EXTERN ?L_MUL_L03 EXTERN ?Register_R4_is_cg_reg EXTERN ?Register_R5_is_cg_reg EXTERN ?Register_R6_is_cg_reg EXTERN ?Register_R8_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\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, R23 ST -Y, R22 ST -Y, R21 ST -Y, R20 ST -Y, R17 ST -Y, R16 IN R17, 0x3F // 60 unsigned char i; // 61 // 62 // 1 ms has passed, decrement all non-zero timers. // 63 for (i = 0; i < TIMERS; i++) { LDI R30, LOW(timeval) LDI R31, (timeval) >> 8 LDI R16, 4 // 64 if(timeval[i] > 0) { ??TICK_ISR_0: 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_1 // 65 timeval[i]--; LD R20, Z 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_1: ADIW R31:R30, 4 DEC R16 TST R16 BRNE ??TICK_ISR_0 // 68 } OUT 0x3F, R17 LD R16, Y+ LD R17, Y+ LD R20, Y+ LD R21, Y+ LD R22, Y+ LD R23, 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 { // 80 if(timeval[timer] > 0) { 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 R16, Z LDD R17, Z+1 LDD R18, Z+2 LDD R19, Z+3 OR R16, R17 OR R16, R18 OR R16, R19 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 { ST -Y, R8 ST -Y, R6 ST -Y, R5 ST -Y, R4 ST -Y, R27 ST -Y, R26 ST -Y, R25 ST -Y, R24 REQUIRE ?Register_R4_is_cg_reg REQUIRE ?Register_R5_is_cg_reg REQUIRE ?Register_R6_is_cg_reg REQUIRE ?Register_R8_is_cg_reg MOV R4, R16 MOV R8, R17 MOV R6, 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; // 104 timeval[timer] += 1000 * (unsigned long)sec; // 105 timeval[timer] += 1 * (unsigned long)ms; MOVW R21:R20, R19:R18 LDI R22, 0 LDI R23, 0 LDI R16, 96 LDI R17, 234 LDI R18, 0 LDI R19, 0 RCALL ?L_MUL_L03 MOVW R25:R24, R17:R16 MOVW R27:R26, R19:R18 MOV R20, R8 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 ADD R16, R24 ADC R17, R25 ADC R18, R26 ADC R19, R27 MOV R20, R6 LDI R21, 0 LDI R22, 0 LDI R23, 0 ADD R20, R16 ADC R21, R17 ADC R22, R18 ADC R23, R19 CLR R5 LSL R4 ROL R5 LSL R4 ROL R5 MOVW R31:R30, R5:R4 SUBI R30, LOW((-(timeval) & 0xFFFF)) SBCI R31, (-(timeval) & 0xFFFF) >> 8 ST Z, R20 STD Z+1, R21 STD Z+2, R22 STD Z+3, R23 // 106 } LD R24, Y+ LD R25, Y+ LD R26, Y+ LD R27, Y+ LD R4, Y+ LD R5, Y+ LD R6, Y+ LD R8, Y+ RET // 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<`: DW SFE(NEAR_Z) - SFB(NEAR_Z) DW SFB(NEAR_Z) DW 0 REQUIRE ?need_segment_init END // // 5 bytes in segment ABSOLUTE // 290 bytes in segment CODE // 6 bytes in segment INITTAB // 2 bytes in segment INTVEC // 16 bytes in segment NEAR_Z // // 290 bytes of CODE memory (+ 8 bytes shared) // 16 bytes of DATA memory (+ 5 bytes shared) // //Errors: none //Warnings: none