############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:39 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\main.c # # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\main.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\main.lst # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\main.r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100_cal\IAR\main.c 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ 2 /*! \file ********************************************************************* 3 * 4 * \brief 5 * Main program file 6 * 7 * Contains the main program, which is a basic state machine. 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: 2302 $ 24 * $RCSfile$ 25 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/main.c $ 26 * $Date: 2007-08-23 14:57:36 +0200 (to, 23 aug 2007) $\n 27 ******************************************************************************/ 28 29 /*! \page License 30 * Copyright (c) 2007, Atmel Corporation All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions are met: 34 * 35 * 1. Redistributions of source code must retain the above copyright notice, 36 * this list of conditions and the following disclaimer. 37 * 38 * 2. Redistributions in binary form must reproduce the above copyright notice, 39 * this list of conditions and the following disclaimer in the documentation 40 * and/or other materials provided with the distribution. 41 * 42 * 3. The name of ATMEL may not be used to endorse or promote products derived 43 * from this software without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED 46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 47 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND 48 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 49 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 52 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57 #include 58 #include 59 #include 60 61 #include "structs.h" 62 63 #include "main.h" 64 #include "ADC.h" 65 #include "statefunc.h" 66 #include "battery.h" 67 #include "menu.h" 68 #include "OWI.h" 69 #include "PWM.h" 70 #include "time.h" 71 #include "USI.h" 72 73 74 75 //****************************************************************************** 76 // Globals 77 //****************************************************************************** \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 78 unsigned char CurrentState; //!< \brief Global that indicates current state \ CurrentState: \ 00000000 DS 1 79 //!< 80 //!< Updated by main(). 81 //!< \note See menu.h for definition of states. 82 83 84 //****************************************************************************** 85 // Functions 86 //****************************************************************************** 87 /*! \brief Main program 88 * 89 * The main function goes into an infinite loop, keeping track of the current 90 * state and the next one. If the next state is different from the current, it 91 * looks up the address to the next state function, in \ref menu_state[], and 92 * updates \ref CurrentState. The state function is then called and will 93 * eventually return a new state, and so the loop reiterates. 94 * 95 * \todo The variable inp is passed to all state functions, but is not used 96 * for anything yet. Remove? 97 */ \ In segment CODE, align 2, keep-with-next 98 int main( void ) \ main: 99 { \ 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 100 unsigned char nextstate, inp, i; 101 unsigned char (*pStateFunc)(unsigned char); // Function pointer. 102 103 // Initialize local state variables. 104 inp = ZERO; \ 00000002 2466 CLR R6 105 CurrentState = nextstate = ST_INIT; \ 00000004 E00A LDI R16, 10 \ 00000006 2F90 MOV R25, R16 \ 00000008 9300.... STS CurrentState, R16 106 pStateFunc = NULL; \ 0000000C E000 LDI R16, 0 \ 0000000E E010 LDI R17, 0 \ 00000010 0128 MOVW R5:R4, R17:R16 107 108 // Look for function associated with current state, get its address. 109 for (i = 0; menu_state[i].state != 0; i++) { \ 00000012 E080 LDI R24, 0 \ ??main_0: \ 00000014 2F48 MOV R20, R24 \ 00000016 E050 LDI R21, 0 \ 00000018 E003 LDI R16, 3 \ 0000001A E010 LDI R17, 0 \ 0000001C .... RCALL ?S_MUL_L02 \ 0000001E .... LDI R30, LOW(menu_state) \ 00000020 .... LDI R31, (menu_state) >> 8 \ 00000022 0FE0 ADD R30, R16 \ 00000024 1FF1 ADC R31, R17 \ 00000026 9104 LPM R16, Z \ 00000028 2300 TST R16 \ 0000002A F0F1 BREQ ??main_1 110 if (menu_state[i].state == CurrentState) { \ 0000002C 2F48 MOV R20, R24 \ 0000002E E050 LDI R21, 0 \ 00000030 E003 LDI R16, 3 \ 00000032 E010 LDI R17, 0 \ 00000034 .... RCALL ?S_MUL_L02 \ 00000036 .... LDI R30, LOW(menu_state) \ 00000038 .... LDI R31, (menu_state) >> 8 \ 0000003A 0FE0 ADD R30, R16 \ 0000003C 1FF1 ADC R31, R17 \ 0000003E 9104 LPM R16, Z \ 00000040 9110.... LDS R17, CurrentState \ 00000044 1701 CP R16, R17 \ 00000046 F471 BRNE ??main_2 111 pStateFunc = menu_state[i].pFunc; \ 00000048 .... LDI R26, LOW((menu_state + 1)) \ 0000004A .... LDI R27, HIGH((menu_state + 1)) \ 0000004C 2F48 MOV R20, R24 \ 0000004E E050 LDI R21, 0 \ 00000050 E003 LDI R16, 3 \ 00000052 E010 LDI R17, 0 \ 00000054 .... RCALL ?S_MUL_L02 \ 00000056 0FA0 ADD R26, R16 \ 00000058 1FB1 ADC R27, R17 \ 0000005A 01FD MOVW R31:R30, R27:R26 \ 0000005C 9105 LPM R16, Z+ \ 0000005E 9114 LPM R17, Z \ 00000060 9731 SBIW R31:R30, 1 \ 00000062 0128 MOVW R5:R4, R17:R16 112 } 113 } \ ??main_2: \ 00000064 9583 INC R24 \ 00000066 CFD6 RJMP ??main_0 114 115 while (TRUE) { 116 // Run function associated with current state, get next state in return. 117 if (pStateFunc != NULL){ \ ??main_1: \ 00000068 E000 LDI R16, 0 \ 0000006A E010 LDI R17, 0 \ 0000006C 1640 CP R4, R16 \ 0000006E 0651 CPC R5, R17 \ 00000070 F021 BREQ ??main_3 118 nextstate = pStateFunc(inp); \ 00000072 2D06 MOV R16, R6 \ 00000074 01F2 MOVW R31:R30, R5:R4 \ 00000076 9509 ICALL \ 00000078 2F90 MOV R25, R16 119 } 120 121 // Look up function for next state, if it differs from the current. 122 if (nextstate != CurrentState) { \ ??main_3: \ 0000007A 9100.... LDS R16, CurrentState \ 0000007E 1790 CP R25, R16 \ 00000080 F399 BREQ ??main_1 123 CurrentState = nextstate; \ 00000082 9390.... STS CurrentState, R25 124 for ( i = 0; menu_state[i].state != 0; i++) { \ 00000086 E080 LDI R24, 0 \ ??main_4: \ 00000088 2F48 MOV R20, R24 \ 0000008A E050 LDI R21, 0 \ 0000008C E003 LDI R16, 3 \ 0000008E E010 LDI R17, 0 \ 00000090 .... RCALL ?S_MUL_L02 \ 00000092 .... LDI R30, LOW(menu_state) \ 00000094 .... LDI R31, (menu_state) >> 8 \ 00000096 0FE0 ADD R30, R16 \ 00000098 1FF1 ADC R31, R17 \ 0000009A 9104 LPM R16, Z \ 0000009C 2300 TST R16 \ 0000009E F321 BREQ ??main_1 125 if (menu_state[i].state == CurrentState) { \ 000000A0 2F48 MOV R20, R24 \ 000000A2 E050 LDI R21, 0 \ 000000A4 E003 LDI R16, 3 \ 000000A6 E010 LDI R17, 0 \ 000000A8 .... RCALL ?S_MUL_L02 \ 000000AA .... LDI R30, LOW(menu_state) \ 000000AC .... LDI R31, (menu_state) >> 8 \ 000000AE 0FE0 ADD R30, R16 \ 000000B0 1FF1 ADC R31, R17 \ 000000B2 9104 LPM R16, Z \ 000000B4 9110.... LDS R17, CurrentState \ 000000B8 1701 CP R16, R17 \ 000000BA F471 BRNE ??main_5 126 pStateFunc = menu_state[i].pFunc; \ 000000BC .... LDI R26, LOW((menu_state + 1)) \ 000000BE .... LDI R27, HIGH((menu_state + 1)) \ 000000C0 2F48 MOV R20, R24 \ 000000C2 E050 LDI R21, 0 \ 000000C4 E003 LDI R16, 3 \ 000000C6 E010 LDI R17, 0 \ 000000C8 .... RCALL ?S_MUL_L02 \ 000000CA 0FA0 ADD R26, R16 \ 000000CC 1FB1 ADC R27, R17 \ 000000CE 01FD MOVW R31:R30, R27:R26 \ 000000D0 9105 LPM R16, Z+ \ 000000D2 9114 LPM R17, Z \ 000000D4 9731 SBIW R31:R30, 1 \ 000000D6 0128 MOVW R5:R4, R17:R16 127 } 128 } \ ??main_5: \ 000000D8 9583 INC R24 \ 000000DA CFD6 RJMP ??main_4 129 } 130 } 131 } 132 133 134 /* Doxygen documentation mainpage ********************************************/ 135 /*! \mainpage 136 * \section intro Introduction 137 * This documents the software for application note AVR458. This is a charger 138 * for Li-Ion batteries, based on ATAVRBC100. 139 * 140 * \section compinfo Compilation Info 141 * This software was compiled with IAR Embedded Workbench, 4.30. To use GCC 142 * the source have to be modified.\n 143 * \n 144 * To make project on IAR EWAVR:\n 145 * Add the .c files to project (ADC.c, battery.c, main.c, menu.c, 146 * OWI.c, PWM.c, time.c and USI.c). Add either LIIONcharge.c or NIMHcharge.c, 147 * and update LIIONspecs.h or NIMHspecs.h, and battery.h with the appropriate 148 * battery data if needed.\n 149 * \n 150 * Use device --cpu=tiny861, enable bit definitions in I/O include files, 151 * optimization low for debug target and high for release, output format: ubrof8 152 * for Debug and intel_extended for Release. \n 153 * 154 * \section deviceinfo Device Info 155 * This application is based on the ATtiny 861, but it is possible to migrate 156 * the design to other AVR microcontrollers, such as pin-compatible devices 157 * ATtiny 261/461. Low pin count devices such as ATtiny 25/45/85 may also be 158 * used, but with reduced functionality. 159 * 160 * Required fuse bit settings: 161 *
    162           *    FUSE BIT  | SETTING
    163           *    ----------+--------------------
    164           *    CKDIV8    | 1 (unprogrammed)
    165           *    CKSEL3..0 | 0010 (internal osc)
    166           *    
167 * 168 * 169 * \section todo To Do-list 170 * \todo 171 * - Finalize master-slave communication protocol 172 * - Implement discharge mode 173 * 174 * \section contactinfo Contact Info 175 * For more info about Atmel AVR visit http://www.atmel.com/products/AVR/ \n 176 * For application notes visit 177 * http://www.atmel.com/dyn/products/app_notes.asp?family_id=607 \n 178 * Support mail: avr@atmel.com 179 */ 180 181 182 /*! \page misra MISRA C rule violations 183 * 184 * \par Rule 1 185 * "All code shall conform to ISO 9899 standard C, with no extensions 186 * permitted." 187 * 188 * Extensions are necessary because ISO C has no way of specifying that a 189 * function should be an interrupt service routine, or that we would like data 190 * members to be stored in f.ex. EEPROM. 191 * 192 * 193 * \par Rule 37 194 * "Bitwise operations shall not be performed on signed integer types." 195 * 196 * The compiler assumes all the 1's we shift around to make bitmasks are signed 197 * integers. Specifying them all to be (unsigned int), either directly or via a 198 * definition, would fix the rule violations, but also reduce code readability. 199 * 200 * 201 * \par Rule 45 202 * "Type casting from any type to or from pointers shall not be used." 203 * 204 * Assigning macro NULL, defined in stdlib.h, to a pointer causes this.. 205 * 206 * 207 * \par Rule 96 208 * "In the definition of a function-like macro the whole definition, and each 209 * instance of a parameter, shall be enclosed in parentheses." 210 * 211 * It is difficult to use parentheses with void function-like macros. 212 */ Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ main 7 4 -> Indirect call 7 2 Segment part sizes: Function/Label Bytes -------------- ----- CurrentState 1 main 220 Others 6 220 bytes in segment CODE 6 bytes in segment INITTAB 1 byte in segment NEAR_Z 220 bytes of CODE memory (+ 6 bytes shared) 1 byte of DATA memory Errors: none Warnings: none