How do I get my AWU ISR into the interrupt vector table? [SOLVED -- RTFM!]

Arduino on the STM8 (8 bit processor)
Jimmus
Posts: 15
Joined: Tue Nov 28, 2017 4:08 am

How do I get my AWU ISR into the interrupt vector table? [SOLVED -- RTFM!]

Post by Jimmus » Wed Jan 10, 2018 8:03 pm

Trying to get Auto Wake Up to work. I have tried everything I could find, and I eventually got it to work but not in a way that I should have to. Long story short, I ended up pretty much talking to the controller registers directly.

Code: Select all

// Tests AutoWakeup so we can use it for power saving mode.

#define ledPin PB5

void setup() {
  pinMode(ledPin, OUTPUT_FAST);
  digitalWrite(ledPin, HIGH);      // Turn off the LED
  AWU->APR = 62;                   // Set up to wake up in 0.5 seconds
  AWU->TBR = 11;
}

void loop() {
  digitalWrite(ledPin, LOW);       // Turn on the LED
  delay(1000);
  digitalWrite(ledPin, HIGH);      // Turn off the LED
  AWU->CSR = 0x10;
  halt();
  digitalWrite(ledPin, HIGH);      // Turn off the LED
  for (;;);                        // Loop here forever
}

volatile unsigned char reg;

INTERRUPT_HANDLER(AWU_IRQHandler, ITC_IRQ_AWU)
{
  reg = AWU->CSR;     // Reading AWU_CSR1 register clears the interrupt flag.
}
The issue is that this doesn't work. Well, it kinda works. I see the LED light up, and turn off, then it waits for 0.5 seconds, but then the LED turns back on. Then, depending on what other debug code I have loaded, it may do it again. Or not. It seems to have somewhat random behavior. So it seems it is working fine up to the halt(), and waking up after 0.5 seconds, as expected. I know this works because if I change the settings I can get it to wake up after 1 second, or 2 seconds, or whatever I want. The problem is that after it wakes up it isn't executing the code that it's supposed to be running.

I looked at the assembly code that is generated, and it is solid. I looked at the .hex file, and the interrupt vector table has 0's where I would have expected the call to my interrupt handler to be, at offset 800C.

Code: Select all

:108000008200806B8200000082000000820000007D
:10801000820000008200812A820081308200813645
So I figure it is doing an INT 000000 instruction, and executing code at the beginning of RAM. Or something. Sometimes it seems to get back into the beginning of my loop() function. Anyway, that's not useful.

I have tried every incantation I could think of or find in the code anywhere.
  • IMPLEMENT_ISR(AWU_InterruptHandler, ITC_IRQ_AWU)
  • void AWU_IRQHandler(void) __interrupt(ITC_IRQ_AWU)
  • void AWU_IRQHandler(void) __interrupt(1) __naked
Among other things. None of them put anything into the interrupt vector table for me. So I looked at the assembly code and tracked down the beginning of the interrupt service routine in the hex file, and modified the hex file. I jammed that address into the interrupt vector table with my editor.

Code: Select all

:108000008200806B8200000082000000820080D12C
:10801000820000008200812A820081308200813645
That works! Perfectly!

But I don't want to have to disassemble hex code, calculate the checksum, and modify the hex every time I recompile my project. So the question is, how am I supposed to do it? And why does it seem to work for the External interrupt and the UART, but not the AWU?
Last edited by Jimmus on Thu Jan 11, 2018 5:41 pm, edited 1 time in total.

User avatar
Pito
Posts: 1707
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: How do I get my AWU ISR into the interrupt vector table?

Post by Pito » Wed Jan 10, 2018 9:41 pm

Afaik the vector table is copied (upon reset) from flash (0x08000000 region) into sram (starting 0x200000XX).
There is the SCB_BASE->VTOR reg which points to the start of the vector table in sram.
So you can write there what you want, I think.

PS: long time back I was setting the new vector table origin like this

Code: Select all

  //SCB_BASE->VTOR = (volatile uint32_t) 0x2000FC00;
   *(int volatile*)0xE000ED08 = (volatile uint32_t) 0x2000FC00;
You may derive from it how to write at vector_table_start + your_offset
:)
Pukao Hats Cleaning Services Ltd.

Jimmus
Posts: 15
Joined: Tue Nov 28, 2017 4:08 am

Re: How do I get my AWU ISR into the interrupt vector table?

Post by Jimmus » Thu Jan 11, 2018 1:04 am

@Pito I'm not sure we're using the same hardware platform. I don't seem to have memory at those addresses. I can't find any mention of SCB anything or VTOR either. Grep doesn't show any matches in the entire package.

User avatar
mrburnette
Posts: 2066
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: How do I get my AWU ISR into the interrupt vector table?

Post by mrburnette » Thu Jan 11, 2018 3:42 am

A recent discussion of changing the vector table:
http://stm32duino.com/viewtopic.php?f=3&t=1848

User avatar
ahull
Posts: 1673
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: How do I get my AWU ISR into the interrupt vector table?

Post by ahull » Thu Jan 11, 2018 4:47 am

Jimmus wrote:
Thu Jan 11, 2018 1:04 am
@Pito I'm not sure we're using the same hardware platform. I don't seem to have memory at those addresses. I can't find any mention of SCB anything or VTOR either. Grep doesn't show any matches in the entire package.
@Jimmus - You could well be correct, what hardware platform are you using, and which arduino core are you using (maple or ...) ?
- Andy Hull -

Jimmus
Posts: 15
Joined: Tue Nov 28, 2017 4:08 am

Re: How do I get my AWU ISR into the interrupt vector table?

Post by Jimmus » Thu Jan 11, 2018 5:28 am

Oh. Sorry. I thought posting in the STM8 sub-forum would indicate which hardware I'm using.

It's a STM8S003F3P6 minimum system development board. I'm using the sduino core, STM8S103F3 breakout board option in the IDE. The sdcc compiler.

dannyf
Posts: 214
Joined: Wed May 11, 2016 4:29 pm

Re: How do I get my AWU ISR into the interrupt vector table?

Post by dannyf » Thu Jan 11, 2018 1:43 pm

You are asking two questions.

1. How to put your it into the vector table? That is compiler specific. You will have to look into your compiler manual for the right syntax.

2. How to get your code to work? It is likely your is is working but the rest of your code isn't. I would keep the main loop clean of all but half() and flip a led in the isr.

edogaldo
Posts: 291
Joined: Fri Jun 03, 2016 8:19 am

Re: How do I get my AWU ISR into the interrupt vector table?

Post by edogaldo » Thu Jan 11, 2018 2:09 pm

Jimmus wrote:
Wed Jan 10, 2018 8:03 pm
The problem is that after it wakes up it isn't executing the code that it's supposed to be running.
Are you saying that the sketch doesn't run the neverending empty loop?
Can it be that resuming from halt or something else (i.e. a watchdog) triggers a system reset?

Jimmus
Posts: 15
Joined: Tue Nov 28, 2017 4:08 am

Re: How do I get my AWU ISR into the interrupt vector table?

Post by Jimmus » Thu Jan 11, 2018 5:26 pm

@edogaldo Yes I'm saying the sketch doesn't run the neverending empty loop. Or any of the code right after the halt() instruction. Notice that code is supposed to turn the LED *OFF* and then enter the forever loop. Behavior is that the LED turns ON after 0.5 seconds. I'm pretty sure it isn't running my ISR because I have put other code in there to test, and it didn't execute. But it doesn't reset either -- then it would blink the LED again like it did the first time. It just turns the LED on. And then nothing else.

@dannyf Yes, I want to know how to put the address of my ISR into the interrupt vector table. I'm pretty sure the rest of my code is working. When I modify the .hex file with my editor and insert the address of my ISR into the interrupt vector table, it works perfectly. I want to know how to get the compiler to do that.

There are other ISRs in the interrupt vector table. Specifically, External Interrupts, and UART TX and RX. As far as I can tell, I did it the same way they did. I grepped every occurrence of anything that had to do with vector, interrupt, or IRQ, and tried them all.

But that's a really good suggestion about reading the manual. I will go do that right now.

Jimmus
Posts: 15
Joined: Tue Nov 28, 2017 4:08 am

Re: How do I get my AWU ISR into the interrupt vector table?

Post by Jimmus » Thu Jan 11, 2018 5:40 pm

Well, RTFM!
If you have multiple source files in your project, interrupt service routines can be present in any of them, but a prototype of the isr MUST be present in the file that contains the function 'main'.
From main.c:

Code: Select all

#include <Arduino.h>

// make sure to define prototypes for all used interrupts
//#include "stm8s_it.h"
From stm8s_it.h:

Code: Select all

#if defined(_SDCC_)  // SDCC patch: interrupt keyword required after function
//FIXME void TRAP_IRQHandler(void) __interrupt(); /* TRAP */
// void TLI_IRQHandler(void) __interrupt(ITC_IRQ_TLI); /* TLI */
// void AWU_IRQHandler(void) __interrupt(ITC_IRQ_AWU); /* AWU */
// void CLK_IRQHandler(void) __interrupt(ITC_IRQ_CLK); /* CLOCK */
 void EXTI_PORTA_IRQHandler(void) __interrupt(ITC_IRQ_PORTA); /* EXTI PORTA */
 void EXTI_PORTB_IRQHandler(void) __interrupt(ITC_IRQ_PORTB); /* EXTI PORTB */
 ...
I uncommented out the line with the AWU_IRQHandler and now it works. Not that it was compiler syntax, per se... Just where it was declared.

Thanks, everyone for your suggestions and comments.

Post Reply