Wiznet makers

ronpang

Published May 27, 2025 © Apache License 2.0 (Apache-2.0)

130 UCC

43 WCC

32 VAR

0 Contests

1 Followers

0 Following

Chapter 10: Overview of W55MH32 Interrupt Applications

Chapter 10: Overview of W55MH32 Interrupt Applications

COMPONENTS
PROJECT DESCRIPTION

Chapter 10: Overview of W55MH32 Interrupt Applications

The reference materials for this chapter are "W55MH32 Reference Manual" and "Cortex-M3 Core Programming Manual" - Chapter 4.3: NVIC and Chapter 4.4: SCB - Section 4.4.5: AIRCR.

The interrupts of W55MH32 are very powerful. Each peripheral can generate an interrupt. Therefore, it is not appropriate to discuss where the interrupts should be explained. Here, we have specially set aside a chapter for a comprehensive summary introduction. Thus, when other chapters involve the knowledge of interrupts, we won't need to spend a lot of space explaining it in detail. We can just give a suggestive overview.

1 Exception type

The W55MH32 incorporates an exception response system at the kernel level, supporting numerous system exceptions and external interrupts. There are 8 system exceptions (if Reset and HardFault are included, it becomes 10), and 60 external interrupts. Except for the priorities of a few exceptions being fixed, the priorities of other exceptions are programmable. The specific system exceptions and external interrupts can be found in the standard library file w55mh32.h, which is the header file. The IRQn_Type structure contains all the exception declarations for the W55MH32 series.

W55MH32 System Error List

Serial Number

Priority

Priority type

Name

Explanation

Address

 

-

-

-

Keep (the actual stored value is the MSP address)

0X0000 0000

-3

-

Fixed

Reset

Reset

0X0000 0004

-2

-

Fixed

NMI

Uninterruptible interruption. The RCC clock security system (CSS) is connected to the NMI vector.

0X0000 0008

-1

-

Fixed

HardFault

All types of errors

0X0000 000C

0

-

Programmable

MemManage

Memory management

0X0000 0010

1

-

Programmable

BusFault

Prefetch failed, memory access failed.

0X0000 0014

2

-

Programmable

UsageFault

Undefined instructions or illegal states

0X0000 0018

 

-

-

-

Maintain

0X0000 001C-0X0000 002B

3

-

Programmable

SVCall

The system services called through the SWI instruction

0X0000 002C

4

-

Programmable

Debug Monitor

Debugging monitor

0X0000 0030

 

-

-

-

Maintain

0X0000 0034

5

-

Programmable

PendSV

System services that can be suspended

0X0000 0038

6

-

Programmable

SysTick

System Tick Timer

0X0000 003C

 

W55MH32 External Interrupt List

Serial Number

Priority

 

Priority type

 

Name

Explanation

Address

 

0

7

Programmable

 

WWDG

Window watchdog interrupt

0X0000 0040

1

8

Programmable

 

PVD

Power voltage detection (PVD) interrupt connected to EXTI

0X0000 0044

2

9

Programmable

 

TAMPER

Intrusion Detection Interruption

0X0000 0048

57

64

Programmable

 

DMA2 Channel 2

DMA2 Channel 2 Interrupt

0X0000 0124

58

65

Programmable

 

DMA2 Channel 3

DMA2 channel 3z interrupt

0X0000 0128

59

66

Programmable

 

DMA2 Channel 4_5

DMA2 channel 4 and channel 5 interrupts

0X0000 012C

 

2 Introduction to NVIC

Before discussing how to configure interrupt priorities, we need to first understand the NVIC. The NVIC is a nested vector interrupt controller that controls all the interrupt-related functions of the entire chip. It is closely coupled with the kernel and is a peripheral within the kernel. However, different chip manufacturers will trim the NVIC in the Cortex-M3 kernel when designing the chips, removing the unnecessary parts. Therefore, the NVIC of the W55MH32 is a subset of the NVIC of the Cortex-M3.

2.1 Introduction to NVIC Registers

In the firmware library, the structure definition of NVIC is quite forward-looking. It reserves many bits for each register, presumably to facilitate future functionality expansion. However, the W55MH32 cannot utilize so many bits; it only uses a portion of them. The specific amount used can be referred to in the "Cortex-M3 Core Programming Manual" - 4.3.11: NVIC Register Mapping.

Code listing: Definition of NVIC structure for interrupt - 1, from the firmware library header file: core_cm3.h

typedef struct {

   __IO uint32_t ISER[8];     
   uint32_t RESERVED0[24];
   __IO uint32_t ICER[8];     
   uint32_t RSERVED1[24];
   __IO uint32_t ISPR[8];       
   uint32_t RESERVED2[24];
   __IO uint32_t ICPR[8];       
   uint32_t RESERVED3[24];
   __IO uint32_t IABR[8];     
   uint32_t RESERVED4[56];
   __IO uint8_t  IP[240];   
   uint32_t RESERVED5[644];
   __O  uint32_t STIR;         
} NVIC_Type;

When configuring interrupts, we usually only use the three registers: ISER, ICER and IP. ISER is used to enable interrupts, ICER is used to disable interrupts, and IP is used to set the interrupt priority.

2.2 NVIC Interrupt Configuration Firmware Library

At the end of the firmware library file core_cm3.h, some functions of the NVIC are also provided. These functions follow the CMSIS rules and can be used by any Cortex-M3 processor. The details are as follows:

NVIC library functions

Description

void NVIC_EnableIRQ(IRQn_Type IRQn)

Enable interrupt

void NVIC_DisableIRQ(IRQn_Type IRQn)

Disability interruption

void NVIC_SetPendingIRQ(IRQn_Type IRQn)

Set the interrupt suspension position

void NVIC_ClearPendingIRQ(IRQn_Type IRQn)

Clear the interrupt suspend state

uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)

Obtain the suspended interrupt number

void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

Set interrupt priority

uint32_t NVIC_GetPriority(IRQn_Type IRQn)

Obtain interrupt priority

void NVIC_SystemReset(void)

System reset

These library functions are rarely used in our programming, and in some cases, we don't even use them at all. When configuring interrupts, we have a more concise method. Please refer to the section on interrupt programming.

 

3 Definition of Priority

3.1 Definition of Priority

In the NVIC, there is a dedicated register: the interrupt priority register NVIC_IPRx, which is used to configure the priority of external interrupts. The IPR width is 8 bits. In principle, each external interrupt can have a priority ranging from 0 to 255. The smaller the value, the higher the priority. However, most CM3 chips have a simplified design, resulting in a reduction in the actual number of supported priorities. In the W55MH32, only the high 4 bits are used, as shown below:

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

Used to express priority

Not used. Reading back is 0.

The 4 bits used to express the priority are divided into preemption priority and sub-priority. If more than one interrupt responds at the same time, the one with higher preemption priority will preempt the one with lower preemption priority, and if the preemption priority is the same, the sub-priority will be compared. If the preemption priority and sub-priority are the same, then compare their hardware interrupt numbers, the smaller the number, the higher the priority.

3.2 Priority Grouping

The grouping of priorities is determined by the PRIGROUP[10:8] bits of the Application Interrupt and Reset Control Register AIRCR of the kernel peripheral SCB, and the W55MH32 is divided into five groups as follows: main priority = preemption priority.

PRIGROUP[2:0]

Interrupt priority value PRI_N [7:4] (binary point)

Primary priority level

Subordinate priority bit

Primary priority

Subordinate priority

0b 011

0b xxxx

[7:4]

None

16

None

0b 100

0b xxx.y

[7:5]

[4]

8

2

0b 101

0b xx.yy

[7:6]

[5:4]

4

4

0b 110

0b x.yyy

[7]

[6:4]

2

9

0b 111

0b .yyyy

None

[7:4]

None

16

The priority grouping can be implemented by calling the library function NVIC_PriorityGroupConfig(). The library functions related to NVIC interrupts are all in the library files misc.c and misc.h.

 Code listing: Interrupt - 2 Interrupt Priority Grouping Library Function NVIC_PriorityGroupConfig()

/**

/**
* Configuring interrupt priority grouping: preemption priority and sub-priority
* The formal parameters are as follows:
* @arg NVIC_PriorityGroup_0: 0bit for Take priority
*                            4 bits for Subordinate priority
* @arg NVIC_PriorityGroup_1: 1 bit for Take priority
*                            3 bits for Subordinate priority
* @arg NVIC_PriorityGroup_2: 2 bit for Take priority
*                            2 bits for Subordinate priority
* @arg NVIC_PriorityGroup_3: 3 bit for Take priority
*                            1 bits for Subordinate priority
* @arg NVIC_PriorityGroup_4: 4 bit for Take priority
*                            0 bits for Subordinate priority
* @Note: If the priority grouping is set to 0, then the preemption priority does not exist and the priority is entirely controlled by the sub-priority.*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
   
   SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

Priority grouping

Primary priority

Subordinate priority

Description

NVIC_PriorityGroup_0

0

0-15

Master - 0 bit, Slave - 4 bit

NVIC_PriorityGroup_1

0-1

0-7

Master - 1 bit, Slave - 3 bits

NVIC_PriorityGroup_2

0-3

0-3

Master - 2 bits, Slave - 2 bits

NVIC_PriorityGroup_3

0-7

0-1

Master - 3 bits, Slave - 1 bit

NVIC_PriorityGroup_4

0-15

0

Master - 4 bits, Slave - 0 bits

 

4 Interrupt programming

When configuring each interrupt, there are generally three programming points:

1. Enable a certain interrupt of the peripheral. This is specifically controlled by the relevant interrupt enable bit of each peripheral. For example, the serial port has a transmission completion interrupt and a reception completion interrupt. Both of these interrupts are controlled by the relevant interrupt enable bits of the serial port control register.

2. Initialize the NVIC_InitTypeDef structure, configure the interrupt priority group, set the preemption priority and sub-priority, and enable the interrupt request. The NVIC_InitTypeDef structure is defined in the header file misc.h of the firmware library.

              Code Listing: Interrupt - 3 NVIC Initialization Structure

typedef struct {

    uint8_t NVIC_IRQChannel;                   
    uint8_t NVIC_IRQChannelPreemptionPriority; 
    uint8_t NVIC_IRQChannelSubPriority;       
    FunctionalState NVIC_IRQChannelCmd;       
} NVIC_InitTypeDef;

Let's explain each member of the NVIC initialization structure one by one:

(1). NVIC_IROChannel: This is used to set the interrupt source. Different interrupt sources are different and cannot be wrongly set. Even if it is wrongly set, the program will not report an error, but will only result in not responding to the interrupt. The specific configuration of the members can be referred to the IRQn_Type structure defined in the w55mh32x.h header file. This structure contains all the interrupt sources.

Code Listing: Interrupt - 4 IRQn_Type Interrupt Source Structure

typedef enum IRQn {
 
   NonMaskableInt_IRQn      = -14,
   MemoryManagement_IRQn    = -12,
   BusFault_IRQn            = -11,
   UsageFault_IRQn          = -10,
   SVCall_IRQn              = -5,
   DebugMonitor_IRQn        = -4,
   PendSV_IRQn              = -2,
   SysTick_IRQn             = -1,
   /W55MH32 External Interrupt Number
   WWDG_IRQn                = 0,
   PVD_IRQn                 = 1,
   TAMP_STAMP_IRQn          = 2,

   // Due to space limitations, the middle part of the code is omitted. For the detailed content, please refer to the library file W55MH32.h.

   DMA2_Channel2_IRQn       = 57,
   DMA2_Channel3_IRQn       = 58,
   DMA2_Channel4_5_IRQn     = 59
} IRQn_Type;

(2). NVIC_IRQChannelPreemptionPriority: Preemption priority. The specific value should be determined according to the priority group. Please refer to the table "Priority Group Truth Table" for details.

(3). NVIC_IRQChannelSubPriority: Sub-priority. The specific value should also be determined according to the priority group. Please refer to the table "Priority Group Truth Table" for details.

(4). NVIC_IRQChannelCmd: Interrupt enable (ENABLE) or disable (DISABLE). This operates on the registers NVIC_ISER and NVIC_ICER.

3. Writing Interrupt Service Functions

In the startup file startup_w55mh32_hd.s, we have pre-written an interrupt service function for each interrupt. However, these interrupt functions are all empty and are only used to initialize the interrupt vector table. The actual interrupt service functions need to be rewritten by us. To facilitate management, we have unified the writing of these interrupt service functions in the library file w55mh32_it.c.

The function name of the interrupt service function must be the same as that set in the startup file. If it is written incorrectly, the system will not be able to find the entry of the interrupt service function in the interrupt vector table, and will directly jump to the empty function pre-written in the startup file, resulting in an infinite loop and the inability to implement the interrupt.

5 Additional Explanation

The custom functions for the configuration of certain peripherals in subsequent other routines, such as NVIC_Configuration(), respectively execute the functions NVIC_PriorityGroupConfig() to configure the interrupt priority group, and NVIC_Init(&NVIC_InitStructure) to assign the interrupt vector and its priority that will be set. Note that NVIC_PriorityGroupConfig is only needed to be set once throughout the entire program.

After the interrupt priority group is set, the interrupt priorities of the corresponding interrupt vectors for various peripherals are interpreted based on the currently set group. For example, if configured as NVIC_PriorityGroup_0 or NVIC_PriorityGroup_4, it is invalid to fill the sub-priority or main priority of NVIC_InitStructure for multiple peripherals separately. Therefore, if there are many peripheral interrupts in the project, after determining which priority group to use, the priority of the interrupt vector for each peripheral should be configured separately.

In other routines, many write NVIC_PriorityGroupConfig in the interrupt configuration functions of each peripheral. Some may repeat the statement NVIC_PriorityGroupConfig() in multiple peripheral configuration functions. Here, it is reminded that when writing your own program, you only need to call it once. Repeated calling is equivalent to repeatedly assigning values to the interrupt-related registers multiple times and taking the last assignment. From the perspective of code layout logic, NVIC_PriorityGroupConfig is suitable to be placed in the main() function.

 

WIZnet is a fabless semiconductor company founded in 1998. Its products include the Internet processor iMCU™, which utilizes TOE (TCP/IP Offload Engine) technology and is based on a unique patented fully hardwired TCP/IP. The iMCU™ is designed for embedded Internet devices in various applications.

WIZnet has more than 70 distributors globally and has offices in Hong Kong, South Korea, and the United States, providing technical support and product marketing services.

The regions managed by the Hong Kong office include Australia, India, Turkey, and Asia (excluding South Korea and Japan). 

Documents
Comments Write