Continuing the STM8 Expedition

STM8S105 Discovery

Internal Flash Memory

 

Though flash memories are primarily intended for storing application codes, it is still possible to use them just like EEPROMs using In-Application Programming (IAP). However, it is important to check that by mistake, we don’t write in those areas where application code reside. IAP can also be used for upgrading application firmware Over-The-Air (OTA).

 

Hardware Connection

 Hardware Schematic

Code Example

#include "STM8S.h"
#include "lcd.h"


#define Button_Port              GPIOB
#define Button_Pin               GPIO_PIN_7


unsigned char bl_state;
unsigned char data_value;


void clock_setup(void);
void GPIO_setup(void);
void Flash_setup(void);
void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned char value);


void main()
{     
       unsigned char value = 0x00;

       clock_setup();
       GPIO_setup();
       Flash_setup();

       LCD_init(); 
       LCD_clear_home();

       LCD_goto(0, 0);
       LCD_putstr("STM8S Flash Test");

       value = FLASH_ReadByte(0x9FF0);
       delay_ms(20);

       LCD_goto(0, 1);
       LCD_putstr("WR: ---");
       LCD_goto(9, 1);
       LCD_putstr("RD:");
       lcd_print(13, 1, value);
       delay_ms(2000);

       while(TRUE)
       {
              if(GPIO_ReadInputPin(Button_Port, Button_Pin) == FALSE)
              {
                     while(GPIO_ReadInputPin(Button_Port, Button_Pin) == FALSE);
                     FLASH_Unlock(FLASH_MEMTYPE_PROG);
                     FLASH_EraseByte(0x9FF0);
                     delay_ms(20);
                     FLASH_ProgramByte(0x9FF0, value);
                     delay_ms(20);
                     FLASH_Lock(FLASH_MEMTYPE_PROG);

                     lcd_print(13, 1, value);
              }

              delay_ms(20);
              lcd_print(4, 1, value);

              value++;
              delay_ms(200);
       };
}


void clock_setup(void)
{
       CLK_DeInit();

       CLK_HSECmd(DISABLE);
       CLK_LSICmd(DISABLE);
       CLK_HSICmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);

       CLK_ClockSwitchCmd(ENABLE);
       CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV4);
                                                                            CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE,
                             CLK_CURRENTCLOCKSTATE_ENABLE);

       CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}


void GPIO_setup(void)
{
       GPIO_DeInit(GPIOB);
       GPIO_Init(Button_Port, Button_Pin, GPIO_MODE_IN_FL_NO_IT);
}


void Flash_setup(void)
{
       FLASH_DeInit();
}


void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned char value)
{
       char chr = 0x00;

       chr = ((value / 100) + 0x30);
       LCD_goto(x_pos, y_pos);
       LCD_putchar(chr);

       chr = (((value / 10) % 10) + 0x30);
       LCD_goto((x_pos + 1), y_pos);
       LCD_putchar(chr);

       chr = ((value % 10) + 0x30);
       LCD_goto((x_pos + 2), y_pos);
       LCD_putchar(chr);
}

 

Explanation

This example is same as the EEPROM example. The differences are the read, write and erase instructions.

value = FLASH_ReadByte(0x9FF0);
….
FLASH_Unlock(FLASH_MEMTYPE_PROG);
FLASH_EraseByte(0x9FF0);
delay_ms(20);
FLASH_ProgramByte(0x9FF0, value);
delay_ms(20);
FLASH_Lock(FLASH_MEMTYPE_PROG);

The same MASS keying technique is needed and everything is same because both memories are controlled using the same set of registers. A few things must be noted while using data EEPROM and program flash:

  • The memory type needs to be specified – FLASH_MEMTYPE_PROG when using program/flash memory and FLASH_MEMTYPE_DATA when using the internal true data EEPROM.
  • By definition a block is a set of bytes and a page is a set of blocks. Most modern memories do not allow byte-level write/erase. However, both memory types of STM8s allow byte-level read, write and erase. By the way, it is wise to use page and block writes/erases to enhance memory life cycle and for faster operations.
  • It is also possible to set configuration bytes using IAP.
  • Avoid frequent writes/erases to increase memory life cycles. If needed to write/erase data frequently use wear-leveling technique. Read operations do not wear memories.
  • Apply Read-Out-Protection (ROP) with ROP configuration bit if you want to protect your code from unfriendly eyes.ROP
  • The read, write and erase location must not be outside specified boundary limits or else the application will surely crash or perform improperly. Check device datasheet for memory locations. A much easier and faster way is to use ST Visual Programmer.EEPROM
    flash
  • Power source must not be fluctuating.

 

  • By definition a block is a set of bytes and a page is a set of blocks. Most modern memories do not allow byte-level write/erase. However, both memory types of STM8s allow byte-level read, write and erase. By the way, it is wise to use page and block writes/erases to enhance memory life cycle and for faster operations.

 

  • It is also possible to set configuration bytes using IAP.

 

Demo

 

Flash (1) Flash (2)

Continue Reading ...

Related Posts

8 comments

  • Sankalp Rai Gambhir

    Thanks Shawon, your blogs are indeed very helpful. Keep Growing.

  • why are you sending the received data back through TX pin?

  • Hi SHAWON SHAHRYIAR

    I am wondering how to get a Max31855 to talk to a STM8s via SPI.

    JP

    • What’s to wonder about it? It is a simple SPI communication and SPI for STM8 is no different from the SPI of other MCUs…. The following lines are taken from the device’s datasheet and the write up there states how to communicate with it:

      “Drive CS low to output the first bit on the SO pin. A complete serial-interface read of the cold-junction compensated thermocouple temperature requires 14 clock cycles. Thirty-two clock cycles are required to read both the thermocouple and reference junction temperatures (Table 2 and Table 3.) The first bit, D31, is the thermocouple temperature sign bit, and is presented to the SO pin within tDV of the falling edge of CS. Bits D[30:18] contain the converted temperature in the order of MSB to LSB, and are presented to the SO pin within tD0 of the falling edge of SCK. Bit D16 is normally low and goes high when the thermocouple input is open or shorted to GND or VCC. The reference junction temperature data begins with D15. CS can be taken high at any point while clocking out con-version data. If T+ and T- are unconnected, the thermocouple temperature sign bit (D31) is 0, and the remainder of the thermocouple temperature value (D[30:18]) is 1.”

Leave a Reply

Your email address will not be published. Required fields are marked *