K0ertis
K0ertis

Reputation: 131

Interrupt STM8s issue with SDCC compiler

I want to use interrupts on the SMT8S003K3 (STM8SVL-DISCOVERY) and somehow it does not get recognized when I use the interrupt on a other file where my main() is located.

I made two tests: - first I modified this code to Standard Peripheral Library:

uint8_t main(){
      CLK->CKDIVR=0;
     TIM1->PSCRH=0;
     TIM1->PSCRL=0x80;
     TIM1->CR1=1;
     TIM1->IER=1;

     GPIOD->DDR = 1;
     GPIOD->CR1 = 1;
     enableInterrupts();

     while(1){
     }
}

void TIM1_overflow_Handler() __interrupt(11)
{
  TIM1->SR1 &= ~1; //reset interrupt
  GPIOD->ODR ^= 1; //toggle LED
}

and it works...

Now to use UnitTests I putted this function into an other file: main_internal (just a simple example):

#ifdef STM8S003
#include "stm8s.h"
#endif
#include "main_internal.h"

void main_internal() {

     CLK->CKDIVR=0;
     TIM1->PSCRH=0;
     TIM1->PSCRL=0x80;
     TIM1->CR1=1;
     TIM1->IER=1;
     GPIOD->DDR = 1;
     GPIOD->CR1 = 1;
     enableInterrupts();

     while(1){
     }
}

void TIM1_overflow_Handler() __interrupt(11)
{
  TIM1->SR1 &= ~1; //reset interrupt
  GPIOD->ODR ^= 1; //toggle LED
}

with the main function:

#include "main_internal.h"

int main(){
  main_internal();
  return 0;
}

and it does nothing... well it flows around in the deep memory of the STM8S003 (as I have seen with the debugger). Is this a linking issue?

This is my Makefile:

ST_TARGET      = main
INCLUDEDIR  = Libraries/inc include
ST_LIBSRCDIR   = Libraries/src
#ST_LIBSRC      = $(ST_LIBSRCDIR)/stm8s_adc1.c  $(ST_LIBSRCDIR)/stm8s_awu.c
#ST_LIBSRC     += $(ST_LIBSRCDIR)/stm8s_beep.c  $(ST_LIBSRCDIR)/stm8s_clk.c
#ST_LIBSRC     += $(ST_LIBSRCDIR)/stm8s_exti.c  $(ST_LIBSRCDIR)/stm8s_flash.c
#ST_LIBSRC     += $(ST_LIBSRCDIR)/stm8s_gpio.c  $(ST_LIBSRCDIR)/stm8s_i2c.c
#ST_LIBSRC     += $(ST_LIBSRCDIR)/stm8s_itc.c   $(ST_LIBSRCDIR)/stm8s_iwdg.c
#ST_LIBSRC     += $(ST_LIBSRCDIR)/stm8s_rst.c   $(ST_LIBSRCDIR)/stm8s_spi.c
#ST_LIBSRC     += $(ST_LIBSRCDIR)/stm8s_tim1.c  $(ST_LIBSRCDIR)/stm8s_wwdg.c

SRC_DIR        = src
SRC_ALL = $(shell find -L $(SRC_DIR) -name '*.c')

SRCS = $(filter-out $(SRC_DIR)/$(ST_TARGET).c,$(SRC_ALL))

ST_OBJS        = $(ST_LIBSRC:.c=.rel)
ST_LIB_FILES := $(addprefix $(ST_BUILD_DIR)/,$(notdir $(ST_OBJS)))
LIBD_FILES := $(addprefix $(ST_DEBUG_DIR)/,$(notdir $(ST_OBJS)))
PR_ST_OBJS       = $(SRCS:.c=.rel)
ST_SRC_FILES := $(addprefix $(ST_BUILD_DIR)/,$(notdir $(PR_ST_OBJS)))
SRCD_FILES := $(addprefix $(ST_DEBUG_DIR)/,$(notdir $(PR_ST_OBJS)))
ST_OBJS += $(PR_ST_OBJS)
STD_OBJS= $(ST_OBJS)
MCU         = STM8S003
ST_COMPILER    = __SDCC__
DEFINES     = -D$(ST_COMPILER) -D$(MCU) -DUSE_STDPERIPH_DRIVER

ST_CFLAGS      = -mstm8 $(DEFINES)
ST_LDFLAGS     = $(addprefix -I ,$(INCLUDEDIR))
ST_DEBUG_FLAGS =  --out-fmt-elf --all-callee-saves --debug --stack-auto --fverbose-asm --float-reent --no-peep

IHX         = $(ST_BUILD_DIR)/$(ST_TARGET).ihx
ELF         = $(ST_DEBUG_DIR)/$(ST_TARGET).elf

$(info $$ srcfiles is [${ST_OBJS}])
$(info $$ srcfiles is [${LIBD_FILES}])
ifdef st-debug
        ST_OUT_DIR=$(ST_DEBUG_DIR)
else
        ST_OUT_DIR=$(ST_BUILD_DIR)
endif

################### BUILD PROCESS ###################
.PHONY: all st-build st-clean st-flash st-debug st-wipe

#all: clean st-build
st: st-clean st-build st-flash

st-debug: $(STD_OBJS) $(ELF)# ST_CFLAGS+=$(ST_DEBUG_FLAGS)
st-debug: ST_CFLAGS+=$(ST_DEBUG_FLAGS)
st-debug: ST_OUT_DIR=$(ST_DEBUG_DIR)
$(STD_OBJS): 

$(ELF): $(SRC_DIR)/$(ST_TARGET).c
        @echo $(ST_OUT_DIR)
        #ST_CFLAGS += $(ST_DEBUG_FLAGS)
        $(ST_CC) $(ST_CFLAGS) $(ST_LDFLAGS) -o $(ST_OUT_DIR)/ $< $(SRCD_FILES) $(LIBD_FILES)
        $(SIZE) $@
        $(SIZE) $@ >> $(MEMORY_USAGE_DIR)/$(MEMORY_USAGE)
        @echo Success!!!!\\n\\n
st-build: $(ST_OBJS) $(IHX)

$(ST_OBJS): 

$(IHX): $(SRC_DIR)/$(ST_TARGET).c $(SRCS:.c)
        $(ST_CC) $(ST_CFLAGS) $(ST_LDFLAGS) -o $(ST_OUT_DIR)/ $< $(ST_SRC_FILES) $(ST_LIB_FILES)
        $(SIZE) $@
        $(SIZE) $@ >> $(MEMORY_USAGE_DIR)/$(MEMORY_USAGE)
        @echo Success!!!!\\n\\n

This would be the code without Standard Peripheral library:

#include <stdint.h>

#define CLK_DIVR    (*(volatile uint8_t *)0x50C6)

#define TIM1_CR1    (*(volatile uint8_t *)0x5250)
#define TIM1_IER    (*(volatile uint8_t *)0x5254)
#define TIM1_SR1    (*(volatile uint8_t *)0x5255)
#define TIM1_CNTRH    (*(volatile uint8_t *)0x525E)
#define TIM1_CNTRL    (*(volatile uint8_t *)0x525F)
#define TIM1_PSCRH    (*(volatile uint8_t *)0x5260)
#define TIM1_PSCRL    (*(volatile uint8_t *)0x5261)

#define PD_ODR    (*(volatile uint8_t *)0x500f)
#define PD_DDR    (*(volatile uint8_t *)0x5011)
#define PD_CR1    (*(volatile uint8_t *)0x5012)

void main(void)
{
     CLK_DIVR = 0x00; // Set the frequency to 16 MHz

     TIM1_PSCRH = 0x00; // Configure timer
     TIM1_PSCRL = 0x80;

     TIM1_CR1 = 0x01; //Enable timer
     TIM1_IER = 0x01; //Enable interrupt - update event

     PD_DDR = 1;
     PD_CR1 = 1;
     __asm__ ("rim");

     while(1){
     }
}

void TIM1_overflow_Handler() __interrupt(11)
{
     TIM1_SR1 &= ~1; //reset interrupt
     PD_ODR ^= 1; //toggle LED
}

Here I have a diff from gdb of the two versions:

15c15
< 00008034:   int     0x0080d7 ;0x80d7 <TIM1_overflow_Handler>
---
> 00008034:   int     0x000000
44c44
< 00008098:   ld      A,(0x80fd,X) ;0x80fd <TIM1_overflow_Handler+38>
---
> 00008098:   ld      A,(0x8114,X) ;0x8114 <TIM1_overflow_Handler+38>
54c54
<  27              CLK_DIVR = 0x00; // Set the frequency to 16 MHz
---
>  8          main_internal();
56,163c56,136
< 000080b1:   neg     (0x50,SP) ;0x50
< 000080b3:   ld      A,0x3500 ;0x3500
<  29              TIM1_PSCRH = 0x00; // Configure timer
< 000080b4:   mov     0x0052,#0x60 ;0x60
<  30              TIM1_PSCRL = 0x80;
< 000080b8:   mov     0x8052,#0x61 ;0x61
<  32              TIM1_CR1 = 0x01; //Enable timer
< 000080bc:   mov     0x0152,#0x50 ;0x50
<  33              TIM1_IER = 0x01; //Enable interrupt - update event
< 000080c0:   mov     0x0152,#0x54 ;0x54
<  35              PD_DDR = 1;
< 000080c4:   mov     0x0150,#0x11 ;0x11
<  36              PD_CR1 = 1;
< 000080c8:   mov     0x0150,#0x12 ;0x12
<  37              __asm__ ("rim");
< 000080cc:   rim     
<  39              while(1){
< 000080cd:   jp      0x80cd ;0x80cd <main+41>
<  41         }
< 000080d0:   pop     0x0001 ;0x1
< 000080d3:   pop     0x0002 ;0x2
< 000080d6:   ret     
<  43         void TIM1_overflow_Handler() __interrupt(11)
<           TIM1_overflow_Handler:
< 000080d7:   push    0x0002 ;0x2
< 000080da:   push    0x0001 ;0x1
< 000080dd:   ldw     Y,SP
< 000080df:   ldw     0x0001,Y ;0x1
<  45              TIM1_SR1 &= ~1; //reset interrupt
< 000080e3:   ldw     X,#0x5255 ;0x5255
< 000080e6:   ld      A,(X)
< 000080e7:   and     A,#0xfe ;0xfe
< 000080e9:   ldw     X,#0x5255 ;0x5255
< 000080ec:   ld      (X),A
<  46              PD_ODR ^= 1; //toggle LED
< 000080ed:   ldw     X,#0x500f ;0x500f
< 000080f0:   ld      A,(X)
< 000080f1:   xor     A,#0x01 ;0x1
< 000080f3:   ldw     X,#0x500f ;0x500f
< 000080f6:   ld      (X),A
<  47         }
< 000080f7:   pop     0x0001 ;0x1
< 000080fa:   pop     0x0002 ;0x2
< 000080fd:   iret    
< 000080fe:   and     A,#0xfe ;0xfe
< 00008100:   ldw     X,#0x5255 ;0x5255
< 00008103:   ld      (X),A
< 00008104:   ldw     X,#0x500f ;0x500f
< 00008107:   ld      A,(X)
< 00008108:   xor     A,#0x01 ;0x1
< 0000810a:   ldw     X,#0x500f ;0x500f
< 0000810d:   ld      (X),A
< 0000810e:   pop     0x0001 ;0x1
< 00008111:   pop     0x0002 ;0x2
< 00008114:   iret    
< 00008115:   ld      (X),A
< 00008116:   ldw     X,#0x5230 ;0x5230
< 00008119:   ld      A,(X)
< 0000811a:   and     A,#0x80 ;0x80
< 0000811c:   cp      A,#0x80 ;0x80
< 0000811e:   jrne    0x8116 ;0x8116
< 00008120:   ret     
< 00008121:   jra     0x8116 ;0x8116
< 00008123:   ret     
< 00008124:   ldw     X,#0x5235 ;0x5235
< 00008127:   ld      A,(X)
< 00008128:   or      A,#0x20 ;0x20
< 0000812a:   ld      (X),A
< 0000812b:   ret     
< 0000812c:   ldw     X,#0x5235 ;0x5235
< 0000812f:   ld      A,(X)
< 00008130:   or      A,#0x20 ;0x20
< 00008132:   ld      (X),A
< 00008133:   ldw     X,#0x5230 ;0x5230
< 00008136:   ld      A,(X)
< 00008137:   and     A,#0xd0 ;0xd0
< 00008139:   ld      (X),A
< 0000813a:   ldw     X,#0x5231 ;0x5231
< 0000813d:   ld      A,(X)
< 0000813e:   ret     
< 0000813f:   sub     SP,#0x08 ;0x8
< 00008141:   mov     0x0050,#0xc6 ;0xc6
< 00008145:   mov     0x0052,#0x60 ;0x60
< 00008149:   mov     0x8052,#0x61 ;0x61
< 0000814d:   mov     0x0152,#0x50 ;0x50
< 00008151:   mov     0x0152,#0x54 ;0x54
< 00008155:   mov     0x0150,#0x11 ;0x11
< 00008159:   mov     0x0150,#0x12 ;0x12
< 0000815d:   rim     
< 0000815e:   ldw     X,#0x525e ;0x525e
< 00008161:   ld      A,(X)
< 00008162:   ldw     X,#0x5231 ;0x5231
< 00008165:   ld      (X),A
< 00008166:   ldw     X,#0x5230 ;0x5230
< 00008169:   ld      A,(X)
< 0000816a:   and     A,#0x80 ;0x80
< 0000816c:   cp      A,#0x80 ;0x80
< 0000816e:   jrne    0x8166 ;0x8166
< 00008170:   ldw     X,#0x1388 ;0x1388
< 00008173:   clr     (0x02,SP) ;0x2
< 00008175:   clr     (0x01,SP) ;0x1
< 00008177:   subw    X,#0x0001 ;0x1
< 0000817a:   ldw     (0x07,SP),X ;0x7
< 0000817c:   ld      A,(0x02,SP) ;0x2
< 0000817e:   sbc     A,#0x00
< 00008180:   ld      (0x06,SP),A ;0x6
< 00008182:   ld      A,(0x01,SP) ;0x1
< 00008184:   sbc     A,#0x00
---
> 000080b1:   iret    
> .........   add     A,0x5f ;0x5f
>  9          return 0;
> 000080b3:   clrw    X
> 10        }
> 000080b4:   pop     0x0001 ;0x1
> 000080b7:   pop     0x0002 ;0x2
> 000080ba:   ret     
>           main_internal:
> 000080bb:   push    0x0002 ;0x2
> 000080be:   push    0x0001 ;0x1
> 000080c1:   ldw     Y,SP
> 000080c3:   ldw     0x0001,Y ;0x1
> ......... ...
> 00ffffff:   neg     (0xa5,SP) ;0xa5
> 01000001:   cpl     (0xf9,SP) ;0xf9
> 01000003:   neg     (0xf7,SP) ;0xf7
> 01000005:   xor     A,0x6f ;0x6f
> 01000007:   cpw     X,#0xc9ac ;0xc9ac
> 0100000a:   scf     
> 0100000b:   int     0x1ee2a7 ;0x1ee2a7
> 0100000f:   sll     0x9b ;0x9b
> 01000011:   clr     (0x99,SP) ;0x99
> 01000013:   jrne    0xffffef ;0xffffef
> 01000015:           
> 01000016:   addw    SP,#0x11 ;0x11
> 01000018:   or      A,(0xaa,SP) ;0xaa
> 0100001a:   sim     
> 0100001b:   mul     X,A
> 0100001c:   xor     A,(0x3d,SP) ;0x3d
> 0100001e:   sub     A,0x63 ;0x63
> 01000020:   adc     A,0x53 ;0x53
> 01000022:   ld      (0xf8,SP),A ;0xf8
> 01000024:   push    0xd95c ;0xd95c
> 01000027:   pop     A
> 01000028:   sbc     A,(0x53,SP) ;0x53
> 0100002a:   cp      A,(0x3e,SP) ;0x3e
> 0100002c:   cpl     0x13 ;0x13
> 0100002e:   sra     (0xc0,X) ;0xc0
> 01000030:   call    (0xa2c9,X) ;0xa2c9
> 01000033:   ld      A,XH
> 01000034:   tnzw    X
> 01000035:   subw    X,#0x59cf ;0x59cf
> 01000038:   ld      (0x22,SP),A ;0x22
> 0100003a:   decw    X
> 0100003b:   cpl     (0xe9,X) ;0xe9
> 0100003d:   and     A,(0x7775,X) ;0x7775
> 01000040:   sub     A,(0x7e1c,X) ;0x7e1c
> 01000043:   xor     A,(X)
> 01000044:   clrw    X
> 01000045:   swap    0xd5 ;0xd5
> 01000047:   rlwa    X,A
> 01000048:   jreq    0x100006b ;0x100006b
> 0100004a:   inc     0x22 ;0x22
> 0100004c:           
> 0100004d:   sra     0xdf ;0xdf
> 0100004f:   cpw     X,#0xb73f ;0xb73f
> 01000052:   ld      (0x0566,X),A ;0x566
> 01000055:   sbc     A,#0x4c ;0x4c
> 01000057:   sll     (X)
> 01000058:   add     A,0x40 ;0x40
> 0100005a:   adc     A,#0x05 ;0x5
> 0100005c:   ld      (0xc2,SP),A ;0xc2
> 0100005e:   ld      XL,A
> 0100005f:   incw    X
> 01000060:   ldw     (0xc8fe,X),Y ;0xc8fe
> 01000063:   call    0x27e5 ;0x27e5
> 01000066:   ldw     X,(0xd0,X) ;0xd0
> 01000068:   cpw     X,0xc159 ;0xc159
> 0100006b:   mov     0xc5,0xe8 ;0xe8
> 0100006e:   cp      A,(X)
> 0100006f:   bcp     A,(0xcb,SP) ;0xcb
> 01000071:   cpw     Y,(X)
> 01000072:   xor     A,(X)
> 01000073:   pop     CC
> 01000074:   swap    (0x1b,SP) ;0x1b
> 01000076:   ldw     X,#0x44cc ;0x44cc
> 01000079:   div     X,A
> 0100007a:   rlc     A
> 0100007b:   sbc     A,0xa8 ;0xa8
> 0100007d:   inc     (0x9b,X) ;0x9b

Surprisingly the line: 00008034: int 0x0080d7 ;0x80d7 is missing in the second version in the main_internal.

Any help would be appreciated

Upvotes: 1

Views: 3056

Answers (1)

K0ertis
K0ertis

Reputation: 131

facepalm

I did not included the interrupt handler in the main_internal.h file:

void TIM1_overflow_Handler() __interrupt(11);

In the SDCC Compiler User Guide page 40 :

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 or included in the file that contains the function main.

So be sure you always make your isr visible to the main function.

Upvotes: 3

Related Questions