Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/GLCDdiags

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Тест памяти и интерфейса GLCD-модуля [1]

Этот пример показывает при помощи Arduino и библиотеки GLCD протестировать память и интерфейс GLCD-модуля. Тесты выполняются с использованием нескольких графиков.

Код

  1.  
  2. /*
  3.  * Тест памяти и интерфейса GLCD-модуля (с графиками)
  4.  *
  5.  * Этот скетч тестирует память и интерфейс GLCD-модуля, а также сообщает
  6.  * о текущей конфигурации библиотеки GLCD (через последовательный порт).
  7.  *
  8.  * Последовательный порт настроен на скорость 9600 бод.
  9.  *
  10.  * Кроме того, он показывает на GLCD-панели несколько графиков,
  11.  * призванных помочь в диагностике того, правильно ли настроены
  12.  * и подключены CS-линии.
  13.  *
  14.  * Память каждого чипа тестируется отдельно.
  15.  * Тесты выполняются начиная с чипа #0.
  16.  * Во время тестирования памяти на GLCD-панели будет поочередно показано
  17.  * несколько графиков.
  18.  *
  19.  * Кроме того, показывается номер чипа и значение координаты X.
  20.  * Если все настроено и работает правильно, чип #0 будет слева, а все
  21.  * последующие чипы – справа.
  22.  *
  23.  * Во время тестирования статус и информация об ошибках будут
  24.  * отправляться через последовательный порт.
  25.  *
  26.  * Этот скетч выполняет несколько разных тестов памяти, но главный тест
  27.  * работает через возрастание. При горизонтальных проходах возрастание
  28.  * будет осуществляться по столбцам (слева направо), а при вертикальных –
  29.  * по страницам (сверху вниз).
  30.  *
  31.  * ПРИМЕЧАНИЕ:
  32.  * Этот скетч – диагностический инструмент, а не пример
  33.  * использования библиотеки. Он использует внутреннюю информацию
  34.  * библиотеки GLCD, которая обычно скетчами не используется.
  35.  * В будущих релизах скетчи, использующие эту информацию,
  36.  * могут работать неправильно.
  37.  */
  38.  
  39.  
  40. #include <glcd.h>
  41. #include "glcd_Buildinfo.h"
  42. #include "include/glcd_io.h"
  43. #include "include/glcd_errno.h"
  44. #include "fonts/SystemFont5x7.h"       // системный шрифт
  45.  
  46. /*
  47.  * Макрос, конвертирующий номер чипа в вертикальные координаты пикселя.
  48.  * x1,y1 это координаты для самого верхнего левого пикселя, а x2,y2 –
  49.  * для самого нижнего левого пикселя.
  50.  */
  51.  
  52. #define chip2x1(chip) ((chip * CHIP_WIDTH) % DISPLAY_WIDTH)
  53. #define chip2y1(chip) (((chip * CHIP_WIDTH)/DISPLAY_WIDTH) * CHIP_HEIGHT)
  54. #define chip2x2(chip) ((chip2x1(chip) + CHIP_WIDTH) >= DISPLAY_WIDTH ? DISPLAY_WIDTH-1 : chip2x1(chip) + CHIP_WIDTH-1)
  55. #define chip2y2(chip) ((chip2y1(chip) + CHIP_HEIGHT) >= DISPLAY_HEIGHT ? DISPLAY_HEIGHT-1 : chip2y1(chip) + CHIP_HEIGHT-1)
  56.  
  57. #include <avr/pgmspace.h>
  58. #define P(name)   static const prog_char name[] PROGMEM   // объявляем статичную строку, которая будет храниться в программной памяти AVR
  59.  
  60. #define MAX_ERRORS 10
  61.  
  62. #ifdef _AVRIO_AVRIO_
  63. #define SerialPrintPINstr(x) \
  64.   _SerialPrintPINstr(x, AVRIO_PIN2AVRPORT(AVRIO_PIN2AVRPIN(x)), AVRIO_PIN2AVRBIT(AVRIO_PIN2AVRPIN(x)))
  65. #else
  66. #define SerialPrintPINstr(x) _SerialPrintPINStr(x)
  67. #endif
  68.  
  69. /*
  70.  * Объявляем в программной памяти строку для горизонтальной линии.
  71.  */
  72. P(hline) =  "--------------------------------------------------------------------\n";
  73.  
  74.  
  75. #define xstr(s) str(s)
  76. #define str(...) #__VA_ARGS__
  77.  
  78. /*
  79.  * Функция для передачи простой закавыченной строки на
  80.  * последовательный порт. Она будет автоматически сохраняться в
  81.  * программной (flash) памяти.
  82.  */
  83.  
  84. #define SerialPrintQ(str) SerialPrintP(PSTR(str))
  85.  
  86. /*
  87.  * Передаем строку из программной памяти на последовательный порт.
  88.  * Также вставляем символ новой строки, потому что последовательный порт
  89.  * работает в «сыром» режиме.
  90.  *
  91.  */
  92.  
  93. void SerialPrintP(const prog_char * str )
  94. {
  95.   char c;
  96.   const prog_char *p = str;
  97.  
  98.   while ((c = pgm_read_byte(p++)))
  99.   {
  100.     if(c == '\n')
  101.       Serial.print('\r');
  102.     Serial.print(c);  
  103.   }
  104. }
  105.  
  106. #ifdef SERIALPRINTF
  107.  
  108. /*
  109.  * Задаем НАСТОЯЩУЮ printf(), потому что у Arduino такой нет.
  110.  *
  111.  * Функция SerialPrintf() автоматически поместит форматирующую строку
  112.  * в программную память AVR.
  113.  *
  114.  */
  115.  
  116. #define SerialPrintf(fmt, ...) _SerialPrintf(PSTR(fmt), ##__VA_ARGS__)
  117.  
  118. extern "C" {
  119.   int serialputc(char c, FILE *fp)
  120.   {
  121.       if(c == '\n')
  122.         Serial.write('\r');
  123.     Serial.write(c);
  124.   }
  125. }
  126.  
  127.  
  128. void _SerialPrintf(const char *fmt, ...)
  129. {
  130. FILE stdiostr;
  131. va_list ap;
  132.  
  133.   fdev_setup_stream(&stdiostr, serialputc, NULL, _FDEV_SETUP_WRITE);
  134.  
  135.   va_start(ap, fmt);
  136.   vfprintf_P(&stdiostr, fmt, ap);
  137.   va_end(ap);
  138. }
  139.  
  140. /*
  141.  * Задаем функцию eprintf() для вывода информации об ошибках.
  142.  * Привязываем ее к функции SerialPrintf(), заданной выше.
  143.  */
  144. #define eprintf(...) SerialPrintf(__VA_ARGS__)
  145.  
  146. #endif //SERIALPRINTF
  147.  
  148.  
  149. /*
  150.  * Функция GlcdPrintf() будет автоматически помещать форматирующую строку
  151.  * в программную память AVR.
  152.  */
  153. #define GlcdPrintf(fmt, ...) GLCD.Printf_P(PSTR(fmt), ##__VA_ARGS__)
  154.  
  155.  
  156. void setup()
  157. {
  158.   Serial.begin(9600);
  159.  
  160. #ifdef CORE_TEENSY
  161.   delay(2000);    // Даем некоторое время на появление USB-соединения.
  162.                   // Плюс еще немного времени на то, чтобы пользователь
  163.                   // запустил монитор порта.
  164.                   // ПРИМЕЧАНИЕ ДЛЯ ПОЛЬЗОВАТЕЛЕЙ Teensy:
  165.                   //    Ждите короткой «вспышки» на иконке монитора порта
  166.                   //    в IDE Arduino. Это значит, что USB-соединение
  167.                   //    появилось, а IDE Arduino заметила плату Teensy.
  168.                   //    Затем кликните на эту иконку, чтобы подключиться
  169.                   //    к виртуальному COM-порту платы Teensy.
  170. #endif
  171.  
  172.   delay(5);    // даем оборудованию время, чтобы загрузиться
  173.   SerialPrintQ("Serial initialized\n");  //  "Последовательное соединение инициализировано\n"
  174. }
  175.  
  176.  
  177. /*
  178.  * Пытаемся показать графическую информацию, которая демонстрирует,
  179.  * правильно ли подключены SC-линии или нет.
  180.  */
  181. void showchipselscreen(void)
  182. {
  183.   /*
  184.    * Рисуем треугольник.
  185.    */
  186.   for(int x = 0; x < GLCD.Width; x++)
  187.   {
  188.      GLCD.DrawVLine( x, 0, map(x, 0, GLCD.Right, 0, GLCD.Bottom));
  189.      delay(50); // небольшая задержка, чтобы определить, не дублируются и не накладываются ли друг на друга CS-линии
  190.   }  
  191.   delay(4000);
  192.   // show chips
  193.   GLCD.ClearScreen();
  194.   for(int chip = 0; chip < glcd_CHIP_COUNT; chip++)
  195.   {
  196.     // Задержка и переменная flash нужны, чтобы определить,
  197.     // не дублируются и не накладываются ли друг на друга CS-линии:
  198.     for(uint8_t flash = 0; flash < 4; flash++)
  199.     {
  200.       GLCD.CursorToXY(chip2x1(chip), chip2y1(chip));
  201.       if(flash & 1)
  202.         GLCD.SetFontColor(BLACK);
  203.       else
  204.         GLCD.SetFontColor(WHITE);
  205.       GLCD.print("Chip:");
  206.       GLCD.print(chip);
  207.       delay(350);
  208.     }
  209.   }
  210.  
  211.   delay(5000);
  212.  
  213.   /*
  214.    * Показываем информацию о версиях и символы формата ASCII.
  215.    */
  216.   GLCD.ClearScreen();
  217.   GLCD.CursorTo(0,0);
  218.   GLCD.print("GLCD   ver ");
  219.   GLCD.println(GLCD_VERSION, DEC);
  220.   GLCD.print("gText  ver ");
  221.   GLCD.println(GTEXT_VERSION, DEC);
  222.   GLCD.print("Device ver ");
  223.   GLCD.println(GLCD_Device, DEC); // не ставим символ новой строки, чтобы не стереть EOL
  224.   for(int i=0; i  < GLCD.Width / GLCD.CharWidth(' '); i++ )
  225.   {
  226.      GLCD.print(char('A' + i)); // показываем символ ASCII
  227.   }
  228.   delay(5000);
  229. }
  230.  
  231. void  loop()
  232. {   // Этот блок будет работать снова и снова.
  233.  
  234. int lcount = 1;
  235. unsigned int glcdspeed, kops, kops_fract;
  236. int status;
  237.  
  238.   while(1)
  239.   {
  240.     /*
  241.      * Перед «общением» с GLCD выгружаем информацию о ее настройках,
  242.      * чтобы затем, собственно, с этим общением не было никаких проблем.
  243.      * Благодаря этому последовательный порт всегда будет иметь доступ
  244.      * к информации о GLCD.
  245.      */
  246.  
  247.     /*
  248.      * Выгружаем информацию о настройках библиотеки GLCD
  249.      * на последовательный порт.
  250.      */
  251.     showGLCDconfig();
  252.  
  253.  
  254.     SerialPrintP(hline);
  255.     SerialPrintQ("Diag Loop: ");    //  "Счетчик циклов"
  256.     Serial.println(lcount);
  257.  
  258.     SerialPrintQ("Initializing GLCD\n");  //  "Инициализация GLCD\n"
  259.     status = GLCD.Init();   // инициализируем библиотеку в режиме рисования
  260.  
  261. #ifndef GLCD_NOINIT_CHECKS
  262.     if(status) // инициализация удалась?
  263.     {
  264.         SerialPrintQ("GLCD initialization Failed: ");  //  "Инициализация GLCD не удалась: "
  265.         switch(status)
  266.         {
  267.                 case GLCD_EBUSY:
  268.                         SerialPrintQ("BUSY wait Timeout");  //  "GLCD занят, таймаут"
  269.                         break;
  270.                 case GLCD_ERESET:
  271.                         SerialPrintQ("RESET wait Timeout");  //  "Сброс, таймаут: "
  272.                         break;
  273.         }
  274.         SerialPrintQ(" (status code: ");    //  "Код статуса: "
  275.         Serial.print(status);
  276.         Serial.println(')');
  277.         goto finished;
  278.     }
  279. #endif
  280.  
  281.  
  282.     GLCD.SelectFont(System5x7, BLACK);
  283.  
  284.  
  285.     SerialPrintQ("Displaying ChipSelect Screens\n");    //  "График подключения CS-линий\n"
  286.     showchipselscreen();
  287.     if( lcdmemtest())
  288.     {
  289.       /*
  290.        * Тесты памяти завершились неуспешно.
  291.        */
  292.       SerialPrintQ("TEST FAILED\n");  //  "ТЕСТ ЗАВЕРШИЛСЯ НЕУСПЕШНО\n: "
  293.     }
  294.     else
  295.     {
  296.       SerialPrintQ("Tests PASSED\n");  //  "ТЕСТ ПРОЙДЕН\n"
  297.  
  298.       /*
  299.        * В конце показываем счетчик циклов.
  300.        */
  301.       GLCD.ClearScreen();
  302.       GLCD.CursorTo(0,0);
  303.       GLCD.print("Diag Loop: ");    //  "Счетчик циклов"
  304.       GLCD.println(lcount);
  305.       GLCD.println("Tests PASSED");  //  "Тесты ПРОЙДЕНЫ"
  306.  
  307.       /*
  308.        * Теперь запускаем тест «скорости» GLCD.
  309.        */
  310.  
  311.       glcdspeed = getglcdspeed();
  312.       /*
  313.        * Рассчитываем скорость в 1000 операций в секунду.
  314.        * Чтобы получить фактическое значение, делим
  315.        * возвращенное значение на 100.
  316.        */
  317.  
  318.       kops = glcdspeed/100;
  319.       kops_fract = glcdspeed %100;
  320.  
  321.       GLCD.print("K SetDot/s: ");   //  "Тысяч нарисованных пикселей в секунду: "
  322.       GLCD.print(kops);
  323.       GLCD.print(".");
  324.       GLCD.println(kops_fract);
  325.  
  326.  
  327.       SerialPrintQ("GLCD.SetDot() speed (K ops/sec): ");  //  "Скорость GLCD.SetDot() (тысяч операций в секунду): "
  328.       Serial.print(kops);
  329.       SerialPrintQ(".");
  330.       Serial.println(kops_fract);
  331.     }
  332.  
  333. finished:
  334.  
  335.     delay(5000);
  336.     lcount++;
  337.   }
  338. }
  339.  
  340.  
  341. uint8_t lcdmemtest(void)
  342. {
  343.   uint8_t errors = 0;
  344.  
  345.   SerialPrintQ("Walking 1s data test\n");    //  "Тестирование одной (пробной) ячейки памяти\n"
  346.  
  347.   errors = lcdw1test();
  348.   if(errors)
  349.     return(errors);
  350.  
  351.   SerialPrintQ("Wr/Rd Chip Select Test\n");  //  "Тестирование записи/чтения номера чипа\n"
  352.  
  353.   errors = lcdrwseltest();
  354.   if(errors)
  355.     return(errors);
  356.  
  357.   GLCD.ClearScreen();
  358.  
  359.   SerialPrintQ("Testing GLCD memory pages\n");  //  "Тестирование страниц памяти GLCD-панели\n"
  360.  
  361.   for(uint8_t chip = 0; chip < glcd_CHIP_COUNT; chip++)
  362.   {
  363.     uint8_t col = chip2x1(chip);
  364.     uint8_t ecol = chip2x2(chip);
  365.  
  366.     if(col >= CHIP_WIDTH)
  367.       GLCD.CursorToXY(0,chip2y1(chip));
  368.     else
  369.       GLCD.CursorToXY(CHIP_WIDTH,chip2y1(chip));
  370.     GLCD.print("Chip:");
  371.     GLCD.print((int)chip);
  372.  
  373.     /*
  374.      * Исходим из того, что высота шрифта – 8 пикселей.
  375.      */
  376.     if(col >= CHIP_WIDTH)
  377.       GLCD.CursorToXY(0,chip2y1(chip)+8);
  378.     else
  379.       GLCD.CursorToXY(CHIP_WIDTH,chip2y1(chip)+8);
  380.     GLCD.print((int)col);
  381.     GLCD.print('-');
  382.     GLCD.print((int)ecol);
  383.     delay(500);
  384.  
  385. //  SerialPrintf("Horizontal Page Test Chip: %d Pixels %d-%d\n", chip, col, ecol);  //  "Тестирование с горизонтальным проходом по страницам"
  386.  
  387.     SerialPrintQ("Horizontal Page Test Chip: ");  //  "Тестирование с горизонтальным проходом по страницам"
  388.     Serial.print((int)chip);
  389.     SerialPrintQ(" Pixels ");
  390.     Serial.print((int)col);
  391.     Serial.print('-');
  392.     Serial.println((unsigned int)ecol);
  393.  
  394.     errors += lcdhpagetest(col, ecol, chip2y1(chip)/8, (chip2y2(chip)+1)/8 - 1, 0, 255);
  395.  
  396.  
  397. //  SerialPrintf("Vertical Page Test Chip: %d Pixels %d-%d\n", chip, col, ecol);  //  "Тестирование с вертикальным проходом по страницам"
  398.  
  399.     SerialPrintQ("Vertical Page Test Chip: ");  //  "Тестирование с вертикальным проходом по страницам"
  400.     Serial.print((int)chip);
  401.     SerialPrintQ(" Pixels ");
  402.     Serial.print((int)col);
  403.     Serial.print('-');
  404.     Serial.println((int)ecol);
  405.  
  406.     errors += lcdvpagetest(col, ecol, chip2y1(chip)/8, (chip2y2(chip)+1)/8 - 1, 0, 255);
  407.     GLCD.ClearScreen();
  408.  
  409.     col += CHIP_WIDTH;
  410.     ecol += CHIP_WIDTH;
  411.     if(ecol > GLCD.Right)
  412.       ecol = GLCD.Right;
  413.   }
  414.  
  415.  
  416.   GLCD.CursorTo(0,0);
  417.   GLCD.print("Full Display");
  418.   GLCD.CursorTo(0,1);
  419.   GLCD.print((int)0);
  420.   GLCD.print('-');
  421.   GLCD.print((int)GLCD.Right);
  422.   delay(1000);
  423.  
  424. //SerialPrintf("Full Module Horizontal Page Test:Pixels %d-%d\n",  0, GLCD.Right);
  425.  
  426.   SerialPrintQ("Full Module Horizontal Page Test:Pixels ");
  427.   Serial.print(0);
  428.   Serial.print('-');
  429.   Serial.println((int)GLCD.Right);
  430.  
  431.   errors += lcdhpagetest(0, GLCD.Right, 0, GLCD.Bottom/8, 0, 255);
  432.  
  433. //SerialPrintf("Full Module Vertical Page Test:Pixels %d-%d\n",  0, GLCD.Right);
  434.  
  435.   SerialPrintQ("Full Module Vertical Page Test:Pixels ");
  436.   Serial.print(0);
  437.   Serial.print('-');
  438.   Serial.println((int)GLCD.Right);
  439.  
  440.   errors += lcdvpagetest(0, GLCD.Right, 0, GLCD.Bottom/8, 0, 255);
  441.  
  442.   GLCD.ClearScreen();
  443.  
  444.   return(errors);
  445. }
  446.  
  447. /*
  448.  * Проходимся по одной ячейке памяти, чтобы понять работают ли
  449.  * запись и считывание.
  450.  */
  451.  
  452. uint8_t
  453. lcdw1test(void)
  454. {
  455.   uint8_t errors = 0;
  456.   uint8_t rdata;
  457.  
  458.   for(uint8_t pat = 1;  pat != 0; pat <<= 1)
  459.   {
  460.     GLCD.GotoXY(0,0);
  461.     GLCD.WriteData(pat);
  462.     GLCD.GotoXY(0,0);
  463.     rdata = GLCD.ReadData();
  464.  
  465.     if(rdata != pat)
  466.     {
  467. //    eprintf(" Compare error: %x != %x\n", rdata, pat);
  468.       SerialPrintQ(" Compare error: ");
  469.       Serial.print((unsigned int)rdata, HEX);
  470.       SerialPrintQ(" != ");
  471.       Serial.println((unsigned int)pat, HEX);
  472.  
  473.       errors++;
  474.     }
  475.   }
  476.   return(errors);
  477. }
  478.  
  479. /*
  480.  * Тест CS-линии с записью/считыванием памяти чипов.
  481.  * Этот тест пытается определить проблемы с CS-линиями, записывая номер
  482.  * чипа в самую младшую страницу памяти каждого чипа. Это выполняется и
  483.  * при возрастании, и при убывании. Это делается два раза, поскольку если
  484.  * CS-линия задана неправильно, то запись можно совершить на несколько
  485.  * чипов одновременно. Чтобы избежать этого, запись нужно проделать два
  486.  * раза – сначала идя от младшего адреса к старшему (возрастание), а
  487.  * потом от старшего к младшему (убывание).
  488.  */
  489.  
  490. uint8_t
  491. lcdrwseltest()
  492. {
  493.   uint8_t errors = 0;
  494.   uint8_t rdata; // считываем данные
  495.  
  496.  
  497.   for(uint8_t chip = 0; chip < glcd_CHIP_COUNT; chip++)
  498.   {
  499.     GLCD.GotoXY(chip2x1(chip), chip2y1(chip));
  500.     GLCD.WriteData(chip);
  501.   }
  502.   for(uint8_t chip = 0; chip < glcd_CHIP_COUNT; chip++)
  503.   {
  504.     GLCD.GotoXY(chip2x1(chip), chip2y1(chip));
  505.     rdata = GLCD.ReadData();
  506.     if(rdata != chip)
  507.     {
  508. //    eprintf(" Compare error: chip:%d %x != %x\n", chip, rdata, chip);
  509.       SerialPrintQ(" Compare error: chip:");
  510.       Serial.print((int)chip);
  511.       Serial.print(' ');
  512.       Serial.print((unsigned int)rdata, HEX);
  513.       SerialPrintQ(" != ");
  514.       Serial.println((unsigned int)chip, HEX);
  515.       errors++;
  516.     }
  517.   }
  518.  
  519.   for(int chip = glcd_CHIP_COUNT - 1; chip >= 0; chip--)
  520.   {
  521.     GLCD.GotoXY(chip2x1(chip), chip2y1(chip));
  522.     GLCD.WriteData(chip);
  523.   }
  524.   for(int chip = glcd_CHIP_COUNT - 1; chip >= 0; chip--)
  525.   {
  526.     GLCD.GotoXY(chip2x1(chip), chip2y1(chip));
  527.     rdata = GLCD.ReadData();
  528.     if(rdata != chip)
  529.     {
  530. //    eprintf(" Compare error: chip:%d  %x != %x\n", chip, rdata, chip);
  531.       SerialPrintQ(" Compare error: chip:");
  532.       Serial.print((int)chip);
  533.       Serial.print(' ');
  534.       Serial.print((unsigned int)rdata, HEX);
  535.       SerialPrintQ(" != ");
  536.       Serial.println((unsigned int)chip, HEX);
  537.       errors++;
  538.     }
  539.   }
  540.  
  541.   return(errors);
  542. }
  543.  
  544.  
  545. /*
  546.  * Поочередно проходим по всем ячейкам памяти.
  547.  *
  548.  * Проход будет осуществляться горизонтально. Начальное значение – sval,
  549.  * конечное значение – eval. Значение sval записывается в стартовую
  550.  * ячейку «x», а затем (по мере прохода через все тестируемые ячейки)
  551.  * постепенно увеличивается. Когда в текущем ряду/странице достигается
  552.  * максимальное значение «x», запись начинает выполняться
  553.  * в следующем ряду/странице.
  554.  *
  555.  * Кроме того, все эти значения будут считываться и сравниваться с
  556.  * ожидаемыми значениями.
  557.  *
  558.  * Затем процесс начинается снова посредством постепенного увеличения
  559.  * стартового значения. Он повторяется, пока стартовое значение не
  560.  * достигнет конечного значения.
  561.  *
  562.  * Переход от одной ячейки к другой выполняется по формуле evel-sval+1.
  563.  *
  564.  * Если sval равно «0», а eval равно «255», будут протестированы
  565.  * каждая ячейка и каждое значение.
  566.  *
  567.  */
  568.  
  569.  
  570. int lcdhpagetest(uint8_t x1, uint8_t x2, uint8_t spage, uint8_t epage, uint8_t sval, uint8_t eval)
  571. {
  572.   uint8_t x;
  573.   uint8_t data;
  574.   uint8_t rdata;
  575.   uint8_t page;
  576.   uint8_t errors = 0;
  577.  
  578.   /*
  579.    * Выполняем тестовый проход по памяти, постепенно увеличивая
  580.    * значение sval, а затем удаляя его.
  581.    */
  582.   do
  583.   {
  584.     /*
  585.      * Поочередно проходя по столбцам (значения x), осуществляем запись
  586.      * во все страницы памяти GLCD.
  587.      */
  588.  
  589.     data = sval;
  590.     for(page = spage; page <= epage; page++)
  591.     {
  592.  
  593.       GLCD.GotoXY(x1, page * 8);
  594.       for(x = x1; x <= x2; x++)
  595.       {
  596.         /*
  597.             * Функция GotoXY() намеренно не выполняется здесь, в цикле,
  598.             * чтобы девайс смог выгрузить внутренний адрес. Это обеспечит,
  599.             * что код для GLCD и оборудование будут должным образом
  600.             * отслеживать друг друга.
  601.          */
  602.         GLCD.WriteData(data);
  603.         data++;
  604.       }
  605.     }
  606.  
  607.     /*
  608.      * Теперь идем обратно и проверяем страницы.
  609.      */
  610.  
  611.     data = sval;
  612.     for(page = spage; page <= epage; page++)
  613.     {
  614.  
  615.       for(x = x1; x<= x2; x++)
  616.       {
  617.         /*
  618.          * При считывании автоматическое увеличение X не выполняется.
  619.          */
  620.         GLCD.GotoXY(x, page * 8);
  621.         rdata = GLCD.ReadData();
  622.  
  623.         if(data != rdata)
  624.         {
  625. //        eprintf(" Verify error: (%d,%d) %x!=%x\n", x, spage*8, data, rdata);
  626.           SerialPrintQ(" Verify error: (");
  627.           Serial.print((unsigned int) x);
  628.           Serial.print(',');
  629.           Serial.print((unsigned int) (spage*8));
  630.           SerialPrintQ(") ");
  631.           Serial.print((unsigned int)data, HEX);
  632.           SerialPrintQ("!=");
  633.           Serial.println((unsigned int)rdata, HEX);
  634.  
  635.           if(++errors > MAX_ERRORS)
  636.             return(errors);
  637.         }
  638.         data++;
  639.       }
  640.     }
  641.   }
  642.   while(sval++ != eval);
  643.   return(0);
  644. }
  645.  
  646. /*
  647.  * Поочередно проходим по всем ячейкам памяти.
  648.  *
  649.  * Проход будет осуществляться вертикально. Начальное значение – sval,
  650.  * конечное значение – eval. Значение sval записывается в стартовую
  651.  * ячейку «x», а затем (по мере прохода через все тестируемые страницы)
  652.  * постепенно увеличивается. Когда достигается максимальный ряд/страница
  653.  * запись продолжается на следующем.
  654.  *
  655.  * Кроме того, все эти значения будут считываться и сравниваться с
  656.  * ожидаемыми значениями.
  657.  *
  658.  * Затем процесс начинается снова посредством постепенного увеличения
  659.  * стартового значения. Он повторяется, пока стартовое значение не
  660.  * достигнет конечного значения.
  661.  *
  662.  * В результате тестируется каждая ячейка памяти – посредством
  663.  * постепенного увеличения значения по формуле evel-sval+1.
  664.  *
  665.  * Если sval равно «0», а eval равно «255», будут протестированы
  666.  * каждая ячейка и каждое значение.
  667.  */
  668.  
  669.  
  670. int lcdvpagetest(uint8_t x1, uint8_t x2, uint8_t spage, uint8_t epage, uint8_t sval, uint8_t eval)
  671. {
  672.   uint8_t x;
  673.   uint8_t data;
  674.   uint8_t rdata;
  675.   uint8_t page;
  676.   uint8_t errors = 0;
  677.  
  678.   /*
  679.    * Выполняем тестовый проход по памяти, постепенно увеличивая
  680.    * значение sval, а затем удаляя его.
  681.    */
  682.   do
  683.   {
  684.     /*
  685.      * Поочередно проходя по столбцам (значения x), осуществляем запись
  686.      * во все страницы памяти GLCD.
  687.      */
  688.  
  689.     data = sval;
  690.     for(x = x1; x <= x2; x++)
  691.     {
  692.       for(page = spage; page <= epage; page++)
  693.       {
  694.         GLCD.GotoXY(x, page * 8);
  695.         GLCD.WriteData(data);
  696.         data++;
  697.       }
  698.     }
  699.  
  700.     /*
  701.      * Теперь идем обратно и проверяем страницы.
  702.      */
  703.  
  704.     data = sval;
  705.     for(x = x1; x<= x2; x++)
  706.     {
  707.       for(page = spage; page <= epage; page++)
  708.       {
  709.         GLCD.GotoXY(x, page * 8);
  710.         rdata = GLCD.ReadData();
  711.  
  712.         if(data != rdata)
  713.         {
  714. //        eprintf(" Verify error: (%d,%d) %x!=%x\n", x, spage*8, data, rdata);
  715.  
  716.           SerialPrintQ(" Verify error: (");
  717.           Serial.print((unsigned int) x);
  718.           Serial.print(',');
  719.           Serial.print((unsigned int) (spage*8));
  720.           SerialPrintQ(") ");
  721.           Serial.print((unsigned int)data, HEX);
  722.           SerialPrintQ("!=");
  723.           Serial.println((unsigned int)rdata, HEX);
  724.  
  725.           if(++errors > MAX_ERRORS)
  726.             return(errors);
  727.         }
  728.         data++;
  729.       }
  730.     }
  731.   }
  732.   while(sval++ != eval);
  733.   return(0);
  734. }
  735.  
  736. /*
  737.  * Выгружаем информацию о настройках GLCD на последовательный порт.
  738.  */
  739.  
  740. void showGLCDconfig(void)
  741. {
  742. #ifdef ARDUINO
  743.   SerialPrintP(hline);
  744.   SerialPrintQ("Reported Arduino Revision: ");  //  "Версия Arduino: "
  745.   Serial.print(ARDUINO/100);
  746.   Serial.print('.');
  747.   Serial.println(ARDUINO%100);
  748. #endif
  749.   SerialPrintP(hline);
  750.   SerialPrintQ("GLCD Lib Configuration: glcd ver: ");  //  "Версия библиотеки GLCD: "
  751.   Serial.print(GLCD_VERSION);
  752.   SerialPrintQ(" glcd_Device ver: ");  //  "Версия GLCD-панели: "
  753.   Serial.print(GLCD_Device);
  754.   SerialPrintQ(" gText ver: ");  //  "Версия gText: "
  755.   Serial.println(GTEXT_VERSION);
  756. #ifdef GLCD_GLCDLIB_DATESTR
  757.   SerialPrintQ("GLCD Lib build date: ");  //  "Дата создания билда библиотеки GLCD: "
  758.   SerialPrintQ(GLCD_GLCDLIB_DATESTR);
  759.   Serial.println();
  760. #endif
  761. #ifdef GLCD_GLCDLIB_BUILDSTR
  762.   SerialPrintQ("GLCD Lib build number: ");  //  "Номер билда библиотеки GLCD: "
  763.   SerialPrintQ(GLCD_GLCDLIB_BUILDSTR);
  764.   Serial.println();
  765. #endif
  766.  
  767. /*
  768.  * Используем ifdef, чтобы показать файлы с ручной,
  769.  * а не автоматической настройкой.
  770.  */
  771.  
  772. #ifdef glcd_ConfigName
  773.   SerialPrintQ("Config File:");  //  "Конфигурационный файл: "
  774.   SerialPrintQ(glcd_ConfigName);
  775. #else
  776.   SerialPrintQ("Panel Configuration:");  //  "Настройки GLCD-панели: "
  777.   SerialPrintQ(glcd_PanelConfigName);
  778.   Serial.println();
  779.   SerialPrintQ("Pin Configuration:");  //  "Конфигурация контактов: "
  780.   SerialPrintQ(glcd_PinConfigName);
  781. #endif
  782.   Serial.println();
  783.   SerialPrintP(hline);
  784.  
  785.   SerialPrintQ("GLCD:");
  786.   SerialPrintQ(glcd_DeviceName);
  787.  
  788. //SerialPrintf("DisplayWidth:%d DisplayHeight:%d\n", GLCD.Width, GLCD.Height);
  789.   SerialPrintQ(" DisplayWidth:");
  790.   Serial.print((int)GLCD.Width);
  791.   SerialPrintQ(" DisplayHeight:");
  792.   Serial.println((int)GLCD.Height);
  793.  
  794. //SerialPrintf("Chips:%d", glcd_CHIP_COUNT);
  795.   SerialPrintQ("Chips:");  //  "Чипы: "
  796.   Serial.print(glcd_CHIP_COUNT);
  797.  
  798.  
  799. //SerialPrintf(" ChipWidth:%3d ChipHeight:%2d\n", CHIP_WIDTH, CHIP_HEIGHT);
  800.   SerialPrintQ(" ChipWidth:");  //  " Ширина чипа:"
  801.   Serial.print(CHIP_WIDTH);
  802.   SerialPrintQ(" ChipHeight:");  //  "Высота чипа:"
  803.   Serial.println(CHIP_HEIGHT);
  804.  
  805. #ifdef glcdCSEL1
  806.   SerialPrintQ(" CSEL1:");
  807.   SerialPrintPINstr(glcdCSEL1);
  808. #endif
  809. #ifdef glcdCSEL2
  810.   SerialPrintQ(" CSEL2:");
  811.   SerialPrintPINstr(glcdCSEL2);
  812. #endif
  813. #ifdef glcdCSEL3
  814.   SerialPrintQ(" CSEL3:");
  815.   SerialPrintPINstr(glcdCSEL3);
  816. #endif
  817. #ifdef glcdCSEL4
  818.   SerialPrintQ(" CSEL4:");
  819.   SerialPrintPINstr(glcdCSEL4);
  820. #endif
  821.  
  822. #if defined(glcdCSEL1) || defined(glcdCSEL2) || defined(glcdCSEL3) || defined(glcdCSEL4)
  823.   Serial.println();
  824. #endif
  825.  
  826.  
  827. #ifdef glcdRES
  828.   SerialPrintQ(" RES:");
  829.   SerialPrintPINstr(glcdRES);
  830. #endif
  831.   SerialPrintQ(" RW:");
  832.   SerialPrintPINstr(glcdRW);
  833.  
  834.   SerialPrintQ(" DI:");
  835.   SerialPrintPINstr(glcdDI);
  836.  
  837. #ifdef glcdEN
  838.   SerialPrintQ(" EN:");
  839.   SerialPrintPINstr(glcdEN);
  840. #endif
  841.  
  842. #ifdef glcdE1
  843.   SerialPrintQ(" E1:");
  844.   SerialPrintPINstr(glcdE1);
  845. #endif
  846. #ifdef glcdE2
  847.   SerialPrintQ(" E2:");
  848.   SerialPrintPINstr(glcdE2);
  849. #endif
  850.  
  851.   Serial.println();
  852.  
  853. //  SerialPrintf(" D0:%s", GLCDdiagsPIN2STR(glcdData0Pin));
  854.   SerialPrintQ(" D0:");
  855.   SerialPrintPINstr(glcdData0Pin);
  856.  
  857.   SerialPrintQ(" D1:");
  858.   SerialPrintPINstr(glcdData1Pin);
  859.  
  860.   SerialPrintQ(" D2:");
  861.   SerialPrintPINstr(glcdData2Pin);
  862.  
  863.   SerialPrintQ(" D3:");
  864.   SerialPrintPINstr(glcdData3Pin);
  865.  
  866.   Serial.println();
  867.  
  868.   SerialPrintQ(" D4:");
  869.   SerialPrintPINstr(glcdData4Pin);
  870.  
  871.   SerialPrintQ(" D5:");
  872.   SerialPrintPINstr(glcdData5Pin);
  873.  
  874.   SerialPrintQ(" D6:");
  875.   SerialPrintPINstr(glcdData6Pin);
  876.  
  877.   SerialPrintQ(" D7:");
  878.   SerialPrintPINstr(glcdData7Pin);
  879.  
  880.   Serial.println();
  881.  
  882. //  SerialPrintf("Delays: tDDR:%d tAS:%d tDSW:%d tWH:%d tWL: %d\n",
  883. //  GLCD_tDDR, GLCD_tAS, GLCD_tDSW, GLCD_tWH, GLCD_tWL);
  884.  
  885.   SerialPrintQ("Delays: tDDR:");
  886.   Serial.print(GLCD_tDDR);
  887.   SerialPrintQ(" tAS:");
  888.   Serial.print(GLCD_tAS);
  889.   SerialPrintQ(" tDSW:");
  890.   Serial.print(GLCD_tDSW);
  891.   SerialPrintQ(" tWH:");
  892.   Serial.print(GLCD_tWH);
  893.   SerialPrintQ(" tWL:");
  894.   Serial.println(GLCD_tWL);
  895.  
  896.  
  897. #ifdef glcd_CHIP0
  898.   SerialPrintQ("ChipSelects:");
  899.   SerialPrintQ(" CHIP0:(");
  900.   SerialPrintQ(xstr(glcd_CHIP0));
  901.   SerialPrintQ(")");
  902. #endif
  903. #ifdef glcd_CHIP1
  904.   SerialPrintQ(" CHIP1:(");
  905.   SerialPrintQ(xstr(glcd_CHIP1));
  906.   SerialPrintQ(")");
  907. #endif
  908. #ifdef glcd_CHIP2
  909.   SerialPrintQ(" CHIP2:(");
  910.   SerialPrintQ(xstr(glcd_CHIP2));
  911.   SerialPrintQ(")");
  912. #endif
  913. #ifdef glcd_CHIP3
  914.   SerialPrintQ(" CHIP3:(");
  915.   SerialPrintQ(xstr(glcd_CHIP3));
  916.   SerialPrintQ(")");
  917. #endif
  918.  
  919. #ifdef glcd_CHIP0
  920.   Serial.println();
  921. #endif
  922.  
  923.  
  924.  
  925. #ifdef _AVRIO_AVRIO_
  926.   /*
  927.    * Показывает Show AVRIO GLCD data mode
  928.    *
  929.    * Требует серьезно повозиться в AVRIO.
  930.    */
  931.  
  932.   SerialPrintQ("Data mode: ");  //  "Режим данных: "
  933.   /*
  934.    * Сначала проверяем полный 8-битный режим.
  935.    *
  936.    */
  937.   if(AVRDATA_8BIT(glcdData0Pin, glcdData1Pin, glcdData2Pin, glcdData3Pin,
  938.   glcdData4Pin, glcdData5Pin, glcdData6Pin, glcdData7Pin))
  939.   {
  940.     /*
  941.      * Полный 8-битный режим.
  942.      */
  943.     SerialPrintQ("byte\n");
  944.   }
  945.   else
  946.   {
  947.     SerialPrintQ("\n d0-d3:");
  948.     if(AVRDATA_4BITHI(glcdData0Pin, glcdData1Pin, glcdData2Pin, glcdData3Pin) ||
  949.       AVRDATA_4BITLO(glcdData0Pin, glcdData1Pin, glcdData2Pin, glcdData3Pin))
  950.     {
  951.       SerialPrintQ("nibble mode");  //  "полубайтный режим"
  952. #ifndef GLCD_ATOMIC_IO
  953.       SerialPrintQ("-Non-Atomic");  //  "-неатомарный"
  954. #else
  955.       SerialPrintQ("-disabled"); // теперь пользователь знает, что AVRIO отключает полубайты, когда находится в атомарном режиме
  956. #endif
  957.     }
  958.     else
  959.     {
  960.       SerialPrintQ("bit i/o");
  961.     }
  962.  
  963.     SerialPrintQ("\n d4-d7:");
  964.  
  965.     if(AVRDATA_4BITHI(glcdData4Pin, glcdData5Pin, glcdData6Pin, glcdData7Pin) ||
  966.       AVRDATA_4BITLO(glcdData4Pin, glcdData5Pin, glcdData6Pin, glcdData7Pin))
  967.     {
  968.       SerialPrintQ("nibble mode");  //  "полубайтный режим"
  969. #ifndef GLCD_ATOMIC_IO
  970.       SerialPrintQ("-Non-Atomic");  //  "-неатомарный"
  971. #else
  972.       SerialPrintQ("-disabled"); // теперь пользователь знает, что AVRIO отключает полубайты, когда находится в атомарном режиме
  973. #endif
  974.     }
  975.     else
  976.     {
  977.       SerialPrintQ("bit i/o");
  978.     }
  979.     Serial.println();
  980.   }
  981.  
  982. #endif // _AVRIO_AVRIO_
  983.  
  984.   /*
  985.    * Показываем рендеринг шрифта:
  986.    */
  987.  
  988. #ifdef GLCD_OLD_FONTDRAW
  989.   SerialPrintQ("Text Render: ");  //  "Рендер шрифта: "
  990.   SerialPrintQ("OLD\n");
  991. #endif
  992.  
  993.   /*
  994.    * Если отключено, не показываем скроллинг вниз.
  995.    */
  996.  
  997. #ifdef GLCD_NO_SCROLLDOWN
  998.   SerialPrintQ("NO Down Scroll\n");  //  "Скроллинг вниз отключен"
  999. #endif
  1000.  
  1001.   /*
  1002.    * Если включено, показываем, кэш считывания.
  1003.    */
  1004. #ifdef GLCD_READ_CACHE
  1005.   SerialPrintQ("READ CACHE enabled\n");  //  "КЭШ СЧИТЫВАНИЯ включен\n"
  1006. #endif
  1007.  
  1008.  
  1009. }
  1010.  
  1011. #ifdef _AVRIO_AVRIO_
  1012. /*
  1013.  * AVRIO-версия строки контакта также содержит AVR-порт и номер контакта.
  1014.  * В итоге получается формат PIN_Pb, где «P» – это порт A-Z,
  1015.  * а «b» – это порт 0-7.
  1016.  */
  1017. void
  1018. _SerialPrintPINstr(uint8_t pin, uint8_t avrport, uint8_t avrbit)
  1019. {
  1020.  
  1021.   /*
  1022.    * Проверяем, используется pin# (Arduino) или #s (AVRPIN).
  1023.    */
  1024.   if(pin >= AVRIO_PIN(AVRIO_PORTA, 0))
  1025.   {
  1026.    
  1027. //  SerialPrintf("0x%x", pin);
  1028.     /*
  1029.      * Если используется #s (AVRPIN), печатаем номер контакта
  1030.      * в шестнадцатеричном значении.
  1031.      */
  1032.     SerialPrintQ("0x");
  1033.     Serial.print(pin,HEX);
  1034.   }
  1035.   else
  1036.   {
  1037. //  SerialPrintf("%d", pin);
  1038.     Serial.print(pin,DEC);
  1039.   }
  1040.  
  1041. //SerialPrintf("(PIN_%c%d)", pin, 'A'-AVRIO_PORTA+avrport, avrbit);
  1042.  
  1043.   SerialPrintQ("(PIN_");
  1044.   Serial.print((char)('A' - AVRIO_PORTA+avrport));
  1045.   Serial.print((int)avrbit);
  1046.   Serial.print(')');
  1047.  
  1048. }
  1049. #else
  1050. void
  1051. _SerialPrintPINstr(uint16_t pin)
  1052. {
  1053.   Serial.print((int) pin);
  1054. }
  1055. #endif
  1056.  
  1057. /*
  1058.  * Эта функция возвращает составную «скорость» GLCD.
  1059.  * Она возвращает скорость SetDot() в 1/10 операций в секунду.
  1060.  * То есть она возвращает количество вызовов функции SetDot(),
  1061.  * но поделенное на 10.
  1062.  */
  1063.  
  1064. uint16_t
  1065. getglcdspeed()
  1066. {
  1067. uint16_t iter = 0;
  1068. unsigned long startmillis;
  1069.  
  1070.   startmillis = millis();
  1071.  
  1072.   while(millis() - startmillis < 1000) // цикл будет продолжаться секунду
  1073.   {
  1074.     /*
  1075.      * Делаем 10 операций, чтобы минимизировать эффект от цикла
  1076.      * и вызова millis().
  1077.      *
  1078.      * ПРИМЕЧАНИЕ: Координаты пикселя были выбраны специально, чтобы для
  1079.      * каждого вызова SetDot() нужно было задать столбец и страницу.
  1080.      * Смысл в том, чтобы показать скорость GLCD, т.к. каждый вызов
  1081.      * функции SetDot() проделывает следующие операции:
  1082.      * - задает страницу
  1083.      * - задает столбец
  1084.      * - считывает байт (фиктивное считывание)
  1085.      * - считывает байт (настоящее считывание)
  1086.      * - задает столбец (для записи)
  1087.      * - записывает байт
  1088.      */
  1089.  
  1090.     GLCD.SetDot(GLCD.Right, GLCD.Bottom, WHITE);
  1091.     GLCD.SetDot(GLCD.Right-1, GLCD.Bottom-9, WHITE);
  1092.     GLCD.SetDot(GLCD.Right, GLCD.Bottom, WHITE);
  1093.     GLCD.SetDot(GLCD.Right-1, GLCD.Bottom-9, WHITE);
  1094.     GLCD.SetDot(GLCD.Right, GLCD.Bottom, WHITE);
  1095.     GLCD.SetDot(GLCD.Right-1, GLCD.Bottom-9, WHITE);
  1096.     GLCD.SetDot(GLCD.Right, GLCD.Bottom, WHITE);
  1097.     GLCD.SetDot(GLCD.Right-1, GLCD.Bottom-9, WHITE);
  1098.     GLCD.SetDot(GLCD.Right, GLCD.Bottom, WHITE);
  1099.     GLCD.SetDot(GLCD.Right-1, GLCD.Bottom-9, WHITE);
  1100.     iter++;
  1101.   }
  1102.  
  1103.   return(iter);
  1104.  
  1105. }

См.также

Внешние ссылки

  1. glcd-v3-20111205.zip