Trigger interrupt through GPIO pin of TC39xx

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

cross mob
lock attach
Attachments are accessible only for community members.
aman_07
Level 1
Level 1
First reply posted First question asked Welcome!

Hello,

This is regarding pin layout of TC39xx board. We are working on a use-case where we need to trigger an interrupt through a GPIO pin by making it high from Canoe. We are unable to find GPIO pin which is relevant for interrupt from the datasheet. Please let us know the same from attached layout.

 

Also if possible please let us know how it can be achieved by giving some hints or snippet of code. Your support will be much appreciated 🙂

0 Likes
1 Solution
cwunder
Employee
Employee
5 likes given 50 likes received 50 solutions authored

You can generate an interrupt on the pin going high using the GTM TIM input. For example, you have on your list P30.0 (GPIO_EXT15). This is connected TIM4 Channel 0. Using ADS and starting from generic program you can place this code in the file Cpu0_Main.c. Every rising edge on P30.0 will increment the variable tim4_0Cnt in the interrupt.

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"

#include "IfxGtm_Tim_In.h"

#define DISABLE_PROT 0

#define VECTAB0 0
#define SRE_ON    (1u << 10u)  /* Service Request Enable */
#define SRE_OFF   (0u << 10u)  /* Service Request non-enabled */
#define TOS_CPU0  (0u << 11u)
/* define the service priority level */
#define SRPN_INT_CPU0_GTM_TIM4_0  2

typedef enum
{
  IfxGtm_ClusterClockDivider_disabled = 0,               /**< \brief Cluster disabled */
  IfxGtm_ClusterClockDivider_enabledWithoutDivider = 1,  /**< \brief Cluster is enabled without clock divider */
  IfxGtm_ClusterClockDivider_enabledWithDivider = 2      /**< \brief Cluster is enabled with clock divider */
} IfxGtm_ClusterCllockConfiguration;

IFX_INTERRUPT(ISR_GTMTIM4_0, VECTAB0, SRPN_INT_CPU0_GTM_TIM4_0);

IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;
volatile uint32 tim4_0Cnt;

/** \brief
 *
 * This function is called from main during initialization phase
 */
void Gtm_init (void)
{
  /* Clock into the fGTM is 200MHz (CCUCON0.GTMDIV=1 driven from fSOURCE0)*/

  /** - GTM clocks */
  Ifx_GTM *gtm = &MODULE_GTM;
  IfxGtm_enable(gtm);

  /*Disable Clusters Protection*/
  GTM_CTRL.B.RF_PROT = DISABLE_PROT;

  /*Write Protection of Cluster Configuration Disabled.  Repeated for first 2 Clusters*/
  for (uint32 i = 0; i < 6; i++)
    MODULE_GTM.CCM[i].PROT.B.CLS_PROT = DISABLE_PROT;

  /* Cluster 0 clock configuration */
  GTM_CLS_CLK_CFG.B.CLS0_CLK_DIV = IfxGtm_ClusterClockDivider_enabledWithDivider;

  /* Clock initialization */
  MODULE_GTM.CMU.CLK[0].CTRL.B.CLK_CNT = 0;   // Cluster clock / 1 = fCMU_CLK0
  MODULE_GTM.CMU.CLK[1].CTRL.B.CLK_CNT = 0;   // Cluster clock / 1 = fCMU_CLK1
  MODULE_GTM.CMU.CLK[2].CTRL.B.CLK_CNT = 0;   // Cluster clock / 1 = fCMU_CLK2
  MODULE_GTM.CMU.CLK[3].CTRL.B.CLK_CNT = 19;  // Cluster clock / 20 = fCMU_CLK3
  MODULE_GTM.CMU.FXCLK.CTRL.B.FXCLK_SEL = 4;  // FXCLK source = fCMU_GCLK

  MODULE_GTM.CMU.CLK_EN.U =
      IFXGTM_CMU_CLKEN_FXCLK |
      IFXGTM_CMU_CLKEN_CLK3 |
      IFXGTM_CMU_CLKEN_CLK2 |
      IFXGTM_CMU_CLKEN_CLK1 |
      IFXGTM_CMU_CLKEN_CLK0;
}

/**/
void Gtm_Tim_initTimer (void)
{
  GTM_TIM4INSEL.B.CH0SEL = 10; /*P30.0*/
  /* TIM4 Channel 0 configuration */
  GTM_TIM4_CH0_CTRL.U = 1       | /*TIM channel x enable */
                        2 << 1  | /*Input Event Mode (TIEM) */
                        1 << 13 | /*rising edge*/
                        0 << 14;  /*only one edge*/
  /* Enable interrupt, interrupt is visible outside GTM */
  GTM_TIM4_CH0_IRQ_EN.U = 0x1;
  /*Enable interrupt on CPU0, its vector table and SRPN level*/
  SRC_GTMTIM40.U = TOS_CPU0 | SRE_ON | SRPN_INT_CPU0_GTM_TIM4_0;
}

/**/
void ISR_GTMTIM4_0(void)
{
  GTM_TIM4_CH0_IRQ_NOTIFY.U = 1;
  tim4_0Cnt++;
}

/**/
void core0_main(void)
{
    /* !!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);
    
    Gtm_init();
    Gtm_Tim_initTimer();
    IfxCpu_enableInterrupts();
    
    while(1)
    {
      /*do nothing*/
    }
}

View solution in original post

0 Likes
3 Replies
cwunder
Employee
Employee
5 likes given 50 likes received 50 solutions authored

You can generate an interrupt on the pin going high using the GTM TIM input. For example, you have on your list P30.0 (GPIO_EXT15). This is connected TIM4 Channel 0. Using ADS and starting from generic program you can place this code in the file Cpu0_Main.c. Every rising edge on P30.0 will increment the variable tim4_0Cnt in the interrupt.

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"

#include "IfxGtm_Tim_In.h"

#define DISABLE_PROT 0

#define VECTAB0 0
#define SRE_ON    (1u << 10u)  /* Service Request Enable */
#define SRE_OFF   (0u << 10u)  /* Service Request non-enabled */
#define TOS_CPU0  (0u << 11u)
/* define the service priority level */
#define SRPN_INT_CPU0_GTM_TIM4_0  2

typedef enum
{
  IfxGtm_ClusterClockDivider_disabled = 0,               /**< \brief Cluster disabled */
  IfxGtm_ClusterClockDivider_enabledWithoutDivider = 1,  /**< \brief Cluster is enabled without clock divider */
  IfxGtm_ClusterClockDivider_enabledWithDivider = 2      /**< \brief Cluster is enabled with clock divider */
} IfxGtm_ClusterCllockConfiguration;

IFX_INTERRUPT(ISR_GTMTIM4_0, VECTAB0, SRPN_INT_CPU0_GTM_TIM4_0);

IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;
volatile uint32 tim4_0Cnt;

/** \brief
 *
 * This function is called from main during initialization phase
 */
void Gtm_init (void)
{
  /* Clock into the fGTM is 200MHz (CCUCON0.GTMDIV=1 driven from fSOURCE0)*/

  /** - GTM clocks */
  Ifx_GTM *gtm = &MODULE_GTM;
  IfxGtm_enable(gtm);

  /*Disable Clusters Protection*/
  GTM_CTRL.B.RF_PROT = DISABLE_PROT;

  /*Write Protection of Cluster Configuration Disabled.  Repeated for first 2 Clusters*/
  for (uint32 i = 0; i < 6; i++)
    MODULE_GTM.CCM[i].PROT.B.CLS_PROT = DISABLE_PROT;

  /* Cluster 0 clock configuration */
  GTM_CLS_CLK_CFG.B.CLS0_CLK_DIV = IfxGtm_ClusterClockDivider_enabledWithDivider;

  /* Clock initialization */
  MODULE_GTM.CMU.CLK[0].CTRL.B.CLK_CNT = 0;   // Cluster clock / 1 = fCMU_CLK0
  MODULE_GTM.CMU.CLK[1].CTRL.B.CLK_CNT = 0;   // Cluster clock / 1 = fCMU_CLK1
  MODULE_GTM.CMU.CLK[2].CTRL.B.CLK_CNT = 0;   // Cluster clock / 1 = fCMU_CLK2
  MODULE_GTM.CMU.CLK[3].CTRL.B.CLK_CNT = 19;  // Cluster clock / 20 = fCMU_CLK3
  MODULE_GTM.CMU.FXCLK.CTRL.B.FXCLK_SEL = 4;  // FXCLK source = fCMU_GCLK

  MODULE_GTM.CMU.CLK_EN.U =
      IFXGTM_CMU_CLKEN_FXCLK |
      IFXGTM_CMU_CLKEN_CLK3 |
      IFXGTM_CMU_CLKEN_CLK2 |
      IFXGTM_CMU_CLKEN_CLK1 |
      IFXGTM_CMU_CLKEN_CLK0;
}

/**/
void Gtm_Tim_initTimer (void)
{
  GTM_TIM4INSEL.B.CH0SEL = 10; /*P30.0*/
  /* TIM4 Channel 0 configuration */
  GTM_TIM4_CH0_CTRL.U = 1       | /*TIM channel x enable */
                        2 << 1  | /*Input Event Mode (TIEM) */
                        1 << 13 | /*rising edge*/
                        0 << 14;  /*only one edge*/
  /* Enable interrupt, interrupt is visible outside GTM */
  GTM_TIM4_CH0_IRQ_EN.U = 0x1;
  /*Enable interrupt on CPU0, its vector table and SRPN level*/
  SRC_GTMTIM40.U = TOS_CPU0 | SRE_ON | SRPN_INT_CPU0_GTM_TIM4_0;
}

/**/
void ISR_GTMTIM4_0(void)
{
  GTM_TIM4_CH0_IRQ_NOTIFY.U = 1;
  tim4_0Cnt++;
}

/**/
void core0_main(void)
{
    /* !!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);
    
    Gtm_init();
    Gtm_Tim_initTimer();
    IfxCpu_enableInterrupts();
    
    while(1)
    {
      /*do nothing*/
    }
}
0 Likes
aman_07
Level 1
Level 1
First reply posted First question asked Welcome!

Hello,

Please let me know if the below code is valid for this task. If yes, then kindly share me the header file "tc3xxk.h"

#include <tc3xxk.h>

void gpio_isr(void)
{
/* Interrupt handling code */
}

int main(void)
{
/* Configure the GPIO as an input */
tc3xxk_gpio_config(GPIO_PIN, TC3XXK_GPIO_INPUT);

/* Set the interrupt trigger type for the GPIO */
tc3xxk_gpio_interrupt_config(GPIO_PIN, TC3XXK_GPIO_RISING_EDGE);

/* Enable the interrupt for the GPIO */
tc3xxk_gpio_interrupt_enable(GPIO_PIN);

/* Register the ISR with the interrupt controller */
tc3xxk_interrupt_register(GPIO_PIN, gpio_isr);

/* Enable global interrupts */
tc3xxk_interrupt_global_enable();

while (1)
{
/* Application code */
}
return
0;
}

0 Likes

I don't recognize that tc3xxk api - is that Infineon code?

0 Likes