Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.  
  3. Пример для LaunchPad MSP-EXP430G2 Rev1.5
  4.  
  5.   Запись флэш-памяти.
  6.   При успешном завершении, включается зеленый светодиод,
  7.   иначе - красный.
  8.  
  9. *)
  10.  
  11. MODULE Flash;
  12.  
  13. IMPORT SYSTEM, MSP430;
  14.  
  15.  
  16. CONST
  17.  
  18.     REDLED   = {0};
  19.     GREENLED = {6};
  20.  
  21.     (* регистры порта P1 *)
  22.     P1OUT = 21H;
  23.     P1DIR = 22H;
  24.  
  25.     FERASE = {1};  (* режим "стереть"  *)
  26.     FWRITE = {6};  (* режим "записать" *)
  27.  
  28.  
  29. PROCEDURE set_bits (mem: INTEGER; bits: SET);
  30. VAR
  31.     b: BYTE;
  32.  
  33. BEGIN
  34.     SYSTEM.GET(mem, b);
  35.     SYSTEM.PUT8(mem, BITS(b) + bits)
  36. END set_bits;
  37.  
  38.  
  39. PROCEDURE clr_bits (mem: INTEGER; bits: SET);
  40. VAR
  41.     b: BYTE;
  42.  
  43. BEGIN
  44.     SYSTEM.GET(mem, b);
  45.     SYSTEM.PUT8(mem, BITS(b) - bits)
  46. END clr_bits;
  47.  
  48.  
  49. (*
  50.     стирание и запись флэш-памяти
  51.     adr   - адрес
  52.     value - значение для записи
  53.     mode  - режим (стереть/записать)
  54. *)
  55. PROCEDURE Write (adr, value: INTEGER; mode: SET);
  56. CONST
  57.     (* сторожевой таймер *)
  58.     WDTCTL = 0120H;
  59.         WDTHOLD  = {7};
  60.         WDTPW    = {9, 11, 12, 14};
  61.  
  62.     (* регистры контроллера флэш-памяти *)
  63.     FCTL1 = 0128H;
  64.         ERASE = {1};
  65.         WRT   = {6};
  66.  
  67.     FCTL2 = 012AH;
  68.         FN0 = {0};
  69.         FN1 = {1};
  70.         FN2 = {2};
  71.         FN3 = {3};
  72.         FN4 = {4};
  73.         FN5 = {5};
  74.         FSSEL0 = {6};
  75.         FSSEL1 = {7};
  76.  
  77.     FCTL3 = 012CH;
  78.         LOCK = {4};
  79.  
  80.     FWKEY = {8, 10, 13, 15};
  81.  
  82. VAR
  83.     wdt: SET;
  84.  
  85. BEGIN
  86.     IF (mode = ERASE) OR (mode = WRT) THEN         (* проверить заданный режим *)
  87.         SYSTEM.GET(WDTCTL, wdt);                   (* сохранить значение регистра сторожевого таймера *)
  88.         SYSTEM.PUT(WDTCTL, WDTPW + WDTHOLD);       (* остановить сторожевой таймер *)
  89.         SYSTEM.PUT(FCTL2, FWKEY + FSSEL1 + FN0);   (* тактовый генератор контроллера флэш-памяти = SMCLK, делитель = 2 *)
  90.         SYSTEM.PUT(FCTL3, FWKEY);                  (* сбросить флаг LOCK *)
  91.         SYSTEM.PUT(FCTL1, FWKEY + mode);           (* установить режим (записать или стереть) *)
  92.         SYSTEM.PUT(adr, value);                    (* запись *)
  93.         SYSTEM.PUT(FCTL1, FWKEY);                  (* сбросить режим *)
  94.         SYSTEM.PUT(FCTL3, FWKEY + LOCK);           (* установить LOCK *)
  95.         SYSTEM.PUT(WDTCTL, WDTPW + wdt * {0..7})   (* восстановить сторожевой таймер *)
  96.     END
  97. END Write;
  98.  
  99.  
  100. (* обработчик ошибок *)
  101. PROCEDURE trap (modNum, modName, err, line: INTEGER);
  102. BEGIN
  103.     set_bits(P1OUT, REDLED) (* включить красный светодиод *)
  104. END trap;
  105.  
  106.  
  107. PROCEDURE main;
  108. CONST
  109.     seg_adr = 0FC00H; (* адрес сегмента для стирания и записи (ДОЛЖЕН БЫТЬ СВОБОДНЫМ!) *)
  110.  
  111. VAR
  112.     adr, x, i: INTEGER;
  113.  
  114.     free: RECORD address, size: INTEGER END;
  115.  
  116. BEGIN
  117.     (* инициализация регистров порта P1 *)
  118.     SYSTEM.PUT8(P1DIR, REDLED + GREENLED);  (* выход *)
  119.  
  120.     (* выключить светодиоды *)
  121.     clr_bits(P1OUT, REDLED + GREENLED);
  122.  
  123.     MSP430.SetTrapProc(trap); (* назначить обработчик ошибок *)
  124.  
  125.     ASSERT(seg_adr MOD 512 = 0); (* адрес сегмента должен быть кратным 512 *)
  126.  
  127.     MSP430.GetFreeFlash(free.address, free.size);
  128.  
  129.     (* проверить, свободен ли сегмент *)
  130.     ASSERT(free.address <= seg_adr);
  131.     ASSERT(seg_adr + 511 <= free.address + free.size);
  132.  
  133.     Write(seg_adr, 0, FERASE); (* стереть сегмент *)
  134.  
  135.     (* записать в сегмент числа 0..255 (256 слов) *)
  136.     adr := seg_adr;
  137.     FOR i := 0 TO 255 DO
  138.         Write(adr, i, FWRITE);
  139.         INC(adr, 2)
  140.     END;
  141.  
  142.     (* проверить запись *)
  143.     adr := seg_adr;
  144.     FOR i := 0 TO 255 DO
  145.         SYSTEM.GET(adr, x);
  146.         ASSERT(x = i); (* если x # i, будет вызван обработчик ошибок *)
  147.         INC(adr, 2)
  148.     END;
  149.  
  150.     (* если нет ошибок, включить зеленый светодиод *)
  151.     set_bits(P1OUT, GREENLED)
  152. END main;
  153.  
  154.  
  155. BEGIN
  156.     main
  157. END Flash.
  158.