Hello,
I have a created a short code to initialise MCU clock before going to _Startup code.
Here is the code.
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include <starts12z.h>
void PLL_init();
void interrupt VectorNumber_Vreset Vreset_ISR();
void interrupt VectorNumber_Vreset Vreset_ISR()
{
PLL_init();
}
void main(void)
{
EnableInterrupts;
/* include your code here */
for(;;) {
__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
void PLL_init()
{
CPMUCLKS_PLLSEL = 1; //FBUS = FPLL/2. FBUS = 32MHz,
CPMUREFDIV_REFFRQ = 1; //Reference clock between 2MHZ and 6MHZ.
CPMUREFDIV_REFDIV = 0x1; //FREF=8/(1+1) = 4MHZ
CPMUSYNR_VCOFRQ = 0x1; //FVCO is between 48MHZ and 80MHZ
CPMUSYNR_SYNDIV = 0x7; //FVCO = 2xFREFx(SYNDIV+1) = FVCO = 2x4x(7+1) = 64MHZ
CPMUPOSTDIV_POSTDIV = 0x0; //FPLL = FVCO/(POSTDIV+1). FPLL = 64MHZ/(0+1) FPLL = 64MHz
CPMUOSC_OSCE = 1; //External oscillator enable. 8MHZ. FREF=FOSC/(REFDIV+1)
while(!CPMUIFLG_LOCK){} // Wait for LOCK.
CPMUIFLG = 0xFF; // clear CMPMU int flags - not needed but good practice
__asm(jmp _Startup); /* Jump to C startup code */
}
I commented this part of code from LCF file
VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */
But the issue is now every time I debug the code with the setting as program entry point, it always jump into the startup code. It never comes to this function PLL_init.
I would like to know how S12ZVC microcontroller is configured for the program startup.
Thank you,
Amit Dhand
解決済! 解決策の投稿を見る。
Hi Amit,
It's true than the example code created it's not working.
I didn't checked it as it was not the problem.
And you're right with PEx code too.
The problem is the same in both cases.
The Stack pointer is not initialized and I don't know exactly how is it defined by default.
Have a look to the cpu.c file.
Extract of void _EntryPoint(void)
{
...
/*lint -save -e950 Disable MISRA rule (1.1) checking. */
__asm(jmp _Startup); /* Jump to C startup code */
/*lint -restore Enable MISRA rule (1.1) checking. */
}
You can see the PEx code is not using c code to call the _Startup but the jmp assembly instruction.
The jmp is not saving the address function on stack.
It's important as the stack is not initialized in _EntryPoint but in _Startup only.
In the PEx example, if you change the code:
++++++++++++++
ISR(Vreset_Interrupt)
{
_EntryPoint();
}
++++++++++++++
by:
++++++++++++++
ISR(Vreset_Interrupt)
{
__asm(jmp _EntryPoint); /* Jump to _EntryPoint code */
}
++++++++++++++
BACK to your Example code.
Just change the code:
void interrupt VectorNumber_Vreset Vreset_ISR();
void interrupt VectorNumber_Vreset Vreset_ISR()
{
__asm(jmp PLL_init);
}
Now it's working.
Have a great day,
Pascal
Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Amit,
I've created a short example based on S12ZVML128.
For the debug option I've selected Stop at entry function.
When I launch the debug session the application is loaded and point to void _Startup(void) function.
Now I added your code and commented the VECTOR 0 _Startup in prm file.
When I launch the Debugger, the application is loaded and point to the void _Startup(void) function too.
However if I click on reset, the application jump to the void interrupt VectorNumber_Vreset Vreset_ISR() function.
It should be the case on your side too.
Now the entry point is defined at _Startup function.
To change it you must define a new one and need to add in prm file (see add the end):
INIT Vreset_ISR
Now when I launch the debugger the application is loaded and point to:
void interrupt VectorNumber_Vreset Vreset_ISR()
Have a great day,
Pascal
Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello Pascal,
Using keyword INIT in LCF file to start from the reset vector is fine. But I observed a weird thing that when the PLL_init function executes the first line of code it jumps to the undefined state.
Then to observe it more clearly I created a ProcessorExpert project for S12ZVC and generated the code.
I got the definition of ISR(Cpu_Interrupt) and I created a similar one for Vreset_ISR which called the _EntryPoint function
ISR(Cpu_Interrupt)
{
/*lint -save -e950 Disable MISRA rule (1.1) checking. */
asm(BGND);
/*lint -restore Enable MISRA rule (1.1) checking. */
}
ISR(Vreset_Interrupt)
{
_EntryPoint();
}
In LCF file
INIT Vreset_Interrupt | /* The entry point of the application. This function is generated into the CPU module. */ |
In vector.c vector table.
_VECTOR(Vreset_Interrupt) | /* 0x00FFFFFC ivVreset | used by PE */ |
When I debug and execute first instruction of the _EntryPoint function, it jumps into this Cpu_Interrupt function and stays there.
Can you help me out on this situation.
Regards,
Amit Dhand
Hi Amit,
It's true than the example code created it's not working.
I didn't checked it as it was not the problem.
And you're right with PEx code too.
The problem is the same in both cases.
The Stack pointer is not initialized and I don't know exactly how is it defined by default.
Have a look to the cpu.c file.
Extract of void _EntryPoint(void)
{
...
/*lint -save -e950 Disable MISRA rule (1.1) checking. */
__asm(jmp _Startup); /* Jump to C startup code */
/*lint -restore Enable MISRA rule (1.1) checking. */
}
You can see the PEx code is not using c code to call the _Startup but the jmp assembly instruction.
The jmp is not saving the address function on stack.
It's important as the stack is not initialized in _EntryPoint but in _Startup only.
In the PEx example, if you change the code:
++++++++++++++
ISR(Vreset_Interrupt)
{
_EntryPoint();
}
++++++++++++++
by:
++++++++++++++
ISR(Vreset_Interrupt)
{
__asm(jmp _EntryPoint); /* Jump to _EntryPoint code */
}
++++++++++++++
BACK to your Example code.
Just change the code:
void interrupt VectorNumber_Vreset Vreset_ISR();
void interrupt VectorNumber_Vreset Vreset_ISR()
{
__asm(jmp PLL_init);
}
Now it's working.
Have a great day,
Pascal
Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Thank you Pascal, I also thought the stack initialisation could be an issue with you. But thanks for confirming it.
Regards,
Amit Dhand
Thank you Pascal, This thing worked out.
Regards,
Amit Dhand