Initial import
[avr_bc100.git] / BaseTinyFirmware / IAR / Release / List / PWM.s90
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //                                                                            /\r
3 // IAR Atmel AVR C/C++ Compiler V4.30F/W32              13/Mar/2008  04:52:01 /\r
4 // Copyright 1996-2007 IAR Systems. All rights reserved.                      /\r
5 //                                                                            /\r
6 //    Source file           =  C:\home\kevin\pub\src\bc100\IAR\PWM.c          /\r
7 //    Command line          =  C:\home\kevin\pub\src\bc100\IAR\PWM.c          /\r
8 //                             --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc1 /\r
9 //                             00\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\Li /\r
12 //                             st\ --initializers_in_flash -s9                /\r
13 //                             --no_cross_call --no_tbaa                      /\r
14 //                             -DENABLE_BIT_DEFINITIONS -e -I "C:\Program     /\r
15 //                             Files\IAR Systems\Embedded Workbench           /\r
16 //                             4.0\avr\INC\" -I "C:\Program Files\IAR         /\r
17 //                             Systems\Embedded Workbench 4.0\avr\INC\CLIB\"  /\r
18 //                             --eeprom_size 512 --misrac=5-9,11-12,14,16-17, /\r
19 //                             19-21,24-26,29-32,34-35,38-39,42-43,46,50,     /\r
20 //                             52-54,56-59,61-62,64-65,68-80,83-84,87-91,     /\r
21 //                             94-95,98-100,103-110,112-126                   /\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
28 //                             112-115,118-126                                /\r
29 //      Not checked         =  6,16,25-26,43,65,70,90,99,103,106-107,110,     /\r
30 //                             116-117                                        /\r
31 //    List file             =  C:\home\kevin\pub\src\bc100\IAR\Release\List\P /\r
32 //                             WM.s90                                         /\r
33 //                                                                            /\r
34 //                                                                            /\r
35 ///////////////////////////////////////////////////////////////////////////////\r
36 \r
37         NAME PWM\r
38 \r
39         RSEG CSTACK:DATA:NOROOT(0)\r
40         RSEG RSTACK:DATA:NOROOT(0)\r
41 \r
42         PUBLIC PWM_DecrementDutyCycle\r
43         PUBLIC PWM_IncrementDutyCycle\r
44         PUBLIC PWM_Start\r
45         PUBLIC PWM_Stop\r
46         PUBWEAK _A_DDRB\r
47         PUBWEAK _A_DT1\r
48         PUBWEAK _A_OCR1A\r
49         PUBWEAK _A_OCR1B\r
50         PUBWEAK _A_OCR1C\r
51         PUBWEAK _A_OCR1D\r
52         PUBWEAK _A_PLLCSR\r
53         PUBWEAK _A_TCCR1A\r
54         PUBWEAK _A_TCCR1B\r
55         PUBWEAK _A_TCCR1C\r
56         PUBWEAK _A_TCCR1D\r
57         PUBWEAK _A_TCCR1E\r
58         PUBWEAK __?EEARH\r
59         PUBWEAK __?EEARL\r
60         PUBWEAK __?EECR\r
61         PUBWEAK __?EEDR\r
62 \r
63         EXTERN Time_Set\r
64         EXTERN Time_Left\r
65 \r
66 // C:\home\kevin\pub\src\bc100\IAR\PWM.c\r
67 //    1 /* This file has been prepared for Doxygen automatic documentation generation.*/\r
68 //    2 /*! \file *********************************************************************\r
69 //    3  *\r
70 //    4  * \brief\r
71 //    5  *      Functions for use of PWM\r
72 //    6  *\r
73 //    7  *      Contains functions for initializing and controlling PWM output.\r
74 //    8  *\r
75 //    9  * \par Application note:\r
76 //   10  *      AVR458: Charging Li-Ion Batteries with BC100\n\r
77 //   11  *      AVR463: Charging NiMH Batteries with BC100\r
78 //   12  *\r
79 //   13  * \par Documentation\r
80 //   14  *      For comprehensive code documentation, supported compilers, compiler \r
81 //   15  *      settings and supported devices see readme.html\r
82 //   16  *\r
83 //   17  * \author\r
84 //   18  *      Atmel Corporation: http://www.atmel.com \n\r
85 //   19  *      Support email: avr@atmel.com\r
86 //   20  *\r
87 //   21  * \r
88 //   22  * $Name$\r
89 //   23  * $Revision: 2299 $\r
90 //   24  * $RCSfile$\r
91 //   25  * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/PWM.c $\r
92 //   26  * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n\r
93 //   27  ******************************************************************************/\r
94 //   28 \r
95 //   29 #include <ioavr.h>\r
96 \r
97         ASEGN ABSOLUTE:DATA:NOROOT,050H\r
98 // <unnamed> volatile __io _A_TCCR1A\r
99 _A_TCCR1A:\r
100         DS 1\r
101 \r
102         ASEGN ABSOLUTE:DATA:NOROOT,04fH\r
103 // <unnamed> volatile __io _A_TCCR1B\r
104 _A_TCCR1B:\r
105         DS 1\r
106 \r
107         ASEGN ABSOLUTE:DATA:NOROOT,04dH\r
108 // <unnamed> volatile __io _A_OCR1A\r
109 _A_OCR1A:\r
110         DS 1\r
111 \r
112         ASEGN ABSOLUTE:DATA:NOROOT,04cH\r
113 // <unnamed> volatile __io _A_OCR1B\r
114 _A_OCR1B:\r
115         DS 1\r
116 \r
117         ASEGN ABSOLUTE:DATA:NOROOT,04bH\r
118 // <unnamed> volatile __io _A_OCR1C\r
119 _A_OCR1C:\r
120         DS 1\r
121 \r
122         ASEGN ABSOLUTE:DATA:NOROOT,04aH\r
123 // <unnamed> volatile __io _A_OCR1D\r
124 _A_OCR1D:\r
125         DS 1\r
126 \r
127         ASEGN ABSOLUTE:DATA:NOROOT,049H\r
128 // <unnamed> volatile __io _A_PLLCSR\r
129 _A_PLLCSR:\r
130         DS 1\r
131 \r
132         ASEGN ABSOLUTE:DATA:NOROOT,047H\r
133 // <unnamed> volatile __io _A_TCCR1C\r
134 _A_TCCR1C:\r
135         DS 1\r
136 \r
137         ASEGN ABSOLUTE:DATA:NOROOT,046H\r
138 // <unnamed> volatile __io _A_TCCR1D\r
139 _A_TCCR1D:\r
140         DS 1\r
141 \r
142         ASEGN ABSOLUTE:DATA:NOROOT,044H\r
143 // <unnamed> volatile __io _A_DT1\r
144 _A_DT1:\r
145         DS 1\r
146 \r
147         ASEGN ABSOLUTE:DATA:NOROOT,037H\r
148 // <unnamed> volatile __io _A_DDRB\r
149 _A_DDRB:\r
150         DS 1\r
151 \r
152         ASEGN ABSOLUTE:DATA:NOROOT,020H\r
153 // <unnamed> volatile __io _A_TCCR1E\r
154 _A_TCCR1E:\r
155         DS 1\r
156 //   30 \r
157 //   31 #include "enums.h"\r
158 //   32 \r
159 //   33 #include "main.h"\r
160 //   34 #include "PWM.h"\r
161 //   35 #include "time.h"\r
162 //   36 \r
163 //   37 \r
164 //   38 //******************************************************************************\r
165 //   39 // Functions\r
166 //   40 //******************************************************************************\r
167 //   41 /*! \brief Stops PWM output\r
168 //   42  *\r
169 //   43  */\r
170 \r
171         RSEG CODE:CODE:NOROOT(1)\r
172 //   44 void PWM_Stop(void)\r
173 PWM_Stop:\r
174 //   45 {\r
175 //   46         OCR1B = 0;  // Reset compare level.\r
176         LDI     R16, 0\r
177         OUT     0x2C, R16\r
178 //   47         PLLCSR = 0; // Disable PLL, switch to synchronous CLK mode.\r
179         OUT     0x29, R16\r
180 //   48         TCCR1A = 0; // Set normal port operation, disable PWM modes.\r
181         OUT     0x30, R16\r
182 //   49         TCCR1B = 0; // Stop timer/counter1.\r
183         OUT     0x2F, R16\r
184 //   50         TCCR1C = 0; // Set normal port operation.\r
185         OUT     0x27, R16\r
186 //   51         TCCR1D = 0; // No fault protection, normal waveform.\r
187         OUT     0x26, R16\r
188 //   52         OCR1C = 0;  // Reset compare.\r
189         OUT     0x2B, R16\r
190 //   53         OCR1D = 0;  // Reset compare.\r
191         OUT     0x2A, R16\r
192 //   54         DT1 = 0;    // No dead time values.\r
193         OUT     0x24, R16\r
194 //   55 }\r
195         RET\r
196         REQUIRE _A_TCCR1A\r
197         REQUIRE _A_TCCR1B\r
198         REQUIRE _A_OCR1B\r
199         REQUIRE _A_OCR1C\r
200         REQUIRE _A_OCR1D\r
201         REQUIRE _A_PLLCSR\r
202         REQUIRE _A_TCCR1C\r
203         REQUIRE _A_TCCR1D\r
204         REQUIRE _A_DT1\r
205 //   56 \r
206 //   57 \r
207 //   58 /*! \brief Initializes and starts PWM output\r
208 //   59  *\r
209 //   60  * Initializes timer1 for use as a PWM with a clock rate of 64 MHz.\n\r
210 //   61  * Its comparator is connected to PB3 and will output high until timer1 reaches\r
211 //   62  * the value of OCR1B. It is then dropped to 0.\n\r
212 //   63  * The comparator outputs high again when the counter overflows, which will\r
213 //   64  * happen at a rate of 250 kHz.\r
214 //   65  */\r
215 \r
216         RSEG CODE:CODE:NOROOT(1)\r
217 //   66 void PWM_Start(void)\r
218 PWM_Start:\r
219 //   67 {\r
220 //   68         // Clear OC1B on compare match, enable PWM on comparator OCR1B.\r
221 //   69         TCCR1A = (1<<COM1B1)|(0<<COM1B0)|(1<<PWM1B);\r
222         LDI     R16, 33\r
223         OUT     0x30, R16\r
224 //   70         \r
225 //   71         // Non-inverted PWM, T/C stopped.\r
226 //   72         TCCR1B = 0;\r
227         LDI     R16, 0\r
228         OUT     0x2F, R16\r
229 //   73         \r
230 //   74         // Copy shadow bits, disconnect OC1D.\r
231 //   75         TCCR1C = (TCCR1A & 0xF0);\r
232         IN      R16, 0x30\r
233         ANDI    R16, 0xF0\r
234         OUT     0x27, R16\r
235 //   76         \r
236 //   77         // No fault protection, use phase & frequency correct PWM.\r
237 //   78         TCCR1D = (0<<WGM11)|(1<WGM10);\r
238         LDI     R16, 0\r
239         OUT     0x26, R16\r
240 //   79         \r
241 //   80         // Does not matter -- PWM6 mode not used.\r
242 //   81         TCCR1E = 0;\r
243         OUT     0x00, R16\r
244 //   82         \r
245 //   83         // Does not matter -- OC1A is disabled.\r
246 //   84         OCR1A = 0;\r
247         OUT     0x2D, R16\r
248 //   85         \r
249 //   86         // Set reset compare level. (Offset is used, or JumperCheck() will fail.)\r
250 //   87         OCR1B = PWM_OFFSET;\r
251         LDI     R16, 12\r
252         OUT     0x2C, R16\r
253 //   88         \r
254 //   89         // TOP value for PWM, f(PWM) = 64MHz / 255 = 251kHz.\r
255 //   90         OCR1C = 0xFF;\r
256         LDI     R16, 255\r
257         OUT     0x2B, R16\r
258 //   91         \r
259 //   92         // Does not matter -- OC1D is disabled.\r
260 //   93         OCR1D = 0;\r
261         LDI     R16, 0\r
262         OUT     0x2A, R16\r
263 //   94         \r
264 //   95         // No dead time values.\r
265 //   96         DT1 = 0;\r
266         OUT     0x24, R16\r
267 //   97         \r
268 //   98         // Set PWM port pin to output.\r
269 //   99         DDRB |= (1<<PB3);\r
270         SBI     0x17, 0x03\r
271 //  100         \r
272 //  101         // Enable PLL, use full speed mode.\r
273 //  102         PLLCSR = (0<<LSM) | (1<<PLLE);\r
274         LDI     R16, 2\r
275         OUT     0x29, R16\r
276 //  103         \r
277 //  104         // Use general timer and wait 1 ms for PLL lock to settle.\r
278 //  105         Time_Set(TIMER_GEN,0,0,1);\r
279         LDI     R20, 1\r
280         LDI     R17, 0\r
281         LDI     R18, 0\r
282         LDI     R19, 0\r
283         RCALL   Time_Set\r
284 //  106         do{ \r
285 //  107         }while(Time_Left(TIMER_GEN));\r
286 ??PWM_Start_0:\r
287         LDI     R16, 2\r
288         RCALL   Time_Left\r
289         TST     R16\r
290         BRNE    ??PWM_Start_0\r
291 //  108         \r
292 //  109         // Now wait for PLL to lock.\r
293 //  110         do{ \r
294 //  111         }while((PLLCSR & (1<<PLOCK)) == 0);\r
295 ??PWM_Start_1:\r
296         IN      R16, 0x29\r
297         SBRS    R16, 0\r
298         RJMP    ??PWM_Start_1\r
299 //  112 \r
300 //  113         // Use PLL as clock source.\r
301 //  114         PLLCSR |= (1<<PCKE);\r
302         IN      R16, 0x29\r
303         ORI     R16, 0x04\r
304         OUT     0x29, R16\r
305 //  115         \r
306 //  116         // CLK PCK = 64MHz / 1 = 64MHz.\r
307 //  117         TCCR1B |= (0<<CS13)|(0<<CS12)|(0<<CS11)|(1<<CS10);\r
308         IN      R16, 0x2F\r
309         ORI     R16, 0x01\r
310         OUT     0x2F, R16\r
311 //  118 }\r
312         RET\r
313         REQUIRE _A_TCCR1A\r
314         REQUIRE _A_TCCR1B\r
315         REQUIRE _A_OCR1A\r
316         REQUIRE _A_OCR1B\r
317         REQUIRE _A_OCR1C\r
318         REQUIRE _A_OCR1D\r
319         REQUIRE _A_PLLCSR\r
320         REQUIRE _A_TCCR1C\r
321         REQUIRE _A_TCCR1D\r
322         REQUIRE _A_DT1\r
323         REQUIRE _A_DDRB\r
324         REQUIRE _A_TCCR1E\r
325 //  119 \r
326 //  120 \r
327 //  121 /*! \brief Increments the PWM duty cycle, if not already at max\r
328 //  122  *\r
329 //  123  * \retval TRUE Success, duty cycle could be incremented.\r
330 //  124  * \retval FALSE Failure, duty cycle already at maximum.\r
331 //  125  */\r
332 \r
333         RSEG CODE:CODE:NOROOT(1)\r
334 //  126 unsigned char PWM_IncrementDutyCycle(void){\r
335 PWM_IncrementDutyCycle:\r
336 //  127 \r
337 //  128         if (OCR1B < PWM_MAX) {\r
338         IN      R16, 0x2C\r
339         CPI     R16, 255\r
340         BREQ    ??PWM_IncrementDutyCycle_0\r
341 //  129                 OCR1B += 1;\r
342         IN      R16, 0x2C\r
343         INC     R16\r
344         OUT     0x2C, R16\r
345 //  130                 return(TRUE);\r
346         LDI     R16, 1\r
347         RET\r
348 //  131         } else {\r
349 //  132                 return(FALSE);\r
350 ??PWM_IncrementDutyCycle_0:\r
351         LDI     R16, 0\r
352         RET\r
353         REQUIRE _A_OCR1B\r
354 //  133         }\r
355 //  134 }\r
356 //  135 \r
357 //  136 \r
358 //  137 /*! \brief Decrements the PWM duty cycle, if not already at zero.\r
359 //  138  *\r
360 //  139  * \retval TRUE Success, duty cycle could be decremented.\r
361 //  140  * \retval FALSE Failure, duty cycle already at zero.\r
362 //  141  */\r
363 \r
364         RSEG CODE:CODE:NOROOT(1)\r
365 //  142 unsigned char PWM_DecrementDutyCycle(void){\r
366 PWM_DecrementDutyCycle:\r
367 //  143         \r
368 //  144         if (OCR1B > 0)  {\r
369         IN      R16, 0x2C\r
370         TST     R16\r
371         BREQ    ??PWM_DecrementDutyCycle_0\r
372 //  145                 OCR1B -= 1;\r
373         IN      R16, 0x2C\r
374         DEC     R16\r
375         OUT     0x2C, R16\r
376 //  146                 return(TRUE);\r
377         LDI     R16, 1\r
378         RET\r
379 //  147         } else {\r
380 //  148                 return(FALSE);\r
381 ??PWM_DecrementDutyCycle_0:\r
382         LDI     R16, 0\r
383         RET\r
384         REQUIRE _A_OCR1B\r
385 //  149         }\r
386 //  150 }\r
387 \r
388         ASEGN ABSOLUTE:DATA:NOROOT,01cH\r
389 __?EECR:\r
390 \r
391         ASEGN ABSOLUTE:DATA:NOROOT,01dH\r
392 __?EEDR:\r
393 \r
394         ASEGN ABSOLUTE:DATA:NOROOT,01eH\r
395 __?EEARL:\r
396 \r
397         ASEGN ABSOLUTE:DATA:NOROOT,01fH\r
398 __?EEARH:\r
399 \r
400         END\r
401 // \r
402 //  12 bytes in segment ABSOLUTE\r
403 // 142 bytes in segment CODE\r
404 // \r
405 // 142 bytes of CODE memory\r
406 //   0 bytes of DATA memory (+ 12 bytes shared)\r
407 //\r
408 //Errors: none\r
409 //Warnings: none\r