1 ///////////////////////////////////////////////////////////////////////////////
\r
3 // IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:39 /
\r
4 // Copyright 1996-2007 IAR Systems. All rights reserved. /
\r
6 // Source file = C:\home\kevin\pub\src\bc100_cal\IAR\statefunc.c /
\r
7 // Command line = C:\home\kevin\pub\src\bc100_cal\IAR\statefunc.c /
\r
8 // --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IA /
\r
9 // R\Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\De /
\r
10 // bug\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug /
\r
11 // \List\ --initializers_in_flash -z2 --no_cse /
\r
12 // --no_inline --no_code_motion --no_cross_call /
\r
13 // --no_clustering --no_tbaa --debug /
\r
14 // -DENABLE_BIT_DEFINITIONS -e --require_prototypes -I /
\r
15 // "C:\Program 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 /
\r
19 // List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\statefun /
\r
23 ///////////////////////////////////////////////////////////////////////////////
\r
27 RSEG CSTACK:DATA:NOROOT(0)
\r
28 RSEG RSTACK:DATA:NOROOT(0)
\r
30 EXTERN ?EPILOGUE_B2_L09
\r
31 EXTERN ?EPILOGUE_B3_L09
\r
32 EXTERN ?EPILOGUE_B4_L09
\r
33 EXTERN ?PROLOGUE2_L09
\r
34 EXTERN ?PROLOGUE3_L09
\r
35 EXTERN ?PROLOGUE4_L09
\r
36 EXTERN ?SS_DIVMOD_L02
\r
38 EXTERN ?need_segment_init
\r
42 PUBWEAK `?<Segment init: NEAR_Z>`
\r
43 PUBLIC BatteryControl
\r
65 EXTERN DisableBatteries
\r
69 EXTERN EnableBattery
\r
71 EXTERN BatteryStatusRefresh
\r
72 EXTERN BatteryDataRefresh
\r
77 EXTERN PWM_IncrementDutyCycle
\r
86 // C:\home\kevin\pub\src\bc100_cal\IAR\statefunc.c
\r
87 // 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
88 // 2 /*! \file *********************************************************************
\r
91 // 5 * State functions
\r
93 // 7 * Contains the functions related to the states defined in menu.h.\n
\r
94 // 8 * Also contains related functions, i.e. for checking jumpers, setting
\r
95 // 9 * error flags and "dozing".
\r
97 // 11 * \note The state function Charge() is in a separate file since it
\r
98 // 12 * should easily be changed with regard to battery type.
\r
100 // 14 * \par Application note:
\r
101 // 15 * AVR458: Charging Li-Ion Batteries with BC100 \n
\r
102 // 16 * AVR463: Charging NiMH Batteries with BC100
\r
104 // 18 * \par Documentation
\r
105 // 19 * For comprehensive code documentation, supported compilers, compiler
\r
106 // 20 * settings and supported devices see readme.html
\r
109 // 23 * Atmel Corporation: http://www.atmel.com \n
\r
110 // 24 * Support email: avr@atmel.com
\r
114 // 28 * $Revision: 2299 $
\r
116 // 30 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/statefunc.c $
\r
117 // 31 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
118 // 32 ******************************************************************************/
\r
120 // 34 #include <ioavr.h>
\r
122 ASEGN ABSOLUTE:DATA:NOROOT,055H
\r
123 // <unnamed> volatile __io _A_MCUCR
\r
127 ASEGN ABSOLUTE:DATA:NOROOT,054H
\r
128 // <unnamed> volatile __io _A_MCUSR
\r
132 ASEGN ABSOLUTE:DATA:NOROOT,048H
\r
133 // <unnamed> volatile __io _A_CLKPR
\r
137 ASEGN ABSOLUTE:DATA:NOROOT,041H
\r
138 // <unnamed> volatile __io _A_WDTCR
\r
142 ASEGN ABSOLUTE:DATA:NOROOT,037H
\r
143 // <unnamed> volatile __io _A_DDRB
\r
147 ASEGN ABSOLUTE:DATA:NOROOT,026H
\r
148 // <unnamed> volatile __io _A_ADCSRA
\r
151 // 35 #include <inavr.h>
\r
152 // 36 #include <stdlib.h>
\r
154 // 38 #include "structs.h"
\r
155 // 39 #include "enums.h"
\r
157 // 41 #include "ADC.h"
\r
158 // 42 #include "statefunc.h"
\r
159 // 43 #include "battery.h"
\r
160 // 44 #include "charge.h"
\r
161 // 45 #include "main.h"
\r
162 // 46 #include "menu.h"
\r
163 // 47 #include "OWI.h"
\r
164 // 48 #include "PWM.h"
\r
165 // 49 #include "time.h"
\r
166 // 50 #include "USI.h"
\r
169 // 53 //******************************************************************************
\r
171 // 55 //******************************************************************************
\r
173 RSEG NEAR_Z:DATA:NOROOT(0)
\r
174 REQUIRE `?<Segment init: NEAR_Z>`
\r
175 // 56 unsigned char ErrorFlags; //!< \brief Holds error flags.
\r
178 // 57 //!< \note See statefunc.h for definitions of flags.
\r
180 // 59 //! \brief Holds the state in which latest error flag was set.
\r
181 // 60 //! \note See menu.h for definitions of states.
\r
183 RSEG NEAR_Z:DATA:NOROOT(0)
\r
184 REQUIRE `?<Segment init: NEAR_Z>`
\r
185 // 61 unsigned char ErrorState;
\r
190 // 64 //******************************************************************************
\r
192 // 66 //******************************************************************************
\r
193 // 67 /*! \brief Initialization
\r
195 // 69 * - Sets the system clock prescaler to 1 (run at 8 MHz)
\r
196 // 70 * - Initializes the one-wire interface
\r
197 // 71 * - Clears on-chip EEPROM
\r
198 // 72 * - Sets battery enable pins as outputs, then disables batteries
\r
199 // 73 * - Initializes SPI according to \ref SPIMODE
\r
200 // 74 * - Initializes ADC
\r
201 // 75 * - Initializes timers
\r
202 // 76 * - Reads battery data from both battery inputs (via ADC)
\r
203 // 77 * - Disables batteries again
\r
204 // 78 * - Sets battery A as the current one (\ref BattActive = 0)
\r
205 // 79 * - Clears ErrorFlags
\r
207 // 81 * \param inp Not used.
\r
209 // 83 * \retval ST_BATCON Next state in the sequence.
\r
212 RSEG CODE:CODE:NOROOT(1)
\r
213 // 85 unsigned char Initialize(unsigned char inp)
\r
216 RCALL ?PROLOGUE4_L09
\r
218 // 87 unsigned char i, page;
\r
220 // 89 // Disable interrupts while setting prescaler.
\r
221 // 90 __disable_interrupt();
\r
224 // 92 CLKPR = (1<<CLKPCE); // Enable CLKPS bit modification.
\r
227 // 93 CLKPR = 0; // Set prescaler 1 => 8 MHz clock frequency.
\r
231 // 95 // Init 1-Wire(R) interface.
\r
232 // 96 OWI_Init(OWIBUS);
\r
236 // 98 // Clear on-chip EEPROM.
\r
237 // 99 for (page = 0; page < 4; page++) {
\r
241 BRCC ??Initialize_1
\r
242 // 100 for (i = 0; i < 32; i++) {
\r
246 BRCC ??Initialize_3
\r
247 // 101 BattEEPROM[page][i] = 0;
\r
254 LDI R20, LOW(BattEEPROM)
\r
255 LDI R21, (BattEEPROM) >> 8
\r
266 RJMP ??Initialize_2
\r
270 RJMP ??Initialize_0
\r
272 // 105 DDRB = (1<<PB4) | (1<<PB5); // Set battery enable pins as outputs.
\r
276 // 106 DisableBatteries();
\r
277 RCALL DisableBatteries
\r
278 // 107 SPI_Init(SPIMODE);
\r
283 // 109 Time_Init();
\r
286 // 111 // Attempt to get ADC-readings (also gets RID-data) from both batteries.
\r
287 // 112 for (i = 0; i < 2; i++) {
\r
291 BRCC ??Initialize_5
\r
292 // 113 EnableBattery(i);
\r
294 RCALL EnableBattery
\r
297 // 115 BatteryStatusRefresh();
\r
298 RCALL BatteryStatusRefresh
\r
301 RJMP ??Initialize_4
\r
303 // 118 DisableBatteries();
\r
305 RCALL DisableBatteries
\r
307 // 120 BattActive = 0; // We have to start somewhere..
\r
309 STS BattActive, R16
\r
310 // 121 ErrorFlags = 0;
\r
312 STS ErrorFlags, R16
\r
314 // 123 // Init complete! Go to ST_BATCON next.
\r
315 // 124 return(ST_BATCON);
\r
318 RJMP ?EPILOGUE_B4_L09
\r
324 // 128 /*! \brief Tests jumper settings and batteries, starts charging if necessary.
\r
326 // 130 * First, JumperCheck() is called. If successful, the function checks if any
\r
327 // 131 * valid batteries are connected and attempts to charge these, if necessary.\n
\r
328 // 132 * If no charging is necessary, the charger goes to ST_SLEEP next.\n
\r
329 // 133 * ST_ERROR is next if either JumperCheck() fails or there are no valid
\r
330 // 134 * batteries. In this last case, the error is also flagged.
\r
332 // 136 * \param inp Not used.
\r
334 // 138 * \retval ST_ERROR Next state if either the jumper check failed, or there are
\r
335 // 139 * no valid batteries.
\r
336 // 140 * \retval ST_PREQUAL Next state if a battery is found to enabled and not fully
\r
338 // 142 * \retval ST_SLEEP Next state if battery/batteries are enabled and fully
\r
342 RSEG CODE:CODE:NOROOT(1)
\r
343 // 145 unsigned char BatteryControl(unsigned char inp)
\r
346 RCALL ?PROLOGUE3_L09
\r
348 // 147 unsigned char i;
\r
350 // 149 // Make sure ADC inputs are configured properly! (Will disables batteries.)
\r
351 // 150 if (!JumperCheck()) {
\r
354 BRNE ??BatteryControl_0
\r
355 // 151 return(ST_ERROR); // Error. Exit before damage is done!
\r
357 RJMP ??BatteryControl_1
\r
360 // 154 // If neither battery is valid, flag error and go to error state
\r
361 // 155 if ((!BattControl[0].Enabled) && (!BattControl[1].Enabled)) {
\r
362 ??BatteryControl_0:
\r
363 LDI R20, LOW(BattControl)
\r
364 LDI R21, (BattControl) >> 8
\r
368 BRNE ??BatteryControl_2
\r
369 LDI R20, LOW((BattControl + 1))
\r
370 LDI R21, HIGH((BattControl + 1))
\r
374 BRNE ??BatteryControl_2
\r
375 // 156 SetErrorFlag(ERR_NO_BATTERIES_ENABLED);
\r
379 // 158 return(ST_ERROR);
\r
381 RJMP ??BatteryControl_1
\r
384 // 161 // Get ADC-readings, try to read EPROM, and start prequalification
\r
385 // 162 // of any uncharged battery.
\r
386 // 163 for (i = 0; i < 2; i++) {
\r
387 ??BatteryControl_2:
\r
389 ??BatteryControl_3:
\r
391 BRCC ??BatteryControl_4
\r
392 // 164 if (BattControl[i].Enabled) {
\r
394 LDI R20, LOW(BattControl)
\r
395 LDI R21, (BattControl) >> 8
\r
401 BREQ ??BatteryControl_5
\r
402 // 165 EnableBattery(i);
\r
404 RCALL EnableBattery
\r
408 // 168 if (BatteryStatusRefresh()) {
\r
409 RCALL BatteryStatusRefresh
\r
411 BREQ ??BatteryControl_5
\r
412 // 169 if (!BattData.Charged) {
\r
413 LDI R30, LOW(BattData)
\r
414 LDI R31, (BattData) >> 8
\r
417 RJMP ??BatteryControl_5
\r
418 // 170 BatteryDataRefresh();
\r
419 RCALL BatteryDataRefresh
\r
421 // 172 return(ST_PREQUAL);
\r
423 RJMP ??BatteryControl_1
\r
428 ??BatteryControl_5:
\r
430 RJMP ??BatteryControl_3
\r
432 // 178 // If we end up here, one or two batteries are found and fully charged.
\r
433 // 179 // Disconnect, so we don't drain them, and go to sleep.
\r
434 // 180 DisableBatteries();
\r
435 ??BatteryControl_4:
\r
436 RCALL DisableBatteries
\r
438 // 182 return(ST_SLEEP);
\r
440 ??BatteryControl_1:
\r
442 RJMP ?EPILOGUE_B3_L09
\r
446 // 186 /*! \brief Start running on batteries
\r
448 // 188 * \todo Run on batteries, if battery voltage high enough.
\r
449 // 189 * \todo Jump here when mains voltage drops below threshold
\r
453 RSEG CODE:CODE:NOROOT(1)
\r
454 // 192 unsigned char Discharge(unsigned char inp)
\r
458 // 194 return(ST_BATCON); // Supply voltage restored, start charging
\r
464 // 198 /*! \brief Sleeps until either battery needs charging
\r
466 // 200 * Calls Doze(), then refreshes the status for both batteries on wakeup. If
\r
467 // 201 * connected batteries are both charged, the function will loop. If not, it's
\r
468 // 202 * back to ST_BATCON.
\r
470 // 204 * \param inp Not used.
\r
472 // 206 * \retval ST_BATCON Next state if a connected battery isn't fully charged.
\r
475 RSEG CODE:CODE:NOROOT(1)
\r
476 // 208 unsigned char Sleep(unsigned char inp)
\r
479 RCALL ?PROLOGUE2_L09
\r
481 // 210 unsigned char i;
\r
484 // 213 Doze(); // Take a nap (~8 seconds).
\r
488 // 215 // If any batteries need charging, go to ST_BATCON.
\r
489 // 216 // Otherwise, keep sleeping.
\r
490 // 217 for (i = 0; i < 2; i++) {
\r
495 // 218 EnableBattery(i);
\r
497 RCALL EnableBattery
\r
500 // 220 if ((BatteryStatusRefresh()) && (!BattData.Charged)) {
\r
501 RCALL BatteryStatusRefresh
\r
504 LDI R30, LOW(BattData)
\r
505 LDI R31, (BattData) >> 8
\r
509 // 221 return(ST_BATCON);
\r
518 // 225 DisableBatteries(); // Disable both batteries before Doze()!
\r
520 RCALL DisableBatteries
\r
521 // 226 } while (TRUE);
\r
525 RJMP ?EPILOGUE_B2_L09
\r
529 // 230 /*! \brief Doze off for approx. 8 seconds (Vcc = 5 V)
\r
531 // 232 * Waits for ADC-cycles to complete, disables the ADC, then sleeps for
\r
532 // 233 * approx. 8 seconds (Vcc = 5 V) using the watchdog timer.
\r
533 // 234 * On wakeup, ADC is re-enabled.
\r
536 RSEG CODE:CODE:NOROOT(1)
\r
537 // 236 void Doze(void)
\r
540 // 238 // Wait for this ADC cycle to complete, then halt after the next one.
\r
543 // 240 ADCS.Halt = TRUE;
\r
545 LDI R31, (ADCS) >> 8
\r
549 // 241 ADCS.Flag = FALSE;
\r
551 LDI R31, (ADCS) >> 8
\r
557 // 244 } while (ADCS.Flag == FALSE);
\r
560 LDI R31, (ADCS) >> 8
\r
565 // 246 WDTCR = (1<<WDP3)|(1<<WDP0); // 8.0 seconds at 5 volts VCC.
\r
568 // 247 WDTCR |= (1<<WDIF)|(1<<WDIE)|(1<<WDE); // Clear flag and enable watchdog.
\r
572 // 248 MCUCR |= (1<<SE) | (1<<SM1)|(1<<SM0); // Sleep enable, mode = standby.
\r
576 // 249 __sleep(); // Go to sleep, wake up by WDT.
\r
579 // 251 __watchdog_reset(); // Clear watchdog reset flag.
\r
581 // 252 MCUSR &= ~(1<<WDRF);
\r
585 // 253 WDTCR |= (1<<WDCE)|(1<<WDE); // Watchdog change enable.
\r
589 // 254 WDTCR = 0; // Turn off watchdog.
\r
593 // 256 ADCS.Halt = FALSE; // Enable consecutive runs of ADC.
\r
595 LDI R31, (ADCS) >> 8
\r
599 // 257 ADCSRA |= (1<<ADEN)|(1<<ADSC); // Enable ADC & start conversion.
\r
604 // 259 // Wait for this cycle to complete.
\r
605 // 260 ADC_Wait();
\r
615 // 264 /*! \brief Handles errors
\r
617 // 266 * Stops PWM output and disables batteries. The function then goes into a loop
\r
618 // 267 * that starts with a call to Doze(), then attempts to handle each error. The
\r
619 // 268 * loop will reiterate until all flags are cleared.\n
\r
620 // 269 * The charger will reinitialize after this.
\r
622 // 271 * Jumper errors are handled by clearing the flag, then calling JumperCheck().
\r
623 // 272 * If unsuccessful, the error flag will now have been set again.\n
\r
625 // 274 * If there are no valid batteries, the loop will simply reiterate until a
\r
626 // 275 * valid battery is found. The error flag will then be cleared.\n
\r
628 // 277 * In the case of PWM controller or battery temperature errors, the error
\r
629 // 278 * flag is simply cleared. This is because the problem may have gone away during
\r
630 // 279 * Doze(), or after reinitializing.\n
\r
632 // 281 * If a battery is exhausted, we clear its exhausted-flag in \ref BattData,
\r
633 // 282 * and change batteries before clearing the error flag.
\r
635 // 284 * \param inp Not used.
\r
638 RSEG CODE:CODE:NOROOT(1)
\r
639 // 286 unsigned char Error(unsigned char inp)
\r
642 RCALL ?PROLOGUE2_L09
\r
644 // 288 unsigned char i;
\r
646 // 290 PWM_Stop(); // Stop charging.
\r
648 // 291 DisableBatteries(); // Disable all loads.
\r
649 RCALL DisableBatteries
\r
652 // 294 Doze(); // Take a nap.
\r
656 // 296 // For each bit in ErrorFlags, starting with LSB, handle
\r
657 // 297 // associated error, if the flag is set.
\r
658 // 298 for (i = 0x01; i!=0; i<<=1) {
\r
664 // 299 if(i & ErrorFlags) {
\r
665 LDS R16, ErrorFlags
\r
670 // 300 switch (i) {
\r
684 // 302 case ERR_JUMPER_MISMATCH:
\r
685 // 303 // Clear flag & recheck.
\r
686 // 304 ErrorFlags &= ~i;
\r
690 LDI R30, LOW(ErrorFlags)
\r
691 LDI R31, (ErrorFlags) >> 8
\r
695 // 305 JumperCheck();
\r
701 // 309 case ERR_NO_BATTERIES_ENABLED:
\r
702 // 310 // Clear if any battery gets enabled.
\r
703 // 311 if ((BattControl[0].Enabled) || (BattControl[1].Enabled)) {
\r
705 LDI R20, LOW(BattControl)
\r
706 LDI R21, (BattControl) >> 8
\r
711 LDI R20, LOW((BattControl + 1))
\r
712 LDI R21, HIGH((BattControl + 1))
\r
717 // 312 ErrorFlags &= ~i;
\r
721 LDI R30, LOW(ErrorFlags)
\r
722 LDI R31, (ErrorFlags) >> 8
\r
731 // 317 case ERR_PWM_CONTROL:
\r
732 // 318 // Clear flag.
\r
733 // 319 ErrorFlags &= ~i;
\r
737 LDI R30, LOW(ErrorFlags)
\r
738 LDI R31, (ErrorFlags) >> 8
\r
746 // 323 case ERR_BATTERY_TEMPERATURE:
\r
747 // 324 // Clear flag.
\r
748 // 325 ErrorFlags &= ~i;
\r
752 LDI R30, LOW(ErrorFlags)
\r
753 LDI R31, (ErrorFlags) >> 8
\r
761 // 329 case ERR_BATTERY_EXHAUSTED:
\r
762 // 330 // Try the other battery.
\r
763 // 331 BattData.Exhausted = FALSE;
\r
765 LDI R30, LOW(BattData)
\r
766 LDI R31, (BattData) >> 8
\r
770 // 332 BattActive = (BattActive + 1) % 2;
\r
771 LDS R30, BattActive
\r
774 MOVW R17:R16, R31:R30
\r
777 RCALL ?SS_DIVMOD_L02
\r
778 STS BattActive, R20
\r
779 // 333 ErrorFlags &= ~i;
\r
782 LDI R30, LOW(ErrorFlags)
\r
783 LDI R31, (ErrorFlags) >> 8
\r
798 // 342 } while (ErrorFlags);
\r
800 LDS R16, ErrorFlags
\r
805 // 344 return(ST_INIT);
\r
808 RJMP ?EPILOGUE_B2_L09
\r
812 // 348 /*! \brief Sets the specified error-flag and saves the current state
\r
814 // 350 * Updates \ref ErrorFlags and \ref ErrorState.
\r
816 // 352 * \note Error flags are specified in statefunc.h.
\r
818 // 354 * \param Flag Specifies what error to flag.
\r
821 RSEG CODE:CODE:NOROOT(1)
\r
822 // 356 void SetErrorFlag(unsigned char Flag)
\r
825 // 358 ErrorFlags |= Flag;
\r
826 LDI R30, LOW(ErrorFlags)
\r
827 LDI R31, (ErrorFlags) >> 8
\r
831 // 359 ErrorState = CurrentState;
\r
832 LDS R17, CurrentState
\r
833 STS ErrorState, R17
\r
838 // 363 /*! \brief Checks on-board jumpers.
\r
840 // 365 * Checks on-board jumpers by disconnecting all loads, engaging the PWM and
\r
841 // 366 * increasing the duty cycle until conditioned output voltage equals conditioned
\r
842 // 367 * input voltage. At low PWM duty and no load buck output should be zero and,
\r
843 // 368 * when increasing PWM duty, should quickly jump to steady state output roughly
\r
844 // 369 * equal to input voltage. Will disable and leave disabled all batteries.
\r
846 // 371 * \retval FALSE If jumper or load mismatch.
\r
847 // 372 * \retval TRUE If everything OK.
\r
850 RSEG CODE:CODE:NOROOT(1)
\r
851 // 374 unsigned char JumperCheck(void)
\r
854 // 376 DisableBatteries(); // Disconnect, or loads may be destroyed!
\r
855 RCALL DisableBatteries
\r
857 // 378 PWM_Start(); // Start PWM (controls the buck charger).
\r
860 // 380 // Use general timer: shouldn't take longer than (6 x 255) / 2500 ~= 0.62s.
\r
861 // 381 Time_Set(TIMER_GEN,0,1,0);
\r
870 // 384 // If the PWM output voltage saturates the ADC, stop PWM output and
\r
871 // 385 // report a failure.
\r
872 // 386 if (ADCS.rawVBAT == 1023) {
\r
875 LDI R31, (ADCS) >> 8
\r
881 BRNE ??JumperCheck_1
\r
884 // 388 return(FALSE);
\r
889 // 391 // If the absolute difference between measured (VIN - VBAT) and the
\r
890 // 392 // typical value are below our set maximum, everything is OK.
\r
891 // 393 if (abs((signed int)(ADCS.VIN - VIN_VBAT_DIFF_TYP - ADCS.VBAT)) <
\r
892 // 394 VIN_VBAT_DIFF_MAX ) {
\r
895 LDI R31, (ADCS) >> 8
\r
901 LDI R31, (ADCS) >> 8
\r
910 BRGE ??JumperCheck_2
\r
914 // 397 return(TRUE);
\r
919 // 400 // Charge current is too high -> check load and jumper J405 and J406.
\r
920 // 401 if (abs(ADCS.IBAT) > 100) {
\r
923 LDI R31, (ADCS) >> 8
\r
930 BRLT ??JumperCheck_3
\r
933 // 403 return(FALSE);
\r
938 // 406 // If the PWM output can't be increased high enough -> check jumpers
\r
939 // 407 // J400-J404, J407 and J408.
\r
940 // 408 if (!PWM_IncrementDutyCycle()) {
\r
942 RCALL PWM_IncrementDutyCycle
\r
944 BRNE ??JumperCheck_4
\r
947 // 410 return(FALSE);
\r
952 // 413 // Wait for ADC conversions to complete
\r
956 // 415 } while (Time_Left(TIMER_GEN));
\r
960 BRNE ??JumperCheck_0
\r
963 // 418 // If we end up here, the measurements took too long.
\r
966 // 420 return(FALSE);
\r
971 ASEGN ABSOLUTE:DATA:NOROOT,01cH
\r
974 ASEGN ABSOLUTE:DATA:NOROOT,01dH
\r
977 ASEGN ABSOLUTE:DATA:NOROOT,01eH
\r
980 ASEGN ABSOLUTE:DATA:NOROOT,01fH
\r
983 RSEG INITTAB:CODE:NOROOT(0)
\r
984 `?<Segment init: NEAR_Z>`:
\r
985 DW SFE(NEAR_Z) - SFB(NEAR_Z)
\r
988 REQUIRE ?need_segment_init
\r
992 // 6 bytes in segment ABSOLUTE
\r
993 // 734 bytes in segment CODE
\r
994 // 6 bytes in segment INITTAB
\r
995 // 2 bytes in segment NEAR_Z
\r
997 // 734 bytes of CODE memory (+ 6 bytes shared)
\r
998 // 2 bytes of DATA memory (+ 6 bytes shared)
\r