This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/EK-TM4C1294XL: Problems with using TI-RTOS for a simple ledToggle

Part Number: EK-TM4C1294XL


Tool/software: TI-RTOS

Hey, every one, I'm facing some problems with TI-RTOS. I'm trying to change the state of an LED(an onboard LED) by receiving characters on UART5, so, when some character arrives on UART5 RX the state of the LED is switched(On -->Off and Off --> On). To accomplish this I'm using TI-RTOS, the idea is basically use an HWI to detect the character in RX and use a Swi to switch the LED, here is the code :

/*Tivaware Drivers*/
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/uart.h"
#include "driverlib/pin_map.h"

#define WS_UART_BAUD_RATE 115200


/*BIOS include headers*/
#include <xdc/std.h>    /*xdc standards*/
#include <ti/sysbios/BIOS.h> /*includes Bios_start*/
#include <xdc/runtime/Log.h> /*includes LogInfo()*/
#include <xdc/runtime/System.h> /*UIA functions*/
#include <ti/sysbios/hal/Hwi.h>
#include <xdc/runtime/Error.h>
#include <ti/sysbios/knl/Swi.h>

/*globals*/
uint32_t g_ui32SysClock;
Swi_Handle uartSwi;


/*Function prototypes*/
void system_start(void);
void uart5_isr(void);
void ledToggle(void);
void create_swi(void);
void ws_init_serial(uint32_t system_clock, void (*pfnHandler) (void));



void main(void){
    system_start();
    BIOS_start();
}


void system_start(void){
    /* Set the clocking to run at 120MHz */
    g_ui32SysClock= SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                        SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
                        SYSCTL_CFG_VCO_480), 120000000);
    /*Enabling and configuring GPIO PORT*/
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);

    /*Turn on the LED*/
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0x00);

    ws_init_serial(g_ui32SysClock, uart5_isr);

    //software interrupt
    create_swi();
}

void ws_init_serial(uint32_t system_clock, void (*pfnHandler)(void)){

    /*Enabling Peripherals*/
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    /*Setting Up pins*/
    GPIOPinConfigure(GPIO_PC6_U5RX);
    GPIOPinConfigure(GPIO_PC7_U5TX);
    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    /*UART Configurations*/
    UARTConfigSetExpClk(UART5_BASE,system_clock,WS_UART_BAUD_RATE,
        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

   /*Setting up the UART HWI*/
    Hwi_Handle myHwi;
    Error_Block eb;
    /*starting the error block*/
    Error_init(&eb);
    /*starting the HWI object*/
    myHwi = Hwi_create(74, pfnHandler, NULL, &eb);
    if (myHwi == NULL) {
        System_abort("UART HWI creation failed");
    }
    /*Enable uart interruptions*/
    IntEnable(INT_UART5);
    UARTIntEnable(UART5_BASE, (UART_INT_RX | UART_INT_RT));


}

/*This function is used to trigger the swi*/
void uart5_isr(void){
    uint32_t ui32Status;
    /*Get the interrrupt status.*/
    ui32Status = UARTIntStatus(UART5_BASE, true);
     /*Clear the asserted interrupts.*/
    UARTIntClear(UART5_BASE, ui32Status);
    /*posting the Swi*/
    Swi_post(uartSwi);
}

void create_swi(void){
    Error_Block eb;
    Error_init(&eb);
    uartSwi = Swi_create(ledToggle,NULL,&eb);
    if (uartSwi == NULL) {
        System_abort("UART SWI creation failed");
    }
}

void ledToggle(void){
  if(GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1))  /*if LED is on*/
  {
      GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0x00);  /*Turn it off*/
  }
  else
  {
      GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1);    /*turn*/
  }

}

The code works well only when I receive the first character, when I send another ones the led doesn't switch.

  • I bet you have to read the character from the RX register before you will get another RX interrupt. I think you should add a 'data = UARTread()' call to your ISR. The UART gives you an interrupt when the RX register transitions from empty to full.  Since you never read it, it never went empty.