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.

Help to get uart bootloader for NON virtual serial port for Tiva launchpad TM4C123G to work

Other Parts Discussed in Thread: EK-TM4C123GXL

Hi

I got the bootloader in "TivaWare_C_Series-2.1.0.12573" to work with LM flash programmer, BUT only on UART0 (PA0=RX and PA1=TX) with the virtual serial port.

I need to get it to work with a "normal" USB2serial device, but now after alot of testing I have no more ideas on how to proceed.

I got the LAB12 in the TM4C123G_LaunchPad_Workshop (an uart test-app that together with terminal program show that the UART works ) to work on UART1 and UART2 together with 2 different USB2serial (one from Ftdchip.com and another from Arduino.

for UART1:

changes in bl_main.c

diff --git a/boot_loader/bl_main.c b/boot_loader/bl_main.c
index fbb7275..35d1449 100644
--- a/boot_loader/bl_main.c
+++ b/boot_loader/bl_main.c
@@ -264,8 +264,8 @@ ConfigureDevice(void)
//
// Enable the the clocks to the UART and GPIO modules.
//
- HWREG(SYSCTL_RCGC2) |= SYSCTL_RCGC2_GPIOA;
- HWREG(SYSCTL_RCGC1) |= SYSCTL_RCGC1_UART0;
+ HWREG(SYSCTL_RCGC2) |= SYSCTL_RCGC2_GPIOB;
+ HWREG(SYSCTL_RCGC1) |= SYSCTL_RCGC1_UART1;

//
// Keep attempting to sync until we are successful.
@@ -281,28 +281,30 @@ ConfigureDevice(void)
//
// Set GPIO A0 and A1 as UART pins.
//
- HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) |= UART_PINS;
+ HWREG(GPIO_PORTB_BASE + GPIO_O_AFSEL) |= UART_PINS;

//
// Set the pin type.
//
- HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= UART_PINS;
+ HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) |= UART_PINS;

//
// Set the baud rate.
//
- HWREG(UART0_BASE + UART_O_IBRD) = ui32ProcRatio >> 6;
- HWREG(UART0_BASE + UART_O_FBRD) = ui32ProcRatio & UART_FBRD_DIVFRAC_M;
+// HWREG(UART1_BASE + UART_O_IBRD) = ui32ProcRatio >> 6;
+// HWREG(UART1_BASE + UART_O_FBRD) = ui32ProcRatio & UART_FBRD_DIVFRAC_M;
+ HWREG(UART1_BASE + UART_O_IBRD) = 0x1B;
+ HWREG(UART1_BASE + UART_O_FBRD) = 0x08;

//
// Set data length, parity, and number of stop bits to 8-N-1.
//
- HWREG(UART0_BASE + UART_O_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
+ HWREG(UART1_BASE + UART_O_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;

//
// Enable RX, TX, and the UART.
//
- HWREG(UART0_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE |
+ HWREG(UART1_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE |
UART_CTL_RXE);

#ifdef UART_AUTOBAUD
@@ -606,8 +608,8 @@ Updater(void)
HWREG(SYSCTL_SRCR1) = SYSCTL_SRCR1_I2C0;
#endif
#ifdef UART_ENABLE_UPDATE
- HWREG(SYSCTL_RCGC1) &= ~SYSCTL_RCGC1_UART0;
- HWREG(SYSCTL_SRCR1) = SYSCTL_SRCR1_UART0;
+ HWREG(SYSCTL_RCGC1) &= ~SYSCTL_RCGC1_UART1;
+ HWREG(SYSCTL_SRCR1) = SYSCTL_SRCR1_UART1;
#endif

for changes in bl_uart.c

diff --git a/boot_loader/bl_uart.c b/boot_loader/bl_uart.c
index 71df5c3..5b87d9b 100644
--- a/boot_loader/bl_uart.c
+++ b/boot_loader/bl_uart.c
@@ -65,14 +65,14 @@ UARTSend(const uint8_t *pui8Data, uint32_t ui32Size)
//
// Make sure that the transmit FIFO is not full.
//
- while((HWREG(UART0_BASE + UART_O_FR) & UART_FR_TXFF))
+ while((HWREG(UART1_BASE + UART_O_FR) & UART_FR_TXFF))
{
}

//
// Send out the next byte.
//
- HWREG(UART0_BASE + UART_O_DR) = *pui8Data++;
+ HWREG(UART1_BASE + UART_O_DR) = *pui8Data++;
}

//
@@ -98,14 +98,14 @@ UARTFlush(void)
// Wait for the UART FIFO to empty and then wait for the shifter to get the
// bytes out the port.
//
- while(!(HWREG(UART0_BASE + UART_O_FR) & UART_FR_TXFE))
+ while(!(HWREG(UART1_BASE + UART_O_FR) & UART_FR_TXFE))
{
}

//
// Wait for the FIFO to not be busy so that the shifter completes.
//
- while((HWREG(UART0_BASE + UART_O_FR) & UART_FR_BUSY))
+ while((HWREG(UART1_BASE + UART_O_FR) & UART_FR_BUSY))
{
}
}
@@ -136,14 +136,14 @@ UARTReceive(uint8_t *pui8Data, uint32_t ui32Size)
//
// Wait for the FIFO to not be empty.
//
- while((HWREG(UART0_BASE + UART_O_FR) & UART_FR_RXFE))
+ while((HWREG(UART1_BASE + UART_O_FR) & UART_FR_RXFE))
{
}

//
// Receive a byte from the UART.
//
- *pui8Data++ = HWREG(UART0_BASE + UART_O_DR);
+ *pui8Data++ = HWREG(UART1_BASE + UART_O_DR);
}
}

Very grateful for help on this

Anders

  • Hello Anders

    When programming the GPIO module for UART1 function, the PCTL needs to be programmed as well. In case of UART-0 the value of the PCTL in GPIO A is default set to UART.

    Please add the following lines.

            HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) &= ~(0xFF);
            HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) |= 0x11;

    Regards

    Amit

  • Hi Amit, and thank you for the tip

    I have tried to put your 2 lines just before.

    HWREG(GPIO_PORTB_BASE + GPIO_O_AFSEL) |= UART_PINS;

    but it doesn't help, where should they be placed?

    Kind regards

    Anders

  • Hi again Amit!

    it works!!

    I had been testing with other baudrate, but now it works when I set it back!

    Thanks alot!!!

    below is the patches needed to get it working on Uart1

    diff --git a/boot_loader/bl_main.c b/boot_loader/bl_main.c
    index fbb7275..097784a 100644
    --- a/boot_loader/bl_main.c
    +++ b/boot_loader/bl_main.c
    @@ -192,6 +192,7 @@ ConfigureDevice(void)
    uint32_t ui32ProcRatio;
    #endif

    +
    #ifdef CRYSTAL_FREQ
    //
    // Since the crystal frequency was specified, enable the main oscillator
    @@ -264,8 +265,8 @@ ConfigureDevice(void)
    //
    // Enable the the clocks to the UART and GPIO modules.
    //
    - HWREG(SYSCTL_RCGC2) |= SYSCTL_RCGC2_GPIOA;
    - HWREG(SYSCTL_RCGC1) |= SYSCTL_RCGC1_UART0;
    + HWREG(SYSCTL_RCGC2) |= SYSCTL_RCGC2_GPIOB;
    + HWREG(SYSCTL_RCGC1) |= SYSCTL_RCGC1_UART1;

    //
    // Keep attempting to sync until we are successful.
    @@ -281,28 +282,30 @@ ConfigureDevice(void)
    //
    // Set GPIO A0 and A1 as UART pins.
    //
    - HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) |= UART_PINS;
    + HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) &= ~(0xFF);
    + HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) |= 0x11;
    + HWREG(GPIO_PORTB_BASE + GPIO_O_AFSEL) |= UART_PINS;

    //
    // Set the pin type.
    //
    - HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= UART_PINS;
    + HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) |= UART_PINS;

    //
    // Set the baud rate.
    //
    - HWREG(UART0_BASE + UART_O_IBRD) = ui32ProcRatio >> 6;
    - HWREG(UART0_BASE + UART_O_FBRD) = ui32ProcRatio & UART_FBRD_DIVFRAC_M;
    + HWREG(UART1_BASE + UART_O_IBRD) = ui32ProcRatio >> 6;
    + HWREG(UART1_BASE + UART_O_FBRD) = ui32ProcRatio & UART_FBRD_DIVFRAC_M;

    //
    // Set data length, parity, and number of stop bits to 8-N-1.
    //
    - HWREG(UART0_BASE + UART_O_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
    + HWREG(UART1_BASE + UART_O_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;

    //
    // Enable RX, TX, and the UART.
    //
    - HWREG(UART0_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE |
    + HWREG(UART1_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE |
    UART_CTL_RXE);

    #ifdef UART_AUTOBAUD
    @@ -606,8 +609,8 @@ Updater(void)
    HWREG(SYSCTL_SRCR1) = SYSCTL_SRCR1_I2C0;
    #endif
    #ifdef UART_ENABLE_UPDATE
    - HWREG(SYSCTL_RCGC1) &= ~SYSCTL_RCGC1_UART0;
    - HWREG(SYSCTL_SRCR1) = SYSCTL_SRCR1_UART0;
    + HWREG(SYSCTL_RCGC1) &= ~SYSCTL_RCGC1_UART1;
    + HWREG(SYSCTL_SRCR1) = SYSCTL_SRCR1_UART1;
    #endif

  • Hello Anders,

    I knew it would work!!! Please do mark the answer verified as it would help others looking for a similar solution. And thanks for posting the updated code as well for future reference

    Regards

    Amit

  • Hi Anders,

    just trying to reproduce your code, since I like to get bootloaded on Uart1 too.
    I am not familiar with applying diff patches, but pretty confident that I changed everything in both files according to your suggestions.
    Still cannot connect. I can see LM Flash sending something at the very beginning, but that's it.

    Can you please give details on LM Flash Programmer?
    I have set it to manual config, Serial, com24(correct),115k

    The Uart1 hardware is working for sure with other firmware.

    I am using same Tivaware.
    Using TivaC Launchpad EK-TM4C123GXL
    Uart0 Example works fine.


    Thank you for any hints on that.


    Cheers

    Juergen
  • Hello Juergen,

    Did you check if bl_uart.c has UART1 as the module base address and bl_config.h has the UART1 Pins correctly defined.

    Regards
    Amit
  • Hi Amit,

    Dawns that - rather naturally & predictably - users fall to this "trap" of the default behavior of Port A - when attempting to migrate such code to other ports/pins.

    It appears so obvious to simply copy/paste the "set-up/config code of Port A" to user's, "Port du jour." And they - most always - fail to detect that "hidden" default behavior of Port A.

    Does this not occur often enough that such should be included w/in our, "Tell TI" thread? Should you agree - I'll drag it there...
  • Hello cb1,

    TivaWare 2.1.1.71 has the fix for the GPIO Ports and Configuration that were in default state. While reviewing the code, it seems that the Base Address may have to be changed to a generic base define.

    Regards
    Amit
  • Hi Amit,

    Good to know - yet, "Tell T.I." targets the "to be updated" DriverLib User Guide.

    I believe some mention of this "Port A, default behavior" w/in the updated guide - may prove useful...
  • Hello cb1,

    I doubt that. The reason being the driverlib user guide is documentation for the driverlib. This is a design artifact and part of the data sheet.

    Regards,
    Amit
  • You are - and remain - the boss.    One hopes the new TivaWare 2.1.1.71 fully alerts, identifies and (saves) users from this on-going pitfall...

    While you note that it's, "Part of the data sheet" - such did not save this particular poster - nor the hundreds (before) - who suffered similar fate...

  • Hello Amit & cb1-,

    thank you for your responses. You gentlemen are very helpful. I read a lot in E2E.

    The base adresses are all correct, but (again - sigh) I stumbled over the double Uart1 Port config.
    The above code was ofcourse for PB0/PB1, but I wired PC4/PC5 for my Uart1.
    This fact just won't stay in my mind ...

    Will have to review my code and try again.


    Cheers

    Juergen
  • Juergen - in the scheme of things - the "double appearance of UART1 catches many.   

    As you mention Port C - beware of any mistake here as you'll "lose" JTAG - you must (only) allow your code to impact PC4-PC7 - never the lower nibble.

    Appreciate your kind words - rare that...

  • Hello cb1 - thank you for the JTAG warning.