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

This program is most of what you need to test your SmartBoard baseboard hardware. It provides a means to test the following:

  • Two channels of CAN (with a loopback cable)
  • RS-232 Ports
  • Analog inputs
  • PWM outputs
  • Ethernet port
  • Real time clock
  • micro SD
  • USB Host port

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Mon Jan 24 00:41:01 2011 +0000
Parent:
0:5db287f0060b
Child:
2:02e7d896824f
Commit message:
v0.09

Changed in this revision

ShowTime.c Show annotated file Show diff for this revision Revisions of this file
ShowTime.h Show annotated file Show diff for this revision Revisions of this file
SmartBoard_Tester.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/ShowTime.c	Sun Jan 16 18:30:14 2011 +0000
+++ b/ShowTime.c	Mon Jan 24 00:41:01 2011 +0000
@@ -1,13 +1,22 @@
-
+/// @file ShowTime.cpp contains a couple of simple time printing apis
+///
+/// APIs for showing the time from the RTC, or from a passed in value.
+///
+/// @note Copyright © 2011 by Smartware Computing, all rights reserved.
+/// @author David Smart
+///
 #include "mbed.h"
-
+#include "ShowTime.h"
 
 static int SignOf(const int i) {
     return (i >= 0) ? 1 : -1;
 }
 
+void ShowTime(int hOffset, int mOffset) {
+    ShowTime(0, hOffset, mOffset);
+}
 
-void ShowTime(time_t tValue=0, int hOffset=0, int mOffset=0) {
+void ShowTime(time_t tValue, int hOffset, int mOffset) {
     time_t ctTime;
     char timbuf[70];
 
--- a/ShowTime.h	Sun Jan 16 18:30:14 2011 +0000
+++ b/ShowTime.h	Mon Jan 24 00:41:01 2011 +0000
@@ -1,13 +1,35 @@
+/// @file ShowTime.h contains a couple of simple time printing apis
+///
+/// APIs for showing the time from the RTC, or from a passed in value.
+///
+/// @note Copyright © 2011 by Smartware Computing, all rights reserved.
+/// @author David Smart
+///
+#ifndef SHOWTIME_H
+#define SHOWTIME_H
 
 /// ShowTime prints out the time to the serial console in a usable format
 ///
 /// This prints the passed in, or current time, to the console. It will
 /// indicate the time zone offset parameters as well.
 ///
-/// @param tValue is the optional time value to convert to friendly time format. If
+/// @param tValue is the non-optional time value to convert to friendly time format. If
 ///     this value is absent or zero, then it will get the system time to convert.
+/// @param hOffset is the non-optional hour offset to the local time zone
+/// @param mOffset is the non-optional minute offset to the local time zone
+/// @returns nothing
+///
+void ShowTime(time_t tValue, int hOffset, int mOffset);
+
+/// ShowTime prints out the time to the serial console in a usable format
+///
+/// This prints the current time to the console. It will
+/// indicate the time zone offset parameters as well.
+///
 /// @param hOffset is the optional hour offset to the local time zone
 /// @param mOffset is the optional minute offset to the local time zone
 /// @returns nothing
 ///
-void ShowTime(time_t tValue=0, int hOffset=0, int mOffset=0);
+void ShowTime(int hOffset=0, int mOffset=0);
+
+#endif
--- a/SmartBoard_Tester.cpp	Sun Jan 16 18:30:14 2011 +0000
+++ b/SmartBoard_Tester.cpp	Mon Jan 24 00:41:01 2011 +0000
@@ -24,6 +24,7 @@
 void PWM_Tests(void);
 void AnalogIn_Tests(void);
 void RTC_Tests(void);
+void RTC_Set(void);
 void MicroSD_Tests(void);
 void RS_232_Tests(void);
 void CAN_Tests(void);
@@ -50,7 +51,7 @@
     switch (i) {
         default:
         case '?':
-            pc.printf("Commands:\r\nx"
+            pc.printf("Commands:\r\n"
                       "  L   LED_Tests();\r\n"
                       "  P   PWM_Tests(); // note interaction between LEDs and PWMs\r\n"
                       "  A   AnalogIn_Tests();\r\n"
@@ -77,6 +78,9 @@
         case 'R':
             RTC_Tests();
             break;
+        case 'r':
+            RTC_Set();
+            break;
         case 'M':
             MicroSD_Tests();
             break;
@@ -113,14 +117,14 @@
     bool init = true;                   ///< init is slightly different
     bool interactive = false;           ///< track when in interactive mode
     int test = 0;                       ///< which test to run
-    char TestList[] = "XLPARMSCEU";     ///< list of valid test commands
+    char TestList[] = "XLPARrMSCEU";    ///< list of valid test commands AUTOTESTS are uppercase
 
     while (1) {
         if (pc.readable() || init) {
             pc.printf("\r\n\r\n");
             pc.printf("SmartBoard Hardware Tester\r\n");
             pc.printf("  SmartBoard Hardware    v0.05\r\n");
-            pc.printf("  SmartBoard Software    v0.07\r\n");
+            pc.printf("  SmartBoard Software    v0.09\r\n");
             pc.printf("\r\n");
             pc.printf("                      [USB]       [Eth/USB]    \r\n");
             pc.printf(" +---------------+------------+---+-------+---+\r\n");
@@ -287,7 +291,7 @@
     const int oldTime = 1256729737;
 
     printf("RTC Test:\r\n");
-    ShowTime(0, -6, 0);
+    ShowTime(tzOffsetHr, tzOffsetMin);
     x = time(NULL);         // Save the time before the test
     printf("    Saving current time(%d)\r\n", x);
 
@@ -299,11 +303,94 @@
         wait(1.0);
     }
     set_time(x + time(NULL) - 1256729737);          // Approximately restored
-    ShowTime(0, -6, 0);
+    ShowTime(tzOffsetHr, tzOffsetMin);
     wait(1.0);
-    ShowTime(0, -6, 0);
+    ShowTime(tzOffsetHr, tzOffsetMin);
+}
+
+/// GetNumber will get from the user a number using the
+/// specified number of digits.
+///
+/// They can enter a number from 0 to 10^(digits-1)
+///
+/// @param digits is the number of digits to enter
+/// @param pValue is a pointer to where to store the result
+/// @returns true if a number was entered
+/// @returns false if they entered a non-digit
+///
+int GetNumber(int digits, int * pValue) {
+    int tempValue = 0;
+    int i;
+
+    while (digits--) {
+        i = pc.getc();
+        if (i == ' ') i = '0';      // special case for leading blank
+        if (i >= '0' && i <= '9') {
+            pc.putc(i);
+            tempValue = tempValue * 10 + (i - '0');
+        } else
+            return false;
+    }
+    *pValue = tempValue;
+    return true;
 }
 
+/// RTC_Set will interactively set the Real Time Clock
+///
+/// It will allow you to enter the date and time information
+/// and then create a timestamp. After this, it will set
+/// the RTC to that timestamp.
+///
+void RTC_Set(void) {
+    time_t seconds = time(NULL);
+    struct tm *t = localtime(&seconds);
+    int i;
+
+    printf("RTC Set:\r\n");
+    ShowTime(seconds, tzOffsetHr, tzOffsetMin);
+    printf("    Enter the time MM/DD/YYYY HH:MM:SS\r\n");
+    while (1) {
+        printf("                 > ");
+        if (GetNumber(2, &t->tm_mon)) {
+            pc.putc('/');
+            if (!GetNumber(2, &t->tm_mday))
+                continue;
+            pc.putc('/');
+            if (!GetNumber(4, &t->tm_year))
+                continue;
+        } else {
+            pc.printf("%02d/%02d/%04d", t->tm_mon+1, t->tm_mday, t->tm_year+1900);
+        }
+        pc.putc(' ');
+        if (!GetNumber(2, &t->tm_hour)) {
+            pc.printf("%02d:%02d:%02d\r\n", t->tm_hour, t->tm_min, t->tm_sec);
+            break;          // they can bail here
+        }
+        pc.putc(':');
+        if (!GetNumber(2, &t->tm_min))
+            continue;
+        pc.putc(':');
+        if (!GetNumber(2, &t->tm_sec))
+            continue;
+        else {
+            t->tm_mon--; // 1-12 => 0-11
+            t->tm_year -= 1900;
+            t->tm_hour -= tzOffsetHr;
+            t->tm_min -= tzOffsetMin;
+            pc.printf("\r\n");
+            // convert to timestamp and display (1256729737)
+            time_t seconds = mktime(t);
+            set_time(seconds);
+            break;
+        }
+    }
+    for (i=0; i<5; i++) {
+        ShowTime(tzOffsetHr, tzOffsetMin);
+        wait(1.0);
+    }
+}
+
+
 /// Ethernet_Tests will attempt to test the Ethernet interface
 ///
 /// It will connect to the network - if possible, then it will
@@ -340,34 +427,54 @@
     }
 }
 
+/// isPrint tests the passed in character for being 'printable'
+///
+/// It will evaluate the character on a simple ASCII range of
+/// characters 0 to 127.
+///
+/// @param i is the character to test
+/// @returns true if the character is in the printable set (including <space>)
+/// @returns false if the character is not printable (may be control code or extended character)
+///
+bool isPrint(char i) {
+    if (i >= ' ' && i <= '~')
+        return true;
+    else
+        return false;
+}
+
 /// MicroSD_Tests attempts to access and write a file on the micro SD card
 ///
 /// It will mount the file system, then attempt to write a simple
 /// file on the micro SD card.
 ///
 void MicroSD_Tests(void) {
-    SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
+    SDFileSystem sd(p5, p6, p7, p8, "ud"); // the pinout on the mbed Cool Components workshop board
+    DigitalIn cardIn(p11);
     FILE *fp;
     char buffer[50];
 
     printf("SD File System Tests:\r\n");
-    mkdir("/sd/mydir", 0777);
-    fp = fopen("/sd/mydir/sdtest.txt", "w");
-    if (fp == NULL) {
-        printf("    Could not open file for write\r\n");
-    } else {
-        fprintf(fp, "Write a message to the micro SD card!");
-        fclose(fp);
-        printf("    Closed file.\r\n");
-        fp = fopen("/sd/mydir/sdtest.txt", "r");
-        if (fp) {
-            printf("    Reading file back.\r\n");
-            if (fgets(buffer, sizeof(buffer), fp)) {
-                if (strlen(buffer) > 2)
-                    buffer[strlen(buffer)-2] = '\0';    // chomp the <LF>
-                printf("    Read: {%s}\r\n", buffer);
+    printf("    Card Detection: %s\r\n", (cardIn) ? "in" : "out");
+    if (cardIn) {
+        mkdir("/ud/testDir", 0777);
+        fp = fopen("/ud/testDir/sdtest.txt", "w");
+        if (fp == NULL) {
+            printf("    Could not open file for write\r\n");
+        } else {
+            fprintf(fp, "Write a message to the micro SD card!\n");
+            fclose(fp);
+            printf("    Closed file.\r\n");
+            fp = fopen("/ud/testDir/sdtest.txt", "r");
+            if (fp) {
+                printf("    Reading file back.\r\n");
+                if (fgets(buffer, sizeof(buffer), fp)) {
+                    while (strlen(buffer) > 0 && !isPrint(buffer[strlen(buffer)-1]))
+                        buffer[strlen(buffer)-1] = '\0';    // chomp the <LF>
+                    printf("    Read: {%s}\r\n", buffer);
+                }
+                fclose(fp);
             }
-            fclose(fp);
         }
     }
     printf("    test complete!\r\n");
@@ -404,6 +511,51 @@
     }
 }
 
+
+/// FormatMicroseconds will format a number of microseconds int ascii seconds.
+///
+/// It will support formatting the number with decimal and thousands
+/// separators.
+///
+/// @param value to format
+/// @returns the formatted string
+///
+char * FormatMicroseconds(int value) {
+    static char result[15] = "";
+    int uSec = value % 1000000;
+    int Sec = value / 1000000;
+    
+    if (Sec > 1000)
+        sprintf(result, "%3i,%3i.%06i", Sec/1000, Sec%1000, uSec);
+    else
+        sprintf(result, "%7i.%06i", Sec, uSec);
+    return result;
+}
+
+
+/// ShowCANMessage will print to the console as specified
+///
+/// This format is used in other tools, and is not explained
+/// here except in the code.
+///
+/// @param tx indicates it is a transmit message when non-zero, receive otherwise
+/// @param ch is the communication channel of this message
+/// @msg is the CAN message to be shown
+/// @uSec is the timestamp in microseconds
+/// @returns nothing
+///
+void ShowCANMessage(int tx, int ch, CANMessage msg, int uSec) {
+    pc.printf("%c %s %d %08X %02X ", (tx) ? 't' : 'r', (msg.format == CANExtended) ? "xtd" : "nrm", ch, msg.id, msg.len);
+    for (int d=0; d<8; d++) {
+        if (d < msg.len)
+            pc.printf("%02X ", msg.data[d]);
+        else
+            pc.printf("   ");
+    }
+    pc.printf("0   0 %s\r\n", FormatMicroseconds(uSec));
+}
+
+
 /// CAN_Tests will send some packets on one CAN port and expect them on the other
 ///
 /// It will attempt to send 10 messages on one port and expect that
@@ -416,21 +568,39 @@
     CAN can2(p30, p29);
     char Txcounter = 0;
     char Rxcounter = 0;
-    CANMessage msg;
+    CANMessage tMsg;
+    CANMessage rMsg;
+    Timer timer;
     int i;
 
-    printf("CAN Tests:\r\n");
-    for (i=0; i<10; i++) {
-        if (can1.write(CANMessage(1337, &Txcounter, 1))) {
+    pc.printf("CAN Tests:\r\n");
+    i = can1.frequency(250000);
+    pc.printf("    can1 frequency set: %i\r\n", i);
+    i = can2.frequency(250000);
+    pc.printf("    can2 frequency set: %i\r\n", i);
+    timer.start();
+    for (i=0; i<25; i++) {  // gets a few more passes to receive the messages
+
+        for (int x=0; x<8; x++)
+            tMsg.data[x] = (char)(rand());
+        tMsg.data[0] = Txcounter;
+        tMsg.id = rand();
+        tMsg.len = rand() % 9;
+        tMsg.type = CANData;
+        tMsg.format  = (rand() & 1) ? CANExtended : CANStandard;
+
+        if (Txcounter < 10 && can1.write(tMsg)) {
+            pc.printf("    ");
+            ShowCANMessage(1, 1, tMsg, timer.read_us());
             Txcounter++;
-            printf("    Message sent: %d\r\n", Txcounter);
-            wait(0.05);
+            //wait(0.05);
         }
-        if (can2.read(msg)) {
-            printf("    Message received: %d\r\n", msg.data[0]);
+        if (can2.read(rMsg)) {
             Rxcounter++;
+            pc.printf("    ");
+            ShowCANMessage(0, 2, rMsg, timer.read_us());
         }
-        wait(0.2);
+        wait(0.005);
     }
     if (Txcounter == Rxcounter)
         printf("    passed.\r\n");