// File: /workspace/github_cpp_makefile_star2_O3/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 0x290be9(%rip), %r14    # 0x30ce88
movzbl (%r14), %ecx
testl %ecx, %ecx
je 0x7c6f1
leaq 0x290bd7(%rip), %rax    # 0x30ce89
movb (%rax), %dl
cmpb $0x4, %dl
ja 0x7c2c6
leal 0x1(%rdx), %esi
movb %sil, (%rax)
testb %dl, %dl
sete %dl
jmp 0x7c2c8
xorl %edx, %edx
leaq 0x290c01(%rip), %rsi    # 0x30ced0
movl (%rsi), %eax
testl %eax, %eax
jg 0x7c2e5
leaq 0x290bf8(%rip), %rdi    # 0x30ced4
movl $0x1, %eax
movl %eax, (%rdi)
movl %eax, (%rsi)
testb %dl, %dl
je 0x7c316
cmpl $0x3, %ecx
je 0x7c39f
cmpl $0x5, %ecx
jne 0x7c3bb
leaq 0x290bae(%rip), %rax    # 0x30ceb0
movsd (%rax), %xmm0
leaq 0x290bb3(%rip), %rax    # 0x30cec0
movsd %xmm0, (%rax)
jmp 0x7c4e9
cmpl $0x3, %ecx
je 0x7c3f4
cmpl $0x5, %ecx
jne 0x7c47e
leaq 0x290b81(%rip), %rcx    # 0x30ceb0
movsd (%rcx), %xmm1
leaq 0x290b7e(%rip), %r15    # 0x30ceb8
movsd (%r15), %xmm0
leaq 0x290b8e(%rip), %rcx    # 0x30ced4
movl (%rcx), %edx
ucomisd %xmm0, %xmm1
leal -0x1(%rdx), %esi
movl %esi, (%rcx)
leaq 0x290b68(%rip), %rbx    # 0x30cec0
movsd (%rbx), %xmm1
jbe 0x7c4ac
cmpl $0x1, %edx
jg 0x7c390
movl %eax, (%rcx)
leaq 0x290aa8(%rip), %rax    # 0x30ce18
subsd (%rax), %xmm1
movsd %xmm1, (%rbx)
xorpd %xmm2, %xmm2
ucomisd %xmm1, %xmm2
jbe 0x7c390
callq 0x7c226
movsd (%rbx), %xmm1
movsd (%r15), %xmm0
ucomisd %xmm1, %xmm0
ja 0x7c4e0
jmp 0x7c4e5
leaq 0x290a2a(%rip), %rax    # 0x30cdd0
leaq 0x290aeb(%rip), %rcx    # 0x30ce98
movsd (%rcx), %xmm0
ucomisd (%rax), %xmm0
ja 0x7c66f
movl $0x3c, 0x2f4a1f(%rip)   # 0x370de4
leaq 0x290afc(%rip), %rax    # 0x30cec8
movsd (%rax), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x7c678
jp 0x7c678
leaq 0x290a2d(%rip), %rax    # 0x30ce18
movsd (%rax), %xmm0
jmp 0x7c4e9
leaq 0x2909d5(%rip), %rdx    # 0x30cdd0
movsd (%rdx), %xmm0
leaq 0x290a8a(%rip), %rdx    # 0x30ce90
movsd (%rdx), %xmm1
movsd 0x8f5b6(%rip), %xmm2    # 0x10b9c8
addsd %xmm1, %xmm2
ucomisd %xmm2, %xmm0
jbe 0x7c5e1
movsd 0x8cce0(%rip), %xmm2    # 0x109108
addsd %xmm1, %xmm2
ucomisd %xmm2, %xmm0
ja 0x7c66f
leaq 0x29099b(%rip), %rdx    # 0x30cdd8
movsd (%rdx), %xmm2
leaq 0x290a58(%rip), %rdx    # 0x30cea0
movsd (%rdx), %xmm3
movapd %xmm3, %xmm4
divsd 0x8f6e8(%rip), %xmm4    # 0x10bb40
ucomisd %xmm2, %xmm4
jbe 0x7c582
movl 0x2f497c(%rip), %edx    # 0x370de4
leal -0x1(%rdx), %esi
movl %esi, 0x2f4973(%rip)    # 0x370de4
testl %edx, %edx
jg 0x7c58c
jmp 0x7c66f
cmpl $0x1, %ecx
jne 0x7c519
leaq 0x290942(%rip), %rdx    # 0x30cdd0
movsd (%rdx), %xmm1
ucomisd 0xa20a6(%rip), %xmm1    # 0x11e540
jbe 0x7c519
leaq 0x290a25(%rip), %rcx    # 0x30cec8
movsd (%rcx), %xmm0
jmp 0x7c606
cmpl $0x1, %edx
jg 0x7c4da
movl %eax, (%rcx)
leaq 0x29095e(%rip), %rax    # 0x30ce18
addsd (%rax), %xmm1
movsd %xmm1, (%rbx)
ucomisd 0x8cba6(%rip), %xmm1    # 0x109070
jbe 0x7c4da
callq 0x7c226
movsd (%rbx), %xmm1
movsd (%r15), %xmm0
ucomisd %xmm0, %xmm1
jbe 0x7c4e5
callq 0x7c226
movsd (%rbx), %xmm0
leaq 0x2909b8(%rip), %rax    # 0x30cea8
movsd %xmm0, (%rax)
movsd 0x8cb74(%rip), %xmm1    # 0x109070
ucomisd %xmm1, %xmm0
ja 0x7c678
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jae 0x7c678
jmp 0x7c687
cmpl $0x4, %ecx
jne 0x7c5e1
leaq 0x290917(%rip), %rdx    # 0x30ce40
movsd (%rdx), %xmm1
ucomisd 0xa200b(%rip), %xmm1    # 0x11e540
jbe 0x7c5e1
leaq 0x290986(%rip), %rcx    # 0x30cec8
movsd (%rcx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jne 0x7c616
jp 0x7c616
leaq 0x29093f(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
divsd %xmm1, %xmm0
xorl %eax, %eax
ucomisd %xmm0, %xmm2
seta %al
leaq 0xa2543(%rip), %rcx     # 0x11eac0
jmp 0x7c84e
movl $0x3c, 0x2f4858(%rip)   # 0x370de4
ucomisd %xmm2, %xmm3
jbe 0x7c5e1
ucomisd %xmm1, %xmm0
leaq 0x29090b(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm0
jbe 0x7c4f4
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x7c5b7
jnp 0x7c4f4
leaq 0x29085a(%rip), %rcx    # 0x30ce18
movsd (%rcx), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
ucomisd %xmm0, %xmm1
jbe 0x7c4f4
movsd %xmm1, (%rax)
movapd %xmm1, %xmm0
jmp 0x7c4f4
leaq 0x2908e0(%rip), %rdx    # 0x30cec8
movsd (%rdx), %xmm0
cmpl $0x1, %ecx
je 0x7c61e
leaq 0x2907e0(%rip), %rcx    # 0x30cdd8
movsd (%rcx), %xmm1
ucomisd 0xa1f3c(%rip), %xmm1    # 0x11e540
jbe 0x7c61e
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jne 0x7c616
jnp 0x7c82b
ucomisd %xmm0, %xmm1
jbe 0x7c62e
jmp 0x7c66f
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x7c62e
jnp 0x7c87b
leaq 0x29089f(%rip), %rcx    # 0x30ced4
movl (%rcx), %edx
leal -0x1(%rdx), %esi
movl %esi, (%rcx)
cmpl $0x1, %edx
jg 0x7c86b
movl %eax, (%rcx)
leaq 0x2907ca(%rip), %rax    # 0x30ce18
movsd (%rax), %xmm0
leaq 0x29084f(%rip), %rax    # 0x30cea8
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
ucomisd 0x8ca07(%rip), %xmm0    # 0x109070
jbe 0x7c4f4
callq 0x7c226
xorpd %xmm1, %xmm1
leaq 0x290829(%rip), %rax    # 0x30cea8
movsd %xmm1, (%rax)
movapd %xmm1, %xmm0
mulsd 0x8f2d1(%rip), %xmm0    # 0x10b960
cvttsd2si %xmm0, %eax
movzwl %ax, %ebx
movl %ebx, %edi
callq 0x7c189
movzbl (%r14), %eax
decl %eax
cmpl $0x4, %eax
ja 0x7c6f1
leaq 0xa28a9(%rip), %rcx     # 0x11ef58
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x2907e1(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x290706(%rip), %rax    # 0x30cdd0
movsd (%rax), %xmm1
leaq 0x2907d3(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm2
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c216b(%rip), %rdi    # 0x33e850
leaq 0xa5fd8(%rip), %rsi     # 0x1226c4
jmp 0x7c818
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2907ad(%rip), %rax    # 0x30ceb0
movsd (%rax), %xmm0
leaq 0x2907aa(%rip), %rax    # 0x30ceb8
movsd (%rax), %xmm1
leaq 0x29078f(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm2
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c2127(%rip), %rdi    # 0x33e850
leaq 0xa600a(%rip), %rsi     # 0x12273a
jmp 0x7c818
leaq 0x290764(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x290749(%rip), %rax    # 0x30ce90
movsd (%rax), %xmm1
leaq 0x290686(%rip), %rax    # 0x30cdd8
movsd (%rax), %xmm2
leaq 0x29074b(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm3
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c20e3(%rip), %rdi    # 0x33e850
leaq 0xa5ee7(%rip), %rsi     # 0x12265b
movl %ebx, %edx
movb $0x4, %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9060
leaq 0x290712(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x290637(%rip), %rax    # 0x30cdd0
movsd (%rax), %xmm1
leaq 0x290634(%rip), %rax    # 0x30cdd8
movsd (%rax), %xmm2
leaq 0x290691(%rip), %rax    # 0x30ce40
movsd (%rax), %xmm3
leaq 0x2906ee(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm4
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c2086(%rip), %rdi    # 0x33e850
leaq 0xa5f21(%rip), %rsi     # 0x1226f2
movl %ebx, %edx
movb $0x5, %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9060
leaq 0x2906b5(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
leaq 0x2905e2(%rip), %rax    # 0x30cdd8
movsd (%rax), %xmm1
leaq 0x2906a7(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm2
movl %ebx, %ecx
shrl $0x6, %ecx
leaq 0x2c203f(%rip), %rdi    # 0x33e850
leaq 0xa5e7e(%rip), %rsi     # 0x122696
movl %ebx, %edx
movb $0x3, %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x9060
leaq 0x29066e(%rip), %rax    # 0x30cea0
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
divsd %xmm1, %xmm0
xorl %eax, %eax
ucomisd %xmm0, %xmm2
seta %al
leaq 0xa2262(%rip), %rcx     # 0x11eab0
mulsd (%rcx,%rax,8), %xmm0
leaq 0x29064e(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm1
mulsd %xmm1, %xmm0
addsd %xmm1, %xmm0
jmp 0x7c4f0
leaq 0x290636(%rip), %rax    # 0x30cea8
movsd (%rax), %xmm0
jmp 0x7c4f4
leaq 0x290596(%rip), %rax    # 0x30ce18
movsd (%rax), %xmm0
leaq 0x29061b(%rip), %rax    # 0x30cea8
addsd (%rax), %xmm0
jmp 0x7c4f0