Reputation: 131
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
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