1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

OP-874 merge of amorale/OP-874_gcs_rescue_erase_settings in next.

+review OPReview-421
This commit is contained in:
Alessio Morale 2013-04-08 01:09:31 +02:00
parent 5dc467bda4
commit 09d2ba1d25
34 changed files with 1248 additions and 2901 deletions

View File

@ -61,6 +61,8 @@ uint8_t Data0;
uint8_t Data1;
uint8_t Data2;
uint8_t Data3;
uint32_t Opt[3];
uint8_t offset = 0;
uint32_t aux;
//Download vars
@ -133,6 +135,14 @@ void processComand(uint8_t *xReceive_Buffer) {
Data1 = xReceive_Buffer[DATA + 1];
Data2 = xReceive_Buffer[DATA + 2];
Data3 = xReceive_Buffer[DATA + 3];
for( uint32_t i=0; i < 3; i++ )
{
Opt[i] = xReceive_Buffer[DATA + 4 * (i+1) ] << 24 |
xReceive_Buffer[DATA + 4 * (i+1) + 1] << 16 |
xReceive_Buffer[DATA + 4 * (i+1) + 2] << 8 |
xReceive_Buffer[DATA + 4 * (i+1) + 3];
}
Command = Command & 0b00011111;
if (EchoReqFlag == 1) {
@ -296,10 +306,16 @@ void processComand(uint8_t *xReceive_Buffer) {
sendData(Buffer + 1, 63);
break;
case JumpFW:
if (Data == 0x5AFE) {
if (Data == 0x5AFE)
{
/* Force board into safe mode */
PIOS_IAP_WriteBootCount(0xFFFF);
}
// pass any Opt value to the firmware
PIOS_IAP_WriteBootCmd(0, Opt[0]);
PIOS_IAP_WriteBootCmd(1, Opt[1]);
PIOS_IAP_WriteBootCmd(2, Opt[2]);
FLASH_Lock();
JumpToApp = 1;
break;
@ -339,8 +355,8 @@ void processComand(uint8_t *xReceive_Buffer) {
downType = Data0;
downPacketTotal = Count;
downSizeOfLastPacket = Data1;
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14 * 4
+ downSizeOfLastPacket * 4) == 1) {
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14
+ downSizeOfLastPacket) == 1) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
@ -383,8 +399,8 @@ void processComand(uint8_t *xReceive_Buffer) {
}
if (EchoReqFlag == 1) {
echoBuffer[0] = echoBuffer[0] | (1 << 6);
sendData(echoBuffer, 63);
echoBuffer[1] = echoBuffer[1] | EchoAnsFlag;
sendData(echoBuffer + 1, 63);
}
return;
}

View File

@ -3,7 +3,7 @@
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_IAP IAP Functions
* @brief STM32F4xx Hardware dependent I2C functionality
* @brief Common IAP functionality
* @{
*
* @file pios_iap.c
@ -32,6 +32,7 @@
* Header files
****************************************************************************************/
#include <pios.h>
#include <pios_bkp.h>
#ifdef PIOS_INCLUDE_IAP
@ -55,7 +56,12 @@
/****************************************************************************************
* Private (static) Data
****************************************************************************************/
const uint16_t pios_iap_cmd_list[] =
{
IAP_CMD1,
IAP_CMD2,
IAP_CMD3
};
/****************************************************************************************
* Public/Global Data
****************************************************************************************/
@ -70,17 +76,8 @@
*/
void PIOS_IAP_Init( void )
{
/* Enable CRC clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
/* Enable PWR and BKP clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_AHB1Periph_BKPSRAM, ENABLE);
/* Enable write access to Backup domain */
PWR_BackupAccessCmd(ENABLE);
/* Clear Tamper pin Event(TE) pending flag */
RTC_ClearFlag(RTC_FLAG_TAMP1F);
PIOS_BKP_Init();
PIOS_BKP_EnableWrite();
}
/*!
@ -97,8 +94,8 @@ uint32_t PIOS_IAP_CheckRequest( void )
uint16_t reg1;
uint16_t reg2;
reg1 = RTC_ReadBackupRegister( MAGIC_REG_1 );
reg2 = RTC_ReadBackupRegister( MAGIC_REG_2 );
reg1 = PIOS_BKP_ReadRegister(MAGIC_REG_1);
reg2 = PIOS_BKP_ReadRegister(MAGIC_REG_2);
if( reg1 == IAP_MAGIC_WORD_1 && reg2 == IAP_MAGIC_WORD_2 ) {
// We have a match.
@ -119,28 +116,62 @@ uint32_t PIOS_IAP_CheckRequest( void )
*/
void PIOS_IAP_SetRequest1(void)
{
RTC_WriteBackupRegister( MAGIC_REG_1, IAP_MAGIC_WORD_1);
PIOS_BKP_WriteRegister(MAGIC_REG_1, IAP_MAGIC_WORD_1);
}
void PIOS_IAP_SetRequest2(void)
{
RTC_WriteBackupRegister( MAGIC_REG_2, IAP_MAGIC_WORD_2);
PIOS_BKP_WriteRegister(MAGIC_REG_2, IAP_MAGIC_WORD_2);
}
void PIOS_IAP_ClearRequest(void)
{
RTC_WriteBackupRegister( MAGIC_REG_1, 0);
RTC_WriteBackupRegister( MAGIC_REG_2, 0);
PIOS_BKP_WriteRegister(MAGIC_REG_1, 0);
PIOS_BKP_WriteRegister(MAGIC_REG_2, 0);
}
uint16_t PIOS_IAP_ReadBootCount(void)
{
return RTC_ReadBackupRegister ( IAP_BOOTCOUNT );
return PIOS_BKP_ReadRegister(IAP_BOOTCOUNT);
}
void PIOS_IAP_WriteBootCount (uint16_t boot_count)
{
RTC_WriteBackupRegister ( IAP_BOOTCOUNT, boot_count );
PIOS_BKP_WriteRegister(IAP_BOOTCOUNT, boot_count);
}
/**
* @brief Return one of the IAP command values passed from bootloader.
* @param number: the index of the command value (0..2).
* @retval the selected command value.
*/
uint32_t PIOS_IAP_ReadBootCmd(uint8_t number)
{
if(PIOS_IAP_CMD_COUNT < number)
{
PIOS_Assert(0);
}
else
{
return PIOS_BKP_ReadRegister(pios_iap_cmd_list[number]);
}
}
/**
* @brief Write one of the IAP command values to be passed to firmware from bootloader.
* @param number: the index of the command value (0..2).
* @param value: value to be written.
*/
void PIOS_IAP_WriteBootCmd(uint8_t number, uint32_t value)
{
if(PIOS_IAP_CMD_COUNT < number)
{
PIOS_Assert(0);
}
else
{
PIOS_BKP_WriteRegister(pios_iap_cmd_list[number], value);
}
}
#endif /* PIOS_INCLUDE_IAP */

View File

@ -0,0 +1,149 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_BKP Backup SRAM functions
* @brief Hardware abstraction layer for backup sram
* @{
*
* @file pios_bkp.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief IAP functions
* @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
*/
#include <pios.h>
#include <pios_bkp.h>
#include <stm32f10x.h>
#include <stm32f10x_bkp.h>
#include <stm32f10x_pwr.h>
/****************************************************************************************
* Header files
****************************************************************************************/
/*****************************************************************************************
* Public Definitions/Macros
****************************************************************************************/
/****************************************************************************************
* Public Functions
****************************************************************************************/
const uint32_t pios_bkp_registers_map[] =
{
BKP_DR1 ,
BKP_DR2 ,
BKP_DR3 ,
BKP_DR4 ,
BKP_DR5 ,
BKP_DR6 ,
BKP_DR7 ,
BKP_DR8 ,
BKP_DR9 ,
BKP_DR10,
BKP_DR11,
BKP_DR12,
BKP_DR13,
BKP_DR14,
BKP_DR15,
BKP_DR16,
BKP_DR17,
BKP_DR18,
BKP_DR19,
#if FALSE /* Not enabled as stm32f4 needs some modifications to
* accomodate more than 20 registers (like storing 2 uint16_t
* regs in one uint32_t bkp location)
*/
BKP_DR20,
BKP_DR21,
BKP_DR22,
BKP_DR23,
BKP_DR24,
BKP_DR25,
BKP_DR26,
BKP_DR27,
BKP_DR28,
BKP_DR29,
BKP_DR30,
BKP_DR32,
BKP_DR33,
BKP_DR34,
BKP_DR35,
BKP_DR36,
BKP_DR37,
BKP_DR38,
BKP_DR39,
BKP_DR40,
BKP_DR41,
BKP_DR42,
#endif
};
#define PIOS_BKP_REGISTERS_COUNT NELEMENTS(pios_bkp_registers_map)
void PIOS_BKP_Init(void)
{
/* Enable CRC clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
/* Enable PWR and BKP clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Clear Tamper pin Event(TE) pending flag */
BKP_ClearFlag();
}
uint16_t PIOS_BKP_ReadRegister(uint32_t regnumber)
{
if(PIOS_BKP_REGISTERS_COUNT < regnumber)
{
PIOS_Assert(0);
} else {
return (uint16_t) BKP_ReadBackupRegister(pios_bkp_registers_map[regnumber]);
}
}
void PIOS_BKP_WriteRegister(uint32_t regnumber,uint16_t data)
{
if(PIOS_BKP_REGISTERS_COUNT < regnumber)
{
PIOS_Assert(0);
} else {
BKP_WriteBackupRegister(pios_bkp_registers_map[regnumber],(uint32_t)data);
}
}
void PIOS_BKP_EnableWrite(void)
{
/* Enable write access to Backup domain */
PWR_BackupAccessCmd(ENABLE);
}
void PIOS_BKP_DisableWrite(void)
{
/* Enable write access to Backup domain */
PWR_BackupAccessCmd(DISABLE);
}
/****************************************************************************************
* Public Data
****************************************************************************************/

View File

@ -1,126 +0,0 @@
/*!
* @File iap.c
* @Brief
*
* Created on: Sep 6, 2010
* Author: joe
*/
/****************************************************************************************
* Header files
****************************************************************************************/
#include <pios.h>
#ifdef PIOS_INCLUDE_IAP
/****************************************************************************************
* Private Definitions/Macros
****************************************************************************************/
/* these definitions reside here for protection and privacy. */
#define IAP_MAGIC_WORD_1 0x1122
#define IAP_MAGIC_WORD_2 0xAA55
#define UPPERWORD16(lw) (uint16_t)((uint32_t)(lw)>>16)
#define LOWERWORD16(lw) (uint16_t)((uint32_t)(lw)&0x0000ffff)
#define UPPERBYTE(w) (uint8_t)((w)>>8)
#define LOWERBYTE(w) (uint8_t)((w)&0x00ff)
/****************************************************************************************
* Private Functions
****************************************************************************************/
/****************************************************************************************
* Private (static) Data
****************************************************************************************/
/****************************************************************************************
* Public/Global Data
****************************************************************************************/
/*!
* \brief PIOS_IAP_Init - performs required initializations for iap module.
* \param none.
* \return none.
* \retval none.
*
* Created: Sep 8, 2010 10:10:48 PM by joe
*/
void PIOS_IAP_Init( void )
{
/* Enable CRC clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
/* Enable PWR and BKP clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Enable write access to Backup domain */
PWR_BackupAccessCmd(ENABLE);
/* Clear Tamper pin Event(TE) pending flag */
BKP_ClearFlag();
}
/*!
* \brief Determines if an In-Application-Programming request has been made.
* \param *comm - Which communication stream to use for the IAP (USB, Telemetry, I2C, SPI, etc)
* \return TRUE - if correct sequence found, along with 'comm' updated.
* FALSE - Note that 'comm' will have an invalid comm identifier.
* \retval
*
*/
uint32_t PIOS_IAP_CheckRequest( void )
{
uint32_t retval = FALSE;
uint16_t reg1;
uint16_t reg2;
reg1 = BKP_ReadBackupRegister( MAGIC_REG_1 );
reg2 = BKP_ReadBackupRegister( MAGIC_REG_2 );
if( reg1 == IAP_MAGIC_WORD_1 && reg2 == IAP_MAGIC_WORD_2 ) {
// We have a match.
retval = TRUE;
} else {
retval = FALSE;
}
return retval;
}
/*!
* \brief Sets the 1st word of the request sequence.
* \param n/a
* \return n/a
* \retval
*/
void PIOS_IAP_SetRequest1(void)
{
BKP_WriteBackupRegister( MAGIC_REG_1, IAP_MAGIC_WORD_1);
}
void PIOS_IAP_SetRequest2(void)
{
BKP_WriteBackupRegister( MAGIC_REG_2, IAP_MAGIC_WORD_2);
}
void PIOS_IAP_ClearRequest(void)
{
BKP_WriteBackupRegister( MAGIC_REG_1, 0);
BKP_WriteBackupRegister( MAGIC_REG_2, 0);
}
uint16_t PIOS_IAP_ReadBootCount(void)
{
return BKP_ReadBackupRegister ( IAP_BOOTCOUNT );
}
void PIOS_IAP_WriteBootCount (uint16_t boot_count)
{
BKP_WriteBackupRegister ( IAP_BOOTCOUNT, boot_count );
}
#endif /* PIOS_INCLUDE_IAP */

View File

@ -0,0 +1,119 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_BKP Backup SRAM functions
* @brief Hardware abstraction layer for backup sram
* @{
*
* @file pios_bkp.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief IAP functions
* @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
*/
#include <pios.h>
#include <pios_bkp.h>
#include <stm32f4xx_rtc.h>
/****************************************************************************************
* Header files
****************************************************************************************/
/*****************************************************************************************
* Public Definitions/Macros
****************************************************************************************/
/****************************************************************************************
* Public Functions
****************************************************************************************/
const uint32_t pios_bkp_registers_map[] =
{
RTC_BKP_DR0,
RTC_BKP_DR1,
RTC_BKP_DR2,
RTC_BKP_DR3,
RTC_BKP_DR4,
RTC_BKP_DR5,
RTC_BKP_DR6,
RTC_BKP_DR7,
RTC_BKP_DR8,
RTC_BKP_DR9,
RTC_BKP_DR10,
RTC_BKP_DR11,
RTC_BKP_DR12,
RTC_BKP_DR13,
RTC_BKP_DR14,
RTC_BKP_DR15,
RTC_BKP_DR16,
RTC_BKP_DR17,
RTC_BKP_DR18,
RTC_BKP_DR19
};
#define PIOS_BKP_REGISTERS_COUNT NELEMENTS(pios_bkp_registers_map)
void PIOS_BKP_Init(void)
{
/* Enable CRC clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC | RCC_AHB1Periph_BKPSRAM, ENABLE);
/* Enable PWR and BKP clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Clear Tamper pin Event(TE) pending flag */
RTC_ClearFlag(RTC_FLAG_TAMP1F);
}
uint16_t PIOS_BKP_ReadRegister(uint32_t regnumber)
{
if(PIOS_BKP_REGISTERS_COUNT < regnumber)
{
PIOS_Assert(0);
} else {
return (uint16_t) RTC_ReadBackupRegister(pios_bkp_registers_map[regnumber]);
}
}
void PIOS_BKP_WriteRegister(uint32_t regnumber,uint16_t data)
{
if(PIOS_BKP_REGISTERS_COUNT < regnumber)
{
PIOS_Assert(0);
} else {
RTC_WriteBackupRegister(pios_bkp_registers_map[regnumber],(uint32_t)data);
}
}
void PIOS_BKP_EnableWrite(void)
{
/* Enable write access to Backup domain */
PWR_BackupAccessCmd(ENABLE);
}
void PIOS_BKP_DisableWrite(void)
{
/* Enable write access to Backup domain */
PWR_BackupAccessCmd(DISABLE);
}
/****************************************************************************************
* Public Data
****************************************************************************************/

View File

@ -220,7 +220,7 @@ int32_t PIOS_SYS_Reset(void)
*/
uint32_t PIOS_SYS_getCPUFlashSize(void)
{
return ((uint32_t) MEM16(0x1fff7a10) * 1000); // it might be possible to locate in the OTP area, but haven't looked and not documented
return ((uint32_t) MEM16(0x1fff7a22) * 1024); // it might be possible to locate in the OTP area, but haven't looked and not documented
}
/**

118
flight/PiOS/inc/pios_bkp.h Normal file
View File

@ -0,0 +1,118 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_BKP Backup SRAM functions
* @brief Hardware abstraction layer for backup sram
* @{
*
* @file pios_bkp.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief IAP functions
* @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
*/
/* Project Includes */
#ifndef PIOS_BKP_H_
#define PIOS_BKP_H_
/****************************************************************************************
* Header files
****************************************************************************************/
/*****************************************************************************************
* Public Definitions/Macros
****************************************************************************************/
// Backup registers definitions
// registers reserved for PIOS usage
#define PIOS_BKP_RESERVED_1 0 // IAP_MAGIC_REG_1
#define PIOS_BKP_RESERVED_2 1 // IAP_MAGIC_REG_2
#define PIOS_BKP_RESERVED_3 2 // IAP_BOOTCOUNT
#define PIOS_BKP_RESERVED_4 3 // PIOS_WDG_REGISTER
#define PIOS_BKP_RESERVED_5 4 // IAP_CMD1
#define PIOS_BKP_RESERVED_6 5 // IAP_CMD2
#define PIOS_BKP_RESERVED_7 6 // IAP_CMD3
#define PIOS_BKP_RESERVED_8 7
#define PIOS_BKP_RESERVED_9 8
#define PIOS_BKP_RESERVED_10 9
// registers reserved for BOARD specific usage
#define PIOS_BKP_BOARD_RESERVED_1 10
#define PIOS_BKP_BOARD_RESERVED_2 11
#define PIOS_BKP_BOARD_RESERVED_3 12
// registers reserved for APP usage
#define PIOS_BKP_APP_RESERVED_1 13
#define PIOS_BKP_APP_RESERVED_2 14
#define PIOS_BKP_APP_RESERVED_3 15
#define PIOS_BKP_APP_RESERVED_4 16
/****************************************************************************************
* Public Functions
****************************************************************************************/
/** @defgroup PIOS_BKP_Public_Functions
* @{
*/
/**
* @brief Initialize the Backup Register hardware
* @param None
* @retval None
*/
void PIOS_BKP_Init(void);
/**
* @brief Reads data from the specified Backup Register.
* @param regnumber: specifies the Backup Register.
* @retval The content of the specified Data Backup Register
*/
uint16_t PIOS_BKP_ReadRegister(uint32_t regnumber);
/**
* @brief Writes user data to the specified Backup Register.
* @param regnumber: specifies the Data Backup Register.
* @param data: data to write
* @retval None
*/
void PIOS_BKP_WriteRegister(uint32_t regnumber,uint16_t data);
/**
* @brief Enable Backup registers write access
* @param None
* @retval None
*/
void PIOS_BKP_EnableWrite(void);
/**
* @brief Disable Backup registers write access
* @param None
* @retval None
*/
void PIOS_BKP_DisableWrite(void);
/**
* @}
*/
/****************************************************************************************
* Public Data
****************************************************************************************/
#endif /* PIOS_BKP_H_ */

View File

@ -1,31 +1,59 @@
/*!
* @File iap.h
* @Brief Header file for the In-Application-Programming Module
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_IAP In-Application-Programming Module
* @brief In-Application-Programming Module
* @{
*
* Created on: Sep 6, 2010
* Author: joe
* @file pios_iap.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief IAP functions
* @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
*/
/* Project Includes */
#ifndef PIOS_IAP_H
#define PIOS_IAP_H
/****************************************************************************************
* Header files
****************************************************************************************/
#include <pios_bkp.h>
/*****************************************************************************************
* Public Definitions/Macros
****************************************************************************************/
#if defined(STM32F4XX)
#define MAGIC_REG_1 RTC_BKP_DR1
#define MAGIC_REG_2 RTC_BKP_DR2
#define IAP_BOOTCOUNT RTC_BKP_DR3
#else
#define MAGIC_REG_1 BKP_DR1
#define MAGIC_REG_2 BKP_DR2
#define IAP_BOOTCOUNT BKP_DR3
#endif
#define MAGIC_REG_1 PIOS_BKP_RESERVED_1
#define MAGIC_REG_2 PIOS_BKP_RESERVED_2
#define IAP_BOOTCOUNT PIOS_BKP_RESERVED_3
#define IAP_CMD1 PIOS_BKP_RESERVED_5
#define IAP_CMD2 PIOS_BKP_RESERVED_6
#define IAP_CMD3 PIOS_BKP_RESERVED_7
#define PIOS_IAP_CLEAR_FLASH_CMD_0 0xFA5F
#define PIOS_IAP_CLEAR_FLASH_CMD_1 0x0001
#define PIOS_IAP_CLEAR_FLASH_CMD_2 0x0000
#define PIOS_IAP_CMD_COUNT 3
/****************************************************************************************
* Public Functions
@ -38,6 +66,19 @@ void PIOS_IAP_ClearRequest(void);
uint16_t PIOS_IAP_ReadBootCount(void);
void PIOS_IAP_WriteBootCount(uint16_t);
/**
* @brief Return one of the IAP command values passed from bootloader.
* @param number: the index of the command value (0..2).
* @retval the selected command value.
*/
uint32_t PIOS_IAP_ReadBootCmd(uint8_t number);
/**
* @brief Write one of the IAP command values to be passed to firmware from bootloader.
* @param number: the index of the command value (0..2).
* @param value: value to be written.
*/
void PIOS_IAP_WriteBootCmd(uint8_t number, uint32_t value);
/****************************************************************************************
* Public Data
****************************************************************************************/

View File

@ -113,7 +113,6 @@ int main()
///
/// Bootloader programing
for (uint32_t offset = 0; offset < embedded_image_size / sizeof(uint32_t); ++offset) {
bool result = false;
@ -156,12 +155,6 @@ void error(int led, int code)
PIOS_LED_Off(led);
PIOS_DELAY_WaitmS(1000);
}
PIOS_DELAY_WaitmS(1000);
for (int x = 0; x < 10; x++) {
PIOS_LED_On(led);
PIOS_DELAY_WaitmS(200);
PIOS_LED_Off(led);
PIOS_DELAY_WaitmS(200);
}
PIOS_DELAY_WaitmS(3000);
}
}

View File

@ -1,60 +0,0 @@
/**
******************************************************************************
*
* @file op_dfu.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @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
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __OP_DFU_H
#define __OP_DFU_H
#include "common.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct {
uint8_t programmingType;
uint8_t readWriteFlags;
uint32_t startOfUserCode;
uint32_t sizeOfCode;
uint8_t sizeOfDescription;
uint8_t BL_Version;
uint16_t devID;
DeviceType devType;
uint32_t FW_Crc;
} Device;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define COMMAND 0
#define COUNT 1
#define DATA 5
/* Exported functions ------------------------------------------------------- */
void processComand(uint8_t *Receive_Buffer);
uint32_t baseOfAdressType(uint8_t type);
uint8_t isBiggerThanAvailable(uint8_t type, uint32_t size);
void OPDfuIni(uint8_t discover);
void DataDownload(DownloadAction);
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type);
#endif /* __OP_DFU_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@ -1,467 +0,0 @@
/**
******************************************************************************
* @addtogroup CopterControlBL CopterControl BootLoader
* @brief These files contain the code to the CopterControl Bootloader.
*
* @{
* @file op_dfu.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief This file contains the DFU commands handling code
* @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 "pios.h"
#include "op_dfu.h"
#include "pios_bl_helper.h"
#include "pios_com_msg.h"
#include <pios_board_info.h>
//programmable devices
Device devicesTable[10];
uint8_t numberOfDevices = 0;
DFUProgType currentProgrammingDestination; //flash, flash_trough spi
uint8_t currentDeviceCanRead;
uint8_t currentDeviceCanWrite;
Device currentDevice;
uint8_t Buffer[64];
uint8_t echoBuffer[64];
uint8_t SendBuffer[64];
uint8_t Command = 0;
uint8_t EchoReqFlag = 0;
uint8_t EchoAnsFlag = 0;
uint8_t StartFlag = 0;
uint32_t Aditionals = 0;
uint32_t SizeOfTransfer = 0;
uint32_t Expected_CRC = 0;
uint8_t SizeOfLastPacket = 0;
uint32_t Next_Packet = 0;
uint8_t TransferType;
uint32_t Count = 0;
uint32_t Data;
uint8_t Data0;
uint8_t Data1;
uint8_t Data2;
uint8_t Data3;
uint8_t offset = 0;
uint32_t aux;
//Download vars
uint32_t downSizeOfLastPacket = 0;
uint32_t downPacketTotal = 0;
uint32_t downPacketCurrent = 0;
DFUTransfer downType = 0;
/* Extern variables ----------------------------------------------------------*/
extern DFUStates DeviceState;
extern uint8_t JumpToApp;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void sendData(uint8_t * buf, uint16_t size);
uint32_t CalcFirmCRC(void);
void DataDownload(DownloadAction action) {
if ((DeviceState == downloading)) {
uint8_t packetSize;
uint32_t offset;
uint32_t partoffset;
SendBuffer[0] = 0x01;
SendBuffer[1] = Download;
SendBuffer[2] = downPacketCurrent >> 24;
SendBuffer[3] = downPacketCurrent >> 16;
SendBuffer[4] = downPacketCurrent >> 8;
SendBuffer[5] = downPacketCurrent;
if (downPacketCurrent == downPacketTotal - 1) {
packetSize = downSizeOfLastPacket;
} else {
packetSize = 14;
}
for (uint8_t x = 0; x < packetSize; ++x) {
partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
offset = baseOfAdressType(downType) + partoffset;
if (!flash_read(SendBuffer + (6 + x * 4), offset,
currentProgrammingDestination)) {
DeviceState = Last_operation_failed;
}
}
downPacketCurrent = downPacketCurrent + 1;
if (downPacketCurrent > downPacketTotal - 1) {
DeviceState = Last_operation_Success;
Aditionals = (uint32_t) Download;
}
sendData(SendBuffer + 1, 63);
}
}
void processComand(uint8_t *xReceive_Buffer) {
Command = xReceive_Buffer[COMMAND];
#ifdef DEBUG_SSP
char str[63]= {0};
sprintf(str,"Received COMMAND:%d|",Command);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
EchoReqFlag = (Command >> 7);
EchoAnsFlag = (Command >> 6) & 0x01;
StartFlag = (Command >> 5) & 0x01;
Count = xReceive_Buffer[COUNT] << 24;
Count += xReceive_Buffer[COUNT + 1] << 16;
Count += xReceive_Buffer[COUNT + 2] << 8;
Count += xReceive_Buffer[COUNT + 3];
Data = xReceive_Buffer[DATA] << 24;
Data += xReceive_Buffer[DATA + 1] << 16;
Data += xReceive_Buffer[DATA + 2] << 8;
Data += xReceive_Buffer[DATA + 3];
Data0 = xReceive_Buffer[DATA];
Data1 = xReceive_Buffer[DATA + 1];
Data2 = xReceive_Buffer[DATA + 2];
Data3 = xReceive_Buffer[DATA + 3];
Command = Command & 0b00011111;
if (EchoReqFlag == 1) {
memcpy(echoBuffer, Buffer, 64);
}
switch (Command) {
case EnterDFU:
if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
|| (DeviceState == DFUidle)) {
if (Data0 > 0)
OPDfuIni(TRUE);
DeviceState = DFUidle;
currentProgrammingDestination = devicesTable[Data0].programmingType;
currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
& 0x01;
currentDevice = devicesTable[Data0];
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Ini();
break;
case Remote_flash_via_spi:
result = TRUE;
break;
default:
DeviceState = Last_operation_failed;
Aditionals = (uint16_t) Command;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Upload:
if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
if ((StartFlag == 1) && (Next_Packet == 0)) {
TransferType = Data0;
SizeOfTransfer = Count;
Next_Packet = 1;
Expected_CRC = Data2 << 24;
Expected_CRC += Data3 << 16;
Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
Expected_CRC += xReceive_Buffer[DATA + 5];
SizeOfLastPacket = Data1;
if (isBiggerThanAvailable(TransferType, (SizeOfTransfer - 1)
* 14 * 4 + SizeOfLastPacket * 4) == TRUE) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
uint8_t result = 1;
if (TransferType == FW) {
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Start();
break;
case Remote_flash_via_spi:
result = FALSE;
break;
default:
break;
}
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
} else {
DeviceState = uploading;
}
}
} else if ((StartFlag != 1) && (Next_Packet != 0)) {
if (Count > SizeOfTransfer) {
DeviceState = too_many_packets;
Aditionals = Count;
} else if (Count == Next_Packet - 1) {
uint8_t numberOfWords = 14;
if (Count == SizeOfTransfer - 1)//is this the last packet?
{
numberOfWords = SizeOfLastPacket;
}
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
for (uint8_t x = 0; x < numberOfWords; ++x) {
offset = 4 * x;
Data = xReceive_Buffer[DATA + offset] << 24;
Data += xReceive_Buffer[DATA + 1 + offset] << 16;
Data += xReceive_Buffer[DATA + 2 + offset] << 8;
Data += xReceive_Buffer[DATA + 3 + offset];
aux = baseOfAdressType(TransferType) + (uint32_t)(
Count * 14 * 4 + x * 4);
result = 0;
for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
if (result == 0) {
result = (FLASH_ProgramWord(aux, Data)
== FLASH_COMPLETE) ? 1 : 0;
}
}
}
break;
case Remote_flash_via_spi:
result = FALSE; // No support for this for the PipX
break;
default:
result = 0;
break;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
++Next_Packet;
} else {
DeviceState = wrong_packet_received;
Aditionals = Count;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Req_Capabilities:
OPDfuIni(TRUE);
Buffer[0] = 0x01;
Buffer[1] = Rep_Capabilities;
if (Data0 == 0) {
Buffer[2] = 0;
Buffer[3] = 0;
Buffer[4] = 0;
Buffer[5] = 0;
Buffer[6] = 0;
Buffer[7] = numberOfDevices;
uint16_t WRFlags = 0;
for (int x = 0; x < numberOfDevices; ++x) {
WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
| WRFlags);
}
Buffer[8] = WRFlags >> 8;
Buffer[9] = WRFlags;
} else {
Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
Buffer[6] = Data0;
Buffer[7] = devicesTable[Data0 - 1].BL_Version;
Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
Buffer[9] = devicesTable[Data0 - 1].devID;
Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
Buffer[15] = devicesTable[Data0 - 1].devID;
}
sendData(Buffer + 1, 63);
break;
case JumpFW:
if (Data == 0x5AFE) {
/* Force board into safe mode */
PIOS_IAP_WriteBootCount(0xFFFF);
}
FLASH_Lock();
JumpToApp = 1;
break;
case Reset:
PIOS_SYS_Reset();
break;
case Abort_Operation:
Next_Packet = 0;
DeviceState = DFUidle;
break;
case Op_END:
if (DeviceState == uploading) {
if (Next_Packet - 1 == SizeOfTransfer) {
Next_Packet = 0;
if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
DeviceState = Last_operation_Success;
} else {
DeviceState = CRC_Fail;
}
}
if (Next_Packet - 1 < SizeOfTransfer) {
Next_Packet = 0;
DeviceState = too_few_packets;
}
}
break;
case Download_Req:
#ifdef DEBUG_SSP
sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
if (DeviceState == DFUidle) {
#ifdef DEBUG_SSP
PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
#endif
downType = Data0;
downPacketTotal = Count;
downSizeOfLastPacket = Data1;
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14
+ downSizeOfLastPacket) == 1) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
downPacketCurrent = 0;
DeviceState = downloading;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
break;
case Status_Request:
Buffer[0] = 0x01;
Buffer[1] = Status_Rep;
if (DeviceState == wrong_packet_received) {
Buffer[2] = Aditionals >> 24;
Buffer[3] = Aditionals >> 16;
Buffer[4] = Aditionals >> 8;
Buffer[5] = Aditionals;
} else {
Buffer[2] = 0;
Buffer[3] = ((uint16_t) Aditionals) >> 8;
Buffer[4] = ((uint16_t) Aditionals);
Buffer[5] = 0;
}
Buffer[6] = DeviceState;
Buffer[7] = 0;
Buffer[8] = 0;
Buffer[9] = 0;
sendData(Buffer + 1, 63);
if (DeviceState == Last_operation_Success) {
DeviceState = DFUidle;
}
break;
case Status_Rep:
break;
}
if (EchoReqFlag == 1) {
echoBuffer[1] = echoBuffer[1] | EchoAnsFlag;
sendData(echoBuffer + 1, 63);
}
return;
}
void OPDfuIni(uint8_t discover) {
const struct pios_board_info * bdinfo = &pios_board_info_blob;
Device dev;
dev.programmingType = Self_flash;
dev.readWriteFlags = (BOARD_READABLE | (BOARD_WRITABLE << 1));
dev.startOfUserCode = bdinfo->fw_base;
dev.sizeOfCode = bdinfo->fw_size;
dev.sizeOfDescription = bdinfo->desc_size;
dev.BL_Version = bdinfo->bl_rev;
dev.FW_Crc = CalcFirmCRC();
dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
dev.devType = bdinfo->hw_type;
numberOfDevices = 1;
devicesTable[0] = dev;
if (discover) {
//TODO check other devices trough spi or whatever
}
}
uint32_t baseOfAdressType(DFUTransfer type) {
switch (type) {
case FW:
return currentDevice.startOfUserCode;
break;
case Descript:
return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
break;
default:
return 0;
}
}
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
switch (type) {
case FW:
return (size > currentDevice.sizeOfCode) ? 1 : 0;
break;
case Descript:
return (size > currentDevice.sizeOfDescription) ? 1 : 0;
break;
default:
return TRUE;
}
}
uint32_t CalcFirmCRC() {
switch (currentProgrammingDestination) {
case Self_flash:
return PIOS_BL_HELPER_CRC_Memory_Calc();
break;
case Remote_flash_via_spi:
return 0;
break;
default:
return 0;
break;
}
}
void sendData(uint8_t * buf, uint16_t size) {
PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, buf, size);
}
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type) {
switch (type) {
case Remote_flash_via_spi:
return FALSE; // We should not get this for the PipX
break;
case Self_flash:
for (uint8_t x = 0; x < 4; ++x) {
buffer[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x);
}
return TRUE;
break;
default:
return FALSE;
}
}

View File

@ -1,60 +0,0 @@
/**
******************************************************************************
*
* @file op_dfu.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @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
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __OP_DFU_H
#define __OP_DFU_H
#include "common.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct {
uint8_t programmingType;
uint8_t readWriteFlags;
uint32_t startOfUserCode;
uint32_t sizeOfCode;
uint8_t sizeOfDescription;
uint8_t BL_Version;
uint16_t devID;
DeviceType devType;
uint32_t FW_Crc;
} Device;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define COMMAND 0
#define COUNT 1
#define DATA 5
/* Exported functions ------------------------------------------------------- */
void processComand(uint8_t *Receive_Buffer);
uint32_t baseOfAdressType(uint8_t type);
uint8_t isBiggerThanAvailable(uint8_t type, uint32_t size);
void OPDfuIni(uint8_t discover);
void DataDownload(DownloadAction);
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type);
#endif /* __OP_DFU_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@ -1,467 +0,0 @@
/**
******************************************************************************
* @addtogroup OpenPilotBL OpenPilot BootLoader
* @brief These files contain the code to the OpenPilot MB Bootloader.
*
* @{
* @file op_dfu.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief This file contains the DFU commands handling code
* @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 "pios.h"
#include "op_dfu.h"
#include "pios_bl_helper.h"
#include "pios_com_msg.h"
#include <pios_board_info.h>
//programmable devices
Device devicesTable[10];
uint8_t numberOfDevices = 0;
DFUProgType currentProgrammingDestination; //flash, flash_trough spi
uint8_t currentDeviceCanRead;
uint8_t currentDeviceCanWrite;
Device currentDevice;
uint8_t Buffer[64];
uint8_t echoBuffer[64];
uint8_t SendBuffer[64];
uint8_t Command = 0;
uint8_t EchoReqFlag = 0;
uint8_t EchoAnsFlag = 0;
uint8_t StartFlag = 0;
uint32_t Aditionals = 0;
uint32_t SizeOfTransfer = 0;
uint32_t Expected_CRC = 0;
uint8_t SizeOfLastPacket = 0;
uint32_t Next_Packet = 0;
uint8_t TransferType;
uint32_t Count = 0;
uint32_t Data;
uint8_t Data0;
uint8_t Data1;
uint8_t Data2;
uint8_t Data3;
uint8_t offset = 0;
uint32_t aux;
//Download vars
uint32_t downSizeOfLastPacket = 0;
uint32_t downPacketTotal = 0;
uint32_t downPacketCurrent = 0;
DFUTransfer downType = 0;
/* Extern variables ----------------------------------------------------------*/
extern DFUStates DeviceState;
extern uint8_t JumpToApp;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void sendData(uint8_t * buf, uint16_t size);
uint32_t CalcFirmCRC(void);
void DataDownload(DownloadAction action) {
if ((DeviceState == downloading)) {
uint8_t packetSize;
uint32_t offset;
uint32_t partoffset;
SendBuffer[0] = 0x01;
SendBuffer[1] = Download;
SendBuffer[2] = downPacketCurrent >> 24;
SendBuffer[3] = downPacketCurrent >> 16;
SendBuffer[4] = downPacketCurrent >> 8;
SendBuffer[5] = downPacketCurrent;
if (downPacketCurrent == downPacketTotal - 1) {
packetSize = downSizeOfLastPacket;
} else {
packetSize = 14;
}
for (uint8_t x = 0; x < packetSize; ++x) {
partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
offset = baseOfAdressType(downType) + partoffset;
if (!flash_read(SendBuffer + (6 + x * 4), offset,
currentProgrammingDestination)) {
DeviceState = Last_operation_failed;
}
}
downPacketCurrent = downPacketCurrent + 1;
if (downPacketCurrent > downPacketTotal - 1) {
DeviceState = Last_operation_Success;
Aditionals = (uint32_t) Download;
}
sendData(SendBuffer + 1, 63);
}
}
void processComand(uint8_t *xReceive_Buffer) {
Command = xReceive_Buffer[COMMAND];
#ifdef DEBUG_SSP
char str[63]= {0};
sprintf(str,"Received COMMAND:%d|",Command);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
EchoReqFlag = (Command >> 7);
EchoAnsFlag = (Command >> 6) & 0x01;
StartFlag = (Command >> 5) & 0x01;
Count = xReceive_Buffer[COUNT] << 24;
Count += xReceive_Buffer[COUNT + 1] << 16;
Count += xReceive_Buffer[COUNT + 2] << 8;
Count += xReceive_Buffer[COUNT + 3];
Data = xReceive_Buffer[DATA] << 24;
Data += xReceive_Buffer[DATA + 1] << 16;
Data += xReceive_Buffer[DATA + 2] << 8;
Data += xReceive_Buffer[DATA + 3];
Data0 = xReceive_Buffer[DATA];
Data1 = xReceive_Buffer[DATA + 1];
Data2 = xReceive_Buffer[DATA + 2];
Data3 = xReceive_Buffer[DATA + 3];
Command = Command & 0b00011111;
if (EchoReqFlag == 1) {
memcpy(echoBuffer, Buffer, 64);
}
switch (Command) {
case EnterDFU:
if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
|| (DeviceState == DFUidle)) {
if (Data0 > 0)
OPDfuIni(TRUE);
DeviceState = DFUidle;
currentProgrammingDestination = devicesTable[Data0].programmingType;
currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
& 0x01;
currentDevice = devicesTable[Data0];
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Ini();
break;
case Remote_flash_via_spi:
result = TRUE;
break;
default:
DeviceState = Last_operation_failed;
Aditionals = (uint16_t) Command;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Upload:
if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
if ((StartFlag == 1) && (Next_Packet == 0)) {
TransferType = Data0;
SizeOfTransfer = Count;
Next_Packet = 1;
Expected_CRC = Data2 << 24;
Expected_CRC += Data3 << 16;
Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
Expected_CRC += xReceive_Buffer[DATA + 5];
SizeOfLastPacket = Data1;
if (isBiggerThanAvailable(TransferType, (SizeOfTransfer - 1)
* 14 * 4 + SizeOfLastPacket * 4) == TRUE) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
uint8_t result = 1;
if (TransferType == FW) {
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Start();
break;
case Remote_flash_via_spi:
result = FALSE;
break;
default:
break;
}
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
} else {
DeviceState = uploading;
}
}
} else if ((StartFlag != 1) && (Next_Packet != 0)) {
if (Count > SizeOfTransfer) {
DeviceState = too_many_packets;
Aditionals = Count;
} else if (Count == Next_Packet - 1) {
uint8_t numberOfWords = 14;
if (Count == SizeOfTransfer - 1)//is this the last packet?
{
numberOfWords = SizeOfLastPacket;
}
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
for (uint8_t x = 0; x < numberOfWords; ++x) {
offset = 4 * x;
Data = xReceive_Buffer[DATA + offset] << 24;
Data += xReceive_Buffer[DATA + 1 + offset] << 16;
Data += xReceive_Buffer[DATA + 2 + offset] << 8;
Data += xReceive_Buffer[DATA + 3 + offset];
aux = baseOfAdressType(TransferType) + (uint32_t)(
Count * 14 * 4 + x * 4);
result = 0;
for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
if (result == 0) {
result = (FLASH_ProgramWord(aux, Data)
== FLASH_COMPLETE) ? 1 : 0;
}
}
}
break;
case Remote_flash_via_spi:
result = FALSE; // No support for this for the PipX
break;
default:
result = 0;
break;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
++Next_Packet;
} else {
DeviceState = wrong_packet_received;
Aditionals = Count;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Req_Capabilities:
OPDfuIni(TRUE);
Buffer[0] = 0x01;
Buffer[1] = Rep_Capabilities;
if (Data0 == 0) {
Buffer[2] = 0;
Buffer[3] = 0;
Buffer[4] = 0;
Buffer[5] = 0;
Buffer[6] = 0;
Buffer[7] = numberOfDevices;
uint16_t WRFlags = 0;
for (int x = 0; x < numberOfDevices; ++x) {
WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
| WRFlags);
}
Buffer[8] = WRFlags >> 8;
Buffer[9] = WRFlags;
} else {
Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
Buffer[6] = Data0;
Buffer[7] = devicesTable[Data0 - 1].BL_Version;
Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
Buffer[9] = devicesTable[Data0 - 1].devID;
Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
Buffer[15] = devicesTable[Data0 - 1].devID;
}
sendData(Buffer + 1, 63);
break;
case JumpFW:
if (Data == 0x5AFE) {
/* Force board into safe mode */
PIOS_IAP_WriteBootCount(0xFFFF);
}
FLASH_Lock();
JumpToApp = 1;
break;
case Reset:
PIOS_SYS_Reset();
break;
case Abort_Operation:
Next_Packet = 0;
DeviceState = DFUidle;
break;
case Op_END:
if (DeviceState == uploading) {
if (Next_Packet - 1 == SizeOfTransfer) {
Next_Packet = 0;
if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
DeviceState = Last_operation_Success;
} else {
DeviceState = CRC_Fail;
}
}
if (Next_Packet - 1 < SizeOfTransfer) {
Next_Packet = 0;
DeviceState = too_few_packets;
}
}
break;
case Download_Req:
#ifdef DEBUG_SSP
sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
if (DeviceState == DFUidle) {
#ifdef DEBUG_SSP
PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
#endif
downType = Data0;
downPacketTotal = Count;
downSizeOfLastPacket = Data1;
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14
+ downSizeOfLastPacket) == 1) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
downPacketCurrent = 0;
DeviceState = downloading;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
break;
case Status_Request:
Buffer[0] = 0x01;
Buffer[1] = Status_Rep;
if (DeviceState == wrong_packet_received) {
Buffer[2] = Aditionals >> 24;
Buffer[3] = Aditionals >> 16;
Buffer[4] = Aditionals >> 8;
Buffer[5] = Aditionals;
} else {
Buffer[2] = 0;
Buffer[3] = ((uint16_t) Aditionals) >> 8;
Buffer[4] = ((uint16_t) Aditionals);
Buffer[5] = 0;
}
Buffer[6] = DeviceState;
Buffer[7] = 0;
Buffer[8] = 0;
Buffer[9] = 0;
sendData(Buffer + 1, 63);
if (DeviceState == Last_operation_Success) {
DeviceState = DFUidle;
}
break;
case Status_Rep:
break;
}
if (EchoReqFlag == 1) {
echoBuffer[1] = echoBuffer[1] | EchoAnsFlag;
sendData(echoBuffer + 1, 63);
}
return;
}
void OPDfuIni(uint8_t discover) {
const struct pios_board_info * bdinfo = &pios_board_info_blob;
Device dev;
dev.programmingType = Self_flash;
dev.readWriteFlags = (BOARD_READABLE | (BOARD_WRITABLE << 1));
dev.startOfUserCode = bdinfo->fw_base;
dev.sizeOfCode = bdinfo->fw_size;
dev.sizeOfDescription = bdinfo->desc_size;
dev.BL_Version = bdinfo->bl_rev;
dev.FW_Crc = CalcFirmCRC();
dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
dev.devType = bdinfo->hw_type;
numberOfDevices = 1;
devicesTable[0] = dev;
if (discover) {
//TODO check other devices trough spi or whatever
}
}
uint32_t baseOfAdressType(DFUTransfer type) {
switch (type) {
case FW:
return currentDevice.startOfUserCode;
break;
case Descript:
return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
break;
default:
return 0;
}
}
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
switch (type) {
case FW:
return (size > currentDevice.sizeOfCode) ? 1 : 0;
break;
case Descript:
return (size > currentDevice.sizeOfDescription) ? 1 : 0;
break;
default:
return TRUE;
}
}
uint32_t CalcFirmCRC() {
switch (currentProgrammingDestination) {
case Self_flash:
return PIOS_BL_HELPER_CRC_Memory_Calc();
break;
case Remote_flash_via_spi:
return 0;
break;
default:
return 0;
break;
}
}
void sendData(uint8_t * buf, uint16_t size) {
PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, buf, size);
}
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type) {
switch (type) {
case Remote_flash_via_spi:
return FALSE; // We should not get this for the PipX
break;
case Self_flash:
for (uint8_t x = 0; x < 4; ++x) {
buffer[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x);
}
return TRUE;
break;
default:
return FALSE;
}
}

View File

@ -1,60 +0,0 @@
/**
******************************************************************************
*
* @file op_dfu.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @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
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __OP_DFU_H
#define __OP_DFU_H
#include "common.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct {
uint8_t programmingType;
uint8_t readWriteFlags;
uint32_t startOfUserCode;
uint32_t sizeOfCode;
uint8_t sizeOfDescription;
uint8_t BL_Version;
uint16_t devID;
DeviceType devType;
uint32_t FW_Crc;
} Device;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define COMMAND 0
#define COUNT 1
#define DATA 5
/* Exported functions ------------------------------------------------------- */
void processComand(uint8_t *Receive_Buffer);
uint32_t baseOfAdressType(uint8_t type);
uint8_t isBiggerThanAvailable(uint8_t type, uint32_t size);
void OPDfuIni(uint8_t discover);
void DataDownload(DownloadAction);
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type);
#endif /* __OP_DFU_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@ -1,468 +0,0 @@
/**
******************************************************************************
* @addtogroup CopterControlBL CopterControl BootLoader
* @brief These files contain the code to the CopterControl Bootloader.
*
* @{
* @file op_dfu.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief This file contains the DFU commands handling code
* @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 "pios.h"
#include <stdbool.h>
#include "op_dfu.h"
#include "pios_bl_helper.h"
#include "pios_com_msg.h"
#include <pios_board_info.h>
//programmable devices
Device devicesTable[10];
uint8_t numberOfDevices = 0;
DFUProgType currentProgrammingDestination; //flash, flash_trough spi
uint8_t currentDeviceCanRead;
uint8_t currentDeviceCanWrite;
Device currentDevice;
uint8_t Buffer[64];
uint8_t echoBuffer[64];
uint8_t SendBuffer[64];
uint8_t Command = 0;
uint8_t EchoReqFlag = 0;
uint8_t EchoAnsFlag = 0;
uint8_t StartFlag = 0;
uint32_t Aditionals = 0;
uint32_t SizeOfTransfer = 0;
uint32_t Expected_CRC = 0;
uint8_t SizeOfLastPacket = 0;
uint32_t Next_Packet = 0;
uint8_t TransferType;
uint32_t Count = 0;
uint32_t Data;
uint8_t Data0;
uint8_t Data1;
uint8_t Data2;
uint8_t Data3;
uint8_t offset = 0;
uint32_t aux;
//Download vars
uint32_t downSizeOfLastPacket = 0;
uint32_t downPacketTotal = 0;
uint32_t downPacketCurrent = 0;
DFUTransfer downType = 0;
/* Extern variables ----------------------------------------------------------*/
extern DFUStates DeviceState;
extern uint8_t JumpToApp;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void sendData(uint8_t * buf, uint16_t size);
uint32_t CalcFirmCRC(void);
void DataDownload(DownloadAction action) {
if ((DeviceState == downloading)) {
uint8_t packetSize;
uint32_t offset;
uint32_t partoffset;
SendBuffer[0] = 0x01;
SendBuffer[1] = Download;
SendBuffer[2] = downPacketCurrent >> 24;
SendBuffer[3] = downPacketCurrent >> 16;
SendBuffer[4] = downPacketCurrent >> 8;
SendBuffer[5] = downPacketCurrent;
if (downPacketCurrent == downPacketTotal - 1) {
packetSize = downSizeOfLastPacket;
} else {
packetSize = 14;
}
for (uint8_t x = 0; x < packetSize; ++x) {
partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
offset = baseOfAdressType(downType) + partoffset;
if (!flash_read(SendBuffer + (6 + x * 4), offset,
currentProgrammingDestination)) {
DeviceState = Last_operation_failed;
}
}
downPacketCurrent = downPacketCurrent + 1;
if (downPacketCurrent > downPacketTotal - 1) {
DeviceState = Last_operation_Success;
Aditionals = (uint32_t) Download;
}
sendData(SendBuffer + 1, 63);
}
}
void processComand(uint8_t *xReceive_Buffer) {
Command = xReceive_Buffer[COMMAND];
#ifdef DEBUG_SSP
char str[63]= {0};
sprintf(str,"Received COMMAND:%d|",Command);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
EchoReqFlag = (Command >> 7);
EchoAnsFlag = (Command >> 6) & 0x01;
StartFlag = (Command >> 5) & 0x01;
Count = xReceive_Buffer[COUNT] << 24;
Count += xReceive_Buffer[COUNT + 1] << 16;
Count += xReceive_Buffer[COUNT + 2] << 8;
Count += xReceive_Buffer[COUNT + 3];
Data = xReceive_Buffer[DATA] << 24;
Data += xReceive_Buffer[DATA + 1] << 16;
Data += xReceive_Buffer[DATA + 2] << 8;
Data += xReceive_Buffer[DATA + 3];
Data0 = xReceive_Buffer[DATA];
Data1 = xReceive_Buffer[DATA + 1];
Data2 = xReceive_Buffer[DATA + 2];
Data3 = xReceive_Buffer[DATA + 3];
Command = Command & 0b00011111;
if (EchoReqFlag == 1) {
memcpy(echoBuffer, xReceive_Buffer, 64);
}
switch (Command) {
case EnterDFU:
if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
|| (DeviceState == DFUidle)) {
if (Data0 > 0)
OPDfuIni(true);
DeviceState = DFUidle;
currentProgrammingDestination = devicesTable[Data0].programmingType;
currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
& 0x01;
currentDevice = devicesTable[Data0];
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Ini();
break;
case Remote_flash_via_spi:
result = true;
break;
default:
DeviceState = Last_operation_failed;
Aditionals = (uint16_t) Command;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Upload:
if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
if ((StartFlag == 1) && (Next_Packet == 0)) {
TransferType = Data0;
SizeOfTransfer = Count;
Next_Packet = 1;
Expected_CRC = Data2 << 24;
Expected_CRC += Data3 << 16;
Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
Expected_CRC += xReceive_Buffer[DATA + 5];
SizeOfLastPacket = Data1;
if (isBiggerThanAvailable(TransferType, (SizeOfTransfer - 1)
* 14 * 4 + SizeOfLastPacket * 4) == true) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
uint8_t result = 1;
if (TransferType == FW) {
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Start();
break;
case Remote_flash_via_spi:
result = false;
break;
default:
break;
}
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
} else {
DeviceState = uploading;
}
}
} else if ((StartFlag != 1) && (Next_Packet != 0)) {
if (Count > SizeOfTransfer) {
DeviceState = too_many_packets;
Aditionals = Count;
} else if (Count == Next_Packet - 1) {
uint8_t numberOfWords = 14;
if (Count == SizeOfTransfer - 1)//is this the last packet?
{
numberOfWords = SizeOfLastPacket;
}
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
for (uint8_t x = 0; x < numberOfWords; ++x) {
offset = 4 * x;
Data = xReceive_Buffer[DATA + offset] << 24;
Data += xReceive_Buffer[DATA + 1 + offset] << 16;
Data += xReceive_Buffer[DATA + 2 + offset] << 8;
Data += xReceive_Buffer[DATA + 3 + offset];
aux = baseOfAdressType(TransferType) + (uint32_t)(
Count * 14 * 4 + x * 4);
result = 0;
for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
if (result == 0) {
result = (FLASH_ProgramWord(aux, Data)
== FLASH_COMPLETE) ? 1 : 0;
}
}
}
break;
case Remote_flash_via_spi:
result = false; // No support for this for the PipX
break;
default:
result = 0;
break;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
++Next_Packet;
} else {
DeviceState = wrong_packet_received;
Aditionals = Count;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Req_Capabilities:
OPDfuIni(true);
Buffer[0] = 0x01;
Buffer[1] = Rep_Capabilities;
if (Data0 == 0) {
Buffer[2] = 0;
Buffer[3] = 0;
Buffer[4] = 0;
Buffer[5] = 0;
Buffer[6] = 0;
Buffer[7] = numberOfDevices;
uint16_t WRFlags = 0;
for (int x = 0; x < numberOfDevices; ++x) {
WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
| WRFlags);
}
Buffer[8] = WRFlags >> 8;
Buffer[9] = WRFlags;
} else {
Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
Buffer[6] = Data0;
Buffer[7] = devicesTable[Data0 - 1].BL_Version;
Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
Buffer[9] = devicesTable[Data0 - 1].devID;
Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
Buffer[15] = devicesTable[Data0 - 1].devID;
}
sendData(Buffer + 1, 63);
break;
case JumpFW:
if (Data == 0x5AFE) {
/* Force board into safe mode */
PIOS_IAP_WriteBootCount(0xFFFF);
}
FLASH_Lock();
JumpToApp = 1;
break;
case Reset:
PIOS_SYS_Reset();
break;
case Abort_Operation:
Next_Packet = 0;
DeviceState = DFUidle;
break;
case Op_END:
if (DeviceState == uploading) {
if (Next_Packet - 1 == SizeOfTransfer) {
Next_Packet = 0;
if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
DeviceState = Last_operation_Success;
} else {
DeviceState = CRC_Fail;
}
}
if (Next_Packet - 1 < SizeOfTransfer) {
Next_Packet = 0;
DeviceState = too_few_packets;
}
}
break;
case Download_Req:
#ifdef DEBUG_SSP
sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
if (DeviceState == DFUidle) {
#ifdef DEBUG_SSP
PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
#endif
downType = Data0;
downPacketTotal = Count;
downSizeOfLastPacket = Data1;
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14 * 4
+ downSizeOfLastPacket * 4) == 1) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
downPacketCurrent = 0;
DeviceState = downloading;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
break;
case Status_Request:
Buffer[0] = 0x01;
Buffer[1] = Status_Rep;
if (DeviceState == wrong_packet_received) {
Buffer[2] = Aditionals >> 24;
Buffer[3] = Aditionals >> 16;
Buffer[4] = Aditionals >> 8;
Buffer[5] = Aditionals;
} else {
Buffer[2] = 0;
Buffer[3] = ((uint16_t) Aditionals) >> 8;
Buffer[4] = ((uint16_t) Aditionals);
Buffer[5] = 0;
}
Buffer[6] = DeviceState;
Buffer[7] = 0;
Buffer[8] = 0;
Buffer[9] = 0;
sendData(Buffer + 1, 63);
if (DeviceState == Last_operation_Success) {
DeviceState = DFUidle;
}
break;
case Status_Rep:
break;
}
if (EchoReqFlag == 1) {
echoBuffer[0] = echoBuffer[0] | (1 << 6);
sendData(echoBuffer, 63);
}
return;
}
void OPDfuIni(uint8_t discover) {
const struct pios_board_info * bdinfo = &pios_board_info_blob;
Device dev;
dev.programmingType = Self_flash;
dev.readWriteFlags = (BOARD_READABLE | (BOARD_WRITABLE << 1));
dev.startOfUserCode = bdinfo->fw_base;
dev.sizeOfCode = bdinfo->fw_size;
dev.sizeOfDescription = bdinfo->desc_size;
dev.BL_Version = bdinfo->bl_rev;
dev.FW_Crc = CalcFirmCRC();
dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
dev.devType = bdinfo->hw_type;
numberOfDevices = 1;
devicesTable[0] = dev;
if (discover) {
//TODO check other devices trough spi or whatever
}
}
uint32_t baseOfAdressType(DFUTransfer type) {
switch (type) {
case FW:
return currentDevice.startOfUserCode;
break;
case Descript:
return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
break;
default:
return 0;
}
}
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
switch (type) {
case FW:
return (size > currentDevice.sizeOfCode) ? 1 : 0;
break;
case Descript:
return (size > currentDevice.sizeOfDescription) ? 1 : 0;
break;
default:
return true;
}
}
uint32_t CalcFirmCRC() {
switch (currentProgrammingDestination) {
case Self_flash:
return PIOS_BL_HELPER_CRC_Memory_Calc();
break;
case Remote_flash_via_spi:
return 0;
break;
default:
return 0;
break;
}
}
void sendData(uint8_t * buf, uint16_t size) {
PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, buf, size);
}
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type) {
switch (type) {
case Remote_flash_via_spi:
return false; // We should not get this for the PipX
break;
case Self_flash:
for (uint8_t x = 0; x < 4; ++x) {
buffer[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x);
}
return true;
break;
default:
return false;
}
}

View File

@ -1,60 +0,0 @@
/**
******************************************************************************
*
* @file op_dfu.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @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
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __OP_DFU_H
#define __OP_DFU_H
#include "common.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct {
uint8_t programmingType;
uint8_t readWriteFlags;
uint32_t startOfUserCode;
uint32_t sizeOfCode;
uint8_t sizeOfDescription;
uint8_t BL_Version;
uint16_t devID;
DeviceType devType;
uint32_t FW_Crc;
} Device;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define COMMAND 0
#define COUNT 1
#define DATA 5
/* Exported functions ------------------------------------------------------- */
void processComand(uint8_t *Receive_Buffer);
uint32_t baseOfAdressType(uint8_t type);
uint8_t isBiggerThanAvailable(uint8_t type, uint32_t size);
void OPDfuIni(uint8_t discover);
void DataDownload(DownloadAction);
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type);
#endif /* __OP_DFU_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@ -1,468 +0,0 @@
/**
******************************************************************************
* @addtogroup CopterControlBL CopterControl BootLoader
* @brief These files contain the code to the CopterControl Bootloader.
*
* @{
* @file op_dfu.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief This file contains the DFU commands handling code
* @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 "pios.h"
#include <stdbool.h>
#include "op_dfu.h"
#include "pios_bl_helper.h"
#include "pios_com_msg.h"
#include <pios_board_info.h>
//programmable devices
Device devicesTable[10];
uint8_t numberOfDevices = 0;
DFUProgType currentProgrammingDestination; //flash, flash_trough spi
uint8_t currentDeviceCanRead;
uint8_t currentDeviceCanWrite;
Device currentDevice;
uint8_t Buffer[64];
uint8_t echoBuffer[64];
uint8_t SendBuffer[64];
uint8_t Command = 0;
uint8_t EchoReqFlag = 0;
uint8_t EchoAnsFlag = 0;
uint8_t StartFlag = 0;
uint32_t Aditionals = 0;
uint32_t SizeOfTransfer = 0;
uint32_t Expected_CRC = 0;
uint8_t SizeOfLastPacket = 0;
uint32_t Next_Packet = 0;
uint8_t TransferType;
uint32_t Count = 0;
uint32_t Data;
uint8_t Data0;
uint8_t Data1;
uint8_t Data2;
uint8_t Data3;
uint8_t offset = 0;
uint32_t aux;
//Download vars
uint32_t downSizeOfLastPacket = 0;
uint32_t downPacketTotal = 0;
uint32_t downPacketCurrent = 0;
DFUTransfer downType = 0;
/* Extern variables ----------------------------------------------------------*/
extern DFUStates DeviceState;
extern uint8_t JumpToApp;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void sendData(uint8_t * buf, uint16_t size);
uint32_t CalcFirmCRC(void);
void DataDownload(DownloadAction action) {
if ((DeviceState == downloading)) {
uint8_t packetSize;
uint32_t offset;
uint32_t partoffset;
SendBuffer[0] = 0x01;
SendBuffer[1] = Download;
SendBuffer[2] = downPacketCurrent >> 24;
SendBuffer[3] = downPacketCurrent >> 16;
SendBuffer[4] = downPacketCurrent >> 8;
SendBuffer[5] = downPacketCurrent;
if (downPacketCurrent == downPacketTotal - 1) {
packetSize = downSizeOfLastPacket;
} else {
packetSize = 14;
}
for (uint8_t x = 0; x < packetSize; ++x) {
partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
offset = baseOfAdressType(downType) + partoffset;
if (!flash_read(SendBuffer + (6 + x * 4), offset,
currentProgrammingDestination)) {
DeviceState = Last_operation_failed;
}
}
downPacketCurrent = downPacketCurrent + 1;
if (downPacketCurrent > downPacketTotal - 1) {
DeviceState = Last_operation_Success;
Aditionals = (uint32_t) Download;
}
sendData(SendBuffer + 1, 63);
}
}
void processComand(uint8_t *xReceive_Buffer) {
Command = xReceive_Buffer[COMMAND];
#ifdef DEBUG_SSP
char str[63]= {0};
sprintf(str,"Received COMMAND:%d|",Command);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
EchoReqFlag = (Command >> 7);
EchoAnsFlag = (Command >> 6) & 0x01;
StartFlag = (Command >> 5) & 0x01;
Count = xReceive_Buffer[COUNT] << 24;
Count += xReceive_Buffer[COUNT + 1] << 16;
Count += xReceive_Buffer[COUNT + 2] << 8;
Count += xReceive_Buffer[COUNT + 3];
Data = xReceive_Buffer[DATA] << 24;
Data += xReceive_Buffer[DATA + 1] << 16;
Data += xReceive_Buffer[DATA + 2] << 8;
Data += xReceive_Buffer[DATA + 3];
Data0 = xReceive_Buffer[DATA];
Data1 = xReceive_Buffer[DATA + 1];
Data2 = xReceive_Buffer[DATA + 2];
Data3 = xReceive_Buffer[DATA + 3];
Command = Command & 0b00011111;
if (EchoReqFlag == 1) {
memcpy(echoBuffer, xReceive_Buffer, 64);
}
switch (Command) {
case EnterDFU:
if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
|| (DeviceState == DFUidle)) {
if (Data0 > 0)
OPDfuIni(true);
DeviceState = DFUidle;
currentProgrammingDestination = devicesTable[Data0].programmingType;
currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
& 0x01;
currentDevice = devicesTable[Data0];
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Ini();
break;
case Remote_flash_via_spi:
result = true;
break;
default:
DeviceState = Last_operation_failed;
Aditionals = (uint16_t) Command;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Upload:
if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
if ((StartFlag == 1) && (Next_Packet == 0)) {
TransferType = Data0;
SizeOfTransfer = Count;
Next_Packet = 1;
Expected_CRC = Data2 << 24;
Expected_CRC += Data3 << 16;
Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
Expected_CRC += xReceive_Buffer[DATA + 5];
SizeOfLastPacket = Data1;
if (isBiggerThanAvailable(TransferType, (SizeOfTransfer - 1)
* 14 * 4 + SizeOfLastPacket * 4) == true) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
uint8_t result = 1;
if (TransferType == FW) {
switch (currentProgrammingDestination) {
case Self_flash:
result = PIOS_BL_HELPER_FLASH_Start();
break;
case Remote_flash_via_spi:
result = false;
break;
default:
break;
}
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
} else {
DeviceState = uploading;
}
}
} else if ((StartFlag != 1) && (Next_Packet != 0)) {
if (Count > SizeOfTransfer) {
DeviceState = too_many_packets;
Aditionals = Count;
} else if (Count == Next_Packet - 1) {
uint8_t numberOfWords = 14;
if (Count == SizeOfTransfer - 1)//is this the last packet?
{
numberOfWords = SizeOfLastPacket;
}
uint8_t result = 0;
switch (currentProgrammingDestination) {
case Self_flash:
for (uint8_t x = 0; x < numberOfWords; ++x) {
offset = 4 * x;
Data = xReceive_Buffer[DATA + offset] << 24;
Data += xReceive_Buffer[DATA + 1 + offset] << 16;
Data += xReceive_Buffer[DATA + 2 + offset] << 8;
Data += xReceive_Buffer[DATA + 3 + offset];
aux = baseOfAdressType(TransferType) + (uint32_t)(
Count * 14 * 4 + x * 4);
result = 0;
for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
if (result == 0) {
result = (FLASH_ProgramWord(aux, Data)
== FLASH_COMPLETE) ? 1 : 0;
}
}
}
break;
case Remote_flash_via_spi:
result = false; // No support for this for the PipX
break;
default:
result = 0;
break;
}
if (result != 1) {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
++Next_Packet;
} else {
DeviceState = wrong_packet_received;
Aditionals = Count;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
}
break;
case Req_Capabilities:
OPDfuIni(true);
Buffer[0] = 0x01;
Buffer[1] = Rep_Capabilities;
if (Data0 == 0) {
Buffer[2] = 0;
Buffer[3] = 0;
Buffer[4] = 0;
Buffer[5] = 0;
Buffer[6] = 0;
Buffer[7] = numberOfDevices;
uint16_t WRFlags = 0;
for (int x = 0; x < numberOfDevices; ++x) {
WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
| WRFlags);
}
Buffer[8] = WRFlags >> 8;
Buffer[9] = WRFlags;
} else {
Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
Buffer[6] = Data0;
Buffer[7] = devicesTable[Data0 - 1].BL_Version;
Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
Buffer[9] = devicesTable[Data0 - 1].devID;
Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
Buffer[15] = devicesTable[Data0 - 1].devID;
}
sendData(Buffer + 1, 63);
break;
case JumpFW:
if (Data == 0x5AFE) {
/* Force board into safe mode */
PIOS_IAP_WriteBootCount(0xFFFF);
}
FLASH_Lock();
JumpToApp = 1;
break;
case Reset:
PIOS_SYS_Reset();
break;
case Abort_Operation:
Next_Packet = 0;
DeviceState = DFUidle;
break;
case Op_END:
if (DeviceState == uploading) {
if (Next_Packet - 1 == SizeOfTransfer) {
Next_Packet = 0;
if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
DeviceState = Last_operation_Success;
} else {
DeviceState = CRC_Fail;
}
}
if (Next_Packet - 1 < SizeOfTransfer) {
Next_Packet = 0;
DeviceState = too_few_packets;
}
}
break;
case Download_Req:
#ifdef DEBUG_SSP
sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
#endif
if (DeviceState == DFUidle) {
#ifdef DEBUG_SSP
PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
#endif
downType = Data0;
downPacketTotal = Count;
downSizeOfLastPacket = Data1;
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14 * 4
+ downSizeOfLastPacket * 4) == 1) {
DeviceState = outsideDevCapabilities;
Aditionals = (uint32_t) Command;
} else {
downPacketCurrent = 0;
DeviceState = downloading;
}
} else {
DeviceState = Last_operation_failed;
Aditionals = (uint32_t) Command;
}
break;
case Status_Request:
Buffer[0] = 0x01;
Buffer[1] = Status_Rep;
if (DeviceState == wrong_packet_received) {
Buffer[2] = Aditionals >> 24;
Buffer[3] = Aditionals >> 16;
Buffer[4] = Aditionals >> 8;
Buffer[5] = Aditionals;
} else {
Buffer[2] = 0;
Buffer[3] = ((uint16_t) Aditionals) >> 8;
Buffer[4] = ((uint16_t) Aditionals);
Buffer[5] = 0;
}
Buffer[6] = DeviceState;
Buffer[7] = 0;
Buffer[8] = 0;
Buffer[9] = 0;
sendData(Buffer + 1, 63);
if (DeviceState == Last_operation_Success) {
DeviceState = DFUidle;
}
break;
case Status_Rep:
break;
}
if (EchoReqFlag == 1) {
echoBuffer[0] = echoBuffer[0] | (1 << 6);
sendData(echoBuffer, 63);
}
return;
}
void OPDfuIni(uint8_t discover) {
const struct pios_board_info * bdinfo = &pios_board_info_blob;
Device dev;
dev.programmingType = Self_flash;
dev.readWriteFlags = (BOARD_READABLE | (BOARD_WRITABLE << 1));
dev.startOfUserCode = bdinfo->fw_base;
dev.sizeOfCode = bdinfo->fw_size;
dev.sizeOfDescription = bdinfo->desc_size;
dev.BL_Version = bdinfo->bl_rev;
dev.FW_Crc = CalcFirmCRC();
dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
dev.devType = bdinfo->hw_type;
numberOfDevices = 1;
devicesTable[0] = dev;
if (discover) {
//TODO check other devices trough spi or whatever
}
}
uint32_t baseOfAdressType(DFUTransfer type) {
switch (type) {
case FW:
return currentDevice.startOfUserCode;
break;
case Descript:
return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
break;
default:
return 0;
}
}
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
switch (type) {
case FW:
return (size > currentDevice.sizeOfCode) ? 1 : 0;
break;
case Descript:
return (size > currentDevice.sizeOfDescription) ? 1 : 0;
break;
default:
return true;
}
}
uint32_t CalcFirmCRC() {
switch (currentProgrammingDestination) {
case Self_flash:
return PIOS_BL_HELPER_CRC_Memory_Calc();
break;
case Remote_flash_via_spi:
return 0;
break;
default:
return 0;
break;
}
}
void sendData(uint8_t * buf, uint16_t size) {
PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, buf, size);
}
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type) {
switch (type) {
case Remote_flash_via_spi:
return false; // We should not get this for the PipX
break;
case Self_flash:
for (uint8_t x = 0; x < 4; ++x) {
buffer[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x);
}
return true;
break;
default:
return false;
}
}

View File

@ -196,6 +196,17 @@ void PIOS_Board_Init(void) {
/* Initialize the real-time clock and its associated tick */
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
PIOS_IAP_Init();
// check for safe mode commands from gcs
if(PIOS_IAP_ReadBootCmd(0) == PIOS_IAP_CLEAR_FLASH_CMD_0 &&
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2)
{
PIOS_FLASHFS_Format(fs_id);
PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0);
}
HwSettingsInitialize();
@ -208,7 +219,6 @@ void PIOS_Board_Init(void) {
AlarmsInitialize();
/* Check for repeated boot failures */
PIOS_IAP_Init();
uint16_t boot_count = PIOS_IAP_ReadBootCount();
if (boot_count < 3) {
PIOS_IAP_WriteBootCount(++boot_count);
@ -792,7 +802,7 @@ void PIOS_Board_Init(void) {
#endif
break;
case BOARD_REVISION_CC3D:
// Revision 2 with L3GD20 gyros, start a SPI interface and connect to it
// Revision 2 with MPU6000 gyros, start a SPI interface and connect to it
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
#if defined(PIOS_INCLUDE_MPU6000)

View File

@ -101,6 +101,23 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
PIOS_EEPROM_Init(&pios_eeprom_cfg);
/* IAP System Setup */
PIOS_IAP_Init();
// check for safe mode commands from gcs
if(PIOS_IAP_ReadBootCmd(0) == PIOS_IAP_CLEAR_FLASH_CMD_0 &&
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) {
OPLinkSettingsGet(&oplinkSettings);
OPLinkSettingsSetDefaults(&oplinkSettings,0);
PIOS_EEPROM_Save((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData));
for (uint32_t i = 0; i < 10; i++) {
PIOS_DELAY_WaitmS(100);
PIOS_LED_Toggle(PIOS_LED_HEARTBEAT);
}
PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0);
}
/* Read the settings from flash. */
/* NOTE: We probably need to save/restore the objID here incase the object changed but the size doesn't */
if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0)
@ -125,10 +142,11 @@ void PIOS_Board_Init(void) {
/* Initialize board specific USB data */
PIOS_USB_BOARD_DATA_Init();
#if defined(PIOS_INCLUDE_USB_CDC)
/* Flags to determine if various USB interfaces are advertised */
bool usb_cdc_present = false;
#if defined(PIOS_INCLUDE_USB_CDC)
if (PIOS_USB_DESC_HID_CDC_Init()) {
PIOS_Assert(0);
}

View File

@ -347,16 +347,27 @@ void PIOS_Board_Init(void) {
#endif
#if defined(PIOS_INCLUDE_RTC)
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
/* IAP System Setup */
PIOS_IAP_Init();
// check for safe mode commands from gcs
if(PIOS_IAP_ReadBootCmd(0) == PIOS_IAP_CLEAR_FLASH_CMD_0 &&
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2)
{
PIOS_FLASHFS_Format(fs_id);
PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0);
}
/* Initialize UAVObject libraries */
EventDispatcherInitialize();
UAVObjInitialize();
HwSettingsInitialize();
#if defined(PIOS_INCLUDE_RTC)
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
/* Initialize the alarms library */
AlarmsInitialize();
@ -373,8 +384,7 @@ void PIOS_Board_Init(void) {
PIOS_TIM_InitClock(&tim_10_cfg);
PIOS_TIM_InitClock(&tim_11_cfg);
PIOS_TIM_InitClock(&tim_12_cfg);
/* IAP System Setup */
PIOS_IAP_Init();
uint16_t boot_count = PIOS_IAP_ReadBootCount();
if (boot_count < 3) {
PIOS_IAP_WriteBootCount(++boot_count);

View File

@ -401,16 +401,29 @@ void PIOS_Board_Init(void) {
PIOS_DEBUG_Assert(0);
}
#if defined(PIOS_INCLUDE_RTC)
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
/* IAP System Setup */
PIOS_IAP_Init();
// check for safe mode commands from gcs
if(PIOS_IAP_ReadBootCmd(0) == PIOS_IAP_CLEAR_FLASH_CMD_0 &&
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2)
{
PIOS_FLASHFS_Format(fs_id);
PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0);
}
/* Initialize UAVObject libraries */
EventDispatcherInitialize();
UAVObjInitialize();
HwSettingsInitialize();
#if defined(PIOS_INCLUDE_RTC)
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
/* Initialize the alarms library */
AlarmsInitialize();
@ -427,8 +440,6 @@ void PIOS_Board_Init(void) {
PIOS_TIM_InitClock(&tim_10_cfg);
PIOS_TIM_InitClock(&tim_11_cfg);
/* IAP System Setup */
PIOS_IAP_Init();
uint16_t boot_count = PIOS_IAP_ReadBootCount();
if (boot_count < 3) {
PIOS_IAP_WriteBootCount(++boot_count);

View File

@ -510,11 +510,10 @@ int DFUObject::AbortOperation(void)
return sendData(buf, BUF_LEN);
}
/**
Starts the firmware (leaves bootloader and boots the main software)
*/
int DFUObject::JumpToApp(bool safeboot)
int DFUObject::JumpToApp(bool safeboot, bool erase)
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
@ -536,6 +535,39 @@ int DFUObject::JumpToApp(bool safeboot)
buf[8] = 0;
buf[9] = 0;
}
if(erase)
{
// force data flash clear
buf[10] = 0x00;
buf[11] = 0x00;
buf[12] = 0xFA;
buf[13] = 0x5F;
buf[14] = 0x00;
buf[15] = 0x00;
buf[16] = 0x00;
buf[17] = 0x01;
buf[18] = 0x00;
buf[19] = 0x00;
buf[20] = 0x00;
buf[21] = 0x00;
} else {
buf[10] = 0x00;
buf[11] = 0x00;
buf[12] = 0x00;
buf[13] = 0x00;
buf[14] = 0x00;
buf[15] = 0x00;
buf[16] = 0x00;
buf[17] = 0x00;
buf[18] = 0x00;
buf[19] = 0x00;
buf[20] = 0x00;
buf[21] = 0x00;
}
return sendData(buf, BUF_LEN);
}

View File

@ -119,7 +119,7 @@ namespace OP_DFU {
{
Q_OBJECT;
public:
public:
static quint32 CRCFromQBArray(QByteArray array, quint32 Size);
//DFUObject(bool debug);
DFUObject(bool debug,bool use_serial,QString port);
@ -129,7 +129,7 @@ namespace OP_DFU {
// Service commands:
bool enterDFU(int const &devNumber);
bool findDevices();
int JumpToApp(bool);
int JumpToApp(bool safeboot, bool erase);
int ResetDevice(void);
OP_DFU::Status StatusRequest();
bool EndOperation();

View File

@ -68,6 +68,24 @@ menu on the right.</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="eraseBootButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Reboot the board and clear its settings memory.
Useful if the board cannot boot properly.
Blue led starts blinking quick for 20-30 seconds than the board will start normally
If telemetry is not running, select the link using the dropdown
menu on the right.</string>
</property>
<property name="text">
<string>Erase settings</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="enabled">
@ -186,14 +204,14 @@ halting a running board.</string>
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;To upgrade the firmware in your boards, proceed as follows:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- Connect telemetry&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- Once telemetry is running, press &amp;quot;Halt&amp;quot; above&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- You will get a list of devices.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- You can then upload/download to/from each board as you wish&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- You can resume operations by pressing &amp;quot;Boot&amp;quot;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;To upgrade the firmware in your boards, proceed as follows:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;- Connect telemetry&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;- Once telemetry is running, press &amp;quot;Halt&amp;quot; above&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;- You will get a list of devices.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;- You can then upload/download to/from each board as you wish&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;- You can resume operations by pressing &amp;quot;Boot&amp;quot;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -208,8 +226,8 @@ p, li { white-space: pre-wrap; }
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</widget>

View File

@ -54,6 +54,7 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
connect(m_config->safeBootButton, SIGNAL(clicked()), this, SLOT(systemSafeBoot()));
connect(m_config->eraseBootButton, SIGNAL(clicked()), this, SLOT(systemEraseBoot()));
connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue()));
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm,SIGNAL(deviceConnected(QIODevice*)),this,SLOT(onPhisicalHWConnect()));
@ -135,10 +136,16 @@ FlightStatus *UploaderGadgetWidget::getFlightStatus()
return status;
}
void UploaderGadgetWidget::bootButtonsSetEnable(bool enabled)
{
m_config->bootButton->setEnabled(enabled);
m_config->safeBootButton->setEnabled(enabled);
m_config->eraseBootButton->setEnabled(enabled);
}
void UploaderGadgetWidget::onPhisicalHWConnect()
{
m_config->bootButton->setEnabled(false);
m_config->safeBootButton->setEnabled(false);
bootButtonsSetEnable(false);
m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false);
}
@ -154,8 +161,7 @@ void UploaderGadgetWidget::populate()
{
m_config->haltButton->setEnabled(true);
m_config->resetButton->setEnabled(true);
m_config->safeBootButton->setEnabled(false);
m_config->bootButton->setEnabled(false);
bootButtonsSetEnable(false);
m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false);
@ -177,8 +183,7 @@ void UploaderGadgetWidget::populate()
void UploaderGadgetWidget::onAutopilotDisconnect(){
m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false);
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
bootButtonsSetEnable(true);
if (currentStep == IAP_STATE_BOOTLOADER) {
m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false);
@ -344,8 +349,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
m_config->resetButton->setEnabled(false);
*/
// Need to re-enable in case we were not connected
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
bootButtonsSetEnable(true);
/*
m_config->telemetryLink->setEnabled(false);
m_config->rescueButton->setEnabled(false);
@ -420,23 +424,38 @@ void UploaderGadgetWidget::systemReset()
void UploaderGadgetWidget::systemBoot()
{
commonSystemBoot(false);
commonSystemBoot(false, false);
}
void UploaderGadgetWidget::systemSafeBoot()
{
commonSystemBoot(true);
commonSystemBoot(true, false);
}
void UploaderGadgetWidget::systemEraseBoot()
{
QMessageBox msgBox;
int result;
msgBox.setWindowTitle(tr("Erase Settings"));
msgBox.setInformativeText(tr("Do you want to erase all settings from the board?\nSettings cannot be recovered after this operation.\nThe board will be restarted and all the setting erased"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel | QMessageBox::Help);
result = msgBox.exec();
if(result == QMessageBox::Ok)
{
commonSystemBoot(true, true);
} else if(result == QMessageBox::Help) {
QDesktopServices::openUrl( QUrl(tr("http://wiki.openpilot.org/display/Doc/Erase+board+settings"), QUrl::StrictMode) );
}
}
/**
* Tells the system to boot (from Bootloader state)
* @param[in] safeboot Indicates whether the firmware should use the stock HWSettings
*/
void UploaderGadgetWidget::commonSystemBoot(bool safeboot)
void UploaderGadgetWidget::commonSystemBoot(bool safeboot, bool erase)
{
clearLog();
m_config->bootButton->setEnabled(false);
m_config->safeBootButton->setEnabled(false);
bootButtonsSetEnable(false);
// Suspend telemety & polling in case it is not done yet
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
@ -459,13 +478,12 @@ void UploaderGadgetWidget::commonSystemBoot(bool safeboot)
log("Could not enter DFU mode.");
delete dfu;
dfu = NULL;
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
bootButtonsSetEnable(true);
m_config->rescueButton->setEnabled(true); // Boot not possible, maybe Rescue OK?
return;
}
log("Booting system...");
dfu->JumpToApp(safeboot);
dfu->JumpToApp(safeboot, erase);
// Restart the polling thread
cm->resumePolling();
m_config->rescueButton->setEnabled(true);
@ -738,8 +756,7 @@ void UploaderGadgetWidget::systemRescue()
}
m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false);
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
bootButtonsSetEnable(true);
m_config->rescueButton->setEnabled(false);
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
}
@ -773,8 +790,7 @@ void UploaderGadgetWidget::cancel()
void UploaderGadgetWidget::uploadStarted()
{
m_config->haltButton->setEnabled(false);
m_config->bootButton->setEnabled(false);
m_config->safeBootButton->setEnabled(false);
bootButtonsSetEnable(false);
m_config->resetButton->setEnabled(false);
m_config->rescueButton->setEnabled(false);
}
@ -784,8 +800,7 @@ void UploaderGadgetWidget::uploadEnded(bool succeed)
Q_UNUSED(succeed);
// device is halted so no halt
m_config->haltButton->setEnabled(false);
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
bootButtonsSetEnable(true);
// device is halted so no reset
m_config->resetButton->setEnabled(false);
m_config->rescueButton->setEnabled(true);
@ -794,8 +809,7 @@ void UploaderGadgetWidget::uploadEnded(bool succeed)
void UploaderGadgetWidget::downloadStarted()
{
m_config->haltButton->setEnabled(false);
m_config->bootButton->setEnabled(false);
m_config->safeBootButton->setEnabled(false);
bootButtonsSetEnable(false);
m_config->resetButton->setEnabled(false);
m_config->rescueButton->setEnabled(false);
}
@ -805,8 +819,7 @@ void UploaderGadgetWidget::downloadEnded(bool succeed)
Q_UNUSED(succeed);
// device is halted so no halt
m_config->haltButton->setEnabled(false);
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
bootButtonsSetEnable(true);
// device is halted so no reset
m_config->resetButton->setEnabled(false);
m_config->rescueButton->setEnabled(true);

View File

@ -97,6 +97,7 @@ private:
void connectSignalSlot(QWidget * widget);
int autoUpdateConnectTimeout;
FlightStatus * getFlightStatus();
void bootButtonsSetEnable(bool enabled);
private slots:
void onPhisicalHWConnect();
void versionMatchCheck();
@ -107,7 +108,8 @@ private slots:
void systemReset();
void systemBoot();
void systemSafeBoot();
void commonSystemBoot(bool = false);
void systemEraseBoot();
void commonSystemBoot(bool safeboot = false, bool erase = false);
void systemRescue();
void getSerialPorts();
void perform();

View File

@ -75,6 +75,7 @@ SRC += $(PIOSCOMMON)/pios_video.c
SRC += $(PIOSCOMMON)/pios_wavplay.c
## PIOS Hardware (Common)
SRC += $(PIOSCOMMON)/pios_iap.c
SRC += $(PIOSCOMMON)/pios_com.c
SRC += $(PIOSCOMMON)/pios_com_msg.c
SRC += $(PIOSCOMMON)/pios_crc.c

View File

@ -1,6 +1,6 @@
BOARD_TYPE := 0x04
BOARD_REVISION := 0x02
BOOTLOADER_VERSION := 0x03
BOOTLOADER_VERSION := 0x04
HW_TYPE := 0x01
MCU := cortex-m3

View File

@ -1,6 +1,6 @@
BOARD_TYPE := 0x05
BOARD_REVISION := 0x01
BOOTLOADER_VERSION := 0x01
BOOTLOADER_VERSION := 0x04
HW_TYPE := 0x00
MCU := cortex-m4

View File

@ -1,6 +1,6 @@
BOARD_TYPE := 0x03
BOARD_REVISION := 0x01
BOOTLOADER_VERSION := 0x02
BOOTLOADER_VERSION := 0x04
HW_TYPE := 0x01
MCU := cortex-m3

View File

@ -1,6 +1,6 @@
BOARD_TYPE := 0x09
BOARD_REVISION := 0x02
BOOTLOADER_VERSION := 0x01
BOOTLOADER_VERSION := 0x04
HW_TYPE := 0x00
MCU := cortex-m4

View File

@ -1,6 +1,6 @@
BOARD_TYPE := 0x09
BOARD_REVISION := 0x03
BOOTLOADER_VERSION := 0x01
BOOTLOADER_VERSION := 0x04
HW_TYPE := 0x00
MCU := cortex-m4

View File

@ -48,15 +48,16 @@ endif
SRC += $(OPSYSTEM)/main.c
SRC += $(OPSYSTEM)/pios_board.c
SRC += $(OPSYSTEM)/pios_usb_board_data.c
SRC += $(OPSYSTEM)/op_dfu.c
## PIOS Hardware (Common)
SRC += $(PIOSCOMMON)/pios_board_info.c
SRC += $(PIOSCOMMON)/pios_com_msg.c
SRC += $(PIOSCOMMON)/pios_iap.c
SRC += $(PIOSCOMMON)/pios_usb_desc_hid_only.c
SRC += $(PIOSCOMMON)/pios_usb_util.c
## Misc library functions
SRC += $(FLIGHTLIB)/op_dfu.c
SRC += $(FLIGHTLIB)/printf-stdarg.c
# List C source files here which must be compiled in ARM-Mode (no -mthumb).