bootloader/uart_commands.c

161 lines
4.0 KiB
C

#include "uart_commands.h"
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] = "0x26113f37\r\n";
char hex[15];
uint32_t res = iap_read_part_id(status);
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();
uart_send(hex, strlen(hex));
uart_send("\r\n", 2);
}else{
uart_send_err();
}
}
void uart_commands_getserial(error_code* status){
char digit;
char hex[40];
uint32_t res[4];
iap_read_serial(status, res);
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(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){
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();
itoa(*status, &digit, 10);
uart_send(&digit, 1);
}
return local_checksum;
}
error_code uart_commands_check(crc_t crc_received, crc_t crc_calculated){
if(crc_received == crc_calculated) return ok;
else return global_checksum;
}
// return: -1 in case of ERR otherwise 0.
int uart_parse_command(char *user_input, cmd_t *cmd) {
//Initialize a simple command (empty, simple, foreground)
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 + &)
do {
//A new element will be added
cmd->argc += 1;
//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
} while (cmd->argv[cmd->argc] != NULL); // while there are still tokens
return 0;
}
uint32_t uart_string_to_int(const char *str) {
//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);
}