Skip to content

Commit

Permalink
Flash bootloader (#22)
Browse files Browse the repository at this point in the history
* flash boot loader application

flash boot loader import from Tivaware and apollo specialization

* boot loader updates
- update linker file for cm_mcu code to store data at right place in flash
- update command line interface to trigger entry into the boot loader
* no autobaud in boot loader
* no force update check (code is there but disabled)
* printouts to make clear when BL is started
  • Loading branch information
pwittich authored Oct 15, 2019
1 parent c00d23b commit 1cd9242
Show file tree
Hide file tree
Showing 34 changed files with 5,910 additions and 19 deletions.
1 change: 1 addition & 0 deletions .cproject
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.1464512116" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="PART_TM4C1290NCPDT"/>
<listOptionValue builtIn="false" value="FIRMWARE_VERSION='&quot;dummy&quot;'"/>
<listOptionValue builtIn="false" value="TARGET_IS_TM4C129_RA2=1"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.323903648" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${FREERTOS_ROOT}/include&quot;"/>
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
include ./makedefs


DIRS=driverlib projects
DIRS=driverlib projects boot_loader

all:
@for d in ${DIRS}; do \
Expand Down
90 changes: 90 additions & 0 deletions boot_loader/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#******************************************************************************
#
# Makefile
#
#******************************************************************************

#
# Defines the part type that this project uses.
#
PART=TM4C1290NCPDT

# # The base directory for TivaWare.
#
ROOT=..


#
# Include the common make definitions.
#
include ${ROOT}/makedefs

#
# Where to find header files that do not live in the source directory.
#
IPATH=.
IPATH+=..
IPATH+=${ROOT}

## where to find sources
VPATH=.
VPATH+=../common

# GIT
GIT_VERSION="$(shell git describe --abbrev=4 --dirty --always --tags)"

CFLAGS+= -DFIRMWARE_VERSION=\"$(GIT_VERSION)\"
CFLAGS+=-DTARGET_IS_TM4C129_RA2
#ugh
CFLAGS:=$(filter-out -DDEBUG,$(CFLAGS))

#
# The default rule, which causes the project to be built.
#
all: ${COMPILER}
all: ${COMPILER}/bl_main.axf

#
# The rule to clean out all the build products.
#
clean:
@rm -rf ${COMPILER} ${wildcard *~}

#
# The rule to create the target directory.
#
${COMPILER}:
@mkdir -p ${COMPILER}


#
# Rules for building the project
#
${COMPILER}/bl_main.axf: ${COMPILER}/bl_main.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_uart.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_check.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_packet.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_autobaud.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_flash.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_userhooks.o
${COMPILER}/bl_main.axf: ${COMPILER}/uart.o
${COMPILER}/bl_main.axf: ${COMPILER}/bl_startup_${COMPILER}.o
# TIVAWARE
#${COMPILER}/bl_main.axf: ${ROOT}/driverlib/${COMPILER}/libdriver.a

SCATTERgcc_bl_main=bl_link.ld
ENTRY_bl_main=ResetISR
CFLAGSgcc=-DTARGET_IS_TM4C129_RA2

# this rule forces the main function to be recompiled when
# any of the dependencies are out of date, to get the
# git and compile time info right.
SRCS=$(shell ls *.c )
HDRS=$(shell ls *.h )
${COMPILER}/bl_main.o: ${SRCS} ${HDRS}
#
# Include the automatically generated dependency files.
#
ifneq (${MAKECMDGOALS},clean)
-include ${wildcard ${COMPILER}/*.d} __dummy__
endif
279 changes: 279 additions & 0 deletions boot_loader/bl_autobaud.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
//*****************************************************************************
//
// bl_autobaud.c - Automatic baud rate detection code.
//
// Copyright (c) 2006-2017 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
//
//*****************************************************************************

#include <stdint.h>
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"
#include "bl_config.h"
#include "boot_loader/bl_uart.h"

//*****************************************************************************
//
// If using auto-baud, make sure that the data buffer is large enough.
//
//*****************************************************************************
#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) && (BUFFER_SIZE < 20)
#error ERROR: BUFFER_SIZE must be >= 20!
#endif

//*****************************************************************************
//
//! \addtogroup bl_autobaud_api
//! @{
//
//*****************************************************************************
#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD) || defined(DOXYGEN)

//*****************************************************************************
//
// This define holds the multiplier for the pulse detection algorithm. The
// value is used to generate a fractional difference detection of
// 1 / PULSE_DETECTION_MULT.
//
//*****************************************************************************
#define PULSE_DETECTION_MULT 3

//*****************************************************************************
//
// This define holds the minimum number of edges to successfully sync to a
// pattern of 2 bytes.
//
//*****************************************************************************
#define MIN_EDGE_COUNT 18

//*****************************************************************************
//
// This global holds the number of edges that have been stored in the global
// buffer g_pui32DataBuffer.
//
//*****************************************************************************
static volatile uint32_t g_ui32TickIndex;

//*****************************************************************************
//
// The data buffer that is used for receiving packets is used to hold the edge
// times during auto-baud. The buffer is not used for receiving packets while
// auto-baud is in progress, so this does not present problems.
//
//*****************************************************************************
extern uint32_t g_pui32DataBuffer[];

//*****************************************************************************
//
//! Handles the UART Rx GPIO interrupt.
//!
//! When an edge is detected on the UART Rx pin, this function is called to
//! save the time of the edge. These times are later used to determine the
//! ratio of the UART baud rate to the processor clock rate.
//!
//! \return None.
//
//*****************************************************************************
void
GPIOIntHandler(void)
{
uint32_t ui32Temp;

//
// Clear the GPIO interrupt source.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_ICR) = UART_RX;

//
// While we still have space in our buffer, store the current system tick
// count and return from interrupt.
//
if(g_ui32TickIndex < 20)
{
ui32Temp = HWREG(NVIC_ST_CURRENT);
g_pui32DataBuffer[g_ui32TickIndex++] = ui32Temp;
}
}

//*****************************************************************************
//
//! Performs auto-baud on the UART port.
//!
//! \param pui32Ratio is the ratio of the processor's crystal frequency to the
//! baud rate being used by the UART port for communications.
//!
//! This function attempts to synchronize to the updater program that is trying
//! to communicate with the boot loader. The UART port is monitored for edges
//! using interrupts. Once enough edges are detected, the boot loader
//! determines the ratio of baud rate and crystal frequency needed to program
//! the UART.
//!
//! \return Returns a value of 0 to indicate that this call successfully
//! synchronized with the other device communicating over the UART, and a
//! negative value to indicate that this function did not successfully
//! synchronize with the other UART device.
//
//*****************************************************************************
int
UARTAutoBaud(uint32_t *pui32Ratio)
{
int32_t i32Pulse, i32ValidPulses, i32Temp, i32Total;
volatile int32_t i32Delay;

//
// Configure and enable SysTick. Set the reload value to the maximum;
// there are only 24 bits in the register but loading 32 bits of ones is
// more efficient.
//
HWREG(NVIC_ST_RELOAD) = 0xffffffff;
HWREG(NVIC_ST_CTRL) = NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE;

//
// Reset the counters that control the pulse detection.
//
i32ValidPulses = 0;
i32Total = 0;
g_ui32TickIndex = 0;

//
// Set the pad(s) for standard push-pull operation.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_PUR) |= UART_RX;
HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= UART_RX;

//
// Interrupt on both edges.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_IBE) = UART_RX;

//
// Clear out all of the gpio interrupts in this register.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_ICR) = UART_RX;

//
// Enable the GPIO pin corresponding to the UART RX pin.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_IM) = UART_RX;

//
// Enable GPIOA Interrupt.
//
HWREG(NVIC_EN0) = 1;

//
// Wait for MIN_EDGE_COUNT to pass to collect enough edges.
//
while(g_ui32TickIndex < MIN_EDGE_COUNT)
{
}

//
// Disable GPIOA Interrupt.
//
HWREG(NVIC_DIS0) = 1;

//
// Calculate the pulse widths from the array of tick times.
//
for(i32Pulse = 0; i32Pulse < (MIN_EDGE_COUNT - 1); i32Pulse++)
{
i32Temp = (((int32_t)g_pui32DataBuffer[i32Pulse] -
(int32_t)g_pui32DataBuffer[i32Pulse + 1]) & 0x00ffffff);
g_pui32DataBuffer[i32Pulse] = i32Temp;
}

//
// This loops handles checking for consecutive pulses that have pulse
// widths that are within an acceptable margin.
//
for(i32Pulse = 0; i32Pulse < (MIN_EDGE_COUNT - 1); i32Pulse++)
{
//
// Calculate the absolute difference between two consecutive pulses.
//
i32Temp = (int32_t)g_pui32DataBuffer[i32Pulse];
i32Temp -= (int32_t)g_pui32DataBuffer[i32Pulse + 1];
if(i32Temp < 0)
{
i32Temp *= -1;
}

//
// This pulse detection code uses the following algorithm:
// If the following is true then we have consecutive acceptable pulses
// abs(Pulse[n] - Pulse[n + 1]) < Pulse[n + 1] / PULSE_DETECTION_MULT
// or
// PULSE_DETECTION_MULT * abs(Pulse[n] - Pulse[n + 1]) < Pulse[n + 1]
//
if((i32Temp * PULSE_DETECTION_MULT) <
(int32_t)g_pui32DataBuffer[i32Pulse + 1])
{
i32Total += (int32_t)g_pui32DataBuffer[i32Pulse];
i32ValidPulses++;
}
else
{
i32ValidPulses = 0;
i32Total = 0;
}

//
// Once we have 7 pulses calculate the ratio needed to program the
// UART.
//
if(i32ValidPulses == 7)
{
//
// Add in the last pulse and calculate the ratio.
//
i32Total += (int32_t)g_pui32DataBuffer[i32Pulse];
*pui32Ratio = i32Total >> 1;

//
// Wait for at least 2 UART clocks since we only wait for 18 of 20
// that are coming from the host. If we don't wait, we can turn
// on the UART while the last two pulses come down.
//
for(i32Delay = i32Total; i32Delay; i32Delay--)
{
}

//
// Indicate a successful auto baud operation.
//
return(0);
}
}

//
// Automatic baud rate detection failed.
//
return(-1);
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
#endif
Loading

0 comments on commit 1cd9242

Please sign in to comment.