2020-08-02

2020-07-06 Longan Nano GD32VF103 PA8 and RTC Interrupts

>>>Longan Nano GD32VF103<<<

Longan Nano GD32VF103 Risc-V 108MHz 32b MCU toolchain, libraries and applications


Illustration 1: Longan Nano test bench


1Introduction

The blink example went up quite painlessly, and I was also able to compile and execute the Bad Apple example that takes a stream of bitmap images from the SD Card and shows them on the screen.

With the basics out of the way, I focused on the interrupts.


1.1Arduino Framework Compatibility

The product page claims compatibility with the Arduino Framework, so I wanted to try the Arduino like interrupt handling.

Early on it was obvious that the Arduino framework has not been completed as the time of writing, with basic HAL functions like the digitalRead() empty. There was no hope of getting Arduino style interrupts to work without doing the framework HAL myself, so I dropped the thing.


2Interrupts

The Risc-V ISA specifies the interrupt handling as part of the core. Details about the ECLIC can be found in this excellent post from Kevin Sangeelee.

The GD32VF103 support an interrupt vector table defined as weak symbols in Start.S in the GD32 framework, it supports tiered priority where high priority interrupts can interrupt low priority ones and has hardware acceleration for them inside the MCU, on top of the special instructions and registers inside the core, as per Risc-V ISA specifications.

The GD32VF103 provides special interrupts from all sort of sources, including a reset vector, an error vector and a watchdog vector, on top of interrupts from almost every peripheral.


2.1Difficulties

Getting the interrupts to work was not easy.

In theory, all I had to do was to define a function with the same name as the symbol in start.S, and the C++ linker should have automagically linked the definitions by overriding the default .weak symbols.

After lots of testing, stack overflow came through with the answer: I need to use the keyword extern “C” to tell the C++ compiler not to change the name of the function and allow the linker to do its job and link the address of the interrupt service routine to the interrupt vector table.


3Example: PA8 EXTI

The Boot button is also wired to the PA8 pin. The EXTI in combination with the ECLIC is used to sense an edge on PA8 and trigger an ISR.

#include <gd32vf103.h>
#define EVER (;;)
void init()
{
//Clock the GPIO banks
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
//Setup the R, G and B LEDs
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
//Setup the boot button
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13);
//Initialize the LEDs to: OFF
gpio_bit_set(GPIOC,GPIO_PIN_13);
gpio_bit_set(GPIOA,GPIO_PIN_1);
gpio_bit_set(GPIOA,GPIO_PIN_2);
//Clock the alternate functions
rcu_periph_clock_enable(RCU_AF);
//Initialize the ECLIC IRQ lines
eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);
eclic_irq_enable(EXTI5_9_IRQn, 1, 1);
//Initialize the EXTI. IRQ can be generated from GPIO edge detectors
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_8);
exti_init(EXTI_8, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
//Clear interrupt flag. Ensure no spurious execution at start
exti_interrupt_flag_clear(EXTI_8);
//Enable the interrupts. From now on interrupt handlers can be executed
eclic_global_interrupt_enable();
return;
}
extern "C"
void EXTI5_9_IRQHandler()
{
//If: interrupt from PA8 boot button
if (exti_interrupt_flag_get(EXTI_8) != RESET)
{
//Clear the interrupt from PA8 boot button
exti_interrupt_flag_clear(EXTI_8);
//Toggle the blue led
gpio_bit_write(GPIOA, GPIO_PIN_2, (bit_status)(1-gpio_input_bit_get(GPIOA, GPIO_PIN_2)));
}
//Default: interrupt from an unhandled GPIO
else
{
//Do nothing (should clear the interrupt flags)
}
}
void delay_us(unsigned int us)
{
uint64_t start_mtime, delta_mtime;
uint64_t tmp = get_timer_value();
do
{
start_mtime = get_timer_value();
}
while (start_mtime == tmp);
do
{
delta_mtime = get_timer_value() - start_mtime;
}
while(delta_mtime <(SystemCoreClock/4000000.0 *us ));
return;
}
int main()
{
init();
for EVER
{
//Toggle the RED LED
gpio_bit_write(GPIOC, GPIO_PIN_13, (bit_status)(1-gpio_input_bit_get(GPIOC, GPIO_PIN_13)));
//2Hz blink
delay_us(250000);
}
return 0;
}
view raw main.cpp hosted with ❤ by GitHub

Video1: PA8 interrupt demo in action

4Example: RTC Interrupt

The RTC timer is initialized to emit a “second” interrupt every 250ms. The interrupt toggles the RED LED.

/****************************************************************************
** OrangeBot Project
*****************************************************************************
** /
** /
** /
** ______ \
** \
** \
*****************************************************************************
** Longan Nano Example - Blink RTC IST
*****************************************************************************
** Author: Orso Eric
** Version:
****************************************************************************/
/****************************************************************************
** DESCRIPTION
*****************************************************************************
** Blink the LEDs using the interrupt service rutine generated by the RTC timer
****************************************************************************/
/****************************************************************************
** HYSTORY VERSION
*****************************************************************************
** 2020-07-05
** Interrupt Service Routine working!
** 2020-07-06
** Format source code
****************************************************************************/
/****************************************************************************
** KNOWN BUG
*****************************************************************************
**
****************************************************************************/
/****************************************************************************
** INCLUDE
****************************************************************************/
#include <gd32vf103.h>
//Onboard RBG LEDs of the Longan Nano
#include "longan_nano_led.hpp"
/****************************************************************************
** NAMESPACES
****************************************************************************/
//using namespace std;
/****************************************************************************
** DEFINES
****************************************************************************/
//forEVER
#define EVER (;;)
/****************************************************************************
** GLOBAL VARIABILE
****************************************************************************/
/****************************************************************************
** FUNCTION PROTOTYPES
****************************************************************************/
//Initialize the board
extern bool init( void );
//Busy delay using the SysTick timer
extern void delay_us(unsigned int us);
/****************************************************************************
** FUNCTION
****************************************************************************/
/***************************************************************************/
//! @brief maim
//! main | void
/***************************************************************************/
//! @param delay | unsigned int | how long to wait for in microseconds
//! @return void |
//! @details \n
//! Handles the ISR lines generated by the GPIO lines 5 to 9
/***************************************************************************/
int main( void )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
bool f_ret = false;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//Initialize the board and return success status
f_ret |= init();
//----------------------------------------------------------------
// MAIN LOOP
//----------------------------------------------------------------
for EVER
{
//Toggle the RED LED
//Longan_nano::Leds::toggle( Longan_nano::Led_color::RED );
//2Hz blink
//delay_us(250000);
}
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return 0;
} //End function: main
/***************************************************************************/
//! @brief utility
//! delay_us
/***************************************************************************/
//! @param delay | unsigned int | how long to wait for in microseconds
//! @return void |
//! @details \n
//! Use the SysTic timer counter to busy wait for the correct number of microseconds
/***************************************************************************/
void delay_us(unsigned int delay)
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
uint64_t start_mtime, delta_mtime;
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
// Wait for the first tick
// Wait for the correct number of ticks
uint64_t tmp = get_timer_value();
do
{
start_mtime = get_timer_value();
}
while (start_mtime == tmp);
do
{
delta_mtime = get_timer_value() - start_mtime;
}
while(delta_mtime <(SystemCoreClock/4000000.0 *delay ));
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return;
} //End function: main
view raw main.cpp hosted with ❤ by GitHub
/****************************************************************************
** init.cpp
*****************************************************************************
** Board initializations
** >GPIO
** >EXTI
** >ECLIC
****************************************************************************/
/****************************************************************************
** INCLUDE
****************************************************************************/
#include <gd32vf103.h>
//Onboard RBG LEDs of the Longan Nano
#include "longan_nano_led.hpp"
/****************************************************************************
** NAMESPACES
****************************************************************************/
//using namespace std;
/****************************************************************************
** GLOBAL VARIABILE
****************************************************************************/
/****************************************************************************
** FUNCTION PROTOTYPES
****************************************************************************/
//Initialize the board
extern bool init( void );
//Initialize RTC Timer to generate a system tick
extern bool init_rtc( void );
//Initialize the EXTI edge detection interrupt from the GPIO
extern bool init_exti(void);
//Initialize the ECLIC interrupt controller
extern bool init_eclic(void);
/****************************************************************************
** FUNCTION
****************************************************************************/
/***************************************************************************/
//! @brief init
//! init |
/***************************************************************************/
//! @return bool | false = OK | true = ERR
//! @details
//! initialize the longan nano pheriperals
/***************************************************************************/
bool init( void )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//Return
bool f_ret = false;
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
// GPIO
// ECLIC
// EXTI
//Initialize the Longan Nano builtin RBG LEDs
f_ret |= Longan_nano::Leds::init();
//Initialize LEDs to OFF
Longan_nano::Leds::set_color( Longan_nano::Led_color::BLACK );
//EXTI GPIO interrupt: PA8 R/F -> EXTI_5_9
f_ret |= init_exti();
//RTC system tick
f_ret |= init_rtc();
//Initialize ECLIC Interrupt controller. Interrupts can now be generated
f_ret |= init_eclic();
//if: initialization failed
if (f_ret == true)
{
}
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return f_ret;
} //end init: init |
/***************************************************************************/
//! @brief init
//! init_exti |
/***************************************************************************/
//! @return bool | false = OK | true = ERR
//! @details
//! initialize the EXTI edge detection interrupt from the GPIO
//! PA8 R/F -> EXTI_5_9
/***************************************************************************/
bool init_exti(void)
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Setup the boot button
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
//Clock the alternate functions
rcu_periph_clock_enable(RCU_AF);
//Initialize the EXTI. IRQ can be generated from GPIO edge detectors
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_8);
exti_init(EXTI_8, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
//Clear interrupt flag. Ensure no spurious execution at start
exti_interrupt_flag_clear(EXTI_8);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return false; //OK
} //end init: init_exti |
/***************************************************************************/
//! @brief init
//! init_rtc |
/***************************************************************************/
//! @return bool | false = OK | true = ERR
//! @details
//! initialize the RTC Real Time Counter
//! setup to emit a 4Hz SECOND interrupt
//!
//! RTC Interrupts:
//! RTC_INT_SECOND: Generated every time RTC_CNT changes (after the prescaler RTC_PSC)
//! RTC_INT_ALARM: Generated when RTC_CNT equals RTC_ALRM
//! RTC_INT_OV: Generated when the 32b RTC_CNT counter overflows to zero
/***************************************************************************/
bool init_rtc(void)
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Backup Clock
rcu_periph_clock_enable(RCU_BKPI);
//
rcu_periph_clock_enable(RCU_PMU);
//Enter configuration mode
pmu_backup_write_enable();
//
bkp_deinit();
//Enable LX crystal 32768 [Hz]
rcu_osci_on(RCU_LXTAL);
//Wait for crystal to stabilize
rcu_osci_stab_wait(RCU_LXTAL);
//Clock the RTC with the LX Crystal
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
rcu_periph_clock_enable(RCU_RTC);
//wait for RTC registers synchronization
rtc_register_sync_wait();
//wait until last write operation on RTC registers has finished
rtc_lwoff_wait();
//Set the RTC Prescaler
rtc_prescaler_set(8192);
//wait until last write operation on RTC registers has finished
rtc_lwoff_wait();
//Emit an interrupt each time RTC_CNT counts
rtc_interrupt_enable(RTC_INT_SECOND);
//wait until last write operation on RTC registers has finished
rtc_lwoff_wait();
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return false; //OK
} //end init: init_rtc |
/***************************************************************************/
//! @brief init
//! init_eclic |
/***************************************************************************/
//! @return bool | false = OK | true = ERR
//! @details
//! Initialize the ECLIC interrupt controller
/***************************************************************************/
bool init_eclic(void)
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Initialize the ECLIC IRQ lines
eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);
eclic_irq_enable(EXTI5_9_IRQn, 1, 1);
//Enable the RTC Interrupt
eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL1_PRIO3);
eclic_irq_enable(RTC_IRQn, 1, 0);
//Enable the interrupts. From now on interrupt handlers can be executed
eclic_global_interrupt_enable();
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return false; //OK
} //end init: init_eclic |
view raw init.cpp hosted with ❤ by GitHub
/****************************************************************************
** int.cpp
*****************************************************************************
** Interrupt Service Routines
** NOTE:
** extern "C" keyword tells the C++ compiler not to mangle the ISR nfunction name
** the Interrupt Vector Table is declared in Start.S and requires special names
** for the ISRs without mangling to link correctly
****************************************************************************/
/****************************************************************************
** Interrupt Vectors
*****************************************************************************
** EXTI5_9_IRQHandler GPIO edge detectors 5 to 9
** RTC_IRQHandler RTC Second
****************************************************************************/
/****************************************************************************
** INCLUDE
****************************************************************************/
#include <gd32vf103.h>
//Onboard RBG LEDs of the Longan Nano
#include "longan_nano_led.hpp"
/***************************************************************************/
//! @brief ISR
//! EXTI5:9 LINES
/***************************************************************************/
//! @return void |
//! @details \n
//! Handles the ISR lines generated by the GPIO lines 5 to 9
/***************************************************************************/
extern "C"
void EXTI5_9_IRQHandler()
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//If: interrupt from PA8 boot button
if (exti_interrupt_flag_get(EXTI_8) != RESET)
{
//Clear the interrupt from PA8 boot button
exti_interrupt_flag_clear(EXTI_8);
//Toggle the green led
Longan_nano::Leds::toggle( Longan_nano::Led_color::GREEN );
}
//Default: interrupt from an unhandled GPIO
else
{
//Do nothing (should clear the interrupt flags)
}
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
} //End ISR: EXTI5_9_IRQHandler
/***************************************************************************/
//! @brief ISR
//! RTC
/***************************************************************************/
//! @return void |
//! @details \n
//! Handles the ISR lines generated by the RTC
//! Includes three vectors:
//! RTC_INT_SECOND: Generated every time RTC_CNT changes (after the prescaler RTC_PSC)
//! RTC_INT_ALARM: Generated when RTC_CNT equals RTC_ALRM
//! RTC_INT_OV: Generated when the 32b RTC_CNT counter overflows to zero
/***************************************************************************/
extern "C"
void RTC_IRQHandler(void)
{
//SECOND interrupt, generated by a change in RTC:CNT
if (rtc_flag_get(RTC_FLAG_SECOND) != RESET)
{
//Clear flag
rtc_flag_clear(RTC_FLAG_SECOND);
Longan_nano::Leds::toggle( Longan_nano::Led_color::RED );
}
//ALARM interrupt, generated when RTC_CNT equals RTC_ALRM
if (rtc_flag_get(RTC_FLAG_ALARM) != RESET)
{
//Clear flag
rtc_flag_clear(RTC_FLAG_ALARM);
}
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
} //End ISR: RTC_IRQHandler
view raw int.cpp hosted with ❤ by GitHub
/**********************************************************************************
** ENVIROMENT VARIABILE
**********************************************************************************/
#ifndef LONGAN_NANO_LED_H_
#define LONGAN_NANO_LED_H_
/**********************************************************************************
** GLOBAL INCLUDES
**********************************************************************************/
#include <gd32vf103.h>
/**********************************************************************************
** DEFINES
**********************************************************************************/
/**********************************************************************************
** MACROS
**********************************************************************************/
/**********************************************************************************
** NAMESPACE
**********************************************************************************/
//! @namespace User My custom namespace
namespace Longan_nano
{
/**********************************************************************************
** TYPEDEFS
**********************************************************************************/
typedef enum _Led_color
{
BLACK,
RED,
GREEN,
BLUE,
WHITE
} Led_color;
typedef enum _Led_gpio
{
RED_GPIO = GPIOC,
GREEN_GPIO = GPIOA,
BLUE_GPIO = GPIOA,
} Led_gpio;
typedef enum _Led_pin
{
RED_PIN = GPIO_PIN_13,
GREEN_PIN = GPIO_PIN_1,
BLUE_PIN = GPIO_PIN_2,
} Led_pin;
/**********************************************************************************
** PROTOTYPE: STRUCTURES
**********************************************************************************/
/**********************************************************************************
** PROTOTYPE: GLOBAL VARIABILES
**********************************************************************************/
/**********************************************************************************
** PROTOTYPE: CLASS
**********************************************************************************/
/************************************************************************************/
//! @class Longan_nano_led
/************************************************************************************/
//! @author Orso Eric
//! @version 0.1 alpha
//! @date 2019/05
//! @brief Dummy Library
//! @details
//! Verbose description \n
//! xxx
//! @pre No prerequisites
//! @bug None
//! @warning No warnings
//! @copyright License ?
//! @todo todo list
/************************************************************************************/
class Leds
{
//Visible to all
public:
//--------------------------------------------------------------------------
// CONSTRUCTORS
//--------------------------------------------------------------------------
//! Default constructor
Leds( void );
//--------------------------------------------------------------------------
// DESTRUCTORS
//--------------------------------------------------------------------------
//!Default destructor
~Leds( void );
//--------------------------------------------------------------------------
// OPERATORS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// SETTERS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// GETTERS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// TESTERS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// PUBLIC METHODS
//--------------------------------------------------------------------------
/***************************************************************************/
//! @brief public static method
//! init |
/***************************************************************************/
//! @return bool | false = OK | true = ERR
//! @details
//! initialize the longan nano GPIO LEDs
/***************************************************************************/
static inline bool init( void )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Clock the GPIO banks
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
//Setup the R (PC13), G (PA1) and B (PA2) LEDs
gpio_init(Led_gpio::RED_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,Led_pin::RED_PIN);
gpio_init(Led_gpio::GREEN_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,Led_pin::GREEN_PIN);
gpio_init(Led_gpio::BLUE_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,Led_pin::BLUE_PIN);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return false; //OK
} //End public static method: init
/***************************************************************************/
//! @brief public static method
//! set_color | Led_color
/***************************************************************************/
//! @param Led_color | color of the LED
//! @return bool | false = OK | true = ERR
//! @details
//! initialize the longan nano GPIO LEDs
/***************************************************************************/
static inline bool set_color( Led_color color )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//LED are inverted. SET turn them OFF
bit_status led_r = FlagStatus::SET;
bit_status led_g = FlagStatus::SET;
bit_status led_b = FlagStatus::SET;
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Switch: Color
switch(color)
{
case (Led_color::BLACK):
{
break;
}
case (Led_color::WHITE):
{
led_r = FlagStatus::RESET;
led_g = FlagStatus::RESET;
led_b = FlagStatus::RESET;
break;
}
default:
{
return true; //FAIL
}
} //End Switch: Color
//Apply the color setting
gpio_bit_write( Led_gpio::RED_GPIO, Led_pin::RED_PIN, (bit_status)led_r );
gpio_bit_write( Led_gpio::GREEN_GPIO, Led_pin::GREEN_PIN, (bit_status)led_g );
gpio_bit_write( Led_gpio::BLUE_GPIO, Led_pin::BLUE_PIN, (bit_status)led_b );
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return false; //OK
} //End public static method: set_color
/***************************************************************************/
//! @brief public static method
//! toggle |
/***************************************************************************/
//! @return bool | false = OK | true = ERR
//! @details
//! initialize the longan nano GPIO LEDs
/***************************************************************************/
static inline bool toggle( Led_color color )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Switch: Color
switch(color)
{
case (Led_color::RED):
{
gpio_bit_write(Led_gpio::RED_GPIO, Led_pin::RED_PIN, (bit_status)(1-gpio_input_bit_get(Led_gpio::RED_GPIO, Led_pin::RED_PIN)));
break;
}
case (Led_color::GREEN):
{
gpio_bit_write(Led_gpio::GREEN_GPIO, Led_pin::GREEN_PIN, (bit_status)(1-gpio_input_bit_get(Led_gpio::GREEN_GPIO, Led_pin::GREEN_PIN)));
break;
}
case (Led_color::BLUE):
{
gpio_bit_write(Led_gpio::BLUE_GPIO, Led_pin::BLUE_PIN, (bit_status)(1-gpio_input_bit_get(Led_gpio::BLUE_GPIO, Led_pin::BLUE_PIN)));
break;
}
default:
{
return true; //FAIL
}
} //End Switch: Color
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return false; //OK
} //End public static method: toggle
//--------------------------------------------------------------------------
// PUBLIC STATIC METHODS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// PUBLIC VARS
//--------------------------------------------------------------------------
//Visible to derived classes
protected:
//--------------------------------------------------------------------------
// PROTECTED METHODS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// PROTECTED VARS
//--------------------------------------------------------------------------
//Visible only inside the class
private:
//--------------------------------------------------------------------------
// PRIVATE METHODS
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// PRIVATE VARS
//--------------------------------------------------------------------------
}; //End Class: Longan_nano_led
/**********************************************************************************
** NAMESPACE
**********************************************************************************/
} //End Namespace: Longan_nano
#else
#warning "Multiple inclusion of hader file"
#endif




5Conclusions

Interrupts are fundamental in an hard real time MCU application and the GD32VF103 is equipped with a refined system to handle interrupts.

This document shows how to generate interrupts from the EXTI and RTC. interrupts can be generated from all sort of sources, and there are even sources for reset, watchdog, errors, etc...




No comments: