kolibrios/programs/develop/oberon07/Samples/MSP430/Flash.ob07
maxcodehack 2f54c7de00 Update oberon07 from akron1's github
git-svn-id: svn://kolibrios.org@8097 a494cfbc-eb01-0410-851d-a64ba20cac60
2020-10-13 07:58:51 +00:00

158 lines
4.3 KiB
Plaintext

(*
Пример для LaunchPad MSP-EXP430G2 Rev1.5
Запись флэш-памяти.
При успешном завершении, включается зеленый светодиод,
иначе - красный.
*)
MODULE Flash;
IMPORT SYSTEM, MSP430;
CONST
REDLED = {0};
GREENLED = {6};
(* регистры порта P1 *)
P1OUT = 21H;
P1DIR = 22H;
FERASE = {1}; (* режим "стереть" *)
FWRITE = {6}; (* режим "записать" *)
PROCEDURE set_bits (mem: INTEGER; bits: SET);
VAR
b: BYTE;
BEGIN
SYSTEM.GET(mem, b);
SYSTEM.PUT8(mem, BITS(b) + bits)
END set_bits;
PROCEDURE clr_bits (mem: INTEGER; bits: SET);
VAR
b: BYTE;
BEGIN
SYSTEM.GET(mem, b);
SYSTEM.PUT8(mem, BITS(b) - bits)
END clr_bits;
(*
стирание и запись флэш-памяти
adr - адрес
value - значение для записи
mode - режим (стереть/записать)
*)
PROCEDURE Write (adr, value: INTEGER; mode: SET);
CONST
(* сторожевой таймер *)
WDTCTL = 0120H;
WDTHOLD = {7};
WDTPW = {9, 11, 12, 14};
(* регистры контроллера флэш-памяти *)
FCTL1 = 0128H;
ERASE = {1};
WRT = {6};
FCTL2 = 012AH;
FN0 = {0};
FN1 = {1};
FN2 = {2};
FN3 = {3};
FN4 = {4};
FN5 = {5};
FSSEL0 = {6};
FSSEL1 = {7};
FCTL3 = 012CH;
LOCK = {4};
FWKEY = {8, 10, 13, 15};
VAR
wdt: SET;
BEGIN
IF (mode = ERASE) OR (mode = WRT) THEN (* проверить заданный режим *)
SYSTEM.GET(WDTCTL, wdt); (* сохранить значение регистра сторожевого таймера *)
SYSTEM.PUT(WDTCTL, WDTPW + WDTHOLD); (* остановить сторожевой таймер *)
SYSTEM.PUT(FCTL2, FWKEY + FSSEL1 + FN0); (* тактовый генератор контроллера флэш-памяти = SMCLK, делитель = 2 *)
SYSTEM.PUT(FCTL3, FWKEY); (* сбросить флаг LOCK *)
SYSTEM.PUT(FCTL1, FWKEY + mode); (* установить режим (записать или стереть) *)
SYSTEM.PUT(adr, value); (* запись *)
SYSTEM.PUT(FCTL1, FWKEY); (* сбросить режим *)
SYSTEM.PUT(FCTL3, FWKEY + LOCK); (* установить LOCK *)
SYSTEM.PUT(WDTCTL, WDTPW + wdt * {0..7}) (* восстановить сторожевой таймер *)
END
END Write;
(* обработчик ошибок *)
PROCEDURE trap (modNum, modName, err, line: INTEGER);
BEGIN
set_bits(P1OUT, REDLED) (* включить красный светодиод *)
END trap;
PROCEDURE main;
CONST
seg_adr = 0FC00H; (* адрес сегмента для стирания и записи (ДОЛЖЕН БЫТЬ СВОБОДНЫМ!) *)
VAR
adr, x, i: INTEGER;
free: RECORD address, size: INTEGER END;
BEGIN
(* инициализация регистров порта P1 *)
SYSTEM.PUT8(P1DIR, REDLED + GREENLED); (* выход *)
(* выключить светодиоды *)
clr_bits(P1OUT, REDLED + GREENLED);
MSP430.SetTrapProc(trap); (* назначить обработчик ошибок *)
ASSERT(seg_adr MOD 512 = 0); (* адрес сегмента должен быть кратным 512 *)
MSP430.GetFreeFlash(free.address, free.size);
(* проверить, свободен ли сегмент *)
ASSERT(free.address <= seg_adr);
ASSERT(seg_adr + 511 <= free.address + free.size);
Write(seg_adr, 0, FERASE); (* стереть сегмент *)
(* записать в сегмент числа 0..255 (256 слов) *)
adr := seg_adr;
FOR i := 0 TO 255 DO
Write(adr, i, FWRITE);
INC(adr, 2)
END;
(* проверить запись *)
adr := seg_adr;
FOR i := 0 TO 255 DO
SYSTEM.GET(adr, x);
ASSERT(x = i); (* если x # i, будет вызван обработчик ошибок *)
INC(adr, 2)
END;
(* если нет ошибок, включить зеленый светодиод *)
set_bits(P1OUT, GREENLED)
END main;
BEGIN
main
END Flash.