#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 // // //}