bootloader/bootloader.c

180 lines
4.1 KiB
C
Raw Normal View History

2022-05-19 08:57:38 -04:00
/*
===============================================================================
Name : bootloader.c
Author : $(author)
Version :
Copyright : $(copyright)
Description : main definition
===============================================================================
*/
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
#include <cr_section_macros.h>
#include <stdio.h>
#include <string.h>
#include "uart_commands.h"
#include "timer.h"
2022-05-19 08:57:38 -04:00
error_code status;
2022-05-30 11:50:19 -04:00
enum States
{
S1,
S2,
S3
};
2022-05-24 10:52:09 -04:00
/*
is_even_assembly:
ldr sp, [r0]
ret
*/
2022-05-19 08:57:38 -04:00
2022-05-30 11:50:19 -04:00
enum States state = S1;
2022-05-24 06:48:02 -04:00
char* argvs[3][10];
2022-05-19 08:57:38 -04:00
cmd_t cmd;
2022-05-28 17:09:33 -04:00
uint32_t* size_store = (uint32_t*) 0x3100;
2022-05-28 13:30:55 -04:00
crc_t* crc_store = (crc_t*) 0x3000;
2022-05-24 06:48:02 -04:00
2022-05-19 08:57:38 -04:00
uint32_t offset, total_size, offset_pointer;
crc_t crc_prog, crc_data;
// TODO: insert other include files here
// TODO: insert other definitions and declarations here
2022-05-19 15:37:51 -04:00
char buff[256];
2022-05-22 13:52:44 -04:00
2022-05-28 13:30:55 -04:00
int is_code_valid(){
crc_t expected_crc = *crc_store;
size_t application_size = *size_store;
crc_t real_crc = crc_init();
2022-05-28 17:09:33 -04:00
if(application_size > MAX_PROG_SIZE) return 0;
2022-05-28 13:30:55 -04:00
real_crc = crc_update(real_crc, (void*)APP_OFFSET, application_size);
real_crc = crc_finalize(real_crc);
error_code is_error = uart_commands_check(real_crc, expected_crc);
if(is_error == ok){
return 1;
}
else{
set_colour(RED);//code invalid, red led
return 0;
}
2022-05-28 13:30:55 -04:00
}
2022-05-28 17:09:33 -04:00
int is_b_pressed(){
int tmp = (LPC_GPIO0->FIOPIN)>>19;
int tmp2 = tmp & 1;
if(tmp2 == 0) return 1;
else return 0;
}
2022-05-28 13:30:55 -04:00
void write_app_info(crc_t* checksum, size_t* size){
iap_prepare_sectors(&status, addr_to_sector(0x3000), addr_to_sector(0x3fff));
if(status != ok){
uart_send_err();
}
iap_erase_sectors(&status, addr_to_sector(0x3000), addr_to_sector(0x3fff));
if(status != ok){
uart_send_err();
}
2022-05-28 17:09:33 -04:00
iap_copy_to_flash(&status, (long unsigned int *)crc_store, (long unsigned int*)checksum, 0x100);
//0x100 a result of trial and error I initially wanted to put 0x4 but noooo it doesn't work
iap_copy_to_flash(&status, (long unsigned int *)size_store, (long unsigned int*)size, 0x100);
}
void launch_program(){
SCB->VTOR = APP_OFFSET;
__asm("ldr r0,=0x4000");
__asm("ldr sp,[r0]");
__asm("ldr pc,[r0,#4]");
}
void manage_bootloader(){
cmd.argv = (char**)argvs;
int var = 1;
char digit;
2022-05-30 13:57:15 -04:00
set_colour(GREEN);
while(var){
2022-05-28 17:09:33 -04:00
uart_receive_command(buff);
uart_parse_command(buff, &cmd);
set_colour(GREEN);
2022-05-30 11:50:19 -04:00
if ((state == S1) && (strncmp("GETID", cmd.argv[0], 5)==0)){
2022-05-28 17:09:33 -04:00
uart_commands_getid(&status);
2022-05-30 11:50:19 -04:00
}else if((state == S1) && (strncmp("GETSE", cmd.argv[0], 5)==0)){
2022-05-28 17:09:33 -04:00
uart_commands_getserial(&status);
2022-05-30 11:50:19 -04:00
}else if((state == S1) && (strncmp("PROG", cmd.argv[0], 4)==0)){
2022-05-28 17:09:33 -04:00
crc_prog = uart_string_to_int(cmd.argv[3]);
total_size = uart_string_to_int(cmd.argv[2]);
offset = uart_string_to_int(cmd.argv[1]);
write_app_info(&crc_prog, (unsigned int *)&total_size);
crc_data = uart_commands_prog(&status, total_size);
2022-05-30 11:50:19 -04:00
if(status == ok){
state = S2;
}
2022-05-28 17:09:33 -04:00
offset_pointer = offset;
2022-05-30 11:50:19 -04:00
}else if(((state == S2) || (state = S3)) && (strcmp("DATA", cmd.argv[0])==0)){
2022-05-28 17:09:33 -04:00
int size = uart_string_to_int(cmd.argv[1]);
crc_t local_checksum = uart_string_to_int(cmd.argv[2]);
uart_commands_data(&status, size, &crc_data, local_checksum, offset_pointer);
2022-05-30 11:50:19 -04:00
if(status == ok){
offset_pointer += size;
state = S3;
}else{
state = S2;
}
2022-05-28 17:09:33 -04:00
2022-05-30 11:50:19 -04:00
}else if((state == S3) && (strncmp("CHECK", cmd.argv[0], 5)==0)){
2022-05-28 17:09:33 -04:00
error_code is_error = uart_commands_check(crc_prog, crc_data);
if(is_error == ok){
2022-05-30 11:50:19 -04:00
state = S1;
2022-05-28 17:09:33 -04:00
uart_send_ok();
uart_send("bla\r\n", 5);//putting bla here so OK will show up
//removing bla for the moment will make ok not show up
var = 0;
LPC_GPIO2->FIOCLR0 = 0xff;
launch_program();
2022-05-28 17:09:33 -04:00
}else{
2022-05-30 11:50:19 -04:00
state = S2;
2022-05-28 17:09:33 -04:00
uart_send_err();
set_colour(RED);
itoa(is_error, &digit, 10);
uart_send(&digit, 1);
//flash LED red, and stays in the bootloader mode
2022-05-28 17:09:33 -04:00
}
2022-05-30 11:50:19 -04:00
}else {
uart_send_cmd_illeg();
2022-05-28 17:09:33 -04:00
}
2022-05-28 13:30:55 -04:00
}
}
2022-05-19 08:57:38 -04:00
int main(void) {
uart_init(115200);
timer_0();
2022-05-28 17:09:33 -04:00
if(is_b_pressed() == 0){
if(is_code_valid()){
launch_program();
}else{
manage_bootloader();
2022-05-19 15:37:51 -04:00
}
2022-05-28 17:09:33 -04:00
}else{
manage_bootloader();
2022-05-28 13:30:55 -04:00
}
2022-05-19 08:57:38 -04:00
while(1);
return 0 ;
}