Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

AURIX™ Forum Discussions

User16079
Level 1
Level 1
Hi,
I am using Infineon aurix 267D for SPI communication with TDA.
I am able to transmit and receive data properly. In run mode I want Aurix to send command after each 100 ms interval but it is taking around 40-50 sec for it.
According to me there may be problem with interrupt or timer configuration but I am unable to find where exactly the error will be.
Can anyone please help me out..?
0 Likes
11 Replies
cwunder
Employee
Employee
25 likes received 25 solutions authored 100 sign-ins
I am not sure which timer you are using. Here is some code to initialize CPU0 STM0 for an interrupt at 100msec intervals assuming you have the STM clock frequency set to 100MHz. Add your SPI trigger to the ISR.

/* The System Timer Frequency is 100 MHz */
#define INTPRIO_STM0_STMIR0 (1)

#define CMP0_COMPARE_VALUE (0x1312Du)
#define MSIZE0 (17u)
#define MSTART0 (7u << 8u)
#define CMP1_COMPARE_VALUE (0x5F5E1u)
#define MSIZE1 (19u << 16u)
#define MSTART1 (8u << 24u)
#define CMP0_TOS (0u)
#define CMP1_TOS (0u)
#define ICR_VALUE (0x1u)
#define OCS_SUS (18u << 24u)
#define SRC_SRE (1u << 10u)

/**************************************************************************
Object: Initialization of CPU0 System Timer Peripheral
Parameters: None
Return: Nothing
**************************************************************************/
void STM0_Init(void) {
/* The Periodic interval for STM0 is 0.10 Seconds */
STM0_CMP0.U = STM0_TIM0.U + CMP0_COMPARE_VALUE;
/* The Periodic interval for STM1 is 1.00 Seconds */
STM0_CMP1.U = STM0_TIM0.U + CMP1_COMPARE_VALUE;
/* STM Compare Match Control Register Value: 0x8130711 */
STM0_CMCON.U = MSTART1 | MSIZE1 | MSTART0 | MSIZE0;
/* the SRC0 Interrupt serviced by TriCore */
IFX_INTERRUPT(STM0_ISR0, 0, INTPRIO_STM0_STMIR0);
SRC_STM0SR0.U = CMP0_TOS | SRC_SRE | INTPRIO_STM0_STMIR0;
/* Configure the Interrupt Control Register of the STM */
STM0_ICR.U = ICR_VALUE;
}

/**************************************************************************
Object: Interrupt routine for STM0_SR0
Parameters: None
Return: Nothing
**************************************************************************/
void STM0_ISR0(void) {
/* load compare register for next event */
STM0_CMP0.U += CMP0_COMPARE_VALUE;
}
0 Likes
User16079
Level 1
Level 1
Hi,
Thank you for quick reply.
I am using system frequency 200Mhz.

/*****************************************************Macro for Pll step for profile with 20MHz Crystal and 200MHz target *****************/
#define IFXSCU_CFG_PLL_STEPS_20MHZ_200MHZ \
{ /*Step 0 Config: 120MHz*/ \
(5 - 1), /*uint8 k2Step;*/ \
0.000100, /*float32 waitTime;*/ \
0 /*IfxScu_PllStepsFunctionHook hookFunction;*/ \
}, \
{ /*Step 1 Config: 150MHz*/ \
(4 - 1), /*uint8 k2Step;*/ \
0.000100, /*float32 waitTime;*/ \
0 /*IfxScu_PllStepsFunctionHook hookFunction;*/ \
}, \
{ /*Step 2 Config: 200MHz*/ \
(3 - 1), /*uint8 k2Step;*/ \
0.000100, /*float32 waitTime;*/ \
0 /*IfxScu_PllStepsFunctionHook hookFunction;*/ \
}
#endif

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

there is no function as STM_init but my STM.c file have following functions....


/******************************************************************************************STM.c***********************************************************************/
void IfxStm_clearCompareFlag(Ifx_STM *stm, IfxStm_Comparator comparator)
{
if (comparator == IfxStm_Comparator_0)
{
stm->ISCR.B.CMP0IRR = 1U;
}
else if (comparator == IfxStm_Comparator_1)
{
stm->ISCR.B.CMP1IRR = 1U;
}
}



void IfxStm_enableOcdsSuspend(Ifx_STM *stm)
{
Ifx_STM_OCS ocs = stm->OCS;

ocs.B.SUS_P = 1;
ocs.B.SUS = 2;
stm->OCS = ocs;
stm->OCS.B.SUS_P = 0;
}


IfxStm_ResourceStm IfxStm_getIndex(Ifx_STM *stm)
{
uint32 index;
IfxStm_ResourceStm result;

result = IfxStm_ResourceStm_none;

for (index = 0; index < IFXSTM_NUM_MODULES; index++)
{
if (IfxStm_cfg_indexMap[index].module == stm)
{
result = IfxStm_cfg_indexMap[index].index;
break;
}
}

return result;
}


boolean IfxStm_initCompare(Ifx_STM *stm, const IfxStm_CompareConfig *config)
{
sint32 index;
boolean result;
//********The STM clock control register is used to switch the STM on or off and to control its input clock rate.****************/
Ifx_STM_CMCON comcon = stm->CMCON; //Compare Match Control Register PLL
Ifx_STM_ICR icr = stm->ICR;

if (config->comparator == 0)
{
comcon.B.MSIZE0 = config->compareSize;
comcon.B.MSTART0 = config->compareOffset;
icr.B.CMP0OS = config->comparatorInterrupt;
result = TRUE;
}
else if (config->comparator == 1)
{
comcon.B.MSIZE1 = config->compareSize;
comcon.B.MSTART1 = config->compareOffset;
icr.B.CMP1OS = config->comparatorInterrupt;
result = TRUE;
}
else
{
/*Invalid value */
result = FALSE;
}

stm->ICR.U = icr.U;
stm->CMCON.U = comcon.U;

/* configure interrupt */
index = IfxStm_getIndex(stm); //getting index having value equal to stm

if (config->triggerPriority > 0)
{
volatile Ifx_SRC_SRCR *srcr;

if (config->comparatorInterrupt == IfxStm_ComparatorInterrupt_ir0)
{
srcr = &(MODULE_SRC.STM.STM[index].SR0);
}
else
{
srcr = &(MODULE_SRC.STM.STM[index].SR1);
}

IfxSrc_init(srcr, config->typeOfService, config->triggerPriority);
IfxSrc_enable(srcr);
}

/*Configure the comparator ticks to current value to avoid any wrong triggering*/
stm->CMP[config->comparator].U = IfxStm_getOffsetTimer(stm, (uint8)config->compareOffset);

/* clear the interrupt flag of the selected comparator before enabling the interrupt */
/* this is to avaoid the unneccesary interrupt for the compare match of reset values of the registers */
IfxStm_clearCompareFlag(stm, config->comparator);
/* enable the interrupt for the selected comparator */
IfxStm_enableComparatorInterrupt(stm, config->comparator);

/*Configure the comparator ticks */
stm->CMP[config->comparator].U = IfxStm_getOffsetTimer(stm, (uint8)config->compareOffset) + config->ticks;

return result;
}


void IfxStm_initCompareConfig(IfxStm_CompareConfig *config)
{
config->comparator = IfxStm_Comparator_0; //value 0
config->compareOffset = IfxStm_ComparatorOffset_0; //value 0
config->compareSize = IfxStm_ComparatorSize_32Bits; //Size of compare value to compare with timer: 32 bits value =31
config->comparatorInterrupt = IfxStm_ComparatorInterrupt_ir0; /*User must select the interrupt output */
config->ticks = 0xFFFFFFFF;
config->triggerPriority = 0;
/* TODO add interrupt configuration */
}


void IfxStm_resetModule(Ifx_STM *stm)
{
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();

IfxScuWdt_clearCpuEndinit(passwd);
stm->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
stm->KRST1.B.RST = 1;
IfxScuWdt_setCpuEndinit(passwd);

while (0 == stm->KRST0.B.RSTSTAT) /* Wait until reset is executed */

{}

IfxScuWdt_clearCpuEndinit(passwd);
stm->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */

IfxScuWdt_setCpuEndinit(passwd);
}


void IfxStm_enableComparatorInterrupt(Ifx_STM *stm, IfxStm_Comparator comparator)
{
if (comparator == IfxStm_Comparator_0)
{
stm->ICR.B.CMP0EN = 1U;
}
else if (comparator == IfxStm_Comparator_1)
{
stm->ICR.B.CMP1EN = 1U;
}
}
/*******************************************/

So i am unable to figure out what all parameters i need to change as per your code. also many values are configured in register so we cant view the values in debug mode.
can you help me out with this?
0 Likes
cwunder
Employee
Employee
25 likes received 25 solutions authored 100 sign-ins
The code example I provided is in lieu of the iLLD for the STM. Would it be possible for you to substitute this code instead of the iLLD for the STM? This could narrow down your issue to see if the problem is related to the configuration of the STM.
0 Likes
User16079
Level 1
Level 1
I am using BaseFramework_TC26xB.
But I don't have any document for reference. where can i find it..?
Also version is iLLD_1_0_0_11_0
I will try to make changes for frequency 200 Mhz meanwhile.
0 Likes
User16079
Level 1
Level 1
#define CMP0_COMPARE_VALUE (0x1312Du)
#define CMP1_COMPARE_VALUE (0x5F5E1u)

how did you calculate value for CMP0_COMPARE_VALUE and CMP1_COMPARE_VALUE .........?
0 Likes
cwunder
Employee
Employee
25 likes received 25 solutions authored 100 sign-ins
The clock for the STM is derived from the SPB. If you have 200MHz system frequency I would expect the SPB frequency to be 100MHz.

Two parameters are programmable for the compare operation:
1. The width of the relevant bits in registers CMP0/CMP1 (compare width MSIZEx) that is taken for the compare operation can be programmed from 0 to 31.
2. The first bit location (MSTARTx) in the 64-bit STM that is taken for the compare operation can be programmed from 0 to 31.

To calculate the compare value you take the period you want and divide it by the tick time of the STM.

For 100msec period, you take 100e-3/10nsec = 10e6 or (0x989680).

Now you need to remove the trailing zeros from this value which will also be the MSTART value. In this case it is 7, and now we right shift this by 7 to get 0x1312D which is the compare value.

You now need to remove the leading zeros to determine the MSIZE value. In this case you have 15 leading zeros so the size of the compare is 32-15=17.

The compare has to be added to the timer at each event to set up the next event.
0 Likes
User16079
Level 1
Level 1
hi,
I tried according to your calculations and following value are obtained:
For 10 ms =0x3D09
For 20 ms =0x3D09
For 50 ms =0x1312D
For 100 ms =0x1312D

but when I changed respective values in my code, same task is getting called at variable time and that time in more than 10 sec always.
0 Likes
cwunder
Employee
Employee
25 likes received 25 solutions authored 100 sign-ins
Generally for the STM to provide a period event. You need to read the current STM timer value (CMP0) and add the compare value to it then write the result back to the compare register. This will set up the next periodic event.

Here is an example of the Interrupt Service Routine for the STM0.

void STM0_ISR0(void) {
/* load compare register for next event */
STM0_CMP0.U += CMP0_COMPARE_VALUE;
}


In addition to the compare value you need the correctly programmed the MSTARTx and MSIZEx values.
For 10msec, compare is 0x3D09, MSIZE0 is 14 and MSTART0 is 6 (CMCON = 0x60E)
For 20msec, compare is 0x3D09, MSIZE0 is 14 and MSTART0 is 7 (CMCON = 0x70E)
For 50msec, compare is 0x1312D, MSIZE0 is 17 and MSTART0 is 6 (CMCON = 0x611)
For 100msec, compare is 0x1312D, MSIZE0 is 17 and MSTART0 is 7 (CMCON = 0x711)
0 Likes
User16079
Level 1
Level 1
I have made changes in MSIZE0 and MSTART0 and following are my observations;

for 100msec i.e MSIZE0=17 & MSTART0=7 : my 100 msec task takes 14 sec to get called and 10msec task takes 1-2 sec

for 10msec i.e MSIZE0=14 & MSTART0=6 : my 100 msec task takes 7 sec to get called and 10msec task takes <1sec(arround 800 msec) but not 10 msec

so i calculated values for 1 msec which are MSIZE0=12 & MSTART0=5 and compare is 0xC35 (CMCON=0x50C)
for this my 100 msec task is getting called at arround 600msec ....

so again I went for reducing the base time and I made it to 100 microsec values obtained are: MSIZE0=10 & MSTART0=4 and compare is 0x271 (CMCON=0x40A)
for this my 100 msec task is getting called at arround 330msec ....
please correct me if my values are wrong ..?
Also are this changes related to Kernal's scheduling because as per my knowledge kernel is responsible for scheduling?
0 Likes
cwunder
Employee
Employee
25 likes received 25 solutions authored 100 sign-ins
If you are using a kernel (RTOS) then most likely the system timer is used as the scheduler (based on the kernel tick time, for example 1 msec).

The system timer discussion in this thread is applicable but it assumes you have full control of the TC26x resources.

When you are using an RTOS you need to know how to configure the kernel tick time and how to create a task with the correct parameters.

In my opinion that should be another thread. Here you asked how to configure the system timer and this has been explained.
0 Likes
User16079
Level 1
Level 1
Do you mean that stm ticks are kernel tick..?
i have doubt related to STM itself that i had calculated values of MSIZE and MSTART due to which i was able to run the function of 100ms in 6 to 7 sec which was taking 42sec initially.
but still 6 to 7 sec is more time taken logically to run task of 100 msec.
is this the correct way to alter and reduce the time?

Thanks in advance.
0 Likes