How to use Interrupts on STM8 with sduino

The official STMicroelectronics Arduino core
Post Reply
leif
Posts: 6
Joined: Wed Oct 14, 2020 1:55 am

How to use Interrupts on STM8 with sduino

Post by leif »

With some googling, sleuthing, and trial-and-error, I figured it out!

With STM8 sduino, attachInterrupt works but not like on a normal arduino.

Interrupts are separate per PORT, not per pin. Each port has multiple pins. PA1, PA2 are on port A, PC3-PC7 are on port C etc.
Use pinMode to designate the pin as input, so that digitalRead can keep working in case you need it.
After that, you must call GPIO_Init (an STM8-specific API function) to actually enable interrupts for a particular pin.
Then, you disable interrupts and call EXTI_SetExtIntSensitivity to set the interrupt trigger type on that entire port.
Finally attachInterrupt(). See my example below, this code works for me on my STM8S003F3.

Hope this saves someone some time. :)

Code: Select all

void ISR()
{
  //your code here
}

void setup()
{
  pinMode(2,INPUT);

  GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_IN_FL_IT);
  disableInterrupts();
  EXTI_SetExtIntSensitivity( EXTI_PORT_GPIOA, EXTI_SENSITIVITY_RISE_ONLY);  
  enableInterrupts();

  attachInterrupt(INT_PORTA & 0xFF,ISR,0);
}
///Leif
zoomx
Posts: 28
Joined: Fri Dec 20, 2019 10:12 am
Location: Near Mt.Etna

Re: How to use Interrupts on STM8 with sduino

Post by zoomx »

+1!!!
dannyf
Posts: 447
Joined: Sat Jul 04, 2020 7:46 pm

Re: How to use Interrupts on STM8 with sduino

Post by dannyf »

GPIO_Init (an STM8-specific API function) to actually enable interrupts for a particular pin.
or you can set the CR2 bits. CR1 bits enable pull-up.
hmeijdam
Posts: 7
Joined: Fri Nov 27, 2020 7:41 pm

Re: How to use Interrupts on STM8 with sduino

Post by hmeijdam »

Pin change interrupts support has been added to sduino.

A little workaround was still needed for me, as the latest sduino version 0.5.0 does not yet includes it.
I had to manually copy the files Winterrupts.h and Arduino.h from the sduino Github page and move that into my Arduino IDE overwriting the current ones in the sduino folder:
E:\Arduino\arduino-1.8.13\portable\packages\sduino\hardware\stm8\0.5.0\cores\sduino
(I have a portable Arduino IDE installation, as I use many different versions of the IDE in parralel, so this may be somewhere else for you)

I also had to change the examplesketch from the sduino project page a little.
the digitalPinToInterrupt (dummy) macro was not yet defined, so that is the line I added in my sketch as workaround-fix.

Code: Select all

// the pin where the input button is attached. Change, if needed
#define BUTTON  PA2
#define digitalPinToInterrupt(p)  ((p)==(p)) // workaround-fix, empty macro is missing in header files

// volatile is important, because this variable is modified in IRQ routine
volatile uint8_t flag = 0;

void on_button_pressed(void) {
  flag = 1;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 1);   // turn off the LED
  pinMode(BUTTON, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON), on_button_pressed, FALLING);
}

void loop() {
  if (flag) {
    digitalWrite(LED_BUILTIN, 0);
    delay(300);
    digitalWrite(LED_BUILTIN, 1);
    flag = 0;
  }
}
Now it compiled for me and when connecting a button between PA2 and GND the led on my stm8s103F3 board blinks for 300ms when the buton is pressed.
rtek1000
Posts: 4
Joined: Wed Dec 18, 2019 7:41 pm

Re: How to use Interrupts on STM8 with sduino

Post by rtek1000 »

Hello,

How can I declare interrupt for I2C?

I noticed that the I2C library doesn't make use of interrupts, and even the register pulling mode doesn't actually make use of control registers, I left this issue open: https://github.com/tenbaht/sduino/issues/143

I was able to make Write in I2C following the example code that ST provided, but the part of reading I2C I couldn't implement.

I'd like to try the I2C implementation with interrupt, but I'm finding examples only for the Cosmic compiler, which unfortunately is a barrier for enforcing licensing via email.

How can I make the attachInterrupt function direct I2C interrupts to the handler?

I tried to understand how to replicate the interrupt to PORTA of these files, but I still couldn't:
https://github.com/tenbaht/sduino/issues/92
https://github.com/tenbaht/sduino/blob/ ... /Arduino.h
https://github.com/tenbaht/sduino/blob/ ... terrupts.c

I also don't understand why there is a table, but for sduino it has a table with another order. Maybe the sduino table was made in implementation order instead of reference order:
ITC_Irq_TypeDef {
ITC_IRQ_TLI = (uint8_t)0,
ITC_IRQ_AWU = (uint8_t)1,
ITC_IRQ_CLK = (uint8_t)2,
ITC_IRQ_PORTA = (uint8_t)3,
ITC_IRQ_PORTB = (uint8_t)4,
ITC_IRQ_PORTC = (uint8_t)5,
ITC_IRQ_PORTD = (uint8_t)6,
ITC_IRQ_PORTE = (uint8_t)7,
ITC_IRQ_SPI = (uint8_t)10,
ITC_IRQ_TIM1_OVF = (uint8_t)11,
ITC_IRQ_TIM1_CAPCOM = (uint8_t)12,
ITC_IRQ_TIM2_OVF = (uint8_t)13,
ITC_IRQ_TIM2_CAPCOM = (uint8_t)14,
ITC_IRQ_TIM3_OVF = (uint8_t)15,
ITC_IRQ_TIM3_CAPCOM = (uint8_t)16,
ITC_IRQ_I2C = (uint8_t)19,
ITC_IRQ_TIM4_OVF = (uint8_t)23,
ITC_IRQ_EEPROM_EEC = (uint8_t)24
}
https://documentation.help/STM8S-A-Stan ... 6a0babfc20
/*
* The new interrupt numbers are a combination of the position in the
* internal jump table (value in LSB) and the real STM8S-Interrupt number (MSB)
*/
#define INT_PORTA ( 0| (uint16_t)(ITC_IRQ_PORTA << 8))
#define INT_PORTB ( 1| (uint16_t)(ITC_IRQ_PORTB << 8))
#define INT_PORTC ( 2| (uint16_t)(ITC_IRQ_PORTC << 8))
#define INT_PORTD ( 3| (uint16_t)(ITC_IRQ_PORTD << 8))
#define INT_PORTE ( 4| (uint16_t)(ITC_IRQ_PORTE << 8))
#define INT_TIM1_CAPCOM ( 5| (uint16_t)(ITC_IRQ_TIM1_CAPCOM << 8))
#define INT_TIM1_OVF ( 6| (uint16_t)(ITC_IRQ_TIM1_OVF << 8))
#define INT_TIM2_CAPCOM ( 7| (uint16_t)(ITC_IRQ_TIM2_CAPCOM << 8))
#define INT_TIM2_OVF ( 8| (uint16_t)(ITC_IRQ_TIM2_OVF << 8))
https://github.com/tenbaht/sduino/blob/ ... /Arduino.h
akki23
Posts: 1
Joined: Sat Aug 05, 2023 3:30 pm

Re: How to use Interrupts on STM8 with sduino

Post by akki23 »

Hi I am trying to execute same kind of code,
I am using arduino-1.8.19(Tried with arduino-1.8.13 as well) portable. I have copied Winterrupts.c & Arduino.h (from github sduino) and replaced with suggested path by you.
Code is compiling and uploading fine. But defined interrupt is not actually working. I have tried with other PINs also for interrupt but non of them are working.
There is one observation with this code is PA2 Pin is highly sensible to interrupt by default even with human touch finger touch is creating call of defined interrupt subroutine. Kindly suggest solution if any.
Here is the code I am using:
"
#define R1 PD1 //ROW1
#define R2 PC6 //ROW2
#define R3 PC5 //ROW3
#define R4 PC3 //ROW4
#define C1 PB4 //COL1
#define C2 PC7 //COL2
#define C3 PC4 //COL3
#define RED PD4 //ACTIVE HIGH
#define GREEN PA3 //ACTIVE HIGH

#define digitalPinToInterrupt(R1) ((R1)==(R1))

volatile uint8_t flag = 0;
int blink_delay = 800;

void button_pressed(void) {
flag = 1;
}

void setup() {
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(C1, OUTPUT);
pinMode(R1, INPUT_PULLUP);
digitalWrite(C1, 0);
digitalWrite(RED, 0);
digitalWrite(GREEN, 0);
attachInterrupt(digitalPinToInterrupt(R1), button_pressed, FALLING);
}

void loop(){
if (flag){
digitalWrite(GREEN, 1);
delay(blink_delay);
digitalWrite(GREEN, 0);
delay(blink_delay);
flag = 0;
}
else {
digitalWrite(RED, 1);
delay(blink_delay);
digitalWrite(RED, 0);
delay(blink_delay);
}
}
"


hmeijdam wrote: Thu Dec 03, 2020 7:22 pm Pin change interrupts support has been added to sduino.

A little workaround was still needed for me, as the latest sduino version 0.5.0 does not yet includes it.
I had to manually copy the files Winterrupts.h and Winterrupts.h from the sduino Github page and move that into my Arduino IDE overwriting the current ones in the sduino folder:
E:\Arduino\arduino-1.8.13\portable\packages\sduino\hardware\stm8\0.5.0\cores\sduino
(I have a portable Arduino IDE installation, as I use many different versions of the IDE in parralel, so this may be somewhere else for you)

I also had to change the examplesketch from the sduino project page a little.
the digitalPinToInterrupt (dummy) macro was not yet defined, so that is the line I added in my sketch as workaround-fix.

Code: Select all

// the pin where the input button is attached. Change, if needed
#define BUTTON  PA2
#define digitalPinToInterrupt(p)  ((p)==(p)) // workaround-fix, empty macro is missing in header files

// volatile is important, because this variable is modified in IRQ routine
volatile uint8_t flag = 0;

void on_button_pressed(void) {
  flag = 1;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 1);   // turn off the LED
  pinMode(BUTTON, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON), on_button_pressed, FALLING);
}

void loop() {
  if (flag) {
    digitalWrite(LED_BUILTIN, 0);
    delay(300);
    digitalWrite(LED_BUILTIN, 1);
    flag = 0;
  }
}
Now it compiled for me and when connecting a button between PA2 and GND the led on my stm8s103F3 board blinks for 300ms when the buton is pressed.
hmeijdam
Posts: 7
Joined: Fri Nov 27, 2020 7:41 pm

Re: How to use Interrupts on STM8 with sduino

Post by hmeijdam »

I removed the the digitalPinToInterrupt macro, that was causing trouble.
After reading this https://tenbaht.github.io/sduino/usage/interrupts/ documentation it seemed better to remove it.

So here is a revised example that should work on almost all pins (see code).

Code: Select all

// Update August 2023 by Hans Meijdam
// Removed the digitalPinToInterrupt macro, that caused problems. 
// The pin- and interrupt numbers seem to be similar, so can be used directly for setting pin and interrupt
// tested PA1-3, PB5, PC3-7 and PD1-6
// note PB4 seems to have no internal pullup, so would need an external pullup to work stable.
// *******************************************************************************************

#define BUTTON PD3    // the pin where the input button is attached. Change, if needed

// volatile is important, because this variable is modified in IRQ routine
volatile uint8_t flag = 0;

void on_button_pressed(void) {
  flag = 1;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 1);   // turn off the LED
  pinMode(BUTTON, INPUT_PULLUP);
  attachInterrupt((BUTTON), on_button_pressed, FALLING);
}

void loop() {
  if (flag) {
    digitalWrite(LED_BUILTIN, 0);
    delay(300);
    digitalWrite(LED_BUILTIN, 1);
    flag = 0;
  }
}
hmeijdam
Posts: 7
Joined: Fri Nov 27, 2020 7:41 pm

Re: How to use Interrupts on STM8 with sduino

Post by hmeijdam »

akki23 wrote: Sat Aug 05, 2023 3:46 pm But defined interrupt is not actually working. I have tried with other PINs also for interrupt but non of them are working.
Now your sketch should work:

Code: Select all

#define R1 PD1 //ROW1
#define R2 PC6 //ROW2
#define R3 PC5 //ROW3
#define R4 PC3 //ROW4
#define C1 PB4 //COL1
#define C2 PC7 //COL2
#define C3 PC4 //COL3
#define RED PD4 //ACTIVE HIGH
#define GREEN PA3 //ACTIVE HIGH

volatile uint8_t flag = 0;
int blink_delay = 800;

void button_pressed(void) {
  flag = 1;
}

void setup() {
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(C1, OUTPUT);
  pinMode(R1, INPUT_PULLUP);
  digitalWrite(C1, 0);
  digitalWrite(RED, 0);
  digitalWrite(GREEN, 0);
  attachInterrupt((R1), button_pressed, FALLING);
}

void loop() {
  if (flag) {
    digitalWrite(GREEN, 1);
    delay(blink_delay);
    digitalWrite(GREEN, 0);
    delay(blink_delay);
    flag = 0;
  }
  else {
    digitalWrite(RED, 1);
    delay(blink_delay);
    digitalWrite(RED, 0);
    delay(blink_delay);
  }
}

Post Reply

Return to “STM8 Core”