TC375 interrupt nesting

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

cross mob
long
Level 1
Level 1
5 questions asked 10 sign-ins 5 replies posted

hello,

I have some questions about the interrupt .

when a interrupt is running ,can another higher priority interrupt run ?

can a trap event interrupt the the process?

Is there anything that can interrupt the process?

0 Likes
1 Solution
David_R
Moderator
Moderator
Moderator
100 replies posted 25 solutions authored 10 likes given

Hi @long 

As can be seen, and answering you question, the higher interrupt always will  be attend unless it's a NMI (like a trap), then so, the higher priority will be serve by the CPU till the end, please check the attached example, and if needed modify according to you needs, also you could find more information regarding the arch on MyICP.

Regards! :1

View solution in original post

0 Likes
7 Replies
David_R
Moderator
Moderator
Moderator
100 replies posted 25 solutions authored 10 likes given

Hi @long 

Regarding to you questions:

1.- when a interrupt is running ,can another higher priority interrupt run ?

Yes, indeed you could configure up to 256 priority levels, more information can be found in our basic trainings interrupt router training

2.- can a trap event interrupt the the process?

Yes, A trap occurs as a result of an event such as a Non-Maskable Interrupt (NMI), an instruction exception or illegal access, more information about it can be found into the TriCore architecture, page 72

3.- Is there anything that can interrupt the process?

Well it depends, if you mean what else could modify the normal execution of a MCU program, it could be: Internal or external interruptions, the trap system, watchdog timer, wrong programming  (stack underflow/overflow), hardware/software reset, the memory protection system, SMU launching an alarm twice, one of the domains that TriCore supports is safety-critical embedded applications. The architecture features a protection system designed to protect core system functionality from the effects of software errors, so i suggest take a look to our basic trainings and check the architecture manual as well, to get access to all those documents please register on MyICP

Regards!
0 Likes
long
Level 1
Level 1
5 questions asked 10 sign-ins 5 replies posted

Thanks for you reply.

now I have try to use the ASCLIN MODULE in the TC375,but it's strange that the Rx ISR away wait until TX ISR is return even if the RX priority is higher  when the RFL and TFL flag is set high 

the configuration is blow

the Tx interrupt priority is 1.

the Tx interrupt TOS is cpu0.

the Rx interrupt priority is 2.

the Rx interrupt TOS is cpu0.

the  FiFo interrupt mode is combine.

 

 

 

 

0 Likes
David_R
Moderator
Moderator
Moderator
100 replies posted 25 solutions authored 10 likes given

Hi @long 

Can you please upload the code, is kind more easy to try to find the issue if both are seeing the same,

Regards!

0 Likes
long
Level 1
Level 1
5 questions asked 10 sign-ins 5 replies posted

Hi @David_R 

Most of the code can be found in the demo "ASCLIN SPI Master 1 KIT TC375 LK".

the environment is the AURIX development studio v1.9.20

I have modified some code in it, and the specific changes are in the inserted code

 

 /* \file IfxAsclin_Spi.c*/
uint32 count_tx_fifo=0;
void IfxAsclin_Spi_write(IfxAsclin_Spi *asclin)
{
    Ifx_ASCLIN        *asclinSFR = asclin->asclin;    /* getting the pointer to ASCLIN registers from module handler */
    IfxAsclin_Spi_Job *job       = &asclin->txJob;    /* getting the txJob structure from module handler */

    if (job->pending)
    {
        //boolean interruptState = IfxCpu_disableInterrupts();

        uint32  count          = (uint32)(16 - IfxAsclin_getTxFifoFillLevel(asclinSFR)); /* getting the fillable count of the Tx Fifo */
        count_tx_fifo=count;
        count = __min(job->pending, count);                                              /* checking for the end of the data */
        //uint32 count=1;
        if (job->data == NULL_PTR)                                                       /* incase of no data to be transmitted (only receive case) */
        {
            uint32 i;
            job->pending = job->pending - count;                                         /* discount the current filling count from job pending */

            for (i = 0; i < count; i++)
            {
                IfxAsclin_writeTxData(asclinSFR, ~0); /* write all 1's */
            }
        }
        else
        {
            job->pending = job->pending - count;                      /* discount the current filling count from job pending */

            /* write data up to the count based on the in width */
//            switch (asclin->dataWidth)
//            {
//            case 1:                                             /* in case of 8 bit wide */
                IfxAsclin_write8(asclinSFR, job->data, count);  /* writing to Tx FIFO */
                job->data = &(((uint8 *)job->data)[count]);     /* pointing to the remaining data */
//                break;
//
//            case 2:                                             /* in case of 16 bit wide*/
//                IfxAsclin_write16(asclinSFR, job->data, count); /* writing to Tx FIFO */
//                job->data = &(((uint16 *)job->data)[count]);    /* pointing to the remaining data */
//                break;
//            }
        }

        //IfxCpu_restoreInterrupts(interruptState);
    }
}


void IfxAsclin_Spi_read(IfxAsclin_Spi *asclin)
{
    Ifx_ASCLIN        *asclinSFR = asclin->asclin;                                  /* getting the pointer to ASCLIN registers from module handler */
    IfxAsclin_Spi_Job *job       = &asclin->rxJob;                                  /* getting the rxJob structure from module handler */

    uint32             count     = (uint32)IfxAsclin_getRxFifoFillLevel(asclinSFR); /* get the readable count of Rx fifo */
    count = __min(job->pending, count);                                             /* check for the end of the data */
    //uint32 count=1;
    if (job->data == NULL_PTR)                                                      /* incase of no data to be received (only transmit case) */
    {
        uint32 i;
        job->pending = job->pending - count;                                        /* discount the current reading count from job pending */

        for (i = 0; i < count; i++)
        {
            IfxAsclin_readRxData(asclinSFR);    /* do dummy reads */
        }
    }
    else if (job->pending > 0)
    {
        job->pending = job->pending - count;    /* discount the current reading count from job pending */

        /* read data up to the count based on the out width */
//        switch (asclin->dataWidth)
//        {
//        case 1:                                            /* in case of 8 bit wide */
            IfxAsclin_read8(asclinSFR, job->data, count);  /* reading from Rx FIFO */
            job->data = &(((uint8 *)job->data)[count]);    /* pointing to the remaining data */
//            break;

//        case 2:                                            /* in case of 16 bit wide*/
//            IfxAsclin_read16(asclinSFR, job->data, count); /* reading from Rx FIFO */
//            job->data = &(((uint16 *)job->data)[count]);   /* pointing to the remaining data */
//            break;
//        }
    }

    if (job->pending == 0)
    {
        asclin->transferInProgress = 0; /* clearing the transfer in progress status */
        IfxAsclin_Spi_unlock(asclin);   /* unlock the driver  */
    }
}
void IfxAsclin_Spi_initModuleConfig(IfxAsclin_Spi_Config *config, Ifx_ASCLIN *asclin)
{
    const IfxAsclin_Spi_Config defaultConfig = {
        .asclin      = NULL_PTR,                           /* will be initialized below */

        .frameMode   = IfxAsclin_FrameMode_spi,            /* SPI mode */
        .clockSource = IfxAsclin_ClockSource_ascFastClock, /* Asclin fast clock, fasclinf*/

        /* Default values for input output control */
        .inputOutput              = {
            .alti     = IfxAsclin_RxInputSelect_0,               /* alternate input 0; */
            .cpol     = IfxAsclin_ClockPolarity_idleHigh,         /* CPOL  active low */
            .spol     = IfxAsclin_SlavePolarity_idlehigh,        /* SPOL  active high */
            .loopBack = FALSE,                                  /* no loop back */
        },

        /* Default Values for Bit sampling */
        .bitSampling              = {
            .medianFilter         = IfxAsclin_SamplesPerBit_one, /* one sample per bit */
        },

        /* Default Values for Frame Control */
        .frame                    = {
            .idleDelay = IfxAsclin_IdleDelay_0,                /* no idle delay */
            .leadDelay = IfxAsclin_LeadDelay_0,                /* one lead bit */
            .stopBit   = IfxAsclin_StopBit_0,                  /* one stop bit (trail delay) */
            .shiftDir  = IfxAsclin_ShiftDirection_msbFirst,    /* shift direction LSB first */
        },

        /* Default Values for Data Control*/
        .dataLength               = IfxAsclin_DataLength_8,          /* number of bits per transfer 8*/

        /* Default Values for fifo Control */
        .fifo                     = {
            .outWidth             = IfxAsclin_RxFifoOutletWidth_1,        /* 8-bit wide read */
            .inWidth              = IfxAsclin_TxFifoInletWidth_1,         /*8-bit wide write */
            .buffMode             = IfxAsclin_ReceiveBufferMode_rxFifo,   /* RxFIFO */
            .txFifoInterruptLevel = IfxAsclin_TxFifoInterruptLevel_0,    /* Tx FIFO interrupt level */
            .rxFifoInterruptLevel = IfxAsclin_RxFifoInterruptLevel_1,    /* Rx FIFO interrupt level */
            .txFifoInterruptMode  = IfxAsclin_FifoInterruptMode_combined, /* Tx FIFO interrupt generation mode */
            .rxFifoInterruptMode  = IfxAsclin_FifoInterruptMode_combined, /* Rx FIFO interrupt generation mode */
        },

        /* Default Values for Interrupt Config */
        .interrupt                = {
            .rxPriority    = 0,                            /* receive interrupt priority 0 */
            .txPriority    = 0,                            /* transmit interrupt priority 0 */
            .erPriority    = 0,                            /* error interrupt priority 0 */
            .typeOfService = IfxSrc_Tos_cpu0,              /* type of service CPU0 */
        },

        .pins                     = NULL_PTR,              /* pins to null pointer */
    };

    /* Default Configuration */
    *config        = defaultConfig;
    /* take over module pointer */
    config->asclin = asclin;
}
 /********************** file Cpu0_Main.c***********************/
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "IfxScuCcu.h"
#include "ASCLIN1_SPI_Master.h"
IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;

float32 fre_asclin;

uint8 tx_data[2048] = {0x00};//1K*1024= 1M
uint8 rx_data[2048] = {0};

void core0_main(void)
{
    IfxCpu_enableInterrupts();

    /* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
     * Enable the watchdogs and service them periodically if it is required
     */
    IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
    IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
    /* Wait for CPU sync event */
    IfxCpu_emitEvent(&g_cpuSyncEvent);
    IfxCpu_waitEvent(&g_cpuSyncEvent, 1);

    /* Initialize ASCLIN module in SPI master mode and transfer data  */
    InitAsclin1SpiMaster();

    for(uint16 i=0 ; i<sizeof(tx_data) ; i++)
    {
        tx_data[i]=i%255;
    }

    while(1)
    {

         Asclin1Spi3WrieTransfer(tx_data,rx_data,200);

    }
}

/*****************ASCLIN_SPI_Mater.c***************************/
void InitAsclin1SpiMaster(void)
{
    /* Initialize one instance of IfxAsclin_Spi_Config with default values */
    IfxAsclin_Spi_Config spiMasterConfig;
    IfxAsclin_Spi_initModuleConfig(&spiMasterConfig, &ASLIN_SPI_MODULE_SELECTED);

    /* Set the desired baud rate and oversampingFactor */
    spiMasterConfig.baudrate.prescaler = PRESCALER;
    spiMasterConfig.baudrate.baudrate = BAUDRATE;
    spiMasterConfig.baudrate.oversampling=IfxAsclin_OversamplingFactor_4;
    /* Set the desired baud rate and oversampingFactor */
    spiMasterConfig.frame.idleDelay = IfxAsclin_IdleDelay_0,                /* no idle delay *///帧之间的空闲时间
    spiMasterConfig.frame.leadDelay = IfxAsclin_LeadDelay_0,                /* one lead bit *///有风险
    spiMasterConfig.frame.stopBit   = IfxAsclin_StopBit_0,                  /* one stop bit (trail delay) */
    spiMasterConfig.frame.shiftDir  = IfxAsclin_ShiftDirection_msbFirst,    /* shift direction LSB first */

    /* ISR priorities and service provider */
    spiMasterConfig.interrupt.txPriority = IFX_INTPRIO_ASCLIN1_TX;
    spiMasterConfig.interrupt.rxPriority = IFX_INTPRIO_ASCLIN1_RX;
    spiMasterConfig.interrupt.typeOfService = IfxSrc_Tos_cpu0;

    /*  loop back mode enable */
    spiMasterConfig.inputOutput.loopBack=FALSE;     //TRUE/FALSE

    /* Pin configuration */
    const IfxAsclin_Spi_Pins pins =
    {
        &CLOCK_PIN,   IfxPort_OutputMode_pushPull,       /* Clock output port pin (CLK)   */
        &MRST_PIN,    IfxPort_InputMode_noPullDevice,    /* MRST port pin    */
        &MTSR_PIN,    IfxPort_OutputMode_pushPull,   /* MTSR port pin    */
        NULL_PTR,//&SOSL_PIN,    IfxPort_OutputMode_pushPull,
        IfxPort_PadDriver_cmosAutomotiveSpeed1
    };
    spiMasterConfig.pins = &pins;

    /* Initialize module with the above parameters */
    IfxAsclin_Spi_initModule(&g_spiHandle, &spiMasterConfig);
}

 

.

 

 

 

 

 

 

 

 

0 Likes
lock attach
Attachments are accessible only for community members.
David_R
Moderator
Moderator
Moderator
100 replies posted 25 solutions authored 10 likes given

Hello @long 

I have attached an example which demonstrate how the priority works and how a task is preempted by another, i used the TC375 Lite Kit 

how does it works:

Inside the file gpt12.c you can modify the priority of T2 and T4

#define T4_INT_NUM              (TX_INT_NUM - 1)
#define T2_INT_NUM              (T4_INT_NUM)

 The first case both has the same priority, on the terminal you should see this output:

David_R_0-1705511552084.png

T4 and T2 has the same priority that's why T2 is not been serving (starving)

Now you change the priority of T2

#define T2_INT_NUM              (T4_INT_NUM - 1)

The output will be:

 

David_R_2-1705511721809.png

So the T4 has the priority over T2, that's why first finish the T4

Finally rise the priority of T2:

#define T2_INT_NUM              (T4_INT_NUM + 1)

The output will be

David_R_3-1705512006314.png

So now the T2 has the priority over T4 that's why T2 finish first than T4, 

Regarding to you code, i really suggest that do not for any circumstance modify the source code of the libraries provided by Infineon, the portability of you code is gonna be null and also there's is no need to do it this way, better make a higher layer and then modify the behavior there.

Cheers :1!

0 Likes
long
Level 1
Level 1
5 questions asked 10 sign-ins 5 replies posted

Hi @David_R 

 I think I have known the interrupt arbitration , indeed if the Tricore enter a interrupt and another higher priority interrupt request come in ,will  the first interrupt continue?

 

0 Likes
David_R
Moderator
Moderator
Moderator
100 replies posted 25 solutions authored 10 likes given

Hi @long 

As can be seen, and answering you question, the higher interrupt always will  be attend unless it's a NMI (like a trap), then so, the higher priority will be serve by the CPU till the end, please check the attached example, and if needed modify according to you needs, also you could find more information regarding the arch on MyICP.

Regards! :1

0 Likes