// File: hollanderic[P]dp832/main.cpp
// Function: main
int main (int argc, char** argv) {
    int opt;
    int channel=1;
    double voltage=0.0;
    double current=0.0;
    bool state=false;
    bool setvoltage=false;
    bool setcurrent=false;
    bool setstate=false;
    bool extra = isExtraMode(argc, argv);

    const std::string psuDevicePath = getDevicePathArg(argc, argv);
    dp830 psu(psuDevicePath.c_str());

    while ((opt = getopt(argc, argv, kValidArgs.c_str())) != -1) {
        switch (opt) {
            case 'c':
                channel = atoi(optarg);
                if ((channel < 1) || (channel > 3)) {
                   fprintf(stderr, "Channel must be in range 1..3\n");
                   return -1;
                }
                break;
            case 'v':
                voltage = std::stod(optarg);
                psu.SetVoltage(channel,voltage);
                setvoltage=true;
                break;
            case 'i':
                current = std::stod(optarg);
                psu.SetCurrent(channel,current);
                setcurrent=true;
                break;
            case 't':
                current = std::stod(optarg);
                psu.SetOCP(channel,current);
                break;
            case 's':
                state = !(atoi(optarg) == 0);
                if (state)
                    psu.On(channel);
                else
                    psu.Off(channel);
                setstate=true;
                break;
            case 'b':
                psu.Bounce(channel,std::stod(optarg));
                break;
            case 'r':
            case 'm': {
                if (extra) {
                  int reps = 1;
                  int tt = 0;
		  if (opt == 'r') {
                     tt = std::stod(optarg);
                     reps = 1000/tt;
                  }
                  for (int i = 0; i < reps; i++) {
                    auto now = (duration_cast<milliseconds>(system_clock::now().time_since_epoch())).count();
                    printf("t=%lu,c=%d,s=%d,vs=%0.03f,is=%0.03f,ocp=%0.03f,v=%0.03f,i=%0.03f,p=%0.03f,tr=%d\n", 
                      now,
                      channel,
                      psu.GetState(channel),
                      psu.GetVoltageSetPoint(channel),
                      psu.GetCurrentSetPoint(channel),
                      psu.GetOCP(channel),
                      psu.MeasureVoltage(channel),
                      psu.MeasureCurrent(channel),
                      psu.MeasurePower(channel),
                      psu.GetOCPTripped(channel));
                    auto delta = (duration_cast<milliseconds>(system_clock::now().time_since_epoch())).count() - now;
                    if ((tt > delta)) {
                      usleep(1000*(tt-delta));
                    }
                  }
                } else { 
                    fprintf(stderr, "Can't use -m in legacy mode, add -x flag\n");
                }
                break;
            }
            case 'w': // ms delay
                if (extra) {
                    usleep(1000*std::stod(optarg));
                } else { 
                    fprintf(stderr, "Can't use -w in legacy mode, add -x flag\n");
                }
                break;
            default:
                break;
        }
    }

    if (!extra) {
      usleep(1*1e6);

      printf("Voltage = %f\n",psu.MeasureVoltage(channel));
      printf("Current = %f\n",psu.MeasureCurrent(channel));
      printf("Power   = %f\n",psu.MeasurePower(channel));
      printf("Volt sp   = %f\n",psu.GetVoltageSetPoint(channel));
      printf("Curr sp   = %f\n",psu.GetCurrentSetPoint(channel));
    }
    //Test Bounce feature - used to bounce a target
    //usleep(3*1e6);
    //psu.Bounce(1,2.5);

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x500, %rsp            # imm = 0x500
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x1, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
movb $0x0, -0x2a(%rbp)
movb $0x0, -0x2b(%rbp)
movb $0x0, -0x2c(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x36b0
movb %al, -0x2d(%rbp)
movl -0x8(%rbp), %esi
movq -0x10(%rbp), %rdx
leaq -0x50(%rbp), %rdi
movq %rdi, -0x3b0(%rbp)
callq 0x3580
movq -0x3b0(%rbp), %rdi
callq 0x20d0
movq %rax, %rsi
leaq -0x260(%rbp), %rdi
callq 0x25a0
jmp 0x37a3
jmp 0x37a5
movl -0x8(%rbp), %eax
movl %eax, -0x3bc(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x3b8(%rbp)
leaq 0x49f0(%rip), %rdi      # 0x81b0
callq 0x20d0
movl -0x3bc(%rbp), %edi
movq -0x3b8(%rbp), %rsi
movq %rax, %rdx
callq 0x2090
movl %eax, -0x14(%rbp)
cmpl $-0x1, %eax
je 0x410b
movl -0x14(%rbp), %eax
addl $-0x62, %eax
movl %eax, %ecx
movq %rcx, -0x3c8(%rbp)
subl $0x15, %eax
ja 0x4104
movq -0x3c8(%rbp), %rax
leaq 0x197c(%rip), %rcx      # 0x5188
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x4256
movq 0x477d(%rip), %rax      # 0x7fb0
movq (%rax), %rdi
callq 0x2290
movl %eax, -0x18(%rbp)
cmpl $0x1, -0x18(%rbp)
jl 0x384a
cmpl $0x3, -0x18(%rbp)
jle 0x3878
movq 0x477f(%rip), %rax      # 0x7fd0
movq (%rax), %rdi
leaq 0x19a7(%rip), %rsi      # 0x5202
movb $0x0, %al
callq 0x2250
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x270(%rbp)
jmp 0x4229
jmp 0x4106
movq 0x472c(%rip), %rax      # 0x7fb0
movq (%rax), %rax
movq %rax, -0x3d8(%rbp)
leaq -0x291(%rbp), %rdi
movq %rdi, -0x3d0(%rbp)
callq 0x22d0
movq -0x3d8(%rbp), %rsi
movq -0x3d0(%rbp), %rdx
leaq -0x290(%rbp), %rdi
callq 0x30b0
jmp 0x38bd
xorl %eax, %eax
movl %eax, %esi
leaq -0x290(%rbp), %rdi
callq 0x3070
movsd %xmm0, -0x3e0(%rbp)
jmp 0x38d7
movsd -0x3e0(%rbp), %xmm0
movsd %xmm0, -0x20(%rbp)
leaq -0x290(%rbp), %rdi
callq 0x2318
leaq -0x291(%rbp), %rdi
callq 0x21b0
movl -0x18(%rbp), %esi
movsd -0x20(%rbp), %xmm0
leaq -0x260(%rbp), %rdi
callq 0x29e0
jmp 0x3912
movb $0x1, -0x2a(%rbp)
jmp 0x4106
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x394d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x290(%rbp), %rdi
callq 0x2318
leaq -0x291(%rbp), %rdi
callq 0x21b0
jmp 0x424a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x424a
movq 0x4634(%rip), %rax      # 0x7fb0
movq (%rax), %rax
movq %rax, -0x3f0(%rbp)
leaq -0x2b9(%rbp), %rdi
movq %rdi, -0x3e8(%rbp)
callq 0x22d0
movq -0x3f0(%rbp), %rsi
movq -0x3e8(%rbp), %rdx
leaq -0x2b8(%rbp), %rdi
callq 0x30b0
jmp 0x39b5
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
callq 0x3070
movsd %xmm0, -0x3f8(%rbp)
jmp 0x39cf
movsd -0x3f8(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x2318
leaq -0x2b9(%rbp), %rdi
callq 0x21b0
movl -0x18(%rbp), %esi
movsd -0x28(%rbp), %xmm0
leaq -0x260(%rbp), %rdi
callq 0x2a20
jmp 0x3a0a
movb $0x1, -0x2b(%rbp)
jmp 0x4106
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3a45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x2318
leaq -0x2b9(%rbp), %rdi
callq 0x21b0
jmp 0x424a
movq 0x4553(%rip), %rax      # 0x7fb0
movq (%rax), %rax
movq %rax, -0x408(%rbp)
leaq -0x2e1(%rbp), %rdi
movq %rdi, -0x400(%rbp)
callq 0x22d0
movq -0x408(%rbp), %rsi
movq -0x400(%rbp), %rdx
leaq -0x2e0(%rbp), %rdi
callq 0x30b0
jmp 0x3a96
xorl %eax, %eax
movl %eax, %esi
leaq -0x2e0(%rbp), %rdi
callq 0x3070
movsd %xmm0, -0x410(%rbp)
jmp 0x3ab0
movsd -0x410(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
leaq -0x2e0(%rbp), %rdi
callq 0x2318
leaq -0x2e1(%rbp), %rdi
callq 0x21b0
movl -0x18(%rbp), %esi
movsd -0x28(%rbp), %xmm0
leaq -0x260(%rbp), %rdi
callq 0x2a60
jmp 0x3aeb
jmp 0x4106
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3b22
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x2e0(%rbp), %rdi
callq 0x2318
leaq -0x2e1(%rbp), %rdi
callq 0x21b0
jmp 0x424a
movq 0x4476(%rip), %rax      # 0x7fb0
movq (%rax), %rdi
callq 0x2290
cmpl $0x0, %eax
sete %al
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
je 0x3b68
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2820
jmp 0x3b66
jmp 0x3b7b
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x28e0
jmp 0x3b79
jmp 0x3b7b
movb $0x1, -0x2c(%rbp)
jmp 0x4106
movl -0x18(%rbp), %eax
movl %eax, -0x424(%rbp)
movq 0x441c(%rip), %rax      # 0x7fb0
movq (%rax), %rax
movq %rax, -0x420(%rbp)
leaq -0x309(%rbp), %rdi
movq %rdi, -0x418(%rbp)
callq 0x22d0
movq -0x420(%rbp), %rsi
movq -0x418(%rbp), %rdx
leaq -0x308(%rbp), %rdi
callq 0x30b0
jmp 0x3bcd
xorl %eax, %eax
movl %eax, %esi
leaq -0x308(%rbp), %rdi
callq 0x3070
movsd %xmm0, -0x430(%rbp)
jmp 0x3be7
movsd -0x430(%rbp), %xmm0
movl -0x424(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2fd0
jmp 0x3c03
leaq -0x308(%rbp), %rdi
callq 0x2318
leaq -0x309(%rbp), %rdi
callq 0x21b0
jmp 0x4106
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3c52
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x308(%rbp), %rdi
callq 0x2318
leaq -0x309(%rbp), %rdi
callq 0x21b0
jmp 0x424a
testb $0x1, -0x2d(%rbp)
je 0x3fea
movl $0x1, -0x310(%rbp)
movl $0x0, -0x314(%rbp)
cmpl $0x72, -0x14(%rbp)
jne 0x3d66
movq 0x431e(%rip), %rax      # 0x7fb0
movq (%rax), %rax
movq %rax, -0x440(%rbp)
leaq -0x339(%rbp), %rdi
movq %rdi, -0x438(%rbp)
callq 0x22d0
movq -0x440(%rbp), %rsi
movq -0x438(%rbp), %rdx
leaq -0x338(%rbp), %rdi
callq 0x30b0
jmp 0x3ccb
xorl %eax, %eax
movl %eax, %esi
leaq -0x338(%rbp), %rdi
callq 0x3070
movsd %xmm0, -0x448(%rbp)
jmp 0x3ce5
movsd -0x448(%rbp), %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x314(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x2318
leaq -0x339(%rbp), %rdi
callq 0x21b0
movl $0x3e8, %eax            # imm = 0x3E8
cltd
idivl -0x314(%rbp)
movl %eax, -0x310(%rbp)
jmp 0x3d66
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3d55
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x2318
leaq -0x339(%rbp), %rdi
callq 0x21b0
jmp 0x424a
movl $0x0, -0x340(%rbp)
movl -0x340(%rbp), %eax
cmpl -0x310(%rbp), %eax
jge 0x3fe8
callq 0x2050
movq %rax, -0x360(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x42a0
movq %rax, -0x450(%rbp)
jmp 0x3da3
movq -0x450(%rbp), %rax
movq %rax, -0x358(%rbp)
leaq -0x358(%rbp), %rdi
callq 0x4270
movq %rax, -0x458(%rbp)
jmp 0x3dc6
movq -0x458(%rbp), %rax
movq %rax, -0x350(%rbp)
leaq -0x350(%rbp), %rdi
callq 0x42c0
movq %rax, -0x460(%rbp)
jmp 0x3de9
movq -0x460(%rbp), %rax
movq %rax, -0x348(%rbp)
movq -0x348(%rbp), %rax
movq %rax, -0x470(%rbp)
movl -0x18(%rbp), %esi
movl %esi, -0x468(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x27a0
movl %eax, -0x464(%rbp)
jmp 0x3e22
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2da0
movsd %xmm0, -0x478(%rbp)
jmp 0x3e3b
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2dd0
movsd %xmm0, -0x480(%rbp)
jmp 0x3e54
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2ae0
movsd %xmm0, -0x488(%rbp)
jmp 0x3e6d
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2f40
movsd %xmm0, -0x490(%rbp)
jmp 0x3e86
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2f70
movsd %xmm0, -0x498(%rbp)
jmp 0x3e9f
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2fa0
movsd %xmm0, -0x4a0(%rbp)
jmp 0x3eb8
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2be0
movl %eax, -0x4a4(%rbp)
jmp 0x3ecf
movl -0x4a4(%rbp), %r8d
movsd -0x4a0(%rbp), %xmm5
movsd -0x498(%rbp), %xmm4
movsd -0x490(%rbp), %xmm3
movsd -0x488(%rbp), %xmm2
movsd -0x480(%rbp), %xmm1
movsd -0x478(%rbp), %xmm0
movl -0x464(%rbp), %ecx
movl -0x468(%rbp), %edx
movq -0x470(%rbp), %rsi
leaq 0x1301(%rip), %rdi      # 0x5221
movb $0x6, %al
callq 0x2040
jmp 0x3f29
callq 0x2050
movq %rax, -0x380(%rbp)
leaq -0x380(%rbp), %rdi
callq 0x42a0
movq %rax, -0x4b0(%rbp)
jmp 0x3f4a
movq -0x4b0(%rbp), %rax
movq %rax, -0x378(%rbp)
leaq -0x378(%rbp), %rdi
callq 0x4270
movq %rax, -0x4b8(%rbp)
jmp 0x3f6d
movq -0x4b8(%rbp), %rax
movq %rax, -0x370(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x42c0
movq %rax, -0x4c0(%rbp)
jmp 0x3f90
movq -0x4c0(%rbp), %rax
subq -0x348(%rbp), %rax
movq %rax, -0x368(%rbp)
movslq -0x314(%rbp), %rax
cmpq -0x368(%rbp), %rax
jle 0x3fd2
movl -0x314(%rbp), %eax
movl -0x368(%rbp), %ecx
subl %ecx, %eax
imull $0x3e8, %eax, %edi      # imm = 0x3E8
callq 0x2240
jmp 0x3fd0
jmp 0x3fd2
jmp 0x3fd4
movl -0x340(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x340(%rbp)
jmp 0x3d70
jmp 0x4002
movq 0x3fdf(%rip), %rax      # 0x7fd0
movq (%rax), %rdi
leaq 0x1277(%rip), %rsi      # 0x5272
movb $0x0, %al
callq 0x2250
jmp 0x4106
testb $0x1, -0x2d(%rbp)
je 0x40ea
movq 0x3f98(%rip), %rax      # 0x7fb0
movq (%rax), %rax
movq %rax, -0x4d0(%rbp)
leaq -0x3a1(%rbp), %rdi
movq %rdi, -0x4c8(%rbp)
callq 0x22d0
movq -0x4d0(%rbp), %rsi
movq -0x4c8(%rbp), %rdx
leaq -0x3a0(%rbp), %rdi
callq 0x30b0
jmp 0x4051
xorl %eax, %eax
movl %eax, %esi
leaq -0x3a0(%rbp), %rdi
callq 0x3070
movsd %xmm0, -0x4d8(%rbp)
jmp 0x406b
movsd -0x4d8(%rbp), %xmm0
movsd 0x1105(%rip), %xmm1     # 0x5180
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, %edi
callq 0x2240
jmp 0x408d
leaq -0x3a0(%rbp), %rdi
callq 0x2318
leaq -0x3a1(%rbp), %rdi
callq 0x21b0
jmp 0x4102
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x40d9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x3a0(%rbp), %rdi
callq 0x2318
leaq -0x3a1(%rbp), %rdi
callq 0x21b0
jmp 0x424a
movq 0x3edf(%rip), %rax      # 0x7fd0
movq (%rax), %rdi
leaq 0x11a1(%rip), %rsi      # 0x529c
movb $0x0, %al
callq 0x2250
jmp 0x4106
jmp 0x4106
jmp 0x37a5
testb $0x1, -0x2d(%rbp)
jne 0x4218
movl $0xf4240, %edi          # imm = 0xF4240
callq 0x2240
jmp 0x4121
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2f40
movsd %xmm0, -0x4e0(%rbp)
jmp 0x413a
movsd -0x4e0(%rbp), %xmm0
leaq 0x117d(%rip), %rdi      # 0x52c6
movb $0x1, %al
callq 0x2040
jmp 0x4152
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2f70
movsd %xmm0, -0x4e8(%rbp)
jmp 0x416b
movsd -0x4e8(%rbp), %xmm0
leaq 0x115a(%rip), %rdi      # 0x52d4
movb $0x1, %al
callq 0x2040
jmp 0x4183
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2fa0
movsd %xmm0, -0x4f0(%rbp)
jmp 0x419c
movsd -0x4f0(%rbp), %xmm0
leaq 0x1137(%rip), %rdi      # 0x52e2
movb $0x1, %al
callq 0x2040
jmp 0x41b4
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2da0
movsd %xmm0, -0x4f8(%rbp)
jmp 0x41cd
movsd -0x4f8(%rbp), %xmm0
leaq 0x1114(%rip), %rdi      # 0x52f0
movb $0x1, %al
callq 0x2040
jmp 0x41e5
movl -0x18(%rbp), %esi
leaq -0x260(%rbp), %rdi
callq 0x2dd0
movsd %xmm0, -0x500(%rbp)
jmp 0x41fe
movsd -0x500(%rbp), %xmm0
leaq 0x10f3(%rip), %rdi      # 0x5300
movb $0x1, %al
callq 0x2040
jmp 0x4216
jmp 0x4218
movl $0x0, -0x4(%rbp)
movl $0x1, -0x270(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x2630
leaq -0x50(%rbp), %rdi
callq 0x2318
movl -0x4(%rbp), %eax
addq $0x500, %rsp            # imm = 0x500
popq %rbp
retq
leaq -0x260(%rbp), %rdi
callq 0x2630
leaq -0x50(%rbp), %rdi
callq 0x2318
movq -0x268(%rbp), %rdi
callq 0x22c0
nopl (%rax,%rax)