(* Пример для 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.