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.
Greetings,
As an occasional forum participant the need for greater, "Serial Boot Loader" detail & clarity became obvious. And that mission has (yesterday) been very well accomplished!
Amit Ashara's forum work is respected & appreciated - yet his creation of this detailed, yet very readable (and understandable) "Serial Boot Loader Application Note" breaks new ground! Forty-five pages of well explained background & implementation await each reader. Amit's use of diagrams - many w/ key/critical details in color - greatly aids understanding.
You can find TI's, "Serial Boot Loader Application Note w/Code Base" at:
http://www.ti.com/lit/an/spma074/spma074.pdf
Amit's work is sure to save we forum users countless time & effort.
Comments, questions, additions & user results - all are welcomed by Amit - w/in this thread. (this may serve as a new, "Boot Loader Central" depository - which proves superior to multiple, individual, "harder to find" threads.)
Amit,
Yes, I modified the examples to attempt a JumpToBootloader call. I added that code from boot_demo1.c into a modified tm4c_all_led_blink but may not be appropriate in this case.
So I have tm4c_device_recovery_code as unchanged in Target. ie, I have the default BOOT_CFG settings.
But I did change tm4c_all_led_blink to based on USR_SW2 attempt to jump into the ROM bootloader thereby negatiing the need for GPIO output from Programmer to Target to place into Bootloader.
Also I have tried this in 2 ways:
1. Target Powered by ICDI, Target GPIO pin pulled up, using ICDI to load image below direct to Target and after DL and button pushes attempt to load file from SBL GUI.
2. Target powered by Programmer and GPIO connected between Programmer and Target (your default mode). DL image below using SDL GUI, then after pushing Target buttons, then disable ticbox for Boot Pin Control and attempt to load new file from SBL GUI.
In each case I get the same error: TIMEOUT from Target. I'm thinking the branch is invalid in the JumpToBootLoader().
My code is as follows: (usr_sw2_mode is just there to see feedback from USR_SW2 and verify isr):
static uint32_t usr_sw2_mode = 0;
static uint32_t ui32SysClock;
//*****************************************************************************
//
// Passes control to the bootloader and initiates a remote software update.
//
// This function passes control to the bootloader and initiates an update of
// the main application firmware image via UART0 or USB depending
// upon the specific boot loader binary in use.
//
// \return Never returns.
//
//*****************************************************************************
void
JumpToBootLoader(void)
{
//
// Disable all processor interrupts. Instead of disabling them
// one at a time, a direct write to NVIC is done to disable all
// peripheral interrupts.
//
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
//
// Return control to the boot loader. This is a call to the SVC
// handler in the boot loader.
//
(*((void (*)(void))(*(uint32_t *)0x2c)))();
}
//*****************************************************************************
//
// GPIOJIntHandler.
//
//*****************************************************************************
void
GpioJIntHandler(void)
{
//
// Clear the GPIO interrupt.
//
//
// Delay here on button push for simple debouncing.
//
SysCtlDelay(ui32SysClock / 10);
//
// Clear the timer interrupt.
//
ROM_GPIOIntClear(GPIO_PORTJ_AHB_BASE, GPIO_INT_PIN_1);
if (usr_sw2_mode < 2)
usr_sw2_mode ++;
else
JumpToBootLoader();
}
//*****************************************************************************
//
// The program main function. It performs initialization, then runs a loop to
// blink LED's
//
//*****************************************************************************
int
main(void)
{
//
// Variable for Clock Frequency
//
#if (defined (TARGET_IS_TM4C129_RA0) || \
defined (TARGET_IS_TM4C129_RA1) || \
defined (TARGET_IS_TM4C129_RA2))
//
// Set the System Clock to 120MHz if the device is a TM4C129
//
ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_XTAL_25MHZ |
SYSCTL_CFG_VCO_480), 120000000);
//
// Configure GPIO Port F Pins 1-3 as GPIO Output (LED)
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, (GPIO_PIN_1 | GPIO_PIN_0));
//
// Initialize the buttons driver.
//
ButtonsInit();
//
// Enable the interrupt for the button.
//
ROM_GPIOIntEnable(GPIO_PORTJ_AHB_BASE, GPIO_INT_PIN_1);
//
// Set pad config.
//
MAP_GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_1,
GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
//
// Set direction.
//
ROM_GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_1, GPIO_DIR_MODE_IN);
//
// Enable the interrupt for the button.
//
ROM_GPIOIntEnable(GPIO_PORTJ_BASE, GPIO_INT_PIN_1);
//
// Enable interrupt to NVIC.
//
ROM_IntEnable(INT_GPIOJ);
ROM_IntMasterEnable();
//
//
while(1)
{
if (usr_sw2_mode == 0)
{
// Blink the LED's together
GPIOPinWrite(GPIO_PORTN_BASE, (GPIO_PIN_1 | GPIO_PIN_0),
(GPIO_PIN_1 | GPIO_PIN_0));
SysCtlDelay(ui32SysClock/12);
GPIOPinWrite(GPIO_PORTN_BASE, (GPIO_PIN_1 | GPIO_PIN_0),
0x0);
SysCtlDelay(ui32SysClock/12);
}
else
{
// Alternate LED's
GPIOPinWrite(GPIO_PORTN_BASE, (GPIO_PIN_1 | GPIO_PIN_0), (GPIO_PIN_0));
SysCtlDelay(ui32SysClock/12);
GPIOPinWrite(GPIO_PORTN_BASE, (GPIO_PIN_1 | GPIO_PIN_0), (GPIO_PIN_1));
SysCtlDelay(ui32SysClock/12);
}
}
#endif
#if (defined (TARGET_IS_TM4C123_RB1) || \
defined (TARGET_IS_TM4C123_RB2))
//
// Set the System Clock to 80MHz if the device is a TM4C123
//
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
//
// Get the System Clock Frequency
//
ui32SysClock = SysCtlClockGet();
//
// Configure GPIO Port F Pins 1-3 as GPIO Output
//
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1));
GPIOPinWrite(GPIO_PORTF_BASE, (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1), 0x0);
//
// Blink the LED's together
//
while(1)
{
GPIOPinWrite(GPIO_PORTF_BASE, (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1),
0x0);
SysCtlDelay(ui32SysClock/12);
GPIOPinWrite(GPIO_PORTF_BASE, (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1),
(GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1));
SysCtlDelay(ui32SysClock/12);
}
#endif
}
Truth in Advertising Dept: This thread "disappeared for 3 or so hours!" (today, Dec 21, '15) Now has been restored.
We were advised that thread had "30 day sticky rating" - and was just renewed!
Hello Amit,
I have added code to initialize UART0. But when I run the ROM_UpdateUART() , the Target LEDs are blinking which means the Target is running an app and is not sitting in the bootloader awaiting an image to be DL (and hence the timeout from the Programmer if I attempt a DL). How do I communicate to the bootloader to wait for an image from UART0? I thought that was what ROM_UpdateUART() is supposed to do.
I have a pull up on GPIO input PB4 that the device_recovery_code is looking for for the normal demo jump to ROM bootloader.
Again, all I am looking for is a way to remove the need for GPIO input PB4 to cause the Target to jump to ROM bootloader, but instead use target sw to make this change from app to bootloader.
My UART0 init code is copied from boot_demo_uart.c
//
// Enable interrupt to NVIC.
//
ROM_IntEnable(INT_GPIOJ);
ROM_IntMasterEnable();
//
// Enable the UART that will be used for the firmware update.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
//
// Configure the UART for 115200, 8-N-1.
//
ROM_UARTConfigSetExpClk(UART0_BASE, ui32SysClock, 115200,
(UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |
UART_CONFIG_WLEN_8));
//
// Enable the UART operation.
//
ROM_UARTEnable(UART0_BASE);
Thanks,
-Phil
Hello Amit,
I already have the interrupts as you indicated and I am using USR_SW2 on the Target(Launchpad T129) which I believe is already properly grounded? I have no change in my result.
So I worked on 'starting over' and making a 'smaller' change relative to your demo. Instead of your demo using 2 GPIO pins to reset and trigger the boot loader, I connected the reset line from the Programmer into a 'new' GPIO pin, PK6 and use that (rather than Target USR_SW2) as a GPIO Isr into the Target to cause the jump to bootloader. This way the Programmer is active while the Target jumps into the boot loader. I pulled up the Target RST and Target PB4 from your demo.
I set an LED just before jumping into the boot loader to verify that action. In each case above, using the Launchpad USR_SW2 or using PK6 as a GPIO isr to jump into the boot loader, I am not able to get the boot loader to accept a file DL.
My code for the jump (including LED writes)
void
JumpToBootLoader(void)
{
// Set the LED's to know state
// PF4 = LED3
GPIOPinWrite(GPIO_PORTF_BASE, (GPIO_PIN_4),
(GPIO_PIN_4));
//
// Disable all processor interrupts. Instead of disabling them
// one at a time, a direct write to NVIC is done to disable all
// peripheral interrupts.
//
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
//
// Return control to the boot loader. This is a call to the SVC
// handler in the boot loader.
//
ROM_UpdateUART();
// Test if returns from boot loader.
// PF0 = LED4
GPIOPinWrite(GPIO_PORTF_BASE, (GPIO_PIN_0),
(GPIO_PIN_0));
}
I even tried keeping the PB4 connected but I dont know if ROM_UpdateUART() looks at PB4 the same way that a reset does.(Nor if the Programmer timing is appropriate for that)
How does the boot loader know that a DL is required w/o the PB4 input? (or maybe I am asking how can that be configured?)
Thanks again,
-Phil