Skip Navigation LinksProjects > LPC1343 Reference Design > Tutorial: Getting Started with the LPC1343 Code Base

Getting Started with the LPC1343 Code Base

Writing your first program using the LPC1343 Code Base.
UPDATE: Since v0.50 of the LPC1343 Code Base all files relating to the CLI/commands have been moved to the "/project" folder, and each command implementation is now contained in it's own individual .c file. The purpose of this change was to making sharing and updating the commands easier, and to seperate the project code from the much more static driver and peripheral code.  As such, this tutorial is slightly out of date so far as file names are concerned, but the general structure of the CLI remains unchanged aside from the improved file organisation. 

The LPC1343 Code Base includes basic software for almost all peripherals available on the LPC1343, as well as a number of drivers for common external components like EEPROM and LCD displays.  This tutorial will try to help you write your first program using the LPC1343 Code Base by adding a new command to the included command-line interface.

Prerequisites
This tutorial assumes that you have already installed and configured a toolchain for ARM, and are able to compile projects based on the LPC1343 Code Base. If you have not yet setup a development environment on your computer or haven't yet built anything, you may want to read Using CodeLite with the LPC1343 (part one and part two).

Project Structure

The LPC1343 Code Base is currently organised in the following manner:

LPC1343 Code Base Architecture

On the lowest level (layer three above), there are two main folders where most of the actual HW access occurs. Functions have been provided to try to make accessing the HW a bit easier by providing simple initialisation routines and various 'helper' methods to access the HW or peripherals without having to manipulate the registers yourself.

  • /Core contains drivers for all of the main internal peripherals (for example, "core/adc" contains a simple driver to work with the analog-to-digital converter)
  • /Drivers contains drivers for a number of external components, or 3rd party APIs, such as the I2C EEPROM device on the LPC1343 Reference Board or Chibi, a lightweight, open-source wireless stack for the Atmel AT86RF212 radio transceiver.

Above this lower layer there are a handful of key files that are used to control how the project is configured and what options are available when interacting with your board. The main files you should take note of are:

  • main.c: The main program entry point (void main), which is where any custom code should be handled. The system initialisation routine (sysinit.c) is called here by default, which will put all HW in an appropriate default state.  The application will then enter an infinite while(1) loop where any custom code you wish to execute should be placed.
  • projectconfig.h: Contains a number of 'defines' that are used to determine which features are included during compilation. By commenting out or modifying simple '#define' statements you can select between USBHID or USBCDC support, whether printf statements should be redirected to UART, to USBCDC or ignored, whether a command-line interface is included, etc.
  • sysinit.c: Initialises all required peripherals, configures the CPU, and puts the device in an appropriate default state. This code is placed in a seperate file than main.c simply to keep main.c as clean as possible.

An easy to use command-line interface is provided to allow you to interact with the HW directly similar to the command-prompt in Windows or in MS-DOS. The command-line interface currently works via either UART (57600 BPS) or USBCDC (Defaults to 115200 BPS), depending on whether CFG_PRINTF_UART or CFG_PRINTF_USBCDC are selected in projectconfig.h. The CLI also requires CFG_INTERFACE to be enabled). The CLI works by constantly calling "cmdPoll()" in main.c. The main files that control the command-line interface are:

  • cmd_tbl.h / commands.c: These two files determine which commands are available in the command-line interface (assuming CFG_INTERFACE is enabled in projectconfig.h).  cmd_tbl.h contains a list of all available commands and basic information about them, and commands.c contains the actual implementation of those commands (though they can be implemented elsewhere as well if you wish to organise your project differently). 

Extending the Command-Line Interface

The LPC1343 Code Base includes an easy-to use, extensible command-line interface that can be used via either UART (with any common RS232 to UART adapter) or USBCDC, depending on which option is selected in projectconfig.h.  This CLI is probably the easiest way to get your first program working.  In this tutorial, we'll enable the command-line interface over USB CDC, meaning that you will need to open up projectconfig.h and make sure that the following config options are set

Required projectconfig.h flags for USB Command-Line Interface
/* USB Configuration */
// #define CFG_USBHID
#define CFG_USBCDC

/* Printf Redirection */
// #define CFG_PRINTF_UART
#define CFG_PRINTF_USBCDC
#define CFG_PRINTF_NEWLINE       "\r\n"

/* CLI Interface Settings */
#define CFG_INTERFACE
#define CFG_INTERFACE_MAXMSGSIZE    (80)
#define CFG_INTERFACE_PROMPT        "LPC1343 >> "

The command-line interface (CLI) works by comparing any incoming messages against a predefined list of 'commands' (defined in 'cmd_tbl.h'). When a matching command is found, the incoming message is parsed and the various arguments are passed to the 'method' or function that is associated with the said command in cmd_tbl. There are three steps required to add a new command:

  1. Add a method prototype in cmd_tbl.h for the function that will handle the new command
  2. Add the command and some basic information about it to the cmd_tbl array
  3. Add the actual function (to commands.c, for example) that will interpret the command parameters and take appropriate actions

Step One: Add the Command Method Prototype in cmd_tbl.h

All method prototypes (or 'declarations') have exactly the same format.  The only thing that changes is a unique name for the method/function.  To add a new function to multiply two numbers, we might name the method as follows:

Method Prototype for Multiply Command
void cmd_multiply(uint8_t argc, char **argv);

Step Two: Add the Command to the cmd_tbl Array

Once the method's prototype has been declared, you need to add it to the list of commands that the command parsing engine will examine to see where to redirect the command. To do this, you simply need to scroll a few lines lower in cmd_tbl.h and find the cmd_tbl[] array. Each command is defined on one line, with a certain number of parameters that control how this command should be parsed, etc. For example, for multiply we could add the following to cmd_tbl:

cmd_t cmd_tbl[] = 
{
...
{ "multiply",                    // The command 'name'
  2,                             // Min # of additional parameters 
  2,                             // Max # of additional parameters
  0,                             // 1 if this command is 'hidden'
  cmd_multiply,                  // The function that handles this cmd
  "Multiplies two integers",     // Desc of this command (for 'help')
  "multiply <int1> <int2>"       // Command syntax w/parameters (for 'help')
},                               // Trailing ',' required after every command
...
}

This will cause the command parsing engine to expect exactly 2 optional parameter for the command 'multiply', and will redirect the command to cmd_multiply (which we defined using the prototype above).

Step Three: Implement the Command

Once the method's prototype has been declared and it had been added to the command table array (cmd_tbl[]), you can open the commands.c file and implement the method as follows:

Multiply with Input Validation
/**************************************************************************/
/*! 
    'multiply' command handler with basic input validation.  Either
    decimal (1, 2, 3) or hexadecimal (0x01, 0xFF) values are accepted.
*/
/**************************************************************************/
void cmd_multiply(uint8_t argc, char **argv)
{
  int32_t results = 0;
  int32_t int1, int2;
  
  // Validate the first number (assigned to int1)
  if (!getNumber (argv[0], &int1))
  {
    // The first integer was invalid
    // A warning message will be displayed by getNumber
    return;
  }
  
  // Validate the second number (assigned to int2)
  if (!getNumber (argv[1], &int2))
  {
    // The second integer was invalid
    // A warning message will be displayed by getNumber
    return;
  }
  
  // If you reach this point, both numbers are valid
  results = int1 * int2;

  // Display the results with printf
  printf("%d %s", (int)results, CFG_PRINTF_NEWLINE);
}

Results

If you build the code base with the above addition, and connect to the CLI with a terminal emulator like RealTerm (57600 BPS is using UART, 115200 if using USBCDC), the new 'multiply' command should appear in the 'help' menu, and you should be able to multiply two integers as seen below:

Multiply Command in RealTerm

You can see the syntax of the new command be entering 'multiply ?', which will display the text we added in cmb_tbl[]. The syntax description and some common validation errors messages can be seen below, along with an example showing that hexadecimal values are also parsed by 'getNumber' (multiplying 0xFF or 255 by 2):

Validating Input with the CLI

  • Facebook
  • DZone It!
  • Digg It!
  • StumbleUpon
  • Technorati
  • Del.icio.us
  • NewsVine
  • Reddit
  • Blinklist
  • Furl it!

Comments