// File: /workspace/github_cpp_makefile_star2_O1/jkingan[P]ladyheather/heathgps.cpp
// Function: constant_load()
void constant_load()
{
DATA_SIZE delta;
u16 pwm;

   if(cc_mode == 0) return;
   if(cc_state < 5) ++cc_state;
   if(sweep_rate <= 0) {
      sweep_rate = sweep_tick = 1;
   }

   if(cc_state == 1) {  // starting up
      if(cc_mode == PWM_SWEEP) {
         cc_pwm = sweep_val = sweep_start;
         goto charged;
      }
      else if((cc_mode == CC_LIPO) && (led_v < unsafe_v)) {  // potentially unsafe cell - don't charge
         goto stop_charge;
      }
      term_timer = TERM_TIME;
      if(sweep_stop) cc_pwm = 0.0;
      else           cc_pwm = PWM_STEP;
   }
   else if(cc_mode == PWM_SWEEP) {   // sweeping PWM value between limits
      if(sweep_start > sweep_end) {  // down sweep
         if(--sweep_tick <= 0) {
            sweep_tick = sweep_rate;
            sweep_val -= PWM_STEP;
            if(sweep_val < 0.0) end_sweep();
         }
         if(sweep_val < sweep_end) {
            end_sweep();
         }
      }
      else {                         // up sweep;
         if(--sweep_tick <= 0) {
            sweep_tick = sweep_rate;
            sweep_val += PWM_STEP;
            if(sweep_val > 1.0) end_sweep();
         }
         if(sweep_val > sweep_end) {
            end_sweep();
         }
      }
      cc_pwm = sweep_val;
      goto charged;
   }
   else {
      if((cc_mode == CC_LIPO) && (led_v > (lipo_volts-0.05))) {  // constant V mode
//       if(led_v > (lipo_volts+0.05)) goto stop_charge;
         if(led_v > (lipo_volts+0.10)) goto stop_charge;
         if(led_i < (cc_val/20.0)) {  // constant I mode - charge done at charge_rate/20
            if(--term_timer < 0) {
               stop_charge:
               end_sweep();
               cc_pwm = 0.0;
               goto charged;
            }
         }
         else term_timer = TERM_TIME;

         if(led_i < cc_val) {
            if((led_v > lipo_volts) && cc_pwm) {
               cc_pwm -= PWM_STEP;
               if(cc_pwm < PWM_STEP) cc_pwm = PWM_STEP;
            }
            goto charged;
         }
      }

      if((cc_mode == CC_VOLTS) && (led_v > 0.050)) {  // must have at least 50mv load voltage
         if(sweep_stop) {
            if(led_v > sweep_stop) {
               end_sweep();
               cc_pwm = 0.0;
            }
            else if(--sweep_tick <= 0) {
               sweep_tick = sweep_rate;
               cc_pwm += PWM_STEP;
               if(cc_pwm > 1.0) {
                  end_sweep();
                  cc_pwm = 0.0;
               }
            }
         }
         else {
            delta = (cc_val - led_v);
            delta /= led_v;
            if(delta < 0.0) delta *= (DATA_SIZE) 0.50;
            else            delta *= (DATA_SIZE) 0.20;
            cc_pwm += (delta * cc_pwm);
         }
      }
      else if((cc_mode == CC_WATTS) && (led_w > 0.050)) {  // must have at least 50mw load power
         if(sweep_stop) {
            if(led_w > sweep_stop) {
               end_sweep();
               cc_pwm = 0.0;
            }
            else if(--sweep_tick <= 0) {
               sweep_tick = sweep_rate;
               cc_pwm += PWM_STEP;
               if(cc_pwm > 1.0) {
                  end_sweep();
                  cc_pwm = 0.0;
               }
            }
         }
         else {
            delta = (cc_val - led_w);
            delta /= led_w;
            if(delta < 0.0) delta *= (DATA_SIZE) 0.25;  // power is a squared function, reduce gain
            else            delta *= (DATA_SIZE) 0.04;
            cc_pwm += (delta * cc_pwm);
         }
      }
      else if((cc_mode > 1) && (led_i > 0.050)) {  // must have at least 50mA load current
         if(sweep_stop) {
            if(led_i > sweep_stop) {
               end_sweep();
               cc_pwm = 0.0;
            }
            else if(--sweep_tick <= 0) {
               sweep_tick = sweep_rate;
               cc_pwm += PWM_STEP;
               if(cc_pwm > 1.0) {
                  end_sweep();
                  cc_pwm = 0.0;
               }
            }
         }
         else {
            delta = (cc_val - led_i);
            delta /= led_i;
            if(delta < 0.0) delta *= (DATA_SIZE) 0.50;
            else            delta *= (DATA_SIZE) 0.20;
            cc_pwm += (delta * cc_pwm);
         }
      }
      else {
         if(sweep_stop) {
            if(--sweep_tick <= 0) {
               sweep_tick = sweep_rate;
               cc_pwm += PWM_STEP;
               if(cc_pwm > 1.0) {
                  end_sweep();
                  cc_pwm = 0.0;
               }
            }
         }
         else {
            cc_pwm += PWM_STEP;
         }
      }
   }

   charged:
   if(cc_pwm > 1.0)        cc_pwm = 1.0;
   else if(cc_pwm <= 0.0F) cc_pwm = 0.0;

   pwm = (u16) (cc_pwm * 65535.0);
   set_batt_pwm(pwm);

   if(cc_mode == CC_LIPO) {
      sprintf(plot_title, " LiPo Charge %.3fA to %.3fV: led_i=%.3fA  pwm=%f %04X %04X", cc_val,lipo_volts, led_i, cc_pwm,pwm,pwm>>6);
   }
   else if(cc_mode == CC_AMPS) {
      sprintf(plot_title, " CC Load %.3fA: led_i=%.3fA  pwm=%f %04X %04X", cc_val, led_i, cc_pwm,pwm,pwm>>6);
   }
   else if(cc_mode == CC_VOLTS) {
      sprintf(plot_title, " CV Load %.3fV: led_v=%.3fV  pwm=%f %04X %04X", cc_val, led_v, cc_pwm,pwm,pwm>>6);
   }
   else if(cc_mode == CC_WATTS) {
      sprintf(plot_title, " CW Load %.3fW: led_v=%.3fV  led_i=%.3fA  led_w=%.3fW  pwm=%f %04X %04X", cc_val, led_v, led_i, led_w, cc_pwm,pwm,pwm>>6);
   }
   else if(cc_mode == PWM_SWEEP) {
      sprintf(plot_title, " PWM sweep from %.3f to %.3f:  pwm=%f %04X %04X", sweep_start, sweep_end, cc_pwm,pwm,pwm>>6);
   }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
leaq 0x2909a4(%rip), %r14    # 0x30ce88
movzbl (%r14), %ecx
testl %ecx, %ecx
je 0x7c946
leaq 0x290992(%rip), %rdx    # 0x30ce89
movb (%rdx), %al
cmpb $0x4, %al
ja 0x7c501
incb %al
movb %al, (%rdx)
leaq 0x2909c8(%rip), %rax    # 0x30ced0
cmpl $0x0, (%rax)
jg 0x7c51d
leaq 0x2909c0(%rip), %rsi    # 0x30ced4
movl $0x1, %edi
movl %edi, (%rsi)
movl %edi, (%rax)
cmpb $0x1, (%rdx)
jne 0x7c54f
cmpl $0x3, %ecx
je 0x7c5d7
cmpl $0x5, %ecx
jne 0x7c5f3
leaq 0x290975(%rip), %rax    # 0x30ceb0
movsd (%rax), %xmm0
leaq 0x29097a(%rip), %rax    # 0x30cec0
movsd %xmm0, (%rax)
jmp 0x7c8a9
cmpl $0x3, %ecx
je 0x7c628
cmpl $0x5, %ecx
jne 0x7c759
leaq 0x290948(%rip), %rcx    # 0x30ceb0
movsd (%rcx), %xmm0
leaq 0x290945(%rip), %rbx    # 0x30ceb8
leaq 0x29095a(%rip), %rcx    # 0x30ced4
movl (%rcx), %edx
leal -0x1(%rdx), %esi
ucomisd (%rbx), %xmm0
movl %esi, (%rcx)
jbe 0x7c6aa
cmpl $0x1, %edx
jg 0x7c5bd
movl (%rax), %eax
movl %eax, (%rcx)
leaq 0x29087d(%rip), %rax    # 0x30ce18
leaq 0x29091e(%rip), %rcx    # 0x30cec0
movsd (%rcx), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, (%rcx)
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x7c5bd
callq 0x7c46b
leaq 0x2908fc(%rip), %rax    # 0x30cec0
movsd (%rbx), %xmm0
ucomisd (%rax), %xmm0
ja 0x7c6ed
jmp 0x7c6f2
leaq 0x2907f2(%rip), %rax    # 0x30cdd0
leaq 0x2908b3(%rip), %rcx    # 0x30ce98
movsd (%rcx), %xmm0
ucomisd (%rax), %xmm0
ja 0x7c863
movl $0x3c, 0x2f47e7(%rip)   # 0x370de4
leaq 0x2908c4(%rip), %rax    # 0x30cec8
movsd (%rax), %xmm1
xorpd %xmm0, %xmm0
ucomisd %xmm0, %xmm1
jne 0x7c8a9
jp 0x7c8a9
leaq 0x2907f5(%rip), %rax    # 0x30ce18
jmp 0x7c6f9
leaq 0x2907a1(%rip), %rdx    # 0x30cdd0
movsd (%rdx), %xmm0
leaq 0x290856(%rip), %rdx    # 0x30ce90
movsd (%rdx), %xmm1
movsd 0x8f382(%rip), %xmm2    # 0x10b9c8
addsd %xmm1, %xmm2
ucomisd %xmm2, %xmm0
jbe 0x7c759
movsd 0x8caac(%rip), %xmm2    # 0x109108
addsd %xmm1, %xmm2
ucomisd %xmm2, %xmm0
ja 0x7c863
leaq 0x290767(%rip), %rdx    # 0x30cdd8
movsd (%rdx), %xmm2
leaq 0x290824(%rip), %rdx    # 0x30cea0
movsd (%rdx), %xmm3
movapd %xmm3, %xmm4
divsd 0x8f4ac(%rip), %xmm4    # 0x10bb38
ucomisd %xmm2, %xmm4
jbe 0x7c702
movl 0x2f474c(%rip), %edx    # 0x370de4
leal -0x1(%rdx), %esi
movl %esi, 0x2f4743(%rip)    # 0x370de4
testl %edx, %edx
jg 0x7c70c
jmp 0x7c863
cmpl $0x1, %edx
jg 0x7c6dc
movl (%rax), %eax
movl %eax, (%rcx)
leaq 0x29075e(%rip), %rax    # 0x30ce18
movsd (%rax), %xmm0
leaq 0x2907fb(%rip), %rax    # 0x30cec0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
ucomisd 0x8c99b(%rip), %xmm0    # 0x109070
jbe 0x7c6dc
callq 0x7c46b
leaq 0x2907dd(%rip), %rax    # 0x30cec0
movsd (%rax), %xmm0
ucomisd (%rbx), %xmm0
jbe 0x7c6f2
callq 0x7c46b
leaq 0x2907c7(%rip), %rax    # 0x30cec0
movsd (%rax), %xmm0
jmp 0x7c8a9
movl $0x3c, 0x2f46d8(%rip)   # 0x370de4
ucomisd %xmm2, %xmm3
jbe 0x7c759
ucomisd %xmm1, %xmm0
jbe 0x7c8b4
leaq 0x290785(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm1
xorpd %xmm0, %xmm0
ucomisd %xmm0, %xmm1
jne 0x7c737
jnp 0x7c8b4
leaq 0x2906da(%rip), %rcx    # 0x30ce18
movsd (%rcx), %xmm0
subsd %xmm0, %xmm1
movsd %xmm1, (%rax)
ucomisd %xmm1, %xmm0
ja 0x7c8a9
jmp 0x7c8b4
cmpl $0x1, %ecx
jne 0x7c7b2
leaq 0x29066b(%rip), %rdx    # 0x30cdd0
movsd (%rdx), %xmm1
ucomisd 0xa1d2f(%rip), %xmm1    # 0x11e4a0
jbe 0x7c7b2
leaq 0x29074e(%rip), %rcx    # 0x30cec8
movsd (%rcx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jne 0x7c7e7
jp 0x7c7e7
leaq 0x29070f(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
divsd %xmm1, %xmm0
xorl %eax, %eax
ucomisd %xmm0, %xmm2
seta %al
leaq 0xa2253(%rip), %rcx     # 0x11ea00
jmp 0x7c891
cmpl $0x4, %ecx
jne 0x7c7ef
leaq 0x290682(%rip), %rdx    # 0x30ce40
movsd (%rdx), %xmm1
ucomisd 0xa1cd6(%rip), %xmm1    # 0x11e4a0
jbe 0x7c7ef
leaq 0x2906f5(%rip), %rcx    # 0x30cec8
movsd (%rcx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jne 0x7c7e7
jnp 0x7c86e
ucomisd %xmm0, %xmm1
jbe 0x7c828
jmp 0x7c863
leaq 0x2906d2(%rip), %rdx    # 0x30cec8
movsd (%rdx), %xmm0
cmpl $0x1, %ecx
je 0x7c818
leaq 0x2905d2(%rip), %rcx    # 0x30cdd8
movsd (%rcx), %xmm1
ucomisd 0xa1c8e(%rip), %xmm1    # 0x11e4a0
ja 0x7c77e
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x7c828
jnp 0x7ca68
leaq 0x2906a5(%rip), %rcx    # 0x30ced4
movl (%rcx), %edx
leal -0x1(%rdx), %esi
movl %esi, (%rcx)
cmpl $0x1, %edx
jg 0x7c8b4
movl (%rax), %eax
movl %eax, (%rcx)
leaq 0x2905d2(%rip), %rax    # 0x30ce18
movsd (%rax), %xmm0
leaq 0x290657(%rip), %rax    # 0x30cea8
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
ucomisd 0x8c80f(%rip), %xmm0    # 0x109070
jbe 0x7c8b4
callq 0x7c46b
xorpd %xmm0, %xmm0
jmp 0x7c8a9
leaq 0x29062b(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
divsd %xmm1, %xmm0
xorl %eax, %eax
ucomisd %xmm0, %xmm2
seta %al
leaq 0xa217f(%rip), %rcx     # 0x11ea10
mulsd (%rcx,%rax,8), %xmm0
leaq 0x29060b(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm1
mulsd %xmm1, %xmm0
addsd %xmm1, %xmm0
leaq 0x2905f8(%rip), %rax    # 0x30cea8
movsd %xmm0, (%rax)
leaq 0x2905ed(%rip), %r15    # 0x30cea8
movsd (%r15), %xmm1
movsd 0x8c7a8(%rip), %xmm0    # 0x109070
ucomisd %xmm0, %xmm1
ja 0x7c8d8
xorpd %xmm0, %xmm0
ucomisd %xmm1, %xmm0
jb 0x7c8dd
movsd %xmm0, (%r15)
movsd (%r15), %xmm0
mulsd 0x8f06e(%rip), %xmm0    # 0x10b958
cvttsd2si %xmm0, %eax
movzwl %ax, %ebx
movl %ebx, %edi
callq 0x7c3fc
movzbl (%r14), %eax
decl %eax
cmpl $0x4, %eax
ja 0x7c946
leaq 0xa258e(%rip), %rcx     # 0x11ee98
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x290586(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x2904ab(%rip), %rax    # 0x30cdd0
movsd (%rax), %xmm1
movsd (%r15), %xmm2
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c1f16(%rip), %rdi    # 0x33e850
leaq 0xa5ca3(%rip), %rsi     # 0x1225e4
jmp 0x7ca55
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x290558(%rip), %rax    # 0x30ceb0
movsd (%rax), %xmm0
leaq 0x290555(%rip), %rax    # 0x30ceb8
movsd (%rax), %xmm1
movsd (%r15), %xmm2
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c1ed8(%rip), %rdi    # 0x33e850
leaq 0xa5cdb(%rip), %rsi     # 0x12265a
jmp 0x7ca55
leaq 0x290515(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x2904fa(%rip), %rax    # 0x30ce90
movsd (%rax), %xmm1
leaq 0x290437(%rip), %rax    # 0x30cdd8
movsd (%rax), %xmm2
movsd (%r15), %xmm3
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c1e9a(%rip), %rdi    # 0x33e850
leaq 0xa5bbe(%rip), %rsi     # 0x12257b
movl %ebx, %edx
movb $0x4, %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9060
leaq 0x2904c9(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x2903ee(%rip), %rax    # 0x30cdd0
movsd (%rax), %xmm1
leaq 0x2903eb(%rip), %rax    # 0x30cdd8
movsd (%rax), %xmm2
leaq 0x290448(%rip), %rax    # 0x30ce40
movsd (%rax), %xmm3
movsd (%r15), %xmm4
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c1e43(%rip), %rdi    # 0x33e850
leaq 0xa5bfe(%rip), %rsi     # 0x122612
movl %ebx, %edx
movb $0x5, %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9060
leaq 0x290472(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x29039f(%rip), %rax    # 0x30cdd8
movsd (%rax), %xmm1
movsd (%r15), %xmm2
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c1e02(%rip), %rdi    # 0x33e850
leaq 0xa5b61(%rip), %rsi     # 0x1225b6
movl %ebx, %edx
movb $0x3, %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9060
leaq 0x2903a9(%rip), %rax    # 0x30ce18
movsd (%rax), %xmm0
leaq 0x29042e(%rip), %rax    # 0x30cea8
addsd (%rax), %xmm0
jmp 0x7c8a9