Example Source Code:
WCLoader C Uploader Example Program
For the WheelCommander WC-132


Description

This example demonstrates how to find, connect to, and manipulate the WheelCommander from Windows through a serial port. This will also work wirelessly via a BlueRadios Bluetooth module, such as the BlueSMiRF made by Sparkfun Electronics. (However, it is safer to perform an actual firmware upgrade via a wired connection).

In this example, the user can optionally specify a baud rate to connect with, and/or a filename of a firmware file to upload. If the filename is omitted, this program just finds the WheelCommander and displays its current firmware version number.


 

Download

WCLoader.c - C source
WCLoader.zip - Zip archive

 

Source Code


WCLoader.c


/********************************************/
/* WCLoader- WheelCommander Firmware Loader */
/*                                          */
/* This example program shows how to        */
/* connect to and invoke operations on a    */
/* nubotics WheelCommander WC-132 using a   */
/* PC serial port.                          */
/*                                          */
/* It relies on the NdiCmdC.h include file, */
/* the NdiCmdC.dll.                         */
/*                                          */
/*                                          */
/* (c)2005 Noetic Design, Inc.              */
/********************************************/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "windows.h"
#undef __cplusplus
#include "..\..\src\NdiCmdC\NdiCmdC.h"

#define TRUE 1
#define FALSE 0


int __cdecl main(int argc, char *argv[])
{
   int wc;
   BOOL is_unicoder = FALSE;
   char name[32];
   char new_name[32];
   int version = 0;
   int new_version;
   int j;
   char firmware_filename[256] = "";
   BOOL firmware_filename_set = FALSE;
   BOOL verbose = FALSE;
   BOOL force_error = FALSE;
   BOOL emergency_recovery = FALSE;
   BOOL special_firmware = FALSE;
   char *p;
   HWND statwindow = (HWND)-1;
   struct _stat stat;
   int ret = 0;
   int cur_baud = 0;
   int baud = -1;
   int baud_rates[10] = {1200, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0};
   char log_file[120] = "wcloader.log";

   NdiCmd_SetLogFile(log_file, FALSE);
   printf("WCLoader v. 1.10  Nubotics WheelCommander Firmware Loader\n(c)2009 Noetic Design, Inc.\n");

//
// scan first for options
//
   for (j = 1; j < argc; j++)
   {
      if ((argv[j][0] == '-') || (argv[j][0] == '/'))
      {
         p = &argv[j][2];
         switch(toupper(argv[j][1]))
         {
            case 'F':
               strcpy(firmware_filename, p);
               if (strlen(firmware_filename))
               {
                  if (_stat(firmware_filename, &stat) == 0)
                  {
                     if (stat.st_size && ((stat.st_mode & _S_IFMT) == _S_IFREG))
                     {
                        firmware_filename_set = TRUE;
                        printf("File to upload: %s, size %d\n", firmware_filename, stat.st_size);
                     }
                     else
                     {
                        printf("File %s not valid.\n", firmware_filename);
                        return 1;
                     }
                  }
                  else
                  {
                     printf("File %s not found.\n", firmware_filename);
                     return 2;
                  }
               }
               break;
            case 'B':
               baud = atoi(p);
               if ((baud < 0) || (baud > 8))
               {
                  printf("Syntax error!  Baud rate must be 0 to 8 inclusive.\n");
                  return 2;
               }
               if (verbose)
                  printf("Baud set to %d\n", baud);
               break;
            case 'V':
               verbose = TRUE;
               printf("Verbose mode on\n");
               break;
            case 'E':
               emergency_recovery = TRUE;
               if (verbose)
                  printf("Emergency recovery mode\n");
               break;
            case 'S':
               special_firmware = TRUE;
               if (verbose)
                  printf("Special firmware mode\n");
               break;
            case 'T':
               force_error = TRUE;
               if (verbose)
                  printf("Force error\n");
               break;
            case '?':
            case 'H':
            default:
               printf("Syntax:\n WCLoader /Ffirmware /V /T /Bn\n");
               printf(" /Ffirmware - specify firmware filename to upload\n");
               printf(" /V         - verbose mode\n");
               printf(" /E         - emergency recovery mode\n");
               printf(" /S         - special firmware\n");
               printf(" /T         - force error in data to test bootloader error handling\n");
               printf(" /Bn        - set baud rate to n, where n is:\n");
               printf("              0 = 1200\n");
               printf("              1 = 4800\n");
               printf("              2 = 9600\n");
               printf("              3 = 19200\n");
               printf("              4 = 38400\n");
               printf("              5 = 57600\n");
               printf("              6 = 115200\n");
               printf("              7 = 230400\n");
               printf("              8 = 460800\n");
               printf("              This changes the baudrate from the last known good rate\n");
               printf("              after a connection is made.  If the WheelCommander cannot\n");
               printf("              be found, the WCWizard dialog will appear so you can make\n");
               printf("              the initial baud rate setting prior to changing it.\n");
               return 1;
         }
      }
   }

// initialize the NdiCmd DLL
   NdiCmd_Init();

// set logging level
   NdiCmd_LogQuiet(!verbose);

// enable bootloader connection in Unicoder
   if (emergency_recovery)
   {
      printf("Setting recovery mode\n");
      NdiCmd_EnableDirect();
      printf("Changing baud rate to %d\n", baud_rates[baud]);
      NdiCmd_SetBaud(0, baud);
      printf("Searching for Device... ");
      if (!NdiCmd_Search())
      {
          printf("WheelCommander not found.\n");
          ret = 3;
      }
   }
   else
   {
      printf("Searching for Device... ");
// search for a WheelCommander
      if (!NdiCmd_Search())
      {
         printf("WheelCommander not found.\n");
         ret = 3;
      }
   }

// see if we found one
   wc = NdiCmd_GetWheelCommander();
   if (wc == -1)
   {
      wc = NdiCmd_GetUnicoder();
      if (wc == -1)
      {
         printf("WheelCommander and Unicoder not found.\n");
         ret = 4;
      }
      else
         is_unicoder = TRUE;
   }

// if not found, run the wizard so user can set it up
   if (ret)
   {
      NdiCmd_RunWizard(TRUE);
      if (((wc = NdiCmd_GetWheelCommander()) == -1) && ((wc = NdiCmd_GetUnicoder()) == -1))
         return ret;
      if (wc == NdiCmd_GetWheelCommander())
         is_unicoder = FALSE;
      else
         is_unicoder = TRUE;
   }

// once found, check the name and version
   if (!emergency_recovery)
   {
      if (!NdiCmd_GetName(wc, name, &version))
      {
         printf("Error retrieving name and version.\n");
         return 5;
      }
   }
   else
   {
      if (!is_unicoder)
         strcpy(name, "WheelCommander");
   }

   printf("Found %s version %d\n", is_unicoder ? "Unicoder" : name, version);

// if user set baud rate on command line, try to pass it to the WheelCommander
   if (!emergency_recovery && (baud != -1))
   {
      NdiCmd_GetBaud(wc, &cur_baud);
      if (cur_baud != baud_rates[baud])
      {
        printf("Attempting to change baud rate from %d to %d\n", cur_baud, baud_rates[baud]);
        if (!NdiCmd_SetBaud(wc, baud))
        {
            printf("Error setting baud rate.\n");
            return 6;
        }
        if (!NdiCmd_Sync(wc))
        {
            printf("Error confirming connection after baud rate change.\n");
            return 7;
        }
        printf("Baud rate changed.\n");
      }
   }

// if the user specified a firmware file, try to update it
   if (firmware_filename_set)
   {
      NdiCmd_LogQuiet(!verbose);
      if (!NdiCmd_UpdateFirmwareEx(firmware_filename, statwindow, special_firmware, emergency_recovery))
      {
         printf("Failed to update firmware!");
         return 8;
      }

      if (!emergency_recovery)
      {
         if (!NdiCmd_GetName(wc, new_name, &new_version))
         {
            printf("Error retrieving name and version after update.\n");
            return 9;
         }
         printf("Firmware upload succeeded.  Name is: %s, was %s; version is: %d, was %d\n",
            new_name, name, new_version, version);
      }
      else
         printf("Firmware upload succeeded.\n");
   }
   return 0;
}

 

 © 2004-2013 Noetic Design, Inc. All Rights Reserved. Nubotics, Unicoder, WheelCommander, and WheelWatcher are trademarks of Noetic Design, Inc.