STM8 SDCC

From ElectroDragon Wiki

STM8 SDCC 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