AN219842 How to use interrupt in TRAVEO™ T2G
About this document
Scope and purpose
This application note explains how to set up and use interrupts for TRAVEO™ T2G family MCU. This document serves as a guide for developing interrupt-based projects. It also explains the interrupt structure, vector selection, and provides guidance on coding interrupt handlers. In addition, it explains how to set up and use the fault report structure that capture the fault information.
Intended audience
This document is intended for anyone who uses the TRAVEO™ T2G family to use interrupt function.
Introduction
This application note describes interrupts in TRAVEO™ T2G family series MCUs. The series includes Arm® Cortex®-M CPUs with enhanced secure hardware extension (eSHE), CAN FD, memory, and analog and digital peripheral functions in a single chip.
The CYT2 series has one Arm® Cortex®-M4F-based CPU (CM4) and Cortex-M0+-based CPU (CM0+). The CYT4 series has two Arm® Cortex®-M7-based CPUs (CM7) and CM0+, and the CYT3 series has one Arm® Cortex®-M7-based CPUs (CM7) and CM0+.
Interrupts are an important part of any embedded application. They free the CPU from having to continuously poll for the occurrence of a specific event; it notifies the CPU only when that event occurs. The occurrence of an interrupt results in the current program flow being stopped and the interrupt service routine (ISR) being executed by the CPU.
In embedded applications, interrupts are frequently used to communicate the status of on-chip peripherals to the CPU. They are also used for notifying when errors are detected from on-chip peripherals.
In this document, an interrupt from a peripheral is called a system interrupt. The series supports up to 1023 system interrupts. For the list of system interrupts supported by the device variants, see the device datasheets [1].
The fault report structures capture faults that occur while software is running. The TRAVEO™ T2G platform uses a centralized fault report structure, which allows for a system-wide, consistent handling of faults and simplifies software development.
Fault report structures have a signaling interface to notify the system of the captured fault.
To understand the functionality described and terminology used in this application note, see the “Interrupts” and “Fault Subsystem” chapter of the architecture technical reference manual (TRM) [2].
Interrupt overview
Interrupt structure
Figure 1 shows a simplified block diagram of the interrupt architecture in CYT2B series.
Figure 1. CYT2B series interrupt architecture
See the Architecture TRM [2] for other series interrupt architecture.
The system interrupts of the series are processed by the NVIC of the individual cores.
In the TRAVEO™ T2G interrupt architecture, each CPU can use eight CPU interrupts IRQ[7:0] and any of the ‘N’ system interrupts can be mapped to any of the IRQ[7:0] of each CPU. All system interrupts can be mapped onto any CPU interrupt simultaneously and the interrupt can be mapped independent for both CPUs.
Multiple system interrupts can be mapped on the same CPU interrupt. Therefore, an active CPU interrupt may indicate one or multiple active system interrupts.
For each interrupt, there are eight levels of configurable priority levels for CM4 and CM7, and four levels for CM0+.
In addition to the NVIC, TRAVEO™ T2G supports a wakeup interrupt controller (WIC) and interrupt synchronizer block.
The WIC provides detection of DeepSleep interrupts in the DeepSleep CPU power mode. When interrupt signal of one or more wakeup sources detected, the WIC generates a wakeup signal, and causes the CPU to enter Active mode. See the device datasheets [1] for the interrupt sources available for DeepSleep wakeup.
The Interrupt synchronizer block synchronizes the interrupts to the CPU clock frequency.
Up to four system interrupts can be mapped to the NMI for each CPU.
Operation overview
Figure 2 shows CPU operation in an interrupt sequence.
Figure 2. Interrupt sequence
When the NVIC receives an interrupt request while another interrupt is being serviced, or receives multiple interrupt requests at the same time, it evaluates the priority of all these interrupts, and sends the exception number of the highest-priority interrupt to the CPU. Therefore, a higher priority interrupt can block the execution of a lower-priority Interrupt processing.
Figure 3 shows the interrupt operation by interrupt priority.
Figure 3. Operation when interrupt occurs during interrupt processing
For more details, see the Arm® documentation sets for CM4, CM7, and CM0+.
Initial setting
This section describes how to initialize interrupts using the Sample Driver Library (SDL). The code snippets in this application note are part of SDL. See Other references for the SDL.
SDL basically has a configuration part and a driver part. The configuration part mainly configures the parameter values for the desired operation. The driver part configures each register based on the parameter values in the configuration part.
You can configure the configuration part according to your system. Figure 4 shows the initializing interrupts.
Figure 4. Interrupt initial setting flow
Note: (*1) Vector table offset register (VTOR) is used vector table setting. Lower 7 bits in VTOR are reserved. Therefore, vector table needs to be aligned on 128-byte boundary.
Note: (*2) “n” in Figure 4 indicates 0, 4. For example, CPUSS_CM4_SYSTEM_INT_CTL shows system interrupt control register for CM4. The CYT2 series have CPUSS_CM4_SYSTEM_INT_CTL and CPUSS_CM0_SYSTEM_INT_CTL registers. The CYT3 and CYT4 series have CPUSS_CM7_0_SYSTEM_INT_CTL, CPUSS_CM7_1_SYSTEM_INT_CTL (only CYT4 series) and CPUSS_CM0_SYSTEM_INT_CTL registers. See the registers TRM [2] for more information.
Note: (*3) Interrupt priority can set with the 8-bit PRI_N field in the NVIC_IPR register. The correspondence between interrupt numbers and register bit fields can be expressed by the following equation:IRQ number = NVIC_IPR register number *4 + PRI_N bit field number. (for example, IRQ5 = NVIC_IPR1.PRI_N1)
Each CPU has a VTOR. It can be used for relocating the vector table from flash to SRAM, thus allowing the change of interrupt handlers dynamically. When VTOR was set to SRAM area, vector table need to place in SRAM.
Note: The software must ensure that the default hardfault vector entry is replaced with the specific user handler. The default SROM handler is only designed to be used during boot.
Use case
This section explains an example of the configure interrupt structure using the following use case.
In this configuration, GPIO Port 8_0 is connected to the button switch. An interrupt is generated by pressing the switch. IDX numbers used this section denote the system interrupt index numbers. In this usage, the IDX number is that of the CYT2B series. See the device datasheets [1] for the actual index number to use. See the “I/O System” chapter in architecture TRM [2] and application note [3] for GPIO setting.
- System Interrupt source: GPIO Port Interrupt#8 (IDX: 29)
- Mapped to CPU Interrupt: IRQ3
- CPU Interrupt Priority: 3
Configuration
Table 1 and Table 2 list the parameters and functions of the configuration part in SDL for interrupt initialization.
Table 1. List of interrupt initialization parameters
Parameters | Description | Value |
---|---|---|
irq_cfg.sysIntSrc | Set system interrupt index number [0: 1022] | CY_BUTTON3_IRQN It is assigned to Port 8 (Index number = 29) |
irq_cfg.intIdx | Set CPU interrupt number [0: 7] CPUIntIdx0_IRQn is assigned to IRQ 0, CPUIntIdx1_IRQn is assigned to IRQ 1, CPUIntIdx2_IRQn is assigned to IRQ 2, CPUIntIdx3_IRQn is assigned to IRQ 3, CPUIntIdx4_IRQn is assigned to IRQ 4, CPUIntIdx5_IRQn is assigned to IRQ 5, CPUIntIdx6_IRQn is assigned to IRQ 6, CPUIntIdx7_IRQn is assigned to IRQ 7, | CPUIntIdx3_IRQn |
irq_cfg.isEnabled | Set interrupt enable False: Disabled True: Enabled | True |
Table 2. List of interrupt initialization functions
Function | Description | Value |
---|---|---|
Cy_SysInt_InitIRQ(irq_cfg) | Configure interrupt structure Irq_cfg: Interrupt structure parameters address | &irq_cfg |
Cy_SysInt_SetSystemIrqVector(sysintSrc, Handler) | Set system interrupt handler to vector table sysintSrc: System interrupt index number Handler: Interrupt handler address | sysintSrc: CY_BUTTON3_IRQN Handler: ButtonIntHandler, See Code Listing 6. |
NVIC_SetPriority(intSrc, intPriority) | Set interrupt priority: intSrc: CPU interrupt number intPriority: Interrupt priority Level | intSrc: CPUIntIdx3_IRQn intPriority: 3ul |
NVIC_ClearPendingIRQ(intSrc) | Clear pending flag: intSrc: CPU interrupt number | CPUIntIdx3_IRQn |
NVIC_EnableIRQ(intSrc) | Set interrupt enable intSrc: CPU interrupt number | CPUIntIdx3_IRQn |
Code Listing 1 and Code Listing 2 show an example program of the interrupt configuration part.
The following description will help you understand the register notation of the driver part of SDL:
- CPUSS->unCM4_SYSTEM_INT_CTLx.u32Register is the CPUSS_CM4_SYSTEM_INT_CTLx register mentioned in the registers TRM [2]. Other registers are also described in the same manner. “ x ” signifies the system interrupt index number.
- Performance improvement measures
For register setting performance improvement, the SDL writes a complete 32-bit data to the register. Each bit field is generated in advance in a bit writable buffer and written to the register as the final 32-bit data.
unIntCtl.stcField.u3CPU_INT_IDX = (uint8_t)config->intIdx; unIntCtl.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul; CPUSS->unCM4_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl.u32Register;
See cyip_cpuss_v2.h under hdr/rev_x/ip for more information on the union and structure representation of registers.
Code Listing 1 Example of vector table configuration
/* (1) Configure Vector Table */
static void CopyVectorTable(void)
{
const uint8_t u8NrOfVectors = (uint8_t) ((uint32_t) &__Vectors_Size / 4);
/* SRAM vector table address */
uint32_t * const pu32RamTable = (uint32_t *) __ramVectors;
/* Flash memory vector table address */
uint32_t * const pu32RomTable = (uint32_t *) (&__vector_table);
/* Copy vector table from Flash memory to SRAM */
for(uint8_t u8Index = 0; u8Index < u8NrOfVectors; u8Index++)
{
pu32RamTable[u8Index] = pu32RomTable[u8Index];
}
SCB->VTOR = (uint32_t) pu32RamTable; /* Set VTOR to SRAM */
}
This code is called during start up.
Code Listing 2 Example of interrupt configuration
#define CY_BUTTON3_PORT GPIO_PRT8 /* IO port definition */
#define CY_BUTTON3_PIN 0 /* IO port configuration */
cy_stc_gpio_pin_config_t user_button3_port_pin_cfg =
{
.outVal = 0ul,
.driveMode = CY_GPIO_DM_HIGHZ,
.hsiom = CY_BUTTON3_PIN_MUX,
.intEdge = CY_GPIO_INTR_FALLING,
.intMask = 1ul,
.vtrip = 0ul,
.slewRate = 0ul,
.driveSel = 0ul,
.vregEn = 0ul,
.ibufMode = 0ul,
.vtripSel = 0ul,
.vrefSel = 0ul,
.vohSel = 0ul,
};
void ButtonIntHandler(void) /* System interrupt handler */
{
:
}
int main(void)
{
SystemInit(); /* (2) Peripheral function setting */
__enable_irq(); /* (3) Enable global interrupt (*1). */
/* (4) Configure IO Port. */
Cy_GPIO_Pin_Init(CY_BUTTON3_PORT, CY_BUTTON3_PIN, &user_button3_port_pin_cfg);
/* Setup GPIO for BUTTON3 interrupt */
/* (5) Set interrupt structure. See [Code Listing 3](#code-listing-3-cy_sysint_initirq-function) and [Code Listing 4](#code-listing-4-cy_sysint_setsystemirqvector-function) for details of each function. */
cy_stc_sysint_irq_t irq_cfg =
{
.sysIntSrc = CY_BUTTON3_IRQN,
.intIdx = CPUIntIdx3_IRQn,
.isEnabled = true,
};
/* (5) Set interrupt structure. See [Code Listing 3](#code-listing-3-cy_sysint_initirq-function) and [Code Listing 4](#code-listing-4-cy_sysint_setsystemirqvector-function) for details of each function. */
Cy_SysInt_InitIRQ(&irq_cfg);
/* System interrupt handler */
/* (5) Set interrupt structure. See [Code Listing 3](#code-listing-3-cy_sysint_initirq-function) and [Code Listing 4](#code-listing-4-cy_sysint_setsystemirqvector-function) for details of each function. */
Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, ButtonIntHandler);
/* (6) Set priority (*1) */
/* (5) Set interrupt structure. See [Code Listing 3](#code-listing-3-cy_sysint_initirq-function) and [Code Listing 4](#code-listing-4-cy_sysint_setsystemirqvector-function) for details of each function. */
NVIC_SetPriority(CPUIntIdx3_IRQn, 3ul);
/* (7) Interrupt Enable (*1) */
/* (5) Set interrupt structure. See [Code Listing 3](#code-listing-3-cy_sysint_initirq-function) and [Code Listing 4](#code-listing-4-cy_sysint_setsystemirqvector-function) for details of each function. */
NVIC_EnableIRQ(CPUIntIdx3_IRQn);
for(;;)
{
}
}
(*1) Programming hint : The CM4/CM0+ interrupt enable and NVIC operation instructions are provided by Cortex microcontroller software interface standard (CMSIS) with intrinsic functions.
Code Listing 3 Cy_SysInt_InitIRQ() function
cy_en_sysint_status_t Cy_SysInt_InitIRQ(const cy_stc_sysint_irq_t* config)
{
cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
un_CPUSS_CM4_SYSTEM_INT_CTL_t unIntCtl = { 0ul };
/* Check if configuration parameter values are valid */
if(NULL != config)
{
unIntCtl.stcField.u3CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
/* Set the parameters to interrupt structure */
CPUSS->unCM4_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl.u32Register;
}
else
{
status = CY_SYSINT_BAD_PARAM;
}
return(status);
}
Code Listing 4 Cy_SysInt_SetSystemIrqVector() function
void Cy_SysInt_SetSystemIrqVector(cy_en_intr_t sysIntSrc, cy_systemIntr_Handler userIsr)
{
/* Check the vector location */
if (Cy_SysInt_SystemIrqUserTableRamPointer != NULL)
{
/* Set the system interrupt handler */
Cy_SysInt_SystemIrqUserTableRamPointer[sysIntSrc] = userIsr;
}
}
Interrupt handling
In this series MCUs, multiple system interrupts can be mapped to the same CPU interrupt. Therefore, they share a CPU interrupt handler.
To identify the system interrupt occurred, each CPU interrupt has a CMn_INT_STATUS register. This register has the following fields:
- CMn_INTx_STATUS.SYSTEM_INT_VALID: specifies if any system interrupt is active for the CPU interrupt.
- CMn_INTx_STATUS.SYSTEM_INT_IDX [9:0]: specifies the index (a number in the range [0, 1022]) of the lowest active system interrupt mapped to the corresponding CPU interrupt.
The CPU interrupt handler uses the SYSTEM_INT_IDX field to index a system interrupt lookup table and jumps to the system interrupt handler.
Note that in this series MCUs, these interrupts are level interrupts, so you should clear the peripheral interrupt in return processing. Also, you should read back the register to ensure the completion of register write access, return from the interrupt after clearing the pending register. Figure 5 shows the interrupt handling example in CYT2B series.
Figure 5. Interrupt Handling
Code Listing 5 and Code Listing 6 show an example program of the interrupt handler.
Code Listing 5 CPU interrupt handler
void CpuUserInt3_Handler(void)
{
un_CPUSS_CM0_INT3_STATUS_t system_int_status = {0};
system_int_status.u32Register = CPUSS->unCM4_INT3_STATUS.u32Register;
if(system_int_status.stcField.u1SYSTEM_INT_VALID) /*(2) Check if IQR is Active */
{
// (3) Read interrupt index
// (4)jump to system interrupt handler
Cy_SystemIrqUserTable[system_int_status.stcField.u10SYSTEM_INT_IDX]();
}
else
{
// Triggered by SW or due to SW clear error (SW cleared a peripheral
// interrupt flag but didn't clear the Pending flag at NVIC)
// Case of Software Trigger (*1)
}
//(9) Clear the IRQ pending flag executed by the Pending register in NVIC (*2)
NVIC_ClearPendingIRQ(CPUIntIdx3_IRQn);
}
Code Listing 6 System interrupt handler
// Interrupt handler registered in the configuration part
void ButtonIntHandler(void)
{
uint32_t intStatus;
/* If button3 falling edge detected */
// Port number Pin number in Port
intStatus = Cy_GPIO_GetInterruptStatusMasked(CY_BUTTON3_PORT, CY_BUTTON3_PIN);
if (intStatus != 0ul)
{
// Clear the peripheral interrupt flag that became the interrupt source. See Code Listing 7.
Cy_GPIO_ClearInterrupt(CY_BUTTON3_PORT, CY_BUTTON3_PIN);
: //(7) Interrupt processing
}
}
Code Listing 7 Cy_GPIO_ClearInterrupt() function
__STATIC_INLINE void Cy_GPIO_ClearInterrupt(volatile stc_GPIO_PRT_t* base, uint32_t pinNum)
{
/* Any INTR MMIO registers AHB clearing must be preceded with an AHB read access */
(void)base->unINTR.u32Register;
base->unINTR.u32Register = CY_GPIO_INTR_STATUS_MASK << pinNum; //(5) Clear interrupt flag
/* This read ensures that the initial write has been flushed out to the hardware */
(void)base->unINTR.u32Register; //(6) Read back
}
Note: (*1) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
Note: (*2) The flag on the pending register (pending flag) is cleared when the CPU interrupt is accepted. Therefore, normally it is not necessary to clear it in the CPU interrupt handler. However, note that when handling multiple interrupts with one interrupt handler. In the following case, invalid interrupts can be prevented by clearing the pending flag when returning from an interrupt.
Note: Figure 6 shows two (Interrupt 1 and Interrupt 2) factors are processed in one system interrupt handler.
Figure 6. Example of pending flag clear
- Interrupt 1 occurs.
- The CPU interrupt handler checks the interrupt factor and jumps to the corresponding system interrupt handler. Here, the pending flag has been cleared because the interrupt was accepted.
- Checks the interrupt factor. If interrupt 1, the flag of interrupt 1 is cleared.
- Processes interrupt 1.
- Interrupt 2 occurs during processing of interrupt 1. Therefore, the pending flag is set again.
- Checks interrupt 2, when the processing of interrupt 1 is completed. In this example, executes the interrupt flag clear and the processing of interrupt 2.
- Clears the pending flag and returns from interrupt handler. If the pending flag is not cleared, an interrupt will be generated again after returning from the CPU interrupt handler.
Peripheral interrupt structure
The interrupt structure of most peripheral functions consists of INTR, INTR_SET, INTR_MASK, and INTR_MASKED registers.
- INTR: Indicates that an interrupt factor has occurred. Software can clear these by writing ‘1’ to these bits.
- INTR_SET: Sets an interrupt. Software can write ‘1’ to these bits to set the corresponding INTR bit.
- INTR_MASK: Masks an interrupt. Software can selectively enable interrupts by writing ‘1’ to the corresponding bit.
- INTR_MASKED: Indicates that a masked interrupt factor has occurred. It reflects a bitwise AND between the interrupt request (INTR) and mask (INTR_MASK) registers.
A software interrupt can be generated by using the INTR_SET register. See Software interrupt (using peripheral) for more details.
Example usage of interrupt structure
An example of using the interrupt structure is explained according to the following usage assumptions.
IDX numbers in this section denote system interrupt index numbers. IDX numbers are the IDX number of CYT2B series. See the device datasheets [1] for the actual index number to use.
Peripheral interrupt handling
This section explains general interrupts from an external pin (GPIO Port#0,1,2), and shows its operation, initial setting, and interrupt handling. Each interrupt is processed by CM4. The following shows the use case.
Use case
- Interrupt setting 1
- System Interrupt source: GPIO Port Interrupt#0 (IDX: 21) rising-edge detection
- Mapped to CPU Interrupt: IRQ4
- CPU Interrupt Priority: 2
- Interrupt setting 2
- System Interrupt source:
- GPIO Port Interrupt#1 (IDX: 22) rising-edge detection
- GPIO Port Interrupt#2 (IDX: 23) rising-edge detection
- Mapped to CPU Interrupt: IRQ5
- CPU Interrupt Priority: 3
- System Interrupt source:
Figure 7 shows interrupt operation for this configuration.
Figure 7. Example interrupt operation usage
If GPIO Port Interrupt#0 and GPIO Port Interrupt#1 interrupts occur at the same time, then the GPIO Port Interrupt#0 interrupt takes precedence because it is mapped to IRQ4, which has higher priority than IRQ5 to which GPIO Port Interrupt#1 interrupt is mapped.
If GPIO Port Interrupt#0 interrupts occur during GPIO Port Interrupt#1 processing, then the GPIO Port Interrupt#0 interrupt takes precedence because it is mapped to IRQ4, which has higher priority than IRQ5 to which GPIO Port Interrupt#1 interrupt is mapped.
If GPIO Port Interrupt#1 and GPIO Port Interrupt#2 interrupts occur at the same time, then the GPIO Port Interrupt#1 interrupt takes precedence (CM0/4_INT5_STATUS register) because both the system interrupts are mapped to IRQ5 but GPIO Port Interrupt#1 has a lower system interrupt index (22) than the system interrupt index (23) of GPIO Port Interrupt#2.
Configuration
- Initial setting procedure
See Initial setting for the initial setting procedure. After each peripheral resource (GPIO Port Interrupt#0,1,2) is set up, each resource interrupt is routed to the CPU interrupt. Next, set the level and permission of each CPU interrupt to the NVIC. After setting up interrupt connection, start each resource. See the “I/O System” chapter of the architecture TRM [2] for GPIO setting.
- Interrupt handler operation
See Interrupt handling for the interrupt handler configuration. When an interrupt occurs, the CPU jumps to the interrupt handler specified in the vector table. Within the CPU interrupt handler, it identifies the system interrupt that triggered the CPU interrupt and jumps to the corresponding ISR. After clearing the system interrupt flag in the CPU interrupt handler and executing the ISR, clear the relevant CPU Pending register bit and return to the main routine.
Figure 8 and Figure 9 show the software flow when single and multiple interrupts occur.
Figure 8. Interrupt operation flow
Note: (*) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
If a high-priority CPU interrupt occurs in the current ISR, suspend current ISR processing and execute the ISR with the higher priority.
Figure 9. Nested interrupt operation flow
Note: (*) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
NMI generation of system interrupts
In this series, up to four of all the available system interrupts can be mapped to the NMI of each CPU. This section explains the Timing Protection configuration using NMI, shows its operation, initial setting, and interrupt handling. Each interrupt is processed by CM4.
Use case
In this configuration, monitor the processing time of the periodic interrupt routine (500 counts) called by TCPWM Group#0 Counter#1.
TCPWM Group#0 Counter#0 is used to monitor the processing time of the interrupt routine. TCPWM Group#0 Counter#0 is a counter that counts upwards, and generates an interrupt when the count value is more than the compare value (100 counts). It starts counting when the periodic interrupt starts, and stops when interrupt processing is completed. If interrupt processing is not completed within a specific time, that is, if the counting is not stopped, an NMI is notified to the CPU by the TCPWM Group#0 Counter#0 underflow interrupt.
- TCPWM Group#0 Counter#0
- System Interrupt source: TCPWM Group#0 Counter#0(IDX: 274) TC interrupt
- Mapped to CPU NMI
- Monitor of IRQ5 ISR operation time
- Compare value: 100 (Monitoring cycle)
- TCPWM Group#0 Counter#1
- System Interrupt source: TCPWM Group#0 Counter#1(IDX: 275) TC interrupt
- Mapped to CPU Interrupt: IRQ5
- CPU Interrupt Priority: 3
- Compare value: 500 (Interrupt period for system operation)
Figure 10 shows interrupt operation for this configuration.
Figure 10. Timing protection operation example
Configuration
- Initial setting procedure
See Initial setting for the initial setting procedure. After each peripheral resource (TCPWM Group#0 Counter#0 and #1) is set up, each resource interrupt is routed to the CPU interrupt. Next, set the level and permission of each CPU interrupt to the NVIC. After setting up interrupt connection, start each resource.
Figure 11 shows the initializing interrupts for NMI generation.
Figure 11. Interrupt structure initial setting procedure for NMI
Table 3 and Table 4 list the parameters and functions of the configuration part in SDL for interrupt initialization.
Table 3. List of interrupt initialization parameters
Parameters | Description | Value |
---|---|---|
irq_cfg_0.sysIntSrc | Set system interrupt index number [0: 1022] | tcpwm_0_interrupts_0_IRQn It is assigned to TCPWM Group#0 Counter#0 (Index number = 274) |
irq_cfg_0.intIdx | Set CPU interrupt number [0: 7] CPUIntIdx0_IRQn is assigned to IRQ 0, CPUIntIdx1_IRQn is assigned to IRQ 1, CPUIntIdx2_IRQn is assigned to IRQ 2, CPUIntIdx3_IRQn is assigned to IRQ 3, CPUIntIdx4_IRQn is assigned to IRQ 4, CPUIntIdx5_IRQn is assigned to IRQ 5, CPUIntIdx6_IRQn is assigned to IRQ 6, CPUIntIdx7_IRQn is assigned to IRQ 7 | CPUIntIdx4_IRQn |
irq_cfg_0.intIdx.isEnabled | Set interrupt enable False: Disabled True: Enabled | True |
irq_cfg_1.sysIntSrc | Set system interrupt index number [0: 1022] | tcpwm_0_interrupts_1_IRQn It is assigned to TCPWM Group#0 Counter#1 (Index number = 275) |
irq_cfg_1.intIdx | Set CPU interrupt number [0: 7] CPUIntIdx0_IRQn is assigned to IRQ 0, CPUIntIdx1_IRQn is assigned to IRQ 1, CPUIntIdx2_IRQn is assigned to IRQ 2, CPUIntIdx3_IRQn is assigned to IRQ 3, CPUIntIdx4_IRQn is assigned to IRQ 4, CPUIntIdx5_IRQn is assigned to IRQ 5, CPUIntIdx6_IRQn is assigned to IRQ 6, CPUIntIdx7_IRQn is assigned to IRQ 7 | CPUIntIdx5_IRQn |
irq_cfg_1.intIdx.isEnabled | Set interrupt enable False: Disabled True: Enabled | True |
Table 4. List of interrupt initialization functions
Function | Description | Value |
---|---|---|
Cy_SysInt_SetIntSourceNMI (Reg_num, sysintSrc) | Set NMI register Reg_num: CM4 NMI control Register number CPUSS_CM4_NMI_CTLx register (x = 0 to 3) sysintSrc: System interrupt index number | Reg_nim: 0 Use CPUSS_CM4_NMI_CTL0 register sysintSrc: tcpwm_0_interrupts_0_IRQn |
Cy_SysInt_InitIRQ(irq_cfg) | Configure interrupt structure Irq_cfg: Interrupt structure parameters address | &irq_cfg0/1 |
Cy_SysInt_SetSystemIrqVector(sysintSrc, Handler) | Set system interrupt handler to vector table sysintSrc: System interrupt index number Handler: Interrupt handler address | sysintSrc: irq_cfg_0/1.sysIntSrc Handler: NMI_Handler / Counter_HandlerSee Code Listing 11 and Code Listing 13. |
NVIC_SetPriority(intSrc, intPriority) | Set interrupt priority: intSrc: CPU interrupt number intPriority: Interrupt priority Level | intSrc: irq_cfg_1.intIdx intPriority: 3ul |
NVIC_EnableIRQ(intSrc) | Set interrupt enable intSrc: CPU interrupt number | irq_cfg_0/1.intIdx |
Code Listing 8 and Code Listing 9 show an example program of the interrupt configuration part. See the “Timer, Counter, and PWM” chapter of the architecture TRM [2] and application note [3] for TCPWM setting details.
Code Listing 8 Example of interrupt configuration 1
#define COMPARE0_NUM (100ul) /* Counter period parameter definition */
#define COMPARE1_NUM (500ul)
cy_stc_tcpwm_counter_config_t MyCounter_config = /* TCPWM configuration */
{
.period = 0xFFFFul,
.clockPrescaler = CY_TCPWM_COUNTER_PRESCALER_DIVBY_4,
.runMode = CY_TCPWM_COUNTER_CONTINUOUS,
.countDirection = CY_TCPWM_COUNTER_COUNT_UP,
.debug_pause = false,
.CompareOrCapture = CY_TCPWM_COUNTER_MODE_COMPARE, /* Compare value */
.compare0 = COMPARE0_NUM, // Set the comp value
.compare0_buff = 0ul, // do not care
.compare1 = 0ul, // do not care
.compare1_buff = 0ul, // do not care
.enableCompare0Swap = false, // do not care
.enableCompare1Swap = false, // do not care
.interruptSources = 0ul, // do not care
.capture0InputMode = 3ul, // do not care
.capture0Input = 0ul, // do not care
.reloadInputMode = 3ul, // do not care
.reloadInput = 0ul, // do not care
.startInputMode = 3ul, // do not care
.startInput = 0ul, // do not care
.stopInputMode = 3ul, // do not care
.stopInput = 0ul, // do not care
.capture1InputMode = 3ul, // do not care
.capture1Input = 0ul, // do not care
.countInputMode = 3ul, // do not care
.countInput = 1ul, // do not care
.trigger1 = CY_TCPWM_COUNTER_OVERFLOW, // do not care
};
/* Configure interrupt structure parameters for TCPWM Group#0 counter#0 */
cy_stc_sysint_irq_t irq_cfg_0 =
{
.sysIntSrc = tcpwm_0_interrupts_0_IRQn,
.intIdx = CPUIntIdx4_IRQn,
.isEnabled = true,
};
/* Configure interrupt structure parameters for TCPWM Group#0 counter#1 */
cy_stc_sysint_irq_t irq_cfg_1 =
{
.sysIntSrc = tcpwm_0_interrupts_1_IRQn,
.intIdx = CPUIntIdx5_IRQn,
.isEnabled = true,
};
Code Listing 9 Example of interrupt configuration 2
/* System interrupt handler */
void Counter_Handler(void)
{
:
}
void NMI_Handler(void)
{
:
}
int main(void)
{
:
/* Initialize TCPWM0_GRPx_CNTx_COUNTER as Counter & Enable */
/* (1) Configure TCPWM */
Cy_Tcpwm_Counter_Init(TCPWMx_GRPx_CNTx_COUNTER_0, &MyCounter_config); /*(1) Configure TCPWM*/
MyCounter_config.compare0 = COMPARE1_NUM; /* (1) Configure TCPWM */
Cy_Tcpwm_Counter_Init(TCPWMx_GRPx_CNTx_COUNTER_1, &MyCounter_config); /*(1)Configure TCPWM*/
Cy_Tcpwm_Counter_Enable(TCPWMx_GRPx_CNTx_COUNTER_0); /* (1) Configure TCPWM */
Cy_Tcpwm_Counter_Enable(TCPWMx_GRPx_CNTx_COUNTER_1); /* (1) Configure TCPWM */
/* Enable Interrupt */
Cy_Tcpwm_Counter_SetCC0_IntrMask(TCPWMx_GRPx_CNTx_COUNTER_0); /* (1) Configure TCPWM */
Cy_Tcpwm_Counter_SetCC0_IntrMask(TCPWMx_GRPx_CNTx_COUNTER_1); /* (1) Configure TCPWM */
/* Set NMI mapping of CM4 */
/* (2) Configure NMI. See Code Listing 10 */
Cy_SysInt_SetIntSourceNMI(0ul, tcpwm_0_interrupts_0_IRQn);
/* Interrupt setting for TCPWMs */
/* (3) Set interrupt structure. See Code Listing 3 and Code Listing 4 for details of each function. */
Cy_SysInt_InitIRQ(&irq_cfg_0);
/* (3) Set interrupt structure. See Code Listing 3 andCode Listing 4 for details of each function. */
Cy_SysInt_InitIRQ(&irq_cfg_1);
/* (3) Set interrupt structure. See Code Listing 3 and Code Listing 4 for details of each function. */
Cy_SysInt_SetSystemIrqVector(irq_cfg_0.sysIntSrc, NMI_Handler); /* NMI handler */
/* (3) Set interrupt structure. See Code Listing 3 and Code Listing 4 for details of each function. */
Cy_SysInt_SetSystemIrqVector(irq_cfg_1.sysIntSrc, Counter_Handler); /* System interrupt handler */
/* Set the Interrupt Priority & Enable the Interrupt */
NVIC_SetPriority(irq_cfg_1.intIdx, 3ul); /* (4) Set priority */
NVIC_EnableIRQ(irq_cfg_1.intIdx); /* (5) Interrupt Enable */
/* Start TCPWM Group#0 Counter#1 */
/* (6) Start TCPWM Group#0 counter#1 timer */
Cy_Tcpwm_TriggerStart(TCPWMx_GRPx_CNTx_COUNTER_1);
for(;;)
{
}
}
Code Listing 10 Cy_SysInt_SetIntSourceNMI () function
void Cy_SysInt_SetIntSourceNMI(uint8_t nmiNum, cy_en_intr_t sysIntSrc)
{
/* Set the fault structure interrupt to NMI */
CPUSS->unCM4_NMI_CTL[nmiNum].stcField.u10SYSTEM_INT_IDX = sysIntSrc;
}
- Interrupt handler operation
See Interrupt handling for the interrupt handler configuration. If interrupt processing is completed within a specific time, NMI will not occur. However, if interrupt processing is not completed within a specific time, NMI is notified, and NMI handler is executed.
Figure 12. Timing protection violation operation flow example
Note: (*1) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
Note: (*2) If there are multiple (four) NMI factors depending on the system, the NMI handler may need to investigate all selected system interrupt sources to identify the source of the CPU NMI.
Programming hint : When an NMI occurs, execute appropriate safe operation such as reset generation. If recovery to normal operation is possible after safe operation, return from the interrupt.
Code Listing 11 System interrupt handler for TCPWM group#0 counter#1
void Counter_Handler(void) /* Interrupt handler registered in the configuration part */
{
/* Check the source that generated the interrupt */
if(Cy_Tcpwm_Counter_GetCC0_IntrMasked(TCPWMx_GRPx_CNTx_COUNTER_1))
{
/* Start TCPWM Group#0 Counter#0 */
/* (1) Start the monitored counter (TCPWM Group#0 Counter#0) */
Cy_Tcpwm_TriggerStart(TCPWMx_GRPx_CNTx_COUNTER_0);
/* Clear TCPWM CC0 interrupt flag Group#0 Counter#1 */
/* (2) Clear the peripheral interrupt flag. See Code Listing 12. */
Cy_Tcpwm_Counter_ClearCC0_Intr(TCPWMx_GRPx_CNTx_COUNTER_1);
/* (4) Interrupt processing */
/* user program here.. */
/* Stop TCPWM Group#0 Counter#0 */
/* (5) Stop the monitored counter (TCPWM Group#0 Counter#0) */
Cy_Tcpwm_TriggerStopOrKill(TCPWMx_GRPx_CNTx_COUNTER_0);
}
}
Code Listing 12 Cy_Tcpwm_Counter_ClearCC0_Intr() function
void Cy_Tcpwm_Counter_ClearCC0_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1CC0_MATCH = 1ul; /* (2) Clear interrupt flag */
ptscTCPWM->unINTR.u32Register; /* (3) Read back */
}
Code Listing 13 NMI handler for TCPWM group#0 counter#0
void NMI_Handler(void) /* NMI handler registered in the configuration part */
{
if(Cy_Tcpwm_Counter_GetCC0_IntrMasked(TCPWMx_GRPx_CNTx_COUNTER_0)) /*(6) Check NMI factor*/
{
/* Safe Operation (Counter#0 Stop)*/
/* (7) Safe Operation (Stop the monitored counter) */
{
/* Stop TCPWM Group#0 Counter#0 */
Cy_Tcpwm_TriggerStopOrKill(TCPWMx_GRPx_CNTx_COUNTER_0);
}
/* Clear TCPWM CC0 interrupt flag Group#0 Counter#0 */
/* (8) Clear the NMI flag, and (9) Read back. See Code Listing 12. */
Cy_Tcpwm_Counter_ClearCC0_Intr(TCPWMx_GRPx_CNTx_COUNTER_0);
}
}
Wakeup interrupt
All available system interrupts can be used in Active power mode and for wake up from Sleep power mode.
A subset of the system interrupts can wake up the CPU from DeepSleep; this subset can be used in Active power mode, and to wake up the CPU from Sleep and DeepSleep power modes. See the device datasheets [1] for available interrupts details.
This section explains an interrupt from the Backup domain that is caused by an interrupt from the real-time clock (RTC) and shows how to set and return processing from DeepSleep mode through an interrupt.
Use case
- Interrupt setting
- System Interrupt source: Backup domain (IDX: 12) ALARM1 interrupt of RTC
- Mapped to CPU Interrupt: IRQ7
- CPU Interrupt Priority: 6
Figure 13 shows interrupt operation for this configuration.
Figure 13. Example wakeup interrupt operation
The wait for interrupt (WFI) executed by the CPU triggers the transition into Sleep, and DeepSleep modes. WFI suspends processor execution until interrupt events occur. When an interrupt from one or more wakeup sources occurs, the WIC generates a wakeup signal and places the CPU in Active mode.
When the CPU enters Active mode, the ISR is executed and the suspended program is resumed after returning from the ISR.
Configuration
- Initial setting procedure
The initial setting for generating a wakeup interrupt using the WIC is the same as normal interrupt setting. See Initial setting for the initial setting procedure and the “Real-Time Clock” chapter of the architecture TRM [2] for RTC setting.
- Interrupt handler operation
See Interrupt handling for interrupt handler configuration. After returning from the Wakeup interrupt, the CPU resumes from the program suspend point.
Figure 14. Wakeup interrupt handling example
Note: (*) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
Software interrupt (using CPU register)
This series can use IRQ8 to IRQ15 for software interrupt. A software interrupt can be generated by writing ‘1’ to the software triggered interrupt register (STIR) of the corresponding CPU interrupts IRQ8 to IRQ15. IRQ0 to IRQ7 can also trigger software interrupts with STIR.
This section explains software interrupt generation by using the STIR register and shows the setting procedure and return processing.
Use case
- Interrupt setting
- Mapped to CPU Interrupt: IRQ8
- CPU Interrupt Priority: 3
Figure 15 shows interrupt operation for this configuration.
Figure 15. Software interrupt operation
Configuration
- Initial setting
Software interrupt does not use interrupt structure, set only NVIC.
Figure 16. Initial setting procedure for software interrupt (using CPU
register)
Table 5 and Table 6 list the parameters and functions of the configuration part in SDL for interrupt initialization.
Table 5. List of interrupt initialization parameters
Parameters | Description | Value |
---|---|---|
cfg.intrSrc | Set CPU interrupt number [8: 15] Internal0_IRQn is assigned to IRQ 8, Internal1_IRQn is assigned to IRQ 9, Internal2_IRQn is assigned to IRQ 10, Internal3_IRQn is assigned to IRQ 11, Internal4_IRQn is assigned to IRQ 12, Internal5_IRQn is assigned to IRQ 13, Internal6_IRQn is assigned to IRQ 1 4, Internal7_IRQn is assigned to IRQ 15 | Internal0_IRQn |
cfg.intrPriority | Set Interrupt Priority | 3ul |
Table 6. List of interrupt initialization functions
Function | Description | Value |
---|---|---|
Cy_SysInt_Init (cfg, Handler) | Configure interrupt structure cfg: Software interrupt parameters address Handler: Interrupt handler address | cfg: cfg address Handler: SoftwareInterupt0Handler,See Code Listing 18. |
NVIC_SetPriority(intrSrc, intPriority) | Set interrupt priority: intrSrc: CPU interrupt number intPriority: Interrupt priority level | intrSrc: Internal0_IRQn intPriority: 3ul |
NVIC_EnableIRQ(intSrc) | Set interrupt enable intSrc: CPU interrupt number | Internal0_IRQn |
Cy_SysInt_SoftwareTrig(intSrc) | Set software interrupt intSrc: CPU interrupt number | Internal0_IRQn |
Code Listing 14 shows an example program of the interrupt configuration part for software interrupt. See Initial setting for Configuration of (1).
Code Listing 14 Example for software interrupt configuration
void SoftwareInterupt0Handler(void) /* System interrupt handler */
{
__NOP();
}
int main(void)
{
SystemInit(); /* (2) Peripheral function setting */
__enable_irq(); /* Enable global interrupts. */ /* (3) Enable global interrupt */
/* Software Interrupt 0 */
{
/* At first change software interrupt 0 handler */
/* The default handler is defined at startup_tviibe1m_cm4 */
cy_stc_sysint_t cfg =
{
.intrSrc = Internal0_IRQn, /* Set configuration parameters for NVIC */
.intrPriority = 3ul,
};
/* (4) Set NVIC registers and interrupt handler. See Code Listing 15. */
Cy_SysInt_Init(&cfg, SoftwareInterupt0Handler);
/* Enable software interrupt IRQ */
NVIC_EnableIRQ(Internal0_IRQn);
/* (6) Interrupt Enable */
/* Force set pending status in the NVIC */
/* (7) Set software interrupt. See Code Listing 17. */
Cy_SysInt_SoftwareTrig(Internal0_IRQn);
}
for(;;)
{
}
}
Code Listing 15 Cy_SysInt_Init() function
cy_en_sysint_status_t Cy_SysInt_Init(const cy_stc_sysint_t * config, cy_israddress userIsr)
{
cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
if(NULL != config) /* Check if configuration parameter values are valid */
{
/* Only set the new vector if it is CPU interrupt (not internal SW interrupt) */
if ((config->intrSrc < CPUIntIdx0_IRQn) || (config->intrSrc >= Internal0_IRQn))
{
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
/ * Set the software interrupt handler. See Code Listing 16. */
(void)Cy_SysInt_SetVector(config->intrSrc, userIsr);
}
}
else
{
return CY_SYSINT_BAD_PARAM; // Vector of system handler have to be set at ROM table.
}
NVIC_SetPriority(config->intrSrc, config->intrPriority); /* (5) Set priority */
}
else
{
status = CY_SYSINT_BAD_PARAM;
}
return(status);
}
Code Listing 16 Cy_SysInt_SetVector() function
void Cy_SysInt_SetVector(IRQn_Type intrSrc, cy_israddress userIsr)
{
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
__ramVectors[CY_INT_IRQ_BASE + intrSrc] = userIsr; /* Set the interrupt handler */
}
}
Code Listing 17 Cy_SysInt_SoftwareTrig() function
__STATIC_INLINE void Cy_SysInt_SoftwareTrig(IRQn_Type intrSrc)
{
NVIC->STIR = intrSrc & CY_SYSINT_STIR_MASK; /* Set STIR */
}
- Interrupt Handling
Figure 17. Software interrupt handling flow example
The pending flag is cleared by handler transition. Therefore, when a software interrupt is generated using the set-pending registers, you do not need to clear the flag at return from the interrupt handler.
Code Listing 18 shows an example of CPU interrupt handler for software interrupt.
Code Listing 18 CPU interrupt handler for software interrupt
void SoftwareInterupt0Handler(void)
{
__NOP(); /* Software interrupt processing */
}
Software interrupt (using peripheral)
This series can generate software interrupts by utilizing unused peripherals. A software interrupt with peripherals uses the INTR_SET register in the peripheral interrupt structure. INTR_SET sets the corresponding bit in the INTR register by software writing ‘1’.
This section explains software interrupt generation by using peripherals and shows the setting procedure and return processing. The interrupt is processed by CM4.
Use case
- Interrupt setting
- System Interrupt source: TCPWM Group#0 Counter#1(IDX: 275) TC interrupt
- Mapped to CPU Interrupt: IRQ4
- CPU Interrupt Priority: 3
In this type of interrupts, the timer function of TCPWM Group#0 Counter#1 is unused.
Figure 18 shows interrupt operation for this configuration.
Figure 18. Software interrupt operation example by utilizing unused TCPWM
Configuration
- Initial setting procedure
See Initial setting for the initial setting procedure. After each peripheral resource (TCPWM Group#0 Counter#1) is set up, each resource interrupt is routed to the CPU interrupt. Next, set the level and permission of each CPU interrupt to the NVIC. After setting up interrupt connection, start each resource. See the “Timer, Counter, and PWM” chapter of the architecture TRM [2] for TCPWM setting.
Figure 19. Initial setting procedure for software interrupt (using peripheral)
Table 7 and Table 8 list the parameters and functions of the configuration part in SDL for interrupt initialization.
Table 7. List of interrupt initialization parameters
Parameters | Description | Value |
---|---|---|
irq_cfg_1.sysIntSrc | Set system interrupt index number [0: 1022] | tcpwm_0_interrupts_1_IRQn It is assigned to TCPWM Group#0 Counter#1 interrupt (Index number = 275) |
irq_cfg_1.intIdx | Set CPU interrupt number [0: 7] CPUIntIdx0_IRQn is assigned to IRQ 0, CPUIntIdx1_IRQn is assigned to IRQ 1, CPUIntIdx2_IRQn is assigned to IRQ 2, CPUIntIdx3_IRQn is assigned to IRQ 3, CPUIntIdx4_IRQn is assigned to IRQ 4, CPUIntIdx5_IRQn is assigned to IRQ 5, CPUIntIdx6_IRQn is assigned to IRQ 6, CPUIntIdx7_IRQn is assigned to IRQ 7 | CPUIntIdx4_IRQn |
irq_cfg_1.isEnabled | Set interrupt enable False: Disabled True: Enabled | True |
Table 8. List of interrupt initialization functions
Function | Description | Value |
---|---|---|
Cy_Tcpwm_Counter_SetTC_IntrMask (Count_num) | TCPWM interrupt enable Count_num: Interrupt enabled timer Counter number | TCPWMx_GRPx_CNTx_COUNTER_1 It is assigned to Counter#1 |
Cy_SysInt_InitIRQ(irq_cfg) | Configure interrupt structure Irq_cfg: Interrupt structure parameters address | &irq_cfg_1 |
Cy_SysInt_SetSystemIrqVector(sysintSrc, Handler) | Set system interrupt handler to vector table sysintSrc: System interrupt index number Handler: Interrupt handler address | sysintSrc: irq_cfg_1.sysIntSrc Handler: Counter_Handler, See Code Listing 21. |
NVIC_SetPriority(intrSrc, intPriority) | Set interrupt priority: intrSrc: CPU interrupt number intPriority: Interrupt priority level | intrSrc: irq_cfg_1.intIdx intPriority: 3ul |
NVIC_EnableIRQ(intSrc) | Set interrupt enable intSrc: CPU interrupt number | intrSrc: irq_cfg_1.intIdx |
Code Listing 19 shows an example program of the interrupt configuration part for software interrupt. See Initial setting for Configuration of (1).
Code Listing 19 Example of interrupt configuration
/ * Interrupt structure configuration parameters */
cy_stc_sysint_irq_t irq_cfg_1 =
{
.sysIntSrc = tcpwm_0_interrupts_1_IRQn,
.intIdx = CPUIntIdx4_IRQn,
.isEnabled = true,
};
void Counter_Handler(void) /* System interrupt handler */
{
:
}
int main(void)
{
SystemInit(); / * (2) Peripheral function setting */
/* (3) Enable global interrupt */
__enable_irq(); /* Enable global interrupts. */
/* (4) Configure the TCPWM. See Architecture TRM [2]. */
/* Configure TCPWM Group#0 Counter#1 */
:
/* Enable Interrupt */
/* (5) Enable the TCPWM counter#1 interrupt. See Code Listing 20. */
Cy_Tcpwm_Counter_SetTC_IntrMask(TCPWMx_GRPx_CNTx_COUNTER_1);
/* Interrupt setting for TCPWMs */
Cy_SysInt_InitIRQ(&irq_cfg_1);
/* (6) Configure interrupt structure */
Cy_SysInt_SetSystemIrqVector(irq_cfg_1.sysIntSrc, Counter_Handler);
/* Set the Interrupt Priority & Enable the Interrupt */
/* (7) Set priority (*1) */
NVIC_SetPriority(irq_cfg_1.intIdx, 3ul);
/* (8) Interrupt Enable (*1) */
NVIC_EnableIRQ(irq_cfg_1.intIdx);
/* Set INTR_SET register, TCPWM Group#0 Counter#1 */
/* (9) Set TCPWM Interrupt */
TCPWMx_GRPx_CNTx_COUNTER_1->unINTR_SET.u32Register = 0x1ul;
for(;;)
{
}
}
Code Listing 20 Cy_Tcpwm_Counter_SetTC_IntrMask () function
void Cy_Tcpwm_Counter_SetTC_IntrMask(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR_MASK.stcField.u1TC = 1ul; /* Interrupt enable */
}
- Interrupt handling
In this case, the start of interrupts is triggered by software. However, interrupt handling is similar to that of peripheral interrupts. See Interrupt handling for the interrupt handler configuration.
When an interrupt occurs, the CPU jumps to the interrupt handler specified in the vector table. Within the CPU interrupt handler, it identifies the system interrupt that triggered the CPU interrupt and jumps to the corresponding ISR. After clearing the system interrupt flag in the CPU interrupt handler and executing the ISR, clear the relevant CPU Pending register bit and return to the main routine.
Figure 20. Software interrupt handling by utilizing unused TCPWM
Note: (*) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
Code Listing 21 shows an example of system interrupt handler. See Code Listing 5 for CPU Interrupt handler.
Code Listing 21 Example of system interrupt handler
/* Interrupt handler registered in the configuration part */
void Counter_Handler(void)
{
/* Check the source that generated the interrupt */
if(Cy_Tcpwm_Counter_GetTC_IntrMasked(TCPWMx_GRPx_CNTx_COUNTER_1))
{
/* Clear TCPWM TC interrupt flag Group#0 Counter#1 */
/* Clear the peripheral interrupt flag that became the interrupt source. See Code Listing 22 */
Cy_Tcpwm_Counter_ClearTC_Intr(TCPWMx_GRPx_CNTx_COUNTER_1);
/* (3) Interrupt Processing. */
/* User program here.. */
}
}
Code Listing 22 Cy_Tcpwm_Counter_ClearTC_Intr()
void Cy_Tcpwm_Counter_ClearTC_Intr(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unINTR.stcField.u1TC = 1ul; /* (1) Clear interrupt flag */
ptscTCPWM->unINTR.u32Register; /* (2) Read back */
}
Fault report structure overview
Fault report structure
Fault report structures encapsulate information about transient faults that occur while software is running. Fault report structures store the information about the faults and can cause reset. The platform uses centralized fault report structures. This centralized nature allows for a system-wide, consistent handling of faults, which simplifies software development because of the following reasons:
- Only a single fault interrupt handler is required
- A fault report structure provides the fault source and additional fault-specific information from a single set of registers; that is, no iterative search for the fault source and fault information is required.
- All pending faults are available from a single set of registers.
Fault report structures capture faults such as MPU/SMPU/PPU protection violations, memory-specific errors such as ECC errors, peripheral-specific errors, and so on. Fault report structures capture only faults.
Figure 21 shows a block diagram of the fault report structure.
Figure 21. Fault report structure
This series have four fault report structures. Each fault report structure has a dedicated set of control and status registers, and captures a single fault.
When the fault report structure captures fault, it provides the following information:
- A flag that indicates a fault is captured
- A fault index that identifies the fault source
- Additional fault information describing fault specifics
For the fault and additional information captured by fault report structures, see the architecture TRM [2].
When the fault report structure captures a fault, it generates the following notification signals:
- Fault interrupt
- Trigger output
- Chip output signal
- Fault reset request
Each output signals can be selected as enabled or disabled with a register. A fault interrupt can be notified to the CPU as a system interrupt.
The pending structure holds the faults that are not captured by the fault report structure. When a pending fault is captured by a fault report structure, the associated pending bit is cleared to ‘0’. The fault report structure functionality is only available in Active and Sleep power modes.
Initial setting procedure
This section describes how to initialize interrupts using Sample Driver Library (SDL). The code snippets in this application note are part of SDL. See Other references for the SDL.
SDL basically has a configuration part and a driver part. The configuration part mainly configures the parameter values for the desired operation. The driver part configures each register based on the parameter values in the configuration part.
You can configure the configuration part according to your system.
Figure 22 shows the procedure for initializing the fault report structure. Initialize the fault report structure, and set the fault connection and action when detecting a fault.
Figure 22. Fault report structure initial setting flow
Use case
In this configuration, the CPU is notified of the interrupt via interrupt structure, when SRAM0 correctable ECC violation is detected.
IDX numbers used this section denote system interrupt index numbers. IDX numbers are the IDX number of CYT2B series. See the device datasheets [1] for the actual index number to use.
- Using fault report structure: #0
- Fault source: CPUSS_RAM0_C_ECC (IDX: 58)
- Fault action: Interrupt generation
- Mapped to CPU Interrupt: IRQ2
- CPU Interrupt Priority: 0
Configuration
Table 9 and Table 10 list the parameters and functions of the configuration part in SDL for fault report structure Initialization.
Table 9. List of fault report structure initialization parameters
Parameters | Description | Value |
---|---|---|
irq_cfg.sysIntSrc | Set system interrupt index number [0: 1022] | cpuss_interrupts_fault_0_IRQn It is assigned to Fault structure #0 interrupt (Index number = 8) |
irq_cfg.intIdx | Set CPU interrupt number [0: 7] CPUIntIdx0_IRQn is assigned to IRQ 0, CPUIntIdx1_IRQn is assigned to IRQ 1, CPUIntIdx2_IRQn is assigned to IRQ 2, CPUIntIdx3_IRQn is assigned to IRQ 3, CPUIntIdx4_IRQn is assigned to IRQ 4, CPUIntIdx5_IRQn is assigned to IRQ 5, CPUIntIdx6_IRQn is assigned to IRQ 6, CPUIntIdx7_IRQn is assigned to IRQ 7 | CPUIntIdx2_IRQn |
irq_cfg.isEnabled | Set interrupt enable False: Disabled True: Enabled | True |
tFlt_Temp.ResetEnable | Set reset request enable: False: Disabled True: Enabled | False |
tFlt_Temp.OutputEnable | Set IO output signal enable: False: Disabled True: Enabled | |
tFlt_Temp.TriggerEnable | Set Trigger output enable: False: Disabled True: Enabled |
Table 10. List of fault report structure initialization functions
Value | ||
---|---|---|
Cy_SysFlt_ClearStatus(FAULT_STRUCT) | Clear fault structure status: FAULT_STRUCT: Fault report structure number FAULT_STRUCT0 = Fault report structure 0 FAULT_STRUCT1 = Fault report structure 1 FAULT_STRUCT2 = Fault report structure 2 FAULT_STRUCT3 = Fault report structure 3 | FAULT_STRUCT0 |
Cy_SysFlt_ClearInterrupt(FAULT_STRUCT) | Clear fault structure interrupt flag: | FAULT_STRUCT0 |
Cy_SysFlt_SetInterruptMask(FAULT_STRUCT) | Set interrupt enable: FAULT_STRUCT: Fault report structure number | FAULT_STRUCT0 |
Cy_SysFlt_SetMaskByIdx(FAULT_STRUCT, faultSrc) | Select fault source: FAULT_STRUCT: Fault report structure number faultSrc: Fault Source | FAULT_STRUCT: FAULT_STRUCT0 faultSrc: CY_SYSFLT_RAMC0_C_ECC It is assigned CPUSS_RAM0_C_ECC (Fault number = 58) |
Cy_SysFlt_Init(FAULT_STRUCT, tFlt_Temp) | Set fault structure action: FAULT_STRUCT: Fault report structure number tFlt_Temp: Action parameters | FAULT_STRUCT0 |
Code Listing 23 show an example program of the fault report configuration part.
The following description will help you understand the register notation of the driver part of SDL:
- ptsc SYSFLT signifies the pointer to the fault report structure register base address.
- ptsc SYSFLT ->un STATUS.u32Register is the FAULT_STRUCTx_STATUS register mentioned in the registers TRM [2]. Other registers are also described in the same manner. “ x ” signifies the fault report structure number.
See cyip_fault_v2.h under hdr/rev_x/ip for more information on the union and structure representation of registers.
Code Listing 23 Example of fault report structure configuration
cy_stc_sysint_irq_t irq_cfg = /* Configure interrupt structure parameters */
{
.sysIntSrc = cpuss_interrupts_fault_0_IRQn,
.intIdx = CPUIntIdx2_IRQn,
.isEnabled = true,
};
int main(void)
{
cy_stc_sysflt_t tFlt_Temp = {0ul};
:
/* Clear Status register */
/* (1) Initialize interrupt flag. See Code Listing 24fault-report-structure-configuration). */
Cy_SysFlt_ClearInterrupt(FAULT_STRUCT0);
/* (2) Read back */
FAULT_STRUCT0->unINTR.u32Register;
/* (3) Initialize status register.See Code Listing 25unction) */
Cy_SysFlt_ClearStatus(FAULT_STRUCT0);
/* Set the signal interface (Interrupt generation) */
/* (4) Fault source selection. See Code Listing 26. */
Cy_SysFlt_SetInterruptMask(FAULT_STRUCT0);
/* (4) Fault source selection. See Code Listing 26. */
/* Fault source enable 58 System memory controller 0 correctable ECC violation */
/* (4) Fault source selection. See Code Listing 26. */
Cy_SysFlt_SetMaskByIdx(FAULT_STRUCT0, CY_SYSFLT_RAMC0_C_ECC);
/* Init Sysflt */
/* (5) Action Setting. See Code Listing 27. */
tFlt_Temp.ResetEnable = false;
/* (5) Action Setting. See Code Listing 27. */
tFlt_Temp.OutputEnable = false;
/* (5) Action Setting. See Code Listing 27. */
tFlt_Temp.TriggerEnable = false;
/* (5) Action Setting. See Code Listing 27. */
Cy_SysFlt_Init(FAULT_STRUCT0, &tFlt_Temp);
/* Interrupt setting */
/* (6) Configure interrupt setting. See Code Listing 3 and Code Listing 4. */
Cy_SysInt_InitIRQ(&irq_cfg);
/* Set interrupt handler */
Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, irqFaultReport0Handler);
/* Set the Interrupt Priority & Enable the Interrupt */
/* (7) Configure NVIC. Priority sets to “0”. */
NVIC_SetPriority(irq_cfg.intIdx, 0ul);
/* (7) Configure NVIC. Priority sets to “0”. */
NVIC_EnableIRQ(irq_cfg.intIdx);
:
for(;;)
{
}
}
Code Listing 24 Cy_SysFlt_ClearInterrupt () function
void Cy_SysFlt_ClearInterrupt(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unINTR.stcField.u1FAULT = true; /* Fault structure interrupt flag clear */
}
Code Listing 25 Cy_SysFlt_ClearStatus () function
void Cy_SysFlt_ClearStatus(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unSTATUS.u32Register = 0x00000000UL; /* Fault structure status clear */
}
Code Listing 26 Cy_SysFlt_SetMaskByIdx() and
Cy_SysFlt_SetInterruptMask() functions
void Cy_SysFlt_SetMaskByIdx(volatile stc_FAULT_STRUCT_t *ptscSYSFLT, cy_en_sysflt_source_t idx)
{
switch(idx / 32)
{
case 0:
ptscSYSFLT->unMASK0.u32Register |= (1UL << (uint32_t)idx); /* Fault source select */
break;
case 1:
ptscSYSFLT->unMASK1.u32Register |= (1UL << ((uint32_t)idx - 32UL));
break;
case 2:
ptscSYSFLT->unMASK2.u32Register |= (1UL << ((uint32_t)idx - 64UL));
break;
default:
break;
}
return;
}
void Cy_SysFlt_SetInterruptMask(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
ptscSYSFLT->unINTR_MASK.stcField.u1FAULT = true; /* Fault structure interrupt enable */
}
Code Listing 27 Cy_SysFlt_Init() function
void Cy_SysFlt_Init(volatile stc_FAULT_STRUCT_t *ptscSYSFLT,const cy_stc_sysflt_t * config)
{
if (config->TriggerEnable) /* Fault action select */
{
ptscSYSFLT->unCTL.stcField.u1TR_EN = true; /* Trigger output enable */
}
else
{
ptscSYSFLT->unCTL.stcField.u1TR_EN = false; /* Trigger output enable */
}
if (config->OutputEnable)
{
ptscSYSFLT->unCTL.stcField.u1OUT_EN = true; /* IO output signal enable */
}
else
{
ptscSYSFLT->unCTL.stcField.u1OUT_EN = false; /* IO output signal enable */
}
if (config->ResetEnable)
{
ptscSYSFLT->unCTL.stcField.u1RESET_REQ_EN = true; /* Reset request enable */
}
else
{
ptscSYSFLT->unCTL.stcField.u1RESET_REQ_EN = false; /* Reset request enable */
}
}
Fault handling
As mentioned earlier, when the fault report structure captures a fault, it can notify the system of the occurrence of the fault. In addition, the fault report structure captures additional information for failure analysis.
Figure 23 shows an example of the handling when an interrupt is notified.
Figure 23. Fault handling example
Note: (*) The SYSTEM_INT_VALID bit is not set when a software interrupt occurs using the software triggered interrupt register (STIR). See Software interrupt (using CPU register) for software interrupts.
Note: (*1) If a fault is not active (FAULT_STRUCT_STATUS.VALID = 0), FAULT_STRUCT_STATUS_IDX and FAULT_STRUCT_DATA are invalid.
Note: (*2) The number of registers used as additional information depends on the detected fault. See the architecture TRM [2] and registers TRM [2] for more information.
The software checks the cause of the fault from the additional information, and executes appropriate safety operation or diagnostic programs according to fault situations. If recovery to normal operation is possible after safe operation, return from the interrupt.
Code Listing 28 shows an example program of the fault interrupt handler.
Code Listing 28 Fault interrupt handler
/* Interrupt handler registered in the configuration part */
void irqFaultReport0Handler(void)
{
cy_en_sysflt_source_t status;
/* Clear Interrupt flag */
/* (1) Clear interrupt flag. See [Code Listing 24](#code-listing-24-cy_sysflt_clearinterrupt--function) */
Cy_SysFlt_ClearInterrupt(FAULT_STRUCT0);
FAULT_STRUCT0->unINTR.u32Register; /* Read Back */ /* (2) Read back */
/* (3) Check fault source. See [Code Listing 29](#code-listing-29-cysysflt_geterrorsource-function). */
status = Cy_SysFlt_GetErrorSource(FAULT_STRUCT0);
/* (3) Check fault source. See [Code Listing 29](#code-listing-29-cysysflt_geterrorsource-function). */
if(status == CY_SYSFLT_RAMC0_C_ECC)
{
/* (4) Read the fault information. See [Code Listing 30](#code-listing-30-cy_sysfltgetdata0-and-1--function). */
violatingAddr = Cy_SysFlt_GetData0(FAULT_STRUCT0);
violatingInfo.u32 = Cy_SysFlt_GetData1(FAULT_STRUCT0);
/* (5) Safe Operation. (Fault handling) */
/* User program here.. */
}
/* Clear Status register */
/* (6) Clear status register. See [Code Listing 25](#code-listing-25-cy_sysflt_clearstatus--function). */
Cy_SysFlt_ClearStatus(FAULT_STRUCT0);
}
Code Listing 29 CySysFlt_GetErrorSource() function
cy_en_sysflt_source_t Cy_SysFlt_GetErrorSource(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
if(ptscSYSFLT->unSTATUS.stcField.u1VALID == 1u) /* Check Fault is valid */
{
/* Read Fault Index */
return((cy_en_sysflt_source_t)(ptscSYSFLT->unSTATUS.stcField.u7IDX));
}
else
{
return CY_SYSFLT_NO_FAULT;
}
}
Code Listing 30 Cy_SysFltGetData0 and 1 () function
uint32_t Cy_SysFlt_GetData0(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unDATA[0].u32Register);
} /* Read additional information of fault */
uint32_t Cy_SysFlt_GetData1(volatile stc_FAULT_STRUCT_t *ptscSYSFLT)
{
return(ptscSYSFLT->unDATA[1].u32Register); /* Read additional information of fault */
}
Usage example of fault report structure
An example of using the fault report structure is explained according to the following usage assumptions.
IDX numbers in this section denote faults index numbers. IDX numbers are the IDX number of CYT2B series. See the device datasheets [1] for the actual index number to use.
Reset generation
This section explains the generation of a reset signal when a fault is detected, and shows its operation and initial setting.
Use case
In this configuration, reset will be issued, when CM0+ violates SMPU protection.
- Using fault report structure: #0
- Fault source: CPUSS_MPU_VIO_0 (IDX: 0)
- Fault Action: Reset generation
Note: (*) See the architecture TRM [2] and registers TRM [2] for fault assignment and additional information.
A fault reset causes a warm/soft reset. For failure analysis, fault information such as FAULT_STATUS and FAULT_DATA registers are retained during a warm/soft reset.
Configuration
- Initial setting procedure
Set according to the Initial setting procedure. Initialize the fault report structure to be used (Fault Report Structure#0), set the action (Reset) at detection and the fault source (MPU_VIO_0). Table 11 and Table 12 list the parameters and functions of the configuration part in SDL for fault report structure Initialization.
Table 11. List of fault report structure initialization parameters
Parameters | Description | Value |
---|---|---|
tFlt_Temp.ResetEnable | Set reset request enable: False: Disabled True: Enabled | True |
tFlt_Temp.OutputEnable | Set IO output signal enable: False: Disabled True: Enabled | False |
tFlt_Temp.TriggerEnable | Set Trigger output enable: False: Disabled True: Enabled | False |
Table 12. List of fault report structure initialization functions
Function | Description | Value |
---|---|---|
Cy_SysFlt_SetMaskByIdx(FAULT_STRUCT, faultSrc) | Select fault source: FAULT_STRUCT: Fault report structure number faultSrc: Fault Source | FAULT_STRUCT: FAULT_STRUCT0 faultSrc: CY_SYSFLT_MPU_0 It is assigned MPU_VIO_0 (Fault number = 0) |
Code Listing 31 shows an example program of the Fault Report Structure configuration part for reset generation.
Code Listing 31 Example of fault report structure configuration
:
/* Fault source enable 58 System memory controller 0 correctable ECC violation */
/* Fault source selection. See [Code Listing 26](#code-listing-26-cy_sysflt_setmaskbyidx-and). */
Cy_SysFlt_SetMaskByIdx(FAULT_STRUCT0, CY_SYSFLT_MPU_0);
:
/* Init Sysflt */
tFlt_Temp.ResetEnable = true; /* Action Setting. See Code Listing 27. */
tFlt_Temp.OutputEnable = false; /* Action Setting. See Code Listing 27. */
tFlt_Temp.TriggerEnable = false; /* Action Setting. See Code Listing 27. */
Cy_SysFlt_Init(FAULT_STRUCT0, &tFlt_Temp); /* Action Setting. See Code Listing 27. */
:
NMI generation via interrupt structure
This section explains the generation of NMI to the CPU when a fault is detected, and shows its operation, initial setting, and fault processing.
Figure 24 shows the procedure for initializing the fault report structure. Initialize the fault report structure, and set the fault connection and action when detecting a fault.
Figure 24. Fault report structure initial setting flow for NMI generation
Use case
Note: In this configuration, reset will be issued, when CM0+ violates SMPU protection. PPU violation can cause a bus error depending on the setting of the CPUSS_BUFF_CTL register. See the architecture TRM [2] and registers TRM [2] for more details.
- Using fault report structure: #0
- Fault source: PERI_MS_VIO_1 (IDX: 29) CM4 peripheral master interface, PPU violation
- Additional information:
- DATA0[31:0] is indicated the violating address1
- DATA1[0] is User read1
- DATA1[1] is User write1
- DATA1[2] is User execute1
- DATA1[3] is Privileged read1
- DATA1[4] is Privileged write1
- DATA1[5] is Privileged execute1
- DATA1[6] is Non-secure1
- DATA1[11:8] is Master identifier1
- DATA1[15:12] is Protection context identifier1
- DATA1[31:28] is fault identification code1
- Interrupt generation
- Mapped to CPU NMI
1 See the architecture TRM [2] and registers TRM [2] for fault assignment and additional information.
Configuration
Set according to the Initial setting procedure. Table 13 and Table 14 list the parameters and functions of the configuration part in SDL for fault report structure Initialization.
Table 13. List of fault report structure initialization parameters
Parameters | Description | Value |
---|---|---|
irq_cfg.sysIntSrc | Set system interrupt index number [0: 1022] | cpuss_interrupts_fault_0_IRQn It is assigned to Fault structure #0 interrupt (Index number = 8) |
irq_cfg.intIdx | Set CPU interrupt number [0: 7] CPUIntIdx0_IRQn is assigned to IRQ 0, CPUIntIdx1_IRQn is assigned to IRQ 1, CPUIntIdx2_IRQn is assigned to IRQ 2, CPUIntIdx3_IRQn is assigned to IRQ 3, CPUIntIdx4_IRQn is assigned to IRQ 4, CPUIntIdx5_IRQn is assigned to IRQ 5, CPUIntIdx6_IRQn is assigned to IRQ 6, CPUIntIdx7_IRQn is assigned to IRQ 7, | CPUIntIdx4_IRQn |
irq_cfg.isEnabled | Set interrupt enable False: Disabled True: Enabled | True |
tFlt_Temp.ResetEnable | Set reset request enable: False: Disabled True: Enabled | False |
tFlt_Temp.OutputEnable | Set IO output signal enable: False: Disabled True: Enabled | False |
tFlt_Temp.TriggerEnable | Set Trigger output enable: False: Disabled True: Enabled | False |
Table 14. List of fault report structure initialization functions
Function | Description | Value |
---|---|---|
Cy_SysFlt_ClearStatus(FAULT_STRUCT) | Clear fault structure status: FAULT_STRUCT: Fault report structure number FAULT_STRUCT0 = Fault report structure 0 FAULT_STRUCT1 = Fault report structure 1 FAULT_STRUCT2 = Fault report structure 2 FAULT_STRUCT3 = Fault report structure 3 | FAULT_STRUCT0 |
Cy_SysFlt_ClearInterrupt(FAULT_STRUCT) | Clear fault structure interrupt flag: | FAULT_STRUCT0 |
Cy_SysFlt_SetInterruptMask(FAULT_STRUCT) | Set interrupt enable: FAULT_STRUCT: Fault report structure number | FAULT_STRUCT0 |
Cy_SysFlt_SetMaskByIdx(FAULT_STRUCT, faultSrc) | Select fault source: FAULT_STRUCT: Fault report structure number faultSrc: Fault Source | FAULT_STRUCT: FAULT_STRUCT0 faultSrc: CY_SYSFLT_MS_PPU_1 It is assigned PERI_MS_VIO_1 (Fault number = 29) |
Cy_SysFlt_Init(FAULT_STRUCT, tFlt_Temp) | Set fault structure action: FAULT_STRUCT: Fault report structure number tFlt_Temp: Action parameters | FAULT_STRUCT0 |
Cy_SysInt_SetIntSourceNMI (Reg_num, sysintSrc) | Set NMI register Reg_num: CM4 NMI control Register number CPUSS_CM4_NMI_CTLx register (x = 0 to 3) sysintSrc: System interrupt index number | Reg_nim: 0ul Use CPUSS_CM4_NMI_CTL0 register sysintSrc: irq_cfg.sysIntSrc |
Code Listing 32 shows an example program of the fault report structure configuration part for NMI generation.
Code Listing 32 Example of fault report structure configuration
cy_stc_sysint_irq_t irq_cfg = /* Configure interrupt structure parameters. */
{
.sysIntSrc = cpuss_interrupts_fault_0_IRQn,
.intIdx = CPUIntIdx4_IRQn,
.isEnabled = true,
};
int main(void)
{
cy_stc_sysflt_t tFlt_Temp = {0ul};
:
/* Clear Status register */
/* (1) Initialize interrupt flag. See Code Listing 24. */
Cy_SysFlt_ClearInterrupt(FAULT_STRUCT0);
/* (2) Read back. */
FAULT_STRUCT0->unINTR.u32Register;
/* (3) Initialize status register. See Code Listing 25. */
Cy_SysFlt_ClearStatus(FAULT_STRUCT0);
/* Set the signal interface (Interrupt generation) */
/* (4) Fault source selection. See Code Listing 26. */
Cy_SysFlt_SetInterruptMask(FAULT_STRUCT0);
/* Fault source enable 29 CM4 Peripheral Master Interface PPU violation */
/* (4) Fault source selection. See Code Listing 26. */
Cy_SysFlt_SetMaskByIdx(FAULT_STRUCT0, CY_SYSFLT_MS_PPU_1);
/* Init Sysflt */
/* (5) Action Setting. See Code Listing 27. */
tFlt_Temp.ResetEnable = false;
/* (5) Action Setting. See Code Listing 27. */
tFlt_Temp.OutputEnable = false;
/* (5) Action Setting. See Code Listing 27. */
tFlt_Temp.TriggerEnable = false;
/* (5) Action Setting. See Code Listing 27. */
Cy_SysFlt_Init(FAULT_STRUCT0, &tFlt_Temp);
/* Set NMI mapping of CM4 */
/* (6) Configure NMI See Code Listing 10. */
Cy_SysInt_SetIntSourceNMI(0ul, irq_cfg.sysIntSrc);
/* Interrupt setting */
Cy_SysInt_InitIRQ(&irq_cfg);
/* (7) Configure interrupt setting. See Code Listing 3 and Code Listing 4. */
Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, NMI_Handler); /* Set NMI handler. */
/* CPUSS_BUFF_CTL register setting */
CPUSS->unBUFF_CTL.stcField.u1WRITE_BUFF = 1ul;
:
for(;;)
{
}
}
- Fault handling example
When access violation to the PPU#1 master occurs, the fault report structure captures the fault information and outputs an interrupt signal to the interrupt structure. The interrupt structure routes an interrupt from the fault report structure to the NMI, and notifies the NMI to the CPU.
Figure 25. Fault handling flow example
Note: (*1) If there are multiple (four) NMI factors depending on the system, the NMI handler may need to investigate all selected system interrupt sources to identify the source of the CPU NMI.
The software checks the cause of the fault from the additional information, and executes appropriate safety operation or diagnostic programs according to fault situations. If recovery to normal operation is possible after safe operation, return from the interrupt.
Code Listing 33 shows an example program of the fault interrupt handler.
Code Listing 33 Fault interrupt handler for NMI generation
void NMI_Handler(void) /* NMI handler registered in the configuration part. */
{
cy_en_sysflt_source_t status;
/* Clear Interrupt flag */
Cy_SysFlt_ClearInterrupt(FAULT_STRUCT0); /* (1) Clear interrupt flag. See Code Listing 24.*/
FAULT_STRUCT0->unINTR.u32Register; /* Read Back */ /* (2) Read back. */
status = Cy_SysFlt_GetErrorSource(FAULT_STRUCT0); /* (3) Check fault factor. See Code Listing 29. */
if(status == CY_SYSFLT_MS_PPU_1) /* (3) Check fault factor. See Code Listing 29. */
{
/* (4) Read the fault information. See Code Listing 30. */
violatingAddr = Cy_SysFlt_GetData0(FAULT_STRUCT0);
violatingInfo.u32 = Cy_SysFlt_GetData1(FAULT_STRUCT0);
/* (5) Execute diagnosis and Safe Operation (Fault handling). */
/* User program here.. */
}
/* Clear Status register */
Cy_SysFlt_ClearStatus(FAULT_STRUCT0); /* (6) Clear status register. See Code Listing 25. */
}
1 See the architecture TRM [2] and registers TRM [2] for fault assignment and additional information.
1 See the architecture TRM [2] and registers TRM [2] for fault assignment and additional information.
1 See the architecture TRM [2] and registers TRM [2] for fault assignment and additional information.
Glossary
Terms | Description |
---|---|
CPU | Central Processing Unit |
NVIC | Nested vectored interrupt controller |
WIC | Wakeup interrupt controller |
NMI | Non-maskable interrupt |
DeepSleep | Low Power mode in TRAVEO™ T2G family series. See the “Device Power Mode” chapter of the architecture TRM [2] for details. |
ISR | Interrupt service routine |
IRQ | Interrupt request |
WFI | Wait for interrupt |
MMIO | Memory mapped I/O |
MPU | Memory Protection Unit. See the “Protection Unit” chapter of the architecture TRM [2] for details. |
SMPU | Shared Memory Protection Unit. See the “Protection Unit” chapter of the architecture TRM [2]for details. |
PPU | Peripheral Protection Unit. See the “Protection Unit” chapter of the architecture TRM [2] for details. |
GPIO | General purpose input/output. See the “IO System” chapter of the architecture TRM [2] for details. |
TCPWM | Timer, Counter, and Pulse Width Modulator. See the “Timer, Counter, and PWM” chapter of the architecture TRM [2] for details. |
RTC | Real-time clock. See the “Real-time Clock” chapter of the architecture TRM [2]for details. |
References
The following are the TRAVEO™ T2G family series datasheets and technical reference manuals. Contact Technical Support to obtain these documents.
-
Device datasheets:
- CYT2B7 d atasheet 32- b it Arm® Cortex®-M4F m icrocontroller TRAVEO™ T2G f amily
- CYT2B9 d atasheet 32- b it Arm® Cortex®-M4F m icrocontroller TRAVEO™ T2G f amily
- CYT4BF d atasheet 32- b it Arm® Cortex®-M7 m icrocontroller TRAVEO™ T2G f amily
- CYT4DN datasheet 32-bit Arm® Cortex®-M7 microcontroller TRAVEO™ T2G family (Doc No. 002-24601)
- CYT3BB/4BB d atasheet 32- b it Arm® Cortex®-M7 m icrocontroller TRAVEO™ T2G f amily
- CYT3DL datasheet 32-bit Arm® Cortex®-M7 microcontroller TRAVEO™ T2G family (Doc No. 002-27763)
-
Technical reference manuals:
-
Body controller entry family
- TRAVEO™ T2G a utomotive b ody c ontroller e ntry f amily a rchitecture t echnical r eference m anual (TRM)
- TRAVEO™ T2G a utomotive b ody c ontroller e ntry r egisters t echnical r eference m anual (TRM) for CYT2B7
- TRAVEO™ T2G a utomotive b ody c ontroller e ntry r egisters t echnical r eference m anual (TRM) for CYT2B9
-
Body controller high family
- TRAVEO™ T2G a utomotive b ody c ontroller h igh f amily a rchitecture t echnical r eference m anual (TRM)
- TRAVEO™ T2G a utomotive b ody c ontroller h igh r egisters t echnical r eference m anual (TRM) for CYT4BF
- TRAVEO™ T2G a utomotive b ody c ontroller h igh r egisters t echnical r eference m anual (TRM) for CYT3BB/4BB
-
Cluster 2D family
- TRAVEO™ T2G automotive cluster 2D family architecture technical reference manual (TRM) (Doc No. 002-25800)
- TRAVEO™ T2G automotive cluster 2D registers technical reference manual (TRM) for CYT4DN (Doc No. 002-25923)
- TRAVEO™ T2G automotive cluster 2D registers technical reference manual (TRM) for CYT3DL (Doc No. 002-29854)
-
-
Application notes:
Other references
A Sample Driver Library (SDL) including startup as sample software to access various peripherals is provided. SDL also serves as a reference, to customers, for drivers that are not covered by the official AUTOSAR products. The SDL cannot be used for production purposes as it does not qualify to any automotive standards. The code snippets in this application note are part of the SDL. Contact Technical Support to obtain the SDL.
Revision history
Document version | Date of release | Description of changes |
---|---|---|
** | 2018-03-09 | New Application Note. |
*A | 2018-11-29 | Changed target parts number (CYT2B series). Added Note (*1) and VTOR explanation in Initial setting Changed IDX from 17, 18, and 19 to 21, 22, and 23 in Peripheral interrupt handling Changed IDX from 274 and 275 to 273 and 274 in NMI generation of system interrupts Changed IDX from 275 to 274 in Software interrupt (using peripheral) Changed IDX from 47 to 8 in NMI generation via interrupt structure |
*B | 2019-02-22 | Added target parts number (CYT4B series). |
*C | 2019-07-25 | Added target parts number (CYT4D series). |
*D | 2020-02-14 | Changed target parts number (CYT2/ CYT4 series) Added target parts number (CYT3 series) |
*E | 2021-10-22 | Changed Figure 3 Updated sections 2.3, 2.4, 2.6, 3.2, 3.3, 3.4 - Changed Flowchart - Change Use case - Added Configuration and Code Updated References Added information on the Sample Driver Library in Other references |
*F | 2021-07-05 | Added note in section 2.3 Updated Figure 4 and Figure 12 Added supported device (CYT3DL) |
*G | 2023-11-10 | Template update; no content update |
1 See the architecture TRM [2] and registers TRM [2] for fault assignment and additional information.