Hello,
I'm still trying to develop my bootloader for MC9S08DZ60.
After I followed the suggestions in this Thread I am facing the problem that my user application doesn't start.
I want to wait for CAN message with ID 0x425 which will start the user application and exit my bootloader. I found a piece of assembly code in this forum which I use:
void CHECK_CAN_MESSAGE (CAN_MESSAGE_t CAN_TMP_MESSAGE){ switch (CAN_TMP_MESSAGE.id.std) { case 0x424 : CopyInRAM(); //WriteFlashRow(CAN_TMP_MESSAGE.databytes); WRITE_TEST (CAN_TMP_MESSAGE.databytes); SET_MESSAGE(RESP_OK); bit_TX = TRUE; break; //if (CAN_TMP_MESSAGE.databytes[0] == 0xaa && CAN_TMP_MESSAGE.databytes[1] == 0xbb) // { //DisableInterrupts; //CopyInRAM(); //EnableInterrupts; // } case 0x425 : __asm{ ldhx 0xC3FE; ldhx ,x jmp ,x }; break; case 0x431 : SET_MESSAGE(TESTMESSAGE); bit_TX = TRUE; break; default : SET_MESSAGE (DEFAULT); bit_TX = TRUE; break; } };
After that nothing happens.
I tried to relocate the interrupt vectors to Address 0xC3C0 but I'm not sure if I had done everything right.
My bootloader application has the following code for vector redirection:
void (* near const BOOT_vect[])(void) @0xFFC0 = { /* Interrupt vector table */ BOOT_ISR_31, /* Int.no. 31 Vacmp2 (at FFC0) Unassigned */ BOOT_ISR_30, /* Int.no. 30 Vacmp1 (at FFC2) Unassigned */ BOOT_ISR_29, /* Int.no. 29 Vcantx (at FFC4) Unassigned */ BOOT_ISR_28, /* Int.no. 28 Vcanrx (at FFC6) CANSetMessage */ BOOT_ISR_27, /* Int.no. 27 Vcanerr (at FFC8) Unassigned */ BOOT_ISR_26, /* Int.no. 26 Vcanwu (at FFCA) Unassigned */ BOOT_ISR_25, /* Int.no. 25 Vrtc (at FFCC) Unassigned */ BOOT_ISR_24, /* Int.no. 24 Viic (at FFCE) Unassigned */ BOOT_ISR_23, /* Int.no. 23 Vadc (at FFD0) Unassigned */ BOOT_ISR_22, /* Int.no. 22 Vport (at FFD2) Unassigned */ BOOT_ISR_21, /* Int.no. 21 Vsci2tx (at FFD4) Unassigned */ BOOT_ISR_20, /* Int.no. 20 Vsci2rx (at FFD6) Unassigned */ BOOT_ISR_19, /* Int.no. 19 Vsci2err (at FFD8) Unassigned */ BOOT_ISR_18, /* Int.no. 18 Vsci1tx (at FFDA) Unassigned */ BOOT_ISR_17, /* Int.no. 17 Vsci1rx (at FFDC) Unassigned */ BOOT_ISR_16, /* Int.no. 16 Vsci1err (at FFDE) Unassigned */ BOOT_ISR_15, /* Int.no. 15 Vspi (at FFE0) Unassigned */ BOOT_ISR_14, /* Int.no. 14 Vtpm2ovf (at FFE2) Unassigned */ BOOT_ISR_13, /* Int.no. 13 Vtpm2ch1 (at FFE4) Unassigned */ BOOT_ISR_12, /* Int.no. 12 Vtpm2ch0 (at FFE6) Unassigned */ BOOT_ISR_11, /* Int.no. 11 Vtpm1ovf (at FFE8) Timer1 */ BOOT_ISR_10, /* Int.no. 10 Vtpm1ch5 (at FFEA) Unassigned */ BOOT_ISR_09, /* Int.no. 9 Vtpm1ch4 (at FFEC) Unassigned */ BOOT_ISR_08, /* Int.no. 8 Vtpm1ch3 (at FFEE) Unassigned */ BOOT_ISR_07, /* Int.no. 7 Vtpm1ch2 (at FFF0) Unassigned */ BOOT_ISR_06, /* Int.no. 6 Vtpm1ch1 (at FFF2) Unassigned */ BOOT_ISR_05, /* Int.no. 5 Vtpm1ch0 (at FFF4) Unassigned */ BOOT_ISR_04, /* Int.no. 4 Vlol (at FFF6) Unassigned */ BOOT_ISR_03, /* Int.no. 3 Vlvd (at FFF8) Unassigned */ BOOT_ISR_02, /* Int.no. 2 Virq (at FFFA) Unassigned */ BOOT_ISR_01 /* Int.no. 1 Vswi (at FFFC) Unassigned */};void (* near const _vectReset[])(void) @0xFFFE = { /* Interrupt vector table */ _Startup /* Int.no. 0 Vreset (at FFFE) Reset vector */};
A interrupt function (i.e. for the timer) contains the following:
interrupt void BOOT_ISR_11 ( void){ if (BOOTLOADERMODE != TRUE) { __asm { ldhx 0xC3E8; //Fetches content of Address jsr ,X //Run Subroutine }; }//end if (BOOTLOADERMODE != TRUE) else { count_5ms++; //Add counter count_10ms++; //Add counter count_50ms++; //Add counter count_1s++; //Add counter bit_1ms = 1; //Set Bit_x = 1 if (count_5ms > 5) { bit_5ms = 1; //Set Bit_x = 1 count_5ms = 0; //Reset counter }//end if (count_5ms > 5) if (count_10ms > 10) { bit_10ms = 1; //Set Bit_x = 1 count_10ms = 0; //Reset counter }//end if (count_10ms > 10) if (count_50ms >50) { bit_50ms = 1; //Set Bit_x = 1 count_50ms = 0; //Reset counter }//endif if (count_50ms >50) if (count_1s >1000) { bit_1s = 1; //Set Bit_x = 1 count_1s = 0; //Reset counter }//endif if (count_1s >1000) TPM1MODH = 0x00; //Modulo High Byte zurücksetzen TPM1MODL = 0xFA; //Modulo Low Byte zurücksetzen TPM1SC &= ~0x80; //Timer 1 Interrupt Flag (TOF-Bit in TPM1C Register) zurücksetzen }//end if (BOOTLOADERMODE == TRUE) };
The interrupts are working properly. But when I want to jump to my user application nothing happens. I've checked the assembly window the first address after the jmp is 4501 with STX ,X and this goes down to C3C0.
My application is stored at address 0x1900 ans Startup code is located at 0x197B.
In my User Application I have:
/*****************************************************************Interrupt vector table*****************************************************************//* Interrupt vector table */#ifndef UNASSIGNED_ISR #define UNASSIGNED_ISR ((void(*near const)(void)) 0xC3FF) //0xFFFF) /* unassigned interrupt service routine */#endifvoid (* near const _vect[])(void) @0xC3C0 = { /* Interrupt vector table geändert von FFC0 auf C3C0*/ UNASSIGNED_ISR, /* Int.no. 31 Vacmp2 (at FFC0) Unassigned */ UNASSIGNED_ISR, /* Int.no. 30 Vacmp1 (at FFC2) Unassigned */ UNASSIGNED_ISR, /* Int.no. 29 Vcantx (at FFC4) Unassigned */ UNASSIGNED_ISR, /* Int.no. 28 Vcanrx (at FFC6) Unassigned */ UNASSIGNED_ISR, /* Int.no. 27 Vcanerr (at FFC8) Unassigned */ UNASSIGNED_ISR, /* Int.no. 26 Vcanwu (at FFCA) Unassigned */ UNASSIGNED_ISR, /* Int.no. 25 Vrtc (at FFCC) Unassigned */ UNASSIGNED_ISR, /* Int.no. 24 Viic (at FFCE) Unassigned */ UNASSIGNED_ISR, /* Int.no. 23 Vadc (at FFD0) Unassigned */ UNASSIGNED_ISR, /* Int.no. 22 Vport (at FFD2) Unassigned */ UNASSIGNED_ISR, /* Int.no. 21 Vsci2tx (at FFD4) Unassigned */ UNASSIGNED_ISR, /* Int.no. 20 Vsci2rx (at FFD6) Unassigned */ UNASSIGNED_ISR, /* Int.no. 19 Vsci2err (at FFD8) Unassigned */ UNASSIGNED_ISR, /* Int.no. 18 Vsci1tx (at FFDA) Unassigned */ UNASSIGNED_ISR, /* Int.no. 17 Vsci1rx (at FFDC) Unassigned */ UNASSIGNED_ISR, /* Int.no. 16 Vsci1err (at FFDE) Unassigned */ UNASSIGNED_ISR, /* Int.no. 15 Vspi (at FFE0) Unassigned */ UNASSIGNED_ISR, /* Int.no. 14 Vtpm2ovf (at FFE2) Unassigned */ UNASSIGNED_ISR, /* Int.no. 13 Vtpm2ch1 (at FFE4) Unassigned */ UNASSIGNED_ISR, /* Int.no. 12 Vtpm2ch0 (at FFE6) Unassigned */ UNASSIGNED_ISR, /* Int.no. 11 Vtpm1ovf (at FFE8) Used */ UNASSIGNED_ISR, /* Int.no. 10 Vtpm1ch5 (at FFEA) Unassigned */ UNASSIGNED_ISR, /* Int.no. 9 Vtpm1ch4 (at FFEC) Unassigned */ UNASSIGNED_ISR, /* Int.no. 8 Vtpm1ch3 (at FFEE) Unassigned */ UNASSIGNED_ISR, /* Int.no. 7 Vtpm1ch2 (at FFF0) Unassigned */ UNASSIGNED_ISR, /* Int.no. 6 Vtpm1ch1 (at FFF2) Unassigned */ UNASSIGNED_ISR, /* Int.no. 5 Vtpm1ch0 (at FFF4) Unassigned */ UNASSIGNED_ISR, /* Int.no. 4 Vlol (at FFF6) Unassigned */ UNASSIGNED_ISR, /* Int.no. 3 Vlvd (at FFF8) Unassigned */ UNASSIGNED_ISR, /* Int.no. 2 Virq (at FFFA) Unassigned */ UNASSIGNED_ISR /* Int.no. 1 Vswi (at FFFC) Unassigned */ //_Startup /* Int.no. 0 Vreset (at FFFE) Reset vector */};void (* near const _vectReset[])(void) @0xC3FE = { /* Interrupt vector table */ _Startup //_EntryPoint /* Int.no. 0 Vreset (at FFFE) Reset vector */};
The Registers in my application code and in my bootloader are initialized with:
/* Initialization of the CPU registers in FLASH *//* NVPROT: EPS=3,FPS=0x3F */const unsigned char NVPROT_INIT @0x0000FFBD = 0xF5; //0xFF;/* NVOPT: KEYEN=0,FNORED=1,EPGMOD=1,SEC1=1,SEC0=0 */const unsigned char NVOPT_INIT @0x0000FFBF = 0x7E;
I don't use interrupts for my Test application at the moment but I will have to use the Timer interrupt.
Does anyone have an idea what is going wrong?
Thank you in advance.
Regards
Michael
已解决! 转到解答。
Hello Michael,
The following portion of your code is incorrect!
case 0x425 : __asm { ldhx 0xC3FE; ldhx ,x jmp ,x }; break;
Either of the following alternatives should work.
case 0x425: __asm { ldhx #0xC3FE; ldhx ,x jmp ,x } break; case 0x425: __asm { ldhx 0xC3FE; jmp ,x } break;
Regards,
Mac
Hello Michael,
The following portion of your code is incorrect!
case 0x425 : __asm { ldhx 0xC3FE; ldhx ,x jmp ,x }; break;
Either of the following alternatives should work.
case 0x425: __asm { ldhx #0xC3FE; ldhx ,x jmp ,x } break; case 0x425: __asm { ldhx 0xC3FE; jmp ,x } break;
Regards,
Mac
Hello Mac,
thank you for your fast reply.
I've changed the code and the now the jump is correct.
But the application still doesn't start. I've tried both portions of code you suggested.
I tried to check step by step and the code stops at address 0x19CB BRCLR 4,0x4B,*+0 ;abs = 0x19CB and it doesn't get further.
But it is possible to go to the "Register"-Window and set the PC Address manually to 0x197B. Then the application code is executed correctly.
Do you have another idea what is the cause for that problem?
Thank you in advance
Best regards
Michael
Hi Michael,
That problem is with your clock generator code.
That instruction is waiting for the "Internal Reference Status" bit (IREFST) in the MCG Status and Control Register (MCGSC) to set. After a synchronization delay, it is meant to reflect the state of the "Internal Reference Select" bit (IREFS) in the MCGC1 register. It is waiting for the switch to the internal clock from the external clock.
Did you intend to switch to the internal clock? I suspect not, as I don't think it is accurate enough for CAN.
Hello Rocco,
thank you for your reply.
Yes you're right. I don't want to switch to the internal clock. The bootloader code initializes an external chrystal to serve the clock. I use a portion of code to set up the register but this is called from the main function.
(The main function calls an other function to init the processor register and the clock as well. I use the same code for the initialisation in my application.)
And according to the data sheet I have to wait between the switches from FEI to PEE mode. But as you mailed this I remember that I had this problem when there was a breakpoint within this function. The switch from FEI to PEE stopped.
(I'm sorry that I don't have the code avaliable at the moment otherwise I would paste it, but it is according to the data sheet).
Do you have an idea how to fix this problem?
Thank you in advance.
Regards
Michael
Hi Michael,
Do you have an idea how to fix this problem?
Without seeing the code, I can only guess. But that's never stopped me before . . .
One possibility is that someone mistyped BRCLR instead of BRSET. Maybe that code should be waiting for a switch to the external clock instead of a switch to the internal clock.
Another possibility is that the code is left over from Processor-Expert or some other "canned" routine that expected to use the internal clock.
I would check both the bootloader and the application to make sure they are agreeing to use the external clock.
Hello Mac,
Hello Rocco,
thank you very much for your kind help.
The problem is solved.
The jump to the start address is working properly when I use the code Mac suggested.
And the application is working properly when I commented out the Function to set the clock.
As I promised in my last post I wanted to provide the Function to set the clock:
void MCG_CLOCK_SET(void){ //Clock Settings für Externe Ozillator 16MHz, mit Ausgang MCGOUT=PPL=32MHz, und BUSCLK=16MHz //Modi werden gewechselt: FEI > FBE > BPLE > PBE > PEE if (*(unsigned char*far)0xFFAF != 0xFF) { /* Test if the device trim value is stored on the specified address */ MCGTRM = *(unsigned char*far)0xFFAF; /* Initialize MCGTRM register from a non volatile memory */ MCGSC = *(unsigned char*far)0xFFAE; /* Initialize MCGSC register from a non volatile memory */ } MCGC2 = 0x36; while((MCGSC & 0x02) != 0x02) { } MCGC1 = 0xB8; while((MCGSC & 0x10) != 0x10) { } while((MCGSC & 0x0C) != 0x08) { } MCGC2 = 0x3E; MCGC1 = 0xA0; MCGC3 = 0x48; //BPLE to PBE MCGC2 &= (unsigned char)~0x08; while((MCGSC & 0x20) != 0x20) { } while((MCGSC & 0x40) != 0x40) { } //PBE to PEE: MCGC1 = 0x20; while((MCGSC & 0x0C) != 0x0C) { }
I don't know why the function wont continue when it is started in this way but I will try to avoid the call, when the bootloader is active.
Thank you.
Michael