// File: /workspace/github_c_makefile_star2_O1/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 0x57b6
movl 0x8(%r14), %eax
andl $0x4, %eax
je 0x57b6
leaq 0xb(%rsp), %rsi
movb $0x7f, (%rsi)
movl $0x1, %edx
movq %r14, %rdi
callq *0x30(%r14)
testl %eax, %eax
jne 0x5ad2
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 0x57b6
testl %eax, %eax
sete %dl
cmpb $0x1f, %cl
sete %cl
andb %dl, %cl
cmpb $0x1, %cl
je 0x5adc
cmpl $0x2, %eax
jne 0x5ae6
leaq 0xb(%rsp), %rsi
movl $0x1, %edx
movq %r14, %rdi
callq *0x30(%r14)
testl %eax, %eax
jne 0x5af0
leaq 0x10(%rsp), %rsi
movl $0x1, %edx
movq %r14, %rdi
callq *0x28(%r14)
testl %eax, %eax
jne 0x5afa
cmpb $0x1f, 0x10(%rsp)
jne 0x5afa
movq %rbx, %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x6b78
testl %eax, %eax
je 0x57d3
movq %rbx, %rdi
callq 0x5c4d
jmp 0x57ed
movl 0x8(%r14), %edx
andl $0x2, %edx
incq %rdx
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq *0x28(%r14)
testl %eax, %eax
je 0x5804
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 %rbx, %rdi
xorl %esi, %esi
callq 0x602b
testl %eax, %eax
jne 0x57c9
movq 0x48(%r14), %rax
movl $0x11, %ecx
testq %rax, %rax
je 0x5870
movb 0x1(%rax), %sil
testb %sil, %sil
je 0x5870
movb 0x11(%rbx), %dl
cmpb (%rax), %dl
je 0x586c
addq $0x3, %rax
movb (%rax), %sil
testb %sil, %sil
je 0x5870
leaq 0x2(%rax), %rdi
cmpb -0x1(%rax), %dl
movq %rdi, %rax
jne 0x5858
movzbl %sil, %ecx
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x5c68
testl %eax, %eax
jne 0x57ed
movb 0x10(%rsp), %al
movb 0x11(%rsp), %cl
incb %al
movb %cl, 0x10(%rbx)
cmpb $0x2, %al
jb 0x5b0c
movzbl %al, %r12d
decq %r12
movq 0x874e(%rip), %r8       # 0xdff8
leaq 0x419b(%rip), %rsi      # 0x9a4c
leaq 0x41b8(%rip), %r10      # 0x9a70
movl $0x7, %ebp
movabsq $0x300000000, %r14      # imm = 0x300000000
movabsq $0x3000000000000, %r11  # imm = 0x3000000000000
movl $0xa1, %r13d
xorl %r15d, %r15d
xorl %eax, %eax
movb 0x12(%rsp,%r15), %cl
movzbl %cl, %edx
cmpl $0x42, %edx
jle 0x593d
cmpl $0x81, %edx
jg 0x5968
leal -0x43(%rdx), %ecx
cmpl $0x31, %ecx
ja 0x5a95
btq %rcx, %rbp
jb 0x59ca
btq %rcx, %r14
jb 0x5a0b
btq %rcx, %r11
jae 0x5a95
movq 0x18(%rbx), %rcx
movzbl 0x8(%rcx), %r9d
cmpb %dl, %r9b
movl %r9d, %edi
cmovbel %edx, %edi
cmpb $-0x1, %r9b
cmovel %edx, %edi
movb %dil, 0x8(%rcx)
jmp 0x5a87
cmpl $0x10, %edx
jg 0x59a4
testl %edx, %edx
je 0x5a49
cmpl $0x1, %edx
je 0x5a51
cmpl $0x2, %edx
jne 0x5a95
movq 0x18(%rbx), %rdx
movb %cl, 0x2(%rdx)
jmp 0x5a87
leal -0x82(%rdx), %ecx
cmpl $0x2, %ecx
jb 0x59ec
leal -0x92(%rdx), %ecx
cmpl $0x2, %ecx
jae 0x5a5a
movq 0x18(%rbx), %rcx
movzbl 0xa(%rcx), %r9d
cmpb %dl, %r9b
movl %r9d, %edi
cmovbel %edx, %edi
cmpb $-0x1, %r9b
cmovel %edx, %edi
movb %dil, 0xa(%rcx)
jmp 0x5a87
leal -0x31(%rdx), %edi
cmpl $0x2, %edi
jb 0x5a2a
cmpl $0x11, %edx
je 0x5a80
cmpl $0x21, %edx
jne 0x5a95
movq 0x18(%rbx), %rdx
movb %cl, 0x4(%rdx)
jmp 0x5a87
movq 0x18(%rbx), %rcx
movzbl 0x6(%rcx), %r9d
cmpb %dl, %r9b
movl %r9d, %edi
cmovbel %edx, %edi
cmpb $-0x1, %r9b
cmovel %edx, %edi
movb %dil, 0x6(%rcx)
jmp 0x5a87
movq 0x18(%rbx), %rcx
movzbl 0x9(%rcx), %r9d
cmpb %dl, %r9b
movl %r9d, %edi
cmovbel %edx, %edi
cmpb $-0x1, %r9b
cmovel %edx, %edi
movb %dil, 0x9(%rcx)
jmp 0x5a87
movq 0x18(%rbx), %rcx
movzbl 0x7(%rcx), %r9d
cmpb %dl, %r9b
movl %r9d, %edi
cmovbel %edx, %edi
cmpb $-0x1, %r9b
cmovel %edx, %edi
movb %dil, 0x7(%rcx)
jmp 0x5a87
movq 0x18(%rbx), %rcx
movzbl 0x5(%rcx), %r9d
cmpb %dl, %r9b
movl %r9d, %edi
cmovbel %edx, %edi
cmpb $-0x1, %r9b
cmovel %edx, %edi
movb %dil, 0x5(%rcx)
jmp 0x5a87
movq 0x18(%rbx), %rdx
movb %cl, (%rdx)
jmp 0x5a87
movq 0x18(%rbx), %rdx
movb %cl, 0x1(%rdx)
jmp 0x5a87
cmpl $0xa1, %edx
jne 0x5a95
movq 0x18(%rbx), %rcx
movzbl 0xb(%rcx), %edx
cmpb $-0x5e, %dl
movl %edx, %edi
cmovbl %r13d, %edi
cmpb $-0x1, %dl
cmovel %r13d, %edi
movb %dil, 0xb(%rcx)
jmp 0x5a87
movq 0x18(%rbx), %rdx
movb %cl, 0x3(%rdx)
incq %r15
cmpq %r15, %r12
jne 0x58dc
jmp 0x5b04
leal 0x1(%rax), %ecx
movl %ecx, 0xc(%rsp)
movq (%r8), %rdi
testl %eax, %eax
je 0x5aa6
movq %r10, %rsi
xorl %eax, %eax
callq 0x2170
leaq 0x3fbc(%rip), %r10      # 0x9a70
leaq 0x3f91(%rip), %rsi      # 0x9a4c
movl 0xc(%rsp), %eax
movq 0x8532(%rip), %r8       # 0xdff8
movabsq $0x3000000000000, %r11  # imm = 0x3000000000000
jmp 0x5a87
callq 0x2ac1
jmp 0x57ed
callq 0x2b49
jmp 0x57b6
callq 0x2ae3
jmp 0x57ed
callq 0x2b05
jmp 0x57ed
callq 0x2b27
jmp 0x57ed
testl %eax, %eax
jne 0x5bf8
movq %rbx, %rdi
xorl %esi, %esi
callq 0x602b
testl %eax, %eax
jne 0x57c9
movq 0x18(%rbx), %rax
cmpb $-0x1, (%rax)
je 0x5bee
cmpb $-0x1, 0x1(%rax)
je 0x5bee
movb 0x2(%rax), %al
cmpb $-0x1, %al
je 0x5bee
movzbl %al, %esi
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
movl $0x1, %ecx
callq 0x5c68
testl %eax, %eax
jne 0x57c9
movb 0x10(%rsp), %al
incb %al
movzbl %al, %ebp
cmpb $0x1, %bpl
jbe 0x5c02
movzwl 0x11(%rsp), %eax
rolw $0x8, %ax
movw %ax, 0x14(%rbx)
cmpl $0x2, %ebp
jne 0x5c2b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x602b
testl %eax, %eax
jne 0x57c9
movq %rbx, %rdi
addq $0x14, %rdi
leaq 0x73ca(%rip), %rax      # 0xcf70
movzwl (%rax), %esi
testw %si, %si
sete %cl
je 0x5c3c
movzwl (%rdi), %edx
leaq 0x73b1(%rip), %rax      # 0xcf70
cmpw %dx, %si
je 0x5be0
addq $0x48, %rax
movzwl (%rax), %esi
testw %si, %si
sete %cl
je 0x5c3c
addq $0x48, %rax
cmpw %dx, %si
jne 0x5bc8
addq $-0x48, %rax
movq %rax, 0x20(%rbx)
testb %cl, %cl
je 0x57ef
jmp 0x5c40
callq 0x2c23
jmp 0x57ed
callq 0x2b6b
jmp 0x5b0c
movq %rbx, %rdi
callq 0x5c4d
movq 0x83e7(%rip), %rax      # 0xdff8
movq (%rax), %rdi
leaq 0x3ea6(%rip), %rsi      # 0x9ac1
xorl %ebx, %ebx
movl %ebp, %edx
xorl %eax, %eax
callq 0x2170
jmp 0x57ef
leaq 0x10(%rsp), %rsi
movl %ebp, %edi
callq 0x2b8d
jmp 0x5b86
movq %rax, 0x20(%rbx)
movq %rbx, %rsi
callq 0x2bf7
jmp 0x57ed