Controller crashs always by a PIT0 and/or PIT1 interrupt.
#include "MPC5604B.h" #include "IntcInterrupts.h" void initModesAndClock(void) { ME.MER.R = 0x0000001D; CGM.FMPLL_CR.R = 0x02400100; ME.RUN[0].R = 0x001F0074; ME.RUNPC[0].R = 0x00000010; ME.PCTL[16].R = 0x0000; ME.PCTL[68].R = 0x0000; ME.PCTL[92].R = 0x0000; ME.MCTL.R = 0x40005AF0; ME.MCTL.R = 0x4000A50F; while (ME.IS.B.I_MTC != 1) {} ME.IS.R = 0x00000001; } void initPeriClkGen(void) { CGM.SC_DC[0].R = 0x80; CGM.SC_DC[1].R = 0x80; CGM.SC_DC[2].R = 0x80; } void disableWatchdog(void) { SWT.SR.R = 0x0000c520; SWT.SR.R = 0x0000d928; SWT.CR.R = 0x8000010A; } void Pit0Interrupt(void) { PIT.CH[0].TFLG.R = 0x00000001; } void Pit1Interrupt(void) { PIT.CH[1].TFLG.R = 0x00000001; } void main() { /* Init */ initModesAndClock(); initPeriClkGen(); disableWatchdog(); INTC_InstallINTCInterruptHandler(Pit0Interrupt,59,2); //Channel 0 INTC_InstallINTCInterruptHandler(Pit1Interrupt,60,2); //Channel 1 PIT.PITMCR.R = 0x00000000; PIT.CH[1].LDVAL.R=64000000; PIT.CH[0].LDVAL.R=128000000; PIT.CH[1].TFLG.R = 0x00000001; PIT.CH[0].TFLG.R = 0x00000001; PIT.CH[1].TCTRL.R = 0x00000003; PIT.CH[0].TCTRL.R = 0x00000003; INTC.CPR.B.PRI = 0; for(;;) { } }
Update, but still not working:
#include "MPC5604B.h" #include "IntcInterrupts.h" void initModesAndClock(void) { ME.MER.R = 0x0000001D; /** EXTERNAL CLOCK */ /** Use external clock from crystal oscillator */ /** Use this crystal oscillator in fast mode */ CGM.FXOSC_CTL.B.OSCBYP = 0u; /** Disable slow mode for external clock */ CGM.SXOSC_CTL.R = 0u; /** EXTERNAL CLOCK CONTROL */ /** Disable FMPLL clock monitor */ CGM.CMU_CSR.B.CME_A = 0u; /** Disable frequency measure */ CGM.CMU_CSR.B.SFM = 0u; /** The external clock shall be greater than FIRC(16MHz)/divisor_value[1, 2, 4, 8] * Like external clock is between 4 and 16 MHz so divisor_value = 8. * This condition is always right */ CGM.CMU_CSR.B.RCDIV = 3u; /** PLL COMPUTATION */ /** Disable PLL modulation */ CGM.FMPLL_MR.B.FM_EN = 0u; CGM.FMPLL_CR.R = 0x02400100; ME.RUN[0].R = 0x001F0074; ME.RUNPC[0].R = 0x00000010; ME.PCTL[16].R = 0x0000; ME.PCTL[68].R = 0x0000; ME.PCTL[92].R = 0x0000; ME.MCTL.R = 0x40005AF0; ME.MCTL.R = 0x4000A50F; /** wait transition completed */ while (ME.GS.B.S_MTRANS != 0u) {} /** check clock = 64MHz is stable */ while (ME.GS.B.S_FXOSC != 1u) {} /** check that current mode = RUN0 */ while (ME.GS.B.S_CURRENTMODE != 4u) {} } void initPeriClkGen(void) { CGM.SC_DC[0].R = 0x80; CGM.SC_DC[1].R = 0x80; CGM.SC_DC[2].R = 0x80; } void disableWatchdog(void) { SWT.SR.R = 0x0000c520; SWT.SR.R = 0x0000d928; SWT.CR.R = 0x8000010A; } void Pit0Interrupt(void) { //if( (SIU.PGPDO[0].R & 0x00080000)>0) SIU.PGPDO[0].R &= ~(0x00080000); //else SIU.PGPDO[0].R |= 0x00080000; SIU.GPDO[12].B.PDO ^= 1; if (PIT.CH[0].TFLG.R == 1) PIT.CH[0].TFLG.R = 1; } void Pit1Interrupt(void) { //if( (SIU.PGPDO[0].R & 0x00000002)>0) SIU.PGPDO[0].R &= ~(0x00000002); //else SIU.PGPDO[0].R |= 0x00000002; SIU.GPDO[30].B.PDO ^= 1; if (PIT.CH[1].TFLG.R == 1) PIT.CH[1].TFLG.R = 1; } void main() { /* Init */ initModesAndClock(); initPeriClkGen(); disableWatchdog(); SIU.PCR[12].R = 0x0200; SIU.PCR[30].R = 0x0200; SIU.GPDO[12].B.PDO = 0; SIU.GPDO[30].B.PDO = 0; INTC_InstallINTCInterruptHandler(Pit0Interrupt,59,2); //Channel 0 INTC_InstallINTCInterruptHandler(Pit1Interrupt,60,2); //Channel 1 PIT.PITMCR.R = 0x00000000; PIT.CH[1].LDVAL.R=64000000; PIT.CH[0].LDVAL.R=128000000; PIT.CH[1].TFLG.R = 0x00000001; PIT.CH[0].TFLG.R = 0x00000001; PIT.CH[1].TCTRL.R = 0x00000003; PIT.CH[0].TCTRL.R = 0x00000003; INTC.CPR.R = 0u; for(;;) { //Test without Interrupts ok //if(PIT.CH[0].TFLG.R>0) Pit0Interrupt(); //if(PIT.CH[1].TFLG.R>0) Pit1Interrupt(); } }
解決済! 解決策の投稿を見る。
Hi Martin,
in the linker file MPC5604B_RAM.lcf find group internal_ram and fix the alignment of __unitialized_intc_handlertable to 0x800 instead of your value. Table has to be aligned to 2KB.
Now, it will work.
Regards,
Martin
Hi Martin,
Could you please clarify what the "wrong" mean? Is TFLG set? Have you set EE bit in MSR register? Do you get any IVOR?
In the project I sent you, it is default project from CodeWarrior 2.10. There is no change in IntcInterrupts.c.
If it is possible, share here your whole project. I will check.
Regards,
Martin
Hi Martin,
in the linker file MPC5604B_RAM.lcf find group internal_ram and fix the alignment of __unitialized_intc_handlertable to 0x800 instead of your value. Table has to be aligned to 2KB.
Now, it will work.
Regards,
Martin
The PIT timer is working (I used that example to write my code). The command intc_installINTCInterruptHandler is doing something wrong (Have i to change some settings in IntcInterrupts.c? INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE = 210? function_align = 16?)
Hi,
look at this example. It shows, how to use PIT timer.
Example MPC5604B PinToggleStationery CW210
Regards,
Martin
Replace Instruction?
The problem is the interrupt handler (Setting the TCTRL = 0x00000001 and using lines 91 and 92 the code works)
Place a condition for these:
if (PIT.CH[0].TFLG.R == 1) PIT.CH[0].TFLG.R = 1;
if (PIT.CH[1].TFLG.R == 1) PIT.CH[1].TFLG.R = 1;
no change
Hi,
before line 06 - CGM.FMPLL_CR.R = 0x02400100:
/** EXTERNAL CLOCK */
/** Use external clock from crystal oscillator */
/** Use this crystal oscillator in fast mode */
CGM.FXOSC_CTL.B.OSCBYP = 0u;
/** Disable slow mode for external clock */
CGM.SXOSC_CTL.R = 0u;
/** EXTERNAL CLOCK CONTROL */
/** Disable FMPLL clock monitor */
CGM.CMU_CSR.B.CME_A = 0u;
/** Disable frequency measure */
CGM.CMU_CSR.B.SFM = 0u;
/** The external clock shall be greater than FIRC(16MHz)/divisor_value[1, 2, 4, 8]
* Like external clock is between 4 and 16 MHz so divisor_value = 8.
* This condition is always right
*/
CGM.CMU_CSR.B.RCDIV = 3u;
/** PLL COMPUTATION */
/** Disable PLL modulation */
CGM.FMPLL_MR.B.FM_EN = 0u;
then change lines 15 & 16 (check ME.IS) by:
/** wait transition completed */
while (ME.GS.B.S_MTRANS != 0u) {}
/** check clock = 64MHz is stable */
while (ME.GS.B.S_FXOSC != 1u) {}
/** check that current mode = RUN0 */
while (ME.GS.B.S_CURRENTMODE != 4u) {}
Now your clock configuration is right.
Change line 53 by INTC.CPR.R = 0u;
You can toogle pins at each PIT interrupt to ensure that application runs (SIU.PCR[number_pad].R = 0x0200u; /** output GPIO */ before PIT.PITMCR instruction then SIU.GPDO[number_pad].B.PDO = 0/1u; in PitxInterrupt functions /** low / high-level output state */
still not working
If you use pads 12 & 30 (PA[12] & PB[14]) at lines 70&71 so change your code into Pit0Interrupt & PitInterrupt by:
SIU.GPDO[12].B.PDO ^= 1; for toogle pad of Pit0Interrupt and SIU.GPDO[30].B.PDO ^= 1; for Pit1Interrupt.
After pad initialization at lines 70&71 add following to set default output state: SIU.GPDO[12].B.PDO = 0; and SIU.GPDO[30].B.PDO = 0;
Replace instruction from line 83 to line 72.