// File: /workspace/github_c_makefile_star2_O3/koendv[P]stm32duino-raspberrypi/Arduino_Tools/src/stm32flash/stm32.c
// Function: stm32_init
stm32_t *stm32_init(struct port_interface *port, const char init)
{
	uint8_t len, val, buf[257];
	stm32_t *stm;
	int i, new_cmds;

	stm      = calloc(sizeof(stm32_t), 1);
	stm->cmd = malloc(sizeof(stm32_cmd_t));
	memset(stm->cmd, STM32_CMD_ERR, sizeof(stm32_cmd_t));
	stm->port = port;

	if ((port->flags & PORT_CMD_INIT) && init)
		if (stm32_send_init_seq(stm) != STM32_ERR_OK)
			return NULL;

	/* get the version and read protection status  */
	if (stm32_send_command(stm, STM32_CMD_GVR) != STM32_ERR_OK) {
		stm32_close(stm);
		return NULL;
	}

	/* From AN, only UART bootloader returns 3 bytes */
	len = (port->flags & PORT_GVR_ETX) ? 3 : 1;
	if (port->read(port, buf, len) != PORT_ERR_OK)
		return NULL;
	stm->version = buf[0];
	stm->option1 = (port->flags & PORT_GVR_ETX) ? buf[1] : 0;
	stm->option2 = (port->flags & PORT_GVR_ETX) ? buf[2] : 0;
	if (stm32_get_ack(stm) != STM32_ERR_OK) {
		stm32_close(stm);
		return NULL;
	}

	/* get the bootloader information */
	len = STM32_CMD_GET_LENGTH;
	if (port->cmd_get_reply)
		for (i = 0; port->cmd_get_reply[i].length; i++)
			if (stm->version == port->cmd_get_reply[i].version) {
				len = port->cmd_get_reply[i].length;
				break;
			}
	if (stm32_guess_len_cmd(stm, STM32_CMD_GET, buf, len) != STM32_ERR_OK)
		return NULL;
	len = buf[0] + 1;
	stm->bl_version = buf[1];
	new_cmds = 0;
	for (i = 1; i < len; i++) {
		val = buf[i + 1];
		switch (val) {
		case STM32_CMD_GET:
			stm->cmd->get = val; break;
		case STM32_CMD_GVR:
			stm->cmd->gvr = val; break;
		case STM32_CMD_GID:
			stm->cmd->gid = val; break;
		case STM32_CMD_RM:
			stm->cmd->rm = val; break;
		case STM32_CMD_GO:
			stm->cmd->go = val; break;
		case STM32_CMD_WM:
		case STM32_CMD_WM_NS:
			stm->cmd->wm = newer(stm->cmd->wm, val);
			break;
		case STM32_CMD_ER:
		case STM32_CMD_EE:
		case STM32_CMD_EE_NS:
			stm->cmd->er = newer(stm->cmd->er, val);
			break;
		case STM32_CMD_WP:
		case STM32_CMD_WP_NS:
			stm->cmd->wp = newer(stm->cmd->wp, val);
			break;
		case STM32_CMD_UW:
		case STM32_CMD_UW_NS:
			stm->cmd->uw = newer(stm->cmd->uw, val);
			break;
		case STM32_CMD_RP:
		case STM32_CMD_RP_NS:
			stm->cmd->rp = newer(stm->cmd->rp, val);
			break;
		case STM32_CMD_UR:
		case STM32_CMD_UR_NS:
			stm->cmd->ur = newer(stm->cmd->ur, val);
			break;
		case STM32_CMD_CRC:
			stm->cmd->crc = newer(stm->cmd->crc, val);
			break;
		default:
			if (new_cmds++ == 0)
				fprintf(stderr,
					"GET returns unknown commands (0x%2x",
					val);
			else
				fprintf(stderr, ", 0x%2x", val);
		}
	}
	if (new_cmds)
		fprintf(stderr, ")\n");
	if (stm32_get_ack(stm) != STM32_ERR_OK) {
		stm32_close(stm);
		return NULL;
	}

	if (stm->cmd->get == STM32_CMD_ERR
	    || stm->cmd->gvr == STM32_CMD_ERR
	    || stm->cmd->gid == STM32_CMD_ERR) {
		fprintf(stderr, "Error: bootloader did not returned correct information from GET command\n");
		return NULL;
	}

	/* get the device ID */
	if (stm32_guess_len_cmd(stm, stm->cmd->gid, buf, 1) != STM32_ERR_OK) {
		stm32_close(stm);
		return NULL;
	}
	len = buf[0] + 1;
	if (len < 2) {
		stm32_close(stm);
		fprintf(stderr, "Only %d bytes sent in the PID, unknown/unsupported device\n", len);
		return NULL;
	}
	stm->pid = (buf[1] << 8) | buf[2];
	if (len > 2) {
		fprintf(stderr, "This bootloader returns %d extra bytes in PID:", len);
		for (i = 2; i <= len ; i++)
			fprintf(stderr, " %02x", buf[i]);
		fprintf(stderr, "\n");
	}
	if (stm32_get_ack(stm) != STM32_ERR_OK) {
		stm32_close(stm);
		return NULL;
	}

	stm->dev = devices;
	while (stm->dev->id != 0x00 && stm->dev->id != stm->pid)
		++stm->dev;

	if (!stm->dev->id) {
		fprintf(stderr, "Unknown/unsupported device (Device ID: 0x%03x)\n", stm->pid);
		stm32_close(stm);
		return NULL;
	}

	return stm;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %esi, %ebp
movq %rdi, %r14
movl $0x28, %edi
movl $0x1, %esi
callq 0x2150
movq %rax, %rbx
movl $0xc, %edi
callq 0x21c0
movq %rax, 0x18(%rbx)
movq $-0x1, (%rax)
movl $0xffffffff, 0x8(%rax)  # imm = 0xFFFFFFFF
movq %r14, 0x8(%rbx)
testb %bpl, %bpl
je 0x56ee
movl 0x8(%r14), %eax
andl $0x4, %eax
je 0x56ee
leaq 0xf(%rsp), %rsi
movb $0x7f, (%rsi)
movl $0x1, %edx
movq %r14, %rdi
callq *0x30(%r14)
testl %eax, %eax
jne 0x5a50
leaq 0x10(%rsp), %r15
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rsi
callq *0x28(%r14)
testl %eax, %eax
sete %dl
movb (%r15), %cl
cmpb $0x79, %cl
sete %sil
testb %sil, %dl
jne 0x56ee
testl %eax, %eax
sete %dl
cmpb $0x1f, %cl
sete %cl
andb %dl, %cl
cmpb $0x1, %cl
je 0x5a5a
cmpl $0x2, %eax
jne 0x5a64
leaq 0xf(%rsp), %rsi
movl $0x1, %edx
movq %r14, %rdi
callq *0x30(%r14)
testl %eax, %eax
jne 0x5a6e
leaq 0x10(%rsp), %rsi
movl $0x1, %edx
movq %r14, %rdi
callq *0x28(%r14)
testl %eax, %eax
jne 0x5a78
cmpb $0x1f, 0x10(%rsp)
jne 0x5a78
movq %rbx, %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x7373
testl %eax, %eax
je 0x570b
movq %rbx, %rdi
callq 0x5bbc
jmp 0x5725
movl 0x8(%r14), %edx
andl $0x2, %edx
incq %rdx
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq *0x28(%r14)
testl %eax, %eax
je 0x573c
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb 0x10(%rsp), %al
movb %al, 0x11(%rbx)
movl 0x8(%r14), %eax
andl $0x2, %eax
movzbl 0x11(%rsp), %ecx
cmovel %eax, %ecx
movb %cl, 0x12(%rbx)
movzbl 0x12(%rsp), %ecx
cmovel %eax, %ecx
movb %cl, 0x13(%rbx)
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0x6230
testl %eax, %eax
jne 0x5701
movq 0x48(%r14), %rax
movl $0x11, %ecx
testq %rax, %rax
je 0x57a9
movb 0x1(%rax), %sil
testb %sil, %sil
je 0x57a9
movb 0x11(%rbx), %dl
cmpb (%rax), %dl
je 0x57a5
addq $0x3, %rax
movb (%rax), %sil
testb %sil, %sil
je 0x57a9
leaq 0x2(%rax), %rdi
cmpb -0x1(%rax), %dl
movq %rdi, %rax
jne 0x5791
movzbl %sil, %ecx
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x5bd7
testl %eax, %eax
jne 0x5725
movb 0x10(%rsp), %al
movb 0x11(%rsp), %cl
incb %al
movb %cl, 0x10(%rbx)
cmpb $0x2, %al
jb 0x5a8a
movzbl %al, %r12d
movl $0x2, %r13d
movq 0x8812(%rip), %rdi      # 0xdff8
leaq 0x4323(%rip), %rsi      # 0x9b10
leaq 0x4340(%rip), %r9       # 0x9b34
movl $0x7, %r14d
movabsq $0x300000000, %r15      # imm = 0x300000000
movabsq $0x3000000000000, %r10  # imm = 0x3000000000000
movl $0xa1, %r11d
xorl %ebp, %ebp
movzbl 0x10(%rsp,%r13), %edx
cmpl $0x42, %edx
jle 0x5874
cmpl $0x81, %edx
jg 0x58a0
leal -0x43(%rdx), %eax
cmpl $0x31, %eax
ja 0x59ce
btq %rax, %r14
jb 0x5902
btq %rax, %r15
jb 0x5941
btq %rax, %r10
jae 0x59ce
movq 0x18(%rbx), %rax
movzbl 0x8(%rax), %ecx
cmpb %dl, %cl
movl %ecx, %r8d
cmovbel %edx, %r8d
cmpb $-0x1, %cl
cmovel %edx, %r8d
movb %r8b, 0x8(%rax)
jmp 0x59bd
cmpl $0x10, %edx
jg 0x58db
testl %edx, %edx
je 0x597d
cmpl $0x1, %edx
je 0x5986
cmpl $0x2, %edx
jne 0x59ce
movq 0x18(%rbx), %rax
movb $0x2, 0x2(%rax)
jmp 0x59bd
leal -0x82(%rdx), %eax
cmpl $0x2, %eax
jb 0x5923
leal -0x92(%rdx), %eax
cmpl $0x2, %eax
jae 0x5990
movq 0x18(%rbx), %rax
movzbl 0xa(%rax), %ecx
cmpb %dl, %cl
movl %ecx, %r8d
cmovbel %edx, %r8d
cmpb $-0x1, %cl
cmovel %edx, %r8d
movb %r8b, 0xa(%rax)
jmp 0x59bd
leal -0x31(%rdx), %eax
cmpl $0x2, %eax
jb 0x595f
cmpl $0x11, %edx
je 0x59b5
cmpl $0x21, %edx
jne 0x59ce
movq 0x18(%rbx), %rax
movb $0x21, 0x4(%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movzbl 0x6(%rax), %ecx
cmpb %dl, %cl
movl %ecx, %r8d
cmovbel %edx, %r8d
cmpb $-0x1, %cl
cmovel %edx, %r8d
movb %r8b, 0x6(%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movzbl 0x9(%rax), %ecx
cmpb %dl, %cl
movl %ecx, %r8d
cmovbel %edx, %r8d
cmpb $-0x1, %cl
cmovel %edx, %r8d
movb %r8b, 0x9(%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movzbl 0x7(%rax), %ecx
cmpb %dl, %cl
movl %ecx, %r8d
cmovbel %edx, %r8d
cmpb $-0x1, %cl
cmovel %edx, %r8d
movb %r8b, 0x7(%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movzbl 0x5(%rax), %ecx
cmpb %dl, %cl
movl %ecx, %r8d
cmovbel %edx, %r8d
cmpb $-0x1, %cl
cmovel %edx, %r8d
movb %r8b, 0x5(%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movb $0x0, (%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movb $0x1, 0x1(%rax)
jmp 0x59bd
cmpl $0xa1, %edx
jne 0x59ce
movq 0x18(%rbx), %rax
movzbl 0xb(%rax), %ecx
cmpb $-0x5e, %cl
movl %ecx, %edx
cmovbl %r11d, %edx
cmpb $-0x1, %cl
cmovel %r11d, %edx
movb %dl, 0xb(%rax)
jmp 0x59bd
movq 0x18(%rbx), %rax
movb $0x11, 0x3(%rax)
cmpq %r13, %r12
je 0x5a82
incq %r13
jmp 0x5816
testl %ebp, %ebp
je 0x5a0f
incl %ebp
movq 0x861d(%rip), %rax      # 0xdff8
movq (%rax), %rdi
movq %r9, %rsi
xorl %eax, %eax
callq 0x2170
leaq 0x4145(%rip), %r9       # 0x9b34
leaq 0x411a(%rip), %rsi      # 0x9b10
movq 0x85fb(%rip), %rdi      # 0xdff8
movabsq $0x3000000000000, %r10  # imm = 0x3000000000000
movl $0xa1, %r11d
jmp 0x59bd
movq %rdi, %rbp
movq (%rdi), %rdi
xorl %eax, %eax
callq 0x2170
leaq 0x4111(%rip), %r9       # 0x9b34
leaq 0x40e6(%rip), %rsi      # 0x9b10
movq %rbp, %rdi
movl $0x1, %ebp
cmpq %r13, %r12
movabsq $0x3000000000000, %r10  # imm = 0x3000000000000
movl $0xa1, %r11d
jne 0x59c6
jmp 0x5b78
callq 0x29f5
jmp 0x5725
callq 0x2a7d
jmp 0x56ee
callq 0x2a17
jmp 0x5725
callq 0x2a39
jmp 0x5725
callq 0x2a5b
jmp 0x5725
testl %ebp, %ebp
jne 0x5b78
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0x6230
testl %eax, %eax
jne 0x5701
movq 0x18(%rbx), %rax
cmpb $-0x1, (%rax)
je 0x5b65
cmpb $-0x1, 0x1(%rax)
je 0x5b65
movb 0x2(%rax), %al
cmpb $-0x1, %al
je 0x5b65
movzbl %al, %esi
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
movl $0x1, %ecx
callq 0x5bd7
testl %eax, %eax
jne 0x5701
movb 0x10(%rsp), %al
incb %al
movzbl %al, %ebp
cmpb $0x1, %bpl
jbe 0x5b82
movzwl 0x11(%rsp), %eax
rolw $0x8, %ax
movw %ax, 0x14(%rbx)
cmpl $0x2, %ebp
jne 0x5bab
movq 0x8(%rbx), %rdi
xorl %esi, %esi
callq 0x6230
testl %eax, %eax
jne 0x5701
leaq 0x7471(%rip), %rax      # 0xcf90
movzwl (%rax), %ecx
movzwl 0x14(%rbx), %edx
testw %cx, %cx
je 0x5b44
leaq 0x745e(%rip), %rax      # 0xcf90
cmpw %dx, %cx
je 0x5b6f
movzwl 0x48(%rax), %ecx
addq $0x48, %rax
testw %cx, %cx
jne 0x5b32
movq %rax, 0x20(%rbx)
movq 0x84a9(%rip), %rax      # 0xdff8
movq (%rax), %rdi
leaq 0x409c(%rip), %rsi      # 0x9bf5
xorl %eax, %eax
callq 0x2170
jmp 0x5701
callq 0x2b2b
jmp 0x5725
movq %rax, 0x20(%rbx)
jmp 0x5727
callq 0x2a9f
jmp 0x5a8a
movq %rbx, %rdi
callq 0x5bbc
movq 0x8467(%rip), %rax      # 0xdff8
movq (%rax), %rdi
leaq 0x3fea(%rip), %rsi      # 0x9b85
xorl %ebx, %ebx
movl %ebp, %edx
xorl %eax, %eax
callq 0x2170
jmp 0x5727
leaq 0x10(%rsp), %rsi
movl %ebp, %edi
callq 0x2ac1
jmp 0x5b05