// File: lucaong[P]elixir_mlx90640/src/MLX90640_API.cpp
// Function: MLX90640_GetFrameData(unsigned char, unsigned short*)
int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData)
{
    uint16_t dataReady = 1;
    uint16_t controlRegister1;
    uint16_t statusRegister;
    int error = 1;
    uint8_t cnt = 0;

    // This gets the chip unstuck in cases in which otherwise data would never
    // come (status register bit 3 always stays at 0)
    /*
    error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);
    if(error == -1)
    {
      return error;
    }
    */
    // End patch
    
    dataReady = 0;
    while(dataReady == 0)
    {
        error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
        if(error != 0)
        {
            return error;
        }    
        dataReady = statusRegister & 0x0008;
    }       
        
    while(dataReady != 0 && cnt < 5)
    { 
        error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);
        if(error == -1)
        {
            return error;
        }
            
        error = MLX90640_I2CRead(slaveAddr, 0x0400, 832, frameData); 
        if(error != 0)
        {
            return error;
        }
                   
        error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
        if(error != 0)
        {
            return error;
        }    
        dataReady = statusRegister & 0x0008;
        cnt = cnt + 1;
    }
    
    if(cnt > 4)
    {
        return -8;
    }    
    
    error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
    frameData[832] = controlRegister1;
    frameData[833] = statusRegister & 0x0001;
    
    if(error != 0)
    {
        return error;
    }
    
    return frameData[833];    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %dil, %al
movb %al, -0x5(%rbp)
movq %rsi, -0x10(%rbp)
movw $0x1, -0x12(%rbp)
movl $0x1, -0x1c(%rbp)
movb $0x0, -0x1d(%rbp)
movw $0x0, -0x12(%rbp)
movzwl -0x12(%rbp), %eax
cmpl $0x0, %eax
jne 0x1e0a
movl $0x8000, %esi           # imm = 0x8000
movl $0x1, %edx
leaq -0x16(%rbp), %rcx
movzbl -0x5(%rbp), %edi
callq 0x5b10
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1dfd
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1f38
movzwl -0x16(%rbp), %eax
andl $0x8, %eax
movw %ax, -0x12(%rbp)
jmp 0x1dc9
jmp 0x1e0c
movzwl -0x12(%rbp), %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x1e(%rbp)
je 0x1e27
movzbl -0x1d(%rbp), %eax
cmpl $0x5, %eax
setl %al
movb %al, -0x1e(%rbp)
movb -0x1e(%rbp), %al
testb $0x1, %al
jne 0x1e33
jmp 0x1ecc
movl $0x8000, %esi           # imm = 0x8000
movl $0x30, %edx
movzbl -0x5(%rbp), %edi
callq 0x5ce0
movl %eax, -0x1c(%rbp)
cmpl $-0x1, -0x1c(%rbp)
jne 0x1e5a
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1f38
movb -0x5(%rbp), %al
movq -0x10(%rbp), %rcx
movl $0x400, %esi            # imm = 0x400
movl $0x340, %edx            # imm = 0x340
movzbl %al, %edi
callq 0x5b10
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1e87
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1f38
movl $0x8000, %esi           # imm = 0x8000
movl $0x1, %edx
leaq -0x16(%rbp), %rcx
movzbl -0x5(%rbp), %edi
callq 0x5b10
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1eb2
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1f38
movzwl -0x16(%rbp), %eax
andl $0x8, %eax
movw %ax, -0x12(%rbp)
movzbl -0x1d(%rbp), %eax
addl $0x1, %eax
movb %al, -0x1d(%rbp)
jmp 0x1e0c
movzbl -0x1d(%rbp), %eax
cmpl $0x4, %eax
jle 0x1ede
movl $0xfffffff8, -0x4(%rbp) # imm = 0xFFFFFFF8
jmp 0x1f38
movl $0x800d, %esi           # imm = 0x800D
movl $0x1, %edx
leaq -0x14(%rbp), %rcx
movzbl -0x5(%rbp), %edi
callq 0x5b10
movl %eax, -0x1c(%rbp)
movw -0x14(%rbp), %cx
movq -0x10(%rbp), %rax
movw %cx, 0x680(%rax)
movzwl -0x16(%rbp), %eax
andl $0x1, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x682(%rax)
cmpl $0x0, -0x1c(%rbp)
je 0x1f2a
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1f38
movq -0x10(%rbp), %rax
movzwl 0x682(%rax), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)