This package contains a simple test of tests for various elements of the SmartBoard hardware, which is a simple baseboard designed for easy embedding. It is able to run both a semi-automatic test suite as well as allow interactive testing.
Dependencies: EthernetNetIf NTPClient_NetServices mbed
SmartBoard_Tester.cpp
00001 /// @file SmartBoard_Tester.cpp is the simple test framework 00002 /// 00003 /// This file contains the startup, interactive, and test code 00004 /// to evaluate the SmartBoard baseboard. 00005 /// 00006 /// @note Copyright © 2011 by Smartware Computing, all rights reserved. 00007 /// This software may be used to derive new software, as long as 00008 /// this copyright statement remains in the source file. 00009 /// @author David Smart 00010 /// 00011 #include "mbed.h" 00012 #include "SmartBoard.h" 00013 #include "ShowTime.h" 00014 #include "EthernetNetIf.h" 00015 #include "NTPClient.h" 00016 #include "SDFileSystem.h" 00017 #include "MSCFileSystem.h" 00018 #include "Watchdog.h" 00019 00020 extern "C" void HardFault_Handler() { 00021 printf("Hard Fault!\n"); 00022 while (1); 00023 } 00024 00025 Watchdog wdt; 00026 00027 Serial pc(USBTX, USBRX); ///!< Used as the console for interactively reporting progress 00028 00029 const char * TicTocServer = "ntp.okstate.edu"; ///!< time server since it is closer than "0.uk.pool.ntp.org" 00030 const int tzOffsetHr = -6; ///!< time zone offset hours to print time in local time 00031 const int tzOffsetMin = 0; ///!< time zone offset minutes to print time in local time 00032 00033 void LED_Tests(void); 00034 void PWM_Tests(void); 00035 void AnalogIn_Tests(void); 00036 void RTC_Tests(void); 00037 void RTC_Set(void); 00038 void MicroSD_Tests(void); 00039 void RS_232_Tests(void); 00040 void CAN_Tests(void); 00041 void Ethernet_Tests(void); 00042 void USBHost_Tests(void); 00043 void FileSystem_Tests(void); 00044 00045 /// TestVector will execute a given test, based on the parameter 00046 /// 00047 /// It can show the list of available commands, as for an interactive 00048 /// test session, or it can simply execute the chosen test. This is 00049 /// used for both the automated testing and the interactive testing, 00050 /// so a couple of the commands for interactive would not be used 00051 /// for the automated testing. 00052 /// '?' causes it to display the available commands. 00053 /// 00054 /// @param i contains the single character value indicating the operation 00055 /// to perform. 00056 /// @returns false if the input paramter was 'X'. 00057 /// @returns true if the input parameters was not 'X'. 00058 /// 00059 bool TestVector(int i) { 00060 bool r = true; ///!< expect to return true 00061 00062 switch (i) { 00063 default: 00064 case '?': 00065 pc.printf("Commands:\r\n" 00066 " L LED_Tests(); // Blink each in turn\r\n" 00067 " P PWM_Tests(); // Ramps the PWM channels\r\n" 00068 " A AnalogIn_Tests(); // Measures voltage on each\r\n" 00069 " R RTC_Tests(); // Saves current time, alters it, restores it\r\n" 00070 " M MicroSD_Tests(); // Writes and Reads file on an installed card\r\n" 00071 " S RS_232_Tests(); // Outputs simple text\r\n" 00072 " C CAN_Tests(); // Requires CAN1 wired to CAN2, loops messages\r\n" 00073 " E Ethernet_Tests(); // Sets the clock from a time server\r\n" 00074 " U USBHost_Tests(); // Writes and Reads file on a memory stick\r\n" 00075 " F FileSystems_Tests(); // Writes and Reads file on internal file system\r\n" 00076 " X eXit to automatic testing\r\n"); 00077 break; 00078 case 'X': 00079 r = false; 00080 break; 00081 case 'L': 00082 LED_Tests(); 00083 break; 00084 case 'P': 00085 PWM_Tests(); 00086 break; 00087 case 'A': 00088 AnalogIn_Tests(); 00089 break; 00090 case 'R': 00091 RTC_Tests(); 00092 break; 00093 case 'r': 00094 RTC_Set(); 00095 break; 00096 case 'M': 00097 MicroSD_Tests(); 00098 break; 00099 case 'S': 00100 RS_232_Tests(); 00101 break; 00102 case 'C': 00103 CAN_Tests(); 00104 break; 00105 case 'E': 00106 Ethernet_Tests(); 00107 break; 00108 case 'U': 00109 USBHost_Tests(); 00110 break; 00111 case 'F': 00112 FileSystem_Tests(); 00113 break; 00114 } 00115 return r; 00116 } 00117 00118 /// main is the main startup code. 00119 /// 00120 /// This initializes the test environment, shows a banner, 00121 /// and starts the automated testing. 00122 /// It also detects if the user is attempting to interact, and 00123 /// between each test category there is the possibility to transfer 00124 /// to the interactive test mode. 00125 /// When in interactive test mode, the user determines which test 00126 /// to run. The user can also exit interactive mode back to the 00127 /// automated test mode. 00128 /// 00129 /// @returns never 00130 /// 00131 int main() { 00132 bool init = true; ///!< init is slightly different 00133 bool interactive = false; ///!< track when in interactive mode 00134 int test = 0; ///!< which test to run 00135 char TestList[] = "XLPARrMSCEU"; ///!< list of valid test commands AUTOTESTS are uppercase 00136 00137 pc.printf("Set your baudrate from 9600 to 921600\r\n"); 00138 pc.baud(921600); 00139 if (wdt.WatchdogCausedReset()) 00140 pc.printf("Watchdog caused reset. WD is armed for 30s cycle.\r\n"); 00141 00142 wdt.Configure(30.0); // longest test should be under this interval 00143 00144 wait(3.0); // just wait a little while in case they want to inject a '?' 00145 while (1) { 00146 wdt.Service(); // do this often enough 00147 00148 if (pc.readable() || init) { 00149 pc.printf("\r\n\r\n"); 00150 pc.printf("SmartBoard Hardware Tester [" __DATE__ " " __TIME__ "]\r\n"); 00151 pc.printf(" SmartBoard Hardware v0.05\r\n"); 00152 pc.printf(" SmartBoard Software v0.13\r\n"); 00153 pc.printf("\r\n"); 00154 pc.printf(" [USB] [Eth/USB] \r\n"); 00155 pc.printf(" +---------------+------------+---+-------+---+\r\n"); 00156 pc.printf(" |O [RS232 1-2] | | | | | | O|\r\n"); 00157 pc.printf(" | | |microSD| | | | |\r\n"); 00158 pc.printf(" |S | | | | | | C|\r\n"); 00159 pc.printf(" |P | +-------+ | | | A|\r\n"); 00160 pc.printf(" |I | | |Yl Gr| N|\r\n"); 00161 pc.printf(" |1 | | +-------+ 1|\r\n"); 00162 pc.printf(" |- | | -|\r\n"); 00163 pc.printf(" |2 | RTC | 2|\r\n"); 00164 pc.printf(" | | (Battery) | |\r\n"); 00165 pc.printf(" | | | |\r\n"); 00166 pc.printf(" | | 1 2 3 4 | |\r\n"); 00167 pc.printf(" | +------------+ |\r\n"); 00168 pc.printf(" |O[Analog In ] O [PWM Out] O|\r\n"); 00169 pc.printf(" +--------------------------------------------+\r\n"); 00170 pc.printf("\r\n"); 00171 init = false; 00172 } 00173 if (pc.readable()) { 00174 interactive = true; 00175 while (pc.readable()) 00176 (void)pc.getc(); 00177 00178 while (interactive) { 00179 wdt.Service(); // do this often enough 00180 pc.printf("> "); 00181 while (!pc.readable()) 00182 wdt.Service(); 00183 int i = pc.getc(); 00184 pc.putc(i); 00185 pc.putc('\r'); 00186 pc.putc('\n'); 00187 interactive = TestVector(i); 00188 } 00189 } else { 00190 if (test == 0) 00191 pc.printf("\x07"); // Bell character indicating start of tests 00192 if (TestList[test] >= 'A' && TestList[test] <= 'Z') // Tests are UPPER-case only 00193 TestVector(TestList[test]); 00194 test++; 00195 if (TestList[test] == '\0') 00196 test = 0; 00197 wait(5.0); // Extra pause 00198 } 00199 } 00200 } 00201 00202 /// LED_Tests performs some simple digital output to the 00203 /// LEDs. 00204 /// 00205 /// It will attempt to exercise the LEDs on the Ethernet ports 00206 /// as well, but by jumper configuration these may not be available. 00207 /// 00208 void LED_Tests(void) { 00209 int l; 00210 int i; 00211 struct { 00212 const char * name; 00213 DigitalOut led; 00214 } Leds[] = { 00215 {"Ethernet Green", ETHERGREEN}, 00216 {"Ethernet Yellow", ETHERYELLOW}, 00217 {"Led 1", LED1}, 00218 {"Led 2", LED2}, 00219 {"Led 3", LED3}, 00220 {"Led 4", LED4} 00221 }; 00222 const int numLeds = sizeof(Leds) / sizeof(Leds[0]); 00223 00224 printf("LED Test:\r\n"); 00225 for (l=0; l<numLeds; l++) { 00226 wdt.Service(); 00227 printf(" Blink %s LED 3 times\r\n", Leds[l].name); 00228 for (i=0; i<3; i++) { 00229 Leds[l].led = true; 00230 wait(0.4); 00231 Leds[l].led = false; 00232 wait(0.4); 00233 } 00234 } 00235 } 00236 00237 /// PWM_Tests performs some simple pwm output to the 00238 /// PWM channels and the LEDs. 00239 /// 00240 /// It will attempt to exercise the outputs with a simple ramping 00241 /// signal, but by jumper configuration these may not be available. 00242 /// 00243 void PWM_Tests(void) { 00244 int l; 00245 int i; 00246 float f; 00247 struct { 00248 const char * name; 00249 PwmOut pwm; 00250 } Pwms[] = { 00251 {"PWM 1", p21}, 00252 {"PWM 2", p22}, 00253 {"PWM 3", p23}, 00254 {"PWM 4", p24}, 00255 {"PWM 5", p25}, 00256 {"PWM 6", p26}, 00257 {"Led 1", LED1}, 00258 {"Led 2", LED2}, 00259 {"Led 3", LED3}, 00260 {"Led 4", LED4} 00261 }; 00262 const int numPwms = sizeof(Pwms) / sizeof(Pwms[0]); 00263 00264 printf("PWM Test:\r\n"); 00265 for (l=0; l<numPwms; l++) { 00266 wdt.Service(); 00267 printf(" Ramp %s PWM 3 times\r\n", Pwms[l].name); 00268 for (i=0; i<3; i++) { 00269 for (f=0.0; f<=1.0; f+= 0.1) { 00270 Pwms[l].pwm = f; 00271 wait(0.1); 00272 } 00273 } 00274 Pwms[l].pwm = 0; // off when done 00275 } 00276 } 00277 00278 /// AnalogIn_Tests takes a few sample measurements on each channel 00279 /// 00280 /// It samples each channel a number of times and presents the 00281 /// converted results on the console. 00282 /// 00283 void AnalogIn_Tests(void) { 00284 int l; 00285 int i; 00286 const int samples = 20; 00287 struct { 00288 const char * name; 00289 AnalogIn in; 00290 } Analogs[] = { 00291 {"Ain 1", p15}, 00292 {"Ain 2", p16}, 00293 {"Ain 3", p17}, 00294 {"Ain 4", p18}, 00295 {"Ain 5", p19}, 00296 {"Ain 6", p20} 00297 }; 00298 const int numAnalogs = sizeof(Analogs) / sizeof(Analogs[0]); 00299 00300 printf("Analog Test:\r\n"); 00301 for (l=0; l<numAnalogs; l++) { 00302 wdt.Service(); 00303 for (i=0; i<samples; i++) { 00304 uint16_t raw = Analogs[l].in.read_u16(); 00305 float flt = Analogs[l].in.read(); 00306 printf(" Analog %i is %04X, %3.2f, %3.2fv\r", l, raw, flt, flt*3.3); 00307 wait(0.1); 00308 } 00309 printf("\n"); 00310 } 00311 } 00312 00313 /// RTC_Tests will perform simple tests on the Real Time Clock 00314 /// 00315 /// It will first sample the time from the RTC and later restore 00316 /// it as best it can. 00317 /// In the middle of that it will set the clock, then simply show 00318 /// the time once per second for 5 seconds. After this it 00319 /// will restore the clock at best it can. 00320 /// 00321 void RTC_Tests(void) { 00322 time_t x; 00323 int i; 00324 const int oldTime = 1256729737; 00325 00326 printf("RTC Test:\r\n"); 00327 ShowTime(tzOffsetHr, tzOffsetMin); 00328 x = time(NULL); // Save the time before the test 00329 printf(" Saving current time(%d)\r\n", x); 00330 00331 set_time(oldTime); // Set RTC time to Wed, 28 Oct 2009 11:35:37 00332 printf(" Set time to Wed, 28 Oct 2009 11:35:37\r\n"); 00333 00334 for (i=0; i<5; i++) { 00335 ShowTime(); 00336 wait(1.0); 00337 } 00338 set_time(x + time(NULL) - 1256729737); // Approximately restored 00339 ShowTime(tzOffsetHr, tzOffsetMin); 00340 wait(1.0); 00341 ShowTime(tzOffsetHr, tzOffsetMin); 00342 } 00343 00344 /// GetNumber will get from the user a number using the 00345 /// specified number of digits. 00346 /// 00347 /// They can enter a number from 0 to 10^(digits-1) 00348 /// 00349 /// @param digits is the number of digits to enter 00350 /// @param pValue is a pointer to where to store the result 00351 /// @returns true if a number was entered 00352 /// @returns false if they entered a non-digit 00353 /// 00354 int GetNumber(int digits, int * pValue) { 00355 int tempValue = 0; 00356 int i; 00357 00358 while (digits--) { 00359 while (!pc.readable()) 00360 wdt.Service(); 00361 i = pc.getc(); 00362 if (i == ' ') i = '0'; // special case for leading blank 00363 if (i >= '0' && i <= '9') { 00364 pc.putc(i); 00365 tempValue = tempValue * 10 + (i - '0'); 00366 } else 00367 return false; 00368 } 00369 *pValue = tempValue; 00370 return true; 00371 } 00372 00373 /// RTC_Set will interactively set the Real Time Clock 00374 /// 00375 /// It will allow you to enter the date and time information 00376 /// and then create a timestamp. After this, it will set 00377 /// the RTC to that timestamp. 00378 /// 00379 void RTC_Set(void) { 00380 time_t seconds = time(NULL); 00381 struct tm *t = localtime(&seconds); 00382 int i; 00383 00384 pc.printf("RTC Set:\r\n"); 00385 ShowTime(seconds, tzOffsetHr, tzOffsetMin); 00386 pc.printf(" Enter the time MM/DD/YYYY HH:MM:SS\r\n"); 00387 while (1) { 00388 int _m, _d, _y, _H, _M, _S; 00389 printf(" > "); 00390 if (GetNumber(2, &_m)) { 00391 pc.putc('/'); 00392 if (!GetNumber(2, &_d)) 00393 continue; 00394 pc.putc('/'); 00395 if (!GetNumber(4, &_y)) 00396 continue; 00397 t->tm_mon = _m - 1; 00398 t->tm_mday = _d; 00399 t->tm_year = _y - 1900; 00400 } else { 00401 pc.printf("%02d/%02d/%04d", t->tm_mon+1, t->tm_mday, t->tm_year+1900); 00402 } 00403 pc.putc(' '); 00404 if (GetNumber(2, &_H)) { 00405 pc.putc(':'); 00406 if (!GetNumber(2, &_M)) 00407 continue; 00408 pc.putc(':'); 00409 if (!GetNumber(2, &_S)) 00410 continue; 00411 t->tm_hour = _H; 00412 t->tm_min = _M; 00413 t->tm_sec = _S; 00414 pc.printf("\r\n"); 00415 pc.printf("%02d/%02d/%04d ", t->tm_mon+1, t->tm_mday, t->tm_year+1900); 00416 pc.printf("%02d:%02d:%02d\r\n", t->tm_hour, t->tm_min, t->tm_sec); 00417 // convert to timestamp and display (1256729737) 00418 time_t seconds = mktime(t); 00419 seconds = seconds - (time_t)(tzOffsetHr * 3600 + tzOffsetMin * 60); 00420 set_time(seconds); 00421 break; 00422 } else { 00423 pc.printf("%02d:%02d:%02d\r\n", t->tm_hour, t->tm_min, t->tm_sec); 00424 break; // they can bail here 00425 } 00426 } 00427 for (i=0; i<5; i++) { 00428 ShowTime(tzOffsetHr, tzOffsetMin); 00429 wait(1.0); 00430 } 00431 } 00432 00433 00434 /// Ethernet_Tests will attempt to test the Ethernet interface 00435 /// 00436 /// It will connect to the network - if possible, then it will 00437 /// try to connect to a network time server and set the clock, 00438 /// using hard coded time server and time zone offset values. 00439 /// 00440 /// It appears that the Ethernet interface cannot be instantiated, 00441 /// destroyed, and later instantiated again (it would reliably "hang"). 00442 /// So, this test is "runonce" protected. 00443 /// 00444 void Ethernet_Tests(void) { 00445 EthernetNetIf eth; 00446 NTPClient ntp; 00447 static bool runonce = true; 00448 00449 printf("Ethernet Test:\r\n"); 00450 if (runonce) { 00451 EthernetErr ethErr = eth.setup(); 00452 if (ethErr) { 00453 printf("Error %d in setup.\r\n", ethErr); 00454 return; 00455 } 00456 printf(" Ethernet Setup OK\r\n"); 00457 ShowTime(0, tzOffsetHr, tzOffsetMin); 00458 printf(" Setting clock to %s\r\n", TicTocServer); 00459 Host server(IpAddr(), 123, TicTocServer); 00460 ntp.setTime(server); 00461 printf(" Clock was set.\r\n"); 00462 wait(1.0); 00463 ShowTime(0, tzOffsetHr, tzOffsetMin); 00464 runonce = false; 00465 } else { 00466 printf(" only runs once per cold-boot.\r\n"); 00467 } 00468 } 00469 00470 /// isPrint tests the passed in character for being 'printable' 00471 /// 00472 /// It will evaluate the character on a simple ASCII range of 00473 /// characters 0 to 127. 00474 /// 00475 /// @param i is the character to test 00476 /// @returns true if the character is in the printable set (including <space>) 00477 /// @returns false if the character is not printable (may be control code or extended character) 00478 /// 00479 bool isPrint(char i) { 00480 if (i >= ' ' && i <= '~') 00481 return true; 00482 else 00483 return false; 00484 } 00485 00486 /// common file system test to write and then read a moderately large file 00487 /// 00488 /// This will create a folder and then open a file for write. It will write a 00489 /// text string to the file and defined number of times and close the file. 00490 /// It will then report the performance metrics in bytes/sec write. 00491 /// It will then open the same file for read and read the file back, one record 00492 /// at a time. It will then report the performance metrics for the read in bytes/sec. 00493 /// 00494 /// @param folder is the folder name to create 00495 /// @param file is the filename to create 00496 /// @param textMessage is the text message to use in the test 00497 /// @param COUNTLIMIT is the number of times the text is written to the file 00498 /// @returns nothing 00499 /// 00500 void RunFileSystemTest(const char * folder, const char * file, const char * textMessage, int COUNTLIMIT) { 00501 FILE *fp; 00502 Timer timer; 00503 char * buffer = (char *)malloc(strlen(textMessage)+2); // just a bit bigger 00504 00505 if (strlen(folder)) 00506 mkdir(folder, 0777); 00507 // Write test 00508 printf(" Starting write test of %i chars.\r\n", strlen(textMessage) * COUNTLIMIT); 00509 int begin = timer.read_us(); 00510 fp = fopen(file, "w"); 00511 if (fp == NULL) { 00512 printf(" Could not open file for write\r\n"); 00513 } else { 00514 int counter; 00515 for (counter=0; counter<COUNTLIMIT; counter++) { 00516 fprintf(fp, textMessage); 00517 } 00518 fclose(fp); 00519 int end = timer.read_us(); 00520 printf(" Closed file. Wrote %i chars in %i uSec.\r\n", 00521 strlen(textMessage) * COUNTLIMIT, 00522 end - begin); 00523 printf(" %6.0f bytes/sec.\r\n", 00524 1.0e6f * (float)(strlen(textMessage) * COUNTLIMIT) / (end - begin)); 00525 00526 // read test 00527 printf(" Read test.\r\n"); 00528 begin = timer.read_us(); 00529 fp = fopen(file, "r"); 00530 if (fp == NULL) { 00531 printf(" could not open file for read\r\n"); 00532 } else { 00533 while (fgets(buffer, sizeof(buffer), fp)) { 00534 while (strlen(buffer) > 0 && !isPrint(buffer[strlen(buffer)-1])) 00535 buffer[strlen(buffer)-1] = '\0'; // chomp the <LF> 00536 //printf(" Read: {%s}\r\n", buffer); 00537 } 00538 fclose(fp); 00539 end = timer.read_us(); 00540 printf(" Closed file. Read %i chars in %i uSec.\r\n", 00541 strlen(textMessage) * COUNTLIMIT, 00542 end - begin); 00543 printf(" %6.0f bytes/sec.\r\n", 00544 1.0e6f * (float)(strlen(textMessage) * COUNTLIMIT) / (end - begin)); 00545 } 00546 } 00547 free(buffer); 00548 } 00549 00550 00551 00552 00553 /// MicroSD_Tests attempts to access and write a file on the micro SD card 00554 /// 00555 /// It will mount the file system, then attempt to write a simple 00556 /// file on the micro SD card. 00557 /// 00558 void MicroSD_Tests(void) { 00559 SDFileSystem sd(p5, p6, p7, p8, "ud"); // the pinout on the mbed Cool Components workshop board 00560 char folder[] = "/ud/testDir"; 00561 char file[] = "/ud/testDir/sdtest.txt"; 00562 DigitalIn cardIn(p11); 00563 const int COUNTLIMIT = 10000; 00564 const char textMessage[] = "Write a message to the micro SD card! 50 chars\r\n"; 00565 00566 printf("SD File System Tests: [installed microSD card required]\r\n"); 00567 printf(" Card Detection: %s\r\n", (cardIn) ? "in" : "out"); 00568 if (cardIn) { 00569 RunFileSystemTest(folder, file, textMessage, COUNTLIMIT); 00570 } 00571 printf(" test complete!\r\n"); 00572 } 00573 00574 /// USBHost_Tests attempts to access and write a file on USB stick 00575 /// 00576 /// It will mount the file system, then attempt to write a simple 00577 /// file on the USB interface. 00578 /// 00579 void USBHost_Tests(void) { 00580 MSCFileSystem fs ("fs"); 00581 char folder[] = "/fs/testDir"; 00582 char file[] = "/fs/testDir/sdtest.txt"; 00583 const int COUNTLIMIT = 10000; 00584 const char textMessage[] = "Write a message to the USB Memory stick 50 chars\r\n"; 00585 00586 printf("USB Host Tests: [installed memory stick required]\r\n"); 00587 RunFileSystemTest(folder, file, textMessage, COUNTLIMIT); 00588 printf(" test complete!\r\n"); 00589 } 00590 00591 00592 /// FileSystem_Tests attempts to access and write a file on the local file system 00593 /// 00594 /// It will mount the file system, then attempt to write a simple 00595 /// file on the interface. While file handles are open, the USB drive will 00596 /// be unavailable. 00597 /// 00598 void FileSystem_Tests(void) { 00599 LocalFileSystem local("local"); 00600 char folder[] = ""; 00601 char file[] = "/local/fstest.txt"; 00602 const int COUNTLIMIT = 10000; 00603 const char textMessage[] = "Write a message to the Local Files 50 chars\r\n"; 00604 00605 printf("Local File System Tests: [mbed onboard file system]\r\n"); 00606 RunFileSystemTest(folder, file, textMessage, COUNTLIMIT); 00607 printf(" test complete!\r\n"); 00608 } 00609 00610 00611 00612 /// FormatMicroseconds will format a number of microseconds int ascii seconds. 00613 /// 00614 /// It will support formatting the number with decimal and thousands 00615 /// separators. 00616 /// 00617 /// @param value to format 00618 /// @returns the formatted string "0034.123456" 00619 /// 00620 char * FormatMicroseconds(int value) { 00621 static char result[15] = ""; 00622 int uSec = value % 1000000; 00623 int Sec = value / 1000000; 00624 00625 sprintf(result, "%04i.%06i", Sec, uSec); 00626 return result; 00627 } 00628 00629 00630 /// ShowCANMessage will print to the console as specified 00631 /// 00632 /// This format is used in other tools, and is not explained 00633 /// here beyond what you see 00634 /// 00635 /// +--- 'r'eceive or 't'ransmit 00636 /// | +--- 'nrm' 11 bit identifier, 'xtd' 29 bit identifier 00637 /// | | +--- channel '1' to '2' 00638 /// | | | +--- identifier in hex 00639 /// | | | | +-- dlc - data length control 00640 /// | | | | | +--------------------+ data bytes 1 to 8 00641 /// | | | | | | +--- fixed zero for compatibility with other tools 00642 /// | | | | | | | +-- fixed zero for compat 00643 /// | | | | | | | | +--- timestamp 00644 /// | | | | | | | | | 00645 /// _ ___ _ ________ __ _______________________ _ ___ ___________ 00646 /// r xtd 2 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890 00647 /// t xtd 1 18EAFF03 03 EE EE 00 0 0 1235.654321 00648 /// 00649 /// @param tx indicates it is a transmit message when non-zero, receive otherwise 00650 /// @param ch is the communication channel of this message 00651 /// @msg is the CAN message to be shown 00652 /// @uSec is the timestamp in microseconds 00653 /// @returns nothing 00654 /// 00655 void ShowCANMessage(int tx, int ch, CANMessage msg, int uSec) { 00656 pc.printf("%c %s %d %08X %02X ", 00657 (tx) ? 't' : 'r', 00658 (msg.format == CANExtended) ? "xtd" : "nrm", ch, msg.id, msg.len); 00659 for (int d=0; d<8; d++) { 00660 if (d < msg.len) 00661 pc.printf("%02X ", msg.data[d]); 00662 else 00663 pc.printf(" "); 00664 } 00665 pc.printf("0 0 %s\r\n", FormatMicroseconds(uSec)); 00666 } 00667 00668 00669 /// CAN_Tests will send some packets on one CAN port and expect them on the other 00670 /// 00671 /// It will attempt to send 10 messages on one port and expect that 00672 /// all 10 messages were received on the other port. The two ports should 00673 /// be wired from one to the other with a loop-back cable and a termination 00674 /// resistor. 00675 /// 00676 void CAN_Tests(void) { 00677 CAN can1(p9, p10); 00678 CAN can2(p30, p29); 00679 char Txcounter = 0; 00680 char Rxcounter = 0; 00681 CANMessage tMsg; 00682 CANMessage rMsg; 00683 Timer timer; 00684 int i; 00685 00686 pc.printf("CAN Tests:\r\n"); 00687 i = can1.frequency(250000); 00688 pc.printf(" can1 frequency set: %i\r\n", i); 00689 i = can2.frequency(250000); 00690 pc.printf(" can2 frequency set: %i\r\n", i); 00691 timer.start(); 00692 for (i=0; i<25; i++) { // gets a few more passes to receive the messages 00693 00694 for (int x=0; x<8; x++) 00695 tMsg.data[x] = (char)(rand()); 00696 tMsg.data[0] = Txcounter; 00697 tMsg.id = rand(); 00698 tMsg.len = rand() % 9; 00699 tMsg.type = CANData; 00700 tMsg.format = (rand() & 1) ? CANExtended : CANStandard; 00701 00702 if (Txcounter < 10 && can1.write(tMsg)) { 00703 pc.printf(" "); 00704 ShowCANMessage(1, 1, tMsg, timer.read_us()); 00705 Txcounter++; 00706 //wait(0.05); 00707 } 00708 if (can2.read(rMsg)) { 00709 Rxcounter++; 00710 pc.printf(" "); 00711 ShowCANMessage(0, 2, rMsg, timer.read_us()); 00712 } 00713 wait(0.005); 00714 } 00715 if (Txcounter == Rxcounter) 00716 printf(" passed.\r\n"); 00717 else 00718 printf(" **** Txcounter (%d) != Rxcounter (%d) ****\r\n", Txcounter, Rxcounter); 00719 } 00720 00721 /// RS_232_Tests will say hello on each of the RS-232 channels 00722 /// 00723 /// It will print a hello text string out each of the ports. 00724 /// 00725 void RS_232_Tests(void) { 00726 Serial s1(p13, p14); 00727 Serial s2(p28, p27); 00728 00729 pc.printf("RS-232 Tests:\r\n"); 00730 s1.printf(" Hello going out S1\r\n"); 00731 s2.printf(" Hello going out S2\r\n"); 00732 pc.printf(" end tests.\r\n"); 00733 }
Generated on Thu Jul 21 2022 00:25:24 by 1.7.2