Arduino:Примеры/GLCDdiags

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

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Тест памяти и интерфейса 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 }

См.также

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