Accessing UART in MSP430F5418

UART is the traditional serial communication protocol used. It offers only two pins RX and TX for sending and receiving characters serially. A microcontroller can have more than one UART. For instance MSP430F5418 microcontroller has two UART’s (UART and enhanced UART). Just read the desired controller datasheet for getting the info.

There are two methods of using UART.

  • Polling mode

  • Interrupt mode

Commonly interrupt will be used for reception and polling is used for transmission. Here, I will use both methods. Code used in this article is for MSP430F5418 microcontroller. But, this can be ported to any microcontroller series with minor adjustments. Changes had to be made in the registers and interrupt handlers.

The USCI (Universal Serial Communication Interface) module in MSP430F5418 is responsible for serial communications. It has support for both synchronous protocols (SPI, I2C) and asynchronous protocols (UART, eUART). This controller comes with two USCI modules A and B.

  • USCI A controls UART, IrDA, SPI

  • USCI B controls SPI, I2C

IrDA is Infrared encoder/decoder and eUART is Enhanced UART which supports auto baud rate detection.

Prerequisites

Before sending/transmitting through UART there are various things which needs to be done. It includes selecting the RX/TX pins, USCI reset, selecting clock source, determining baud rate and finally enabling the USCI module…Let us look into the software part for more detail.

Configure the Clock source

Select the pins where the crystal is connected, using the PSEL instruction. After that, select the clock source. !!!yep I can your voice, what is the use of clock in asynchronous mode? The reason is that clock source is necessary for the generation of baud rate to synchronize both transmitter and receiver. I had selected SMCLK. You can select as per your wish. The available clocks are SMCLK, ACLK, UCAxCLK.

void clk_config(void) {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      P7SEL |= 0x03;                            // Port select XT1
      UCSCTL3 |= SELREF_2;                      // FLL Ref = REFO
      UCSCTL6 &= ~XT1OFF;                       // Set XT1 On
      UCSCTL6 |= XT1DRIVE_0 + XTS;              // Max drive strength, adjust
                                                // according to crystal frequency.
                                                // LFXT1 HF mode
      delay_ms(10);

      // Loop until XT1,XT2 & DCO stabilizes
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

      UCSCTL4 = SELA_0 + SELS_0 + SELM_0;       // Select ACLK, SMCLK, MCLK as LFXT1
}

 

Here, the clock source is selected as the high frequency crystal oscillator connected to PORT7 pins 0 and 1. As you can see from the code above, the drive strength is selected as per the crystal oscillator frequency. I had used 4MHz crystal, but you can connect up to the maximum allowed frequency.

Note: While using the external crystal it is necessary to check the oscillator fault flags. This will avoid you a lot of troubles. If your fault flag is set even you had connected the crystal properly, do check the soldering point of the crystal. A small dry soldering will spoil your day.

Initializing UART

First step is to select the RX/TX pin on Port3. Using PSEL enables us to select the UART pins as they are also used as general purpose I/O pins. Then, clearing UCSWRST bit in UCA0CTL1 register resets UART. Baud rate can be generated using external clock source (UCAxCLK) and internal clock sources (SMCLK, ACLK) depending upon the selection of UCSSELx bit. Then, the baud rate generator is configured for 9600 baud from 4MHz SMCLK. UCA0MCTL register is used to provide the necessary modulation. Finally, the UCSWRST is reset to initialize the UART module with the selected configuration. 

void uart_init_9600(void) {
      P3SEL = 0x30;                             // Enable TX/RX pins
      UCA0CTL1 |= UCSWRST;                      // Reset USCI
      UCA0CTL1 |= UCSSEL_2;                     // SMCLK
      UCA0BR0 = 0xA0;                            // Baud rate setting (4MHz 9600)
      UCA0BR1 = 0x01;                              //
      UCA0MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
      UCA0CTL1 &= ~UCSWRST;                     // Enable UART
      //  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
      //  __bis_SR_register(GIE);                   // interrupts enabled
}

Note: The UCSWRST bit should be set before configuring the USCI registers. Finally, it should be reset to enable UART.

Polling mode

In this mode the interrupts are not used. Instead the interrupt flags are polled in order to transmit and receive. The interrupt flags are always set during TX and RX irrespective of enabling or disabling interrupts.

Transmitting Characters

Transmission can be enabled by writing to UCA0TXBUF. If the buffer is empty UCTXIFG flag will be set, when it is full it will bet reset. Here, the flag is polled untill it is set. Once, it is set the data will be written to the buffer and the data will be transferred to the Transmit shift register then transmitted via TX pin. The TX flag will automatically reset once the data is loaded into buffer and will be set when it is transmitted.

void uart_put_char(char data)
{
while (!(UCA0IFG&UCTXIFG)); // Is USCI_A0 TX buffer ready?
UCA0TXBUF = data; // Transmit the data
return;
}

Receiving Characters

Method used for transmission is used for reception also. The UCRXIFG is polled until it is set. When there is data in UCA0RXBUF the flag will be set, once the data is read it will be automatically reset.

char uart_get_char(void)
{
    unsigned char rec_data;
    while (!(UCA0IFG&UCRXIFG));        // Is USCI_A0 RX buffer ready?
    rec_data = UCA0RXBUF;              // Read the data
    return rec_data;
}

Interrupt mode

Using interrupts is the recommended way over polling, because polling causes the time of the controller to be wasted. Hence, interrupts are used to save the processor time. Also, if you were not aware of the timing of the receiving character, using  interrupt will be handy. MSP430F5418 uses same interrupt handler for both transmission and reception. If the TX and RX interrupt are enabled the interrupt request will be generated during transmission and reception.

Uncomment the last two lines in uart_init_9600() function to enable interrupt. It is to be noted that the interrupt is enabled only for reception.

Interrupt handler

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
  switch(__even_in_range(UCA0IV,4))
  {
  case 0:break;                             // Vector 0 - no interrupt
  case 2:                                   // Vector 2 - RXIFG
    buffer = UCA0RXBUF;                     // Read the data
    break;
  case 4:break;                             // Vector 4 - TXIFG
  default: break;
  }
}

When a byte is arrived it will be stored in the UCA0RXBUF buffer, then the interrupt flag will be set and the RX ISR will be called. Inside the ISR, the data byte will be read, then the UCRXIFG flag will be automatically reset.

Delay function

Using the accurate delay in your code is recommended. When it comes to delay, many of us will use the for loop for generating the delay. But, that will not be accurate. TI doesn’t provides any delay function in their libraries. So, I had written a delay function, which will be far more accurate than the delay generated using for loop. 

I used for loop too :_)

inline void delay_ms(unsigned int k) {
    unsigned int j;
    for(j=0;j<k;j++) {
        _delay_cycles(4000);
    }
}
Advertisements

[Bash Tricks]: Re-run a range of ‘history’ commands

Tags

, ,

Sometime we may want to run a range of commands which was run in the past (captured in ‘history‘ command). This can be achieved using ‘fc‘ command.

Run ‘history’ command to find the range you want to re-run. For example, range from 1000 to 1010.

fc 1000 1010

The above command will copy the range of commands to a temporary file (same can be saved as shell script if you wish to re-run in future) and open it. The default editor is ‘vim’, use ‘:w [filename]’ to save to new file.

Running a single command from history can be done using ![command number in history]. For example ,

!1000 #This will run the command in 1000th line in history.
!1000:p #Just previewing without running

Note: ‘fc’ is bash built-in command. So no external package is needed.

Caution: The above command will be executed once you run ‘fc’. So beware of ‘rm’ and similar commands. Try out in /tmp

[Bash Tricks]: sudo to last run command

Tags

, , ,

To re-run the previous command, we can use the below special way in bash.


!! #This re-runs the previous command

But the question is, why should i run ‘!!‘ instead of using up arrow for previous command. One quick use case would be for running ‘sudo‘.

We often end up in ‘Permission denied‘ error and re-run the same command using ‘sudo‘ either by re-typing the whole command or by giving up arrow and navigate to the beginning using ‘Home‘ Button or ‘Side Arrows‘ or using ‘Ctrl + a‘ (as mentioned in Quick Linux CLI tips, at least it was the best way).

Another best way to re-run the previous command with ‘sudo‘ can be the following.


sudo !!

Re run the previous command with sudo

Re run the previous command with sudo

[Bash Tricks]: Editing wrongly typed command

Tags

,

We often used to type a lengthy command and realize the error after running the command. To correct this error, either we used to re-type the whole command or edit (after up arrow). This can be easily handled with bash tricks by using ‘^’.

Example:


cp /some/very/long/path/for/the/source /some/extra/loong/path/for/destination

Note the wrong spell ‘loong‘ in destination path. To resolve this, either we used to re-type the whole command or edit the spell for correct destination.

The above can be done in one liner bash tricks as below.


^loong^long

Editing wrongly typed command

Editing wrongly typed command

Linux Kernel Source browsing using cscope

Tags

Source code browsing in large projects is always tedious job to narrow down. In repositories like Linux Kernel, where the source code grows everyday needs regular updating and indexing to keep the search efficient and correct.

For browsing the source code in Linux Kernel, there are few options and built-in ways to remember when using ‘cscope‘ and ‘ctags‘. This blog shows those options.

Note: This blog will not explain how to use cscope and ctags for browsing.

Linux Kernel Make provides a direct way to index the source code by the following command.


make cscope tags

We can filter our search to specific architecture by specifying the ARCH option


make ARCH=arm cscope tags

Both of the above command is equivalent to the following cscope and ctags command.


cscope -bqkR ; ctags -R

Where,

-b Build the cross-reference only

-q Enable  fast  symbol  lookup  via  an  inverted index

-k For kernel mode (avoids indexing /usr/include and other system directories)

-R Recursive for all directories

Refer man page of cscope and ctags for more options.

VLSI in a Layman Language

Tags

, ,

After a many days, I find some time to open up a word editor to put on my thoughts about VLSI, Since I am Master degree graduate in VLSI, and I am working in the field of VLSI, I plan to make a blog on the topic ”VLSI in a  layman language”. In recent years, the term VLSI became a very fancy and talks of the town. When I was doing my undergraduate in electronics and communication, a decade ago, the term VLSI with respect to the tools and advance in technology make a popularity in midst of engineers. In this blog I plan to put up, what is my understanding about VLSI.

Flow

The term VLSI stands for Very large scale integration, which everyone will know by this time. What is actually VLSI? As like other engineering phases, VLSI too has Design, Verification and Implementation. The VLSI design starts with Requirement specification, which will be collected from the customer. The next will be deciding the architecture; it’s nothing but the high level (Block diagram) functionality of the circuit (Integrated Circuit (IC)). Following the architecture design, the architecture implementation using the EDA (Engineering Design Automation) tools is carried out. The first step in building the architecture is, implementation of the logics using Hardware description language. As in standard, we have two hardware description languages in use, VHDL (VHSIC (Very High Speed Integrated Circuits) Hardware Description Language) and Verilog HDL. The code written in the HDL which describes the circuit is known as RTL (Register Transfer Level), which means the lowest level of abstraction that can be described using HDL is the register level.

Once the Coding is done, the RTL needs to be verified in terms of functionality, power; area etc., the modern EDA tools provides more easy way to do these sophisticated processes. Now comes the question of FPGA or ASIC. What are these two things? FPGA stands for Field Programmable Gate Array and ASIC for Application Specific Integrated Circuit. On proceeding with the process of manufacturing the IC, few more steps are involved which will involve more cost and time. On manufacturing the functionality as IC, if there is any bug involved in the function, the whole effort will be wasted; hence FPGA provides the door step to build the prototype, to verify the functions before making the IC as Application specific. However, in some cases the Application specific IC may not be available. In such cases, FPGA can be directly used. Shown in figure is the ASIC manufacturing process.

Intel Edison Stop Arduino functionality

After checking the first program with Arduino IDE in Intel Edison from “Intel Edison Arduino IDE Programming with Linux“, we might get annoyed of blinking LED when working with Linux stuff. We may don’t want Ardunio programs (sketches in Intel Edison world).

How to disable or stop this Arduino functionality in Intel Edison?

Quick workout:

Stop or Disable the clloader service:

  • systemctl stop clloader or systemctl disable clloader
  • rm /sketch/sketch.elf; systemctl restart clloader

Explanation:

The above mentioned commands will stop the “clloader” service, which is responsible for starting the Arduino sketches in Intel Edison after getting the ELF file over zmodem.

‘systemctl’ is the command used to stop service in systemd.

Note:

You can get started with Intel Edison by following this blog.

 

Intel Edison Arduino IDE programming with Linux

Tags

Before Getting into the first program you may need to refer the “Intel Edison Getting Started Linux” to get started if this your first look into Intel Edison.

This Blog “Intel Edison Arduino IDE programming Linux” will guide you to write/use the first program in Adrunio IDE in Linux Platform.

Introduction:

Intel Edison cannot be used as a standalone unit or hardware. To make it functional, we need some kind to breakout broad by which we can power Intel Edison and other interfaces can be used.

Officially there are two supported breakout boards in market.

Featured Image Arduino

  • Mini Breakout board with minimal features.

Intel Edison in Mini Breakout board Separated

Installing Arduino IDE in Ubuntu Linux:

Step 1:

  • Download the supported Arduino IDE from Intel website.
  • Extract the Arduino ZIP file.

01 Intel Edison Arduino IDE

  • Extract in Ubuntu (You can also use “unzip” in CLI)

02 Intel Edison Arduino IDE Extracting

03 Intel Edison Arduino IDE Extracting in progress

04 Intel Edison Arduino IDE extract success

Step 2:

  • Install java. Arduino needs ‘java‘ to run.
  • If ‘java‘ is already installed in your system, you may see the below screen.

Intel Edison Java Installed

  • Else, you can install ‘java’ by running ‘sudo apt-get install default.jre‘ package.

Intel Edison Installing Java

Step 3:

  • Navigate into the path in Command Line or Terminal
  • Run the ‘sudo ./arduino‘ file.

05 Intel Edison Running Arduino IDE

  • This will open up the Arduino IDE Graphically.

Step 4:

  • Select the blinking LED example by navigating into “File -> Examples -> 01 Basics -> Blink

06A Intel Edison LED Blink example opened

Step 5:

  • Configure the Board type as “Intel Edison” under “Tools -> Board -> Intel Edison

06B Intel Edison Arduino IDE selecting board type

  • Configure the serial port as “/dev/ttyACM0” under “Tools -> Serial Ports -> /dev/ttyACM0

06C Intel Edison Arduino IDE selecting serial port

  • Note: Connecting two Micro USB to USB in PC/Laptop is mandatory here. Refer “Getting Started” guide for better pictures.

08 Intel Edison Powering and Debugging cable connection 09A Intel Edison Connting and powering with Laptop

Step 6:

  • Upload this program to Intel Edison. Click Upload button or ‘Ctrl + u‘ or “File -> Upload”
  • This uploading process includes compilation and uploading.

07 Intel Edison Highlight Upload button 08 Intel Edison Arduino IDE Compiling LED Blink example 09 Intel Edison Arduino IDE uploading LED Blink sketch 10 Intel Edison Arduino IDE LED blink uploading done

  • The above four images explains the various stages. Refer End of this blog for errors.

Step 7:

  • Now the LED 13 on Arduino breakout board should be blinking (with 1second in on state and 1second in off state).
  • You can also verify this by logging into Intel Edison over serial console (via minicom). Refer Getting started guide to know how to connect Serial console using minicom.

11 Intel Edison Running the sketch

  • In the above image, sketch directory will contain the latest uploaded sketch (ELF) file.
  • Process listing shows the “sketch.elf” is running. This process is started by “clloader” daemon which watches the zmodem.

Beware of Errors:

  •  They are two most common error in Arduino IDE programming.
    1. Missing the “Board type” selection under “Tools -> Board” i.e. in this case “Intel Edsison” and Missing the Serial port selection under “Tools -> Serial Ports” i.e. in this case “/dev/ttyACM0
    2. If you are using both Micro USB (one for programming and other serial debug using minicom), you will see two serial ports under “Tools -> Serial ports” i.e. “/dev/ttyUSB0” and “/dev/ttyACM0“. Serial port should be selected as “/dev/ttyACM0“. Selecting “/dev/ttyUSB0” here will result in Upload Error i.e. “Transfer Incomplete“. Refer this failure log for more details.

Refer this article to understand the difference between /dev/ttyACM and /dev/ttyUSB.

Failure log snip:

rz-sh: rz: not foundroot@edison:~# B00000000123273-sh: B00000000123273: not foundroot@edison:~# Retry 0: Got TIMEOUT
Retry 0: Got TIMEOUT

If have done all the previous steps correctly, you might see a similar success log in your terminal (where you have opended/run ‘sudo ./arduino‘)

Future Blog will cover:

  • How Arduino IDE i.e. controller code runs on Intel Edison platform?
  • How sketches are automatically started using clloader?
  • How “Blink Program” runs without “main” function?

Follow us for more updates : https://pgtux.wordpress.com/2014/11/12/how-to-follow-penguintux/