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.

TM4C123GH6PM: How to use SW UART and DFU mode

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL,

Hello, I am Sky.

.

.

I have implemented SW UART function using the 'usb_dev_serial' example which is located in "C:\ti\TivaWare_C_Series-2.1.3.156\examples\boards\ek-tm4c123gxl\usb_dev_serial", and it works well.

Now, I am trying to develop USB DFU function to upload my firmware without JTAG or ICDI.

.

.

In detail, my board will be putted into a locked case, and a service engineer want to upload the latest firmware using Windows program in fields.

The board has 1 TM4C123GH6PM microcontroller and various sensors.

Moreover, UART0/USB pins are used for SW UART, I2C0 pins are used for a sensor, and SSI0 pins are vacancies in my board.

We don't want to use J-TAG or additional device to upload new firmware because of its capacity of the board and costs.

.

.

Fortunately, I found very helpful references as below:

[SPMU301D.pdf] TivaWare™ Boot Loader

[SPMA054.pdf] Tiva™ Application Update Using the USB DFU Class

[Source Code for Firmware] C:\ti\TivaWare_C_Series-2.1.3.156\examples\boards\dk-tm4c123g\boot_usb

[Source Code for Windows DLL] C:\ti\TivaWare_C_Series-2.1.3.156\tools\lmdfu

[E2E Thread for C# interface] e2e.ti.com/.../370958

.

.

Here is my question.

.

.

1) Switching from SW UART mode to DFU mode

My firmware runs SW UART mode and process messages. How can I switch to DFU mode when executing SW UART mode?

.

2) Alternatives rather than DFU mode

In SW UART mode, can I receive BINARY DATA and write flash memory directly?

Is there any example to use DIY FIRMWARE UPGRADE FUNCTION instead of DFU mode?

.

.

Please give me some comments or share helpful source codes.

.

.

Kind Regards,

Sky.

  • Hello Sky

    Let me first start with a clarification question. The usb_dev_serial uses the UART0 via the ICDI and the USB port emulating a COM service to transfer the data. What is the SW UART you are referring to here?
  • Hello Amit Ashara,
    .
    I am sorry for using vague expression.
    I meant that the SW UART is exactly same thing as you mentioned.
    It occupies UART0 and USB port, and emulates COM service as "Stellaris Virtual Serial Port".
    .
    .
    Kind Regards,
    Sky.
  • Hello Sky,

    Thanks for the clarification. First of all I would answer the questiom-2 in your first post: The DFU function is standardized by the USB organization. So the use of or creation of a DIY FIRMWARE UPGRADE is not without perils and hazards (and not to mention reinventing the wheel leads nowhere).

    Now to answer Question-1: when a DFU is requested the COM port services need to be terminated and the USB device re-enumerated as DFU class device. An example is examples\boards\dk-tm4c129x\boot_demo_usb where a TM4C129x device enumerates as a HID device and dfuprog.exe allows it to move to the DFU mode instead terminating the HID device. The example would need to be modified for TM4C123x device class.
  • Hello, Amit Ashara.

    Happy New Year!
    It was nice to understand DFU mode and its procedure.
    However, it was focused on two devices, HID and DFU devices, and therefore, it was a little confusing.
    .
    .
    Finally, I found an appropriate thread for only DFU mode.
    [Link] e2e.ti.com/.../1084244
    When I follow the recommendation, it enables me to find a device "Stellaris Device Firmware Upgrade" well.
    Moreover, dfuprog.exe also works well to see a status of DFU devices and upload my program.
    I would like to share my source code.
    .
    int main()
    {
    ROM_IntMasterDisable();
    ROM_SysTickIntDisable();
    ROM_SysTickDisable();

    ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    uint32_t ui32SysClock = ROM_SysCtlClockGet();

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);

    HWREG(NVIC_DIS0) = 0xffffffff;
    HWREG(NVIC_DIS1) = 0xffffffff;
    HWREG(NVIC_DIS2) = 0xffffffff;
    HWREG(NVIC_DIS3) = 0xffffffff;
    HWREG(NVIC_DIS4) = 0xffffffff;

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_USB0);
    ROM_SysCtlUSBPLLEnable();
    ROM_SysCtlDelay(ui32SysClock*2 / 3);
    ROM_IntMasterEnable();
    ROM_UpdateUSB(0);
    }
    .
    .
    Thanks for your kindness.
    -Sky
  • Hello Sky

    The code you mentioned is a standard code as part of the invoking DFU boot loader.
  • Hello Amit Ashara,

    Yes, you are right.
    I just found the WORKING CODE of DFU boot loader for TM4C123C, but it is a small part of whole program.
    Now I am trying to implement "a switching system" between Realtime and DFU mode.
    I think that the source code (boot_demo_usb) you suggested shows this mechanism well.

    However, I have a problem to develop this.
    I think that it is not suitable for my environment because it uses HID mouse code.

    Then I change a few settings as below:

    1) In tUSBDCompositeDevice g_sCompDevice variable, I change a parameter from USB_PID_COMP_HID_DFU to USB_PID_DFU
    2) In definitions, I change NUM_DEVICES from 2 to 1, because I don't need a HID mouse device


    Then, here is my brief code:

    void main()
    {
    uint32_t ui32SysClock = ROM_SysCtlClockGet();
    uint32_t ui32PLLRate = 0;
    SysCtlVCOGet(SYSCTL_XTAL_25MHZ, &ui32PLLRate);
    USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &ui32SysClock);
    USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate);

    USBDDFUCompositeInit(0, &g_sDFUDevice, &(g_sCompDevice.psDevices[0]));
    USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_BUFFER_SIZE, g_pui8DescriptorBuffer);

    while(1)
    {
    //operating main loop

    if (g_bUpdateSignalled) break;
    }

    EnterDFUMode(); //a standard code to enter DFU mode as I mentioned above.
    }


    I expect that in while loop, it runs as a run-time mode, and in dfuprog.exe, this device would be shown in a list of DFU devices.

    However, there are nothing to appear...

    Is there any problem?

  • Hi Sky,

    USB DFU is indeed tricky to get up and running, but certainly possible.

    When talking about DFU there are two modes to keep in mind. The most important is the DFU update mode that can be activated for example with a call to ROM_UpdateUSB(0). When the TM4C is in this DFU mode, it allows to download a new firmware onto the TM4C. It is also active by default when the TM4C flash is empty. (Flash a zero-byte file to your microcontroller). Get this part running first so that you know how to get a new firmware into your microcontroller.

    The second part is the DFU runtime mode. This allows to signal the DFU capability to the host PC. This is done by creating a USB composite device with the last device your USB DFU device. This is not required; you could think of different ways to trigger DFU update mode; for example by using a GPIO pin.

  • Hello Sky

    You are violating a basic rule of composite device by changing the number of devices. When there multiple types of devices it forms a composite device. If it is a single device then it is a simple device. Having a composite device descriptor with the value 1 does not make any sense.

    Secondly, what is the EnterDFUMode function call?