MCF5282 - problem with PIT (?) or exception vector (?) & monitoring registers

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF5282 - problem with PIT (?) or exception vector (?) & monitoring registers

2,268 Views
Hagar
Contributor I

I am trying to make the CF generate a “RTC” that I can use for multi-purpose functions.

 

I thought about using one of the PIT for incrementing a counter.

I created a structure with multiple counter entities:

 

typedef struct

{

  uint16 ledCounter;

  uint32 secondsCounter;

  uint16 systemCounter;

} RTcounters;

 

and an Update procedure

void updateRTcounters( void )

{

  static uint16 count = 0;

 

  g_RTcounters.systemCounter++;

  g_RTcounters.ledCounter++;

    

  count++;

 

  if( count >= ONE_SECOND_CONSTANT)

  {

    g_RTcounters.secondsCounter++;

    count = 0;

  }

 

}

 

where the ONE_SECOND_CONSTANT and g_RTcounters are as follows:

 

#define ONE_SECOND_CONSTANT   4000   /* 4000 * 250us = 1s. */

RTcounters g_RTcounters;

 

That would update all counters every time this PIT0 count reaches zero, when I reload it to my constant and start over (forever).

My PIT initialization is as follows:

 

/******************************

 * Timer 0: Ticks every 250us *

 ******************************/

void pit_init_0()

{

  /* Timer setup for continuous interrupts every 250us. */

 

  MCF_PIT0_PCSR = 0x021E; /* RES=0, PRE=2 (64MHz/8 = 8MHz = 125ns), RES=0, DOZE=0

                                                                                                                                                                       HALT=0, OVW=1, PIE=1, PIF=1, RLD=1, EN=0. */

  MCF_PIT0_PMR = 1999;    /* 125ns * 2000 = 250us. */

  MCF_PIT0_PCSR |= MCF_PIT_PCSR_EN; /* Enable. */

}

 

Using this idea I can implement for example a toggle for an LED using one of the counters (ledCounter) in the following procedure (LED would be located on PORT E, with option for another one in PORT TD):

void flashDebugLed2( void )

{

  if (g_RTcounters.ledCounter >= 4000)

  {

    //Toggle LED 2

    MCF5282_GPIO_PORTE ^= 0x01;

    MCF5282_GPIO_PORTTD ^= 0x01;

    g_RTcounters.ledCounter = 0;

  }

}

 

So in the initialization of the system routine I unmasked this particular interruption

void __initialize_system(void)

{

  MCF_INTC0_IMRL = 0xFFFFFFFF;  /* int 1-31 masked. */

 

  MCF_INTC0_IMRH = 0xFF7FFFFF;  /* int 55 active, all other masked. */

 

  /* Other peripherals. */ 

  MCF_INTC0_ICR55 = 0x34;    /* Level 6, priority 4  - PIT0. */

 

}

 

Then in my exception.c I added the following code:

/********************************************************************/

__declspec(interrupt) void irq_handler (void)
{
 printf("irq_handler\n");
 /* empty */
}

/********************************************************************/

__interrupt__
void pit0_handler (void)
{
 //Clear IRQ
 MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF;
 
 //Update all periodic counters
  updateRTcounters();
   
}

and finally, I changed on my vector table the call from:

  asm_exception_handler,           /* 119 (0x___) Reserved                   */
to:

   pit0_handler,              /* 119 (0x___) Reserved                   */

 

And I monitor my count variable and it is not incrementing, so my routine updateRTcounters is never called. So, I cannot say if my PIT is not working or if my expection implementation is not properly set.

 

I tried to look at the registers, but my register windows (view-> registers) only shows values for the general purpose registers, EMAC Registers and supervisor registers. All other registers appears as unavailable or  write only (when this is the case). So, I cannot see the contents of the register while I am debugging, even the register details gives me Debugger Error 104100 (unless I am missing something stupid).

 

 

I am using MCF5282 on its evaluation board, CodeWarrior Development Studio 5.9.0 and I need HELP!

Labels (1)
0 Kudos
5 Replies

584 Views
RichTestardi
Senior Contributor II
If your register window doesn't show you your peripheral registers, try setting the Target Processor drop-down entry in your target settings -> Debugger -> CF Debugger Settings dialog box.
 
If it helps, here is pit code, attached, that works for MCF52221/52233 (and MCF51JM128, which you can ignore) which should be very nearly identical to the pit you are using.
 
-- Rich
0 Kudos

584 Views
Hagar
Contributor I
Hi Rich!
 
I am still experiencing some problems. Now that I can monitor the registers (thanks to you), I can go a little deeper, but with no joy. Apparently my PIT is set correctly and by that I mean that my registers were set properly and I have the following information on the registers, after I am running, in a given moment:
 
For the PIT0:
 
PCSR0 = 0x021F
PMR0 = 0x07CF /*1999*/
PCNTR0 = 0x0025 /* that seams ok, as we would expect something smaller than 0x07CF.*/
 
For the Int Controller 0:
 
IPRH0 = 0x00800000 /* this bothers me. It says that there is a pending int request (at least at the correct spot) but this never goes away. Could that mean that the int handler routine is never executed and the flag is never cleared? */
IPRL0 = 0x00000000
IMRH0 = 0xFD7FFFFF /* Int 55 and 57 enable. Currently I am not doing anything with PIT2. */
IMRL0 = 0xFFFFFFFE /* I thought it would be safer to set bit 0 = 0. */
both INTFRCH0 and INTFRCL0 = 0
I set ICR055 to 0x34
 
So, PIT is up and running and generating  int request that is never treated.
 
In my exception.c file (generated by the system), I added:
 
/********************************************************************/
__declspec(interrupt) void irq_handler (void)
{
 printf("irq_handler\n");
 /* empty */
}
/********************************************************************/
__interrupt__
void pit0_handler (void)
{
 //Clear IRQ
 MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF;
 
 //Update all periodic counters
  updateRTcounters();
   
}
and in a header file I have the declaration:
 
#define __interrupt__ __declspec(interrupt)
 
and them I changed the call at position /* 119 on my vector table, to go to my pit0_handler routine.
 
typedef void (* vectorTableEntryType)(void);
#pragma define_section vectortable ".vectortable" far_absolute R
/* CF have 255 vector + SP_INIT in the vector table (256 entries) */
__declspec(vectortable) vectorTableEntryType _vect[256] = {   /* Interrupt vector table */
   (vectorTableEntryType)__SP_AFTER_RESET,  /*   0 (0x000) Initial supervisor SP      */
_startup,                        /*   1 (0x004) Initial PC                 */
asm_exception_handler,           /*   2 (0x008) Access Error               */
asm_exception_handler,           /*   3 (0x00C) Address Error              */
asm_exception_handler,           /*   4 (0x010) Illegal Instruction        */
asm_exception_handler,           /*   5 (0x014) Reserved                    */ 
...
asm_exception_handler,           /* 118 (0x___) Reserved                   */
pit0_handler,                              /* 119 (= 0x77) (0x___) Reserved                   */
asm_exception_handler,           /* 120 (0x___) Reserved                   */
...
 
If I look in memory at the position where the vector_table is assembled, I see that it is pointing to the corret routine, but this is never executed (the pit0_handler).
 
My question is: with the debugger, can I set breakpoints inside an interrupt routine? Do I need to set any parameter in the Debugger settings differently? Do I need to change anything at the linker level (I did not touch the linker so far)?
Just setting breakpoints at pit0_handler tells me that the routine is never executed...
 
What am I missing?
 
I appreciate any lights that you might give me.
 
Rgds,
 
Hagar
 
 
 
 
 


Message Edited by Hagar on 2009-01-12 10:13 PM
0 Kudos

584 Views
SimonMarsden_de
Contributor II
Do other interrupts fire OK? If not, it's possible that you've got all interrupts masked by the processor's main Status Register (SR).

You need to make sure that the interrupt mask bits of the SR are set to a low enough level to allow the interrupt through.

For example, to set the mask to 0 you can do:

asm {
    move    #0x2000,sr
}

The value 0x2000 sets the mask to 0 whilst leaving the processor in Supervisor mode.

With CodeWarrior's libraries, you could also achieve this by doing:

    asm_set_ipl(0);


Just an idea.


Simon
0 Kudos

584 Views
Hagar
Contributor I
Simon:
 
Thank you so much for your input. You solved my problem.
 
The first instruction on the _startup routine is
 
move.w #2700, sr
 
in order to disable interruptions, and I never worried about that (and completely forgot about that). Now, as per your suggestion, I am writting #2000 into sr just before initializing my PITs and everything is working as expected.
For those who are not aware, Interrupt requests are inhibited for all priority levels less than or equal to the current level, except the edge-sensitive level 7 request, which cannot be masked, and this is set at bits 10-8 @ SR register.
 
Thank you very much, Simon!
 
Best Regards,
 
Hagar
0 Kudos

584 Views
Hagar
Contributor I
Hi, Rich!
 
Thanks for your input. As a matter of fact, with your hint of looking at the target settings -> Debbuger -> CF Debugger Settings dialog box,  I tried to play around different settings there and one of my trials solved the problem of having most of the registers appearing as "unavailable". I had the  "Use Memory Configuration File" checked, pointing to a file {Project}cfg\MCF5282_CONSOLE_INTERNAL_RAM.mem  and I simply unchecked this option and now I have access to the contents of all my registers, including the detailed view of them. Now I can proceed and debug my PIT code. Thanks for the example code for the PIT for MCF52221/52233. I will take a look at them also, and I will let you know how things develop from here. 
 
Best Rgds,
 
Hagar
0 Kudos