Interrupts and Exceptions

Description

This section explains how to use interrupts and exceptions and access functions for the Enhanced Core Local Interrupt Controller(ECLIC).

Nuclei provides a template file startup_device for each supported compiler. The file must be adapted by the silicon vendor to include interrupt vectors for all device-specific interrupt handlers. Each interrupt handler is defined as a weak function to an dummy handler. These interrupt handlers can be used directly in application software without being adapted by the programmer.

Click Interrupt to learn more about interrupt handling in Nuclei processor core.

NMI Interrupt

NMI interrupt entry is stored by CSR_MNVEC. If CSR_MMSIC[9] is 1 then NMI entry is the same as Exception which get from CSR_MTVEC. If CSR_MMSIC[9] is 1 NMI entry is reset vector.

Exception

Exception has only 1 entry address which stored by CSR_MTVEC. All the exceptions will jump to the same entry exc_entry defined in intexc_<Device>.S.

The table below lists the core exception code of the Nuclei N/NX processors.

Core exception code of the Nuclei N/NX processors

Exception Code

Value

Description

InsUnalign_EXCn

0

Instruction address misaligned

InsAccFault_EXCn

1

Instruction access fault

IlleIns_EXCn

2

Illegal instruction

Break_EXCn

3

Beakpoint

LdAddrUnalign_EXCn

4

Load address misaligned

LdFault_EXCn

5

Load access fault

StAddrUnalign_EXCn

6

Store or AMO address misaligned

StAccessFault_EXCn

7

Store or AMO access fault

UmodeEcall_EXCn

8

Environment call from User mode

MmodeEcall_EXCn

11

Environment call from Machine mode

NMI_EXCn

0xfff

NMI interrupt

Vector Table

The Vector Table defines the entry addresses of the ECLIC managed interrupts.

It is typically located at the beginning of the program memory, and you can modify CSR MTVT to reallocate the base address of this vector table, but you need to take care of the base address alignment according to the number of interrupts.

base address alignment according to the number of interrupts

Number of Interrupt

Alignment Requirements of CSR MTVT

0 to 16

64-byte

17 to 32

128-byte

33 to 64

256-byte

65 to 128

512-byte

129 to 256

1KB

257 to 512

2KB

513 to 1024

4KB

Interrupt number 0~18 is reserved by Nuclei Core. 19~1023 could be used by Silicon Vendor Device.

Below is an example interrupt allocated table:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
typedef enum IRQn {
    /******  Nuclei N/NX Processor Core Internal Interrupt Numbers *************************/
    Reserved0_IRQn               =   0,     /*!<  Internal reserved                        */
    Reserved1_IRQn               =   1,     /*!<  Internal reserved                        */
    Reserved2_IRQn               =   2,     /*!<  Internal reserved                        */
    SysTimerSW_IRQn              =   3,     /*!<  System Timer SW interrupt                */
    Reserved3_IRQn               =   4,     /*!<  Internal reserved                        */
    Reserved4_IRQn               =   5,     /*!<  Internal reserved                        */
    Reserved5_IRQn               =   6,     /*!<  Internal reserved                        */
    SysTimer_IRQn                =   7,     /*!<  System Timer Interrupt                   */
    Reserved6_IRQn               =   8,     /*!<  Internal reserved                        */
    Reserved7_IRQn               =   9,     /*!<  Internal reserved                        */
    Reserved8_IRQn               =  10,     /*!<  Internal reserved                        */
    Reserved9_IRQn               =  11,     /*!<  Internal reserved                        */
    Reserved10_IRQn              =  12,     /*!<  Internal reserved                        */
    Reserved11_IRQn              =  13,     /*!<  Internal reserved                        */
    Reserved12_IRQn              =  14,     /*!<  Internal reserved                        */
    Reserved13_IRQn              =  15,     /*!<  Internal reserved                        */
    Reserved14_IRQn              =  16,     /*!<  Internal reserved                        */
    HardFault_IRQn               =  17,     /*!<  Hard Fault, storage access error         */
    Reserved15_IRQn              =  18,     /*!<  Internal reserved                        */

    /******  GD32VF103 Specific External Interrupt Numbers *********************************/
    WWDGT_IRQn                   =  19,     /*!< window watchDog timer interrupt           */
    LVD_IRQn                     =  20,     /*!< LVD through EXTI line detect interrupt    */
    TAMPER_IRQn                  =  21,     /*!< tamper through EXTI line detect           */
                 :       :
                 :       :
    CAN1_EWMC_IRQn               =  85,     /*!< CAN1 EWMC interrupt                       */
    USBFS_IRQn                   =  86,     /*!< USBFS global interrupt                    */
    SOC_INT_MAX,                            /*!< Number of total Interrupts                */
} IRQn_Type;

ECLIC API Definitions

When macro NMSIS_ECLIC_VIRTUAL is defined, the ECLIC access functions in the table below must be implemented for virtualizing ECLIC access.

These functions should be implemented in a separate source module. The original NMSIS-Core __ECLIC_xxx functions are always available independent of NMSIS_ECLIC_VIRTUAL macro.

ECLIC Access Functions

ECLIC ACCESS FUNCTIONS

NMSIS-CORE FUNCTIONS FOR ECLIC

ECLIC_SetCfgNlbits

__ECLIC_SetCfgNlbits()

ECLIC_GetCfgNlbits

__ECLIC_GetCfgNlbits()

ECLIC_GetInfoVer

__ECLIC_GetInfoVer()

ECLIC_GetInfoCtlbits

__ECLIC_GetInfoCtlbits()

ECLIC_GetInfoNum

__ECLIC_GetInfoNum()

ECLIC_SetMth

__ECLIC_SetMth()

ECLIC_GetMth

__ECLIC_GetMth()

ECLIC_EnableIRQ

__ECLIC_EnableIRQ()

ECLIC_GetEnableIRQ

__ECLIC_GetEnableIRQ()

ECLIC_DisableIRQ

__ECLIC_DisableIRQ()

ECLIC_SetPendingIRQ

__ECLIC_SetPendingIRQ()

ECLIC_GetPendingIRQ

__ECLIC_GetPendingIRQ()

ECLIC_ClearPendingIRQ

__ECLIC_ClearPendingIRQ()

ECLIC_SetTrigIRQ

__ECLIC_SetTrigIRQ()

ECLIC_GetTrigIRQ

__ECLIC_GetTrigIRQ()

ECLIC_SetShvIRQ

__ECLIC_SetShvIRQ()

ECLIC_GetShvIRQ

__ECLIC_GetShvIRQ()

ECLIC_SetCtrlIRQ

__ECLIC_SetCtrlIRQ()

ECLIC_GetCtrlIRQ

__ECLIC_GetCtrlIRQ()

ECLIC_SetLevelIRQ

__ECLIC_SetLevelIRQ()

ECLIC_GetLevelIRQ

__ECLIC_GetLevelIRQ()

ECLIC_SetPriorityIRQ

__ECLIC_SetPriorityIRQ()

ECLIC_GetPriorityIRQ

__ECLIC_GetPriorityIRQ()

When NMSIS_VECTAB_VIRTUAL macro is defined, the functions in the table below must be replaced to virtualize the API access functions to the interrupt vector table.

The ECLIC vector table API should be implemented in a separate source module.

This allows, for example, alternate implementations to relocate the vector table from flash to RAM on the first vector table update.

The original NMSIS-Core functions are always available, but prefixed with __ECLIC.

ECLIC Vector Access Functions

ECLIC Vector Table Access

NMSIS-CORE FUNCTIONS

ECLIC_SetVector

__ECLIC_SetVector()

ECLIC_GetVector

__ECLIC_GetVector()

ECLIC Function Usage

The code below shows the usage of various NMSIS ECLIC flow with an GD32VF103 device.

gd32vf103_interrupt_example1.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "gd32vf103.h"

// Vector interrupt which could be nested
__INTERRUPT void eclic_button1_handler(void)
{
    SAVE_IRQ_CSR_CONTEXT();                                           /* save mepc,mcause,msubm enable interrupts */

    GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << GREEN_LED_GPIO_OFFSET);        /* Green LED On */
    GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_1_GPIO_OFFSET);           /* Clear the GPIO Pending interrupt by writing 1. */

    RESTORE_IRQ_CSR_CONTEXT();                                        /* disable interrupts,restore mepc,mcause,msubm */
}

// Non-vector interrupt
void eclic_button2_handler(void)
{
    GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << GREEN_LED_GPIO_OFFSET);        /* Green LED On */
    GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_2_GPIO_OFFSET);           /* Clear the GPIO Pending interrupt by writing 1. */
}

void eclic_global_initialize(void)
{
    ECLIC_SetMth(0);
    ECLIC_SetCfgNlbits(3);
}

int eclic_register_interrupt(IRQn_Type IRQn, uint8_t shv, uint32_t trig_mode, uint32 lvl, uint32_t priority, void * handler)
{
    ECLIC_SetShvIRQ(IRQn, shv);
    ECLIC_SetTrigIRQ(IRQn, trig_mode);
    ECLIC_SetLevelIRQ(IRQn, lvl);
    ECLIC_SetPriorityIRQ(IRQn, priority);
    ECLIC_SetVector(IRQn, (rv_csr_t)(handler));
    ECLIC_EnableIRQ(IRQn);
    return 0;
}

int main (void)
{
    uint32_t returnCode;

    eclic_global_initialize();                                /* initialize ECLIC */

    GPIO_init();                                              /* initialize GPIO */

    returnCode = eclic_register_interrupt(BTN1_IRQn,1,2,1,0,Button1_IRQHandler);  /* register system button1 interrupt */
    returnCode = eclic_register_interrupt(BTN2_IRQn,0,2,2,0,Button2_IRQHandler);  /* register system button2 interrupt */

    __enable_irq();                                           /* enable global interrupt */

    if (returnCode != 0)  {                                   /* Check return code for errors */
      // Error Handling
    }

    while(1);
}

Interrupt and Exception API

enum NMSIS_Core_IntExc::IRQn

Values:

Reserved0_IRQn = 0
Reserved1_IRQn = 1
Reserved2_IRQn = 2
SysTimerSW_IRQn = 3
Reserved3_IRQn = 4
Reserved4_IRQn = 5
Reserved5_IRQn = 6
SysTimer_IRQn = 7
Reserved6_IRQn = 8
Reserved7_IRQn = 9
Reserved8_IRQn = 10
Reserved9_IRQn = 11
Reserved10_IRQn = 12
Reserved11_IRQn = 13
Reserved12_IRQn = 14
Reserved13_IRQn = 15
Reserved14_IRQn = 16
Reserved15_IRQn = 17
Reserved16_IRQn = 18
FirstDeviceSpecificInterrupt_IRQn = 19
SOC_INT_MAX
__STATIC_FORCEINLINE void __ECLIC_SetCfgNlbits(uint32_t nlbits)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetCfgNlbits(void)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoVer(void)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoCtlbits(void)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoNum(void)
__STATIC_FORCEINLINE void __ECLIC_SetMth(uint8_t mth)
__STATIC_FORCEINLINE uint8_t __ECLIC_GetMth(void)
__STATIC_FORCEINLINE void __ECLIC_EnableIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetEnableIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_DisableIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ(IRQn_Type IRQn, uint32_t trig)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetTrigIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv)
__STATIC_FORCEINLINE uint32_t __ECLIC_GetShvIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl)
__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs)
__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ(IRQn_Type IRQn, uint8_t pri)
__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __ECLIC_SetVector(IRQn_Type IRQn, rv_csr_t vector)
__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector(IRQn_Type IRQn)
__STATIC_FORCEINLINE void __set_exc_entry(rv_csr_t addr)
__STATIC_FORCEINLINE rv_csr_t __get_exc_entry(void)
__STATIC_FORCEINLINE void __set_nonvec_entry(rv_csr_t addr)
__STATIC_FORCEINLINE rv_csr_t __get_nonvec_entry(void)
__STATIC_FORCEINLINE rv_csr_t __get_nmi_entry(void)
ECLIC_SetCfgNlbits __ECLIC_SetCfgNlbits
ECLIC_GetCfgNlbits __ECLIC_GetCfgNlbits
ECLIC_GetInfoVer __ECLIC_GetInfoVer
ECLIC_GetInfoCtlbits __ECLIC_GetInfoCtlbits
ECLIC_GetInfoNum __ECLIC_GetInfoNum
ECLIC_SetMth __ECLIC_SetMth
ECLIC_GetMth __ECLIC_GetMth
ECLIC_EnableIRQ __ECLIC_EnableIRQ
ECLIC_GetEnableIRQ __ECLIC_GetEnableIRQ
ECLIC_DisableIRQ __ECLIC_DisableIRQ
ECLIC_SetPendingIRQ __ECLIC_SetPendingIRQ
ECLIC_GetPendingIRQ __ECLIC_GetPendingIRQ
ECLIC_ClearPendingIRQ __ECLIC_ClearPendingIRQ
ECLIC_SetTrigIRQ __ECLIC_SetTrigIRQ
ECLIC_GetTrigIRQ __ECLIC_GetTrigIRQ
ECLIC_SetShvIRQ __ECLIC_SetShvIRQ
ECLIC_GetShvIRQ __ECLIC_GetShvIRQ
ECLIC_SetCtrlIRQ __ECLIC_SetCtrlIRQ
ECLIC_GetCtrlIRQ __ECLIC_GetCtrlIRQ
ECLIC_SetLevelIRQ __ECLIC_SetLevelIRQ
ECLIC_GetLevelIRQ __ECLIC_GetLevelIRQ
ECLIC_SetPriorityIRQ __ECLIC_SetPriorityIRQ
ECLIC_GetPriorityIRQ __ECLIC_GetPriorityIRQ
ECLIC_SetVector __ECLIC_SetVector
ECLIC_GetVector __ECLIC_GetVector
SAVE_IRQ_CSR_CONTEXT()
RESTORE_IRQ_CSR_CONTEXT()
group NMSIS_Core_IntExc

Functions that manage interrupts and exceptions via the ECLIC.

Defines

ECLIC_SetCfgNlbits __ECLIC_SetCfgNlbits
ECLIC_GetCfgNlbits __ECLIC_GetCfgNlbits
ECLIC_GetInfoVer __ECLIC_GetInfoVer
ECLIC_GetInfoCtlbits __ECLIC_GetInfoCtlbits
ECLIC_GetInfoNum __ECLIC_GetInfoNum
ECLIC_SetMth __ECLIC_SetMth
ECLIC_GetMth __ECLIC_GetMth
ECLIC_EnableIRQ __ECLIC_EnableIRQ
ECLIC_GetEnableIRQ __ECLIC_GetEnableIRQ
ECLIC_DisableIRQ __ECLIC_DisableIRQ
ECLIC_SetPendingIRQ __ECLIC_SetPendingIRQ
ECLIC_GetPendingIRQ __ECLIC_GetPendingIRQ
ECLIC_ClearPendingIRQ __ECLIC_ClearPendingIRQ
ECLIC_SetTrigIRQ __ECLIC_SetTrigIRQ
ECLIC_GetTrigIRQ __ECLIC_GetTrigIRQ
ECLIC_SetShvIRQ __ECLIC_SetShvIRQ
ECLIC_GetShvIRQ __ECLIC_GetShvIRQ
ECLIC_SetCtrlIRQ __ECLIC_SetCtrlIRQ
ECLIC_GetCtrlIRQ __ECLIC_GetCtrlIRQ
ECLIC_SetLevelIRQ __ECLIC_SetLevelIRQ
ECLIC_GetLevelIRQ __ECLIC_GetLevelIRQ
ECLIC_SetPriorityIRQ __ECLIC_SetPriorityIRQ
ECLIC_GetPriorityIRQ __ECLIC_GetPriorityIRQ
ECLIC_SetVector __ECLIC_SetVector
ECLIC_GetVector __ECLIC_GetVector
SAVE_IRQ_CSR_CONTEXT()

Save necessary CSRs into variables for vector interrupt nesting.

This macro is used to declare variables which are used for saving CSRs(MCAUSE, MEPC, MSUB), and it will read these CSR content into these variables, it need to be used in a vector-interrupt if nesting is required.

Remark

  • Interrupt will be enabled after this macro is called

  • It need to be used together with RESTORE_IRQ_CSR_CONTEXT

  • Don’t use variable names __mcause, __mpec, __msubm in your ISR code

  • If you want to enable interrupt nesting feature for vector interrupt, you can do it like this:

    // __INTERRUPT attribute will generates function entry and exit sequences suitable
    // for use in an interrupt handler when this attribute is present
    __INTERRUPT void eclic_mtip_handler(void)
    {
        // Must call this to save CSRs
        SAVE_IRQ_CSR_CONTEXT();
        // !!!Interrupt is enabled here!!!
        // !!!Higher priority interrupt could nest it!!!
    
        // put you own interrupt handling code here
    
        // Must call this to restore CSRs
        RESTORE_IRQ_CSR_CONTEXT();
    }
    

RESTORE_IRQ_CSR_CONTEXT()

Restore necessary CSRs from variables for vector interrupt nesting.

This macro is used restore CSRs(MCAUSE, MEPC, MSUB) from pre-defined variables in SAVE_IRQ_CSR_CONTEXT macro.

Remark

  • Interrupt will be disabled after this macro is called

  • It need to be used together with SAVE_IRQ_CSR_CONTEXT

Enums

enum IRQn

Definition of IRQn numbers.

The core interrupt enumeration names for IRQn values are defined in the file <Device>.h.

  • Interrupt ID(IRQn) from 0 to 18 are reserved for core internal interrupts.

  • Interrupt ID(IRQn) start from 19 represent device-specific external interrupts.

  • The first device-specific interrupt has the IRQn value 19.

The table below describes the core interrupt names and their availability in various Nuclei Cores.

Values:

Reserved0_IRQn = 0

Internal reserved.

Reserved1_IRQn = 1

Internal reserved.

Reserved2_IRQn = 2

Internal reserved.

SysTimerSW_IRQn = 3

System Timer SW interrupt.

Reserved3_IRQn = 4

Internal reserved.

Reserved4_IRQn = 5

Internal reserved.

Reserved5_IRQn = 6

Internal reserved.

SysTimer_IRQn = 7

System Timer Interrupt.

Reserved6_IRQn = 8

Internal reserved.

Reserved7_IRQn = 9

Internal reserved.

Reserved8_IRQn = 10

Internal reserved.

Reserved9_IRQn = 11

Internal reserved.

Reserved10_IRQn = 12

Internal reserved.

Reserved11_IRQn = 13

Internal reserved.

Reserved12_IRQn = 14

Internal reserved.

Reserved13_IRQn = 15

Internal reserved.

Reserved14_IRQn = 16

Internal reserved.

Reserved15_IRQn = 17

Internal reserved.

Reserved16_IRQn = 18

Internal reserved.

FirstDeviceSpecificInterrupt_IRQn = 19

First Device Specific Interrupt.

SOC_INT_MAX

Number of total interrupts.

Functions

__STATIC_FORCEINLINE void __ECLIC_SetCfgNlbits(uint32_t nlbits)

Set nlbits value.

This function set the nlbits value of CLICCFG register.

Remark

  • nlbits is used to set the width of level in the CLICINTCTL[i].

See

  • ECLIC_GetCfgNlbits

Parameters
  • [in] nlbits: nlbits value

__STATIC_FORCEINLINE uint32_t __ECLIC_GetCfgNlbits(void)

Get nlbits value.

This function get the nlbits value of CLICCFG register.

Return

nlbits value of CLICCFG register

Remark

  • nlbits is used to set the width of level in the CLICINTCTL[i].

See

  • ECLIC_SetCfgNlbits

__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoVer(void)

Get the ECLIC version number.

This function gets the hardware version information from CLICINFO register.

Return

hardware version number in CLICINFO register.

Remark

  • This function gets harware version information from CLICINFO register.

  • Bit 20:17 for architecture version, bit 16:13 for implementation version.

See

  • ECLIC_GetInfoNum

__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoCtlbits(void)

Get CLICINTCTLBITS.

This function gets CLICINTCTLBITS from CLICINFO register.

Return

CLICINTCTLBITS from CLICINFO register.

Remark

  • In the CLICINTCTL[i] registers, with 2 <= CLICINTCTLBITS <= 8.

  • The implemented bits are kept left-justified in the most-significant bits of each 8-bit CLICINTCTL[I] register, with the lower unimplemented bits treated as hardwired to 1.

See

  • ECLIC_GetInfoNum

__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoNum(void)

Get number of maximum interrupt inputs supported.

This function gets number of maximum interrupt inputs supported from CLICINFO register.

Return

number of maximum interrupt inputs supported from CLICINFO register.

Remark

  • This function gets number of maximum interrupt inputs supported from CLICINFO register.

  • The num_interrupt field specifies the actual number of maximum interrupt inputs supported in this implementation.

See

  • ECLIC_GetInfoCtlbits

__STATIC_FORCEINLINE void __ECLIC_SetMth(uint8_t mth)

Set Machine Mode Interrupt Level Threshold.

This function sets machine mode interrupt level threshold.

See

  • ECLIC_GetMth

Parameters
  • [in] mth: Interrupt Level Threshold.

__STATIC_FORCEINLINE uint8_t __ECLIC_GetMth(void)

Get Machine Mode Interrupt Level Threshold.

This function gets machine mode interrupt level threshold.

Return

Interrupt Level Threshold.

See

  • ECLIC_SetMth

__STATIC_FORCEINLINE void __ECLIC_EnableIRQ(IRQn_Type IRQn)

Enable a specific interrupt.

This function enables the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

See

  • ECLIC_DisableIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE uint32_t __ECLIC_GetEnableIRQ(IRQn_Type IRQn)

Get a specific interrupt enable status.

This function returns the interrupt enable status for the specific interrupt IRQn.

Return

  • 0 Interrupt is not enabled

  • 1 Interrupt is pending

Remark

  • IRQn must not be negative.

See

  • ECLIC_EnableIRQ

  • ECLIC_DisableIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_DisableIRQ(IRQn_Type IRQn)

Disable a specific interrupt.

This function disables the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

See

  • ECLIC_EnableIRQ

Parameters
  • [in] IRQn: Number of the external interrupt to disable

__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ(IRQn_Type IRQn)

Get the pending specific interrupt.

This function returns the pending status of the specific interrupt IRQn.

Return

  • 0 Interrupt is not pending

  • 1 Interrupt is pending

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetPendingIRQ

  • ECLIC_ClearPendingIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ(IRQn_Type IRQn)

Set a specific interrupt to pending.

This function sets the pending bit for the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

See

  • ECLIC_GetPendingIRQ

  • ECLIC_ClearPendingIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ(IRQn_Type IRQn)

Clear a specific interrupt from pending.

This function removes the pending state of the specific interrupt IRQn. IRQn cannot be a negative number.

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetPendingIRQ

  • ECLIC_GetPendingIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ(IRQn_Type IRQn, uint32_t trig)

Set trigger mode and polarity for a specific interrupt.

This function set trigger mode and polarity of the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

See

  • ECLIC_GetTrigIRQ

Parameters

__STATIC_FORCEINLINE uint32_t __ECLIC_GetTrigIRQ(IRQn_Type IRQn)

Get trigger mode and polarity for a specific interrupt.

This function get trigger mode and polarity of the specific interrupt IRQn.

Return

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetTrigIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv)

Set interrupt working mode for a specific interrupt.

This function set selective hardware vector or non-vector working mode of the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

See

  • ECLIC_GetShvIRQ

Parameters

__STATIC_FORCEINLINE uint32_t __ECLIC_GetShvIRQ(IRQn_Type IRQn)

Get interrupt working mode for a specific interrupt.

This function get selective hardware vector or non-vector working mode of the specific interrupt IRQn.

Return

shv

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetShvIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl)

Modify ECLIC Interrupt Input Control Register for a specific interrupt.

This function modify ECLIC Interrupt Input Control(CLICINTCTL[i]) register of the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

See

  • ECLIC_GetCtrlIRQ

Parameters
  • [in] IRQn: Interrupt number

  • [in] intctrl: Set value for CLICINTCTL[i] register

__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ(IRQn_Type IRQn)

Get ECLIC Interrupt Input Control Register value for a specific interrupt.

This function modify ECLIC Interrupt Input Control register of the specific interrupt IRQn.

Return

value of ECLIC Interrupt Input Control register

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetCtrlIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs)

Set ECLIC Interrupt level of a specific interrupt.

This function set interrupt level of the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

  • If lvl_abs to be set is larger than the max level allowed, it will be force to be max level.

  • When you set level value you need use clciinfo.nlbits to get the width of level. Then we could know the maximum of level. CLICINTCTLBITS is how many total bits are present in the CLICINTCTL register.

See

  • ECLIC_GetLevelIRQ

Parameters
  • [in] IRQn: Interrupt number

  • [in] lvl_abs: Interrupt level

__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ(IRQn_Type IRQn)

Get ECLIC Interrupt level of a specific interrupt.

This function get interrupt level of the specific interrupt IRQn.

Return

Interrupt level

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetLevelIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ(IRQn_Type IRQn, uint8_t pri)

Get ECLIC Interrupt priority of a specific interrupt.

This function get interrupt priority of the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

  • If pri to be set is larger than the max priority allowed, it will be force to be max priority.

  • Priority width is CLICINTCTLBITS minus clciinfo.nlbits if clciinfo.nlbits is less than CLICINTCTLBITS. Otherwise priority width is 0.

See

  • ECLIC_GetPriorityIRQ

Parameters
  • [in] IRQn: Interrupt number

  • [in] pri: Interrupt priority

__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ(IRQn_Type IRQn)

Get ECLIC Interrupt priority of a specific interrupt.

This function get interrupt priority of the specific interrupt IRQn.

Return

Interrupt priority

Remark

  • IRQn must not be negative.

See

  • ECLIC_SetPriorityIRQ

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __ECLIC_SetVector(IRQn_Type IRQn, rv_csr_t vector)

Set Interrupt Vector of a specific interrupt.

This function set interrupt handler address of the specific interrupt IRQn.

Remark

  • IRQn must not be negative.

  • You can set the CSR_CSR_MTVT to set interrupt vector table entry address.

  • If your vector table is placed in readonly section, the vector for IRQn will not be modified. For this case, you need to use the correct irq handler name defined in your vector table as your irq handler function name.

  • This function will only work correctly when the vector table is placed in an read-write enabled section.

See

  • ECLIC_GetVector

Parameters
  • [in] IRQn: Interrupt number

  • [in] vector: Interrupt handler address

__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector(IRQn_Type IRQn)

Get Interrupt Vector of a specific interrupt.

This function get interrupt handler address of the specific interrupt IRQn.

Return

Interrupt handler address

Remark

  • IRQn must not be negative.

  • You can read CSR_CSR_MTVT to get interrupt vector table entry address.

See

  • ECLIC_SetVector

Parameters
  • [in] IRQn: Interrupt number

__STATIC_FORCEINLINE void __set_exc_entry(rv_csr_t addr)

Set Exception entry address.

This function set exception handler address to ‘CSR_MTVEC’.

Remark

  • This function use to set exception handler address to ‘CSR_MTVEC’. Address is 4 bytes align.

See

  • __get_exc_entry

Parameters
  • [in] addr: Exception handler address

__STATIC_FORCEINLINE rv_csr_t __get_exc_entry(void)

Get Exception entry address.

This function get exception handler address from ‘CSR_MTVEC’.

Return

Exception handler address

Remark

  • This function use to get exception handler address from ‘CSR_MTVEC’. Address is 4 bytes align

See

  • __set_exc_entry

__STATIC_FORCEINLINE void __set_nonvec_entry(rv_csr_t addr)

Set Non-vector interrupt entry address.

This function set Non-vector interrupt address.

Remark

  • This function use to set non-vector interrupt entry address to ‘CSR_MTVT2’ if

  • CSR_MTVT2 bit0 is 1. If ‘CSR_MTVT2’ bit0 is 0 then set address to ‘CSR_MTVEC’

See

  • __get_nonvec_entry

Parameters
  • [in] addr: Non-vector interrupt entry address

__STATIC_FORCEINLINE rv_csr_t __get_nonvec_entry(void)

Get Non-vector interrupt entry address.

This function get Non-vector interrupt address.

Return

Non-vector interrupt handler address

Remark

  • This function use to get non-vector interrupt entry address from ‘CSR_MTVT2’ if

  • CSR_MTVT2 bit0 is 1. If ‘CSR_MTVT2’ bit0 is 0 then get address from ‘CSR_MTVEC’.

See

  • __set_nonvec_entry

__STATIC_FORCEINLINE rv_csr_t __get_nmi_entry(void)

Get NMI interrupt entry from ‘CSR_MNVEC’.

This function get NMI interrupt address from ‘CSR_MNVEC’.

Return

NMI interrupt handler address

Remark

  • This function use to get NMI interrupt handler address from ‘CSR_MNVEC’. If CSR_MMISC_CTL[9] = 1 ‘CSR_MNVEC’

  • will be equal as mtvec. If CSR_MMISC_CTL[9] = 0 ‘CSR_MNVEC’ will be equal as reset vector.

  • NMI entry is defined via CSR_MMISC_CTL, writing to CSR_MNVEC will be ignored.