📄 bl_main.c
字号:
//*****************************************************************************
//
// bl_main.c - The file holds the main control loop of the boot loader.
//
// Copyright (c) 2006-2008 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. You may not combine
// this software with "viral" open-source software in order to form a larger
// program. Any use in violation of the foregoing restrictions may subject
// the user to criminal sanctions under applicable laws, as well as to civil
// liability for the breach of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". 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.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 3047 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************
#include "hw_gpio.h"
#include "hw_flash.h"
#include "hw_i2c.h"
#include "hw_memmap.h"
#include "hw_nvic.h"
#include "hw_ssi.h"
#include "hw_sysctl.h"
#include "hw_types.h"
#include "hw_uart.h"
#include "bl_commands.h"
#include "bl_config.h"
#include "bl_decrypt.h"
#include "bl_i2c.h"
#include "bl_packet.h"
#include "bl_ssi.h"
#include "bl_uart.h"
#include "bootldr.h"
#include "aes.h"
#include <hw_types.h>
#include <hw_memmap.h>
#include <hw_sysctl.h>
#include <hw_gpio.h>
#include <sysctl.h>
#include <gpio.h>
#define ewarm
// 将较长的标识符定义成较短的形式
#define SysCtlPeriEnable SysCtlPeripheralEnable
#define SysCtlPeriDisable SysCtlPeripheralDisable
#define GPIOPinTypeIn GPIOPinTypeGPIOInput
#define GPIOPinTypeOut GPIOPinTypeGPIOOutput
#define GPIOPinTypeOD GPIOPinTypeGPIOOutputOD
// 定义LED
#define LED_PERIPH SYSCTL_PERIPH_GPIOC
#define LED_PORT GPIO_PORTC_BASE
#define LED_PIN GPIO_PIN_7
#define ledOn() GPIOPinWrite(LED_PORT , LED_PIN , 0x00 << 7)
#define ledOff() GPIOPinWrite(LED_PORT , LED_PIN , 0x01 << 7)
#define ledToggle() GPIOPinWrite(LED_PORT , LED_PIN , ~GPIOPinRead(LED_PORT , LED_PIN))
//*****************************************************************************
//
// Make sure that the application start address is a multiple of 1024 bytes.
//
//*****************************************************************************
#if (APP_START_ADDRESS & 0x3ff)
#error ERROR: APP_START_ADDRESS must be a multiple of 1024 bytes!
#endif
//*****************************************************************************
//
// Make sure that the flash reserved space is a multiple of 1024 bytes.
//
//*****************************************************************************
#if (FLASH_RSVD_SPACE & 0x3ff)
#error ERROR: FLASH_RSVD_SPACE must be a multiple of 1024 bytes!
#endif
//*****************************************************************************
//
//! \addtogroup boot_loader_api
//! @{
//
//*****************************************************************************
#if defined(I2C_ENABLE_UPDATE) || defined(SSI_ENABLE_UPDATE) || \
defined(UART_ENABLE_UPDATE) || defined(DOXYGEN)
//*****************************************************************************
//
// A prototype for the function (in the startup code) for calling the
// application.
//
//*****************************************************************************
extern void CallApplication(unsigned long ulBase);
//*****************************************************************************
//
// A prototype for the function (in the startup code) for a predictable length
// delay.
//
//*****************************************************************************
extern void Delay(unsigned long ulCount);
//*****************************************************************************
//
// Holds the current status of the last command that was issued to the boot
// loader.
//
//*****************************************************************************
//unsigned char g_ucStatus;
//*****************************************************************************
//
// This holds the current remaining size in bytes to be downloaded.
//
//*****************************************************************************
//unsigned long g_ulTransferSize;
//*****************************************************************************
//
// This holds the current address that is being written to during a download
// command.
//
//*****************************************************************************
//unsigned long g_ulTransferAddress;
//*****************************************************************************
//
// This is the data buffer used during transfers to the boot loader.
//
//*****************************************************************************
unsigned long g_pulDataBuffer[BUFFER_SIZE/4];
//*****************************************************************************
//
// This is an specially aligned buffer pointer to g_pulDataBuffer to make
// copying to the buffer simpler. It must be offset to end on an address that
// ends with 3.
//
//*****************************************************************************
unsigned char *g_pucDataBuffer;
//*****************************************************************************
//
// Converts a word from big endian to little endian. This macro uses compiler-
// specific constructs to perform an inline insertion of the "rev" instruction,
// which performs the byte swap directly.
//
//*****************************************************************************
//=============================================================================
// Error Codes
#define ERROR_OK 0x11
#define ERROR_CRC 0x22
//=============================================================================
// Frame types
#define TYPE_EOF 0
#define TYPE_ERASE 1
#define TYPE_PREPARE 2
#define TYPE_DATA 3
#define TYPE_PROGRAM 4
#define TYPE_EEPROM 5
#define TYPE_LOCKBITS 6
#define TYPE_RESET 7
#if KEY_COUNT > 0
const unsigned char initialVector[16] =
{
(unsigned char)(INITIALVECTOR_3 >> 24),
(unsigned char)(INITIALVECTOR_3 >> 16),
(unsigned char)(INITIALVECTOR_3 >> 8),
(unsigned char)(INITIALVECTOR_3 >> 0),
(unsigned char)(INITIALVECTOR_2 >> 24),
(unsigned char)(INITIALVECTOR_2 >> 16),
(unsigned char)(INITIALVECTOR_2 >> 8),
(unsigned char)(INITIALVECTOR_2 >> 0),
(unsigned char)(INITIALVECTOR_1 >> 24),
(unsigned char)(INITIALVECTOR_1 >> 16),
(unsigned char)(INITIALVECTOR_1 >> 8),
(unsigned char)(INITIALVECTOR_1 >> 0),
(unsigned char)(INITIALVECTOR_0 >> 24),
(unsigned char)(INITIALVECTOR_0 >> 16),
(unsigned char)(INITIALVECTOR_0 >> 8),
(unsigned char)(INITIALVECTOR_0 >> 0)
};
#endif // KEY_COUNT > 0
#if defined(ewarm)
#include <intrinsics.h>
#define SwapWord(x) __REV(x)
#endif
#if defined(codered) || defined(gcc) || defined(sourcerygxx)
#define SwapWord(x) __extension__ \
({ \
register unsigned long __ret, __inp = x; \
__asm__("rev %0, %1" : "=r" (__ret) : "r" (__inp)); \
__ret; \
})
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION)
#define SwapWord(x) __rev(x)
#endif
//*****************************************************************************
//
//! Configures the microcontroller.
//!
//! This function configures the peripherals and GPIOs of the microcontroller,
//! preparing it for use by the boot loader. The interface that has been
//! selected as the update port will be configured, and auto-baud will be
//! performed if required.
//!
//! This function is contained in <tt>bl_main.c</tt>.
//!
//! \return None.
//
//*****************************************************************************
void
ConfigureDevice(void)
{
#ifdef UART_ENABLE_UPDATE
unsigned long ulProcRatio;
#endif
#ifdef CRYSTAL_FREQ
//
// Since the crystal frequency was specified, enable the main oscillator
// and clock the processor from it.
//
HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCDIS);
Delay(524288);
HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & ~(SYSCTL_RCC_OSCSRC_M)) |
SYSCTL_RCC_OSCSRC_MAIN);
//
// Set the flash programming time based on the specified crystal frequency.
//
HWREG(FLASH_USECRL) = ((CRYSTAL_FREQ + 999999) / 1000000) - 1;
#else
//
// Set the flash to program at 16 MHz since that is just beyond the fastest
// that we could run.
//
HWREG(FLASH_USECRL) = 15;
#endif
#ifdef I2C_ENABLE_UPDATE
//
// Enable the clocks to the I2C and GPIO modules.
//
HWREG(SYSCTL_RCGC2) = SYSCTL_RCGC2_GPIOB;
HWREG(SYSCTL_RCGC1) = SYSCTL_RCGC1_I2C0;
//
// Configure the GPIO pins for hardware control, open drain with pull-up,
// and enable them.
//
HWREG(GPIO_PORTB_BASE + GPIO_O_AFSEL) = (1 << 7) | I2C_PINS;
HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) = (1 << 7) | I2C_PINS;
HWREG(GPIO_PORTB_BASE + GPIO_O_ODR) = I2C_PINS;
//
// Enable the I2C Slave Mode.
//
HWREG(I2C0_MASTER_BASE + I2C_O_MCR) = I2C_MCR_MFE | I2C_MCR_SFE;
//
// Setup the I2C Slave Address.
//
HWREG(I2C0_SLAVE_BASE + I2C_O_SOAR) = I2C_SLAVE_ADDR;
//
// Enable the I2C Slave Device on the I2C bus.
//
HWREG(I2C0_SLAVE_BASE + I2C_O_SCSR) = I2C_SCSR_DA;
#endif
#ifdef SSI_ENABLE_UPDATE
//
// Enable the clocks to the SSI and GPIO modules.
//
HWREG(SYSCTL_RCGC2) = SYSCTL_RCGC2_GPIOA;
HWREG(SYSCTL_RCGC1) = SYSCTL_RCGC1_SSI0;
//
// Make the pin be peripheral controlled.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) = SSI_PINS;
HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) = SSI_PINS;
//
// Set the SSI protocol to Motorola with default clock high and data
// valid on the rising edge.
//
HWREG(SSI0_BASE + SSI_O_CR0) = (SSI_CR0_SPH | SSI_CR0_SPO |
(DATA_BITS_SSI - 1));
//
// Enable the SSI interface in slave mode.
//
HWREG(SSI0_BASE + SSI_O_CR1) = SSI_CR1_MS | SSI_CR1_SSE;
#endif
#ifdef UART_ENABLE_UPDATE
//
// Enable the the clocks to the UART and GPIO modules.
//
HWREG(SYSCTL_RCGC2) = SYSCTL_RCGC2_GPIOA;
HWREG(SYSCTL_RCGC1) = SYSCTL_RCGC1_UART0;
//
// Keep attempting to sync until we are successful.
//
#ifdef UART_AUTOBAUD
while(UARTAutoBaud(&ulProcRatio) < 0)
{
}
#else
ulProcRatio = UART_BAUD_RATIO(UART_FIXED_BAUDRATE);
#endif
//
// Set GPIO A0 and A1 as UART pins.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) = UART_PINS;
//
// Set the pin type.
//
HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) = UART_PINS;
//
// Set the baud rate.
//
HWREG(UART0_BASE + UART_O_IBRD) = ulProcRatio >> 6;
HWREG(UART0_BASE + UART_O_FBRD) = ulProcRatio & 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;
//
// Enable RX, TX, and the UART.
//
HWREG(UART0_BASE + UART_O_CTL) = (UART_CTL_UARTEN | UART_CTL_TXE |
UART_CTL_RXE);
#ifdef UART_AUTOBAUD
//
// Need to ack in the UART case to hold it up while we get things set up.
//
AckPacket();
#endif
#endif
}
unsigned short CRC(unsigned short oldCRC,unsigned char ch)
{
static const unsigned short crcPoly = 0x8005;
int n;
unsigned long m;
m = ((unsigned long)oldCRC << 8) | ch;
for (n = 0; n < 8; n++)
if ((m <<= 1) & 0x1000000)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -