summaryrefslogtreecommitdiff
path: root/boot_loader/bl_check.c
diff options
context:
space:
mode:
authorYuval Adam <yuval@y3xz.com>2015-03-13 12:24:52 +0200
committerYuval Adam <yuval@y3xz.com>2015-03-13 12:24:52 +0200
commit4085ae3ddfbbf10c8ccbd3dccd43452c40a1fe40 (patch)
treeac63581949a49511136e7e9e47d265bfb4119b26 /boot_loader/bl_check.c
parent788db64b8642bf31de6930d18a62177c64163ee0 (diff)
Add bootloader, nfclib and sensorlib
Diffstat (limited to 'boot_loader/bl_check.c')
-rw-r--r--boot_loader/bl_check.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/boot_loader/bl_check.c b/boot_loader/bl_check.c
new file mode 100644
index 0000000..b481013
--- /dev/null
+++ b/boot_loader/bl_check.c
@@ -0,0 +1,266 @@
+//*****************************************************************************
+//
+// bl_check.c - Code to check for a forced update.
+//
+// Copyright (c) 2006-2014 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.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "inc/hw_gpio.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_sysctl.h"
+#include "inc/hw_types.h"
+#include "bl_config.h"
+#include "boot_loader/bl_check.h"
+#include "boot_loader/bl_hooks.h"
+#ifdef CHECK_CRC
+#include "boot_loader/bl_crc32.h"
+#endif
+
+//*****************************************************************************
+//
+//! \addtogroup bl_check_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// This global is used to remember if a forced update occurred.
+//
+//*****************************************************************************
+#ifdef ENABLE_UPDATE_CHECK
+uint32_t g_ui32Forced;
+#endif
+
+//*****************************************************************************
+//
+// A prototype for the function (in the startup code) for a predictable length
+// delay.
+//
+//*****************************************************************************
+extern void Delay(uint32_t ui32Count);
+
+//*****************************************************************************
+//
+//! Checks a GPIO for a forced update.
+//!
+//! This function checks the state of a GPIO to determine if a update is being
+//! requested.
+//!
+//! \return Returns a non-zero value if an update is being requested and zero
+//! otherwise.
+//
+//*****************************************************************************
+#ifdef ENABLE_UPDATE_CHECK
+uint32_t
+CheckGPIOForceUpdate(void)
+{
+ //
+ // Enable the required GPIO module.
+ //
+ HWREG(SYSCTL_RCGC2) |= FORCED_UPDATE_PERIPH;
+
+ //
+ // Wait a while before accessing the peripheral.
+ //
+ Delay(3);
+
+#ifdef FORCED_UPDATE_KEY
+ //
+ // Unlock the GPIO Access.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_LOCK) = FORCED_UPDATE_KEY;
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_CR) = 1 << FORCED_UPDATE_PIN;
+#endif
+
+ //
+ // Enable the pin used to see if an update is being requested.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_DEN) |= 1 << FORCED_UPDATE_PIN;
+#ifdef FORCED_UPDATE_WPU
+ //
+ // Set the output drive strength.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_DR2R) |= 1 << FORCED_UPDATE_PIN;
+
+ //
+ // Enable the weak pull up.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_PUR) |= 1 << FORCED_UPDATE_PIN;
+
+ //
+ // Make sure that the analog mode select register is clear for this pin.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_AMSEL) &= ~(1 << FORCED_UPDATE_PIN);
+#endif
+#ifdef FORCED_UPDATE_WPD
+ //
+ // Set the output drive strength.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_DR2R) |= 1 << FORCED_UPDATE_PIN;
+
+ //
+ // Enable the weak pull down.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_PDR) |= 1 << FORCED_UPDATE_PIN;
+
+ //
+ // Make sure that the analog mode select register is clear for this pin.
+ // This register only appears in DustDevil-class (and later) devices, but
+ // is a harmless write on Sandstorm- and Fury-class devices.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_AMSEL) &= ~(1 << FORCED_UPDATE_PIN);
+#endif
+
+#ifdef FORCED_UPDATE_KEY
+ //
+ // Unlock the GPIO Access.
+ //
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_LOCK) = FORCED_UPDATE_KEY;
+ HWREG(FORCED_UPDATE_PORT + GPIO_O_CR) = 0;
+#endif
+
+ //
+ // Wait a while before reading the pin.
+ //
+ Delay(1000);
+
+ //
+ // Check the pin to see if an update is being requested.
+ //
+ if(HWREG(FORCED_UPDATE_PORT + (1 << (FORCED_UPDATE_PIN + 2))) ==
+ (FORCED_UPDATE_POLARITY << FORCED_UPDATE_PIN))
+ {
+ //
+ // Remember that this was a forced update.
+ //
+ g_ui32Forced = 1;
+
+ return(1);
+ }
+
+ //
+ // No update is being requested so return 0.
+ //
+ return(0);
+}
+#endif
+
+//*****************************************************************************
+//
+//! Checks if an update is needed or is being requested.
+//!
+//! This function detects if an update is being requested or if there is no
+//! valid code presently located on the microcontroller. This is used to tell
+//! whether or not to enter update mode.
+//!
+//! \return Returns a non-zero value if an update is needed or is being
+//! requested and zero otherwise.
+//
+//*****************************************************************************
+uint32_t
+CheckForceUpdate(void)
+{
+#ifdef CHECK_CRC
+ uint32_t ui32Retcode;
+#endif
+
+#ifdef BL_CHECK_UPDATE_FN_HOOK
+ //
+ // If the update check function is hooked, call the application to determine
+ // how to proceed.
+ //
+ return(BL_CHECK_UPDATE_FN_HOOK());
+#else
+ uint32_t *pui32App;
+
+#ifdef ENABLE_UPDATE_CHECK
+ g_ui32Forced = 0;
+#endif
+
+ //
+ // See if the first location is 0xfffffffff or something that does not
+ // look like a stack pointer, or if the second location is 0xffffffff or
+ // something that does not look like a reset vector.
+ //
+ pui32App = (uint32_t *)APP_START_ADDRESS;
+ if((pui32App[0] == 0xffffffff) ||
+ ((pui32App[0] & 0xfff00000) != 0x20000000) ||
+ (pui32App[1] == 0xffffffff) ||
+ ((pui32App[1] & 0xfff00001) != 0x00000001))
+ {
+ return(1);
+ }
+
+ //
+ // If required, scan the image for an embedded CRC and ensure that it
+ // matches the current CRC of the image.
+ //
+#ifdef CHECK_CRC
+ InitCRC32Table();
+ ui32Retcode = CheckImageCRC32(pui32App);
+
+ //
+ // If ENFORCE_CRC is defined, we only boot the image if the CRC is
+ // present in the image information header and the value calculated
+ // matches the value in the header. If ENFORCE_CRC is not defined, we
+ // the image if the CRC is good but also if the length field of the header
+ // is zero (which typically indicates that the post-build step of running
+ // binpack to add the length and CRC to the header was not run).
+ //
+#ifdef ENFORCE_CRC
+ if(ui32Retcode != CHECK_CRC_OK)
+#else
+ if((ui32Retcode != CHECK_CRC_OK) && (ui32Retcode != CHECK_CRC_NO_LENGTH))
+#endif
+ {
+ //
+ // The CRC32 image check failed indicating that the image is
+ // corrupt (or doesn't have the CRC embedded correctly). Either way,
+ // fail the update check and force the boot loader to retain control.
+ //
+ return(2);
+ }
+#endif
+
+#ifdef ENABLE_UPDATE_CHECK
+ //
+ // If simple GPIO checking is configured, determine whether or not to force
+ // an update.
+ //
+ return(CheckGPIOForceUpdate());
+#else
+ //
+ // GPIO checking is not required so, if we get here, a valid image exists
+ // and no update is needed.
+ //
+ return(0);
+#endif
+#endif
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************