196 lines
5.6 KiB
C
196 lines
5.6 KiB
C
#include "bootload.h"
|
|
|
|
//=================================================================================================
|
|
//
|
|
// BOOTLOAD operations
|
|
// This file includes all the bootload functions possible to be called from the bootload dictionary.
|
|
//
|
|
// See description of the commands contained here in shared/shared_dictionaries.h
|
|
//
|
|
//=================================================================================================
|
|
|
|
|
|
//const uint32_t fixed_const __attribute__((at(0x0800F000)));
|
|
//fixed_const= 0xDEADBEEF;
|
|
|
|
//int gSquared __attribute__((at(0x5000))); // Place at 0x5000
|
|
|
|
|
|
/* Desc:Function takes an opcode which was transmitted via USB
|
|
* then decodes it to call designated function.
|
|
* shared_dict_bootload.h is used in both host and fw to ensure opcodes/names align
|
|
* Pre: Macros must be defined in firmware pinport.h & bootload.h
|
|
* opcode must be defined in shared_dict_bootload.h
|
|
* Post:function call complete.
|
|
* Rtn: SUCCESS if opcode found, error if opcode not present or other problem.
|
|
*/
|
|
|
|
uint16_t addrh;
|
|
uint16_t *addr_ptr;
|
|
|
|
typedef void (*pFunction)(void);
|
|
|
|
uint8_t bootload_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
|
|
{
|
|
#define RD_LEN 0
|
|
#define RD0 1
|
|
#define RD1 2
|
|
#define RD2 3
|
|
#define RD3 4
|
|
|
|
#define BYTE_LEN 1
|
|
#define HWORD_LEN 2
|
|
#define WORD_LEN 4
|
|
|
|
pFunction JumpToApplication;
|
|
|
|
switch (opcode) {
|
|
#ifdef STM_CORE
|
|
//case JUMP_BL: jump_to_bootloader(); break;
|
|
//device won't respond after this point so actually expect an error to result
|
|
|
|
case LOAD_ADDRH: addrh = operand; break;
|
|
|
|
case JUMP_ADDR: //jump2addr((addrh<<16) | (operand)); break;
|
|
JumpToApplication = (void (*)(void)) ((addrh<<16|operand)); //Base of flash
|
|
//JumpToApplication = (void (*)(void)) (*((uint32_t *) ((0x1FFFC400 + 4)))); //jump to vector
|
|
JumpToApplication();
|
|
break;
|
|
//device may not respond depending on the address/function being jumped to
|
|
|
|
case PREP_FWUPDATE:
|
|
//while we are directly jumping to fwupdate section
|
|
//it should be okay since it's in a fixed location
|
|
return fwupdate_forever(); break;
|
|
//this function hijacked the stack frame to steal execution
|
|
//after returing from the current USB ISR
|
|
//it returns SUCCESS if it found and modified
|
|
//the stack frame successfully
|
|
//if it didn't find the stack frame it probably exceeded SRAM
|
|
//space and caused a hardfault.
|
|
//Once the USB ISR is completed, exectution left main application code for good
|
|
//will respond to usb interrupts, but are directed to fwupdater
|
|
|
|
case SET_PTR_HI:
|
|
addr_ptr = (uint16_t*) ((((uint32_t)addr_ptr) & 0x0000FFFF) | (operand<<16));
|
|
break;
|
|
|
|
case SET_PTR_LO:
|
|
addr_ptr = (uint16_t*) ((((uint32_t)addr_ptr) & 0xFFFF0000) | (operand));
|
|
break;
|
|
|
|
case GET_PTR:
|
|
//update ptr with offset
|
|
rdata[RD_LEN] = WORD_LEN;
|
|
rdata[RD0] = (uint32_t)addr_ptr;
|
|
rdata[RD1] = ((uint32_t)addr_ptr)>>8;
|
|
rdata[RD2] = ((uint32_t)addr_ptr)>>16;
|
|
rdata[RD3] = ((uint32_t)addr_ptr)>>24;
|
|
break;
|
|
|
|
case RD_PTR_OFFSET:
|
|
//use offset from current pointer but don't change it
|
|
rdata[RD_LEN] = HWORD_LEN;
|
|
rdata[RD0] = addr_ptr[operand];
|
|
rdata[RD1] = (addr_ptr[operand])>>8;
|
|
break;
|
|
|
|
case WR_PTR_OFFSET:
|
|
//use offset from current pointer but don't change it
|
|
addr_ptr[miscdata] = operand;
|
|
break;
|
|
|
|
case RD_PTR_OFF_UP:
|
|
//update ptr with offset
|
|
addr_ptr += operand;
|
|
rdata[RD_LEN] = HWORD_LEN;
|
|
rdata[RD0] = *addr_ptr;
|
|
rdata[RD1] = (*addr_ptr)>>8;
|
|
break;
|
|
|
|
case WR_PTR_OFF_UP:
|
|
//update ptr with miscdata
|
|
addr_ptr += miscdata;
|
|
//write operand to address that's being pointed to
|
|
*addr_ptr = operand;
|
|
break;
|
|
|
|
//can't get this to go where I want 0x08000800
|
|
//so for now I'll just put it there manually post-build
|
|
//can use the pointer to read 4bytes at 0x08000800
|
|
//which is the begining of application code space
|
|
//should include ascii "AV00" with the digits for version
|
|
// case GET_APP_VER:
|
|
// rdata[RD_LEN] = WORD_LEN;
|
|
// rdata[RD0] = app_version[0];
|
|
// rdata[RD1] = app_version[1];
|
|
// rdata[RD2] = app_version[2];
|
|
// rdata[RD3] = app_version[3];
|
|
// break;
|
|
|
|
default:
|
|
//opcode doesn't exist
|
|
return ERR_UNKN_BOOTLOAD_OPCODE;
|
|
#endif
|
|
}
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
//void jump_to_bootloader()
|
|
//{
|
|
//
|
|
//#ifdef STM_INL6
|
|
//// 070C6 jump to: 0x1FFFC519
|
|
//// 070RB jump to: 0x1FFFCBC1
|
|
//
|
|
//
|
|
// asm(
|
|
// //"ldr pc, boot_addr\n\t"
|
|
//// "ldr r0, =0x12345678\n\t"
|
|
//// "mov r0, r0\n\t"
|
|
//// "mov r0, r0\n\t"
|
|
// //".p2align 2\n\t"
|
|
// //"boot_addr:\n\t"
|
|
// //".word 0x1FFFC519"
|
|
// "ldr r0, [pc, #8]\n\t"// @ remember pc is 8 bytes ahead
|
|
// "mov r13, r0\n\t" //load main stack pointer
|
|
// "ldr r0, [pc, #8]\n\t"// @ remember pc is 8 bytes ahead
|
|
// //"mov lr, r0\n\t"
|
|
// //"bx lr \n\t"// @ function return
|
|
// //"bkpt\n\t"
|
|
// "mov r0, r0\n\t"
|
|
// //"mov pc, r0\n\t"
|
|
// "bx r0\n\t"
|
|
// //"bootaddr\n\t"//
|
|
// //".word 0x1FFFC519" //070C6
|
|
// ".p2align 2\n\t"
|
|
// ".word 0x20001278\n\t" //C6 MSP @ reset
|
|
//// ".word 0x00010002\n\t"
|
|
// //".word 0x00030004\n\t"
|
|
// //".word 0x1FFFC519\n\t" //C6 AN2606
|
|
// ".word 0x1FFFCAC5\n\t" //C6 BL reset vector
|
|
// //".word 0x1FFFCBC1\n\t" //stlink PC when connecting with BL grounded
|
|
// //".word 0x1FFFC919\n\t" //best guess based on C6
|
|
// //".word 0x1FFFCBC1\n\t" //bootloader reset vector
|
|
// ".word 0x00050006\n\t"
|
|
// ".word 0x00070008\n\t"
|
|
//// ".word 0x1FFFC919\n\t"
|
|
//// ".word 0x1FFFC919\n\t"
|
|
//// ".word 0x1FFFC919\n\t"
|
|
//// ".word 0x1FFFC919\n\t"
|
|
//// ".word 0x1FFFC919\n\t"
|
|
// ".word 0x1FFFC919"
|
|
// //".word 0x1FFFCBC1"
|
|
// );
|
|
//bootaddr:
|
|
// asm(
|
|
// ".word 0xDEADBEEF"
|
|
// );
|
|
//
|
|
//#endif
|
|
//
|
|
//
|
|
//}
|