Search Microcontrollers

Wednesday, June 13, 2012

MSP430G2 - Serial communication 2 : RS485

I am going to use the Launchpad to test some serial communication over RS485.

RS485 is a popular serial protocol that can use only two wires and reach great distances an many devices can be connected on the same line, for this reason is quite popular with industrial instrumentation.

The problem with RS485 is that in it's two wire version it is a half duplex protocol, which basically mean it is synchronous : you cannot send and receive data at the same time.
While this is ok for many applications, it actually requires some attention on how you develop your protocol.

First, you normally need to have a single device (often called "master") initiating the communication and then you need to address a specific device which will respond ONLY when it will understand that your communication packet is over.

This is key, since in half duplex, when a device is in "write mode" it will not be able to read any data and will lose all the eventual bytes sent.

Some simple chips are available to "drive" the RS485, probably the most common one is the inexpensive MAX485 (which I am using).




These drivers feature on one side a TTL UART (RO/DI) and a R/W mode set pin (RE / DE) and on the other side they provide the A,B differential line for the RS485.

RO and DI are simply connected to a ttl uart TX and RX, while the RE/DE are connected together and managed with a separate ttl line (we will call it RW)
When the  RW line is high, then the driver is set to WRITE data and it will output into the differential line whatever arrives in the uart TX.
When RW is low, all the data incoming from the differential line is sent to the uart RX.

So, the basic operation mode is to have RW low, then, when we need to send out a data stream, RW is set to high, the data stream is flushed out the uart TX and finally RW is driven back to low.

On the MSP430 RW will be connected to any available GPIO line and the procedure that sends data packets overt the uart will manage to bring theis GPIO line up before sending and immediately down after sending. 

However, with more complex architectures things may not be that simple.
I am using the java RXTX GNU serial communication library to manage the communications  and I am experiencing issues both on pc platforms and on a beaglebone.
The reason is that the OS / library is buffering the data and if I simply raise RW, write, lower RW I normally end up by setting the driver in read mode before the buffer is actually flushed.

I tried to use the outputBufferEmpty method to switch back RW to low, but did not work either as the method is called sometimes before the actual data physically manages to escape the buffer.
Forcing a buffer.flush or adding a delay has the opposite effect : sometimes the slave device answers before the RW is driven to LOW, so the master misses part of the response.
This is happening at least on the beaglebone.

The purpose of my test is to use the MSP430 as an echo device that responds after a given delay, and check if the beaglebone can get the answer.
The idea is to send two bytes of data from the bone, they will represent a 16 bit integer, then the MSP430 will wait for a number of microseconds equal to that integer before responding with "OK".

The software on the bone will generate a ramp with the delay request and log the success/failure to receive the response.

Once the delay range is identified, a repetitive test will be performed with numbers around that value to calculate the percentage of success versus the delay.
Small data streams and long data streams will be used for the test. 
   
  

Tuesday, June 12, 2012

MSP430G2 - Serial communication 1

Most tutorials discuss about serial communication at a later stage as it might involve some more complexity.

I prefer to introduce it briefly here since I believe it's the easiest way to verify / debug the code execution.
We all have a PC, right? Let's use it to see what's happening on the Launchpad!

Serial communication can happen with different protocols, here we will discuss the RS232 kind of serial communication which is the easiest to interface with all the widely used PC operating systems.
Microcontrollers normally don't have a RS232 interface, instead they have a TTL UART which basically works the same except it does not provide any high level protocol feature, nor it boosts the signal to reach high distances with a decent speed.

As already anticipated in another post, the launchpad, similarly to most of the dev boards, includes an FTDI interface that emulates a serial over the USB connection.
From a software standpoint, on the connected PC, this can be treated as a normal serial port.

When deploying a project with a microcontroller, if the serial connection to a pc is still needed, a FTDI converted cable is needed (they cost around 8-10$).

Some processors from the MPS430 family include the USCI option, which provides, amongst other protocols, a hadrware TTL UART.
We will discuss this one today, even if it is possible to emulate a software serial using the GPIO and an internal timer.

Serial communication is defined with a few parameters :

  1. Baud rate (speed) [2400,9600,19200...115200]
  2. Byte length [7 or 8]
  3. Parity [even , odd, none, mark, space]
  4. stop bit [1,1.5,2]


All these parameters are related to the low level (physical) protocol, so they do apply to the TTL UART as well.
Instead we will not have any flow control option.

All the standard baud rates were defined using a 32.768 Hz Oscillator, therefore some of them may became unreliable when using a different frequency (unless it is a multiple of 32.768 Hz).
Also, having  a reliable oscillator is key in achieving high quality and fast serial connections, for this kind of job the external low frequency oscillator may help a lot.... but we will manage also without.

In a real project, if the components that need to exchange data are not too far away and can control the exact baud rate, higher frequencies might help to achieve faster transfer rates... but for this an I2C or SPI connection may be more suitable.

Did you manage to upload your code to the launchpad? If you did, it means that the serial communication worked smoothly.

Registers

As usual all the configuration is done via a set of registers, this is what the User guide reports :


The first register UCAxCTL0, USCI_Ax (x is normally 1, unless more than 1 USCI is available in the specific MCU) is used to set parity, stop bits, synchronous / asynchronous mode, data length, little/big endian etc...
When the value is set to 0 (default, all bits to zero) the configuration will be the most common one : 8,N,1 asynchronous LSB first.
If you need a different settings, check the user guide for details.

The UCAxCTL1 Control Register 1 is used to select which clock system is used to generate the needed baud rate.
This is set with the two highest bits :
  • 00 = UCLK
  • 01 = ACLK
  • 10 , 11 = SMCLK


The register is used also for managing breaks, address transmission and other functions, we will not discuss them here.

Now, once we have the reference clock and we want to generate a specific baud rate, we need to divide the clock frequency by setting the prescaler (divider).
UCAxBR0 and UCAxBR1 are used to set the divider :  The 16-bit value of (UCAxBR0 + UCAxBR1 × 256) forms the prescaler value.

Common values are shown in the picture below

In order to reduce errors the UCAxMCTL register is used to fine tune the modulation by using an oversampling technique (requires a high frequency BRCLK >=1MHz).

An online calculator ( http://mspgcc.sourceforge.net/baudrate.html ) allows to identify the proper registry settings depending on the BRCLK and of the desired baud rate




Finally when all the parameters are properly set up the UART is initialized :

UCTL0 &=~SWRST;

And then eventually the interrupt is enabled 

IE1 |= URXIE0 + UTXIE0;

Note that a different Interrupt is available for RX and TX

If it looks a bit complex... it's because it is complex, but luckily libraries are available online.

Next step will be to create a UART_setup function that uses the information in this post, then transmit and receive functions will be created.
Transmit and receive are quite symple : to transmit data is written to a UART TX register once it is ready to transmit (an interrupt flag can be checked for that).
Similarly to read data it's enough to read a UART RX register when the rx interrupt is raised.

A sample program

We are going to use the Hardware UART, this requires the two jumpers RXD and TXD on the launchpad to be set horizontally instead of vertically. 

#include <msp430g2553.h>

void main(void)
{
 // stop the watchdog

 WDTCTL = WDTPW + WDTHOLD; // allow debugging

 // configure the CPU clock (MCLK) 
 // to run from DCO @ 16MHz and SMCLK = DCO / 4

 BCSCTL1 = CALBC1_16MHZ; // Set DCO
 DCOCTL = CALDCO_16MHZ;
 BCSCTL2= DIVS_2 + DIVM_0; // divider=4 for SMCLK and 1 for MCLK

 // set the pin mode 3 for pins 1 & 2 of port 1 (Uart mode)

 P1SEL |= BIT1 + BIT2; // low bit = 1 for pin 1 and 2
 P1SEL2 |= BIT1 + BIT2; // high bit = 1 for pin 1 and 2

 // configure the UART

 UCA0CTL0 = 0; //UART mode, No parity, LSB first, 8 data, 1 stop
 UCA0CTL1 = UCSSEL_2; //use SCLK
 UCA0BR0 = 0x1A; //lower byte of UCBR0. 26dec  
                 //(4MHz / 9600 baud)  see table 15-5
 UCA0BR1 = 0x0; //upper byte of UCBR0.set to 0
 UCA0MCTL = UCBRF_1 + UCBRS_0 + UCOS16; //sets UCBRFx to 1,
                                 // UCBRSx tto 0 , UCOS16=1
 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI **
 UC0IE |= UCA0RXIE; // Enable USCI_A1 RX interrupt
 _EINT(); // global enable interrupts
 while (1); // process is managed by the interrupt vector
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
 UCA0TXBUF=UCA0RXBUF; // echo TX = RX
}


This is just an example program that configures the UART at 9600,8,N,1 and echoes any incoming char using the interrupt vector triggered by the RX signal.

The first instruction is used to disable the watchdog, this is a good idea to enable the debugger to stop anytime the code.
Then the MCLK and SCLK clocks are set to 16MHz and 4MHz respectively.
The hardware UART  RXD and TXD pins are on P1.1 and P1.2 (MSP430G2253, might be different on other devices, check the specific Datasheet), however their default configuration is to function as GPIO pins,  so we need to SELect the mode 3 for them, which corresponds to UART functions.
We normally need to set the direction for them, but this is not necessary if we select the UART mode, direction will be set automatically (table 16 of the datasheet).
Finally we need to setup the uart.
We want it to run using SMCLK as clock generator, which is configured to run at 4MHz, therefore we check the values in table 15-5 corresponding to the 4MHz BRCLK.
We notice that error rate is optimal at 9600 baud for this frequency and that the divider should be set to 26, RSx = 0 RFx = 1, UCOS16 = 1. All that is set in the UCA0MCTL register :
 UCA0MCTL = UCBRF_1 + UCBRS_0 + UCOS16; 

At this point we can reset the uart as we finished our configuration, then we can enable the RX interrupt and finally we can globally enable interrupts.

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)

Defines a function whose address is specifically set to match the address of the UART RX interrupt vector, meaning this function is called each time the RX interrupt is triggered.

In this function we just echo in the TX buffer whatever we read in the RX buffer

Primary resources availability



I am glad that beer is a renewable resource

Sunday, June 10, 2012

MSP430G2 - The GPIO and Pin Multiplexing

One of the most obvious ways to use a microcontroller is to read or write digital signals.

Examples of these activities are detecting if a push button is pressed (read) or lighting up an LED (writing).
The General Purpose Input Output is the easiest peripheral for these purposes.

In the MSP430G2 MCU family, there are up to 8 GPIO ports, each one of which controlling 8 digital I/O pins.
Each one of these digital I/O pins can be configured as Input OR Output via software, this configuration is referred to as DIRECTION of the pin.

Additionally pullup/down resistors can be activated on each pin.
This feature is extremely valuable for Input pins as it can prevent that their state is "floating" between levels due to currents captured from the nearby environment.
MCUs like the MSP430 have software configurable pullup or pullown resistors to force the digital levels to Vcc (pullup) or to GND (pulldown) when no specific signal is provided from outside.

These pull resistors are configured using the PxREN (Resistor ENable) registers.

Let's assume we want to use P1.5 as an output, we will then need to set to 1 it's directions bit in the P1DIR register.

P1DIR |= 0x10; // 10h = 0001 0000b 
               // we turn on the 5th bit in the register.

Then we will control the digital value by setting the 5th bit in the register P1OUT.

P1OUT |= 0x10;  // P1.5 will have Vcc value (1)
P1OUT &= ~0x10; // P1.5 will be driven down to GND (0) 

If we don't have any other pin configured as output in port 1, we can also disregard to save the status of the other pins and use

P1OUT = 0x10; 

Instead if we want to read the digital values from P1.5 :

P1DIR &= ~0x10; // we clear the 5th bit of the dir register to set the gpio pin to input 
myBooleanVariable = (P1IN & 0x10) > 0 ;  // we test the 5th bit, 
    // the result of (P1IN & 0x10) will be either 0 or 0x10

Let's imagine P1.5 is connected to a push button, normally open.
In that case we want a pulldown resistor to secure the level to 0.

P1REN |= 0x10; // setting the 5th bit of the P1REN register 
         // enables the pull (up or down) resistor.
P1OUT &= ~0x10; // When a pin is configured as input and the pull 
  // resistor function is enabled , the P1OUT register 
  // is used to specify the type  of resistor 
  // connection needed : 1 = pullup, 0 = pulldown                          

Digital inputs can be used to trigger interrupts, we will discuss this feature in another lesson.

Multiplexing 

Modern MCUs pack many different functions, but try to keep a reasonable number of pins to reduce the footprint on the PCB (Printed Circuit Board).
To achieve this, a single pin can be used for different purposes and configured via software.
As an example, a pin may be used as GPIO, ADC Input and UART RX.
Before using it , we need to ensure that the correct function is selected, this is done using the PxSEL and PxSEL2 registers.

When both pin specific bits are zero, then the selected function is GPIO.

P1SEL &= ~0x10; 
P1SEL2 &= ~0x10; 

Since a default function is assigned if no specific configuration is performed, it will be common that those instructions are not used.

When bit x of PxSEL is 1 and the same bit in PxSEL2 is 0, the "primary periphearal mode" is selected.
When both two are set to 1 , then the secondary peripheral mode is activated.

To discover which primary and secondary functions the pins have,  you need to refer to the data sheet of the specific MCU you are programming.

Basically 3 different configurations are normally available : GPIO, primary peripheral, secondary peripheral

MSP430G2 - The clock System(s)

There are plenty of features in the MPS430G2xxx MCU family, probably a good candidate to start with is the clock system(s).

I am using the plural because these processors include different clocks, each one of  them can then be sourced by different oscillators...
It looks quite complex, especially if you try to understand the C (or ASM) code that configures them, but there are some basic concepts behind that, if understood, help in shredding light on the matter.

First of all a clock system is something that is used to give the pace, typically for the execution of instructions.
The processor itself needs a clock to be able to execute a program, but some of it's components, such as timers (or the ADC) may eventually use a different clock to perform instructions at regular intervals.

A clock needs an oscillator signal in input, this can be generated by a crystal or by a digital device, then this signal is manipulated in a way that the frequency matches the needed one.
Typically the clock system contains a digital divider that lowers the input frequency dividing it by a programmable number.


The TI workshop material illustrates which clock systems are present in the MPS430G2, this explanation can be found here (MSP430G2xx User's Guide) and here (workshop guide, useful when watching the workshop videos)

A more detailed description is available in the user guide which can be downloaded here (MSP430G2xx User's Guide), you really need to download this one if you want to program this MCU.

In summary, there are 3 different clock systems (plus a separate one for the ADC) they are :
  1. MCLK : The Master Clock, it is used to drive the CPU
  2. SMCLK : The Sub Master Clock, used normally for "fast" peripherals
  3. ACLK : Auxiliary Clock - An independent clock used for "slow" peripherals
 Each clock system can be sourced by different oscillators (not all the combinations are possible) and can divide the input frequency using an internal divider.

The available oscillators are :

  1. DCO : Digital Controlled Oscillator - Internal oscillator used by default to drive the MCLK with frequencies from 0 to 16MHz
  2. VLO : Very Low frequency/power Oscillator - Internal oscillator used to typically for the ACLK clock
  3. XT1 : External low frequency crystal (optional)
  4. XT2 : External high frequency crystal (optional)

You should have the MPS430G2xx user guide open now at chapter 5. 
The beginning of the chapter explains in greater detail the few lines I introduced here, then it gets a bit technical -good for general understanding-, but the part that really we need is the 5.3.
Here we understand how to manipulate the registers to drive the clock systems the way we need.

Controlling the DCO 

Remember : DCO is an oscillator, not a clock, it is fed as input to a clock.
The DCO uses a single 8 bit register to configure the oscillating frequency, these 8 bits are grouped into two sets : the lower 5 (0-4 MODx) control the divider within the frequency range selected with the 3 highest bits (5-7 DCOx).

Setting the ACLK

Aclk is configured using the register BCSCTL1, also used to partially configure the external crystal oscillators.
BCSCTL1 is an 8 bit register where it is possible to set the frequency divider for ACLK (DIVAx , bits 4 and 5) with values : 1,2,4,8.
Bits 0-3 set the frequency range

Setting MCLK and SMCLK

Those two clock systems are configured via the BCSCTL2 8 bit register.
MCLK oscillator can be DCO,XT2,XT1,VLO, basically any available oscillator and this si selected witht eh two highest bits of the register (6-7 SELMx).
SMCLK instead can be sourced from the DCO or from the optional XT2 with bit 3 SELS.
There are then two bits per each clock to set the divider (1,2,4,8) being DIVMx and DIVSx

Settings the external (optional) crystal oscillators

These oscillators are set using the BCSCTL3 register.    
I am not detailing this part, let's just say an interesting feature is that different internal capacitors can be coupled to the external crystal by setting this register.

Getting started to code 

Finally, let's get to real coding.
You should check this video first : An Introduction to Code Composer Studio on the MSP430
A few things might be not completely clear, that's ok... we'll get here, you can also avoid soldering the optional crystal.
In the third video of the workshop the GPIO is used to blink an LED with a frequency set by a timer, whose frequency depends on a clock.
In the third exercise of the workshop we bump into this instruction :

BCSCTL3 |= LFXT1S_2;

 If you are not used to C syntax, this is a short version of  BCSCTL3 = BCSCTL3 LFXT1S_2;
What does it mean? BSCTL3 is the register that allows to configure the external crystal oscillator.
LFXT1S_2 is a constant (defined in the .h file) and its value is 0x20 (0010 0000).
By using an OR ( | ) operation with this constant on a variable we turn on in the variable (a register in this case) all the bits that are "1" in the constant leaving the others unchanged.
This is typical when we configure a register that contains different settings : we need to change just one part of it leaving the rest unchanged.

Example :

A = 1101 1011;
B = 0000 1110;

A |= B;


   1101 1011 |
   0000 1110
  ------------
A= 1101 111


Similarly, if we need to turn off some bits, we will use an AND operation ( & ) which is visible in the same exercise with the following instruction :

IFG1 &= ~OFIFG;

In this case the IFG1 (Interrupt flag register) is used to clear the flag OFIFG which is it's second bit (0000 0010).
We use and AND when we want to turn off (set to 0) one or more bits, and with this operation only the bits that are "1" in the constant will remain unchanged, the others will be turned off.
So, our goal was to turn off the second bit, therefore we need to first reverse all the bit of the constant.

0000 0010 -> 1111 1101 

This is done with a NOT operation ( ~ )    

There is another way of singularly set bits on some specific registers, this si done using the _bis_xx calls, which are a bit special since they are assembly calls from C.


_bis_SR_register(SCG1 + SCG0);

This is possible because the MPS430xx family supports some specific assembly instructions that can directly manipulate single bits.

Now, the next instruction should be a bit more understandable :

BCSCTL2 |= SELM_3 + DIVM_3;

The BCSCTL2 register configures MCLK and SMCLK, in this case we are targeting the CPU clock (MCLK) and we are setting two parameters :
1) We select the the source oscillator (SELM_x) 
2) We select the frequency divider divider (DIVM_x)

Notice that doing   BCSCTL2 |= SELM_3 + DIVM_3; is exactly the same thing as doing 
BCSCTL2 |= SELM_3;
BCSCTL2 |= DIVM_3;

SELM_3 is 0011b and it represents the VLO (low frequency) oscillator, by using this we are planning to use our CPU very slowly so we are reasonably targeting an application that does not require CPU intensive calculations or anyway an extremely quick response.
Since we are just blinking an LED...
Moreover we use the highest divider DIVM_3 = 0011b = /8 from the set [1,2,4,8] so we are driving the CPU as slow as possible.

Friday, June 8, 2012

MSP430G2 Tutorial - Microcontrollers

Hello,
I am learning to use & program the MSP430G2 microcontroller from Texas Instruments, so I thought I could write down my notes here as I am planning to use them for reference in the future, plus they might prove useful to others.
For this last reason I will add some background information, to make my minutes usable by others willing to learn.

Basic Concepts

You should be familiar with teh concept of what a microcontroller is, if not you should check here : http://en.wikipedia.org/wiki/Microcontroller

To put it plain simple a microcontroller is a microprocessor to which a number of different peripherals were added.
Each model has it's own mix of peripherals, providing different functionality, however the main "building blocks" you can expect to find are :
  1. Flash memory to store the code that will be executed
  2. RAM to store variables needed by your program
  3. Clock Systems : one or more are provided to service the CPU and it's peripherals. ome may use external crystals, some others might be "self contained"
  4. Timers to count delays, activate something periodically etc
  5. A Watchdog : a special timer that monitors the status of the code execution and resets the MCU if it appears "stuck"
  6. Serial communication (typically TTL UARTS, SPI, I2C)
  7. GPIO (General Purpose Inpu Ouutput) : allows to write or read digital signals
  8. ADC (Analogic To Digital Converter) : commonly a 10bit ADC to read analogic inputs, usually from sensors (temperature, voltage, current etc..)
  9. PWM (Pulse Width Modulation) : used to dim lights, drive electric motors etc.. 
  10. ....
Development boards

Normally microcotnrollers are programmed using a JTAG interface (http://en.wikipedia.org/wiki/Joint_Test_Action_Group) which is typically based on a SPI serial protocol (http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus).
This means that a "programmer" device is needed to send the firmware to the MCU, however for all the available MCU some dev boards were created, containing already the programmer circuit.
The most common solution nowadays is include a USB connection that emulates a serial port using FTDI chips (http://en.wikipedia.org/wiki/FTDI).

The MSP430G2 has a cheap and simple dev board created by Texas Instruments, called the "Launchpad".
www.ti.com/launchpad

Programming

Normally the software is created on a PC based IDE (there are various environments, some Opens Source, some proprietary, that support different devices) and then transferred (uploaded) into the flash ram of the MCU device, via USB cable.
The mainly used programming languages are C (ANSI C, not C++) and Assembly.
Being able to program an MCU requires a good understanding on how the hardware works and how the software can drive the various components of the MCU.
To turn on / off or to configure the peripherals the MCUs provide specific "registers", which are memory locations in which each bit has a specific function.
Since there might be hundreds of those individual bit "switches", normally a header file (.h) is provided so that they can be addressed by name.  

The best ide to work with the Launchpad is Code Composer Studio, which is based on Eclipse.
It can be downloaded here : http://www.ti.com/tool/ccstudio
It normally requires a license, but not for the MSP430G2, since the "code limitation" option is totally fine with these processors.

A great workshop which will be used as a reference in this tutorial can be found here : 

The present tutorial, in the next lessons, aims to provide further explanation on the topics covered by the launchpad workshop.
I strongly recommend to watch, at this point the introductory video of the workshop.


video platformvideo managementvideo solutionsvideo player
and



video platformvideo managementvideo solutionsvideo player