Compare commits

...

15 Commits

Author SHA1 Message Date
yul
e1ffa61060 fixed most warnings 2022-05-30 19:57:15 +02:00
yul
b21b8dbf2d state machine, error handling, and twinkling led 2022-05-30 19:34:27 +02:00
yul
a94c55d4a6 added state machine 2022-05-30 17:50:19 +02:00
yul
917aa733ff the ok not working. for the moment work around with bla 2022-05-29 00:05:04 +02:00
yul
a7f16616f0 yeaaah 2022-05-28 23:09:33 +02:00
yul
02cc22e6ae yeaaah sonic! 2022-05-28 19:30:55 +02:00
yul
84caa2db3b empty message 2022-05-24 16:52:09 +02:00
yul
ae3e68c12b sonic works too 2022-05-24 15:43:24 +02:00
yul
41414634b6 yeah mylab2_test works as well 2022-05-24 15:17:23 +02:00
yul
49b56a0c12 CANOPEN works 2022-05-24 14:53:35 +02:00
yul
10f6b3677f string_to_digit changed back to stroul 2022-05-24 13:21:02 +02:00
yul
3768522850 oh well 2022-05-24 12:48:02 +02:00
yul
a695df73d2 i am really tired i want to cry and watch kdrama 2022-05-22 23:50:15 +02:00
yul
3672c0f986 data works! ok doesn't! 2022-05-22 23:44:17 +02:00
yul
8ee6dff899 bla 2022-05-22 20:00:02 +02:00
7 changed files with 281 additions and 142 deletions

View File

@ -18,17 +18,33 @@
#include <string.h>
#include "uart_commands.h"
#include "timer.h"
error_code status;
char okk[4] = "OK\r\n";
char errr[5] = "ERR\r\n";
enum States
{
S1,
S2,
S3
};
/*
is_even_assembly:
ldr sp, [r0]
ret
*/
enum States state = S1;
char* argvs[3][10];
cmd_t cmd;
uint32_t* size_store = (uint32_t*) 0x3100;
crc_t* crc_store = (crc_t*) 0x3000;
uint32_t offset, total_size, offset_pointer;
crc_t crc_prog, crc_data;
@ -40,41 +56,124 @@ crc_t crc_prog, crc_data;
char buff[256];
int main(void) {
uart_init(115200);
while(1){
int is_code_valid(){
crc_t expected_crc = *crc_store;
size_t application_size = *size_store;
crc_t real_crc = crc_init();
if(application_size > MAX_PROG_SIZE) return 0;
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;
}
}
int is_b_pressed(){
int tmp = (LPC_GPIO0->FIOPIN)>>19;
int tmp2 = tmp & 1;
if(tmp2 == 0) return 1;
else return 0;
}
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();
}
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;
set_colour(GREEN);
while(var){
uart_receive_command(buff);
uart_parse_command(buff, &cmd);
if (strncmp("GETID", cmd.argv[0], 5)==0){
set_colour(GREEN);
if ((state == S1) && (strncmp("GETID", cmd.argv[0], 5)==0)){
uart_commands_getid(&status);
}else if(strncmp("GETSE", cmd.argv[0], 5)==0){
}else if((state == S1) && (strncmp("GETSE", cmd.argv[0], 5)==0)){
uart_commands_getserial(&status);
}else if(strncmp("PROG", cmd.argv[0], 4)==0){
}else if((state == S1) && (strncmp("PROG", cmd.argv[0], 4)==0)){
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]);
crc_data = uart_commands_prog();
write_app_info(&crc_prog, (unsigned int *)&total_size);
crc_data = uart_commands_prog(&status, total_size);
if(status == ok){
state = S2;
}
offset_pointer = offset;
}else if(strcmp("DATA", cmd.argv[0])==0){
}else if(((state == S2) || (state = S3)) && (strcmp("DATA", cmd.argv[0])==0)){
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);
uart_commands_data(&status, size, &crc_data, crc_data, offset_pointer);
if(status == 0) offset_pointer += size;
}else if(strcmp("CHECK", cmd.argv[0])==0){
error_code is_error = uart_commands_check(crc_prog, crc_data);
if(is_error == ok){
uart_send(okk, 5);
uart_commands_data(&status, size, &crc_data, local_checksum, offset_pointer);
if(status == ok){
offset_pointer += size;
state = S3;
}else{
uart_send(errr, 6);
state = S2;
}
}else if((state == S3) && (strncmp("CHECK", cmd.argv[0], 5)==0)){
error_code is_error = uart_commands_check(crc_prog, crc_data);
if(is_error == ok){
state = S1;
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();
}else{
state = S2;
uart_send_err();
set_colour(RED);
itoa(is_error, &digit, 10);
uart_send(&digit, 1);
//flash LED red, and stays in the bootloader mode
}
}else {
uart_send_cmd_illeg();
}
}
}
}
int main(void) {
uart_init(115200);
timer_0();
if(is_b_pressed() == 0){
if(is_code_valid()){
launch_program();
}else{
manage_bootloader();
}
}else{
manage_bootloader();
}
while(1);
return 0 ;
}

94
iap.c
View File

@ -14,38 +14,47 @@
#include "iap.h"
uint32_t command[5];
uint32_t output[5];
unsigned int command[5];
unsigned int output[5];
IAP iap_entry =(IAP) IAP_LOCATION;
volatile char test[32] = {'t', 'e', 's', 't', 'i', 'n', 'g', '!',
't', 'e', 's', 't', 'i', 'n', 'g', '!',
't', 'e', 's', 't', 'i', 'n', 'g', '!',
't', 'e', 's', 't', 'i', 'n', 'g', '!'};
void iap_everything_is_alright(void){
LPC_GPIO2->FIOPIN = 0x00;
}
void iap_something_went_wrong(int error_code){
LPC_GPIO2->FIOPIN = error_code;
int addr_to_sector(unsigned long int addr){
int tmp = addr & 0xfffff;
tmp = tmp >> 12;
if(tmp <= 15) return tmp;
else{
if(tmp >= 0x10 && tmp <=0x17)
return 16;
else if(tmp >= 0x18 && tmp <= 0x1f)
return 17;
else if(tmp >= 0x20 && tmp <= 0x27)
return 18;
else if(tmp >= 0x28 && tmp <= 0x2f)
return 19;
else if(tmp >= 0x30 && tmp <= 0x37)
return 20;
else if(tmp >= 0x38 && tmp <= 0x3f)
return 21;
else if(tmp >= 0x40 && tmp <= 0x47)
return 22;
else if(tmp >= 0x48 && tmp <= 0x4f)
return 23;
else if(tmp >= 0x50 && tmp <= 0x57) return 24;
else if(tmp >= 0x58 && tmp <= 0x3f) return 25;
else if(tmp >= 0x60 && tmp <= 0x67) return 26;
else if(tmp >= 0x68 && tmp <= 0x6f) return 27;
else if(tmp >= 0x70 && tmp <= 0x77) return 28;
else if(tmp >= 0x78 && tmp <= 0x7f) return 29;
}
return -1;
}
void iap_entry_wrapped(void){
__disable_irq();
iap_entry(command, output);
__enable_irq();
}
/*void iap_read_part_id(void){
command[0] = 54;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS){
iap_everything_is_alright();
printf("part id is %d\n", output[1]);
}else{
iap_something_went_wrong(output[0]);
}
}*/
void iap_prepare_sectors(error_code* status, int start, int end){
command[0] = 50;
@ -53,11 +62,9 @@ void iap_prepare_sectors(error_code* status, int start, int end){
command[2] = end;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
iap_everything_is_alright();
*status = 0;
}else{
iap_something_went_wrong(output[0]);
*status = -1;
*status = output[0];
}
}
@ -69,9 +76,8 @@ void iap_erase_sectors(error_code* status, int start, int end){
command[3] = IAP_CLOCK_100M;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
iap_everything_is_alright();
}else{
iap_something_went_wrong(output[0]);
*status = output[0];
}
}
@ -81,31 +87,26 @@ uint32_t iap_read_part_id(error_code* status){
command[0] = 54;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
iap_everything_is_alright();
*status = 0;
return output[1];
}else{
iap_something_went_wrong(output[0]);
*status = -1;
return -1;
}
}
void iap_copy_to_flash(error_code* status, int dst_flash, uint32_t* src_ram, int num_bytes){
//iap_prepare_sectors(status, dst_flash, dst_flash+num_bytes);
//iap_erase_sectors(status, dst_flash, dst_flash+num_bytes);
//iap_prepare_sectors(status, dst_flash, dst_flash+num_bytes);
void iap_copy_to_flash(error_code* status, long unsigned int* dst_flash, uint8_t* src_ram, int num_bytes){
iap_prepare_sectors(status, addr_to_sector((long unsigned int)dst_flash), addr_to_sector((long unsigned int)dst_flash+num_bytes));
command[0] = 51;
command[1] = dst_flash;
command[2] = *src_ram;
command[1] = (unsigned int)dst_flash;
command[2] = (unsigned int)src_ram;
command[3] = num_bytes;
command[4] = IAP_CLOCK_100M;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
iap_everything_is_alright();
*status = 0;
}else{
iap_something_went_wrong(output[0]);
*status = -1;
*status = output[0];
}
}
@ -114,26 +115,13 @@ void iap_read_serial(error_code* status, uint32_t* res){
command[0] = 58;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
iap_everything_is_alright();
*status = 0;
res[0] = output[1];
res[1] = output[2];
res[2] = output[3];
res[3] = output[4];
}else{
iap_something_went_wrong(output[0]);
*status = -1;
*status = output[0];
}
}
// TODO: insert other include files here
// TODO: insert other definitions and declarations here
/*
int main(void) {
LPC_PINCON->PINSEL4 &= ~0xFF; //Configure the PORT2 Pins as GPIO;
LPC_GPIO2->FIODIR = 0xff; //Configure the PORT2 pins as OUTPUT;
iap_read_part_id();
iap_erase_sectors(2, 9);
iap_copy_to_flash(0x8000,(uint8_t*)test, 4);
}*/

12
iap.h
View File

@ -26,18 +26,18 @@ typedef enum _error_code {
typedef void (*IAP)(unsigned int[], unsigned int[]);
void iap_everything_is_alright(void);
void iap_something_went_wrong(int error_code);
/*This command must be executed before executing "Copy RAM to Flash" or
"Erase Sector(s)" command. Successful execution of the "Copy RAM to Flash" or
"Erase Sector(s)" command causes relevant sectors to be protected again. To
prepare a single sector use the same "Start" and "End" sector numbers.*/
void iap_prepare_sectors(error_code* status, int start, int end);
void iap_erase_sectors(error_code* status, int start, int end);
void iap_copy_to_flash(error_code* status, int dst_flash, uint32_t* src_ram, int num_bytes);
void iap_copy_to_flash(error_code* status, long unsigned int * dst_flash, uint8_t* src_ram, int num_bytes);
uint32_t iap_read_part_id(error_code* status);
void iap_read_serial(error_code* status, uint32_t* res);
int addr_to_sector(unsigned long int addr);

11
uart.c
View File

@ -32,13 +32,12 @@ void uart_init(uint32_t baudrate){
}
void uart_send(char* buff, uint32_t length){
int tmp;
//int tmp;
while (length-- != 0 ){
LPC_UART0->THR = *buff++;
//LPC_UART0->THR = *buff++;
while(((LPC_UART0->LSR)&(1<<5)) == 0);//stuck in while when U1THR contains valid data
tmp = LPC_UART0->RBR;
LPC_GPIO2->FIOCLR = 0xff;
LPC_GPIO2->FIOSET = tmp;
LPC_UART0->THR = *buff++;
//tmp = LPC_UART0->RBR;
}
}
@ -47,12 +46,10 @@ void uart_receive_command(char* chara){
char* curr = chara;
while(((LPC_UART0->LSR)&(1)) == 0);
*curr = LPC_UART0->RBR;
//while(strncmp("\r\n",curr, 2) != 0){
while(*curr != '\n'){
if((*curr != '\n')) curr++;
while(((LPC_UART0->LSR)&(1)) == 0);
*curr = LPC_UART0->RBR;
//if(strncmp("\r\n",curr, 2) != 0) curr++;
}
}

View File

@ -1,81 +1,114 @@
#include "uart_commands.h"
static uint8_t data[4096];
static uint8_t data[1024];
char OK[5] = "OK\r\n";
char ERR[6] = "ERR\r\n";
char CMD_ILLEGAL[13] = "CMD_ILLEGAL\r\n";
void digit_to_str(char* str, uint32_t number, int base){
itoa(number,str,16);
}
void uart_commands_getid(error_code* status){
char hex[15];
//char hex[15] = "0x26113f37\r\n";
char hex[15];
uint32_t res = iap_read_part_id(status);
sprintf(hex, "0x%x\r\n", res);
digit_to_str(hex+2, res, 16);
hex[0]='0';
hex[1]='x';
//sprintf(hex, "0x%x\r\n", res);
if(*status == 0){
uart_send(OK, strlen(OK));
uart_send_ok();
uart_send(hex, strlen(hex));
}
uart_send("\r\n", 2);
}else{
uart_send_err();
}
}
void uart_commands_getserial(error_code* status){
char hex[40];
char digit;
char hex[40];
uint32_t res[4];
iap_read_serial(status, res);
sprintf(hex, "0x%x%x%x%x\r\n", res[0], res[1], res[2], res[3]);
if(*status == 0){
uart_send(OK, 4);
uart_send(hex, 35);
digit_to_str(hex+2, res[0], 16);
hex[0]='0';
hex[1]='x';
if(*status != ok){
uart_send_err();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
}
if(*status == ok){
uart_send_ok();
uart_send(hex, strlen(hex));
digit_to_str(hex, res[1], 16);
uart_send(hex, strlen(hex));
digit_to_str(hex, res[2], 16);
uart_send(hex, strlen(hex));
digit_to_str(hex, res[3], 16);
uart_send(hex, strlen(hex));
uart_send("\r\n", 2);
}
}
crc_t uart_commands_prog(void){
uart_send(OK, 5);
crc_t uart_commands_prog(error_code* status, int size){
char digit;
iap_prepare_sectors(status, addr_to_sector(APP_OFFSET), addr_to_sector(APP_OFFSET+size));
if(*status != ok){
uart_send_err();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
}
iap_erase_sectors(status, addr_to_sector(APP_OFFSET), addr_to_sector(APP_OFFSET+size));
if(*status != ok){
uart_send_err();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
}
iap_prepare_sectors(status, addr_to_sector(APP_OFFSET), addr_to_sector(APP_OFFSET+size));
if(*status != ok){
uart_send_err();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
}
uart_send_ok();
return crc_init();
}
error_code uart_commands_data(error_code* status, int size, crc_t* checksum_global, crc_t checksum_loc, int offset){
char digit;
uart_receive_data(data, size);
crc_t checksum_tmp = crc_init();
checksum_tmp = crc_update(checksum_tmp, data, size);
checksum_tmp = crc_finalize(checksum_tmp);
if(checksum_loc == checksum_tmp){
int tmp = size;
iap_prepare_sectors(status, APP_OFFSET, APP_OFFSET+size/4095+1);
iap_erase_sectors(status, APP_OFFSET, APP_OFFSET+size/4095+1);
iap_prepare_sectors(status, APP_OFFSET, APP_OFFSET+size/4095+1);
while(tmp >= 4096){
iap_copy_to_flash(status, offset/0x1000, &checksum_loc, 4096);
if(*status != ok){
uart_send(ERR, 6);
}
tmp = tmp - 4096;
}
while(tmp >= 1024){
iap_copy_to_flash(status, offset/0x1000, &checksum_loc, 1024);
if(*status != ok){
uart_send(ERR, 6);
}
tmp = tmp - 1024;
}
while(tmp >= 512){
iap_copy_to_flash(status, offset/0x1000, &checksum_loc, 512);
if(*status != ok){
uart_send(ERR, 6);
}
tmp = tmp - 512;
}
while(tmp >= 256){
iap_copy_to_flash(status, offset/0x1000, &checksum_loc, 256);
if(*status != ok){
uart_send(ERR, 6);
}
tmp = tmp - 256;
}
iap_prepare_sectors(status, addr_to_sector(offset), addr_to_sector(offset+size)+1);
*checksum_global = crc_update(*checksum_global, data, size);
//verify if size == 4095 if smaller
if(size == 0x0400)
iap_copy_to_flash(status, (long unsigned int *)offset, data, size);
else{
iap_copy_to_flash(status, (long unsigned int *)offset, data, 0x400);
*checksum_global = crc_finalize(*checksum_global);
}
if(*status != ok){
uart_send_err();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
return *status;
}
uart_send_ok();
return ok;
}else{
uart_send(ERR, 6);
return local_checksum;
uart_send_err();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
}
return local_checksum;
}
error_code uart_commands_check(crc_t crc_received, crc_t crc_calculated){
@ -88,7 +121,9 @@ error_code uart_commands_check(crc_t crc_received, crc_t crc_calculated){
int uart_parse_command(char *user_input, cmd_t *cmd) {
//Initialize a simple command (empty, simple, foreground)
cmd->argv = NULL;
cmd->argv[0] = NULL;
cmd->argv[1] = NULL;
cmd->argv[2] = NULL;
cmd->argc = -1;
//Separate string in different token (i.e. command name + params + &)
@ -96,10 +131,6 @@ int uart_parse_command(char *user_input, cmd_t *cmd) {
//A new element will be added
cmd->argc += 1;
//Allocate a new pointer on char for next argv element
if((cmd->argv = realloc(cmd->argv, (cmd->argc+1)*sizeof(char*))) == NULL)
perror("uart_parse_command::realloc");
//Get the adress of the next token (could be NULL to indicate end of argv)
cmd->argv[cmd->argc] = strtok(user_input, DELIMIERS);
user_input = NULL; //Useless to execute it each time but easier than having two different strtok calls
@ -110,8 +141,20 @@ int uart_parse_command(char *user_input, cmd_t *cmd) {
}
uint32_t uart_string_to_int(const char *str) {
// Convert input in port number
char* tmp;
unsigned long long int hex = strtoull(str, &tmp, 16);
//char* tmp;
//unsigned long long int hex = strtoull(str, &tmp, 16);
unsigned long int hex = strtoul(str, NULL, 16);
return hex;
}
void uart_send_ok(){
uart_send(OK, 4);
}
void uart_send_err(){
uart_send(ERR, 6);
}
void uart_send_cmd_illeg(){
uart_send(CMD_ILLEGAL, 13);
}

View File

@ -7,7 +7,9 @@
#include "crc.h"
#define DELIMIERS ","
#define APP_OFFSET 4
#define LPC1769_FLASH_SIZE 0x80000
#define APP_OFFSET 0x4000
#define MAX_PROG_SIZE (LPC1769_FLASH_SIZE - APP_OFFSET)
@ -18,11 +20,12 @@ typedef struct cmd {
} cmd_t;
void uart_commands_getid(error_code* status);
void uart_commands_getserial(error_code* status);
crc_t uart_commands_prog(void);
crc_t uart_commands_prog(error_code* status, int size);
error_code uart_commands_data(error_code* status, int size, crc_t* checksum_global, crc_t checksum_loc, int offset);
@ -30,4 +33,13 @@ error_code uart_commands_check(crc_t crc_received, crc_t crc_calculated);
int uart_parse_command(char *user_input, cmd_t *cmd);
void uart_send_ok();
void uart_send_err();
void uart_send_cmd_illeg();
void digit_to_str(char* str, uint32_t number, int base);
uint32_t uart_string_to_int(const char* str);

Binary file not shown.