mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
OP-214 SSP protocol now implemented on the Uploader gadget, and board halt/reboot is now tested and working. Not tried an actual firmware flash yet, but if you do, please report (should work).
I have done my best to make the interface foolproof, by only enabling the relevant buttons in the relevant situations, please let me know if this creates trouble in some use-cases I have overlooked... git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2254 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
1aa6a206db
commit
1ef88e854b
@ -537,7 +537,7 @@ uint16_t qssp::sf_CheckTimeout()
|
||||
}
|
||||
if(retval)
|
||||
if (debug)
|
||||
qDebug()<<"timeout"<<current_time<<thisport->timeout;
|
||||
qDebug()<<"timeout "<<current_time<<thisport->timeout;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,11 @@ using namespace OP_DFU;
|
||||
|
||||
DFUObject::DFUObject(bool _debug,bool _use_serial,QString portname): debug(_debug),use_serial(_use_serial),mready(true)
|
||||
{
|
||||
info = NULL;
|
||||
|
||||
qRegisterMetaType<OP_DFU::Status>("Status");
|
||||
if(use_serial)
|
||||
{
|
||||
// cout<<"Connect hw now and press any key";
|
||||
// getch();
|
||||
// delay::msleep(2000);
|
||||
PortSettings settings;
|
||||
settings.BaudRate=BAUD57600;
|
||||
settings.DataBits=DATA_8;
|
||||
@ -57,20 +55,25 @@ DFUObject::DFUObject(bool _debug,bool _use_serial,QString portname): debug(_debu
|
||||
info->timeoutLen = 1000;
|
||||
if(info->status()!=port::open)
|
||||
{
|
||||
cout<<"Could not open serial port\n";
|
||||
mready=false;
|
||||
cout << "Could not open serial port\n";
|
||||
mready = false;
|
||||
return;
|
||||
}
|
||||
serialhandle=new qsspt(info,debug);
|
||||
serialhandle = new qsspt(info,debug);
|
||||
|
||||
while(serialhandle->ssp_Synchronise()==false)
|
||||
int count = 0;
|
||||
while((serialhandle->ssp_Synchronise()==false) && (count < 10))
|
||||
{
|
||||
if (debug)
|
||||
qDebug()<<"SYNC failed, resending";
|
||||
count++;
|
||||
}
|
||||
if (count == 10) {
|
||||
mready = false;
|
||||
return;
|
||||
}
|
||||
qDebug() << "SYNC Succeded";
|
||||
serialhandle->start();
|
||||
// serialhandle->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -93,7 +96,12 @@ DFUObject::DFUObject(bool _debug,bool _use_serial,QString portname): debug(_debu
|
||||
|
||||
DFUObject::~DFUObject()
|
||||
{
|
||||
hidHandle.close(0);
|
||||
if (use_serial) {
|
||||
if (mready)
|
||||
delete serialhandle;
|
||||
} else {
|
||||
hidHandle.close(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,10 @@ through serial or USB)</string>
|
||||
<property name="toolTip">
|
||||
<string>Boots the system.
|
||||
Only useful if the system is halted
|
||||
(mainboard blue LED blinking slowly, orange LED off)</string>
|
||||
(mainboard blue LED blinking slowly, orange LED off)
|
||||
|
||||
If telemetry is not running, select the link using the dropdown
|
||||
menu on the right.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Boot</string>
|
||||
@ -66,7 +69,9 @@ through serial or USB)</string>
|
||||
<widget class="QPushButton" name="rescueButton">
|
||||
<property name="toolTip">
|
||||
<string>Start a guided procedure to manually
|
||||
recover a system which does not boot.</string>
|
||||
recover a system which does not boot.
|
||||
|
||||
Rescue is possible in USB mode only.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rescue</string>
|
||||
@ -89,7 +94,12 @@ recover a system which does not boot.</string>
|
||||
<item>
|
||||
<widget class="QComboBox" name="telemetryLink">
|
||||
<property name="toolTip">
|
||||
<string>When telemetry is not connected, select the communication method using this combo box.</string>
|
||||
<string>When telemetry is not connected, select the communication
|
||||
method using this combo box.
|
||||
|
||||
You can use this to force a communication channel when doing
|
||||
a "Boot" (button on the left). It is updated automatically when
|
||||
halting a running board.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -141,7 +151,7 @@ p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; 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="-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=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Connect telemetry in USB mode</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;">- 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;">- 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;">- You can then upload/download to/from each board as you wish</p>
|
||||
@ -161,7 +171,7 @@ p, li { white-space: pre-wrap; }
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; 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;"><span style=" font-weight:600;">Please connect your board through USB for firmware upload.</span></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;"></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -26,6 +26,8 @@
|
||||
*/
|
||||
#include "uploadergadgetwidget.h"
|
||||
|
||||
#define DFU_DEBUG true
|
||||
|
||||
UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_config = new Ui_UploaderWidget();
|
||||
@ -89,6 +91,20 @@ void UploaderGadgetWidget::getSerialPorts()
|
||||
}
|
||||
|
||||
|
||||
QString UploaderGadgetWidget::getPortDevice(const QString &friendName)
|
||||
{
|
||||
QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
|
||||
foreach( QextPortInfo port, ports ) {
|
||||
if(port.friendName == friendName)
|
||||
#ifdef Q_OS_WIN
|
||||
return port.portName;
|
||||
#else
|
||||
return port.physName;
|
||||
#endif
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enables widget buttons if autopilot connected
|
||||
@ -96,6 +112,9 @@ void UploaderGadgetWidget::getSerialPorts()
|
||||
void UploaderGadgetWidget::onAutopilotConnect(){
|
||||
m_config->haltButton->setEnabled(true);
|
||||
m_config->resetButton->setEnabled(true);
|
||||
m_config->bootButton->setEnabled(false);
|
||||
m_config->rescueButton->setEnabled(false);
|
||||
m_config->telemetryLink->setEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,6 +123,9 @@ void UploaderGadgetWidget::onAutopilotConnect(){
|
||||
void UploaderGadgetWidget::onAutopilotDisconnect(){
|
||||
m_config->haltButton->setEnabled(false);
|
||||
m_config->resetButton->setEnabled(false);
|
||||
m_config->bootButton->setEnabled(true);
|
||||
m_config->rescueButton->setEnabled(true);
|
||||
m_config->telemetryLink->setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
@ -161,16 +183,22 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
|
||||
case IAP_STEP_RESET:
|
||||
{
|
||||
currentStep = IAP_STATE_READY;
|
||||
if (success) {
|
||||
log("Oops, unexpected success step 3");
|
||||
if (!success) {
|
||||
log("Oops, failure step 3");
|
||||
log("Reset did NOT happen");
|
||||
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
|
||||
break;
|
||||
}
|
||||
// The board is now reset: we have to disconnect telemetry
|
||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||
QString dli = cm->getCurrentDevice().devName;
|
||||
QString dlj = cm->getCurrentDevice().displayedName;
|
||||
cm->disconnectDevice();
|
||||
log("Board Reset");
|
||||
if (dlj.startsWith("USB"))
|
||||
m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText("USB"));
|
||||
else
|
||||
m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText(dli));
|
||||
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
|
||||
@ -183,9 +211,16 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
|
||||
cnx->suspendPolling();
|
||||
|
||||
// Tell the mainboard to get into bootloader state:
|
||||
log("Going into Bootloader mode...");
|
||||
if (!dfu)
|
||||
dfu = new DFUObject(false, false, QString());
|
||||
log("Going into Bootloader mode, please wait 5 seconds...");
|
||||
this->repaint();
|
||||
delay::msleep(5000); // Required to let the board settle, otherwise we
|
||||
// get garbage on the USB HID pipe for the 1st request. Why ???
|
||||
if (!dfu) {
|
||||
if (dlj.startsWith("USB"))
|
||||
dfu = new DFUObject(DFU_DEBUG, false, QString());
|
||||
else
|
||||
dfu = new DFUObject(DFU_DEBUG,true, getPortDevice(dli));
|
||||
}
|
||||
dfu->AbortOperation();
|
||||
if(!dfu->enterDFU(0))
|
||||
{
|
||||
@ -210,9 +245,12 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
|
||||
dw->populate();
|
||||
m_config->systemElements->addTab(dw, QString("Device") + QString::number(i));
|
||||
}
|
||||
/* (done already by autopilot disconnect signal)
|
||||
m_config->haltButton->setEnabled(false);
|
||||
m_config->resetButton->setEnabled(false);
|
||||
//m_config->bootButton->setEnabled(true);
|
||||
m_config->bootButton->setEnabled(true);
|
||||
*/
|
||||
m_config->telemetryLink->setEnabled(false);
|
||||
m_config->rescueButton->setEnabled(false);
|
||||
}
|
||||
break;
|
||||
@ -241,41 +279,58 @@ void UploaderGadgetWidget::systemReset()
|
||||
*/
|
||||
void UploaderGadgetWidget::systemBoot()
|
||||
{
|
||||
if (currentStep == IAP_STATE_BOOTLOADER) {
|
||||
clearLog();
|
||||
if (!dfu)
|
||||
dfu = new DFUObject(true, false, QString());
|
||||
dfu->AbortOperation();
|
||||
if(!dfu->enterDFU(0))
|
||||
{
|
||||
log("Could not enter DFU mode.");
|
||||
return;
|
||||
}
|
||||
log("Booting system...");
|
||||
dfu->JumpToApp();
|
||||
currentStep = IAP_STATE_READY;
|
||||
// Restart the polling thread
|
||||
clearLog();
|
||||
if (currentStep != IAP_STATE_BOOTLOADER) {
|
||||
log("Did not go into bootloader from this interface");
|
||||
log("I assume you know what you're doing...");
|
||||
this->repaint();
|
||||
// Stop the polling thread just in case (really necessary)
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
RawHIDConnection *cnx = pm->getObject<RawHIDConnection>();
|
||||
cnx->resumePolling();
|
||||
// m_config->bootButton->setEnabled(false);
|
||||
m_config->haltButton->setEnabled(true);
|
||||
m_config->resetButton->setEnabled(true);
|
||||
m_config->rescueButton->setEnabled(true);
|
||||
m_config->boardStatus->setText("Running");
|
||||
cnx->suspendPolling();
|
||||
}
|
||||
|
||||
QString devName = m_config->telemetryLink->currentText();
|
||||
|
||||
if (!dfu) {
|
||||
if (devName == "USB")
|
||||
dfu = new DFUObject(DFU_DEBUG, false, QString());
|
||||
else
|
||||
dfu = new DFUObject(DFU_DEBUG,true,getPortDevice(devName));
|
||||
}
|
||||
dfu->AbortOperation();
|
||||
if(!dfu->enterDFU(0))
|
||||
{
|
||||
log("Could not enter DFU mode.");
|
||||
delete dfu;
|
||||
dfu = NULL;
|
||||
return;
|
||||
}
|
||||
log("Booting system...");
|
||||
dfu->JumpToApp();
|
||||
// Restart the polling thread
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
RawHIDConnection *cnx = pm->getObject<RawHIDConnection>();
|
||||
cnx->resumePolling();
|
||||
// m_config->bootButton->setEnabled(false);
|
||||
//m_config->haltButton->setEnabled(true);
|
||||
//m_config->resetButton->setEnabled(true);
|
||||
m_config->rescueButton->setEnabled(true);
|
||||
m_config->telemetryLink->setEnabled(true);
|
||||
m_config->boardStatus->setText("Running");
|
||||
if (currentStep == IAP_STATE_BOOTLOADER) {
|
||||
// Freeze the tabs, they are not useful anymore and their buttons
|
||||
// will cause segfaults or weird stuff if we use them.
|
||||
for (int i=0; i< m_config->systemElements->count(); i++) {
|
||||
deviceWidget *qw = (deviceWidget*)m_config->systemElements->widget(i);
|
||||
qw->freeze();
|
||||
}
|
||||
|
||||
delete dfu;
|
||||
dfu = NULL;
|
||||
|
||||
} else {
|
||||
log("Not in bootloader mode!");
|
||||
}
|
||||
currentStep = IAP_STATE_READY;
|
||||
log("You can now reconnect telemetry...");
|
||||
delete dfu;
|
||||
dfu = NULL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,7 +382,7 @@ void UploaderGadgetWidget::systemRescue()
|
||||
case RESCUE_STEP3:
|
||||
log("... Detecting Mainboard...");
|
||||
repaint();
|
||||
dfu = new DFUObject(true, false, QString());
|
||||
dfu = new DFUObject(DFU_DEBUG, false, QString());
|
||||
dfu->AbortOperation();
|
||||
if(!dfu->enterDFU(0))
|
||||
{
|
||||
|
@ -74,6 +74,7 @@ private:
|
||||
bool resetOnly;
|
||||
void log(QString str);
|
||||
void clearLog();
|
||||
QString getPortDevice(const QString &friendName);
|
||||
|
||||
QLineEdit* openFileNameLE;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user