mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
OP-874 merge of amorale/OP-874_gcs_rescue_erase_settings in next.
+review OPReview-421
This commit is contained in:
parent
5dc467bda4
commit
09d2ba1d25
@ -1,60 +1,60 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file op_dfu.h
|
* @file op_dfu.h
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
* @brief
|
* @brief
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
#ifndef __OP_DFU_H
|
#ifndef __OP_DFU_H
|
||||||
#define __OP_DFU_H
|
#define __OP_DFU_H
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t programmingType;
|
uint8_t programmingType;
|
||||||
uint8_t readWriteFlags;
|
uint8_t readWriteFlags;
|
||||||
uint32_t startOfUserCode;
|
uint32_t startOfUserCode;
|
||||||
uint32_t sizeOfCode;
|
uint32_t sizeOfCode;
|
||||||
uint8_t sizeOfDescription;
|
uint8_t sizeOfDescription;
|
||||||
uint8_t BL_Version;
|
uint8_t BL_Version;
|
||||||
uint16_t devID;
|
uint16_t devID;
|
||||||
DeviceType devType;
|
DeviceType devType;
|
||||||
uint32_t FW_Crc;
|
uint32_t FW_Crc;
|
||||||
} Device;
|
} Device;
|
||||||
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
/* Exported define -----------------------------------------------------------*/
|
/* Exported define -----------------------------------------------------------*/
|
||||||
#define COMMAND 0
|
#define COMMAND 0
|
||||||
#define COUNT 1
|
#define COUNT 1
|
||||||
#define DATA 5
|
#define DATA 5
|
||||||
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
/* Exported functions ------------------------------------------------------- */
|
||||||
void processComand(uint8_t *Receive_Buffer);
|
void processComand(uint8_t *Receive_Buffer);
|
||||||
uint32_t baseOfAdressType(uint8_t type);
|
uint32_t baseOfAdressType(uint8_t type);
|
||||||
uint8_t isBiggerThanAvailable(uint8_t type, uint32_t size);
|
uint8_t isBiggerThanAvailable(uint8_t type, uint32_t size);
|
||||||
void OPDfuIni(uint8_t discover);
|
void OPDfuIni(uint8_t discover);
|
||||||
void DataDownload(DownloadAction);
|
void DataDownload(DownloadAction);
|
||||||
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type);
|
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type);
|
||||||
#endif /* __OP_DFU_H */
|
#endif /* __OP_DFU_H */
|
||||||
|
|
||||||
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
@ -1,468 +1,484 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @addtogroup CopterControlBL CopterControl BootLoader
|
* @addtogroup CopterControlBL CopterControl BootLoader
|
||||||
* @brief These files contain the code to the CopterControl Bootloader.
|
* @brief These files contain the code to the CopterControl Bootloader.
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
* @file op_dfu.c
|
* @file op_dfu.c
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
* @brief This file contains the DFU commands handling code
|
* @brief This file contains the DFU commands handling code
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "pios.h"
|
#include "pios.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "op_dfu.h"
|
#include "op_dfu.h"
|
||||||
#include "pios_bl_helper.h"
|
#include "pios_bl_helper.h"
|
||||||
#include "pios_com_msg.h"
|
#include "pios_com_msg.h"
|
||||||
#include <pios_board_info.h>
|
#include <pios_board_info.h>
|
||||||
//programmable devices
|
//programmable devices
|
||||||
Device devicesTable[10];
|
Device devicesTable[10];
|
||||||
uint8_t numberOfDevices = 0;
|
uint8_t numberOfDevices = 0;
|
||||||
|
|
||||||
DFUProgType currentProgrammingDestination; //flash, flash_trough spi
|
DFUProgType currentProgrammingDestination; //flash, flash_trough spi
|
||||||
uint8_t currentDeviceCanRead;
|
uint8_t currentDeviceCanRead;
|
||||||
uint8_t currentDeviceCanWrite;
|
uint8_t currentDeviceCanWrite;
|
||||||
Device currentDevice;
|
Device currentDevice;
|
||||||
|
|
||||||
uint8_t Buffer[64];
|
uint8_t Buffer[64];
|
||||||
uint8_t echoBuffer[64];
|
uint8_t echoBuffer[64];
|
||||||
uint8_t SendBuffer[64];
|
uint8_t SendBuffer[64];
|
||||||
uint8_t Command = 0;
|
uint8_t Command = 0;
|
||||||
uint8_t EchoReqFlag = 0;
|
uint8_t EchoReqFlag = 0;
|
||||||
uint8_t EchoAnsFlag = 0;
|
uint8_t EchoAnsFlag = 0;
|
||||||
uint8_t StartFlag = 0;
|
uint8_t StartFlag = 0;
|
||||||
uint32_t Aditionals = 0;
|
uint32_t Aditionals = 0;
|
||||||
uint32_t SizeOfTransfer = 0;
|
uint32_t SizeOfTransfer = 0;
|
||||||
uint32_t Expected_CRC = 0;
|
uint32_t Expected_CRC = 0;
|
||||||
uint8_t SizeOfLastPacket = 0;
|
uint8_t SizeOfLastPacket = 0;
|
||||||
uint32_t Next_Packet = 0;
|
uint32_t Next_Packet = 0;
|
||||||
uint8_t TransferType;
|
uint8_t TransferType;
|
||||||
uint32_t Count = 0;
|
uint32_t Count = 0;
|
||||||
uint32_t Data;
|
uint32_t Data;
|
||||||
uint8_t Data0;
|
uint8_t Data0;
|
||||||
uint8_t Data1;
|
uint8_t Data1;
|
||||||
uint8_t Data2;
|
uint8_t Data2;
|
||||||
uint8_t Data3;
|
uint8_t Data3;
|
||||||
uint8_t offset = 0;
|
uint32_t Opt[3];
|
||||||
uint32_t aux;
|
|
||||||
//Download vars
|
uint8_t offset = 0;
|
||||||
uint32_t downSizeOfLastPacket = 0;
|
uint32_t aux;
|
||||||
uint32_t downPacketTotal = 0;
|
//Download vars
|
||||||
uint32_t downPacketCurrent = 0;
|
uint32_t downSizeOfLastPacket = 0;
|
||||||
DFUTransfer downType = 0;
|
uint32_t downPacketTotal = 0;
|
||||||
/* Extern variables ----------------------------------------------------------*/
|
uint32_t downPacketCurrent = 0;
|
||||||
extern DFUStates DeviceState;
|
DFUTransfer downType = 0;
|
||||||
extern uint8_t JumpToApp;
|
/* Extern variables ----------------------------------------------------------*/
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
extern DFUStates DeviceState;
|
||||||
/* Private functions ---------------------------------------------------------*/
|
extern uint8_t JumpToApp;
|
||||||
void sendData(uint8_t * buf, uint16_t size);
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
uint32_t CalcFirmCRC(void);
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
void sendData(uint8_t * buf, uint16_t size);
|
||||||
void DataDownload(DownloadAction action) {
|
uint32_t CalcFirmCRC(void);
|
||||||
if ((DeviceState == downloading)) {
|
|
||||||
|
void DataDownload(DownloadAction action) {
|
||||||
uint8_t packetSize;
|
if ((DeviceState == downloading)) {
|
||||||
uint32_t offset;
|
|
||||||
uint32_t partoffset;
|
uint8_t packetSize;
|
||||||
SendBuffer[0] = 0x01;
|
uint32_t offset;
|
||||||
SendBuffer[1] = Download;
|
uint32_t partoffset;
|
||||||
SendBuffer[2] = downPacketCurrent >> 24;
|
SendBuffer[0] = 0x01;
|
||||||
SendBuffer[3] = downPacketCurrent >> 16;
|
SendBuffer[1] = Download;
|
||||||
SendBuffer[4] = downPacketCurrent >> 8;
|
SendBuffer[2] = downPacketCurrent >> 24;
|
||||||
SendBuffer[5] = downPacketCurrent;
|
SendBuffer[3] = downPacketCurrent >> 16;
|
||||||
if (downPacketCurrent == downPacketTotal - 1) {
|
SendBuffer[4] = downPacketCurrent >> 8;
|
||||||
packetSize = downSizeOfLastPacket;
|
SendBuffer[5] = downPacketCurrent;
|
||||||
} else {
|
if (downPacketCurrent == downPacketTotal - 1) {
|
||||||
packetSize = 14;
|
packetSize = downSizeOfLastPacket;
|
||||||
}
|
} else {
|
||||||
for (uint8_t x = 0; x < packetSize; ++x) {
|
packetSize = 14;
|
||||||
partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
|
}
|
||||||
offset = baseOfAdressType(downType) + partoffset;
|
for (uint8_t x = 0; x < packetSize; ++x) {
|
||||||
if (!flash_read(SendBuffer + (6 + x * 4), offset,
|
partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
|
||||||
currentProgrammingDestination)) {
|
offset = baseOfAdressType(downType) + partoffset;
|
||||||
DeviceState = Last_operation_failed;
|
if (!flash_read(SendBuffer + (6 + x * 4), offset,
|
||||||
}
|
currentProgrammingDestination)) {
|
||||||
}
|
DeviceState = Last_operation_failed;
|
||||||
downPacketCurrent = downPacketCurrent + 1;
|
}
|
||||||
if (downPacketCurrent > downPacketTotal - 1) {
|
}
|
||||||
DeviceState = Last_operation_Success;
|
downPacketCurrent = downPacketCurrent + 1;
|
||||||
Aditionals = (uint32_t) Download;
|
if (downPacketCurrent > downPacketTotal - 1) {
|
||||||
}
|
DeviceState = Last_operation_Success;
|
||||||
sendData(SendBuffer + 1, 63);
|
Aditionals = (uint32_t) Download;
|
||||||
}
|
}
|
||||||
}
|
sendData(SendBuffer + 1, 63);
|
||||||
void processComand(uint8_t *xReceive_Buffer) {
|
}
|
||||||
|
}
|
||||||
Command = xReceive_Buffer[COMMAND];
|
void processComand(uint8_t *xReceive_Buffer) {
|
||||||
#ifdef DEBUG_SSP
|
|
||||||
char str[63]= {0};
|
Command = xReceive_Buffer[COMMAND];
|
||||||
sprintf(str,"Received COMMAND:%d|",Command);
|
#ifdef DEBUG_SSP
|
||||||
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
|
char str[63]= {0};
|
||||||
#endif
|
sprintf(str,"Received COMMAND:%d|",Command);
|
||||||
EchoReqFlag = (Command >> 7);
|
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
|
||||||
EchoAnsFlag = (Command >> 6) & 0x01;
|
#endif
|
||||||
StartFlag = (Command >> 5) & 0x01;
|
EchoReqFlag = (Command >> 7);
|
||||||
Count = xReceive_Buffer[COUNT] << 24;
|
EchoAnsFlag = (Command >> 6) & 0x01;
|
||||||
Count += xReceive_Buffer[COUNT + 1] << 16;
|
StartFlag = (Command >> 5) & 0x01;
|
||||||
Count += xReceive_Buffer[COUNT + 2] << 8;
|
Count = xReceive_Buffer[COUNT] << 24;
|
||||||
Count += xReceive_Buffer[COUNT + 3];
|
Count += xReceive_Buffer[COUNT + 1] << 16;
|
||||||
|
Count += xReceive_Buffer[COUNT + 2] << 8;
|
||||||
Data = xReceive_Buffer[DATA] << 24;
|
Count += xReceive_Buffer[COUNT + 3];
|
||||||
Data += xReceive_Buffer[DATA + 1] << 16;
|
|
||||||
Data += xReceive_Buffer[DATA + 2] << 8;
|
Data = xReceive_Buffer[DATA] << 24;
|
||||||
Data += xReceive_Buffer[DATA + 3];
|
Data += xReceive_Buffer[DATA + 1] << 16;
|
||||||
Data0 = xReceive_Buffer[DATA];
|
Data += xReceive_Buffer[DATA + 2] << 8;
|
||||||
Data1 = xReceive_Buffer[DATA + 1];
|
Data += xReceive_Buffer[DATA + 3];
|
||||||
Data2 = xReceive_Buffer[DATA + 2];
|
Data0 = xReceive_Buffer[DATA];
|
||||||
Data3 = xReceive_Buffer[DATA + 3];
|
Data1 = xReceive_Buffer[DATA + 1];
|
||||||
Command = Command & 0b00011111;
|
Data2 = xReceive_Buffer[DATA + 2];
|
||||||
|
Data3 = xReceive_Buffer[DATA + 3];
|
||||||
if (EchoReqFlag == 1) {
|
for( uint32_t i=0; i < 3; i++ )
|
||||||
memcpy(echoBuffer, xReceive_Buffer, 64);
|
{
|
||||||
}
|
Opt[i] = xReceive_Buffer[DATA + 4 * (i+1) ] << 24 |
|
||||||
switch (Command) {
|
xReceive_Buffer[DATA + 4 * (i+1) + 1] << 16 |
|
||||||
case EnterDFU:
|
xReceive_Buffer[DATA + 4 * (i+1) + 2] << 8 |
|
||||||
if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
|
xReceive_Buffer[DATA + 4 * (i+1) + 3];
|
||||||
|| (DeviceState == DFUidle)) {
|
}
|
||||||
if (Data0 > 0)
|
|
||||||
OPDfuIni(true);
|
Command = Command & 0b00011111;
|
||||||
DeviceState = DFUidle;
|
|
||||||
currentProgrammingDestination = devicesTable[Data0].programmingType;
|
if (EchoReqFlag == 1) {
|
||||||
currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
|
memcpy(echoBuffer, xReceive_Buffer, 64);
|
||||||
currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
|
}
|
||||||
& 0x01;
|
switch (Command) {
|
||||||
currentDevice = devicesTable[Data0];
|
case EnterDFU:
|
||||||
uint8_t result = 0;
|
if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
|
||||||
switch (currentProgrammingDestination) {
|
|| (DeviceState == DFUidle)) {
|
||||||
case Self_flash:
|
if (Data0 > 0)
|
||||||
result = PIOS_BL_HELPER_FLASH_Ini();
|
OPDfuIni(true);
|
||||||
break;
|
DeviceState = DFUidle;
|
||||||
case Remote_flash_via_spi:
|
currentProgrammingDestination = devicesTable[Data0].programmingType;
|
||||||
result = true;
|
currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
|
||||||
break;
|
currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
|
||||||
default:
|
& 0x01;
|
||||||
DeviceState = Last_operation_failed;
|
currentDevice = devicesTable[Data0];
|
||||||
Aditionals = (uint16_t) Command;
|
uint8_t result = 0;
|
||||||
}
|
switch (currentProgrammingDestination) {
|
||||||
if (result != 1) {
|
case Self_flash:
|
||||||
DeviceState = Last_operation_failed;
|
result = PIOS_BL_HELPER_FLASH_Ini();
|
||||||
Aditionals = (uint32_t) Command;
|
break;
|
||||||
}
|
case Remote_flash_via_spi:
|
||||||
}
|
result = true;
|
||||||
break;
|
break;
|
||||||
case Upload:
|
default:
|
||||||
if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
|
DeviceState = Last_operation_failed;
|
||||||
if ((StartFlag == 1) && (Next_Packet == 0)) {
|
Aditionals = (uint16_t) Command;
|
||||||
TransferType = Data0;
|
}
|
||||||
SizeOfTransfer = Count;
|
if (result != 1) {
|
||||||
Next_Packet = 1;
|
DeviceState = Last_operation_failed;
|
||||||
Expected_CRC = Data2 << 24;
|
Aditionals = (uint32_t) Command;
|
||||||
Expected_CRC += Data3 << 16;
|
}
|
||||||
Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
|
}
|
||||||
Expected_CRC += xReceive_Buffer[DATA + 5];
|
break;
|
||||||
SizeOfLastPacket = Data1;
|
case Upload:
|
||||||
|
if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
|
||||||
if (isBiggerThanAvailable(TransferType, (SizeOfTransfer - 1)
|
if ((StartFlag == 1) && (Next_Packet == 0)) {
|
||||||
* 14 * 4 + SizeOfLastPacket * 4) == true) {
|
TransferType = Data0;
|
||||||
DeviceState = outsideDevCapabilities;
|
SizeOfTransfer = Count;
|
||||||
Aditionals = (uint32_t) Command;
|
Next_Packet = 1;
|
||||||
} else {
|
Expected_CRC = Data2 << 24;
|
||||||
uint8_t result = 1;
|
Expected_CRC += Data3 << 16;
|
||||||
if (TransferType == FW) {
|
Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
|
||||||
switch (currentProgrammingDestination) {
|
Expected_CRC += xReceive_Buffer[DATA + 5];
|
||||||
case Self_flash:
|
SizeOfLastPacket = Data1;
|
||||||
result = PIOS_BL_HELPER_FLASH_Start();
|
|
||||||
break;
|
if (isBiggerThanAvailable(TransferType, (SizeOfTransfer - 1)
|
||||||
case Remote_flash_via_spi:
|
* 14 * 4 + SizeOfLastPacket * 4) == true) {
|
||||||
result = false;
|
DeviceState = outsideDevCapabilities;
|
||||||
break;
|
Aditionals = (uint32_t) Command;
|
||||||
default:
|
} else {
|
||||||
break;
|
uint8_t result = 1;
|
||||||
}
|
if (TransferType == FW) {
|
||||||
}
|
switch (currentProgrammingDestination) {
|
||||||
if (result != 1) {
|
case Self_flash:
|
||||||
DeviceState = Last_operation_failed;
|
result = PIOS_BL_HELPER_FLASH_Start();
|
||||||
Aditionals = (uint32_t) Command;
|
break;
|
||||||
} else {
|
case Remote_flash_via_spi:
|
||||||
|
result = false;
|
||||||
DeviceState = uploading;
|
break;
|
||||||
}
|
default:
|
||||||
}
|
break;
|
||||||
} else if ((StartFlag != 1) && (Next_Packet != 0)) {
|
}
|
||||||
if (Count > SizeOfTransfer) {
|
}
|
||||||
DeviceState = too_many_packets;
|
if (result != 1) {
|
||||||
Aditionals = Count;
|
DeviceState = Last_operation_failed;
|
||||||
} else if (Count == Next_Packet - 1) {
|
Aditionals = (uint32_t) Command;
|
||||||
uint8_t numberOfWords = 14;
|
} else {
|
||||||
if (Count == SizeOfTransfer - 1)//is this the last packet?
|
|
||||||
{
|
DeviceState = uploading;
|
||||||
numberOfWords = SizeOfLastPacket;
|
}
|
||||||
}
|
}
|
||||||
uint8_t result = 0;
|
} else if ((StartFlag != 1) && (Next_Packet != 0)) {
|
||||||
switch (currentProgrammingDestination) {
|
if (Count > SizeOfTransfer) {
|
||||||
case Self_flash:
|
DeviceState = too_many_packets;
|
||||||
for (uint8_t x = 0; x < numberOfWords; ++x) {
|
Aditionals = Count;
|
||||||
offset = 4 * x;
|
} else if (Count == Next_Packet - 1) {
|
||||||
Data = xReceive_Buffer[DATA + offset] << 24;
|
uint8_t numberOfWords = 14;
|
||||||
Data += xReceive_Buffer[DATA + 1 + offset] << 16;
|
if (Count == SizeOfTransfer - 1)//is this the last packet?
|
||||||
Data += xReceive_Buffer[DATA + 2 + offset] << 8;
|
{
|
||||||
Data += xReceive_Buffer[DATA + 3 + offset];
|
numberOfWords = SizeOfLastPacket;
|
||||||
aux = baseOfAdressType(TransferType) + (uint32_t)(
|
}
|
||||||
Count * 14 * 4 + x * 4);
|
uint8_t result = 0;
|
||||||
result = 0;
|
switch (currentProgrammingDestination) {
|
||||||
for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
|
case Self_flash:
|
||||||
if (result == 0) {
|
for (uint8_t x = 0; x < numberOfWords; ++x) {
|
||||||
result = (FLASH_ProgramWord(aux, Data)
|
offset = 4 * x;
|
||||||
== FLASH_COMPLETE) ? 1 : 0;
|
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];
|
||||||
break;
|
aux = baseOfAdressType(TransferType) + (uint32_t)(
|
||||||
case Remote_flash_via_spi:
|
Count * 14 * 4 + x * 4);
|
||||||
result = false; // No support for this for the PipX
|
result = 0;
|
||||||
break;
|
for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
|
||||||
default:
|
if (result == 0) {
|
||||||
result = 0;
|
result = (FLASH_ProgramWord(aux, Data)
|
||||||
break;
|
== FLASH_COMPLETE) ? 1 : 0;
|
||||||
}
|
}
|
||||||
if (result != 1) {
|
}
|
||||||
DeviceState = Last_operation_failed;
|
}
|
||||||
Aditionals = (uint32_t) Command;
|
break;
|
||||||
}
|
case Remote_flash_via_spi:
|
||||||
|
result = false; // No support for this for the PipX
|
||||||
++Next_Packet;
|
break;
|
||||||
} else {
|
default:
|
||||||
DeviceState = wrong_packet_received;
|
result = 0;
|
||||||
Aditionals = Count;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
if (result != 1) {
|
||||||
DeviceState = Last_operation_failed;
|
DeviceState = Last_operation_failed;
|
||||||
Aditionals = (uint32_t) Command;
|
Aditionals = (uint32_t) Command;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
++Next_Packet;
|
||||||
case Req_Capabilities:
|
} else {
|
||||||
OPDfuIni(true);
|
DeviceState = wrong_packet_received;
|
||||||
Buffer[0] = 0x01;
|
Aditionals = Count;
|
||||||
Buffer[1] = Rep_Capabilities;
|
}
|
||||||
if (Data0 == 0) {
|
} else {
|
||||||
Buffer[2] = 0;
|
DeviceState = Last_operation_failed;
|
||||||
Buffer[3] = 0;
|
Aditionals = (uint32_t) Command;
|
||||||
Buffer[4] = 0;
|
}
|
||||||
Buffer[5] = 0;
|
}
|
||||||
Buffer[6] = 0;
|
break;
|
||||||
Buffer[7] = numberOfDevices;
|
case Req_Capabilities:
|
||||||
uint16_t WRFlags = 0;
|
OPDfuIni(true);
|
||||||
for (int x = 0; x < numberOfDevices; ++x) {
|
Buffer[0] = 0x01;
|
||||||
WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
|
Buffer[1] = Rep_Capabilities;
|
||||||
| WRFlags);
|
if (Data0 == 0) {
|
||||||
}
|
Buffer[2] = 0;
|
||||||
Buffer[8] = WRFlags >> 8;
|
Buffer[3] = 0;
|
||||||
Buffer[9] = WRFlags;
|
Buffer[4] = 0;
|
||||||
} else {
|
Buffer[5] = 0;
|
||||||
Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
|
Buffer[6] = 0;
|
||||||
Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
|
Buffer[7] = numberOfDevices;
|
||||||
Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
|
uint16_t WRFlags = 0;
|
||||||
Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
|
for (int x = 0; x < numberOfDevices; ++x) {
|
||||||
Buffer[6] = Data0;
|
WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
|
||||||
Buffer[7] = devicesTable[Data0 - 1].BL_Version;
|
| WRFlags);
|
||||||
Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
|
}
|
||||||
Buffer[9] = devicesTable[Data0 - 1].devID;
|
Buffer[8] = WRFlags >> 8;
|
||||||
Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
|
Buffer[9] = WRFlags;
|
||||||
Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
|
} else {
|
||||||
Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
|
Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
|
||||||
Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
|
Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
|
||||||
Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
|
Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
|
||||||
Buffer[15] = devicesTable[Data0 - 1].devID;
|
Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
|
||||||
}
|
Buffer[6] = Data0;
|
||||||
sendData(Buffer + 1, 63);
|
Buffer[7] = devicesTable[Data0 - 1].BL_Version;
|
||||||
break;
|
Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
|
||||||
case JumpFW:
|
Buffer[9] = devicesTable[Data0 - 1].devID;
|
||||||
if (Data == 0x5AFE) {
|
Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
|
||||||
/* Force board into safe mode */
|
Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
|
||||||
PIOS_IAP_WriteBootCount(0xFFFF);
|
Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
|
||||||
}
|
Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
|
||||||
FLASH_Lock();
|
Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
|
||||||
JumpToApp = 1;
|
Buffer[15] = devicesTable[Data0 - 1].devID;
|
||||||
break;
|
}
|
||||||
case Reset:
|
sendData(Buffer + 1, 63);
|
||||||
PIOS_SYS_Reset();
|
break;
|
||||||
break;
|
case JumpFW:
|
||||||
case Abort_Operation:
|
if (Data == 0x5AFE)
|
||||||
Next_Packet = 0;
|
{
|
||||||
DeviceState = DFUidle;
|
/* Force board into safe mode */
|
||||||
break;
|
PIOS_IAP_WriteBootCount(0xFFFF);
|
||||||
|
}
|
||||||
case Op_END:
|
// pass any Opt value to the firmware
|
||||||
if (DeviceState == uploading) {
|
PIOS_IAP_WriteBootCmd(0, Opt[0]);
|
||||||
if (Next_Packet - 1 == SizeOfTransfer) {
|
PIOS_IAP_WriteBootCmd(1, Opt[1]);
|
||||||
Next_Packet = 0;
|
PIOS_IAP_WriteBootCmd(2, Opt[2]);
|
||||||
if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
|
|
||||||
DeviceState = Last_operation_Success;
|
FLASH_Lock();
|
||||||
} else {
|
JumpToApp = 1;
|
||||||
DeviceState = CRC_Fail;
|
break;
|
||||||
}
|
case Reset:
|
||||||
}
|
PIOS_SYS_Reset();
|
||||||
if (Next_Packet - 1 < SizeOfTransfer) {
|
break;
|
||||||
Next_Packet = 0;
|
case Abort_Operation:
|
||||||
DeviceState = too_few_packets;
|
Next_Packet = 0;
|
||||||
}
|
DeviceState = DFUidle;
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
case Download_Req:
|
case Op_END:
|
||||||
#ifdef DEBUG_SSP
|
if (DeviceState == uploading) {
|
||||||
sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
|
if (Next_Packet - 1 == SizeOfTransfer) {
|
||||||
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
|
Next_Packet = 0;
|
||||||
#endif
|
if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
|
||||||
if (DeviceState == DFUidle) {
|
DeviceState = Last_operation_Success;
|
||||||
#ifdef DEBUG_SSP
|
} else {
|
||||||
PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
|
DeviceState = CRC_Fail;
|
||||||
#endif
|
}
|
||||||
downType = Data0;
|
}
|
||||||
downPacketTotal = Count;
|
if (Next_Packet - 1 < SizeOfTransfer) {
|
||||||
downSizeOfLastPacket = Data1;
|
Next_Packet = 0;
|
||||||
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14 * 4
|
DeviceState = too_few_packets;
|
||||||
+ downSizeOfLastPacket * 4) == 1) {
|
}
|
||||||
DeviceState = outsideDevCapabilities;
|
}
|
||||||
Aditionals = (uint32_t) Command;
|
break;
|
||||||
|
case Download_Req:
|
||||||
} else {
|
#ifdef DEBUG_SSP
|
||||||
downPacketCurrent = 0;
|
sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
|
||||||
DeviceState = downloading;
|
PIOS_COM_SendString(PIOS_COM_TELEM_USB,str);
|
||||||
}
|
#endif
|
||||||
} else {
|
if (DeviceState == DFUidle) {
|
||||||
DeviceState = Last_operation_failed;
|
#ifdef DEBUG_SSP
|
||||||
Aditionals = (uint32_t) Command;
|
PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
|
||||||
}
|
#endif
|
||||||
break;
|
downType = Data0;
|
||||||
|
downPacketTotal = Count;
|
||||||
case Status_Request:
|
downSizeOfLastPacket = Data1;
|
||||||
Buffer[0] = 0x01;
|
if (isBiggerThanAvailable(downType, (downPacketTotal - 1) * 14
|
||||||
Buffer[1] = Status_Rep;
|
+ downSizeOfLastPacket) == 1) {
|
||||||
if (DeviceState == wrong_packet_received) {
|
DeviceState = outsideDevCapabilities;
|
||||||
Buffer[2] = Aditionals >> 24;
|
Aditionals = (uint32_t) Command;
|
||||||
Buffer[3] = Aditionals >> 16;
|
|
||||||
Buffer[4] = Aditionals >> 8;
|
} else {
|
||||||
Buffer[5] = Aditionals;
|
downPacketCurrent = 0;
|
||||||
} else {
|
DeviceState = downloading;
|
||||||
Buffer[2] = 0;
|
}
|
||||||
Buffer[3] = ((uint16_t) Aditionals) >> 8;
|
} else {
|
||||||
Buffer[4] = ((uint16_t) Aditionals);
|
DeviceState = Last_operation_failed;
|
||||||
Buffer[5] = 0;
|
Aditionals = (uint32_t) Command;
|
||||||
}
|
}
|
||||||
Buffer[6] = DeviceState;
|
break;
|
||||||
Buffer[7] = 0;
|
|
||||||
Buffer[8] = 0;
|
case Status_Request:
|
||||||
Buffer[9] = 0;
|
Buffer[0] = 0x01;
|
||||||
sendData(Buffer + 1, 63);
|
Buffer[1] = Status_Rep;
|
||||||
if (DeviceState == Last_operation_Success) {
|
if (DeviceState == wrong_packet_received) {
|
||||||
DeviceState = DFUidle;
|
Buffer[2] = Aditionals >> 24;
|
||||||
}
|
Buffer[3] = Aditionals >> 16;
|
||||||
break;
|
Buffer[4] = Aditionals >> 8;
|
||||||
case Status_Rep:
|
Buffer[5] = Aditionals;
|
||||||
|
} else {
|
||||||
break;
|
Buffer[2] = 0;
|
||||||
|
Buffer[3] = ((uint16_t) Aditionals) >> 8;
|
||||||
}
|
Buffer[4] = ((uint16_t) Aditionals);
|
||||||
if (EchoReqFlag == 1) {
|
Buffer[5] = 0;
|
||||||
echoBuffer[0] = echoBuffer[0] | (1 << 6);
|
}
|
||||||
sendData(echoBuffer, 63);
|
Buffer[6] = DeviceState;
|
||||||
}
|
Buffer[7] = 0;
|
||||||
return;
|
Buffer[8] = 0;
|
||||||
}
|
Buffer[9] = 0;
|
||||||
void OPDfuIni(uint8_t discover) {
|
sendData(Buffer + 1, 63);
|
||||||
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
if (DeviceState == Last_operation_Success) {
|
||||||
Device dev;
|
DeviceState = DFUidle;
|
||||||
|
}
|
||||||
dev.programmingType = Self_flash;
|
break;
|
||||||
dev.readWriteFlags = (BOARD_READABLE | (BOARD_WRITABLE << 1));
|
case Status_Rep:
|
||||||
dev.startOfUserCode = bdinfo->fw_base;
|
|
||||||
dev.sizeOfCode = bdinfo->fw_size;
|
break;
|
||||||
dev.sizeOfDescription = bdinfo->desc_size;
|
|
||||||
dev.BL_Version = bdinfo->bl_rev;
|
}
|
||||||
dev.FW_Crc = CalcFirmCRC();
|
if (EchoReqFlag == 1) {
|
||||||
dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
|
echoBuffer[1] = echoBuffer[1] | EchoAnsFlag;
|
||||||
dev.devType = bdinfo->hw_type;
|
sendData(echoBuffer + 1, 63);
|
||||||
numberOfDevices = 1;
|
}
|
||||||
devicesTable[0] = dev;
|
return;
|
||||||
if (discover) {
|
}
|
||||||
//TODO check other devices trough spi or whatever
|
void OPDfuIni(uint8_t discover) {
|
||||||
}
|
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||||
}
|
Device dev;
|
||||||
uint32_t baseOfAdressType(DFUTransfer type) {
|
|
||||||
switch (type) {
|
dev.programmingType = Self_flash;
|
||||||
case FW:
|
dev.readWriteFlags = (BOARD_READABLE | (BOARD_WRITABLE << 1));
|
||||||
return currentDevice.startOfUserCode;
|
dev.startOfUserCode = bdinfo->fw_base;
|
||||||
break;
|
dev.sizeOfCode = bdinfo->fw_size;
|
||||||
case Descript:
|
dev.sizeOfDescription = bdinfo->desc_size;
|
||||||
return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
|
dev.BL_Version = bdinfo->bl_rev;
|
||||||
break;
|
dev.FW_Crc = CalcFirmCRC();
|
||||||
default:
|
dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
|
||||||
|
dev.devType = bdinfo->hw_type;
|
||||||
return 0;
|
numberOfDevices = 1;
|
||||||
}
|
devicesTable[0] = dev;
|
||||||
}
|
if (discover) {
|
||||||
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
|
//TODO check other devices trough spi or whatever
|
||||||
switch (type) {
|
}
|
||||||
case FW:
|
}
|
||||||
return (size > currentDevice.sizeOfCode) ? 1 : 0;
|
uint32_t baseOfAdressType(DFUTransfer type) {
|
||||||
break;
|
switch (type) {
|
||||||
case Descript:
|
case FW:
|
||||||
return (size > currentDevice.sizeOfDescription) ? 1 : 0;
|
return currentDevice.startOfUserCode;
|
||||||
break;
|
break;
|
||||||
default:
|
case Descript:
|
||||||
return true;
|
return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
|
||||||
}
|
break;
|
||||||
}
|
default:
|
||||||
|
|
||||||
uint32_t CalcFirmCRC() {
|
return 0;
|
||||||
switch (currentProgrammingDestination) {
|
}
|
||||||
case Self_flash:
|
}
|
||||||
return PIOS_BL_HELPER_CRC_Memory_Calc();
|
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
|
||||||
break;
|
switch (type) {
|
||||||
case Remote_flash_via_spi:
|
case FW:
|
||||||
return 0;
|
return (size > currentDevice.sizeOfCode) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
default:
|
case Descript:
|
||||||
return 0;
|
return (size > currentDevice.sizeOfDescription) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
void sendData(uint8_t * buf, uint16_t size) {
|
}
|
||||||
PIOS_COM_MSG_Send(PIOS_COM_TELEM_USB, buf, size);
|
|
||||||
}
|
uint32_t CalcFirmCRC() {
|
||||||
|
switch (currentProgrammingDestination) {
|
||||||
bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type) {
|
case Self_flash:
|
||||||
switch (type) {
|
return PIOS_BL_HELPER_CRC_Memory_Calc();
|
||||||
case Remote_flash_via_spi:
|
break;
|
||||||
return false; // We should not get this for the PipX
|
case Remote_flash_via_spi:
|
||||||
break;
|
return 0;
|
||||||
case Self_flash:
|
break;
|
||||||
for (uint8_t x = 0; x < 4; ++x) {
|
default:
|
||||||
buffer[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x);
|
return 0;
|
||||||
}
|
break;
|
||||||
return true;
|
}
|
||||||
break;
|
|
||||||
default:
|
}
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup PIOS_IAP IAP Functions
|
* @addtogroup PIOS_IAP IAP Functions
|
||||||
* @brief STM32F4xx Hardware dependent I2C functionality
|
* @brief Common IAP functionality
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file pios_iap.c
|
* @file pios_iap.c
|
||||||
@ -32,6 +32,7 @@
|
|||||||
* Header files
|
* Header files
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#include <pios.h>
|
#include <pios.h>
|
||||||
|
#include <pios_bkp.h>
|
||||||
|
|
||||||
#ifdef PIOS_INCLUDE_IAP
|
#ifdef PIOS_INCLUDE_IAP
|
||||||
|
|
||||||
@ -55,7 +56,12 @@
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Private (static) Data
|
* Private (static) Data
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
|
const uint16_t pios_iap_cmd_list[] =
|
||||||
|
{
|
||||||
|
IAP_CMD1,
|
||||||
|
IAP_CMD2,
|
||||||
|
IAP_CMD3
|
||||||
|
};
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Public/Global Data
|
* Public/Global Data
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
@ -70,17 +76,8 @@
|
|||||||
*/
|
*/
|
||||||
void PIOS_IAP_Init( void )
|
void PIOS_IAP_Init( void )
|
||||||
{
|
{
|
||||||
/* Enable CRC clock */
|
PIOS_BKP_Init();
|
||||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
|
PIOS_BKP_EnableWrite();
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -97,8 +94,8 @@ uint32_t PIOS_IAP_CheckRequest( void )
|
|||||||
uint16_t reg1;
|
uint16_t reg1;
|
||||||
uint16_t reg2;
|
uint16_t reg2;
|
||||||
|
|
||||||
reg1 = RTC_ReadBackupRegister( MAGIC_REG_1 );
|
reg1 = PIOS_BKP_ReadRegister(MAGIC_REG_1);
|
||||||
reg2 = RTC_ReadBackupRegister( MAGIC_REG_2 );
|
reg2 = PIOS_BKP_ReadRegister(MAGIC_REG_2);
|
||||||
|
|
||||||
if( reg1 == IAP_MAGIC_WORD_1 && reg2 == IAP_MAGIC_WORD_2 ) {
|
if( reg1 == IAP_MAGIC_WORD_1 && reg2 == IAP_MAGIC_WORD_2 ) {
|
||||||
// We have a match.
|
// We have a match.
|
||||||
@ -119,28 +116,62 @@ uint32_t PIOS_IAP_CheckRequest( void )
|
|||||||
*/
|
*/
|
||||||
void PIOS_IAP_SetRequest1(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)
|
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)
|
void PIOS_IAP_ClearRequest(void)
|
||||||
{
|
{
|
||||||
RTC_WriteBackupRegister( MAGIC_REG_1, 0);
|
PIOS_BKP_WriteRegister(MAGIC_REG_1, 0);
|
||||||
RTC_WriteBackupRegister( MAGIC_REG_2, 0);
|
PIOS_BKP_WriteRegister(MAGIC_REG_2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PIOS_IAP_ReadBootCount(void)
|
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)
|
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 */
|
#endif /* PIOS_INCLUDE_IAP */
|
149
flight/PiOS/STM32F10x/pios_bkp.c
Normal file
149
flight/PiOS/STM32F10x/pios_bkp.c
Normal 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
|
||||||
|
****************************************************************************************/
|
@ -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 */
|
|
119
flight/PiOS/STM32F4xx/pios_bkp.c
Normal file
119
flight/PiOS/STM32F4xx/pios_bkp.c
Normal 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
|
||||||
|
****************************************************************************************/
|
@ -220,7 +220,7 @@ int32_t PIOS_SYS_Reset(void)
|
|||||||
*/
|
*/
|
||||||
uint32_t PIOS_SYS_getCPUFlashSize(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
118
flight/PiOS/inc/pios_bkp.h
Normal 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_ */
|
@ -1,45 +1,86 @@
|
|||||||
/*!
|
/**
|
||||||
* @File iap.h
|
******************************************************************************
|
||||||
* @Brief Header file for the In-Application-Programming Module
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
*
|
* @{
|
||||||
* Created on: Sep 6, 2010
|
* @addtogroup PIOS_IAP In-Application-Programming Module
|
||||||
* Author: joe
|
* @brief In-Application-Programming Module
|
||||||
*/
|
* @{
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
|
||||||
#ifndef PIOS_IAP_H
|
|
||||||
#define PIOS_IAP_H
|
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
/****************************************************************************************
|
* Header files
|
||||||
* Header files
|
****************************************************************************************/
|
||||||
****************************************************************************************/
|
#include <pios_bkp.h>
|
||||||
|
|
||||||
/*****************************************************************************************
|
/*****************************************************************************************
|
||||||
* Public Definitions/Macros
|
* Public Definitions/Macros
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if defined(STM32F4XX)
|
#define MAGIC_REG_1 PIOS_BKP_RESERVED_1
|
||||||
#define MAGIC_REG_1 RTC_BKP_DR1
|
#define MAGIC_REG_2 PIOS_BKP_RESERVED_2
|
||||||
#define MAGIC_REG_2 RTC_BKP_DR2
|
#define IAP_BOOTCOUNT PIOS_BKP_RESERVED_3
|
||||||
#define IAP_BOOTCOUNT RTC_BKP_DR3
|
#define IAP_CMD1 PIOS_BKP_RESERVED_5
|
||||||
#else
|
#define IAP_CMD2 PIOS_BKP_RESERVED_6
|
||||||
#define MAGIC_REG_1 BKP_DR1
|
#define IAP_CMD3 PIOS_BKP_RESERVED_7
|
||||||
#define MAGIC_REG_2 BKP_DR2
|
|
||||||
#define IAP_BOOTCOUNT BKP_DR3
|
#define PIOS_IAP_CLEAR_FLASH_CMD_0 0xFA5F
|
||||||
#endif
|
#define PIOS_IAP_CLEAR_FLASH_CMD_1 0x0001
|
||||||
|
#define PIOS_IAP_CLEAR_FLASH_CMD_2 0x0000
|
||||||
/****************************************************************************************
|
|
||||||
* Public Functions
|
#define PIOS_IAP_CMD_COUNT 3
|
||||||
****************************************************************************************/
|
|
||||||
void PIOS_IAP_Init(void);
|
/****************************************************************************************
|
||||||
uint32_t PIOS_IAP_CheckRequest( void );
|
* Public Functions
|
||||||
void PIOS_IAP_SetRequest1(void);
|
****************************************************************************************/
|
||||||
void PIOS_IAP_SetRequest2(void);
|
void PIOS_IAP_Init(void);
|
||||||
void PIOS_IAP_ClearRequest(void);
|
uint32_t PIOS_IAP_CheckRequest( void );
|
||||||
uint16_t PIOS_IAP_ReadBootCount(void);
|
void PIOS_IAP_SetRequest1(void);
|
||||||
void PIOS_IAP_WriteBootCount(uint16_t);
|
void PIOS_IAP_SetRequest2(void);
|
||||||
|
void PIOS_IAP_ClearRequest(void);
|
||||||
/****************************************************************************************
|
uint16_t PIOS_IAP_ReadBootCount(void);
|
||||||
* Public Data
|
void PIOS_IAP_WriteBootCount(uint16_t);
|
||||||
****************************************************************************************/
|
|
||||||
|
/**
|
||||||
#endif /* PIOS_IAP_H */
|
* @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
|
||||||
|
****************************************************************************************/
|
||||||
|
|
||||||
|
#endif /* PIOS_IAP_H */
|
||||||
|
@ -113,7 +113,6 @@ int main()
|
|||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
/// Bootloader programing
|
/// Bootloader programing
|
||||||
for (uint32_t offset = 0; offset < embedded_image_size / sizeof(uint32_t); ++offset) {
|
for (uint32_t offset = 0; offset < embedded_image_size / sizeof(uint32_t); ++offset) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@ -156,12 +155,6 @@ void error(int led, int code)
|
|||||||
PIOS_LED_Off(led);
|
PIOS_LED_Off(led);
|
||||||
PIOS_DELAY_WaitmS(1000);
|
PIOS_DELAY_WaitmS(1000);
|
||||||
}
|
}
|
||||||
PIOS_DELAY_WaitmS(1000);
|
PIOS_DELAY_WaitmS(3000);
|
||||||
for (int x = 0; x < 10; x++) {
|
|
||||||
PIOS_LED_On(led);
|
|
||||||
PIOS_DELAY_WaitmS(200);
|
|
||||||
PIOS_LED_Off(led);
|
|
||||||
PIOS_DELAY_WaitmS(200);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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****/
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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****/
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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****/
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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****/
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -196,7 +196,18 @@ void PIOS_Board_Init(void) {
|
|||||||
/* Initialize the real-time clock and its associated tick */
|
/* Initialize the real-time clock and its associated tick */
|
||||||
PIOS_RTC_Init(&pios_rtc_main_cfg);
|
PIOS_RTC_Init(&pios_rtc_main_cfg);
|
||||||
#endif
|
#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();
|
HwSettingsInitialize();
|
||||||
|
|
||||||
#ifndef ERASE_FLASH
|
#ifndef ERASE_FLASH
|
||||||
@ -208,7 +219,6 @@ void PIOS_Board_Init(void) {
|
|||||||
AlarmsInitialize();
|
AlarmsInitialize();
|
||||||
|
|
||||||
/* Check for repeated boot failures */
|
/* Check for repeated boot failures */
|
||||||
PIOS_IAP_Init();
|
|
||||||
uint16_t boot_count = PIOS_IAP_ReadBootCount();
|
uint16_t boot_count = PIOS_IAP_ReadBootCount();
|
||||||
if (boot_count < 3) {
|
if (boot_count < 3) {
|
||||||
PIOS_IAP_WriteBootCount(++boot_count);
|
PIOS_IAP_WriteBootCount(++boot_count);
|
||||||
@ -792,7 +802,7 @@ void PIOS_Board_Init(void) {
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case BOARD_REVISION_CC3D:
|
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);
|
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_MPU6000)
|
#if defined(PIOS_INCLUDE_MPU6000)
|
||||||
|
@ -101,6 +101,23 @@ void PIOS_Board_Init(void) {
|
|||||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||||
PIOS_EEPROM_Init(&pios_eeprom_cfg);
|
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. */
|
/* Read the settings from flash. */
|
||||||
/* NOTE: We probably need to save/restore the objID here incase the object changed but the size doesn't */
|
/* 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)
|
if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0)
|
||||||
@ -125,10 +142,11 @@ void PIOS_Board_Init(void) {
|
|||||||
/* Initialize board specific USB data */
|
/* Initialize board specific USB data */
|
||||||
PIOS_USB_BOARD_DATA_Init();
|
PIOS_USB_BOARD_DATA_Init();
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_USB_CDC)
|
||||||
/* Flags to determine if various USB interfaces are advertised */
|
/* Flags to determine if various USB interfaces are advertised */
|
||||||
bool usb_cdc_present = false;
|
bool usb_cdc_present = false;
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_USB_CDC)
|
|
||||||
if (PIOS_USB_DESC_HID_CDC_Init()) {
|
if (PIOS_USB_DESC_HID_CDC_Init()) {
|
||||||
PIOS_Assert(0);
|
PIOS_Assert(0);
|
||||||
}
|
}
|
||||||
|
@ -346,17 +346,28 @@ void PIOS_Board_Init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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 */
|
/* Initialize UAVObject libraries */
|
||||||
EventDispatcherInitialize();
|
EventDispatcherInitialize();
|
||||||
UAVObjInitialize();
|
UAVObjInitialize();
|
||||||
|
|
||||||
HwSettingsInitialize();
|
HwSettingsInitialize();
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_RTC)
|
|
||||||
PIOS_RTC_Init(&pios_rtc_main_cfg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize the alarms library */
|
/* Initialize the alarms library */
|
||||||
AlarmsInitialize();
|
AlarmsInitialize();
|
||||||
|
|
||||||
@ -373,8 +384,7 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_TIM_InitClock(&tim_10_cfg);
|
PIOS_TIM_InitClock(&tim_10_cfg);
|
||||||
PIOS_TIM_InitClock(&tim_11_cfg);
|
PIOS_TIM_InitClock(&tim_11_cfg);
|
||||||
PIOS_TIM_InitClock(&tim_12_cfg);
|
PIOS_TIM_InitClock(&tim_12_cfg);
|
||||||
/* IAP System Setup */
|
|
||||||
PIOS_IAP_Init();
|
|
||||||
uint16_t boot_count = PIOS_IAP_ReadBootCount();
|
uint16_t boot_count = PIOS_IAP_ReadBootCount();
|
||||||
if (boot_count < 3) {
|
if (boot_count < 3) {
|
||||||
PIOS_IAP_WriteBootCount(++boot_count);
|
PIOS_IAP_WriteBootCount(++boot_count);
|
||||||
|
@ -401,15 +401,28 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_DEBUG_Assert(0);
|
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 */
|
/* Initialize UAVObject libraries */
|
||||||
EventDispatcherInitialize();
|
EventDispatcherInitialize();
|
||||||
UAVObjInitialize();
|
UAVObjInitialize();
|
||||||
|
|
||||||
HwSettingsInitialize();
|
HwSettingsInitialize();
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_RTC)
|
|
||||||
PIOS_RTC_Init(&pios_rtc_main_cfg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize the alarms library */
|
/* Initialize the alarms library */
|
||||||
AlarmsInitialize();
|
AlarmsInitialize();
|
||||||
@ -427,8 +440,6 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_TIM_InitClock(&tim_10_cfg);
|
PIOS_TIM_InitClock(&tim_10_cfg);
|
||||||
PIOS_TIM_InitClock(&tim_11_cfg);
|
PIOS_TIM_InitClock(&tim_11_cfg);
|
||||||
|
|
||||||
/* IAP System Setup */
|
|
||||||
PIOS_IAP_Init();
|
|
||||||
uint16_t boot_count = PIOS_IAP_ReadBootCount();
|
uint16_t boot_count = PIOS_IAP_ReadBootCount();
|
||||||
if (boot_count < 3) {
|
if (boot_count < 3) {
|
||||||
PIOS_IAP_WriteBootCount(++boot_count);
|
PIOS_IAP_WriteBootCount(++boot_count);
|
||||||
|
@ -510,11 +510,10 @@ int DFUObject::AbortOperation(void)
|
|||||||
|
|
||||||
return sendData(buf, BUF_LEN);
|
return sendData(buf, BUF_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Starts the firmware (leaves bootloader and boots the main software)
|
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];
|
char buf[BUF_LEN];
|
||||||
buf[0] =0x02;//reportID
|
buf[0] =0x02;//reportID
|
||||||
@ -536,6 +535,39 @@ int DFUObject::JumpToApp(bool safeboot)
|
|||||||
buf[8] = 0;
|
buf[8] = 0;
|
||||||
buf[9] = 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);
|
return sendData(buf, BUF_LEN);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ namespace OP_DFU {
|
|||||||
{
|
{
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static quint32 CRCFromQBArray(QByteArray array, quint32 Size);
|
static quint32 CRCFromQBArray(QByteArray array, quint32 Size);
|
||||||
//DFUObject(bool debug);
|
//DFUObject(bool debug);
|
||||||
DFUObject(bool debug,bool use_serial,QString port);
|
DFUObject(bool debug,bool use_serial,QString port);
|
||||||
@ -129,7 +129,7 @@ namespace OP_DFU {
|
|||||||
// Service commands:
|
// Service commands:
|
||||||
bool enterDFU(int const &devNumber);
|
bool enterDFU(int const &devNumber);
|
||||||
bool findDevices();
|
bool findDevices();
|
||||||
int JumpToApp(bool);
|
int JumpToApp(bool safeboot, bool erase);
|
||||||
int ResetDevice(void);
|
int ResetDevice(void);
|
||||||
OP_DFU::Status StatusRequest();
|
OP_DFU::Status StatusRequest();
|
||||||
bool EndOperation();
|
bool EndOperation();
|
||||||
|
@ -68,6 +68,24 @@ menu on the right.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<widget class="QPushButton" name="resetButton">
|
<widget class="QPushButton" name="resetButton">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
@ -186,14 +204,14 @@ halting a running board.</string>
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">To upgrade the firmware in your boards, proceed as follows:</p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">To upgrade the firmware in your boards, proceed as follows:</span></p>
|
||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
|
<p style="-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;"><br /></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Connect telemetry</p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">- Connect telemetry</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Once telemetry is running, press &quot;Halt&quot; above</p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">- Once telemetry is running, press &quot;Halt&quot; above</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- You will get a list of devices.</p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">- You will get a list of devices.</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- You can then upload/download to/from each board as you wish</p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">- You can then upload/download to/from each board as you wish</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- You can resume operations by pressing &quot;Boot&quot;</p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">- You can resume operations by pressing &quot;Boot&quot;</span></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -208,8 +226,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string>
|
<p style="-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;"><br /></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -54,6 +54,7 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
|
|||||||
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
|
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
|
||||||
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
|
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
|
||||||
connect(m_config->safeBootButton, SIGNAL(clicked()), this, SLOT(systemSafeBoot()));
|
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()));
|
connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue()));
|
||||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||||
connect(cm,SIGNAL(deviceConnected(QIODevice*)),this,SLOT(onPhisicalHWConnect()));
|
connect(cm,SIGNAL(deviceConnected(QIODevice*)),this,SLOT(onPhisicalHWConnect()));
|
||||||
@ -135,10 +136,16 @@ FlightStatus *UploaderGadgetWidget::getFlightStatus()
|
|||||||
return status;
|
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()
|
void UploaderGadgetWidget::onPhisicalHWConnect()
|
||||||
{
|
{
|
||||||
m_config->bootButton->setEnabled(false);
|
bootButtonsSetEnable(false);
|
||||||
m_config->safeBootButton->setEnabled(false);
|
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
m_config->telemetryLink->setEnabled(false);
|
m_config->telemetryLink->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -154,8 +161,7 @@ void UploaderGadgetWidget::populate()
|
|||||||
{
|
{
|
||||||
m_config->haltButton->setEnabled(true);
|
m_config->haltButton->setEnabled(true);
|
||||||
m_config->resetButton->setEnabled(true);
|
m_config->resetButton->setEnabled(true);
|
||||||
m_config->safeBootButton->setEnabled(false);
|
bootButtonsSetEnable(false);
|
||||||
m_config->bootButton->setEnabled(false);
|
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
m_config->telemetryLink->setEnabled(false);
|
m_config->telemetryLink->setEnabled(false);
|
||||||
|
|
||||||
@ -177,8 +183,7 @@ void UploaderGadgetWidget::populate()
|
|||||||
void UploaderGadgetWidget::onAutopilotDisconnect(){
|
void UploaderGadgetWidget::onAutopilotDisconnect(){
|
||||||
m_config->haltButton->setEnabled(false);
|
m_config->haltButton->setEnabled(false);
|
||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
m_config->bootButton->setEnabled(true);
|
bootButtonsSetEnable(true);
|
||||||
m_config->safeBootButton->setEnabled(true);
|
|
||||||
if (currentStep == IAP_STATE_BOOTLOADER) {
|
if (currentStep == IAP_STATE_BOOTLOADER) {
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
m_config->telemetryLink->setEnabled(false);
|
m_config->telemetryLink->setEnabled(false);
|
||||||
@ -344,8 +349,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
|
|||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
*/
|
*/
|
||||||
// Need to re-enable in case we were not connected
|
// Need to re-enable in case we were not connected
|
||||||
m_config->bootButton->setEnabled(true);
|
bootButtonsSetEnable(true);
|
||||||
m_config->safeBootButton->setEnabled(true);
|
|
||||||
/*
|
/*
|
||||||
m_config->telemetryLink->setEnabled(false);
|
m_config->telemetryLink->setEnabled(false);
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
@ -420,23 +424,38 @@ void UploaderGadgetWidget::systemReset()
|
|||||||
|
|
||||||
void UploaderGadgetWidget::systemBoot()
|
void UploaderGadgetWidget::systemBoot()
|
||||||
{
|
{
|
||||||
commonSystemBoot(false);
|
commonSystemBoot(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UploaderGadgetWidget::systemSafeBoot()
|
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)
|
* Tells the system to boot (from Bootloader state)
|
||||||
* @param[in] safeboot Indicates whether the firmware should use the stock HWSettings
|
* @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();
|
clearLog();
|
||||||
m_config->bootButton->setEnabled(false);
|
bootButtonsSetEnable(false);
|
||||||
m_config->safeBootButton->setEnabled(false);
|
|
||||||
|
|
||||||
// Suspend telemety & polling in case it is not done yet
|
// Suspend telemety & polling in case it is not done yet
|
||||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||||
@ -459,13 +478,12 @@ void UploaderGadgetWidget::commonSystemBoot(bool safeboot)
|
|||||||
log("Could not enter DFU mode.");
|
log("Could not enter DFU mode.");
|
||||||
delete dfu;
|
delete dfu;
|
||||||
dfu = NULL;
|
dfu = NULL;
|
||||||
m_config->bootButton->setEnabled(true);
|
bootButtonsSetEnable(true);
|
||||||
m_config->safeBootButton->setEnabled(true);
|
|
||||||
m_config->rescueButton->setEnabled(true); // Boot not possible, maybe Rescue OK?
|
m_config->rescueButton->setEnabled(true); // Boot not possible, maybe Rescue OK?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log("Booting system...");
|
log("Booting system...");
|
||||||
dfu->JumpToApp(safeboot);
|
dfu->JumpToApp(safeboot, erase);
|
||||||
// Restart the polling thread
|
// Restart the polling thread
|
||||||
cm->resumePolling();
|
cm->resumePolling();
|
||||||
m_config->rescueButton->setEnabled(true);
|
m_config->rescueButton->setEnabled(true);
|
||||||
@ -738,8 +756,7 @@ void UploaderGadgetWidget::systemRescue()
|
|||||||
}
|
}
|
||||||
m_config->haltButton->setEnabled(false);
|
m_config->haltButton->setEnabled(false);
|
||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
m_config->bootButton->setEnabled(true);
|
bootButtonsSetEnable(true);
|
||||||
m_config->safeBootButton->setEnabled(true);
|
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
|
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
|
||||||
}
|
}
|
||||||
@ -773,8 +790,7 @@ void UploaderGadgetWidget::cancel()
|
|||||||
void UploaderGadgetWidget::uploadStarted()
|
void UploaderGadgetWidget::uploadStarted()
|
||||||
{
|
{
|
||||||
m_config->haltButton->setEnabled(false);
|
m_config->haltButton->setEnabled(false);
|
||||||
m_config->bootButton->setEnabled(false);
|
bootButtonsSetEnable(false);
|
||||||
m_config->safeBootButton->setEnabled(false);
|
|
||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -784,8 +800,7 @@ void UploaderGadgetWidget::uploadEnded(bool succeed)
|
|||||||
Q_UNUSED(succeed);
|
Q_UNUSED(succeed);
|
||||||
// device is halted so no halt
|
// device is halted so no halt
|
||||||
m_config->haltButton->setEnabled(false);
|
m_config->haltButton->setEnabled(false);
|
||||||
m_config->bootButton->setEnabled(true);
|
bootButtonsSetEnable(true);
|
||||||
m_config->safeBootButton->setEnabled(true);
|
|
||||||
// device is halted so no reset
|
// device is halted so no reset
|
||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
m_config->rescueButton->setEnabled(true);
|
m_config->rescueButton->setEnabled(true);
|
||||||
@ -794,8 +809,7 @@ void UploaderGadgetWidget::uploadEnded(bool succeed)
|
|||||||
void UploaderGadgetWidget::downloadStarted()
|
void UploaderGadgetWidget::downloadStarted()
|
||||||
{
|
{
|
||||||
m_config->haltButton->setEnabled(false);
|
m_config->haltButton->setEnabled(false);
|
||||||
m_config->bootButton->setEnabled(false);
|
bootButtonsSetEnable(false);
|
||||||
m_config->safeBootButton->setEnabled(false);
|
|
||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
m_config->rescueButton->setEnabled(false);
|
m_config->rescueButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -805,8 +819,7 @@ void UploaderGadgetWidget::downloadEnded(bool succeed)
|
|||||||
Q_UNUSED(succeed);
|
Q_UNUSED(succeed);
|
||||||
// device is halted so no halt
|
// device is halted so no halt
|
||||||
m_config->haltButton->setEnabled(false);
|
m_config->haltButton->setEnabled(false);
|
||||||
m_config->bootButton->setEnabled(true);
|
bootButtonsSetEnable(true);
|
||||||
m_config->safeBootButton->setEnabled(true);
|
|
||||||
// device is halted so no reset
|
// device is halted so no reset
|
||||||
m_config->resetButton->setEnabled(false);
|
m_config->resetButton->setEnabled(false);
|
||||||
m_config->rescueButton->setEnabled(true);
|
m_config->rescueButton->setEnabled(true);
|
||||||
|
@ -97,6 +97,7 @@ private:
|
|||||||
void connectSignalSlot(QWidget * widget);
|
void connectSignalSlot(QWidget * widget);
|
||||||
int autoUpdateConnectTimeout;
|
int autoUpdateConnectTimeout;
|
||||||
FlightStatus * getFlightStatus();
|
FlightStatus * getFlightStatus();
|
||||||
|
void bootButtonsSetEnable(bool enabled);
|
||||||
private slots:
|
private slots:
|
||||||
void onPhisicalHWConnect();
|
void onPhisicalHWConnect();
|
||||||
void versionMatchCheck();
|
void versionMatchCheck();
|
||||||
@ -107,7 +108,8 @@ private slots:
|
|||||||
void systemReset();
|
void systemReset();
|
||||||
void systemBoot();
|
void systemBoot();
|
||||||
void systemSafeBoot();
|
void systemSafeBoot();
|
||||||
void commonSystemBoot(bool = false);
|
void systemEraseBoot();
|
||||||
|
void commonSystemBoot(bool safeboot = false, bool erase = false);
|
||||||
void systemRescue();
|
void systemRescue();
|
||||||
void getSerialPorts();
|
void getSerialPorts();
|
||||||
void perform();
|
void perform();
|
||||||
|
@ -75,6 +75,7 @@ SRC += $(PIOSCOMMON)/pios_video.c
|
|||||||
SRC += $(PIOSCOMMON)/pios_wavplay.c
|
SRC += $(PIOSCOMMON)/pios_wavplay.c
|
||||||
|
|
||||||
## PIOS Hardware (Common)
|
## PIOS Hardware (Common)
|
||||||
|
SRC += $(PIOSCOMMON)/pios_iap.c
|
||||||
SRC += $(PIOSCOMMON)/pios_com.c
|
SRC += $(PIOSCOMMON)/pios_com.c
|
||||||
SRC += $(PIOSCOMMON)/pios_com_msg.c
|
SRC += $(PIOSCOMMON)/pios_com_msg.c
|
||||||
SRC += $(PIOSCOMMON)/pios_crc.c
|
SRC += $(PIOSCOMMON)/pios_crc.c
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BOARD_TYPE := 0x04
|
BOARD_TYPE := 0x04
|
||||||
BOARD_REVISION := 0x02
|
BOARD_REVISION := 0x02
|
||||||
BOOTLOADER_VERSION := 0x03
|
BOOTLOADER_VERSION := 0x04
|
||||||
HW_TYPE := 0x01
|
HW_TYPE := 0x01
|
||||||
|
|
||||||
MCU := cortex-m3
|
MCU := cortex-m3
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BOARD_TYPE := 0x05
|
BOARD_TYPE := 0x05
|
||||||
BOARD_REVISION := 0x01
|
BOARD_REVISION := 0x01
|
||||||
BOOTLOADER_VERSION := 0x01
|
BOOTLOADER_VERSION := 0x04
|
||||||
HW_TYPE := 0x00
|
HW_TYPE := 0x00
|
||||||
|
|
||||||
MCU := cortex-m4
|
MCU := cortex-m4
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BOARD_TYPE := 0x03
|
BOARD_TYPE := 0x03
|
||||||
BOARD_REVISION := 0x01
|
BOARD_REVISION := 0x01
|
||||||
BOOTLOADER_VERSION := 0x02
|
BOOTLOADER_VERSION := 0x04
|
||||||
HW_TYPE := 0x01
|
HW_TYPE := 0x01
|
||||||
|
|
||||||
MCU := cortex-m3
|
MCU := cortex-m3
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BOARD_TYPE := 0x09
|
BOARD_TYPE := 0x09
|
||||||
BOARD_REVISION := 0x02
|
BOARD_REVISION := 0x02
|
||||||
BOOTLOADER_VERSION := 0x01
|
BOOTLOADER_VERSION := 0x04
|
||||||
HW_TYPE := 0x00
|
HW_TYPE := 0x00
|
||||||
|
|
||||||
MCU := cortex-m4
|
MCU := cortex-m4
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BOARD_TYPE := 0x09
|
BOARD_TYPE := 0x09
|
||||||
BOARD_REVISION := 0x03
|
BOARD_REVISION := 0x03
|
||||||
BOOTLOADER_VERSION := 0x01
|
BOOTLOADER_VERSION := 0x04
|
||||||
HW_TYPE := 0x00
|
HW_TYPE := 0x00
|
||||||
|
|
||||||
MCU := cortex-m4
|
MCU := cortex-m4
|
||||||
|
@ -48,15 +48,16 @@ endif
|
|||||||
SRC += $(OPSYSTEM)/main.c
|
SRC += $(OPSYSTEM)/main.c
|
||||||
SRC += $(OPSYSTEM)/pios_board.c
|
SRC += $(OPSYSTEM)/pios_board.c
|
||||||
SRC += $(OPSYSTEM)/pios_usb_board_data.c
|
SRC += $(OPSYSTEM)/pios_usb_board_data.c
|
||||||
SRC += $(OPSYSTEM)/op_dfu.c
|
|
||||||
|
|
||||||
## PIOS Hardware (Common)
|
## PIOS Hardware (Common)
|
||||||
SRC += $(PIOSCOMMON)/pios_board_info.c
|
SRC += $(PIOSCOMMON)/pios_board_info.c
|
||||||
SRC += $(PIOSCOMMON)/pios_com_msg.c
|
SRC += $(PIOSCOMMON)/pios_com_msg.c
|
||||||
|
SRC += $(PIOSCOMMON)/pios_iap.c
|
||||||
SRC += $(PIOSCOMMON)/pios_usb_desc_hid_only.c
|
SRC += $(PIOSCOMMON)/pios_usb_desc_hid_only.c
|
||||||
SRC += $(PIOSCOMMON)/pios_usb_util.c
|
SRC += $(PIOSCOMMON)/pios_usb_util.c
|
||||||
|
|
||||||
## Misc library functions
|
## Misc library functions
|
||||||
|
SRC += $(FLIGHTLIB)/op_dfu.c
|
||||||
SRC += $(FLIGHTLIB)/printf-stdarg.c
|
SRC += $(FLIGHTLIB)/printf-stdarg.c
|
||||||
|
|
||||||
# List C source files here which must be compiled in ARM-Mode (no -mthumb).
|
# List C source files here which must be compiled in ARM-Mode (no -mthumb).
|
||||||
|
Loading…
Reference in New Issue
Block a user