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.

UART GPIO_PA5_U3TX not working

Other Parts Discussed in Thread: TM4C1294NCPDT

Hi all,

Basics: the IC is TM4C1294NCPDT, (same one used on the EK) the board is custom. Using CCSv6.

Our board uses 8 uarts. To test the hardware, we wrote a basic test program that sends bytes via UART in one port and expects to receive them in another. Everything works, except transmitting via PA5_U3TX. I am probably blind to something with so much cut and paste... but maybe there's a special requirement to configure pin #38 that I failed to read.

UART configurations are:

void InitCN5A(void)
{
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);  // Pins UART1 GPS_TX e GPS_RX
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); // Enable GPS Uart1
    GPIOPinConfigure(GPIO_PB0_U1RX);
    GPIOPinConfigure(GPIO_PB1_U1TX);
    ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    ROM_UARTConfigSetExpClk(UART1_BASE, g_ui32SysClock, 912600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
}


void InitCN7(void)
{
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);  // Pinos RX5 (U3RX/PA4/37) e TX5(U3TX/PA5/38)
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3); // Enable Uart3
    GPIOPinConfigure(GPIO_PA4_U3RX);
    GPIOPinConfigure(GPIO_PA5_U3TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    ROM_UARTConfigSetExpClk(UART3_BASE, g_ui32SysClock, 912600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
}

And the loop where the things should get tested is:

	case 25: // Send some char
		sent_char = 99;
		ROM_UARTCharPutNonBlocking(UART1_BASE,sent_char);
		char_count++;
		systick_task = 26;
		break;
	case 26: // Wait for received character on U3RX
		// Test without interrupt
		while(ROM_UARTCharsAvail(UART3_BASE))
		{
			received_char = ROM_UARTCharGetNonBlocking(UART3_BASE);
		}
		// End of debug test
		if (received_char)
		{
			if (received_char == sent_char)
			{
				char_matches++;
			}
			received_char = 0;
			systick_task = 25;
		}
		if (systick_counter == systick_next_count)  // End of test time
		{
			systick_task = 27;
		}
		break;

	case 29: // Send some char
		sent_char = 88;
		ROM_UARTCharPutNonBlocking(UART3_BASE,sent_char);
		char_count++;
		systick_task = 30;
		break;
	case 30: // Wait for received character on U1RX
		// Test without interrupt
		while(ROM_UARTCharsAvail(UART1_BASE))
		{
			received_char = ROM_UARTCharGetNonBlocking(UART1_BASE);
		}
		// End of debug test
		if (received_char)
		{
			if (received_char == sent_char)
			{
				char_matches++;
			}
			received_char = 0;
			systick_task = 29;
		}
		if (systick_counter == systick_next_count)  // End of test time
		{
			systick_task = 31;
		}
		break;


This piece of code is just the relevant part for a complete loop back test. If you'd need the rest of the case statements I'll be happy to post, but I suspect that I am really forgetting something basic... The same thing is working for other uarts, but I can't get U3 to transmit anything!!!

To make sure it is not a hardware problem, I configured the same pin as GPIO, send a high signal via PA5, which was properly received on the other end of the circuit.

Help appreciated!!!

  • Hello Bruno,

    I just took the part of the code for UART and GPIO Initialization on a TM4C1294NCPDT part and sent a fixed character of 0x38 and saw it coming out on the scope. So the Transmission section of the code is clean for sure.

    You may need to check how it is wired to the UART-1 RX Pin

    Regards

    Amit

  • Along with wiring/shorts/opens have you a 2nd board.  Always difficult to bring up a brand new board - by itself.  Our group never builds/buys less than 3 - which enables famed, "A-B" comparison/test.

    The fact that you report receiving signal when that pin is converted to GPIO may indicate an error @ your UART RX side SW configuration.  That's where I'd place my money.

    By my read of your testing - and Amit's verification of UART-3's code - appears that NOT wiring but SW issue is plaguing your UART-3 TX!  (this proved by your (claimed) success of reading when pins in question switched to GPIO)

    Dawns too that simple "re-route" of UART-3 to (another) working UART will quickly aid in such resolution.

    I'd add that having a "known good" UART set-up surely beats your "loopback" test method.  We always employ such - and bring up each UART independently - you may be "held hostage" by your test setup - not any MCU flaw! 

    Using the "DUT" to "test itself" - while inventive & resource conserving - is not best/brightest nor well recognized as a proper test/troubleshooting technique.  (i.e. loopback provides less value than separate UART device employed for test/verify.)

  • Hello cb1

    Poster's requirement was that on the UART TX pin. With the same configuration it works, so I am not sure if it is indeed a SW issue alone as it could be wiring on a custom board. However most of the other code is not visible, it could be SW as well due to reconfiguration of the IO.

    Perhaps a dump of the GPIO Port Pins in memory browser may tell more info.

    Regards

    Amit

  • Hello Amit,

    Here we disagree - my read reveals poster to (claim) that UART_3_TX "fails" due to his inability to "read" UART data on a connected (yet different) UART_RX pin.  His test methodology is very non-standard - unwise (as stated) to rely upon the DUT to serve as "test vehicle."  (Yes I know loopback is a convenience - but a very "iffy" one when board is new - and custom.) 

    Note that poster claims that when he changes UART_3_TX to GPIO he reports, "valid receiption."  Yet - in both cases - we're at the mercy of the poster's interpretation of just what qualifies as "valid."  Unexplained thus far - not good.

    You reported your recognition of 0x38 - at the UART-RX pin connected to UART_3_TX.  May I ask if you read that value w/in the UART Register for that UART-RX Port?  (you might have simply observed TX on a scope)

    I'd bet that sloppy "cut/paste" caused some butchering of (baud rate, likely suspect) some aspect of the UART set-up/config.  (Even the presence of excess "C" on that pin may cause a problem - poster's board is custom - but (again) as he reports "receiving" via GPIO - I'd say a miswire is unlikely...)  Stack of chips on butchered SW config or C sitting on that line...

    I do stand by my (earlier/bold) point - "Routing UART_3_TX to a "working" UART_RX pin" is best/brightest means of quickly resolving!

  • Hello cb1,

    Fair enough. Yes, as I mentioned earlier, I did check it on a scope as the poster's original thread, I interpreted as TX Pin is working in GPIO Mode. Now from a testing perspective, indeed a loop-back is often unwise as two-wrongs may correct each other. I know this method has been tested albeit between UART-3 and UART-4 instead of UART-1 as the poster mentioned. Worthwhile to make the change, but to see the full code would also be worth the analysis.

    Regards

    Amit

  • Gentlemen,

    Thanks for your comments. The initial text on such messages can never be clear enough, but you took a good understaing and I appreciate the efforts on helping.

    These are some statements that will further add information:

    - We built 5 boards. The same situation applies to all five of them.

    - The "problem" itself is that U3TX does not transmit. The testing software expects to see the transmitted character as a received byte on a different port, and during the test if fails. But placing the scope on the U3TX pin also shows nothing (a much more reliable and electric test, I agree!)

    - Any combinations of Tx and Rx between the 8 ports work fine with that code, except trying to send via U3TX to any of the other ports. Again: nothing comes out of U3Tx on the 5 boards we built.

    - Configuring that same U3Tx pin as a GPIO and creating some sort of square signal there works perfectly on the scope: the pin is electrically working, is properly soldered, and there are no weak pull ups or downs to hinder.

    So my guess is one of two:

    1- There is some special configuration required on the multiplexing of pin 38/PA5/U3TX that I failed to read (I remember that some pins require a separate register unlocking before changing their fuctions), or

    2- I have 5 bad CPU's (very unlinkely, but due to the non-existance of these chips in the market, we did cannibalize lots of Evaluation Kit boards to populate all our boards of this development, which could increase the odds). I wonder if there is any other suggestion for a test here?

    Or maybe I just cut/paste something stupidily wrong and my tired eyes can't see it?

    I can send the whole testing code if you'd like, but the wiring to test it all might be a bit tiring... Let me know if you are willing to take a look and I will post right away!

    HOLD EVERYTHING! I WROTE A UART3TX CODE ONLY, AND IT WORKS... I WILL FIGURE OUT WHAT'S WRONG LATER TODAY AND POST HERE.
    NOPE... THE PHYSICAL PORT ACTUALLY WORKS WITH SIMPLER CODE, BUT I HAVE NOT FOUND OUT WHAT IS WRONG... SEE LONG POST BELOW.

    Thanks again!

  • Hello Bruno

    Run the original code and check the GPIO register space for configuration. It should be from 0x400-0x420 and 0x500-0x540 that should tell if there was a reconfiguration.

    Regards

    Amit

  • cb1_mobile said:
    Stack of chips on butchered SW config or C sitting on that line...

    Methinks time for the "house" to pay up - clearly the proper UART Config has been missed or "eaten!"  You may deliver the cash to the bright red sports car - and recall that the celebratory beverage should be "shaken not stirred..."

  • For those who like those games of finding seven differences...

    These codes, although running in our custom board, can be easily tested on a TM4129 Evaluation Kit, as the pins for the LEDs are the same. Just loopback Tx and Rx on UARTs 1 and 3.

    Two attached codes. The first is very clean, and just with the scope looking at the LED's I can see that both UARTs are actually working. These use simple loopback cables in each UART, not crossing between them. The hardware is indeed working fine.

    The second is the reduced code of what began as my complete test program. This one uses UART0 as a console. Misteriously, the code shows "PASS" on UART1 (cases 24-27) and "FAIL" on UART3 (cases 28-31). To easily evaluate the correctness of the program sequence, replace all UART3_BASE for UART1_BASE on the second set of statements (Cases 28-31), the console shows a PASS result on both cycles (meaning the program sequence is actually proper).

    Why doesn't UART3 work on the second code???????? I will probably give up and rewrite the whole thing, as I'm sure the hardware is fine. But that's an example that is really bugging me this week and I could not find the culprit!

    Code A:

    //*****************************************************************************
    #include <stdint.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    
    // Definição de Macros
    // =========================================================
    #define CLOCK_SYSTICK 	100
    #define TASK_SYSTICK 	0x01
    
    // declaracao de variáveis globais
    //*****************************************************************************
    uint32_t g_ui32SysClock;
    char received_char;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    // The UART interrupt handler.
    //*****************************************************************************
    
    
    void InitGPIO(void)
    {
        // Configurações de LEDS e BOTOES da Placa
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);  // Pino BT1
        ROM_GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_4);  // BT1(PK4/63)
        GPIOPadConfigSet(GPIO_PORTK_BASE, GPIO_PIN_4, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU); // Weak Pull Up Required for this push-button
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);  // LEDS de STATUS
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1);  // LED1(PN0/107), LED2(PN1/108)
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);  // LEDS de ETHERNET
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4);  // LED_GREEN_LINK(PF0/42), LED_RED_ACT(PF4/46)
    
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);  // Pinos de Habilitação dos Transceivers
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_2 | GPIO_PIN_3);  // TX_EN(PH2/31), RX_EN(PH3/32)
    }
    
    void InitCN7(void)  // Linhas TX5 e RX5 do esquema elétrico, que estão ligadas em U3TX e U3RX
    {
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);  // Pins RX5 (U3RX/PA4/37) e TX5(U3TX/PA5/38)
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3); // Enable Uart3
        GPIOPinConfigure(GPIO_PA4_U3RX);
        GPIOPinConfigure(GPIO_PA5_U3TX);
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5);
        ROM_UARTConfigSetExpClk(UART3_BASE, g_ui32SysClock, 912600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
    }
    
    void InitCN5A(void) // É o mesmo DB9 do GPS, configurado de maneira diferente para os testes de UART1
    {
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);  // Pinos UART1 GPS_TX e GPS_RX
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); // Enable GPS Uart1
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        ROM_UARTConfigSetExpClk(UART1_BASE, g_ui32SysClock, 912600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
    }
    
    
    //*****************************************************************************
    int main(void)
    {
    	g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
    
        InitGPIO(); 		// Inicializa LEDS e BOTOES
        InitCN7();			// Inicializa os pinos do conector
        InitCN5A();			// Inicializa os pinos do conector
    
        while(1)
        {
        	ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4,(ROM_GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4) ^ GPIO_PIN_4)); // // Toggle RED LED
    
        	// Teste da UART3 (CN7)
        	ROM_UARTCharPut(UART3_BASE,0x38);
        	while(ROM_UARTCharsAvail(UART3_BASE))
        	{
        		ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0,(ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_0) ^ GPIO_PIN_0)); // Toggle LED1
        		received_char = ROM_UARTCharGet(UART3_BASE);
        	}
    
        	// Teste da UART1 (CN5A)
        	ROM_UARTCharPut(UART1_BASE,0x38);
        	while(ROM_UARTCharsAvail(UART1_BASE))
        	{
        		ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1,(ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1) ^ GPIO_PIN_1)); // Toggle LED2
        		received_char = ROM_UARTCharGet(UART1_BASE);
        	}
        }
    }
    

    Code B:

    #include <stdint.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    
    // Definição de Macros
    // =========================================================
    #define CLOCK_SYSTICK 	100
    #define TASK_SYSTICK 	0x01
    
    // declaracao de variáveis globais
    //*****************************************************************************
    uint32_t g_ui32SysClock;
    volatile uint32_t task_enable;
    uint32_t test_mode = 1;
    char received_char;
    char string_char[32];
    uint32_t auxiliar = 0;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    // The UART interrupt handler.
    //*****************************************************************************
    void UART0IntHandler(void)
    {
        uint32_t ui32Status;
        ui32Status = ROM_UARTIntStatus(UART0_BASE, true);
        ROM_UARTIntClear(UART0_BASE, ui32Status);
    }
    
    void UART1IntHandler(void) // GPS
    {
        uint32_t ui32Status;
        ui32Status = ROM_UARTIntStatus(UART1_BASE, true);
        ROM_UARTIntClear(UART1_BASE, ui32Status);
        while(ROM_UARTCharsAvail(UART1_BASE))
        {
        	received_char = ROM_UARTCharGetNonBlocking(UART1_BASE);
        }
    }
    
    
    void UART3IntHandler(void)
    {
        uint32_t ui32Status;
        ui32Status = ROM_UARTIntStatus(UART3_BASE, true);
        ROM_UARTIntClear(UART3_BASE, ui32Status);
        while(ROM_UARTCharsAvail(UART3_BASE))
        {
        	received_char = ROM_UARTCharGetNonBlocking(UART3_BASE);
        }
    }
    
    void SysTickIntHandler(void)
    {
    	task_enable |= TASK_SYSTICK;   // Enable SysTick Task
    }
    
    //*****************************************************************************
    // Send a string to the UART0 - Console
    //*****************************************************************************
    void UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
    {
        while(ui32Count--)
        {
            ROM_UARTCharPut(UART0_BASE, *pui8Buffer++);
        }
        ROM_UARTCharPut(UART0_BASE,0x0A);
        ROM_UARTCharPut(UART0_BASE,0x0D);
    }
    
    void SysTickInit(void)
    {
    	  ROM_SysTickPeriodSet(g_ui32SysClock/CLOCK_SYSTICK);   // CLOCK_SYSTICK clicks per second
    	  ROM_SysTickEnable();
    	  ROM_SysTickIntEnable();
    }
    
    void InitUART0(void)
    {
        // Congigurações da Porta Serial UART0 (conector DB15 Service)
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);  // Pinos UART0 TX e RX (Console)
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        ROM_UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
    }
    
    void InitGPIO(void)
    {
        // Configurações de LEDS e BOTOES da Placa
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);  // Pino BT1
        ROM_GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_4);  // BT1(PK4/63)
        GPIOPadConfigSet(GPIO_PORTK_BASE, GPIO_PIN_4, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU); // Weak Pull Up Required for this push-button
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);  // LEDS de STATUS
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1);  // LED1(PN0/107), LED2(PN1/108)
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);  // LEDS de ETHERNET
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4);  // LED_GREEN_LINK(PF0/42), LED_RED_ACT(PF4/46)
    
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);  // Pinos de Habilitação dos Transceivers
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_2 | GPIO_PIN_3);  // TX_EN(PH2/31), RX_EN(PH3/32)
    }
    
    void InitCN5A(void) // É o mesmo DB9 do GPS, configurado de maneira diferente para os testes de UART1
    {
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);  // Pinos UART1 GPS_TX e GPS_RX
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); // Enable GPS Uart1
        GPIOPinConfigure(GPIO_PB0_U1RX);
        GPIOPinConfigure(GPIO_PB1_U1TX);
        ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        ROM_UARTConfigSetExpClk(UART1_BASE, g_ui32SysClock, 912600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
    }
    
    
    void InitCN7(void) // UART3
    {
        // Configurações da porta serial CN7 (interna) UART3
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);  // Pinos RX5 (U3RX/PA4/37) e TX5(U3TX/PA5/38)
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3); // Enable Uart3
        GPIOPinConfigure(GPIO_PA4_U3RX);
        GPIOPinConfigure(GPIO_PA5_U3TX);
        ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5);
        ROM_UARTConfigSetExpClk(UART3_BASE, g_ui32SysClock, 912600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
    }
    
    
    void TaskSystick(void)
    {
    	static uint64_t systick_counter = 0;
    	static uint32_t systick_next_task = 1;
    	static uint32_t systick_next_count = 0;
    	static uint32_t systick_task = 1;  // 999 for debug, Default = 1
    	static uint32_t led_blinking = 0;
    	static uint32_t char_count = 0;
    	static char sent_char;
    	static uint32_t char_matches = 0;
    
    	systick_counter++;
    	switch(systick_task)
    	{
    	case 0: // Do nothing until the next_count is met
    		if (systick_counter == systick_next_count)
    			systick_task = systick_next_task;
    		break;
    	case 1: // Cases 1 and 2 test (blink) the four onboard leds
    		ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_0 | GPIO_PIN_1); // Turn ON LED1/LED2
    		ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4, GPIO_PIN_0 | GPIO_PIN_4); // Turn ON LED_LINK/LED_ACT
    		systick_task = 0;
    		systick_next_task = 2;
    		systick_next_count = systick_counter + CLOCK_SYSTICK/10;
    		break;
    	case 2:
    		ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0); // Turn OFF LED1/LED2
    		ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4, 0); // Turn OFF LED_LINK/LED_ACT
    		if (systick_counter >= CLOCK_SYSTICK)  // After 1 second...
    		{
    			systick_task = 4;
    			led_blinking = 1;
    			ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 , GPIO_PIN_0);
    		}
    		else
    		{
    			systick_task = 0;
    			systick_next_task = 1;
    			systick_next_count = systick_counter + CLOCK_SYSTICK/10;
    		}
    		break;
    	case 99: // Fail!!!
    		UARTSend((uint8_t *)"Teste FINISHED                ", 30);
    		UARTSend((uint8_t *)"==============================", 30);
    		systick_task = 100;
    		led_blinking = 0;
    		systick_next_count = systick_counter + CLOCK_SYSTICK * 3;
    		break;
    	case 100:
    		if (!(systick_counter%50))
    			ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4,(ROM_GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4) ^ GPIO_PIN_4)); // // Toggle RED LED
    		if (systick_counter == systick_next_count)
    			systick_task = 1;
    		break;
    	case 4: // Welcoming message
    		UARTSend((uint8_t *)"                              ", 30);
    		UARTSend((uint8_t *)"Teste CN5 REV.A               ", 30);
    		UARTSend((uint8_t *)"==============================", 30);
    		ROM_GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_2 | GPIO_PIN_3, 0); // Enable transceivers
    		systick_task = 24;
    		break;
    	case 24: // Loopback test TX RX
    		UARTSend((uint8_t *)"8)    Test Port CN5A lower,   ", 30);
    		systick_next_count = systick_counter + CLOCK_SYSTICK * 1; // test for 3 seconds
    		systick_task = 25;
    		break;
    	case 25: // Send random char
    		sent_char = 0x38;
    		ROM_UARTCharPutNonBlocking(UART1_BASE,sent_char);
    		char_count++;
    		systick_task = 26;
    		break;
    	case 26: // Wait for received character on U3RX
    		while(ROM_UARTCharsAvail(UART1_BASE))
    		{
    			received_char = ROM_UARTCharGetNonBlocking(UART1_BASE);
    		}
    		if (received_char)
    		{
    			if (received_char == sent_char)
    			{
    				char_matches++;
    			}
    			received_char = 0;
    			systick_task = 25;
    		}
    		if (systick_counter == systick_next_count)  // End of test time
    		{
    			systick_task = 27;
    		}
    		break;
    
    
    	case 27: // Display loopback test result
    		sprintf(string_char,"   Bytes Sent:           %5d",char_count);
    		UARTSend((uint8_t *) string_char, 30);
    		sprintf(string_char,"   Matches:              %5d",char_matches);
    		UARTSend((uint8_t *) string_char, 30);
    		if ((char_count) && (char_count == char_matches))
    		{
    			UARTSend((uint8_t *)"                        PASS! ", 30);
    		}
    		else
    		{
    			UARTSend((uint8_t *)"                        FAIL! ", 30);
    		}
    		UARTSend((uint8_t *)"==============================", 30);
    		systick_task = 28;
    		char_count = 0;
    		char_matches = 0;
    		break;
    
    	case 28: // Loopback test TX RX
    		UARTSend((uint8_t *)"      Test Port CN7  inner... ", 30);
    		systick_next_count = systick_counter + CLOCK_SYSTICK * 1; // test for 3 seconds
    		systick_task = 29;
    		break;
    	case 29: // Send random char
    		sent_char = 0x39;
    		ROM_UARTCharPut(UART3_BASE,sent_char);
    		char_count++;
    		systick_task = 30;
    		break;
    	case 30: // Wait for received character on U3RX
    		// Test without interrupt
    		while(ROM_UARTCharsAvail(UART3_BASE))
    		{
    			received_char = ROM_UARTCharGet(UART3_BASE);
    		}
    		// End of debug test
    		if (received_char)
    		{
    			if (received_char == sent_char)
    			{
    				char_matches++;
    			}
    			received_char = 0;
    			systick_task = 29;
    		}
    		if (systick_counter == systick_next_count)  // End of test time
    		{
    			systick_task = 31;
    		}
    		break;
    	case 31: // Display loopback test result
    		sprintf(string_char,"  2Bytes Sent:           %5d",char_count);
    		UARTSend((uint8_t *) string_char, 30);
    		sprintf(string_char,"  2Matches:              %5d",char_matches);
    		UARTSend((uint8_t *) string_char, 30);
    		if ((char_count) && (char_count == char_matches))
    		{
    			UARTSend((uint8_t *)"                       2PASS! ", 30);
    		}
    		else
    		{
    			UARTSend((uint8_t *)"                       2FAIL! ", 30);
    		}
    		UARTSend((uint8_t *)"==============================", 30);
    		systick_task = 32;
    		char_count = 0;
    		char_matches = 0;
    		break;
    
    
    	default:
    		systick_task = 99;
    	}
    	if (led_blinking)
    	{
    		if (!(systick_counter%10))
    		{
    			ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0,(ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_0) ^ GPIO_PIN_0));
    			ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1,(ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1) ^ GPIO_PIN_1));
    		}
    	}
    }
    
    
    //*****************************************************************************
    int main(void)
    {
    	g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 60000000);
    
        InitGPIO(); 		// Inicializa LEDS e BOTOES
        InitUART0();  		// Inicializa a UART do Console
        InitCN5A();			// Inicializa o conector DB9-F do GPS em modo de teste de UART
        InitCN7();			// Inicializa o conector DB9-F interno
    
        ROM_IntMasterEnable();
        SysTickInit();
    
        while(1)
        {
        	if (task_enable & TASK_SYSTICK)
        	{
        		TaskSystick();
        		task_enable &= ~TASK_SYSTICK;
        	}
    
        }
    }
    

  • As past stated (repeatedly) using loopback when a 2nd, off-board, known good UART sits forlornly - frees (both) you and hapless/would be helpers - from dealing w/this manuscript.

    That independent, off-board UART - may be programmed just once - escapes the evil of, "cut/paste" reprogramming to accommodate the "simplification" supplied by "loopback!"

    Loopback may be "ok" for long tested, known-good hardware - yet is, "ocean seat on Titanic" (as you've discovered) when employed for new board...

  • Hello Bruno,

    In the first code if you cross the cables and then in the while loop if you write to UART3 can you do a read from UART1?

    Regards

    Amit

  • And then...

    I found an error on the board design. The board uses a quadruple RS422 driver, and one of the channels had the TX_NEG and TX_POS inverted.

    The GPIO "was working" simply because I was generating a square pulse and seeing one on the other side. But the character that was received was wrong, for it was a wrong combination of plus and minuses into the receiving driver...

    Further,  it's always interesting to read cb1_mobile's comments: are you related to Sir William Shakespeare somehow? (just an ice breaking comment, for it takes me two or three readings to digest your posts, but I'm not complaining).

    By the way, I found it when I decided to make an even simpler test code, port by port.

        while(1)
        {
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_PIN_4); // RED LED ON
    
        	MAP_UARTCharPutNonBlocking(UART3_BASE,0x39);
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_PIN_0); // LINK LED ON
    
        	while(!(MAP_UARTCharsAvail(UART3_BASE))); // It takes 10.8us until there is a character available here!
    
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0); // LINK LED OFF
    
        	while(MAP_UARTCharsAvail(UART3_BASE))
        	{
        		MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0); // LED1 ON when something is received on UART3
        		received_char = MAP_UARTCharGet(UART3_BASE);
        		if (received_char == 0x39) MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1); // LED2 ON when it is 0x39
        	}
    
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0); // RED LED OFF
        	MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0); // LED1 LED2 OFF
        }

    Cheers and Thanks!

  • Bruno Saraiva said:
    it's always interesting to read cb1_mobile's comments: are you related to Sir William Shakespeare somehow?

     

    Not quite - credit Bronx HS of Science, NYU Eng. & UCLA law for "bard-like" (bard-lite, really) writing style.  Writing contracts - endless drone of tech - some "escape" proves worthwhile - aids productivity.   (and living 13 years in L.A. - writing for the "studio" - some history lingers...)

    And - had you employed a "proper" known-good UART (off-board - thus available for repeat testing of all such boards) none of the time/effort/heartache would have been required.  (You were "hoisted" by your own petard...)

    Good of you to close this UART tech loop - and recall - my Verify Award drink must be, "shaken - not stirred."

  • "And - had you employed a "proper" known-good UART (off-board - thus available for repeat testing of all such boards) none of the time/effort/heartache would have been required.  (You were "hoisted" by your own petard...)"

    This is our company's first contact with RS422, everything before was 232, so I didn't have anything differential available. So my best bet to test my RS422 outputs was by using the RS422 inputs that I had just created, what about this great idea!?!?!?

    C'mon, it worked in 5 out of 6 ports of this board, I can't complain! (The other two are RS232 levels that output data to PC's).

    One day I'll have the time and willing required to design a proper test setup - and then I'll have to write code to test the test bench... :(

    Thanks for the comments! And I'll take my drink cold from the microbrewery - neither shaken, nor stirred.

  • Hello cb1

    I suspected the board to be an issue as a cross loopback did not work for one specific UART instance.

    Regards

    Amit

  • Gentlemen,

    Never on my few posts I left a subject open after finding out the solution. I firmly believe it is the best way to say thanks for the support, and to make the thread actually useful. I was hoping that this one was closed for good, but now I have a totally different situation which probably should even open a new thread. Here it goes:

    Following Amit's advice: "can you cross loopback with the simple code?", I tested for that. Look at this very simple code:

        while(1)
        {
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_PIN_4); // RED LED ON
    
        	// Teste da UART1 (CN5A)
        	MAP_UARTCharPut(UART1_BASE,0x39);
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_PIN_0); // LINK LED ON
        	while(!(MAP_UARTCharsAvail(UART3_BASE))); // It takes 10.8us @921600 until there is a character available here!
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0); // LINK LED OFF
        	while(MAP_UARTCharsAvail(UART3_BASE))
        	{
        		MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0); // LED1 ON when something is received on UART1
        		received_char = MAP_UARTCharGet(UART3_BASE);
    //    		MAP_UARTCharPut(UART0_BASE,received_char);  // Send char to console
        		if (received_char == 0x39)
        		{
        			GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1); // LED2 ON when it is 0x39
        			SysCtlDelay(20000);  // Breathe...
        		}
        	}
        	MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0); // RED LED OFF
        	MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0); // LED1 LED2 OFF
        }

    LED1 should tell me when a byte is received on UART3. LED2 should tell me when it matches what was sent. Previous hardware bug apart (the diff lines were crossed in one direction only and they should work from U1->U3), the results I got is completely insane:

    - Initially at 921600, I had LED1 saying characters were coming in, but no LED2 showing match
    - I probed directly on both U1TX(96) and U3RX(37) pins, and the signal is perfectly the same as far as I can scroll my scope's memory.

    - Then I reduced UART speed to 115200 not touching any other line of code. LED2 started to pulse as expected: EVERY received byte matched the sent byte. Of course, signals on the scope were again identical.

    - So I added the console output of the commented line, to see "what byte was being received!?". Turns out it was exactly 0x39, even going back to a faster speed of 921600. Step debugging shows the IF statement is returning true in any of the speeds.

    - I added the delay line after turning on the LED2 just in case my eyes and my scope were not fast enough. Still no LED2 pulses from any UART speeds of 460800 and above. Perfect LED2 pulses on speeds up to 230400.

    - I played with different optimization settings, all the way from the standard level 2 to "OFF". No changes here.

    - WORSE: with UART at 460800 and SysCtlDelay at 20000: when I start the debugger, I get no pulses. If I pause the debugger and resume it, voila, LED2 starts to pulse perfectly as expected!!!! Repeated this 10 times to make sure I'm not freaking. Other test: if I simply reset the board disconnected from the JTAG, no pulses on the LED.

    This is not at all a UART question anymore. The Tx and Rx signals are perfectly identical all the time. This is something new for me and I have no clue what is causing it. How can I rely the rest of my application on "if (received_char == something)" when this simple test is not working properly?

    Thanks for your ideas! I have a bunch of saved scope screens and pictures if such will help.

  • More than ever - this reporter stands by past (rejected) advice to build an adequate, "off-board" RS232/485 "known good" bi-directional device.  Offer this as we've (long) noted such "hard to explain" gremlins - most always resulting from famed (time-saving...NOT) "loopback."

    Indeed great that you've, "closed the loop" upon past - but operation as you describe is best confirmed via, "real-world" operating conditions (i.e. transmission line, real line drivers) difficult to achieve via (usually compromised) loopback...