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. |