ME11C Sample Code in Maxim Integrated Team
Dependencies: BMI160 max32630hsp3 MemoryLCD USBDevice
Fork of Host_Software_MAX32664GWEC_SpO2_HR-_EXTE by
bootloader/bootldrAPI.cpp
- Committer:
- seyhmus.cacina
- Date:
- 2019-03-18
- Revision:
- 0:b259fd1a88f5
File content as of revision 0:b259fd1a88f5:
/*
* bootldrInterface.cpp
*
* Created on: Feb 7, 2019
* Author: Yagmur.Gok
*/
#include <mbed.h> /*for type definitions*/
#include "bootldrAPI.h"
#include "SHComm.h"
#include "demoDefinitions.h"
//extern Serial daplink;
//#define SERIALOUT printf
//#define SERIALIN printf
#define COMM_SUCCESS 0
#define COMM_GENERAL_ERROR -1
#define COMM_INVALID_PARAM -254
#define COMM_NOT_RECOGNIZED -255
#define BL_FLASH_ERR_GENERAL -1
#define BL_FLASH_ERR_CHECKSUM -2
#define BL_FLASH_ERR_AUTH -3
#define BL_SET_NUM_PAGES_FAIL -4
#define BL_FLASS_ERASE_FAIL -5
#define BL_SET_IV_FAIL -6
#define BL_FLASHING_FAIL -7
#define BL_RAM_ALLOC_FAIL -8
#define AES_NONCE_SIZE 11
#define AES_AUTH_SIZE 16
#define BOOTLOADER_MAX_PAGE_SIZE (8192)
#define CHECKBYTES_SIZE (16)
#define FLASHCMDBYTES (2)
#define SS_BOOTLOADER_ERASE_DELAY 700
#define AES_NONCE_SIZE 11
#define AES_AUTH_SIZE 16
#define MAX_PAGE_SIZE 8192
#define CHECKBYTES_SIZE 16
#define PAGE_WRITE_DELAY_MS 170
#define MAX_PAGE_NUMBER 31
#define PAGE_ERASE_CMD_SLEEP_MS 50
#define BL_CFG_SAVE_CMD_SLEEP_MS 50
static int parse_iv(const char* cmd, uint8_t* iv_bytes);
static int parse_auth(const char* cmd, uint8_t *auth_bytes);
static int is_hub_ready_for_flash(void);
static void clear_state_info(void);
typedef struct {
int num_allocated_pages; /* Allocated page size */
int num_pages;
int num_received_pages;
int page_size;
uint8_t auth[AES_AUTH_SIZE];
uint8_t nonce[AES_NONCE_SIZE];
uint8_t pages[MAX_PAGE_NUMBER * (MAX_PAGE_SIZE + CHECKBYTES_SIZE)]; //TODO: Use dynamic allocation
} app_image_t;
static app_image_t *app_image = NULL;
static struct {
uint32_t num_pages;
uint32_t page_size;
uint32_t hub_mode_bootloader;
uint32_t is_iv_set;
uint32_t is_auth_done;
uint32_t is_flash_erased;
uint32_t flag_image_on_ram;
uint32_t bootcmds_delay_factor;
uint32_t ebl_mode;
}bootldrState = { 0 , 0 , 0 ,0 , 0 , 0 , 0 , 1 ,1};
int BOOTLDR_get_host_bootloader_state(const char *null_arg){
SERIALOUT(" \r\n BOOT STATE INFO: \r\n num_pages= %d \r\n page_size= %d \r\n is_iv_set= %d \r\n is_auth_done= %d \r\n is_flash_erased= %d \r\n flag_image_on_ram= %d \r\n bootcmds_delay_factor= %d \r\n ebl_mode= %d \r\n",
bootldrState.num_pages,
bootldrState.page_size,
bootldrState.is_iv_set,
bootldrState.is_auth_done,
bootldrState.is_flash_erased,
bootldrState.flag_image_on_ram,
bootldrState.bootcmds_delay_factor,
bootldrState.ebl_mode );
}
int SH_BOOTLDR_enter_blmode(const char *null_arg){
int status = 0x00;
//status = sh_put_in_bootloader();
//status = sh_set_ebl_mode((uint8_t)1); /* 1: GPIO rest 0: CMD reset*/
if( status == 0x00) {
//////////status = sh_reset_to_bootloader(); - CHECKIF PROBLEM STILL PRESENT!!
status = sh_debug_reset_to_bootloader();
//status = sh_set_sensorhub_operating_mode((uint8_t)0x08);
if (status == 0x00) {
SERIALOUT("\r\n%s err=%d\r\n", "bootldr", COMM_SUCCESS);
bootldrState.hub_mode_bootloader = 1;
}
else
SERIALOUT("\r\n%s err=%d\r\n", "bootldr", COMM_GENERAL_ERROR);
}
return status;
}
int SH_BOOTLDR_exit_blmode(const char *null_arg){
int status;
status = sh_reset_to_main_app() ; //sh_exit_from_bootloader();
if (status == 0x00)
printf("\r\n exited from bootloader mode \r\n");
if (status == 0x00) {
SERIALOUT("\r\n%s err=%d\r\n", "exit", COMM_SUCCESS);
bootldrState.hub_mode_bootloader = 0;
}
else
SERIALOUT("\r\n%s err=%d\r\n", "exit", COMM_GENERAL_ERROR);
return status;
}
int SH_BOOTLOADER_image_on_ram( const char *arg ){
int status = COMM_SUCCESS;
int tmp;
sscanf(arg, "%*s %d", &tmp );
bootldrState.flag_image_on_ram = (tmp > 0)? 1:0 ;
if(tmp == 1){
app_image = (app_image_t*) malloc(sizeof(*app_image));
if(app_image != NULL){
app_image->num_allocated_pages = MAX_PAGE_NUMBER;
app_image->num_pages = 0;
app_image->num_received_pages = 0;
app_image->page_size = MAX_PAGE_SIZE;
//app_image->nonce = {0};
//app_image->auth = {0};
//app_image->pages = {0};
}else {
SERIALOUT("Memory allocation fail for ram image \r\n");
status = BL_RAM_ALLOC_FAIL;
}
}
SERIALOUT("\r\n%s err=%d\r\n", "image_on_ram", COMM_SUCCESS);
}
int SH_BOOTLDR_get_pagesz(const char *null_arg){
int status;
int pageSize;
if (bootldrState.flag_image_on_ram) {
SERIALOUT("\r\n%s value=%d err=%d\r\n", "page_size", MAX_PAGE_SIZE, COMM_SUCCESS);
app_image->page_size = MAX_PAGE_SIZE;
bootldrState.page_size = MAX_PAGE_SIZE;
SERIALOUT("\r\n%s err=%d\r\n", "image_on_ram", 1);
}else {
status = sh_get_bootloader_pagesz(&pageSize);
if (status == 0x00 ){
if( pageSize == -2){
SERIALOUT("\r\n Page size over maximum allowable \r\n");
status = -1;
}else {
SERIALOUT("\r\n%s value=%d err=%d\r\n", "page_size", pageSize, status);
bootldrState.page_size = pageSize;
}
}else
SERIALOUT("\r\n%s err=%d\r\n", "page_size", status);
}
return status;
}
int SH_BOOTLDR_set_pagecount(const char *arg){
int status = -1;
int pageCount;
if(sscanf(arg, "%*s %d", &pageCount)){
if(bootldrState.flag_image_on_ram){
app_image->num_pages = (pageCount <= MAX_PAGE_NUMBER)? pageCount:0;
app_image->num_allocated_pages = MAX_PAGE_NUMBER;
bootldrState.num_pages = app_image->num_pages;
}else {
status = sh_set_bootloader_numberofpages(pageCount);
if (status == 0x00){
bootldrState.num_pages = pageCount;
}else
bootldrState.num_pages = 0;
}
}
SERIALOUT("\r\n%s err=%d\r\n", "num_pages", status);
return status;
}
int SH_BOOTLDR_set_iv(const char *arg) {
uint8_t iv_bytes[AES_NONCE_SIZE];
int status = parse_iv(arg, &iv_bytes[0]);
if( status == 0x00){
if(bootldrState.flag_image_on_ram){
int i=0;
for(i = 0 ; i != AES_NONCE_SIZE ; i++)
app_image->nonce[i] = iv_bytes[i];
bootldrState.is_iv_set = 1;
}else {
status = sh_set_bootloader_iv(iv_bytes);
if( status == 0x00 ) {
bootldrState.is_iv_set = 1;
}
else {
bootldrState.is_iv_set = 0;
status = COMM_GENERAL_ERROR;
}
}
}
SERIALOUT("\r\n%s err=%d\r\n", "set_iv", status);
return status;
}
int SH_BOOTLDR_set_authentication(const char *arg){
uint8_t auth_bytes[AES_AUTH_SIZE];
int status = parse_auth(arg, &auth_bytes[0]);
if( status == 0x00){
if(bootldrState.flag_image_on_ram){
int i=0;
for(i = 0 ; i != AES_AUTH_SIZE ; i++)
app_image->auth[i] = auth_bytes[i];
bootldrState.is_auth_done = 1;
}else {
status = sh_set_bootloader_auth(auth_bytes);
if( status == 0x00 ){
bootldrState.is_auth_done = 1;
}
else
status = COMM_GENERAL_ERROR;
}
}
SERIALOUT("\r\n%s err=%d\r\n", "set_auth", status);
return status;
}
int SH_BOOTLDR_eraseflash(const char *null_arg){
int status;
if(bootldrState.flag_image_on_ram){
SERIALOUT("\r\n%s err=%d\r\n", "erase", COMM_SUCCESS);
status == 0x00 /*SS_SUCCESS*/;
}else {
status = sh_set_bootloader_erase();
if(status == 0x00 /*SS_SUCCESS*/) {
bootldrState.is_flash_erased = 1;
}else{
status = COMM_GENERAL_ERROR;
}
SERIALOUT("\r\n%s err=%d\r\n", "erase", status);
}
return status;
}
int SH_BOOTLDR_receive_image_to_ram(void){
int status;
int totalBytes = 0;
int currentPage = 1;
if( app_image != NULL && app_image->num_allocated_pages > 0) {
uint8_t *page = &app_image->pages[0];
uint32_t offset = 0;
while (currentPage <= app_image->num_pages) {
while (totalBytes < (MAX_PAGE_SIZE + CHECKBYTES_SIZE)) {
page[totalBytes++] = SERIALIN(); // daplink.getc(); ; /////////////////////////////////////////////////////m_USB->_getc();
}
currentPage++;
SERIALOUT("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
offset += MAX_PAGE_SIZE + CHECKBYTES_SIZE;
page = &app_image->pages[offset];
totalBytes = 0;
}
app_image->num_received_pages = currentPage;
status = COMM_SUCCESS;
}else
status = COMM_GENERAL_ERROR;
return status;
}
int SH_BOOTLDR_flash_pages(void){
int totalBytes = 0;
int currentPage = 1;
char charbuf_flash[256];
int data_len_flash = 0;
int status;
static uint8_t tx_buf[ BOOTLOADER_MAX_PAGE_SIZE + CHECKBYTES_SIZE + FLASHCMDBYTES] = { SS_FAM_W_BOOTLOADER, SS_CMDIDX_SENDPAGE };
uint8_t *data_buffer = &tx_buf[2];
if(!is_hub_ready_for_flash()){
printf("missing condition for flashing: no page size , no page number, iv notset , no outhentication , flash noterased or mode is not bootloader!\r\n");
clear_state_info();
return -1;
}
printf(" \r\n NOW WE ARE FLASHING THE PAGES..........\r\n");
printf(" \r\n page_size: %d \r\n", bootldrState.page_size);
printf(" \r\n num_pages: %d \r\n", bootldrState.num_pages);
while (currentPage <= bootldrState.num_pages) {
while (totalBytes < (bootldrState.page_size + CHECKBYTES_SIZE)) {
data_buffer[totalBytes++] = SERIALIN(); //daplink.getc(); //m_USB->_getc(); !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MYG
//Here we should be able to take the data over BLE
}
printf(" \r\n NOW WE GOT A PAGE..........\r\n");
//status = sh_bootloader_flashpage(&tx_buf[0] , bootldrState.page_size);
status = sh_write_cmd(tx_buf, bootldrState.page_size + CHECKBYTES_SIZE + 2, 2000);
if (status == 0x00)
printf(" \r\n NOW WE PUSHED A PAGE..........\r\n");
/*
if (status == 0x00){
currentPage++;
SERIALOUT("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
}else{
if (status == SS_ERR_BTLDR_CHECKSUM)
SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_CHECKSUM);
else
SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_GENERAL);
}
*/
if (status == SS_ERR_BTLDR_CHECKSUM) {
data_len_flash = snprintf(charbuf_flash, sizeof(charbuf_flash), "\r\npageFlashDone err=%d\r\n", FLASH_ERR_CHECKSUM);
SERIALOUT(charbuf_flash);
} else if (status != SS_SUCCESS) {
data_len_flash = snprintf(charbuf_flash, sizeof(charbuf_flash), "\r\npageFlashDone err=%d\r\n", FLASH_ERR_GENERAL);
SERIALOUT(charbuf_flash);
} else {
currentPage++;
data_len_flash = snprintf(charbuf_flash, sizeof(charbuf_flash), "\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
SERIALOUT(charbuf_flash);
}
totalBytes = 0;
}
//SERIALOUT(" all pages are flashed \r\n");
clear_state_info();
return status;
}
int SH_BOOTLDR_flash(const char *null_arg){
int status;
if(bootldrState.flag_image_on_ram)
status = SH_BOOTLDR_receive_image_to_ram();
else
status = SH_BOOTLDR_flash_pages();
SERIALOUT("\r\n%s err=%d\r\n", "flash", status);
return status;
}
int SH_BOOTLDR_flash_appimage_from_ram(const char *null_arg){
int currentPage = 1;
uint32_t offset = 0;
int ret;
if(app_image == NULL)
return -1;
/* Put device to bootloader mode */
int status = SH_BOOTLDR_enter_blmode(NULL);
if( status != 0x00)
return -1;
wait_ms(10);
status = sh_set_bootloader_numberofpages(app_image->num_pages);
SERIALOUT("*** set_num_page... ret: %d\n", ret);
if (status != 0x00) {
return BL_SET_NUM_PAGES_FAIL;
}
status = sh_set_bootloader_iv(app_image->nonce);
SERIALOUT("*** set_iv... ret: %d\n", ret);
if (status != 0) {
return BL_SET_IV_FAIL;
}
status = sh_set_bootloader_auth(app_image->auth);
SERIALOUT("*** set_auth... ret: %d\n", ret);
if (status != 0) {
return BL_FLASH_ERR_AUTH;
}
status = sh_set_bootloader_erase() ;
SERIALOUT("*** erase app memory... ret: %d\n", ret);
if (status != 0) {
return BL_FLASS_ERASE_FAIL;
}
static uint8_t tx_buf[MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2];
tx_buf[0] = SS_FAM_W_BOOTLOADER;
tx_buf[1] = SS_CMDIDX_SENDPAGE;
while (currentPage <= app_image->num_pages) {
memcpy(&tx_buf[2], &app_image->pages[offset], MAX_PAGE_SIZE + CHECKBYTES_SIZE);
status = sh_write_cmd(tx_buf, MAX_PAGE_SIZE + CHECKBYTES_SIZE + 2, bootldrState.bootcmds_delay_factor * PAGE_WRITE_DELAY_MS);
if (status == SS_ERR_BTLDR_CHECKSUM) {
SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_CHECKSUM);
break;
} else if (status != SS_SUCCESS) {
SERIALOUT("\r\npageFlashDone err=%d\r\n", BL_FLASH_ERR_GENERAL);
break;
} else {
SERIALOUT("\r\npageFlashDone err=%d\r\n", COMM_SUCCESS);
}
offset += MAX_PAGE_SIZE + CHECKBYTES_SIZE;
currentPage++;
}
return COMM_SUCCESS;
}
int SH_BOOTLDR_set_host_ebl_mode(const char *arg) {
int status;
int tmp;
sscanf(arg, "%*s %*s %*s %d", &tmp);
status = sh_set_ebl_mode(tmp);
if( status == 0x00) {
bootldrState.ebl_mode = tmp;
}else
status = COMM_INVALID_PARAM;
SERIALOUT("\r\n%s err=%d\r\n", "set_cfg host ebl",status);
return status;
}
int SH_BOOTLDR_get_host_ebl_mode(const char *null_arg){
int value;
value = sh_get_ebl_mode();
SERIALOUT("\r\n%s value=%s\r\n", "get_cfg host ebl", (value==1)? "GPIO_RST_MODE":"CMD_RST_MODE");
return 0x00;
}
int SH_BOOTLDR_set_host_bootcmds_delay_factor( const char *arg) {
int status;
int tmp;
sscanf(arg, "%*s %*s %*s %d", &tmp);
status = sh_set_bootloader_delayfactor( tmp);
if( status == 0x00) {
bootldrState.bootcmds_delay_factor = tmp;
}else
status = COMM_INVALID_PARAM;
SERIALOUT("\r\n%s err=%d\r\n", "set_cfg host cdf",status);
return status;
}
int SH_BOOTLDR_get_host_bootcmds_delay_factor( const char *null_arg){
int value;
value = sh_get_bootloader_delayfactor();
SERIALOUT("\r\n%s value=%d \r\n", "get_cfg host cdf", value);
return 0x00;
}
static int is_hub_ready_for_flash(void){
int status = 0;
if( bootldrState.hub_mode_bootloader == 1 &&
bootldrState.is_auth_done == 1 &&
bootldrState.is_iv_set == 1 &&
bootldrState.is_flash_erased == 1 &&
bootldrState.num_pages > 0 &&
bootldrState.page_size > 0 )
status = 1;
return status;
}
static void clear_state_info(void) {
bootldrState.is_auth_done = 0;
bootldrState.is_iv_set = 0;
bootldrState.is_flash_erased = 0;
bootldrState.num_pages = 0;
bootldrState.page_size = 0;
bootldrState.hub_mode_bootloader;
return;
}
static int parse_iv(const char* cmd, uint8_t* iv_bytes) {
int status = 0x00;
char cmdStr[] = "set_iv ";
int length = strlen(cmd);
int expected_length = strlen(cmdStr) + 2*AES_NONCE_SIZE;
if (length != expected_length) {
SERIALOUT("Couldn't parse IV, incorrect number of characters (len:%d, expected:%d)\n",
length, expected_length);
status = COMM_INVALID_PARAM;
}else{
const char* ivPtr = cmd + strlen(cmdStr);
int num_found;
int byteVal;
for (int ividx = 0; ividx < AES_NONCE_SIZE; ividx++) {
num_found = sscanf(ivPtr, "%2X", &byteVal);
if (num_found != 1 || byteVal > 0xFF) {
status = COMM_INVALID_PARAM;
//break; //
return status;
}
iv_bytes[ividx] = (uint8_t)byteVal;
ivPtr += 2;
}
}
return status;
}
static int parse_auth(const char* cmd, uint8_t *auth_bytes){
int status = 0x00;
char cmdStr[] = "set_auth ";
int length = strlen(cmd);
int expected_length = strlen(cmdStr) + 2*AES_AUTH_SIZE;
if (length != expected_length) {
status = -1;
}else{
const char* macPtr = cmd + strlen(cmdStr);
int num_found;
int byteVal;
for (int aidx = 0; aidx < AES_AUTH_SIZE; aidx++) {
num_found = sscanf(macPtr, "%2X", &byteVal);
if (num_found != 1 || byteVal > 0xFF) {
status = COMM_INVALID_PARAM;;
//break; //
return status;
}
auth_bytes[aidx] = (uint8_t)byteVal;
macPtr += 2;
}
}
return status;
}
