Add update code to updater and use uart for status updates
This commit is contained in:
		| @@ -37,7 +37,7 @@ | ||||
| #include <stm-periph/stm32-gpio-macros.h> | ||||
| #include <stm-periph/rcc-manager.h> | ||||
| #include <stm-periph/uart.h> | ||||
| #include <reflow-controller/shell-uart-config.h> | ||||
| #include <reflow-controller/periph-config/shell-uart-config.h> | ||||
| #include <reflow-controller/oven-driver.h> | ||||
| #include <fatfs/ff.h> | ||||
| #include <reflow-controller/ui/gui.h> | ||||
|   | ||||
| @@ -13,7 +13,7 @@ set(ELFFILE "${PROJECT_NAME}.elf") | ||||
| aux_source_directory("." SRCS) | ||||
| aux_source_directory("fatfs" FATFS_SRCS) | ||||
| aux_source_directory("fatfs/shimatta_sdio_driver" SDIO_SRCS) | ||||
| aux_source_directory("../../stm-periph" STM_PERIPH_SRCS) | ||||
| set(STM_PERIPH_SRCS "../../stm-periph/backup-ram.c" "../../stm-periph/rcc-manager.c" "../../stm-periph/crc-unit.c") | ||||
| set(SAFETY_MEMORY_SRCS "../../safety/safety-memory.c") | ||||
|  | ||||
| add_executable(${ELFFILE} ${SRCS} ${FATFS_SRCS} ${SDIO_SRCS} ${STM_PERIPH_SRCS} ${SAFETY_MEMORY_SRCS}) | ||||
|   | ||||
| @@ -37,22 +37,22 @@ void flash_writer_perform_mass_erase(void) | ||||
| uint32_t flash_writer_get_flash_size(void) | ||||
| { | ||||
| 	uint32_t flash_size; | ||||
| 	const uint32_t *flash_size_ptr = (const uint32_t *)0x1FFF7A22UL; | ||||
| 	const uint16_t *flash_size_ptr = (const uint16_t *)0x1FFF7A22UL; | ||||
|  | ||||
| 	flash_size = *flash_size_ptr; | ||||
| 	flash_size = (uint32_t)*flash_size_ptr; | ||||
| 	flash_size *= 1024; | ||||
|  | ||||
| 	return flash_size; | ||||
| } | ||||
|  | ||||
| int flash_writer_write_to_memory(void *dest, void *src, uint32_t size) | ||||
| int flash_writer_write_to_memory(void *dest, const void *src, uint32_t size) | ||||
| { | ||||
| 	uint32_t full_word_cnt; | ||||
| 	uint32_t byte_cnt; | ||||
| 	uint32_t idx; | ||||
| 	uint32_t *word_src_ptr; | ||||
| 	const uint32_t *word_src_ptr; | ||||
| 	uint32_t *word_dest_ptr; | ||||
| 	char *char_src_ptr; | ||||
| 	const char *char_src_ptr; | ||||
| 	char *char_dest_ptr; | ||||
|  | ||||
| 	flash_writer_enable_access(); | ||||
|   | ||||
| @@ -11,6 +11,6 @@ uint32_t flash_writer_get_flash_size(void); | ||||
|  | ||||
| uint32_t flash_writer_get_base_address(void); | ||||
|  | ||||
| int flash_writer_write_to_memory(void *dest, void *src, uint32_t size); | ||||
| int flash_writer_write_to_memory(void *dest, const void *src, uint32_t size); | ||||
|  | ||||
| #endif /* _FLASH_WRITER_H_ */ | ||||
|   | ||||
| @@ -13,6 +13,8 @@ | ||||
| #include "flash-writer.h" | ||||
|  | ||||
| #include <stdbool.h> | ||||
| #include <string.h> | ||||
| #include "uart.h" | ||||
|  | ||||
| static volatile unsigned int wait_tick; | ||||
|  | ||||
| @@ -46,6 +48,9 @@ static void __attribute__((noreturn)) ram_code_exit(bool updated) | ||||
| 	boot_status.reboot_to_bootloader = 0x0UL; | ||||
| 	safety_memory_set_boot_status(&boot_status); | ||||
|  | ||||
| 	uart_send_string("Rebooting in 1s...\r\n"); | ||||
| 	sdio_wait_ms(1000); | ||||
|  | ||||
| 	NVIC_SystemReset(); | ||||
| 	while(1); | ||||
| } | ||||
| @@ -90,17 +95,103 @@ exit: | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| int write_flash_from_buffer(const char *buffer, uint32_t len, uint32_t addr) | ||||
| { | ||||
| 	return flash_writer_write_to_memory((void *)addr, buffer, len); | ||||
| } | ||||
|  | ||||
| int update_flash_from_file(const char *fname) | ||||
| { | ||||
| 	enum hex_parser_ret hex_ret; | ||||
| 	struct hex_parser parser; | ||||
| 	static char write_buffer[4096]; | ||||
| 	uint32_t wbuffer_base_addr = 0; | ||||
| 	uint32_t wbuffer_fill_level = 0; | ||||
| 	uint32_t addr; | ||||
| 	static char tmp_buff[256]; | ||||
| 	size_t dlen; | ||||
| 	int retval = 0; | ||||
| 	int res; | ||||
|  | ||||
| 	hex_ret = hex_parser_open(&parser, fname); | ||||
| 	if (hex_ret != HEX_PARSER_OK) { | ||||
| 		uart_send_string("Error reading hex file.\r\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	do { | ||||
| 		hex_ret = hex_parser_parse(&parser, &addr, tmp_buff, sizeof(tmp_buff), &dlen); | ||||
| 		if (hex_ret == HEX_PARSER_DATA_OK) { | ||||
| 			/* Check if tmp would fit in wbuffer */ | ||||
| 			if (dlen + wbuffer_fill_level > sizeof(write_buffer)) { | ||||
| 				/* Write out the buffer and clean it  if it doens't fit */ | ||||
| 				res = write_flash_from_buffer(write_buffer, wbuffer_fill_level, wbuffer_base_addr); | ||||
| 				if (res) { | ||||
| 					retval = -4; | ||||
| 					goto exit_parser_close; | ||||
| 				} | ||||
| 				wbuffer_fill_level = 0; | ||||
| 				wbuffer_base_addr = 0; | ||||
| 			} | ||||
|  | ||||
| 			/* Check if parsed data can be linearily appended to buffer */ | ||||
| 			if (wbuffer_fill_level && wbuffer_base_addr + wbuffer_fill_level != addr) { | ||||
| 				/* Write out the buffer and clean it if it cannot be appended */ | ||||
| 				res = write_flash_from_buffer(write_buffer, wbuffer_fill_level, wbuffer_base_addr); | ||||
| 				if (res) { | ||||
| 					retval = -4; | ||||
| 					goto exit_parser_close; | ||||
| 				} | ||||
| 				wbuffer_fill_level = 0; | ||||
| 				wbuffer_base_addr = 0; | ||||
| 			} | ||||
|  | ||||
| 			/* Fill in the data into the buffer */ | ||||
| 			if (wbuffer_fill_level == 0) { | ||||
| 				wbuffer_base_addr = addr; | ||||
| 			} | ||||
| 			memcpy(&write_buffer[wbuffer_fill_level], tmp_buff, dlen); | ||||
| 			wbuffer_fill_level += dlen; | ||||
| 		} | ||||
| 	} while (hex_ret == HEX_PARSER_DATA_OK || hex_ret == HEX_PARSER_OK); | ||||
|  | ||||
| 	if (hex_ret == HEX_PARSER_EOF_RECORD) { | ||||
| 		if (wbuffer_fill_level > 0) { | ||||
| 			res = write_flash_from_buffer(write_buffer, wbuffer_fill_level, wbuffer_base_addr); | ||||
| 			if (res) { | ||||
| 				retval = -4; | ||||
| 				goto exit_parser_close; | ||||
| 			} | ||||
| 		} | ||||
| 		retval = 0; | ||||
| 	} else { | ||||
| 		retval = -3; | ||||
| 	} | ||||
|  | ||||
| exit_parser_close: | ||||
| 	hex_parser_close(&parser); | ||||
|  | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| int ram_code_main(void) | ||||
| { | ||||
| 	FRESULT fres; | ||||
| 	int res; | ||||
| 	enum safety_memory_state safety_mem_state; | ||||
| 	static char filename[256]; | ||||
| 	int retries = 3; | ||||
|  | ||||
| 	SysTick_Config(168000UL); | ||||
| 	external_watchdog_disable(); | ||||
| 	__enable_irq(); | ||||
| 	 | ||||
|  | ||||
| 	/* Init the uart module | ||||
| 	 * Pins don't need configuration. They're already setup by the main program | ||||
| 	 */ | ||||
| 	uart_init(); | ||||
| 	uart_send_string("Updater started.\r\n"); | ||||
|  | ||||
| 	res = safety_memory_init(&safety_mem_state); | ||||
| 	if (res || safety_mem_state != SAFETY_MEMORY_INIT_VALID_MEMORY) { | ||||
| 		ram_code_exit(false); | ||||
| @@ -108,6 +199,7 @@ int ram_code_main(void) | ||||
|  | ||||
| 	fres = f_mount(fs, "0:/", 1); | ||||
| 	if (fres != FR_OK) { | ||||
| 		uart_send_string("Could not mount SD card\r\n"); | ||||
| 		ram_code_exit(false); | ||||
| 	} | ||||
|  | ||||
| @@ -115,10 +207,43 @@ int ram_code_main(void) | ||||
| 	if (res) | ||||
| 		ram_code_exit(false); | ||||
|  | ||||
| 	uart_send_string("Checking hex file\r\n"); | ||||
| 	uart_send_string(filename); | ||||
| 	uart_send_string("\r\n"); | ||||
| 	if (check_hex_file(filename)) { | ||||
| 		uart_send_string("Error in hex file\r\n"); | ||||
| 		ram_code_exit(false); | ||||
| 	} | ||||
|  | ||||
| 	uart_send_string("File "); | ||||
| 	uart_send_string(filename); | ||||
| 	uart_send_string(" checked successfully.\r\n"); | ||||
| 	uart_send_string("Starting updater...\r\n"); | ||||
|  | ||||
| 	do { | ||||
| 		uart_send_string("Erasing chip..."); | ||||
| 		flash_writer_perform_mass_erase(); | ||||
| 		uart_send_string(" done\r\n"); | ||||
|  | ||||
| 		uart_send_string("Programming flash...\r\n"); | ||||
| 		res = update_flash_from_file(filename); | ||||
|  | ||||
| 		if (res) { | ||||
| 			uart_send_string("Programming NOT successful.\r\n"); | ||||
| 			if (retries > 0) { | ||||
| 				uart_send_string("Will retry...\r\n"); | ||||
| 			} | ||||
| 		} else { | ||||
| 			uart_send_string("Programming completed successfully!\r\n"); | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 	} while (retries > 0); | ||||
|  | ||||
| 	if (res) { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	while(1) { | ||||
| 		__WFI(); | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										29
									
								
								stm-firmware/updater/ram-code/uart.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								stm-firmware/updater/ram-code/uart.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #include "uart.h" | ||||
| #include <reflow-controller/periph-config/shell-uart-config.h> | ||||
| #include <stm32/stm32f4xx.h> | ||||
| #include <string.h> | ||||
|  | ||||
| void uart_init(void) | ||||
| { | ||||
| 	SHELL_UART_RCC_REG |= SHELL_UART_RCC_MASK; | ||||
| 	SHELL_UART_PERIPH->BRR = SHELL_UART_BRR_REG_VALUE; | ||||
| 	SHELL_UART_PERIPH->CR2 = 0; | ||||
| 	SHELL_UART_PERIPH->CR3 = 0; | ||||
| 	SHELL_UART_PERIPH->CR1 = USART_CR1_TE | USART_CR1_UE; | ||||
| } | ||||
|  | ||||
| void uart_send_char(char c) | ||||
| { | ||||
| 	while (!(SHELL_UART_PERIPH->SR & USART_SR_TXE)); | ||||
| 	SHELL_UART_PERIPH->DR = c; | ||||
| } | ||||
|  | ||||
| void uart_send_string(const char *str) | ||||
| { | ||||
| 	int len, i; | ||||
|  | ||||
| 	len = strlen(str); | ||||
| 	for (i = 0; i < len; i++) { | ||||
| 		uart_send_char(str[i]); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										10
									
								
								stm-firmware/updater/ram-code/uart.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								stm-firmware/updater/ram-code/uart.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #ifndef _UART_H_ | ||||
| #define _UART_H_ | ||||
|  | ||||
| void uart_init(void); | ||||
|  | ||||
| void uart_send_char(char c); | ||||
|  | ||||
| void uart_send_string(const char *str); | ||||
|  | ||||
| #endif /* _UART_H_ */ | ||||
		Reference in New Issue
	
	Block a user