CW files

Discussions and support about ChibiOS/RT, the free embedded RTOS.
louis
Posts: 23
Joined: Tue May 17, 2016 9:26 am

Re: CW files

Postby louis » Fri Jul 22, 2016 1:10 pm

Hi,

Okay :) Thank you: it is in spc_clock_init(void), isn't it?

Louis

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: CW files

Postby Giovanni » Fri Jul 22, 2016 1:29 pm

Yes.

Giovanni

louis
Posts: 23
Joined: Tue May 17, 2016 9:26 am

Re: CW files

Postby louis » Mon Jul 25, 2016 1:44 pm

Hi Giovanni,

My interrupts (IVOR10 & IVOR4) are still never called after our modifications. I asked some help from my service.
My IVORS are well linked : good position in MAP file.

Code: Select all

.handlers section layout
  Starting        Virtual  File
  address  Size   address  offset
  ---------------------------------
  00000000 0000ae 000100a0 00000310  1 .handlers    ivor.o
  00000000 0000ae 000100a0 00000310  4 _@DummyFn1    ivor.o
  00000000 000000 000100a0 00000310    _IVOR10 (entry of .handlers)    ivor.o
  00000040 000000 000100e0 00000350    _IVOR4 (entry of .handlers)    ivor.o
  00000084 000000 00010124 00000394    _ivor_exit (entry of .handlers)    ivor.o



But when do you initialize your PIT?
After the setup during the linker time, how do you call the IVORS?

Louis

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: CW files

Postby Giovanni » Mon Jul 25, 2016 2:38 pm

Hi,

louis wrote:But when do you initialize your PIT?


Peripherals are initialized in the HAL, if you don't use HAL then you have to provide initialization. Anyway, why PIT? are you using the Decrementer or PIT for systick?

louis wrote:After the setup during the linker time, how do you call the IVORS?


I don't understand this question.

Just a suggestion, why don't you try to get one of the provided demos working? this way you could just examine the code and test changes.

Giovanni

louis
Posts: 23
Joined: Tue May 17, 2016 9:26 am

Re: CW files

Postby louis » Mon Jul 25, 2016 3:42 pm

In my old projet I used a pit driver which setups the IVORs (the 10 and 11). The PIT was attached to my IVORs and then we started the PIT timer.
I just don't understand where the timer call the IVORs.
If I don't use HAL, what is it essentiel from this component for the use of DEC on RT? Then, I will add it.

The PIT driver is code is bellow:

Code: Select all

//============================================================================//
// NAME : vDPit_eInit_Exe
//============================================================================//
// ROLE : Init du PIT
//----------------------------------------------------------------------------//
// INPUT  :
// OUTPUT :
//============================================================================//
void vDPit_eInit_Exe(void)
{
   union SPR_HID0VAL      unHID0;

   //Set DEC
   MvSetSpr(DEC,0);   //Clear DEC

   //Read HID0
   unHID0.R = Mu32GetSpr(HID0);

   //Set HID0
   unHID0.B.TBEN         = 1U;      //Enable time base
   unHID0.B.SEL_TBCLK   = 0U;      //Processor clock
   MvSetSpr(HID0,unHID0.R);


#if(Du16DPit_PITRTIUsed>0U)
   PIT.PITMCR.B.MDIS_RTI   = 0U;      //Enable timer clock
#endif

   //Set PIT module MCR
   PIT.PITMCR.B.MDIS   = 0U;      //Enable timer clock

#if (DEBUG_MODE != 0U)
   PIT.PITMCR.B.FRZ   = 1U;      //Freeze timer in DEBUG Mode
#else
   PIT.PITMCR.B.FRZ   = 0U;
#endif
}


//============================================================================//
// NAME : s32DPit_eSetEvent_Exe
//============================================================================//
// ROLE : Set callback event for timer overflow
//----------------------------------------------------------------------------//
// INPUT  : Channel ID , Channel Priority (only for PIT timers), Event Handler
// OUTPUT :   -1 ==> Bad channel number
//============================================================================//
TS32 s32DPit_eSetEvent_Exe(TU16 Fu16Channel, TU8 Fu8PitPrio, TpfDPit_eEvtExe * FpfEventRoutine)
{
   union SPR_TSRVAL   unTSR;
   union SPR_TCRVAL   unTCR;
   TS32               s32RetVal   = Ds32Core_eSuccess;

   //Setup the timer
   switch(Fu16Channel)
   {
      case Ceu16DPit_eDEC:
         //Set exception
         vDCpu_eInstallCoreISR_Exe(Ceu16DCpu_eIVOR10Decrementer, FpfEventRoutine);

         //Set TSR
         unTSR.R      = 0U;
         unTSR.B.DIS   = 1U;      //Clear interrupt request
         MvSetSpr(TSR,unTSR.R);

         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.DIE   = 1U;
         MvSetSpr(TCR,unTCR.R);
         break;

      case Ceu16DPit_eFIT:
         //Set exception
         vDCpu_eInstallCoreISR_Exe(Ceu16DCpu_eIVOR11FixInterval, FpfEventRoutine);
         

         //Set TSR
         unTSR.R      = 0U;
         unTSR.B.FIS   = 1U;      //Clear interrupt request
         MvSetSpr(TSR,unTSR.R);

         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.FIE   = 1U;
         MvSetSpr(TCR,unTCR.R);
         break;

      case Ceu16DPit_ePIT01:
      case Ceu16DPit_ePIT02:
      case Ceu16DPit_ePIT03:
      case Ceu16DPit_ePIT04:
         //Install ISR
         vDCpu_eInstallISR_Exe(Ctu16DPit_iISRSource[Fu16Channel], Fu8PitPrio, FpfEventRoutine);

         //Clear interrupt request
         PIT.TIMER[Fu16Channel].TFLG.B.TIF   = 1U;

         //Enable interrupt request
         PIT.TIMER[Fu16Channel].TCTRL.B.TIE   = 1U;
         break;

#if(Du16DPit_PITRTIUsed>0U)
      case Ceu16DPit_ePITRTI:
         //Install ISR
         vDCpu_eInstallISR_Exe(Ceu16DCpu_eRTI, Fu8PitPrio, FpfEventRoutine);

         //Clear interrupt request
         PIT.RTI.TFLG.B.TIF   = 1U;

         //Enable interrupt request
         PIT.RTI.TCTRL.B.TIE   = 1U;
         break;
#endif

      default :
         s32RetVal = Ds32Core_eErrorBadParameter;
         break;
   }

   return (s32RetVal);
}


//============================================================================//
// NAME : s32DPit_eClearEvent_Exe
//============================================================================//
// ROLE : Clear callback event for timer overflow
//----------------------------------------------------------------------------//
// INPUT  : Channel ID
// OUTPUT : -1 ==> Bad channel number
//============================================================================//
TS32 s32DPit_eClearEvent_Exe(TU16 Fu16Channel)
{
   union SPR_TCRVAL   unTCR;
   TS32               s32RetVal   = Ds32Core_eSuccess;

   //Setup the timer
   switch(Fu16Channel)
   {
      case Ceu16DPit_eDEC:
         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.DIE   = 0U;      //Clear interrupt enable
         MvSetSpr(TCR,unTCR.R);

         //Clear exception
         vDCpu_eRemoveCoreISR_Exe( Ceu16DCpu_eIVOR10Decrementer );      // Remove interrupt routine
         break;

      case Ceu16DPit_eFIT:
         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.FIE   = 0U;      //Clear interrupt enable
         MvSetSpr(TCR,unTCR.R);

         //Clear exception
         vDCpu_eRemoveCoreISR_Exe( Ceu16DCpu_eIVOR11FixInterval );      // Remove interrupt routine
         break;

      case Ceu16DPit_ePIT01:
      case Ceu16DPit_ePIT02:
      case Ceu16DPit_ePIT03:
      case Ceu16DPit_ePIT04:
         //Clear interrupt enable
         PIT.TIMER[Fu16Channel].TCTRL.B.TIE   = 0U;

         // Remove interrupt routine
         vDCpu_eRemoveISR_Exe(Ctu16DPit_iISRSource[Fu16Channel]);
         break;

#if(Du16DPit_PITRTIUsed>0U)
      case Ceu16DPit_ePITRTI:
         //Clear interrupt enable
         PIT.RTI.TCTRL.B.TIE   = 0U;

         // Remove interrupt routine
         vDCpu_eRemoveISR_Exe(Ceu16DCpu_eRTI);
         break;
#endif

      default :
         s32RetVal = Ds32Core_eErrorBadParameter;
         break;
   }

   return (s32RetVal);
}


//============================================================================//
// NAME : vDPit_eAckEvent_Exe
//============================================================================//
// ROLE : Ack ISR from callback event for timer overflow
//----------------------------------------------------------------------------//
// INPUT  : Channel ID
// OUTPUT :
//============================================================================//
void vDPit_eAckEvent_Exe(TU16 Fu16Channel)
{
   union SPR_TSRVAL   unTSR;

   //Setup the timer
   switch(Fu16Channel)
   {
      case Ceu16DPit_eDEC:
         //Set TSR
         unTSR.R      = 0U;
         unTSR.B.DIS   = 1U;      //Clear interrupt request
         MvSetSpr(TSR,unTSR.R);
         break;

      case Ceu16DPit_eFIT:
         //Set TSR
         unTSR.R      = 0U;
         unTSR.B.FIS   = 1U;      //Clear interrupt request
         MvSetSpr(TSR,unTSR.R);
         break;

      case Ceu16DPit_ePIT01:
      case Ceu16DPit_ePIT02:
      case Ceu16DPit_ePIT03:
      case Ceu16DPit_ePIT04:
         //Clear interrupt request
         PIT.TIMER[Fu16Channel].TFLG.B.TIF   = 1U;
         break;

#if(Du16DPit_PITRTIUsed>0U)
      case Ceu16DPit_ePITRTI:
         //Clear interrupt request
         PIT.RTI.TFLG.B.TIF   = 1U;
         break;
#endif

      default :
         //Nothing to do
         break;
   }
}


//============================================================================//
// NAME : s32DPit_eStart_Exe
//============================================================================//
// ROLE : Start the timer
//----------------------------------------------------------------------------//
// INPUT  : Channel ID , period res @1us
// OUTPUT :   Period / Error (-1 : Period too large)
//============================================================================//
TS32 s32DPit_eStart_Exe(TU16 Fu16Channel, TU32 Fu32Period)
{
   union SPR_TCRVAL   unTCR;
   TU32               u32Tmp      = 0U;
   TU32               u32TBClock   = 0U;
   TU16               u16TBBits   = 0U;
   TU16               u16FP         = 0U;

   //Setup the timer
   switch(Fu16Channel)
   {
      case Ceu16DPit_eDEC:
         u32Tmp = (Du32DCpu_eFSYS*Du16DPit_eResolution);

         //Calculate reload value
         u32Tmp *= Fu32Period;

         if((u32Tmp/Fu32Period) != (Du32DCpu_eFSYS*Du16DPit_eResolution))
         {
            Fu32Period = 0xFFFFFFFF/(Du32DCpu_eFSYS*Du16DPit_eResolution);
         }
         else   {}      //Empty ELSE

         //Set DEC
         MvSetSpr(DEC,u32Tmp);

         //Set DECAR
         MvSetSpr(DECAR,u32Tmp);

         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.ARE   = 1U;
         MvSetSpr(TCR,unTCR.R);
         break;

      case Ceu16DPit_eFIT:
         u32TBClock    = Fu32Period * Du32DCpu_eFSYS;

#ifdef __CWCC__   //CW IDE
//   Du16DPit_eResolution = 1
#pragma warn_no_side_effect off
#endif
         u32TBClock   *= Du16DPit_eResolution;
#ifdef __CWCC__   //CW IDE
#pragma warn_no_side_effect on
#endif
         u32TBClock   -=1U;
         u16TBBits    = 0U;

         while(u32TBClock>0U)
         {
            u32TBClock>>=1;
            u16TBBits++;
         }

         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set Watch point
         u16FP   = 64-u16TBBits;

         unTCR.B.FP     = (u16FP&0x0003);
         unTCR.B.FPEXT  = ((u16FP&0x003C)>>2);

         //Set TCR
         MvSetSpr(TCR,unTCR.R);
         break;

      case Ceu16DPit_ePIT01:
      case Ceu16DPit_ePIT02:
      case Ceu16DPit_ePIT03:
      case Ceu16DPit_ePIT04:
         u32Tmp = (Du32DCpu_eFSYS*Du16DPit_eResolution);

         //Calculate reload value
         u32Tmp *= Fu32Period;

         if((u32Tmp/Fu32Period) != (Du32DCpu_eFSYS*Du16DPit_eResolution))
         {
            Fu32Period = 0xFFFFFFFF/(Du32DCpu_eFSYS*Du16DPit_eResolution);
         }
         else   {}      //Empty ELSE

         //   Set Current Value
         PIT.TIMER[Fu16Channel].CVAL.R         = u32Tmp - 1U;

         //   Set Load Value
         PIT.TIMER[Fu16Channel].LDVAL.R      = u32Tmp - 1U;

         //   Enable timer
         PIT.TIMER[Fu16Channel].TCTRL.B.TEN   = 1U;
         break;

#if(Du16DPit_PITRTIUsed>0U)
      case Ceu16DPit_ePITRTI:
         u32Tmp = (Du32DCpu_eFOSC*Du16DPit_eResolution);

         //Calculate reload value
         u32Tmp *= Fu32Period;

         if((u32Tmp/Fu32Period) != (Du32DCpu_eFOSC*Du16DPit_eResolution))
         {
            Fu32Period = 0xFFFFFFFF/(Du32DCpu_eFOSC*Du16DPit_eResolution);
         }
         else   {}      //Empty ELSE

         //   Set Current Value
         PIT.RTI.CVAL.R   = u32Tmp - 1U;

         //   Set Load Value
         PIT.RTI.LDVAL.R   = u32Tmp - 1U;

         //   Enable timer
         PIT.RTI.TCTRL.B.TEN   = 1U;
         break;
#endif

      default :
         Fu32Period   = (TU32)Ds32Core_eErrorBadParameter;
         break;
   }

   return ((TS32)Fu32Period);
}


//============================================================================//
// NAME : vDPit_eStop_Exe
//============================================================================//
// ROLE : Stop the timer
//----------------------------------------------------------------------------//
// INPUT  : Channel ID
// OUTPUT :
//============================================================================//
void vDPit_eStop_Exe(TU16 Fu16Channel)
{
   union SPR_TCRVAL   unTCR;

   //Setup the timer
   switch(Fu16Channel)
   {
      case Ceu16DPit_eDEC:
         //Set DEC
         MvSetSpr(DEC,0);

         //Set DECAR
         MvSetSpr(DECAR,0);

         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.ARE   = 0U;
         MvSetSpr(TCR,unTCR.R);
         break;

      case Ceu16DPit_eFIT:
         //Read TCR
         unTCR.R = Mu32GetSpr(TCR);

         //Set TCR
         unTCR.B.FP     = 0U;
         unTCR.B.FPEXT  = 0U;
         MvSetSpr(TCR,unTCR.R);
         break;

      case Ceu16DPit_ePIT01:
      case Ceu16DPit_ePIT02:
      case Ceu16DPit_ePIT03:
      case Ceu16DPit_ePIT04:
         //   Disable timer
         PIT.TIMER[Fu16Channel].TCTRL.B.TEN   = 0U;

         //   Reset Current Value
         PIT.TIMER[Fu16Channel].CVAL.R         = 0U;

         //   Reset Load Value
         PIT.TIMER[Fu16Channel].LDVAL.R      = 0U;
         break;

#if(Du16DPit_PITRTIUsed>0U)
      case Ceu16DPit_ePITRTI:
         //   Disable timer
         PIT.RTI.TCTRL.B.TEN   = 0U;

         //   Reset Current Value
         PIT.RTI.CVAL.R   = 0U;

         //   Reset Load Value
         PIT.RTI.LDVAL.R   = 0U;
         break;
#endif

      default :
         //Nothing to do
         break;
   }
}


Louis

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: CW files

Postby Giovanni » Mon Jul 25, 2016 4:37 pm

Your PIT driver also handles the Decrementer (IVOR10) and the FIT (IVOR11) which are not PITs. The PIT is a peripheral and it generates IRQs, all IRQs share IVOR4.

If you use IVOR10 for systick then you need to setup the Decrementer.

The OS expects the system tick timer to be appropriately initialized. In ChibiOS usually the HAL does that, in you case you have to handle initialization, the RTOS is just a guest of your framework.

Not having access to your software environment I can only give generic advice.

Giovanni

louis
Posts: 23
Joined: Tue May 17, 2016 9:26 am

Re: CW files

Postby louis » Tue Jul 26, 2016 10:45 am

Hi,

Your generic advice is really good for me Giovanni. How to setup the DEC? (should i use my PIT driver or ChibiOS can do this).

For System Tick, what is the exatly appropriately initialization ?

Louis

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: CW files

Postby Giovanni » Tue Jul 26, 2016 11:16 am

You could use your driver for initialization if you are confident it works.

As long IVOR10 is invoked and it executes the correct code it will be fine.

Giovanni

louis
Posts: 23
Joined: Tue May 17, 2016 9:26 am

Re: CW files

Postby louis » Tue Jul 26, 2016 3:24 pm

Hi,

Now interruptions work. ChSleepMillisecobd() works also. I have still a problem, but it is in internal of my project.
Thank you for your help Giovanni :)

Louis

louis
Posts: 23
Joined: Tue May 17, 2016 9:26 am

Re: CW files

Postby louis » Wed Jul 27, 2016 1:02 pm

Hi Giovanni,

Do you know a free tracealyzer for ChibiOS?

Louis


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: No registered users and 10 guests