NFLic

STM8uLoader

Класс Dumps. Модули записи в память EEPROM (Статья 9)

В предыдущей статье был добавлен в командную строку файл прошивки памяти RAM, в класс Dumps.cs были добавлены модули записи в RAM и копирования в RAM память STM8. В этой статье добавляем модули записи в EEPROM память.

В адресном пространстве STM8S103F3 ячейки EEPROM памяти расположены в адресах $4000...$427F (640 байт). Память EEPROM разделена на 10 блоков(block) по 16 слов(word) или 64 байта, в каждом слове 4 байта. Начальные адреса блоков, выровненны по маске $xx00 $xx40 $xx80 $xxC0. Начальные адреса слов, выровненны по маске $xxx0 $xxx4 $xxx8 $xxC. Байты имеют произвольный доступ в пределах адресного пространства. Адреса блоков :

 
  $4000...$403F, $4040...$407F, $4080...$40BF, $40C0...$40FF, 
  $4100...$413F, $4140...$417F, $4180...$41BF, $41C0...$41FF, 
  $4200...$423F, $4240...$427F.

 

В отличие от записи в RAM запись в EEPROM требует :

- разблокирования EEPROM памяти после каждого сброса STM8 последовательной записью значений $AE и $56 в регистр FLASH_DUKR ($5064). С этого момента доступна побайтовая запись ячеек памяти EEPROM. При некорректной записи в регистр FLASH_DUKR потребуется повторная перезагрузка STM8;

- выбора режима Standard block programming (запись блока со стиранием) $01/$FE, Fast block programming (запись блока без стиранием) $10/$EF, Block erase (стирание блока) $20/$DF, Word programming $40/$BF последовательной записью в регистры FLASH_CR2 ($505B) и FLASH_NCR2 ($505C). При некорректной записи в регистры FLASH_CR2 ($505B) и FLASH_NCR2 ($505C) будет выполняться только побайтовая(медленная) запись;

- на время записи/стирания EEPROM памяти останавливается выполнение программы;

- программа записи/стирания EEPROM памяти (кроме побайтовой записи) желательно должна исполняться из RAM памяти;

- при побайтовой записи в EEPROM требуется только предварительное разблокирование последовательной записью значений $AE и $56 в регистр FLASH_DUKR ($5064), далее обычные команды записи в ячейки памяти (напр LD).

 

Standard block programming. В этом режиме происходит запись блока с автоматическим стиранием (требуется в два раза больше времени на запись). Алгоритм записи:

1 - разблокировать запись/стирание EEPROM последовательным копированием значений $AE и $56 в регистр FLASH_DUKR ($5064), если это еще не сделано;

2 - выбрать режим Standard block programming последовательным копированием значений $01 и $FE в регистры FLASH_CR2 ($505B) и FLASH_NCR2 ($505C) соответственно;

3 - наполнить блок с начального адреса, выровненного по маске $xx00 $xx40 $xx80 $xxC0 требуемым содержимым командами записи в ячейки памяти (напр LD, MOV и пр.);

4 - при копировании в блок всех 64 байтов автоматически начинается запись блока, на время записи останавливается выполнение команд;

5 - после записи блока режим Standard block programming отключается;

6 - при необходимоти записи следующего блока перейти к п.2;

7 - при копирования более 64 байт лишние байты будут записываться в побайтовом (медленном) режиме ;

8 - после окончания записи автоматически начнется выполнение команд.

 

    ; unlock EEPROM memory  (writing the correct MASS keys)
         mov      FLASH_DUKR, #$AE      ; Write $AE then $56 in FLASH_DUKR($5064)
         mov      FLASH_DUKR, #$56
         mov      FLASH_CR2,  #$01      ; Write $01 then $FE in FLASH_CR2($505B) and FLASH_NCR2($505C)   
         mov      FLASH_NCR2, #$FE      
         ldw     X, #$8800              ; src table in FLASH
         ldw     Y, #$4240              ; dst table in EEPROM
         mov     $0000, #64             ; counter in RAM
    Write_block_cycle:
         ld      A, (X)
         ld      (Y), A		; после выполнения этой команды при последней итерации начинается запись блока 
         dec     $0000      ; после окончания записи блока начинает выполняться эта команда
         jrne    Write_block_cycle

 

Fast block programming. В этом режиме происходит запись блока с предварительно стертым содержимым (требуется меньше времени на запись). Алгоритм записи:

1 - разблокировать запись/стирание EEPROM памяти данных последовательным копированием значений $AE и $56 в регистр FLASH_DUKR ($5064), если это еще не сделано;

2 - выбрать режим Fast block programming последовательным копированием значений $10 и $EF в регистры FLASH_CR2 ($505B) и FLASH_NCR2 ($505C) соответственно;

3 - наполнить блок с начального адреса, выровненного по маске $xx00 $xx40 $xx80 $xxC0 требуемым содержимым командами записи в ячейки памяти (напр LD, MOV и пр.);

4 - при копировании в блок всех 64 байтов автоматически начинается запись блока, на время записи останавливается выполнение команд;

5 - после записи блока режим Fast block programming отключается;

6 - при необходимоти записи следующего блока перейти к п.2;

7 - при копирования более 64 байт лишние байты будут записываться в побайтовом (медленном) режиме ;

8 - после окончания записи автоматически начнется выполнение команд.

 

Block erase. В этом режиме происходит стирание содержимого блока. Алгоритм стирания:

1 - разблокировать запись/стирание EEPROM памяти данных последовательным копированием значений $AE и $56 в регистр FLASH_DUKR ($5064), если это еще не сделано;

2 - выбрать режим Block erase последовательным копированием значений $20 и $DF в регистры FLASH_CR2 ($505B) и FLASH_NCR2 ($505C) соответственно;

3 - скопировть значение $00 в четыре последовательные ячейки памяти внутри блока с начальным адресом выровненым по маске $xxx0 $xxx4 $xxx8 $xxxC командами записи в ячейки памяти (напр LD, MOV и пр.);

4 - автоматически начнется стирание блока, на время стирания останавливается выполнение команд;

5 - после стирания блока режим Block erase отключается;

6 - при необходимоти стереть следующий блок перейти к п.2;

7 - после окончания стирания блока автоматически начнется выполнение команд.

 

Word programming. В этом режиме происходит запись слова. Стирание происходит записью нулевых значений. Алгоритм записи:

1 - разблокировать запись/стирание EEPROM памяти данных последовательным копированием значений $AE и $56 в регистр FLASH_DUKR ($5064), если это еще не сделано;

2 - выбрать режим Word programming последовательным копированием значений $40 и $BF в регистры FLASH_CR2 ($505B) и FLASH_NCR2 ($505C) соответственно;

3 - заполнить содержимым четыре последовательные ячейки памяти с начальным адресом выровненным по маске $xxx0 $xxx4 $xxx8 $xxxC;

4 - при копировании всех 4 байтов автоматически начинается запись слова, на время записи останавливается выполнение команд;

5 - после записи блока режим Word programming отключается;

7 - при копирования более 4 байт лишние байты будут записываться в побайтовом (медленном) режиме ;

8 - после окончания записи автоматически начнется выполнение команд.

 

         mov     FLASH_DUKR, #$AE
         mov     FLASH_DUKR, #$56
         mov     FLASH_CR2,  #$40
         mov     FLASH_NCR2, #$BF
    ; следующая запись произойдет с начальным адресом $4100
         mov     $4100, #$11      ; запись произойдет по адресу $4100
         mov     $4101, #$11      ; запись произойдет по адресу $4101
         mov     $4102, #$11      ; запись произойдет по адресу $4102
         mov     $4103, #$11      ; запись произойдет по адресу $4103

         mov     FLASH_DUKR, #$40
         mov     FLASH_DUKR, #$BF
    ; следующая запись произойдет с начальным адресом $4240 вместо ожидаемого $423F
         ld      A, #$33          
         ld      $423F, A         ; запись произойдет по адресу $4240
         ld      $4240, A         ; запись произойдет по адресу $4241
         ld      $4241, A         ; запись произойдет по адресу $4242
         ld      $4242, A         ; запись произойдет по адресу $4243
    ; следующая запись произойдет с начальным адресом $4124 вместо ожидаемого $4121
         mov     FLASH_DUKR, #$40
         mov     FLASH_DUKR, #$BF
         ldw     X, #$8200
         ldw     Y, #$4121
         mov     $0000, #4
    Write_word_cycle:
         ld      A, (X)
         ld      (Y), A		 
         dec     $0000
         jrne    Write_word_cycle

 

Byte programming. В этом режиме происходит побайтовая запись в ячейки EEPROM. Для STM8S103F3 на время записи также останавливается выполнеие команд. Алгоритм записи:

1 - разблокировать запись/стирание EEPROM последовательным копированием значений $AE и $56 в регистр FLASH_DUKR ($5064), если это еще не сделано;

2 - скопировать байт(байты) в ячейку(ячейки) EEPROM командами записи в ячейки памяти (напр LD, MOV и пр.);

3 - на время записи каждого байта останавливается выполнение команд.

 

    ; unlock EEPROM memory  (writing the correct MASS keys)
         mov     FLASH_DUKR, #$AE     ; Write $AE then $56 in FLASH_DUKR($5064)
         mov     FLASH_DUKR, #$56     ; If wrong keys have been entered, another key programming sequence can be issued without resetting the device.
         mov     $427F, #$14

 

Классы [Dumps], [FileOpenMemorySorting], [IntelHEXfile], [MotorolaS19file].

 

Файл STM8uLoader.cs :

 

// STM8uLoader.cs
using System;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Collections.Generic;

public class STM8uLoader
{
	
	public static void Main(string[] arg)   { 
		if (arg.Length == 0) {Console.WriteLine("Отсутствуют аргументы командной строки"); 
								Console.ReadKey(); return;}
		else fileName = arg[0];
		Console.WriteLine("Обнаружены {0} аргумент(ов) командной строки", arg.Length);
		foreach(string strArg in arg){
			Console.WriteLine(strArg);
		}//foreach
			
		FileOpenMemorySorting fileSorted = new FileOpenMemorySorting(fileName);

		Console.Write("Из файла");
			foreach( KeyValuePair kvp in fileSorted.GetRAMaddressLineSorted() ){
				Console.Write("\n${0:X4} ", kvp.Key);
				for(int i = 0; i < kvp.Value.Length; i++) Console.Write("${0:X2} ", kvp.Value[i]);
			}// foreach

		Console.WriteLine("\n");

		

		//Dumps	myDumps = new Dumps();

		Dumps.COM_port_Open();
		readThread = new Thread(Dumps.Read);
		readThread.IsBackground = true; // не позволит остаться потоку в памяти после закрытия программы ?
			try {
				readThread.Start();		// запускаем поток чтения COM порта
			} catch (Exception ex) {Console.WriteLine("readThread.Start(). Exception" + ex.Message); } 
					
		Dumps.Load_First_Dump(Dumps.Read_128000v14);

		blckAdr = 0x0100;	blckSize = 178;
		Console.WriteLine("Из памяти до записи");
		Dumps.Dump_To_Console(Dumps.Read_128000(blckAdr, blckSize));

		//Dumps.Load_Dump(Dumps.Write_RAM_128000v14);
		Console.WriteLine("пишем в память");
		Dumps.Write_RAM_128000(fileSorted.GetRAMaddressLineSorted());
		
		//Dumps.Load_Dump(Dumps.Read_128000v14);

		blckAdr = 0x0100;	blckSize = 178;
		Console.WriteLine("Из памяти после записи");
		Dumps.Dump_To_Console(Dumps.Read_128000(blckAdr, blckSize));
		
		
		blckAdr = 0x4100;	blckSize = 512;
		Console.WriteLine("Из EEPROM до записи");
		Dumps.Dump_To_Console(Dumps.Read_128000(blckAdr, blckSize));

		addressBytesBlock.Clear();
		blckAdr = 0x4100;
		for(int i = 0; blckAdr < 0x4280; i = i + 64){
			for(int j = 0; j < 64; j++){
				blck64Bytes[j] = (byte)0x00;
			}
			addressBytesBlock.Add(blckAdr, blck64Bytes);
			blckAdr = blckAdr + 64;
		}
		Dumps.WriteBlock_EEPROM_128000(addressBytesBlock);

		blckAdr = 0x4100;	blckSize = 512;
		Console.WriteLine("Из EEPROM после записи");
		Dumps.Dump_To_Console(Dumps.Read_128000(blckAdr, blckSize));


		addressBytesBlock.Clear();
		blckAdr = 0x4100;
		for(; blckAdr < 0x4280;){
			for(int j = 0; j < 4; j++){
				wrd4Bytes[j] = (byte)0x11;
			}
			addressBytesBlock.Add(blckAdr, wrd4Bytes);
			blckAdr = blckAdr + 19;
		}
		Dumps.WriteWord_EEPROM_128000(addressBytesBlock);

		blckAdr = 0x4100;	blckSize = 512;
		Console.WriteLine("Из EEPROM после записи");
		Dumps.Dump_To_Console(Dumps.Read_128000(blckAdr, blckSize));
		
		
		
		
		
		
		readThread.Join();	// останавливаем поток чтения COM порта
		Dumps.COM_port_Close();
		Console.ReadKey(); return;
    } // Main();
    public static Thread readThread;

	public static string stringMemoryMap = "";
	public  static byte rx_byte = 0x00;
	public static byte[] btBytes = new byte[1];
	public static byte[] wrd4Bytes = new byte[4];
	public static byte[] blck64Bytes = new byte[64];
	public static byte[] blck192Bytes = new byte[192];
	public static SortedDictionary addressBytesBlock = new SortedDictionary();
	
	public static int blckAdr;
	public static int blckSize;
	public  static bool unready = true;
	public  static string fileName;	
	public static byte[] txBytes = {0, 0};

}// class STM8uLoader
// STM8uLoader.cs

 

Запускаем BAT файл [run.bat], нажимаем кнопку сброса на плате STM8.

 

 

 

 

В следующей статье добавим в класс Dumps.cs модули записи во FLASH память программ.

 

Исходники:[boot_PC.zip] , [WriteByte_EEPROM_128000v14.asm] , [WriteWord_EEPROM_128000v14.asm] , [WriteBlock_EEPROM_128000v14.asm] .

 

[Класс Dumps. Модули записи и копирования в память RAM (Статья 8)] [Оглавление.] [Класс Dumps. Модули записи в память FLASH (Статья 10)]