Back to Getting Started

Back to Examples

This example demonstrates setting up and making use of the Terminal Board or the Breakout Board, both a general purpose peripheral that is useful for debugging, testing, and external signal interfaces. In this example, the terminal board/breakout board is used to create a serial light/LED application.

This examples helps you in:

1. Figuring out how the terminal/breakout board is mapped to the signals on the SPIP header.

2. Accessing the GPIOs(switch,LED) through the terminal/breakout pins and controlling them, thereby creating a serial LED/light application.

Stackview - if using terminal board

Fig. 1: TOP VIEW Fig. 2: BOTTOM VIEW

Stackview - if using breakout board

Fig. 1: TOP VIEW Fig. 2: BOTTOM VIEW

Note : In addition to the PIEP TI CC2541 board and the USB board, you will be requiring a set of LEDs(6-8) and a pushbutton/switch. You can buy them here.

Before you proceed with this tutorial, you must have the Koliada Visual Studio plugin and Koliada toolchain setup. For more information on the setup check out Koliada Getting started. This tutorial is currently based on the TI CC2541 which uses the 8051.

Depending on the pins on the Breakout/Terminal Board we are using we should connect each output pin to positive/Vin of the LED and the input pin to positive/Vin of switch. The ground of each LED and switch must be connected to the CC2541 board's ground pin.

Before working on this example, make sure you have set the latest KoliadaESDK(TM). More information on setSDK setup and setting the path is shown here.

Note: After making sure the SDK path is set, you must know that the board config must be flashed only if you are using any I/O pins. In this particular example, there are I/O configurations for the LED and Switch, and hence you should open the Terminal_Breakout config project in visual studio. You can find the project under KoliadaESDK(TM)→examples→Terminal_BreakoutConfig.

Select the SDK using the SDK Dropdown button at the top.

Now compile the config project and hit download to target.

You should see the following output on your serial terminal

Fig. 5: Serial Output of Config

Since the I/O ports for the LED and the Switch are configured by downloading the config project we can move on to download the application firmware. You find the application firmware for Terminal example under KoliadaESDK(TM)→examples→TestTerminal_Breakout.

Now compile the project and hit download to target.

You should see the following output on your serial terminal:

Fig. 6: Serial Output of Application

In this example we should be testing the operation of the external I/Os ( serial LED/Lights and the Switch ) through the terminal/breakout board.

There are six LEDs and a button/SW configured in this example. The LEDs should be lighting up in a looping sequential order.

When you press the external button/SW you should the see the switching frequency of the serial lighting changes and the LEDs switch at a much slower rate. The initial switch frequency (the time between when one of the LED is turned off and the following LED is turned off) is 100ms. 100ms, 500ms and 1000ms are the three switching frequencies and each button press toggles between these switching frequencies.

Terminal/Breakout Config

As mentioned above the Terminal_BreakoutConfig.c file configures the I/O pins. Hence we configure the necessary LEDs and Switches that we intend to use. Here in this example SW1 and LEDs 2,4,5,6,8,10 are used. Hence the respective port numbers are configured. Port and Bit specifies the port and mask used. The port and mask details for the CC2541 board and Terminal board can be found in CC2541 user sheet and Terminal user sheet/Breakout user sheet. The given five binary bits specify the direction of the port input/ output, the edge trigger rising/falling, reenable, inversion and initial high/low state. The name describes the I/O pin name that can be used in the application firmware.

PinDescriptor pinTable[] =
	{
// mark unused entries with GPIOX
// there is an implicit assumption that LEDs 1-4 and SW1-4 are first 8 entries
// single entry can describe multiple pins with same port/config (OR the bits together)
// for outputpins, REN is the init state (lo = 0, 1 = hi)
//
//                       +-------------- dir: 0 = input,   1 = output
//                       |  +----------- ies: 0 = rising,  1 = falling
//                       |  |  +-------- ren: 0 - pull,    1 - 3-state
//                       |  |  |  +----- inv: 0 - normal,  1 - invert
//                       |  |  |  |  +-- set: 0 = off,     1 = on
//                       |  |  |  |  |
//  pin    port   mask   |  |  |  |  |        Name
//-------|-------|-----|-----------------|------------------------------------------
/*   0 */ {PORT0, BIT3, {1, 0, 0, 0, 0}},	/*< LED5, SYSLED, OTA_READY, OTA_LOAD, OTA_DECODE, OTA_ERROR >*/
/*   1 */ {PORT0, BIT6, {1, 0, 0, 0, 0}},	/*< LED2 >*/
/*   2 */ {PORT1, BIT1, {1, 0, 0, 0, 0}},	/*< LED4 >*/
/*   3 */ {PORT0, BIT2, {1, 0, 0, 0, 0}},	/*< LED6 >*/
/*   4 */ {PORT0, BIT4, {1, 0, 0, 0, 0}},	/*< LED8 >*/
/*   5 */ {PORT1, BIT3, {1, 0, 0, 0, 0}},	/*< LED10 >*/
/*   6 */ {PORT0, BIT7, {0, 0, 0, 1, 0}},	/*< SW1 >*/
 
	};

We can walkthrough TestTerminal_Breakout.c now.

Application firmware(TestTerminal/Breakout) app explanation

The main.c calls TestTerminal_Breakout function in TestTerminal_Breakout.c

 void TestTerminal_Breakout()
	{
	printf(">>%s\n", __func__);
 
	// look up the i/o pins
	LED2 = GPIO.FIND("LED2");
	LED4 = GPIO.FIND("LED4");
	LED5 = GPIO.FIND("LED5");
	LED6 = GPIO.FIND("LED6");
	LED8 = GPIO.FIND("LED8");
	LED10 = GPIO.FIND("LED10");
 
	SW1 = GPIO.FIND("SW1");// deliberate switch!
 
	// create testButton event
	objectCreate(testButtonEvent);
	objectCreate(LedTimer, kIntervalTimer, TICKS((TCount*500)+100));
 
	// connect a handler to the event
	OnEvent(testButtonEvent, (HANDLER) testButtonEventHandler);
	OnEvent(LedTimer, (HANDLER) LedTimerHandler);
 
	// capture gpio interrupt to trigger the event
	// here we use the port interrupt for PB1 (BUTTON)
	// note: it is up to the developer to manage overlapping pin port IRQs!
	GPIO.SetIRQ(SW1, testButtonEvent);
 
	// enable interrupts for the button(s)
	GPIO.IFG(SW1, 0);
	GPIO.IEN(SW1, 1);
	GPIO.SET(LED2,0);
	GPIO.SET(LED4,0);
	GPIO.SET(LED5,0);
	GPIO.SET(LED6,0);
	GPIO.SET(LED8,0);
	GPIO.SET(LED10,0);
	cmStartTimer(LedTimer);
	printf("press button to change LED frequency ->\n");
	// wait for system events
	WaitEvent(0, 0);// never returns
	}

The GPIO.FIND("LED2") finds the port named under LED2 and its respective settings. Similarly the port and port settings of the other LED and Switches are found.

The GPIO.IFG() sets the interrupt flag bit and GPIO.IEN()sets the Interrupt enable bit. Now since all the events are set the system goes to event listening mode. This is done by using WaitEvent(0, 0); which waits for any event(LED timer and button trigger event in this case).

The objectCreate(LedTimer, kIntervalTimer, TICKS(100)); creates a timer under the name LedTimer(which is supposed to fire every 100 milliseconds). On this event (OnEvent(LedTimer, (HANDLER) LedTimerHandler);) the LedTimerHandler will be called. Also once the timer is created and the timer handler is configured we need to enable/start the timer using cmStartTimer(LedTimer);. Also make sure the timer is defined using DefineTimer(LedTimer);

The LedTimerHandler checks the LED light count and toggles the necessary LED based on the light count. The GPIO.SET() sets the LED2 to the toggle state specified(1-ON or 0=OFF).

DefineTimer(LedTimer);
void LedTimerHandler(TIMER t)
	{
 
	switch(count)
	{
	case 1:
	//debug("%d\n",count);
	  GPIO.SET(LED10,0);
	  GPIO.SET(LED2,1);
	 break;
 
	case 2:
	 //debug("%d\n",count);
	   GPIO.SET(LED2,0);
           GPIO.SET(LED4,1);
	 break;
 
	case 3:
	//debug("%d\n",count);
	  GPIO.SET(LED4,0);
	  GPIO.SET(LED5,1);
	 break;
 
	case 4:
	  //debug("%d\n",count);
	  GPIO.SET(LED5,0);
	  GPIO.SET(LED6,1);
	 break;
 
	case 5:
       // debug("%d\n",count);
	  GPIO.SET(LED6,0);
	  GPIO.SET(LED8,1);
	 break;
 
	case 6:
       // debug("%d\n",count);
	  GPIO.SET(LED8,0);;
	  GPIO.SET(LED10,1);
	 break; 
	}
		count = (count + 1)%7;
	}

The Button events are defined using DefineEvent()

Now let us take a look at the testbuttonhandlers.

The testButtonEventHandler stops the LED timer and resets the timer frequency and restarts the timer again. Hence everytime the button is pressed the LED toggle frequency is shifted between 100ms, 500ms and 1000ms. Remember the Interrupt flag and the interrupt enable bit needs to be set again using GPIO.IFG() and GPIO.IEN(). Otherwise the button will not trigger an interrupt again.

DefineEvent(testButtonEvent);
void testButtonEventHandler(EVENT e, word port, word mask)
	{
	  debug("%d\n", TCount);
	// called each time the BUTTON is pushed
 
	// print something
	printf("%s(%p, port=%u, mask=%8.8b)\n", __FUNC__, e, port, mask);
 
	// toggle LED1 (system LED)
	//GPIO.XOR(LED2);
        cmStopTimer(LedTimer);
	cmSetTimer(LedTimer, ((TCount*500)+100));
	debug("Frequency changed to %d ms\n", ((TCount*500)+100));
	cmStartTimer(LedTimer);
	TCount = (TCount+1)%3;
	// re-enable
	GPIO.IFG(SW1, 0);
	GPIO.IEN(SW1, 1);
	}

We have now accomplished setting up and accessing the switch and LED through Terminal or Breakout I/O ports and controlling them. The tutorial helped you setup LEDs and switches (I/Os) through the external terminal or breakout interface. Now you can try setting up and accessing more I/O ports available on the terminal board or breakout and observe your results. If you have not used both terminal and breakout board with this example, try setting up the other board you didn't use. The terminal and breakout boards can be swapped without any requirement for code to be flashed again and you should see the same results.

More Examples

More Boards

      Copyright © 2018-2019 Koliada, LLC
  • piep/examples/terminal.txt
  • Last modified: 2019/04/16 01:11
  • by venkat