Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8096 → Rev 8097

/programs/develop/oberon07/Samples/MSP430/Flash.ob07
0,0 → 1,157
(*
 
Пример для 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.