Embedded Electronics

Low Energy UART on Silicon Labs EFM32 using Emlib Libraries

Posted by Salman Khaja in: EFM32 emlib LEUART rs232 serial uart

Introduction

The EFM32 LEUART is a low energy UART which offers data transmission and reception by using a very minimal power. The design and implementation for LEUART has been explained in below sections

The EFM32 has two LEUART which needs only 32.768 KHz clock source to allow UART communication up to 9600 baud/s. So the EFM32 hardware is designed for operating in deep sleep mode called EM2 and it can wait for an incoming UART frame while consuming extremely little energy.

Another hardware feature of EFM32 LUART is that option to block incoming frames until a configurable start frame is detected. It also has an option to detect a configurable signal frame to indicate the end of transmission

An overview of the LEUART is shown in Figure 1


Data Frame

A EFM32 LEUART frame consists of a start bit, 8 or 9 data bits, an optional parity bit, and 1 or 2 stop bits. 

Figure 2 LEUART frame format
 
A transmission can be initiated by a start bit which pulls the line down from its idle high state. After transmitting the start bit, the data and parity bits are sent sequentially until the frame transmission is ended by the stop bits that holds the line high. Then the line either enters its high idle state, or a new start bit is sent. Technically, when a frame is ready to be transmitted, it is transferred from the transmit register to a shift register where the bits are sent one by one, least significant bit first.

Clock Sources

As like EFM32 timer clock section, LEUART can be driven from three different clock sources
•    the Low Frequency RF Oscillator (LFRCO)
•    the Low Frequency Crystal Oscillator (LFXO)
•    the High Frequency Core Clock divided by 2 (HFCORECLK_LE/2)

Baud rates

The baud rate offered on a 32.768 KHz clock is between 300 and 9600 Baud/second. For this example, baud rate selected is 9600 Baud/s

EFM32 LEUART configuration

Prior to start using of EFM32 UART some configurations must be performed to ensure that it works as expected. In order to facilitate that the below parameters must be configured
•    Set HFCLK clock
•    Enable clock for core
•    LEUART and peripherals   
•    Set start and signal frame for RX
•    Enable LEUART Interrupt

Software Example

This uart software mentioned below shows how to setup the USART in asynchronous mode (essentially a UART) for basic serial communication.  UART communication is very popular in embedded designs due to the low number of required pins (Transmit Data line, Receive Data line, and Ground).  There are even some "single-wire" UARTs available (shared TX/RX line), however these still require a common ground to operate properly.  UARTs work asynchronously, meaning there is no dedicated clock line between the 2 devices.  Therefore, each device needs to have a predefined matching data rate and frame format to actually communicate.

The LEUART is clocked with 32768Hz clock from LFXO crystal on EFM32 Giant Gecko Starter Kit. Clock to GPIO ports are enabled, then only RX and TX pins will work. Then we need to disable transmission and reception functionality of LEUART inorder to avoid accidental transmission and reception of junk values. Then we set baud rate to 9600. Baud rate register value is calculated using below formula and loaded to corresponding register.

 Value= (((32 *(clockFrequency)) / baudrate)-32)*8,  
       
 where clockFrequency=32768 and baudrate=9600

Configured the properties (stopbits, parity, data size etc.) of LEUART data frame. Transmission and reception are enabled. Transmitter pin PD4 as configured push-pull and receiver pin PD5 is configured as input pull-up mode. 

The code found below can tested using a custom expansion board which has LEUART0 available on an external connector.  A terminal emulator program (Tera Term) was used to display characters transmitted to and from the Giant Gecko.  

The serial port of the terminal program was setup with the following settings:
Baud Rate (bps):  9600
Data Bits:  8
Parity:  none
Stop Bits:  1
Flow Control:  none

Working (No loop back)
-    EFM32 board will transmit a message to TERATERM (eg: “EFM32 LEUART”)
-    Then it will wait for a character to receive from TERATERM. (Eg: “e” entered in teraterm)
-    EFM32 board will receive character sent from PC (Eg: “e”) and confirm this by transmitting back entered character to PC (EG: "Received char is: e");

 Working (with loop back)
-    Enable Loop-back and tristate in transmitter pin inorder to make transmitter pin in tristate mode  over  a  single  data-link whenever not transmitting data.
-    EFM32 board will transmit a string to TERATERM (eg: “
EFM32 LEUART”)
-    Then the string will loops backs and transmits again.
-    So the string (“
EFM32 LEUART”) will be transmitted continuously.

Code

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_leuart.h"

volatile uint32_t msTicks; /* counts 1ms timeTicks */

void Delay(uint32_t dlyTicks);

/**************************************************************************//**
 * @brief SysTick_Handler
 * Interrupt Service Routine for system tick counter
 *****************************************************************************/
void SysTick_Handler(void)
{
    msTicks++;       /* increment counter necessary in Delay()*/
}

/**************************************************************************//**
 * @brief Delays number of msTick Systicks (typically 1 ms)
 * @param dlyTicks Number of ticks to delay
 *****************************************************************************/
void Delay(uint32_t dlyTicks)
{
    uint32_t curTicks;

    curTicks = msTicks;
    while ((msTicks - curTicks) < dlyTicks) ;
}


LEUART_Init_TypeDef leuart0Init =
{
        .enable   = leuartEnable,       /* Activate data reception on LEUn_TX pin. */
        .refFreq  = 0,                    /* Inherit the clock frequenzy from the LEUART clock source */
        .baudrate = 9600,                 /* Baudrate = 9600 bps */
        .databits = leuartDatabits8,      /* Each LEUART frame containes 8 databits */
        .parity   = leuartNoParity,       /* No parity bits in use */
        .stopbits = leuartStopbits1,      /* Setting the number of stop bits in a frame to 2 bitperiods */
};

int main(void)
{
    /* Chip errata */
    CHIP_Init();

    /* Setup SysTick Timer for 1 msec interrupts  */
    if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ;

    /********Enable Clock to MCU core ****/
    CMU_ClockEnable(cmuClock_CORELE, true);
    /***Use LFXO clock as source to LFB peripherals**********/
    CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
    /*********Enable clocks to GPIO**********/
    CMU_ClockEnable(cmuClock_GPIO, true);
    /* Enable LEUART0 clock */
    CMU_ClockEnable(cmuClock_LEUART0, true);
    /* Reset LEUART */
    LEUART_Reset(LEUART0);
    /****Initialise LEUART*********/
    LEUART_Init(LEUART0, &leuart0Init);

    /* Route LEUART0 RX and TX to desired pins*/
    LEUART0->ROUTE = LEUART_ROUTE_RXPEN |
            LEUART_ROUTE_TXPEN ;

    /*****Configure GPIO ports as required for LEUART****/
    GPIO_PinModeSet(gpioPortD,                /* GPIO port */
            4,                        /* GPIO port number */
            gpioModePushPull,         /* Pin mode is set to push pull */
            1);                       /* High idle state */

    GPIO_PinModeSet(gpioPortD,            /* Port */
            5,                    /* Port number */
            gpioModeInputPull,    /* Pin mode is set to input only, with pull direction given bellow */
            1);                   /* Pull direction is set to pull-up */

    //#define LOOPBACK  /*Uncommant to run as loopback code.*/

#ifdef LOOPBACK

    LEUART0->CTRL|=1<<7;        //Enable loop back

    /* In this setup, the LEUART both receives and transmits data on the same pin. This is enabled by setting
    LOOPBK in LEUARTn_CTRL, which connects the receiver to the transmitter output. Because they are
    both connected to the same line, it is important that the LEUART transmitter does not drive the line when
    receiving data, as this would corrupt the data on the line.*/

    LEUART0->CTRL|=1;            //Enable tristated when the transmitter is inactive.
    /* When  communicating  over  a  single  data-link,  the  transmitter  must  thus  be  tristated  whenever  not
    transmitting data. If AUTOTRI in LEUARTn_CTRL is set, the LEUART automatically tristates LEUn_TX
    whenever the transmitter is inactive.*/

#endif



    /***********************************Working*******************************/
    /* If loopback enabled, LEUART transmit a character x, due to loop-back, character x loops back to Rx pin of MCU
     * LEUART receiver reads loopbacked character and again LEUART transmit received character x, due to loop-back, character x loops back to Rx pin of MCU again
     * Note: Since our serial to USB convertor do not support Loop-back/half duplex communication, we can't test it completely
     */

    /* If loop-back not enabled, then LEUART transmit a string "Transmission working" at first, then it wait for character to receive from PC and
     * transmit the received character to PC.
     */

#ifndef LOOPBACK
    int i;
    char outBuffer[500],a='\0';
    strcpy(outBuffer, "Transmission working");
    for (i=0;outBuffer[i]!='\0';i++) LEUART_Tx(LEUART0, outBuffer[i]);
    Delay(1000);
#else
    char x;
    x='a';
#endif


    while (1){
#ifdef LOOPBACK
        LEUART_Tx(LEUART0, x);
        x=LEUART_Rx(LEUART0);

#else
        a=LEUART_Rx(LEUART0);
        sprintf(outBuffer, "Received char is: %c\n",a);
        for (i=0;outBuffer[i]!='\0';i++){
            LEUART_Tx(LEUART0, outBuffer[i]);
        }
        Delay(100);
#endif
    }
}

0 comments:

Post a Comment

Newer Post Home
Powered by Blogger.

About Me

My photo
Salman Khaja
View my complete profile

Blog Archive

  • ▼  2016 (2)
    • ▼  December (2)
      • Example code for Segment LCD on EFM32 Giant Gecko ...
      • Low Energy UART on Silicon Labs EFM32 using Emlib ...

About This Blog

Featured Content

Follow Us

"© Copyright 2014" Eleven 40 Blogger · All Rights Reserved · And Our Sitemap · All Logos & Trademark Belongs To Their Respective Owners·
Template Developed By Blogging Recipes.