STM8 SDCC
STM8 SDCC commands
- [SDCC guide], commands
sdcc -mstm8 --std-c99 led.c
Important compiler options for STM8 developers include:
- -c to compile into object files to be linked later
- --std-c99 for compilation in C99 mode (some C99 features, e.g. variable-length arrays are not yet supported in sdcc though)
- --opt-code-size for optimization for code size
- --max-allocs-per-node to select the optimization level. the default value is 3000. Higher values result in more optimized code, longer compiler runtime, and higher memory usage during compilation.
Quick Guide in Linux SDCC
Install
- Install ubuntu on virtualbox, Install sdcc: apt-get install sdcc
- update sdcc for stm8, manually remove and install sdcc
sudo apt-get update sudo apt-get remove sdcc sdcc-libraries sudo apt-get install sdcc
- Install stm8flash
git clone https://github.com/vdudouyt/stm8flash.git cd stm8flash make sudo make install
Demo code example
- git clone stm8 blink example:
git clone https://github.com/vdudouyt/sdcc-examples-stm8.git cd sdcc-examples-stm8
- edit code for stm8s103f3:
#define PB_ODR *(unsigned char*)0x5005
#define PB_IDR *(unsigned char*)0x5006
#define PB_DDR *(unsigned char*)0x5007
#define PB_CR1 *(unsigned char*)0x5008
#define PB_CR2 *(unsigned char*)0x5009
int main()
{
int d;
// Configure pins
PB_DDR = 0x20;
PB_CR1 = 0x20;
// Loop
do {
PB_ODR ^= 0x20;
for(d = 0; d < 15000; d++) { }
} while(1);
}
- Or use
#define PB_ODR *(unsigned char*)0x5005
// Port B data direction register, for setting pins as INPUT or OUTPUT
#define PB_DDR *(unsigned char*)0x5007
// Port B control register 1,
#define PB_CR1 *(unsigned char*)0x5008
int main() {
int d;
// Configure pins
PB_DDR = 0x20; // 0x20(00100000) pin 5 set to 1 -> setting it as OUTPUT
PB_CR1 = 0x20; // 0x20(00100000) pin 5 set to 1 -> setting it as PUSH-PULL Mode (only when configured as output)
// Loop
do {
PB_ODR ^= 0x20; // 0x20(00100000) pin 5 XOR/toggle between HIGH and LOW
for(d = 0; d < 29000; d++) {
}
} while(1);
}
- change the makefile:
SDCC=sdcc
SDLD=sdld
OBJECTS=blinky.ihx
.PHONY: all clean flash
all: $(OBJECTS)
clean:
rm -f $(OBJECTS)
flash: $(OBJECTS)
stm8flash -cstlinkv2 -pstm8s103f3 -w $(OBJECTS)
%.ihx: %.c
$(SDCC) -lstm8 -mstm8 --out-fmt-ihx $(CFLAGS) $(LDFLAGS) $<
- run make again and run commands to convert c file to ihx and write flash:
make
Flash
stm8flash -c stlinkv2 -p stm8s103 -w blinky.ihx
- or convert first by
sdcc -lstm8 -mstm8 --out-fmt-ihx blinky.c
- read flash
stm8flash -c stlinkv2 -p stm8s003?3 -r aa.hex
- ./stm8flash -c stlink -p stm8s103k3 -w led.ihx
Alternative official demo code
// Source code under CC0 1.0
#include <stdint.h>
#define CLK_DIVR (*(volatile uint8_t *)0x50c6)
#define CLK_PCKENR1 (*(volatile uint8_t *)0x50c7)
#define TIM1_CR1 (*(volatile uint8_t *)0x5250)
#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 PB_ODR (*(volatile uint8_t *)0x5005)
#define PB_DDR (*(volatile uint8_t *)0x5007)
#define PB_CR1 (*(volatile uint8_t *)0x5008)
unsigned int clock(void)
{
unsigned char h = TIM1_CNTRH;
unsigned char l = TIM1_CNTRL;
return((unsigned int)(h) << 8 | l);
}
void main(void)
{
CLK_DIVR = 0x00; // Set the frequency to 16 MHz
// Configure timer
// 1000 ticks per second
TIM1_PSCRH = 0x3e;
TIM1_PSCRL = 0x80;
// Enable timer
TIM1_CR1 = 0x01;
PB_DDR = 0x20;
PB_CR1 = 0x20;
for(;;)
PB_ODR = (clock() % 1000 < 500) << 5;
}
Error fix: Unlock
- The issue written in pdf datasheet pg 45.
- sudo stm8flash -c stlinkv2 -p "stm8s103f3" -w blinky.ihx
Determine FLASH area Writing Intel hex file 182 bytes at 0x8000... Tries exceeded
- Run command
echo "00 00 ff 00 ff 00 ff 00 ff 00 ff" | xxd -r -p > factory_defaults.bin stm8flash -c stlinkv2 -p stm8s103f3 -s opt -w factory_defaults.bin