// File: /workspace/github_c_makefile_star2_O2/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, %r15
pushq $0x28
popq %rdi
pushq $0x1
popq %r14
movq %r14, %rsi
callq 0x2150
movq %rax, %rbx
pushq $0xc
popq %rdi
callq 0x21c0
orq $-0x1, (%rax)
orl $-0x1, 0x8(%rax)
movq %rax, 0x18(%rbx)
movq %r15, 0x8(%rbx)
testb %bpl, %bpl
je 0x4c2f
movl 0x8(%r15), %eax
andl $0x4, %eax
je 0x4c2f
leaq 0xb(%rsp), %rsi
movb $0x7f, (%rsi)
pushq $0x1
popq %rdx
movq %r15, %rdi
callq *0x30(%r15)
testl %eax, %eax
jne 0x4cc4
leaq 0x10(%rsp), %r12
pushq $0x1
popq %rdx
movq %r15, %rdi
movq %r12, %rsi
callq *0x28(%r15)
testl %eax, %eax
sete %dl
movb (%r12), %cl
cmpb $0x79, %cl
sete %sil
testb %sil, %dl
jne 0x4c2f
testl %eax, %eax
sete %dl
cmpb $0x1f, %cl
sete %cl
andb %dl, %cl
cmpb $0x1, %cl
je 0x5023
cmpl $0x2, %eax
jne 0x4f42
leaq 0xb(%rsp), %rsi
pushq $0x1
popq %rdx
movq %r15, %rdi
callq *0x30(%r15)
testl %eax, %eax
jne 0x4cc4
leaq 0x10(%rsp), %rsi
pushq $0x1
popq %rdx
movq %r15, %rdi
callq *0x28(%r15)
testl %eax, %eax
jne 0x4f42
cmpb $0x1f, 0x10(%rsp)
jne 0x4f42
pushq $0x1
popq %rbp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x5132
testl %eax, %eax
je 0x4c4d
movq %rbx, %rdi
callq 0x5139
jmp 0x4f5e
movl 0x8(%r15), %edx
andl $0x2, %edx
incq %rdx
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq *0x28(%r15)
testl %eax, %eax
jne 0x4f5e
movb 0x10(%rsp), %al
movb %al, 0x11(%rbx)
movl 0x8(%r15), %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
callq 0x5154
testl %eax, %eax
jne 0x4c40
movq 0x48(%r15), %rdx
pushq $0x11
popq %rax
testq %rdx, %rdx
je 0x4cdc
incq %rdx
movzbl (%rdx), %ecx
testl %ecx, %ecx
je 0x4cdc
movb 0x11(%rbx), %sil
leaq 0x2(%rdx), %rdi
cmpb -0x1(%rdx), %sil
movq %rdi, %rdx
jne 0x4caa
jmp 0x4cde
movq 0x8325(%rip), %rax      # 0xcff0
movq (%rax), %rcx
leaq 0x4240(%rip), %rdi      # 0x8f15
pushq $0x1e
jmp 0x4f55
movl %eax, %ecx
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x515b
testl %eax, %eax
jne 0x4f5e
movb 0x10(%rsp), %al
movb 0x11(%rsp), %cl
incb %al
movb %cl, 0x10(%rbx)
movzbl %al, %r13d
movl $0xa1, %edi
leaq 0x3d5a(%rip), %rsi      # 0x8a6c
leaq 0x3d77(%rip), %r9       # 0x8a90
pushq $0x7
popq %r12
movabsq $0x300000000, %r15      # imm = 0x300000000
movabsq $0x3000000000000, %r10  # imm = 0x3000000000000
xorl %r11d, %r11d
cmpq %r13, %r14
jae 0x4f75
movzbl 0x11(%rsp,%r14), %edx
leal -0x43(%rdx), %eax
cmpl $0x31, %eax
jbe 0x4db9
leal -0x31(%rdx), %eax
cmpl $0x2, %eax
jb 0x4e72
leal -0x82(%rdx), %eax
cmpl $0x2, %eax
jb 0x4e15
leal -0x92(%rdx), %eax
cmpl $0x2, %eax
jb 0x4e36
cmpl $0xa1, %edx
je 0x4e90
cmpl $0x1, %edx
je 0x4ec9
cmpl $0x2, %edx
je 0x4ebf
cmpl $0x11, %edx
je 0x4eb5
cmpl $0x21, %edx
je 0x4eab
testl %edx, %edx
jne 0x4ed9
movq 0x18(%rbx), %rax
movb $0x0, (%rax)
jmp 0x4ed1
btq %rax, %r12
jb 0x4df4
btq %rax, %r15
jb 0x4e54
btq %rax, %r10
jae 0x4d4b
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 0x4ed1
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 0x4ed1
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 0x4ed1
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 0x4ed1
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 0x4ed1
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 0x4ed1
movq 0x18(%rbx), %rax
movzbl 0xb(%rax), %ecx
cmpb $-0x5e, %cl
movl %ecx, %edx
cmovbl %edi, %edx
cmpb $-0x1, %cl
cmovel %edi, %edx
movb %dl, 0xb(%rax)
jmp 0x4ed1
movq 0x18(%rbx), %rax
movb $0x21, 0x4(%rax)
jmp 0x4ed1
movq 0x18(%rbx), %rax
movb $0x11, 0x3(%rax)
jmp 0x4ed1
movq 0x18(%rbx), %rax
movb $0x2, 0x2(%rax)
jmp 0x4ed1
movq 0x18(%rbx), %rax
movb $0x1, 0x1(%rax)
incq %r14
jmp 0x4d34
testl %r11d, %r11d
je 0x4f0f
incl %r11d
movl %r11d, 0xc(%rsp)
movq 0x8103(%rip), %rax      # 0xcff0
movq (%rax), %rdi
movq %r9, %rsi
xorl %eax, %eax
callq 0x2170
movl 0xc(%rsp), %r11d
leaq 0x3b8a(%rip), %r9       # 0x8a90
leaq 0x3b5f(%rip), %rsi      # 0x8a6c
jmp 0x4f31
movq 0x80da(%rip), %rax      # 0xcff0
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2170
leaq 0x3b69(%rip), %r9       # 0x8a90
leaq 0x3b3e(%rip), %rsi      # 0x8a6c
movl %ebp, %r11d
movl $0xa1, %edi
movabsq $0x3000000000000, %r10  # imm = 0x3000000000000
jmp 0x4ed1
movq 0x80a7(%rip), %rax      # 0xcff0
movq (%rax), %rcx
leaq 0x4012(%rip), %rdi      # 0x8f65
pushq $0x17
popq %rsi
pushq $0x1
popq %rdx
callq 0x22b0
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testl %r11d, %r11d
jne 0x505c
movq %rbx, %rdi
callq 0x5154
testl %eax, %eax
jne 0x4c40
movq 0x18(%rbx), %rax
cmpb $-0x1, (%rax)
je 0x5044
cmpb $-0x1, 0x1(%rax)
je 0x5044
movb 0x2(%rax), %al
cmpb $-0x1, %al
je 0x5044
movzbl %al, %esi
leaq 0x10(%rsp), %rdx
pushq $0x1
popq %rcx
movq %rbx, %rdi
callq 0x515b
testl %eax, %eax
jne 0x4c40
movb 0x10(%rsp), %al
incb %al
movzbl %al, %ebp
cmpb $0x1, %bpl
jbe 0x5086
movzwl 0x11(%rsp), %eax
rolw $0x8, %ax
movw %ax, 0x14(%rbx)
cmpl $0x2, %ebp
jne 0x50af
movq %rbx, %rdi
callq 0x5154
testl %eax, %eax
jne 0x4c40
leaq 0x6fb5(%rip), %rax      # 0xbfc0
movzwl (%rax), %ecx
testw %cx, %cx
je 0x510d
cmpw 0x14(%rbx), %cx
je 0x507d
addq $0x48, %rax
jmp 0x500b
movq 0x7fc6(%rip), %rax      # 0xcff0
movq (%rax), %rcx
leaq 0x3f00(%rip), %rdi      # 0x8f34
pushq $0x30
popq %rsi
pushq $0x1
popq %rdx
callq 0x22b0
jmp 0x4c2f
movq 0x7fa5(%rip), %rax      # 0xcff0
movq (%rax), %rcx
leaq 0x3a43(%rip), %rdi      # 0x8a98
pushq $0x48
jmp 0x4f55
movq 0x7f8d(%rip), %rax      # 0xcff0
movq (%rax), %rcx
leaq 0x3f91(%rip), %rdi      # 0x8ffe
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x22b0
jmp 0x4f7e
movq %rax, 0x20(%rbx)
jmp 0x4f60
movq %rbx, %rdi
callq 0x5139
movq 0x7f5b(%rip), %rax      # 0xcff0
movq (%rax), %rdi
leaq 0x3a42(%rip), %rsi      # 0x8ae1
xorl %ebx, %ebx
movl %ebp, %edx
xorl %eax, %eax
callq 0x2170
jmp 0x4f60
movq 0x7f3a(%rip), %rax      # 0xcff0
movq (%rax), %rdi
leaq 0x3a5c(%rip), %rsi      # 0x8b1c
movl %ebp, %edx
xorl %eax, %eax
callq 0x2170
movl %ebp, %r15d
decq %r15
leaq 0x3a75(%rip), %r14      # 0x8b4b
xorl %r12d, %r12d
movq 0x7f10(%rip), %rax      # 0xcff0
movq (%rax), %rsi
cmpq %r12, %r15
je 0x5100
movzbl 0x12(%rsp,%r12), %edx
movq %rsi, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x2170
incq %r12
jmp 0x50d9
pushq $0xa
popq %rdi
callq 0x2130
jmp 0x4ff4
movq %rax, 0x20(%rbx)
movq 0x7ed8(%rip), %rax      # 0xcff0
movq (%rax), %rdi
movzwl 0x14(%rbx), %edx
leaq 0x3a2b(%rip), %rsi      # 0x8b51
xorl %eax, %eax
callq 0x2170
jmp 0x4c40