// File: /workspace/github_c_makefile_star2_O1/DrYerzinia[P]C_DigiMode/src/io/uart/UART.c
// Function: UART_open
int UART_open(UART *self, char *device_name, unsigned int baud_rate){

	self->fd = open(device_name, O_RDWR | O_NOCTTY);
	if(self->fd < 0){
		perror("Unable to open UART");
		return -1;
	}

	tcgetattr(self->fd, &(self->tio));

	self->tio.c_cflag = CS8 | CLOCAL | CREAD;
	self->tio.c_iflag = IGNPAR;
	self->tio.c_oflag = 0;
	self->tio.c_lflag = 0;

	/* Set baud rate
	 */
	speed_t standard_baud_rate = B0;
	switch(baud_rate){
		case 50:
			standard_baud_rate = B50;
			break;
		case 75:
			standard_baud_rate = B75;
			break;
		case 110:
			standard_baud_rate = B110;
			break;
		case 134:
			standard_baud_rate = B134;
			break;
		case 150:
			standard_baud_rate = B150;
			break;
		case 200:
			standard_baud_rate = B200;
			break;
		case 300:
			standard_baud_rate = B300;
			break;
		case 600:
			standard_baud_rate = B600;
			break;
		case 1200:
			standard_baud_rate = B1200;
			break;
		case 1800:
			standard_baud_rate = B1800;
			break;
		case 2400:
			standard_baud_rate = B2400;
			break;
		case 4800:
			standard_baud_rate = B4800;
			break;
		case 9600:
			standard_baud_rate = B9600;
			break;
		case 19200:
			standard_baud_rate = B19200;
			break;
		case 38400:
			standard_baud_rate = B38400;
			break;
		case 57600:
			standard_baud_rate = B57600;
			break;
		case 115200:
			standard_baud_rate = B115200;
			break;
		case 230400:
			standard_baud_rate = B230400;
			break;
	}

	if(standard_baud_rate == B38400){

		// Ensure 38400 is actually 38400
		struct serial_struct ss;
		ioctl(self->fd, TIOCGSERIAL, &ss);
		ss.flags &= ~ASYNC_SPD_MASK;
		ioctl(self->fd, TIOCSSERIAL, &ss);

	} else if(standard_baud_rate == B0){

		standard_baud_rate = B38400;

		struct serial_struct ss;

		ioctl(self->fd, TIOCGSERIAL, &ss);

		ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;

		ss.custom_divisor = ((float)(ss.baud_base + (baud_rate / 2)) / baud_rate) + 0.5;

		unsigned int actual_rate = ss.baud_base / ss.custom_divisor;

		fprintf(stderr, "Actual baud rate set to %d\n", actual_rate);
		fprintf(stderr, "Error of %f%%\n", fabs((float)(baud_rate - actual_rate) / ((float)(baud_rate + actual_rate) / 2.0F)) * 100.0F);

		ioctl(self->fd, TIOCSSERIAL, &ss);

	}

	cfsetispeed(&(self->tio), standard_baud_rate);
	cfsetispeed(&(self->tio), standard_baud_rate);

	/* Wait until there is at least 1 byte and
	 * have an indefinite timeout
	 */
	self->tio.c_cc[VMIN] = 1;
	self->tio.c_cc[VTIME] = 0;

	tcflush(self->fd, TCIFLUSH);
	tcsetattr(self->fd, TCSANOW, &(self->tio));

	return 0;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x50, %rsp
movl %edx, %ebp
movq %rdi, %rbx
xorl %r12d, %r12d
movq %rsi, %rdi
movl $0x102, %esi            # imm = 0x102
xorl %eax, %eax
callq 0x10e0
movl %eax, (%rbx)
testl %eax, %eax
js 0x1719
leaq 0x4(%rbx), %r14
movl %eax, %edi
movq %r14, %rsi
callq 0x10c0
movq $0x8b0, 0xc(%rbx)       # imm = 0x8B0
movq $0x4, 0x4(%rbx)
movb $0x1, %al
cmpl $0x707, %ebp            # imm = 0x707
jg 0x15de
cmpl $0x95, %ebp
jle 0x1627
cmpl $0x12b, %ebp            # imm = 0x12B
jle 0x16cf
cmpl $0x12c, %ebp            # imm = 0x12C
je 0x175f
cmpl $0x258, %ebp            # imm = 0x258
je 0x174f
movl $0x0, %r15d
cmpl $0x4b0, %ebp            # imm = 0x4B0
jne 0x1782
movl $0x9, %r15d
jmp 0x177d
cmpl $0x4aff, %ebp           # imm = 0x4AFF
jle 0x164f
cmpl $0xe0ff, %ebp           # imm = 0xE0FF
jle 0x16f8
cmpl $0xe100, %ebp           # imm = 0xE100
je 0x1767
cmpl $0x1c200, %ebp          # imm = 0x1C200
je 0x1757
movl $0x0, %r15d
cmpl $0x38400, %ebp          # imm = 0x38400
jne 0x1782
movl $0x1003, %r15d          # imm = 0x1003
jmp 0x177d
cmpl $0x6d, %ebp
jg 0x1680
cmpl $0x32, %ebp
je 0x172f
movl $0x0, %r15d
cmpl $0x4b, %ebp
jne 0x1782
movl $0x2, %r15d
jmp 0x177d
cmpl $0x12bf, %ebp           # imm = 0x12BF
jg 0x16a6
cmpl $0x708, %ebp            # imm = 0x708
je 0x1737
movl $0x0, %r15d
cmpl $0x960, %ebp            # imm = 0x960
jne 0x1782
movl $0xb, %r15d
jmp 0x177d
cmpl $0x6e, %ebp
je 0x173f
movl $0x0, %r15d
cmpl $0x86, %ebp
jne 0x1782
movl $0x4, %r15d
jmp 0x177d
cmpl $0x12c0, %ebp           # imm = 0x12C0
je 0x1747
movl $0x0, %r15d
cmpl $0x2580, %ebp           # imm = 0x2580
jne 0x1782
movl $0xd, %r15d
jmp 0x177d
cmpl $0x96, %ebp
je 0x176f
movl $0x0, %r15d
cmpl $0xc8, %ebp
jne 0x1782
movl $0x6, %r15d
jmp 0x177d
cmpl $0x4b00, %ebp           # imm = 0x4B00
je 0x1777
movl $0x0, %r15d
cmpl $0x9600, %ebp           # imm = 0x9600
jne 0x1782
movl $0xf, %r15d
movb $0x1, %r12b
jmp 0x1780
leaq 0xa10(%rip), %rdi       # 0x2130
callq 0x1100
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x17f5
movl $0x1, %r15d
jmp 0x177d
movl $0xa, %r15d
jmp 0x177d
movl $0x3, %r15d
jmp 0x177d
movl $0xc, %r15d
jmp 0x177d
movl $0x8, %r15d
jmp 0x177d
movl $0x1002, %r15d          # imm = 0x1002
jmp 0x177d
movl $0x7, %r15d
jmp 0x177d
movl $0x1001, %r15d          # imm = 0x1001
jmp 0x177d
movl $0x5, %r15d
jmp 0x177d
movl $0xe, %r15d
xorl %r12d, %r12d
xorl %eax, %eax
testb %r12b, %r12b
je 0x17be
movl (%rbx), %edi
leaq 0x8(%rsp), %r15
movl $0x541e, %esi           # imm = 0x541E
movq %r15, %rdx
xorl %eax, %eax
callq 0x1050
andl $0xffffefcf, 0x10(%r15) # imm = 0xFFFFEFCF
movl (%rbx), %edi
movl $0x541f, %esi           # imm = 0x541F
movq %r15, %rdx
xorl %eax, %eax
callq 0x1050
movl $0xf, %r15d
jmp 0x17c2
testb %al, %al
jne 0x1804
movq %r14, %rdi
movl %r15d, %esi
callq 0x10f0
movq %r14, %rdi
movl %r15d, %esi
callq 0x10f0
movw $0x100, 0x1a(%rbx)      # imm = 0x100
movl (%rbx), %edi
xorl %ebp, %ebp
xorl %esi, %esi
callq 0x1040
movl (%rbx), %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x10d0
movl %ebp, %eax
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movl %ebp, %esi
callq 0x11b6
jmp 0x17b6