mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-02 10:24:11 +01:00
a8d4297abe
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@313 ebee16cc-31ac-478f-84a7-5cbb03baadba
210 lines
6.3 KiB
C
210 lines
6.3 KiB
C
/**
|
|
******************************************************************************
|
|
*
|
|
* @file bootloader.h
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
* @brief Bootloader functions header
|
|
* @see The GNU Public License (GPL) Version 3
|
|
*
|
|
*****************************************************************************/
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
/* Includes */
|
|
#include "openpilot_bl.h"
|
|
|
|
/* Local Functions */
|
|
static void Serial_PutString(uint8_t *s);
|
|
static void FLASH_DisableWriteProtectionPages(void);
|
|
static void SerialDownload(void);
|
|
|
|
/* Global Variables */
|
|
extern uint32_t FlashDestination;
|
|
extern uint8_t file_name[FILE_NAME_LENGTH];
|
|
|
|
/* Local variables */
|
|
static uint32_t UserMemoryMask = 0;
|
|
|
|
/**
|
|
* Main bootloader function
|
|
*/
|
|
void StartBootloader(void)
|
|
{
|
|
uint8_t key = 0;
|
|
uint32_t BlockNbr = 0;
|
|
bool FlashProtection = FALSE;
|
|
|
|
/* Get the number of block (4 or 2 pages) from where the user program will be loaded */
|
|
BlockNbr = (FlashDestination - 0x08000000) >> 12;
|
|
|
|
/* Compute the mask to test if the Flash memory, where the user program will be loaded, is write protected */
|
|
if(BlockNbr < 62) {
|
|
UserMemoryMask = ((uint32_t) ~((1 << BlockNbr) - 1));
|
|
} else {
|
|
UserMemoryMask = ((uint32_t) 0x80000000);
|
|
}
|
|
|
|
/* Test if any page of Flash memory where program user will be loaded is write protected */
|
|
if((FLASH_GetWriteProtectionOptionByte() & UserMemoryMask) != UserMemoryMask) {
|
|
FlashProtection = TRUE;
|
|
SerialPutString("Download Image To the STM32F10x Internal Flash ------- 1\r\n");
|
|
SerialPutString("Execute The New Program ------------------------------ 2\r\n");
|
|
SerialPutString("Disable the write protection ------------------------- 3\r\n");
|
|
} else {
|
|
FlashProtection = FALSE;
|
|
SerialPutString("Download Image To the STM32F10x Internal Flash ------- 1\r\n");
|
|
SerialPutString("Execute The New Program ------------------------------ 2\r\n");
|
|
}
|
|
|
|
/* Loop through 1mS check for specified time */
|
|
for(int32_t i = 0; i < OPBL_MAGIC_TIMEOUT; i++) {
|
|
uint16_t start = PIOS_DELAY_TIMER->CNT;
|
|
|
|
/* Check for magic character for 1mS */
|
|
while((volatile uint16_t)(PIOS_DELAY_TIMER->CNT - start) <= 1000) {
|
|
/* Check to see if there is anything on the receiving buffer */
|
|
if(PIOS_COM_ReceiveBufferUsed(OPBL_COM_PORT) > 0) {
|
|
key = PIOS_COM_ReceiveBuffer(OPBL_COM_PORT);
|
|
if(key == 0x31) {
|
|
/* Flash unlock */
|
|
FLASH_Unlock();
|
|
|
|
/* Download user application in the Flash */
|
|
SerialDownload();
|
|
return;
|
|
} else if ((key == 0x33) && (FlashProtection == TRUE)) {
|
|
/* Disable the write protection of desired pages */
|
|
FLASH_DisableWriteProtectionPages();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Calculate the number of pages
|
|
* \param[in] Size The image size
|
|
* \return The number of pages
|
|
*/
|
|
uint32_t FLASH_PagesMask(__IO uint32_t Size)
|
|
{
|
|
uint32_t pagenumber = 0x0;
|
|
uint32_t size = Size;
|
|
|
|
if((size % PAGE_SIZE) != 0) {
|
|
pagenumber = (size / PAGE_SIZE) + 1;
|
|
} else {
|
|
pagenumber = size / PAGE_SIZE;
|
|
}
|
|
return pagenumber;
|
|
|
|
}
|
|
|
|
/**
|
|
* Print a string on the HyperTerminal
|
|
* \param[in] s The string to be printed
|
|
*/
|
|
static void Serial_PutString(uint8_t *s)
|
|
{
|
|
while(*s != '\0') {
|
|
PIOS_COM_SendChar(OPBL_COM_PORT, *s);
|
|
s++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable the write protection of desired pages
|
|
*/
|
|
static void FLASH_DisableWriteProtectionPages(void)
|
|
{
|
|
uint32_t useroptionbyte = 0, WRPR = 0;
|
|
uint16_t var1 = OB_IWDG_SW, var2 = OB_STOP_NoRST, var3 = OB_STDBY_NoRST;
|
|
FLASH_Status status = FLASH_BUSY;
|
|
|
|
WRPR = FLASH_GetWriteProtectionOptionByte();
|
|
|
|
/* Test if user memory is write protected */
|
|
if((WRPR & UserMemoryMask) != UserMemoryMask) {
|
|
useroptionbyte = FLASH_GetUserOptionByte();
|
|
|
|
UserMemoryMask |= WRPR;
|
|
|
|
status = FLASH_EraseOptionBytes();
|
|
|
|
if(UserMemoryMask != 0xFFFFFFFF) {
|
|
status = FLASH_EnableWriteProtection(
|
|
(uint32_t) ~UserMemoryMask);
|
|
}
|
|
|
|
/* Test if user Option Bytes are programmed */
|
|
if((useroptionbyte & 0x07) != 0x07) { /* Restore user Option Bytes */
|
|
if((useroptionbyte & 0x01) == 0x0) {
|
|
var1 = OB_IWDG_HW;
|
|
}
|
|
if((useroptionbyte & 0x02) == 0x0) {
|
|
var2 = OB_STOP_RST;
|
|
}
|
|
if((useroptionbyte & 0x04) == 0x0) {
|
|
var3 = OB_STDBY_RST;
|
|
}
|
|
|
|
FLASH_UserOptionByteConfig(var1, var2, var3);
|
|
}
|
|
|
|
if(status == FLASH_COMPLETE) {
|
|
SerialPutString("Write Protection disabled...\r\n");
|
|
|
|
SerialPutString("...and a System Reset will be generated to re-load the new option bytes\r\n");
|
|
|
|
/* Enable WWDG clock */
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
|
|
|
|
/* Generate a system Reset to re-load the new option bytes: enable WWDG and set
|
|
counter value to 0x4F, as T6 bit is cleared this will generate a WWDG reset */
|
|
WWDG_Enable(0x4F);
|
|
} else {
|
|
SerialPutString("Error: Flash write unprotection failed...\r\n");
|
|
}
|
|
} else {
|
|
SerialPutString("Flash memory not write protected\r\n");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Download and program the binary file
|
|
*/
|
|
static void SerialDownload(void)
|
|
{
|
|
uint8_t tab_1024[1024] = { 0 };
|
|
int32_t Size = 0;
|
|
|
|
SerialPutString("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
|
|
Size = Ymodem_Receive(&tab_1024[0]);
|
|
if(Size > 0) {
|
|
SerialPutString("\n\n\rProgramming Completed Successfully!\n\r");
|
|
} else if(Size == -1) {
|
|
SerialPutString("\n\n\rThe image size is higher than the allowed space memory!\n\r");
|
|
} else if(Size == -2) {
|
|
SerialPutString("\n\n\rVerification failed!\n\r");
|
|
} else if(Size == -3) {
|
|
SerialPutString("\r\n\nAborted by user.\n\r");
|
|
} else {
|
|
SerialPutString("\n\rFailed to receive the file!\n\r");
|
|
}
|
|
}
|