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.

Question pertaining to UART_ECHO program

I have slightly modified the UART_ECHO program. The intention is that from the Launchpad + XBee system I send "0" and "1". The other system based on Arduino + Xbee intercepts the signal and blinks the LED. This works fine. However, whenever the "0" and "1" are send back from Arduino + XBee  system to Launchpad + XBee nothing happens. My understanding is that whenever the "0" or "1" is send to Launchpad + Xbee the UARTIntHandler will be invoked and the line " while(ROM_UARTCharsAvail(UART0_BASE))" will be executed with the code in this loop. In the debugger I never end up in this part of the code. Is my understaning correct? Does anyone knows what happens? (Definitely the two XBees communicate both ways. I have checked this using two systems based on Arduino + XBee. In this experiment I just want to replace one Arduino + Xbee with Launchpad + Xbee combination).

My code that I use is below. Any help greatly appreciated.

*************************************************************

include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"

int temp=0;

//*****************************************************************************
//
//! \addtogroup example_list//! <h1>UART Echo (uart_echo)</h1>A
//!
//! This example application utilizes the UART to echo text. The first UART
//! (connected to the USB debug virtual serial port on the evaluation board)
//! will be configured in 115,200 baud, 8-n-1 mode. All characters received on
//! the UART are transmitted back to the UART.
//
//*****************************************************************************
//*****************************************************************************//
// The error routine that is called if the driver library encounters an error.//
//*****************************************************************************
//#ifdef DEBUG
//void
//__error__(char *pcFilename, unsigned long ulLine)
//{
//}
//#endif


//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************
void
UARTIntHandler(void)
{
unsigned long ulStatus;
//
// Get the interrupt status.
//
ulStatus = ROM_UARTIntStatus(UART0_BASE, true);

//
// Clear the asserted interrupts.
//
ROM_UARTIntClear(UART0_BASE, ulStatus);
//
// Loop while there are characters in the receive FIFO.
//
while(ROM_UARTCharsAvail(UART0_BASE))
{
//
// Read the next character from the UART and write it back to the UART.
//
ROM_UARTCharPutNonBlocking(UART0_BASE,
ROM_UARTCharGetNonBlocking(UART0_BASE));

//
// Blink the LED to show a character transfer is occuring.
//
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

//
// Delay for 1 millisecond. Each SysCtlDelay is about 3 clocks.
//
SysCtlDelay(SysCtlClockGet() / (1000 * 3));
//
// Turn off the LED
//
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

}
}

//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void
UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
//
// Loop while there are more characters to send.
//
while(ulCount--)
{
//
// Write the next character to the UART.
//
ROM_UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
}
}

//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int
main(void){
//
// Enable lazy stacking for interrupt handlers. This allows floating-point
// instructions to be used within interrupt handlers, but at the expense of
// extra stack usage.
//

ROM_FPUEnable();
ROM_FPULazyStackingEnable();

//
// Set the clocking to run directly from the crystal.
//

ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
//
// Enable the GPIO port that is used for the on-board LED.
//

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//
// Enable the GPIO pins for the LED (PF2).
//

ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
//
// Enable the peripherals used by this example.
//

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable processor interrupts.
//

ROM_IntMasterEnable();
//
// Set GPIO A0 and A1 as UART pins.
//

ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
ROM_GPIOPinConfigure(GPIO_PA1_U0TX);

ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Configure the UART for 9600, 8-N-1 operation.
//

ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 9600,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
//
// Enable the UART interrupt.
//

ROM_IntEnable(INT_UART0);
ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

//
// Send 0 & 1.
//

while(1)
{
if(temp==1){
UARTSend((unsigned char *)"0", 1);
temp=0;
SysCtlDelay(6000000);
}

if(temp==0){
UARTSend((unsigned char *)"1", 1);
temp=1;
SysCtlDelay(6000000);
}

}
}

  • From a quick scan, it looks to me as if your code should be OK. I would suggest you check that the UART0RX pin (PA1) is correctly connected between the Launchpad and your XBee. If it is, put a scope on it and make sure you see received data being sent to the TM4C device at the expected baud rate of 9600bps.

  • Thank you very much for the advice. I will try to check this problem with the scope.

  • Beyond Dave's input - might this be either:

    a) absence of line-level translator (assumes external device employs RS232 signal levels - we don't know)

    b) some unwanted "cross-connection" suffered upon the UART_RX pin

    Suspect your Arduino board's UART signal handling/shifting (if any) must be modeled by your launchpad...

  • The setup that I had, were two Arduino's with the XBee shields and Xbee's on top. In this configuration everything works fine. I need to migrate to Launchpad so what I did I replaced one Arduino+shield+XBee with the Launchpad + Xbee. I thought that there would be no problem. I can send the data to Arduino and I can see the data (blinking LED). The problem is that when the Arduino responds the Launchpad does not see it. I don't know where the break is. I am running the program in the debugger so I see that the interrupt does not happen. I think Dave has an interesting idea with the scope. At least I can figure out if on the RX pin I am getting anything.

    That's the way I see thinks at this point. 

    Thank you for your advice and comments.

  • You need to insure that UART_RX signal level does not exceed the ratings of launchpad's MCU.  RS232 levels are far in excess of any MCU's capability.

    My suggestion was that you check your other, working board - for the presence of any signal level ICs (or resistor dividers) which may protect the Arduino MCU - and are not present w/in the launchpad...

    Suggest strongly that you cease all testing - and break the connection between Xbee and launchpad's UART_RX - prior to measuring the Xbee's signal output.  If that is an RS232 level - and no protection exists between it and your launchpad - unpleasant results are likely...

  • CB1 makes a good point. I was assuming that the XBee UART uses CMOS level signals rather than RS232 levels. Looking at the specs for a couple of XBee parts, they seem to use 3.3V UART signals so you should be OK. That said, I didn't look at all the datasheets and you didn't mention which part you are using so it is conceivable that there are some parts in the range with "real" RS232 outputs (though I think this is unlikely).

  • So my question is like this. If I try a system with two Launchpads+XBees talking to each other, will I avoid all the incompatibilities that you mention above? Will such experiment prove anything then? 

  • I think you will find there are no incompatibilities. Have you checked the UART0RX connection? The fact that you are seeing no interrupts from the UART when you say you are definitely receiving data on the XBee suggests to me that the data is not getting from the XBee to the MCU. If the transmit path is working, that suggests to me that it's not a serial parameter configuration error (the two sides must agree on the baud rate) so a bad RX connection to the MCU would be the first thing I would look at to debug the problem.

  • @Dave,

    Thank you - and agree most newer XBees employ "MCU friendly" levels.  But not all!  (clients have discovered - the hard way)

    Dawns that poster is using "essence" of the UART_Echo - and does not that "normally" see an interconnect - UART_RX to UART_TX?  (albeit different UARTs)

    And - should that connection remain - and should connected UART_TX pin be "active" - might not that cause signal contention or signal overlap???

    Choice of UART_Echo - in this usage - may prove unwise...

  • Now that you mention it, I failed to notice that the echo section of the interrupt handler is still there. This doesn't involve any hardware connection - just a software retransmit of all received characters. This will definitely cause things not to work as expected but it doesn't explain why no UART receive interrupts are being seen. The code:

      //
    // Read the next character from the UART and write it back to the UART.
    //
    ROM_UARTCharPutNonBlocking(UART0_BASE,
    ROM_UARTCharGetNonBlocking(UART0_BASE));

    causes all received characters to be retransmitted by UART0 so, as soon as the first character is received, I would expect to see the XBee get that character sent back to it. I don't know what the XBee will do but you would definitely get a bunch of extra transmit traffic that you didn't expect to see.

    Unless my understanding of the original problem is wrong, I still think we need to be certain that the UART0RX line is properly connected to the XBee's transmit line (and that the signal levels are compatible, given that you note that some XBee modules used different UART levels).

  • Dave, 

    Thank you for all the advice/hints. I can do some research now and I hope at least narrow down the problem. I have to run to the airport now. I will try all your suggestions tomorrow and will post the results.

    Thank you

    Damian

  • Thank you, Sir.  Have never/ever used that UART_Echo - but this sequence concerns. 

     // Read the next character from the UART and write it back to the UART.
    //
    ROM_UARTCharPutNonBlocking(UART0_BASE,
    ROM_UARTCharGetNonBlocking(UART0_BASE));

    Sequence here seems backward - appears to TX(Put) prior to RX (Get) - again I've noted but saw little point in such "echo."

    Your insight into the "excess" TX activity caused by "echo" surely concerns.  We've avoided launch - but many "echo style" programs do perform signal cross-over - as part of their test/verify...  (some may be "other" ARM vendors - we use many...)

  • Take a closer look at the parentheses and imagine the code correctly indented ;-)

  • Good grief - where is my pistol?

    Must have looked @ that 20 times - never noted the "short/unclosed" top line. 

    No excuse justifies - but that code's left alignment suggested, "Back to Back" Funcition calls - completely missed the "camouflaged" parameter...  (Would K&R approve?)

    Thank you, Dave.

    Must state again - your responsiveness, expertise and caring are always appreciated and much valued...

  • I tried two Stellaris Launchpads with the XBees and it does not work. I simply do not get the interrupt on either one. The problem is definitely with the interrupt handler. For example I don't have a problem to send character from the Stellaris Launchpad to the PC that has XBee mounted via USB adapter. I can start the X-CTU and I see the characters on the terminal editor.

     

  • Are you really using UART0 to connect the XBee? On the Launchpad, UART0 is connected to the in-circuit debug interface (ICDI). If you are using UART0, therefore, you will need to break that connection before connecting your XBee. If you connect your XBee to UART0 on PA0/PA1, I can imagine that transmit would work but both the XBee and the ICDI part will be driving the receive line and I strongly suspect that would cause you not to see valid receive data.

    On a Launchpad, I would expect you to be using the UART that is connected to pins 3 and 4 of the J1 Boosterpack connector. On Stellaris or Tiva Launchpad, this connects to UART1 on PB0/PB1.

  • Dave,

    Thank you for your answer. I believe that's my problem. I am connected to the RXD/TXD that is almost on the top of the board and I believe it translates to PA0//PA1. If this connection creates a conflict then that what  happens to me. I will try the PB0/PB1 combination for UART1. I am currently travelling so I will try it on Friday and post my results.

    Thank you

    Damian

     

  • Thanks a lot. That was a problem. I just was able to test it out and on UART1 - PB0/PB1 I am receiving data. 

    However, I have another question/problem. (I list the code below). I am sending a character every 5 seconds to the launchpad/XBee. And as I mentioned above it works just fine now. When I am in the debugger I can see the correct data. However, whenever I remove all the breaks and make the program go it somehow stalls. My observation is that when it empties the receiving buffer it stops working. Do you have any idea why it is happening?

    Actually I thought that the code will be hovering in the last while(1) loop and whenever the character is received it will interrupt into the UARTIntHandler and come back. However, this is not happening either. 

    *******************************************************************

    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/UART.h"


    int temp=0;
    int delay;
    unsigned char val;
    char value;
    static int a = 0;

    //
    //*****************************************************************************
    //
    // The UART interrupt handler.
    //
    //*****************************************************************************
    //

    void
    UARTIntHandler(void)
    {
    unsigned long ulStatus;
    //
    // Get the interrupt status.
    //
    ulStatus = ROM_UARTIntStatus(UART1_BASE, true);

    //
    // Clear the asserted interrupts.
    //
    ROM_UARTIntClear(UART1_BASE, ulStatus);
    //
    // Loop while there are characters in the receive FIFO.
    //

    while(ROM_UARTCharsAvail(UART1_BASE))
    {
    //
    // Read the next character from the UART and write it back to the UART.
    //
    value = ROM_UARTCharGetNonBlocking(UART1_BASE);

    a++;

    //
    // Blink the LED to show a character transfer is occuring.
    //

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

    //
    // Delay for 1 millisecond. Each SysCtlDelay is about 3 clocks.
    //

    SysCtlDelay(SysCtlClockGet() / (1000 * 3));
    //
    // Turn off the LED
    //
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

    }
    }

    //*****************************************************************************
    //
    // Send a string to the UART.
    //
    //*****************************************************************************
    void
    UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
    {
    //
    // Loop while there are more characters to send.
    //
    while(ulCount--)
    {
    //
    // Write the next character to the UART.
    //
    ROM_UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
    }
    }

    //*****************************************************************************
    //
    // This example demonstrates how to send a string of data to the UART.
    //
    //*****************************************************************************
    int
    main(void){
    //
    // Enable lazy stacking for interrupt handlers. This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //

    ROM_FPUEnable();
    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the crystal.
    //

    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);
    //
    // Enable the GPIO port that is used for the on-board LED.
    //

    //d ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    //d ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //
    // Enable the GPIO pins for the LED (PF2).
    //
    //d ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
    //d ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_2);
    //
    // Enable the peripherals used by this example.
    //

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    //
    // Enable processor interrupts.
    //
    ROM_IntMasterEnable();
    //
    // Set GPIO A0 and A1 as UART pins.
    //

    ROM_GPIOPinConfigure(GPIO_PB0_U1RX);
    ROM_GPIOPinConfigure(GPIO_PB1_U1TX);

    ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    //
    // Configure the UART for 9600, 8-N-1 operation.
    //

    ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 9600,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    //
    // Enable the UART interrupt.
    //

    ROM_IntEnable(INT_UART1);
    ROM_UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT);

    while(1)
    {

    SysCtlDelay(20000000);

    }

    }

  • Damian,

      It would be a great deal more helpful if you could describe what you are seeing (what do you mean by "stalling", for example? Is the program faulting? Is it stuck in your SysCtlDelay loop in main()? Is it stuck somewhere else?) Come to that, some indication of what you expect would also be helpful. A quick look through your source shows me that you seem to be receiving characters but doing nothing with them.

      Normally, posting a long chunk of code (with the formatting stripped so that it's difficult to read) isn't the best way to approach asking a question. Looking through this code, the only obvious problem I can see is that your UARTSend function won't work (you don't check to see if there's space available in the UART FIFO before writing characters to it so I reckon the majority of the data you are trying to write, unless you are really careful to call the function only with very short strings and only very seldom, will be thrown away). This function is never called, though, so that's unlikely to be directly responsible for the problem.

      Another problem, at least from a general interrupt handling philosophy point of view, is that you are delaying inside your ISR. This is normally considered to be a very bad idea. Rather than wasting time in interrupt context, set a flag and use some of the time you are already wasting in the main loop to flash your LED. That speeds up your interrupt handling and will likely prevent you from losing received data when you start wanting to receive more than a few bytes per second.

  • Dave,

    Thanks a lot for the e-mail and valuable pointers. I fixed the software problem that I mentioned in my last e-mail so everything works as expected. (I am a software guy so I came today to work committed to solve the program problems. I removed this time delay, cleaned up in general etc. and it works just fine.)

    Again big thanks for the hardware tip that you gave me couple weeks ago. This was a big help for me. Thanks.

    Damian