1
0
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:
edouard 2010-12-19 14:42:47 +00:00 committed by edouard
parent 1aa6a206db
commit 1ef88e854b
5 changed files with 122 additions and 48 deletions

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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 &quot;Boot&quot; (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; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;To upgrade the firmware in your boards, proceed as follows:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- Connect telemetry in USB mode&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- Connect telemetry&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- Once telemetry is running, press &amp;quot;Halt&amp;quot; above&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- You will get a list of devices.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- You can then upload/download to/from each board as you wish&lt;/p&gt;
@ -161,7 +171,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Please connect your board through USB for firmware upload.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</widget>

View File

@ -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))
{

View File

@ -74,6 +74,7 @@ private:
bool resetOnly;
void log(QString str);
void clearLog();
QString getPortDevice(const QString &friendName);
QLineEdit* openFileNameLE;