1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-05 21:52:10 +01:00

OP-21/Bootloader CLI- New version to be used with the new BL FW. Linux and MacOs Devs please test it, I'm having probs using serial port in unbuffered mode under Linux VM. I'm hoping its just a VM problem.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2212 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
zedamota 2010-12-10 19:16:09 +00:00 committed by zedamota
parent cc5a4c2bb9
commit eb01c55478
11 changed files with 584 additions and 317 deletions

View File

@ -15,39 +15,61 @@ int main(int argc, char *argv[])
port * info; port * info;
PortSettings settings; PortSettings settings;
settings.BaudRate=BAUD19200; settings.BaudRate=BAUD57600;
settings.DataBits=DATA_8; settings.DataBits=DATA_8;
settings.FlowControl=FLOW_OFF; settings.FlowControl=FLOW_OFF;
settings.Parity=PAR_NONE; settings.Parity=PAR_NONE;
settings.StopBits=STOP_2; settings.StopBits=STOP_1;
settings.Timeout_Millisec=500; settings.Timeout_Millisec=5000;
info=new port(settings,"COM2"); info=new port(settings,"COM3");
info->rxBuf = sspRxBuf; info->rxBuf = sspRxBuf;
info->rxBufSize = MAX_PACKET_DATA_LEN; info->rxBufSize = MAX_PACKET_DATA_LEN;
info->txBuf = sspTxBuf; info->txBuf = sspTxBuf;
info->txBufSize = 255; info->txBufSize = 255;
info->max_retry = 3; info->max_retry = 3;
info->timeoutLen = 100; info->timeoutLen = 5000;
//qssp b(info); //qssp b(info);
qsspt bb(info); qsspt bb(info);
uint8_t buf[1000];
QCoreApplication a(argc, argv); QCoreApplication a(argc, argv);
QByteArray arr; while(!bb.ssp_Synchronise())
while(true)
{ {
qDebug()<<"trying sync";
}
bb.start();
qDebug()<<"sync complete";
buf[0]=0;
buf[1]=1;
buf[2]=2;
while(true)
{
if(bb.sendData(buf,63))
qDebug()<<"send OK";
// else
// qDebug()<<"send NOK";
// //bb.ssp_SendData(buf,63);
}
while(true)
{
if(bb.packets_Available()>0) if(bb.packets_Available()>0)
{ {
arr=bb.read_Packet();
qDebug()<<"receive="<<(int)arr[0]<<(int)arr[1]<<(int)arr[2];
}
// b.ssp_ReceiveProcess(); bb.read_Packet(buf);
// b.ssp_SendProcess(); qDebug()<<"receive="<<(int)buf[0]<<(int)buf[1]<<(int)buf[2];
// if(b.isDataAvailable()) ++buf[0];
// { ++buf[1];
// QByteArray bb=b.readData(); ++buf[2];
// qDebug()<<bb[0]<<bb[1]<<bb[2]; //bb.ssp_SendData(buf,63);
// } bb.sendData(buf,63);
}
//bb.ssp_ReceiveProcess();
//bb.ssp_SendProcess();
} }
return a.exec(); return a.exec();
} }

View File

@ -1,29 +1,38 @@
#include "port.h" #include "port.h"
#include "..\delay.h"
port::port(PortSettings settings,QString name) port::port(PortSettings settings,QString name):mstatus(port::closed)
{ {
timer.start(); timer.start();
sport = new QextSerialPort(name,settings, QextSerialPort::Polling); sport = new QextSerialPort(name,settings, QextSerialPort::Polling);
sport->open(QIODevice::ReadWrite | QIODevice::Unbuffered); if(sport->open(QIODevice::ReadWrite|QIODevice::Unbuffered))
{
mstatus=port::open;
// sport->setDtr();
}
else
mstatus=port::error;
}
port::portstatus port::status()
{
return mstatus;
} }
int16_t port::pfSerialRead(void) int16_t port::pfSerialRead(void)
{ {
char c[1]; char c[1];
if(sport->bytesAvailable()>0) if(sport->bytesAvailable())
{ {
sport->read(c,1); sport->read(c,1);
} }
else return -1; else return -1;
//qDebug()<<"read="<<c[0]; return (uint8_t)c[0];
return c[0];
} }
void port::pfSerialWrite(uint8_t c) void port::pfSerialWrite(uint8_t c)
{ {
char cc[1]; char cc[1];
cc[0]=c; cc[0]=c;
while (sport->write(cc,1)==-1){}; sport->write(cc,1);
} }
uint32_t port::pfGetTime(void) uint32_t port::pfGetTime(void)

View File

@ -9,7 +9,7 @@
class port class port
{ {
public: public:
enum portstatus{open,closed,error};
virtual int16_t pfSerialRead(void); // function to read a character from the serial input stream virtual int16_t pfSerialRead(void); // function to read a character from the serial input stream
virtual void pfSerialWrite( uint8_t ); // function to write a byte to be sent out the serial port virtual void pfSerialWrite( uint8_t ); // function to write a byte to be sent out the serial port
virtual uint32_t pfGetTime(void); virtual uint32_t pfGetTime(void);
@ -38,7 +38,9 @@ public:
uint32_t TxError; uint32_t TxError;
uint16_t flags; uint16_t flags;
port(PortSettings settings,QString name); port(PortSettings settings,QString name);
portstatus status();
private: private:
portstatus mstatus;
QTime timer; QTime timer;
QextSerialPort *sport; QextSerialPort *sport;
}; };

View File

@ -11,7 +11,7 @@
#define ESC 224 // ESC character used in Serial Protocol #define ESC 224 // ESC character used in Serial Protocol
#define ESC_SYNC 1 // ESC_SYNC character used in Serial Protocol #define ESC_SYNC 1 // ESC_SYNC character used in Serial Protocol
#define ACK_BIT 0x80 // Ack bit, bit 7 of sequence number, 1 = Acknowledge, 0 = #define ACK_BIT 0x80 // Ack bit, bit 7 of sequence number, 1 = Acknowledge, 0 =
// new packet // new packet
// packet location definitions. // packet location definitions.
#define LENGTH 0 #define LENGTH 0
#define SEQNUM 1 #define SEQNUM 1
@ -84,7 +84,7 @@ static const uint16_t CRC_TABLE[] = {
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
}; };
/** EXTERNAL DATA **/ /** EXTERNAL DATA **/
@ -110,16 +110,22 @@ void qssp::ssp_Init(const PortConfig_t* const info)
thisport->maxRetryCount = info->max_retry; thisport->maxRetryCount = info->max_retry;
thisport->timeoutLen = info->timeoutLen; thisport->timeoutLen = info->timeoutLen;
thisport->txBufSize = info->txBufSize; thisport->txBufSize = info->txBufSize;
thisport->rxBufSize = info->rxBufSize; thisport->rxBufSize = info->rxBufSize;
thisport->txBuf = info->txBuf; thisport->txBuf = info->txBuf;
thisport->rxBuf = info->rxBuf; thisport->rxBuf = info->rxBuf;
thisport->retryCount = 0; thisport->retryCount = 0;
thisport->sendSynch = FALSE; //TRUE; thisport->sendSynch = FALSE; //TRUE;
thisport->rxSeqNo = 255; thisport->rxSeqNo = 255;
thisport->txSeqNo = 255; thisport->txSeqNo = 255;
thisport->SendState = SSP_IDLE; thisport->SendState = SSP_IDLE;
thisport->InputState =(ReceiveState)0;
thisport->DecodeState =(decodeState_)0;
thisport->TxError =0;
thisport->RxError =0;
thisport->txSeqNo =0;
thisport->rxSeqNo =0;
} }
/*! /*!
@ -135,33 +141,35 @@ void qssp::ssp_Init(const PortConfig_t* const info)
*/ */
int16_t qssp::ssp_SendProcess( ) int16_t qssp::ssp_SendProcess( )
{ {
int16_t value = SSP_TX_WAITING; int16_t value = SSP_TX_WAITING;
if (thisport->SendState == SSP_AWAITING_ACK ) { if (thisport->SendState == SSP_AWAITING_ACK ) {
if (sf_CheckTimeout() == TRUE) { if (sf_CheckTimeout() == TRUE) {
if (thisport->retryCount < thisport->maxRetryCount) { if (thisport->retryCount < thisport->maxRetryCount) {
// Try again // Try again
sf_SendPacket(); sf_SendPacket();
sf_SetSendTimeout(); sf_SetSendTimeout();
value = SSP_TX_WAITING; value = SSP_TX_WAITING;
} else { } else {
// Give up, # of trys has exceded the limit // Give up, # of trys has exceded the limit
value = SSP_TX_TIMEOUT; value = SSP_TX_TIMEOUT;
CLEARBIT( thisport->flags, ACK_RECEIVED); CLEARBIT( thisport->flags, ACK_RECEIVED);
thisport->SendState = SSP_IDLE; thisport->SendState = SSP_IDLE;
} if (debug)
} else { qDebug()<<"Send TimeOut!";
value = SSP_TX_WAITING; }
} } else {
value = SSP_TX_WAITING;
}
} else if( thisport->SendState == SSP_ACKED ) { } else if( thisport->SendState == SSP_ACKED ) {
SETBIT( thisport->flags, ACK_RECEIVED); SETBIT( thisport->flags, ACK_RECEIVED);
value = SSP_TX_ACKED; value = SSP_TX_ACKED;
thisport->SendState = SSP_IDLE; thisport->SendState = SSP_IDLE;
} else { } else {
thisport->SendState = SSP_IDLE; thisport->SendState = SSP_IDLE;
value = SSP_TX_IDLE; value = SSP_TX_IDLE;
} }
return value; return value;
} }
/*! /*!
@ -174,17 +182,18 @@ int16_t qssp::ssp_SendProcess( )
*/ */
int16_t qssp::ssp_ReceiveProcess() int16_t qssp::ssp_ReceiveProcess()
{ {
int16_t b; int16_t b;
int16_t packet_status = SSP_RX_IDLE; int16_t packet_status = SSP_RX_IDLE;
do { do {
b = thisport->pfSerialRead(); // attempt to read a char from the serial buffer b = thisport->pfSerialRead(); // attempt to read a char from the serial buffer
if (b != -1) { if (b != -1) {
packet_status = sf_ReceiveState(b); // process the newly received byte in the receive state machine packet_status = sf_ReceiveState(b); // process the newly received byte in the receive state machine
} }
// keep going until either we received a full packet or there are no more bytes to process // keep going until either we received a full packet or there are no more bytes to process
} while (packet_status != SSP_RX_COMPLETE && b != -1); } while (packet_status != SSP_RX_COMPLETE && b != -1);
return packet_status;
return packet_status;
} }
/*! /*!
@ -225,8 +234,8 @@ uint16_t qssp::ssp_SendDataBlock(uint8_t *data, uint16_t length )
uint16_t retval = FALSE; uint16_t retval = FALSE;
packet_status = ssp_SendData(data, length ); // send the data packet_status = ssp_SendData(data, length ); // send the data
while( packet_status == SSP_TX_WAITING ) { // check the status while( packet_status == SSP_TX_WAITING ) { // check the status
(void)ssp_ReceiveProcess(); // process any bytes received. (void)ssp_ReceiveProcess(); // process any bytes received.
packet_status = ssp_SendProcess(); // check the send status packet_status = ssp_SendProcess(); // check the send status
} }
if( packet_status == SSP_TX_ACKED ) { // figure out what happened to the packet if( packet_status == SSP_TX_ACKED ) { // figure out what happened to the packet
@ -278,7 +287,7 @@ int16_t qssp::ssp_SendData(const uint8_t *data, const uint16_t length )
thisport->txSeqNo++; // update the sequence number. thisport->txSeqNo++; // update the sequence number.
if( thisport->txSeqNo > 0x7F) { // check for sequence number rollover if( thisport->txSeqNo > 0x7F) { // check for sequence number rollover
thisport->txSeqNo = 1; // if we do have rollover then reset to 1 not zero, thisport->txSeqNo = 1; // if we do have rollover then reset to 1 not zero,
// zero is reserviced for synchronization requests // zero is reserviced for synchronization requests
} }
} }
@ -287,19 +296,23 @@ int16_t qssp::ssp_SendData(const uint8_t *data, const uint16_t length )
thisport->txSeqNo++; // update the sequence number. thisport->txSeqNo++; // update the sequence number.
if( thisport->txSeqNo > 0x7F) { // check for sequence number rollover if( thisport->txSeqNo > 0x7F) { // check for sequence number rollover
thisport->txSeqNo = 1; // if we do have rollover then reset to 1 not zero, thisport->txSeqNo = 1; // if we do have rollover then reset to 1 not zero,
// zero is reserved for synchronization requests // zero is reserved for synchronization requests
} }
#endif #endif
CLEARBIT( thisport->flags, ACK_RECEIVED); CLEARBIT( thisport->flags, ACK_RECEIVED);
thisport->SendState = SSP_AWAITING_ACK; thisport->SendState = SSP_AWAITING_ACK;
value = SSP_TX_WAITING; value = SSP_TX_WAITING;
thisport->retryCount = 0; // zero out the retry counter for this transmission thisport->retryCount = 0; // zero out the retry counter for this transmission
sf_MakePacket( thisport->txBuf, data, length, thisport->txSeqNo ); sf_MakePacket( thisport->txBuf, data, length, thisport->txSeqNo );
sf_SendPacket( ); // punch out the packet to the serial port sf_SendPacket( ); // punch out the packet to the serial port
sf_SetSendTimeout( ); // do the timeout values sf_SetSendTimeout( ); // do the timeout values
if (debug)
qDebug()<<"Sent DATA PACKET:"<<thisport->txSeqNo;
} else { } else {
// error we are already sending a packet. Need to wait for the current packet to be acked or timeout. // error we are already sending a packet. Need to wait for the current packet to be acked or timeout.
value = SSP_TX_BUSY; value = SSP_TX_BUSY;
if (debug)
qDebug()<<"Error sending TX was busy";
} }
return value; return value;
} }
@ -335,8 +348,8 @@ uint16_t qssp::ssp_Synchronise( )
#else #else
packet_status = ssp_SendData( NULL, 0 ); packet_status = ssp_SendData( NULL, 0 );
#endif #endif
while( packet_status == SSP_TX_WAITING ) { // we loop until we time out. while( packet_status == SSP_TX_WAITING ) { // we loop until we time out.
(void)ssp_ReceiveProcess( ); // do the receive process (void)ssp_ReceiveProcess( ); // do the receive process
packet_status = ssp_SendProcess( ); // do the send process packet_status = ssp_SendProcess( ); // do the send process
} }
thisport->sendSynch = FALSE; thisport->sendSynch = FALSE;
@ -366,14 +379,14 @@ uint16_t qssp::ssp_Synchronise( )
* Packet should be formed through the use of sf_MakePacket before calling this function. * Packet should be formed through the use of sf_MakePacket before calling this function.
*/ */
void qssp::sf_SendPacket() void qssp::sf_SendPacket()
{ {
// add 3 to packet data length for: 1 length + 2 CRC (packet overhead) // add 3 to packet data length for: 1 length + 2 CRC (packet overhead)
uint8_t packetLen = thisport->txBuf[LENGTH] + 3; uint8_t packetLen = thisport->txBuf[LENGTH] + 3;
// use the raw serial write function so the SYNC byte does not get 'escaped' // use the raw serial write function so the SYNC byte does not get 'escaped'
thisport->pfSerialWrite(SYNC); thisport->pfSerialWrite(SYNC);
for( uint8_t x = 0; x < packetLen; x++ ) { for( uint8_t x = 0; x < packetLen; x++ ) {
sf_write_byte(thisport->txBuf[x] ); sf_write_byte(thisport->txBuf[x] );
} }
thisport->retryCount++; thisport->retryCount++;
} }
@ -434,6 +447,8 @@ void qssp::sf_SendAckPacket(uint8_t seqNumber)
// create the packet, note we pass AckSequenceNumber directly // create the packet, note we pass AckSequenceNumber directly
sf_MakePacket( thisport->txBuf, NULL, 0, AckSeqNumber ); sf_MakePacket( thisport->txBuf, NULL, 0, AckSeqNumber );
sf_SendPacket( ); sf_SendPacket( );
if (debug)
qDebug()<<"Sent ACK PACKET:"<<seqNumber;
// we don't set the timeout for an ACK because we don't ACK our ACKs in this protocol // we don't set the timeout for an ACK because we don't ACK our ACKs in this protocol
} }
@ -448,15 +463,15 @@ void qssp::sf_SendAckPacket(uint8_t seqNumber)
*/ */
void qssp::sf_write_byte(uint8_t c ) void qssp::sf_write_byte(uint8_t c )
{ {
if( c == SYNC ) { // check for SYNC byte if( c == SYNC ) { // check for SYNC byte
thisport->pfSerialWrite( ESC ); // since we are not starting a packet we must ESCAPE the SYNCH byte thisport->pfSerialWrite( ESC ); // since we are not starting a packet we must ESCAPE the SYNCH byte
thisport->pfSerialWrite( ESC_SYNC ); // now send the escaped synch char thisport->pfSerialWrite( ESC_SYNC ); // now send the escaped synch char
} else if( c == ESC ) { // Check for ESC character } else if( c == ESC ) { // Check for ESC character
thisport->pfSerialWrite( ESC ); // if it is, we need to send it twice thisport->pfSerialWrite( ESC ); // if it is, we need to send it twice
thisport->pfSerialWrite( ESC ); thisport->pfSerialWrite( ESC );
} else { } else {
thisport->pfSerialWrite( c ); // otherwise write the byte to serial port thisport->pfSerialWrite( c ); // otherwise write the byte to serial port
} }
} }
/************************************************************************************************************ /************************************************************************************************************
@ -482,7 +497,7 @@ void qssp::sf_write_byte(uint8_t c )
uint16_t qssp::sf_crc16( uint16_t crc, uint8_t data ) uint16_t qssp::sf_crc16( uint16_t crc, uint8_t data )
{ {
return (crc >> 8) ^ CRC_TABLE[( crc ^ data ) & 0x00FF ]; return (crc >> 8) ^ CRC_TABLE[( crc ^ data ) & 0x00FF ];
} }
@ -499,7 +514,7 @@ void qssp::sf_SetSendTimeout()
{ {
uint32_t timeout; uint32_t timeout;
timeout = thisport->pfGetTime() + thisport->timeoutLen; timeout = thisport->pfGetTime() + thisport->timeoutLen;
thisport->timeout = timeout; thisport->timeout = timeout;
} }
/*! /*!
@ -520,6 +535,9 @@ uint16_t qssp::sf_CheckTimeout()
if( current_time > thisport->timeout ) { if( current_time > thisport->timeout ) {
retval = TRUE; retval = TRUE;
} }
if(retval)
if (debug)
qDebug()<<"timeout"<<current_time<<thisport->timeout;
return retval; return retval;
} }
@ -545,32 +563,32 @@ uint16_t qssp::sf_CheckTimeout()
*/ */
int16_t qssp::sf_ReceiveState(uint8_t c ) int16_t qssp::sf_ReceiveState(uint8_t c )
{ {
int16_t retval = SSP_RX_RECEIVING; int16_t retval = SSP_RX_RECEIVING;
switch( thisport->InputState ) { switch( thisport->InputState ) {
case state_unescaped_e: case state_unescaped_e:
if( c == SYNC ) { if( c == SYNC ) {
thisport->DecodeState = decode_len1_e; thisport->DecodeState = decode_len1_e;
} else if ( c == ESC ) { } else if ( c == ESC ) {
thisport->InputState = state_escaped_e; thisport->InputState = state_escaped_e;
} else { } else {
retval = sf_DecodeState(c); retval = sf_DecodeState(c);
}
break; // end of unescaped state.
case state_escaped_e:
thisport->InputState = state_unescaped_e;
if( c == SYNC ) {
thisport->DecodeState = decode_len1_e;
} else if (c == ESC_SYNC ) {
retval = sf_DecodeState(SYNC);
} else {
retval = sf_DecodeState(c);
}
break; // end of the escaped state.
default:
break;
} }
return retval; break; // end of unescaped state.
case state_escaped_e:
thisport->InputState = state_unescaped_e;
if( c == SYNC ) {
thisport->DecodeState = decode_len1_e;
} else if (c == ESC_SYNC ) {
retval = sf_DecodeState(SYNC);
} else {
retval = sf_DecodeState(c);
}
break; // end of the escaped state.
default:
break;
}
return retval;
} }
/**************************************************************************** /****************************************************************************
@ -595,69 +613,69 @@ int16_t qssp::sf_ReceiveState(uint8_t c )
*/ */
int16_t qssp::sf_DecodeState( uint8_t c ) int16_t qssp::sf_DecodeState( uint8_t c )
{ {
int16_t retval; int16_t retval;
switch( thisport->DecodeState ) { switch( thisport->DecodeState ) {
case decode_idle_e: case decode_idle_e:
// 'c' is ignored in this state as the only way to leave the idle state is // 'c' is ignored in this state as the only way to leave the idle state is
// recognition of the SYNC byte in the sf_ReceiveState function. // recognition of the SYNC byte in the sf_ReceiveState function.
retval = SSP_RX_IDLE; retval = SSP_RX_IDLE;
break; break;
case decode_len1_e: case decode_len1_e:
thisport->rxBuf[LENGTH]= c; thisport->rxBuf[LENGTH]= c;
thisport->rxBufLen = c; thisport->rxBufLen = c;
if( thisport->rxBufLen <= thisport->rxBufSize ) { if( thisport->rxBufLen <= thisport->rxBufSize ) {
thisport->DecodeState = decode_seqNo_e; thisport->DecodeState = decode_seqNo_e;
retval = SSP_RX_RECEIVING; retval = SSP_RX_RECEIVING;
} else { } else {
thisport->DecodeState = decode_idle_e; thisport->DecodeState = decode_idle_e;
retval = SSP_RX_IDLE; retval = SSP_RX_IDLE;
}
break;
case decode_seqNo_e:
thisport->rxBuf[SEQNUM] = c;
thisport->crc = 0xffff;
thisport->rxBufLen--; // subtract 1 for the seq. no.
thisport->rxBufPos = 2;
thisport->crc = sf_crc16( thisport->crc, c );
if( thisport->rxBufLen > 0 ) {
thisport->DecodeState = decode_data_e;
} else {
thisport->DecodeState = decode_crc1_e;
}
retval = SSP_RX_RECEIVING;
break;
case decode_data_e:
thisport->rxBuf[ (thisport->rxBufPos)++] = c;
thisport->crc = sf_crc16( thisport->crc, c );
if( thisport->rxBufPos == (thisport->rxBufLen+2) ) {
thisport->DecodeState = decode_crc1_e;
}
retval = SSP_RX_RECEIVING;
break;
case decode_crc1_e:
thisport->crc = sf_crc16( thisport->crc, c );
thisport->DecodeState = decode_crc2_e;
retval = SSP_RX_RECEIVING;
break;
case decode_crc2_e:
thisport->DecodeState = decode_idle_e;
// verify the CRC value for the packet
if( sf_crc16( thisport->crc, c) == 0) {
// TODO shouldn't the return value of sf_ReceivePacket() be checked?
sf_ReceivePacket();
retval = SSP_RX_COMPLETE;
} else {
thisport->RxError++;
retval = SSP_RX_IDLE;
}
break;
default:
thisport->DecodeState = decode_idle_e; // unknown state so reset to idle state and wait for the next start of a packet.
retval = SSP_RX_IDLE;
break;
} }
return retval; break;
case decode_seqNo_e:
thisport->rxBuf[SEQNUM] = c;
thisport->crc = 0xffff;
thisport->rxBufLen--; // subtract 1 for the seq. no.
thisport->rxBufPos = 2;
thisport->crc = sf_crc16( thisport->crc, c );
if( thisport->rxBufLen > 0 ) {
thisport->DecodeState = decode_data_e;
} else {
thisport->DecodeState = decode_crc1_e;
}
retval = SSP_RX_RECEIVING;
break;
case decode_data_e:
thisport->rxBuf[ (thisport->rxBufPos)++] = c;
thisport->crc = sf_crc16( thisport->crc, c );
if( thisport->rxBufPos == (thisport->rxBufLen+2) ) {
thisport->DecodeState = decode_crc1_e;
}
retval = SSP_RX_RECEIVING;
break;
case decode_crc1_e:
thisport->crc = sf_crc16( thisport->crc, c );
thisport->DecodeState = decode_crc2_e;
retval = SSP_RX_RECEIVING;
break;
case decode_crc2_e:
thisport->DecodeState = decode_idle_e;
// verify the CRC value for the packet
if( sf_crc16( thisport->crc, c) == 0) {
// TODO shouldn't the return value of sf_ReceivePacket() be checked?
sf_ReceivePacket();
retval = SSP_RX_COMPLETE;
} else {
thisport->RxError++;
retval = SSP_RX_IDLE;
}
break;
default:
thisport->DecodeState = decode_idle_e; // unknown state so reset to idle state and wait for the next start of a packet.
retval = SSP_RX_IDLE;
break;
}
return retval;
} }
/************************************************************************************************************ /************************************************************************************************************
@ -686,58 +704,78 @@ int16_t qssp::sf_DecodeState( uint8_t c )
int16_t qssp::sf_ReceivePacket() int16_t qssp::sf_ReceivePacket()
{ {
int16_t value = FALSE; int16_t value = FALSE;
if( ISBITSET(thisport->rxBuf[SEQNUM], ACK_BIT ) ) { if( ISBITSET(thisport->rxBuf[SEQNUM], ACK_BIT ) ) {
// Received an ACK packet, need to check if it matches the previous sent packet // Received an ACK packet, need to check if it matches the previous sent packet
if( ( thisport->rxBuf[SEQNUM] & 0x7F) == (thisport->txSeqNo & 0x7f)) { if( ( thisport->rxBuf[SEQNUM] & 0x7F) == (thisport->txSeqNo & 0x7f)) {
// It matches the last packet sent by us // It matches the last packet sent by us
SETBIT( thisport->txSeqNo, ACK_BIT ); SETBIT( thisport->txSeqNo, ACK_BIT );
thisport->SendState = SSP_ACKED; thisport->SendState = SSP_ACKED;
value = FALSE; value = FALSE;
} if (debug)
qDebug()<<"Received ACK:"<<(thisport->txSeqNo & 0x7F);
}
// else ignore the ACK packet // else ignore the ACK packet
} else { } else {
// Received a 'data' packet, figure out what type of packet we received... // Received a 'data' packet, figure out what type of packet we received...
if( thisport->rxBuf[SEQNUM] == 0 ) { if( thisport->rxBuf[SEQNUM] == 0 ) {
// Synchronize sequence number with host if (debug)
qDebug()<<"Received SYNC Request";
// Synchronize sequence number with host
#ifdef ACTIVE_SYNCH #ifdef ACTIVE_SYNCH
thisport->sendSynch = TRUE; thisport->sendSynch = TRUE;
#endif #endif
sf_SendAckPacket(thisport->rxBuf[SEQNUM] ); sf_SendAckPacket(thisport->rxBuf[SEQNUM] );
thisport->rxSeqNo = 0; thisport->rxSeqNo = 0;
value = FALSE; value = FALSE;
} else if( thisport->rxBuf[SEQNUM] == thisport->rxSeqNo ) { } else if( thisport->rxBuf[SEQNUM] == thisport->rxSeqNo ) {
// Already seen this packet, just ack it, don't act on the packet. // Already seen this packet, just ack it, don't act on the packet.
sf_SendAckPacket(thisport->rxBuf[SEQNUM] ); sf_SendAckPacket(thisport->rxBuf[SEQNUM] );
value = FALSE; value = FALSE;
} else { } else {
//New Packet //New Packet
thisport->rxSeqNo = thisport->rxBuf[SEQNUM]; thisport->rxSeqNo = thisport->rxBuf[SEQNUM];
// Let the application do something with the data/packet. // Let the application do something with the data/packet.
// skip the first two bytes (length and seq. no.) in the buffer. // skip the first two bytes (length and seq. no.) in the buffer.
pfCallBack( &(thisport->rxBuf[2]), thisport->rxBufLen); if (debug)
qDebug()<<"Received DATA PACKET seq="<<thisport->rxSeqNo<<"Data="<<(uint8_t)thisport->rxBuf[2]<<(uint8_t)thisport->rxBuf[3]<<(uint8_t)thisport->rxBuf[4];
pfCallBack( &(thisport->rxBuf[2]), thisport->rxBufLen);
// after we send the ACK, it is possible for the host to send a new packet. // after we send the ACK, it is possible for the host to send a new packet.
// Thus the application needs to copy the data and reset the receive buffer // Thus the application needs to copy the data and reset the receive buffer
// inside of thisport->pfCallBack() // inside of thisport->pfCallBack()
sf_SendAckPacket(thisport->rxBuf[SEQNUM] ); sf_SendAckPacket(thisport->rxBuf[SEQNUM] );
value = TRUE; value = TRUE;
}
} }
return value; }
return value;
} }
qssp::qssp(port * info) qssp::qssp(port * info,bool debug):debug(debug)
{ {
thisport=info;
thisport->retryCount = 0; thisport=info;
thisport->sendSynch = FALSE; //TRUE; thisport->maxRetryCount = info->max_retry;
thisport->rxSeqNo = 255; thisport->timeoutLen = info->timeoutLen;
thisport->txSeqNo = 255; thisport->txBufSize = info->txBufSize;
thisport->SendState = SSP_IDLE; thisport->rxBufSize = info->rxBufSize;
thisport->txBuf = info->txBuf;
thisport->rxBuf = info->rxBuf;
thisport->retryCount = 0;
thisport->sendSynch = FALSE; //TRUE;
thisport->rxSeqNo = 255;
thisport->txSeqNo = 255;
thisport->SendState = SSP_IDLE;
thisport->InputState =(ReceiveState)0;
thisport->DecodeState =(decodeState_)0;
thisport->TxError =0;
thisport->RxError =0;
thisport->txSeqNo =0;
thisport->rxSeqNo =0;
} }
void qssp::pfCallBack( uint8_t * buf, uint16_t size) void qssp::pfCallBack( uint8_t * buf, uint16_t size)
{ {
qDebug()<<"receive callback"<<buf[0]<<buf[1]<<buf[2]<<buf[3]<<buf[4]; if (debug)
qDebug()<<"receive callback"<<buf[0]<<buf[1]<<buf[2]<<buf[3]<<buf[4];
} }

View File

@ -79,6 +79,7 @@ private:
void sf_MakePacket( uint8_t *buf, const uint8_t * pdata, uint16_t length, uint8_t seqNo ); void sf_MakePacket( uint8_t *buf, const uint8_t * pdata, uint16_t length, uint8_t seqNo );
int16_t sf_ReceivePacket(); int16_t sf_ReceivePacket();
uint16_t ssp_SendDataBlock(uint8_t *data, uint16_t length ); uint16_t ssp_SendDataBlock(uint8_t *data, uint16_t length );
bool debug;
public: public:
/** PUBLIC FUNCTIONS **/ /** PUBLIC FUNCTIONS **/
virtual void pfCallBack( uint8_t *, uint16_t); // call back function that is called when a full packet has been received virtual void pfCallBack( uint8_t *, uint16_t); // call back function that is called when a full packet has been received
@ -89,7 +90,7 @@ public:
void ssp_Init( const PortConfig_t* const info); void ssp_Init( const PortConfig_t* const info);
int16_t ssp_ReceiveByte( ); int16_t ssp_ReceiveByte( );
uint16_t ssp_Synchronise( ); uint16_t ssp_Synchronise( );
qssp(port * info); qssp(port * info,bool debug);
}; };
#endif // QSSP_H #endif // QSSP_H

View File

@ -1,40 +1,72 @@
#include "qsspt.h" #include "qsspt.h"
qsspt::qsspt(port * info):qssp(info),endthread(false) qsspt::qsspt(port * info,bool debug):qssp(info,debug),endthread(false),datapending(false),debug(debug)
{ {
this->start();
} }
void qsspt::run() void qsspt::run()
{ {
while(!endthread) while(!endthread)
{ {
this->ssp_ReceiveProcess(); receivestatus=this->ssp_ReceiveProcess();
this->ssp_SendProcess(); sendstatus=this->ssp_SendProcess();
sendbufmutex.lock();
if(datapending && receivestatus==SSP_TX_IDLE)
{
this->ssp_SendData(mbuf,msize);
datapending=false;
}
sendbufmutex.unlock();
if(sendstatus==SSP_TX_ACKED)
sendwait.wakeAll();
}
} }
bool qsspt::sendData(uint8_t * buf,uint16_t size)
{
if(datapending)
return false;
sendbufmutex.lock();
datapending=true;
mbuf=buf;
msize=size;
sendbufmutex.unlock();
msendwait.lock();
sendwait.wait(&msendwait,100000);
msendwait.unlock();
return true;
} }
void qsspt::pfCallBack( uint8_t * buf, uint16_t size) void qsspt::pfCallBack( uint8_t * buf, uint16_t size)
{ {
//qDebug()<<"receive callback"<<buf[0]<<buf[1]<<buf[2]<<buf[3]<<buf[4]<<"array size="<<queue.count(); if (debug)
qDebug()<<"receive callback"<<buf[0]<<buf[1]<<buf[2]<<buf[3]<<buf[4]<<"array size="<<queue.count();
QByteArray array; QByteArray array;
for(int x=0;x<size;x++) for(int x=0;x<size;x++)
{ {
array.append((char)buf[x]); array.append(buf[x]);
} }
mutex.lock(); mutex.lock();
queue.enqueue(array); queue.enqueue(array);
//queue.enqueue((const char *)&buf); // queue.enqueue((const char *)&buf);
mutex.unlock(); mutex.unlock();
} }
int qsspt::packets_Available() int qsspt::packets_Available()
{ {
return queue.count(); return queue.count();
} }
QByteArray qsspt::read_Packet() int qsspt::read_Packet(void * data)
{ {
mutex.lock(); mutex.lock();
if(queue.size()==0)
{
mutex.unlock();
return -1;
}
QByteArray arr=queue.dequeue(); QByteArray arr=queue.dequeue();
memcpy(data,(uint8_t*)arr.data(),arr.length());
mutex.unlock(); mutex.unlock();
return arr; return arr.length();
} }
qsspt::~qsspt() qsspt::~qsspt()
{ {

View File

@ -4,20 +4,30 @@
#include "qssp.h" #include "qssp.h"
#include <QThread> #include <QThread>
#include <QQueue> #include <QQueue>
#include <QWaitCondition>
class qsspt:private qssp, public QThread class qsspt:public qssp, public QThread
{ {
public: public:
qsspt(port * info); qsspt(port * info,bool debug);
void run(); void run();
int packets_Available(); int packets_Available();
QByteArray read_Packet(); int read_Packet(void *);
~qsspt(); ~qsspt();
bool sendData(uint8_t * buf,uint16_t size);
private: private:
virtual void pfCallBack( uint8_t *, uint16_t); virtual void pfCallBack( uint8_t *, uint16_t);
uint8_t * mbuf;
uint16_t msize;
QQueue<QByteArray> queue; QQueue<QByteArray> queue;
QMutex mutex; QMutex mutex;
QMutex sendbufmutex;
bool datapending;
bool endthread; bool endthread;
uint16_t sendstatus;
uint16_t receivestatus;
QWaitCondition sendwait;
QMutex msendwait;
bool debug;
}; };
#endif // QSSPT_H #endif // QSSPT_H

View File

@ -8,15 +8,26 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
///SSP/////////////////////////////////
/////////////////////////////////////////////
// OP_DFU dfu(false); // OP_DFU dfu(false);
// dfu.test(); // dfu.test();
QCoreApplication a(argc, argv); QCoreApplication a(argc, argv);
// argc=4;
// argv[1]="-ls";
// argv[2]="-t";
// argv[3]="COM3";
if(argc>1||!PRIVATE) if(argc>1||!PRIVATE)
{ {
bool use_serial=false;
bool verify; bool verify;
bool debug=false; bool debug=false;
OP_DFU::Actions action; OP_DFU::Actions action;
QString file; QString file;
QString serialport;
QString description; QString description;
int device=-1; int device=-1;
QStringList args; QStringList args;
@ -44,14 +55,17 @@ int main(int argc, char *argv[])
cout<<"| -r : resets the device |\n"; cout<<"| -r : resets the device |\n";
cout<<"| -j : exits bootloader and jumps to user FW |\n"; cout<<"| -j : exits bootloader and jumps to user FW |\n";
cout<<"| -debug : prints debug information |\n"; cout<<"| -debug : prints debug information |\n";
cout<<"| -t <port> : uses serial port* |\n";
cout<<"| |\n"; cout<<"| |\n";
cout<<"| examples: |\n"; cout<<"| examples: |\n";
cout<<"| |\n"; cout<<"| |\n";
cout<<"| program and verify device #0 |\n"; cout<<"| program and verify device #0 |\n";
cout<<"| OPUploadTool -p c:/OpenPilot.bin -w \"Openpilot Firmware\" -v -d 0 |\n"; cout<<"| OPUploadTool -p c:/OpenPilot.bin -w \"Openpilot Firmware\" -v -d 0 |\n";
cout<<"| |\n"; cout<<"| |\n";
cout<<"| Perform a quick compare of FW in file with FW in device #1 |\n"; cout<<"| Perform a quick compare of FW in file with FW in device #1 |\n";
cout<<"| OPUploadTool -ch c:/OpenPilot2.bin -d 2 |\n"; cout<<"| OPUploadTool -ch c:/OpenPilot2.bin -d 2 |\n";
cout<<"| |\n";
cout<<"| *requires valid user space firmwares already running |\n";
cout<<"|________________________________________________________________________|\n"; cout<<"|________________________________________________________________________|\n";
return 0; return 0;
@ -168,6 +182,14 @@ int main(int argc, char *argv[])
cout<<"wrong parameters"; cout<<"wrong parameters";
return -1; return -1;
} }
if(args.contains(USE_SERIAL))
{
if(args.indexOf(USE_SERIAL)+1<args.length())
{
serialport=(args[args.indexOf(USE_SERIAL)+1]);
use_serial=true;
}
}
if(debug) if(debug)
{ {
qDebug()<<"Action="<<(int)action; qDebug()<<"Action="<<(int)action;
@ -175,10 +197,16 @@ int main(int argc, char *argv[])
qDebug()<<"Device="<<device; qDebug()<<"Device="<<device;
qDebug()<<"Action="<<action; qDebug()<<"Action="<<action;
qDebug()<<"Desctription"<<description; qDebug()<<"Desctription"<<description;
qDebug()<<"Use Serial port"<<use_serial;
if(use_serial)
qDebug()<<"Port Name"<<serialport;
} }
///////////////////////////////////ACTIONS START/////////////////////////////////////////////////// ///////////////////////////////////ACTIONS START///////////////////////////////////////////////////
OP_DFU dfu(debug); OP_DFU dfu(debug,use_serial,serialport);
if(!dfu.ready())
return -1;
dfu.AbortOperation(); dfu.AbortOperation();
if(!dfu.enterDFU(0)) if(!dfu.enterDFU(0))
{ {
@ -294,12 +322,12 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
OP_DFU dfu(true); // OP_DFU dfu(true);
//dfu.findDevices(); // //dfu.findDevices();
dfu.enterDFU(1); // dfu.enterDFU(1);
dfu.UploadFirmware("c:/ahrs.bin",true,1); // dfu.UploadFirmware("c:/ahrs.bin",true,1);
// dfu.UploadDescription("josemanuel"); // // dfu.UploadDescription("josemanuel");
// QString str=dfu.DownloadDescription(12); // // QString str=dfu.DownloadDescription(12);
// dfu.JumpToApp(); // dfu.JumpToApp();
// qDebug()<<"Description="<<str; // qDebug()<<"Description="<<str;
return a.exec(); return a.exec();

View File

@ -2,41 +2,82 @@
#include <cmath> #include <cmath>
#include <qwaitcondition.h> #include <qwaitcondition.h>
#include <QMutex> #include <QMutex>
#include <conio.h>
OP_DFU::OP_DFU(bool _debug): debug(_debug) OP_DFU::OP_DFU(bool _debug,bool _use_serial,QString portname): debug(_debug),use_serial(_use_serial),mready(true)
{ {
send_delay=10; if(use_serial)
use_delay=true;
int numDevices=0;
cout<<"Please connect device now\n";
int count=0;
while(numDevices==0)
{ {
cout<<"."; cout<<"Connect hw now and press any key";
delay::msleep(500); // getch();
numDevices = hidHandle.open(1,0x20a0,0x4117,0,0); //0xff9c,0x0001); // delay::msleep(2000);
if(++count==10) PortSettings settings;
settings.BaudRate=BAUD57600;
settings.DataBits=DATA_8;
settings.FlowControl=FLOW_OFF;
settings.Parity=PAR_NONE;
settings.StopBits=STOP_1;
settings.Timeout_Millisec=1000;
info=new port(settings,portname);
info->rxBuf = sspRxBuf;
info->rxBufSize = MAX_PACKET_DATA_LEN;
info->txBuf = sspTxBuf;
info->txBufSize = MAX_PACKET_DATA_LEN;
info->max_retry = 10;
info->timeoutLen = 1000;
if(info->status()!=port::open)
{ {
cout<<"\r"; cout<<"Could not open serial port\n";
cout<<" "; mready=false;
cout<<"\r"; return;
count=0;
} }
serialhandle=new qsspt(info,debug);
while(serialhandle->ssp_Synchronise()==false)
{
if (debug)
qDebug()<<"SYNC failed, resending";
}
qDebug()<<"SYNC Succeded";
serialhandle->start();
// serialhandle->start();
}
else
{
send_delay=10;
use_delay=true;
int numDevices=0;
cout<<"Please connect device now\n";
int count=0;
while(numDevices==0)
{
cout<<".";
delay::msleep(500);
numDevices = hidHandle.open(1,0x20a0,0x4117,0,0); //0xff9c,0x0001);
if(++count==10)
{
cout<<"\r";
cout<<" ";
cout<<"\r";
count=0;
}
}
if(debug)
qDebug() << numDevices << " device(s) opened";
//sendReset();
} }
if(debug)
qDebug() << numDevices << " device(s) opened";
//sendReset();
} }
void OP_DFU::sendReset(void) void OP_DFU::sendReset(void)
{ {
char b[64]={0x02,0x24,0x3C,0x20,0x17,0x00,0x30,0x76,0x1F,0x40,0x62,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x40,0x2E,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; char b[64]={0x02,0x24,0x3C,0x20,0x17,0x00,0x30,0x76,0x1F,0x40,0x62,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x40,0x2E,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
hidHandle.send(0,b,64,1000); sendData(b,64);
delay::msleep(600); delay::msleep(600);
char bb[64]={0x02,0x24,0x3C,0x20,0x17,0x00,0x30,0x76,0x1F,0x40,0xB9,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0xE8,0x30,0x00,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; char bb[64]={0x02,0x24,0x3C,0x20,0x17,0x00,0x30,0x76,0x1F,0x40,0xB9,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0xE8,0x30,0x00,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
hidHandle.send(0,bb,64,1000); sendData(bb,64);
delay::msleep(600); delay::msleep(600);
char bbb[64]={0x02,0x24,0x3C,0x20,0x17,0x00,0x30,0x76,0x1F,0x40,0x10,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF9,0x61,0x34,0x00,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; char bbb[64]={0x02,0x24,0x3C,0x20,0x17,0x00,0x30,0x76,0x1F,0x40,0x10,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF9,0x61,0x34,0x00,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
hidHandle.send(0,bbb,64,1000); sendData(bbb,64);
} }
bool OP_DFU::SaveByteArrayToFile(QString const & sfile, const QByteArray &array) bool OP_DFU::SaveByteArrayToFile(QString const & sfile, const QByteArray &array)
@ -68,7 +109,7 @@ bool OP_DFU::enterDFU(int const &devNumber)
buf[8] = 1;//DFU Data2 buf[8] = 1;//DFU Data2
buf[9] = 1;//DFU Data3 buf[9] = 1;//DFU Data3
int result = hidHandle.send(0,buf, BUF_LEN, 500); int result = sendData(buf, BUF_LEN);
if(result<1) if(result<1)
return false; return false;
if(debug) if(debug)
@ -104,7 +145,8 @@ bool OP_DFU::StartUpload(qint32 const & numberOfBytes, TransferTypes const & typ
buf[11] = crc; buf[11] = crc;
if(debug) if(debug)
qDebug()<<"Number of packets:"<<numberOfPackets<<" Size of last packet:"<<lastPacketCount; qDebug()<<"Number of packets:"<<numberOfPackets<<" Size of last packet:"<<lastPacketCount;
int result = hidHandle.send(0,buf, BUF_LEN, 5000); int result = sendData(buf, BUF_LEN);
delay::msleep(1000);
if(debug) if(debug)
qDebug() << result << " bytes sent"; qDebug() << result << " bytes sent";
if(result>0) if(result>0)
@ -145,7 +187,7 @@ bool OP_DFU::UploadData(qint32 const & numberOfBytes, QByteArray & data)
packetsize=lastPacketCount; packetsize=lastPacketCount;
else else
packetsize=14; packetsize=14;
// qDebug()<<packetcount; // qDebug()<<packetcount;
buf[2] = packetcount>>24;//DFU Count buf[2] = packetcount>>24;//DFU Count
buf[3] = packetcount>>16;//DFU Count buf[3] = packetcount>>16;//DFU Count
buf[4] = packetcount>>8;//DFU Count buf[4] = packetcount>>8;//DFU Count
@ -164,8 +206,8 @@ bool OP_DFU::UploadData(qint32 const & numberOfBytes, QByteArray & data)
// qDebug()<<" Data0="<<(int)data[0]<<" Data0="<<(int)data[1]<<" Data0="<<(int)data[2]<<" Data0="<<(int)data[3]<<" buf6="<<(int)buf[6]<<" buf7="<<(int)buf[7]<<" buf8="<<(int)buf[8]<<" buf9="<<(int)buf[9]; // qDebug()<<" Data0="<<(int)data[0]<<" Data0="<<(int)data[1]<<" Data0="<<(int)data[2]<<" Data0="<<(int)data[3]<<" buf6="<<(int)buf[6]<<" buf7="<<(int)buf[7]<<" buf8="<<(int)buf[8]<<" buf9="<<(int)buf[9];
//delay::msleep(send_delay); //delay::msleep(send_delay);
if(int ret=StatusRequest()!=OP_DFU::uploading) return false; if(int ret=StatusRequest()!=OP_DFU::uploading) return false;
int result = hidHandle.send(0,buf, BUF_LEN, 5000); int result = sendData(buf, BUF_LEN);
// qDebug()<<"sent:"<<result; // qDebug()<<"sent:"<<result;
if(result<1) if(result<1)
{ {
return false; return false;
@ -180,7 +222,7 @@ bool OP_DFU::UploadData(qint32 const & numberOfBytes, QByteArray & data)
} }
OP_DFU::Status OP_DFU::UploadDescription(QString & description) OP_DFU::Status OP_DFU::UploadDescription(QString & description)
{ {
cout<<"Starting uploading description\n"; cout<<"Starting uploading description\n";
if(description.length()%4!=0) if(description.length()%4!=0)
{ {
int pad=description.length()/4; int pad=description.length()/4;
@ -229,8 +271,8 @@ void OP_DFU::test()
++buf[1]; ++buf[1];
++buf[2]; ++buf[2];
++buf[63]; ++buf[63];
hidHandle.send(0,buf,BUF_LEN,5000); sendData(buf,BUF_LEN);
result = hidHandle.receive(0,buf,BUF_LEN,5000); result = receiveData(buf,BUF_LEN);
qDebug()<<"Result="<<result; qDebug()<<"Result="<<result;
qDebug()<<(int)buf[0]<<":"<<(int)buf[1]<<":"<<(int)buf[2]<<":"<<(int)buf[63]; qDebug()<<(int)buf[0]<<":"<<(int)buf[1]<<":"<<(int)buf[2]<<":"<<(int)buf[63];
@ -263,7 +305,7 @@ QByteArray OP_DFU::StartDownload(qint32 const & numberOfBytes, TransferTypes con
buf[8] = 1;//DFU Data2 buf[8] = 1;//DFU Data2
buf[9] = 1;//DFU Data3 buf[9] = 1;//DFU Data3
int result = hidHandle.send(0,buf, BUF_LEN, 500); int result = sendData(buf, BUF_LEN);
if(debug) if(debug)
qDebug() << "StartDownload:"<<numberOfPackets<<"packets"<<" Last Packet Size="<<lastPacketCount<<" "<<result << " bytes sent"; qDebug() << "StartDownload:"<<numberOfPackets<<"packets"<<" Last Packet Size="<<lastPacketCount<<" "<<result << " bytes sent";
float percentage; float percentage;
@ -277,7 +319,7 @@ QByteArray OP_DFU::StartDownload(qint32 const & numberOfBytes, TransferTypes con
// qDebug()<<"Status="<<StatusToString(StatusRequest()); // qDebug()<<"Status="<<StatusToString(StatusRequest());
result = hidHandle.receive(0,buf,BUF_LEN,5000); result = receiveData(buf,BUF_LEN);
if(debug) if(debug)
qDebug() << result << " bytes received"<<" Count="<<x<<"-"<<(int)buf[2]<<";"<<(int)buf[3]<<";"<<(int)buf[4]<<";"<<(int)buf[5]<<" Data="<<(int)buf[6]<<";"<<(int)buf[7]<<";"<<(int)buf[8]<<";"<<(int)buf[9]; qDebug() << result << " bytes received"<<" Count="<<x<<"-"<<(int)buf[2]<<";"<<(int)buf[3]<<";"<<(int)buf[4]<<";"<<(int)buf[5]<<" Data="<<(int)buf[6]<<";"<<(int)buf[7]<<";"<<(int)buf[8]<<";"<<(int)buf[9];
int size; int size;
@ -304,7 +346,7 @@ void OP_DFU::ResetDevice(void)
buf[7] = 0; buf[7] = 0;
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 500); int result = sendData(buf, BUF_LEN);
} }
void OP_DFU::AbortOperation(void) void OP_DFU::AbortOperation(void)
{ {
@ -319,7 +361,7 @@ void OP_DFU::AbortOperation(void)
buf[7] = 0; buf[7] = 0;
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 500); int result = sendData(buf, BUF_LEN);
} }
void OP_DFU::JumpToApp() void OP_DFU::JumpToApp()
{ {
@ -335,7 +377,7 @@ void OP_DFU::JumpToApp()
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 500); int result = sendData(buf, BUF_LEN);
} }
OP_DFU::Status OP_DFU::StatusRequest() OP_DFU::Status OP_DFU::StatusRequest()
{ {
@ -351,10 +393,10 @@ OP_DFU::Status OP_DFU::StatusRequest()
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 10000); int result = sendData(buf, BUF_LEN);
if(debug) if(debug)
qDebug() << result << " bytes sent"; qDebug() << result << " bytes sent";
result = hidHandle.receive(0,buf,BUF_LEN,10000); result = receiveData(buf,BUF_LEN);
if(debug) if(debug)
qDebug() << result << " bytes received"; qDebug() << result << " bytes received";
if(buf[1]==OP_DFU::Status_Rep) if(buf[1]==OP_DFU::Status_Rep)
@ -380,12 +422,12 @@ bool OP_DFU::findDevices()
buf[7] = 0; buf[7] = 0;
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 5000); int result = sendData(buf, BUF_LEN);
if(result<1) if(result<1)
{ {
return false; return false;
} }
result = hidHandle.receive(0,buf,BUF_LEN,5000); result = receiveData(buf,BUF_LEN);
if(result<1) if(result<1)
{ {
return false; return false;
@ -413,8 +455,8 @@ bool OP_DFU::findDevices()
buf[7] = 0; buf[7] = 0;
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 5000); int result = sendData(buf, BUF_LEN);
result = hidHandle.receive(0,buf,BUF_LEN,5000); result = receiveData(buf,BUF_LEN);
devices[x].ID=buf[9]; devices[x].ID=buf[9];
devices[x].BL_Version=buf[7]; devices[x].BL_Version=buf[7];
devices[x].SizeOfDesc=buf[8]; devices[x].SizeOfDesc=buf[8];
@ -466,7 +508,7 @@ bool OP_DFU::EndOperation()
buf[8] = 0; buf[8] = 0;
buf[9] = 0; buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 5000); int result = sendData(buf, BUF_LEN);
// hidHandle.receive(0,buf,BUF_LEN,5000); // hidHandle.receive(0,buf,BUF_LEN,5000);
if(debug) if(debug)
qDebug() << result << " bytes sent"; qDebug() << result << " bytes sent";
@ -600,17 +642,17 @@ OP_DFU::Status OP_DFU::CompareFirmware(const QString &sfile, const CompareType &
} }
if(type==OP_DFU::crccompare) if(type==OP_DFU::crccompare)
{ {
quint32 crc=CRCFromQBArray(arr,devices[device].SizeOfCode); quint32 crc=CRCFromQBArray(arr,devices[device].SizeOfCode);
if(crc==devices[device].FW_CRC) if(crc==devices[device].FW_CRC)
{ {
cout<<"Compare Successfull CRC MATCH!\n"; cout<<"Compare Successfull CRC MATCH!\n";
} }
else else
{ {
cout<<"Compare failed CRC DONT MATCH!\n"; cout<<"Compare failed CRC DONT MATCH!\n";
} }
return StatusRequest(); return StatusRequest();
} }
else else
{ {
if(arr==StartDownload(arr.length(),OP_DFU::FW)) if(arr==StartDownload(arr.length(),OP_DFU::FW))
@ -736,3 +778,43 @@ quint32 OP_DFU::CRCFromQBArray(QByteArray array, quint32 Size)
} }
return CRC32WideFast(0xFFFFFFFF,Size/4,(quint32*)t); return CRC32WideFast(0xFFFFFFFF,Size/4,(quint32*)t);
} }
int OP_DFU::sendData(void * data,int size)
{
if(!use_serial)
{
return hidHandle.send(0,data, size, 5000);
}
else
{
if(serialhandle->sendData((uint8_t*)data+1,size-1))
{
if (debug)
qDebug()<<"packet sent"<<"data0"<<((uint8_t*)data+1)[0];
return size;
}
if(debug)
qDebug()<<"Serial send OVERRUN";
}
}
int OP_DFU::receiveData(void * data,int size)
{
if(!use_serial)
{
return hidHandle.receive(0,data, size, 10000);
}
else
{
int x;
QTime time;
time.start();
while(true)
{
if(x=serialhandle->read_Packet(data+1)!=-1||time.elapsed()>10000)
{
if(time.elapsed()>10000)
qDebug()<<"____timeout";
return x;
}
}
}
}

View File

@ -5,10 +5,15 @@
#include <../../plugins/rawhid/pjrc_rawhid.h> #include <../../plugins/rawhid/pjrc_rawhid.h>
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QList> #include <QList>
#include <iostream> #include <iostream>
#include "delay.h" #include "delay.h"
#include "../../../libs/qextserialport/src/qextserialport.h"
#include <QTime>
#include ".\SSP\qssp.h"
#include ".\SSP\port.h"
#include ".\SSP\qsspt.h"
using namespace std; using namespace std;
#define BUF_LEN 64 #define BUF_LEN 64
@ -25,6 +30,11 @@ using namespace std;
#define LISTDEVICES "-ls" //done #define LISTDEVICES "-ls" //done
#define RESET "-r" #define RESET "-r"
#define JUMP "-j" #define JUMP "-j"
#define USE_SERIAL "-t"
#define MAX_PACKET_DATA_LEN 255
#define MAX_PACKET_BUF_SIZE (1+1+MAX_PACKET_DATA_LEN+2)
class OP_DFU class OP_DFU
{ {
@ -73,32 +83,31 @@ public:
enum Commands enum Commands
{ {
Reserved, Reserved,//0
Req_Capabilities, Req_Capabilities,//1
Rep_Capabilities, Rep_Capabilities,//2
EnterDFU, EnterDFU,//3
JumpFW, JumpFW,//4
Reset, Reset,//5
Abort_Operation, Abort_Operation,//6
Upload, Upload,//7
Op_END, Op_END,//8
Download_Req, Download_Req,//9
Download, Download,//10
Status_Request, Status_Request,//11
Status_Rep, Status_Rep,//12
}; };
struct device struct device
{ {
int ID; int ID;
quint32 FW_CRC; quint32 FW_CRC;
int BL_Version; int BL_Version;
int SizeOfDesc; int SizeOfDesc;
quint32 SizeOfCode; quint32 SizeOfCode;
bool Readable; bool Readable;
bool Writable; bool Writable;
}; };
void JumpToApp(); void JumpToApp();
void ResetDevice(void); void ResetDevice(void);
bool enterDFU(int const &devNumber); bool enterDFU(int const &devNumber);
@ -113,8 +122,8 @@ public:
QByteArray StartDownload(qint32 const & numberOfBytes, TransferTypes const & type); QByteArray StartDownload(qint32 const & numberOfBytes, TransferTypes const & type);
bool SaveByteArrayToFile(QString const & file,QByteArray const &array); bool SaveByteArrayToFile(QString const & file,QByteArray const &array);
void CopyWords(char * source, char* destination, int count); void CopyWords(char * source, char* destination, int count);
// QByteArray DownloadData(int devNumber,int numberOfPackets); // QByteArray DownloadData(int devNumber,int numberOfPackets);
OP_DFU(bool debug); OP_DFU(bool debug,bool use_serial,QString port);
void sendReset(void); void sendReset(void);
bool findDevices(); bool findDevices();
QList<device> devices; QList<device> devices;
@ -126,13 +135,22 @@ public:
void test(); void test();
int send_delay; int send_delay;
bool use_delay; bool use_delay;
bool ready(){return mready;}
void AbortOperation(void); void AbortOperation(void);
private: private:
bool mready;
bool debug; bool debug;
int RWFlags; int RWFlags;
bool use_serial;
qsspt * serialhandle;
int sendData(void*,int);
int receiveData(void * data,int size);
pjrc_rawhid hidHandle; pjrc_rawhid hidHandle;
int setStartBit(int command){return command|0x20;} int setStartBit(int command){return command|0x20;}
uint8_t sspTxBuf[MAX_PACKET_BUF_SIZE];
uint8_t sspRxBuf[MAX_PACKET_BUF_SIZE];
port * info;
}; };

View File

@ -7,7 +7,7 @@
QT += core QT += core
QT -= gui QT -= gui
DEFINES += QEXTSERIALPORT_LIBRARY
TARGET = OPUploadTool TARGET = OPUploadTool
CONFIG += console CONFIG += console
CONFIG -= app_bundle CONFIG -= app_bundle
@ -16,14 +16,26 @@ TEMPLATE = app
DEFINES += RAWHID_LIBRARY DEFINES += RAWHID_LIBRARY
SOURCES += main.cpp \ SOURCES += main.cpp \
op_dfu.cpp \ op_dfu.cpp \
delay.cpp delay.cpp \
./SSP/qssp.cpp \
./SSP/port.cpp \
./SSP/qsspt.cpp \
../../libs/qextserialport/src/qextserialport.cpp
HEADERS += ../../plugins/rawhid/pjrc_rawhid.h \ HEADERS += ../../plugins/rawhid/pjrc_rawhid.h \
../../plugins/rawhid/rawhid_global.h \ ../../plugins/rawhid/rawhid_global.h \
op_dfu.h \ op_dfu.h \
delay.h delay.h \
../../libs/qextserialport/src/qextserialport.h \
../../libs/qextserialport/src/qextserialenumerator.h \
../../libs/qextserialport/src/qextserialport_global.h \
./SSP/qssp.h \
./SSP/port.h \
./SSP/common.h \
./SSP/qsspt.h
win32 { win32 {
SOURCES += ../../plugins/rawhid/pjrc_rawhid_win.cpp SOURCES += ../../plugins/rawhid/pjrc_rawhid_win.cpp
LIBS += -lhid \ LIBS += -lhid \
-lsetupapi -lsetupapi
} }
@ -51,3 +63,16 @@ linux-g++-64 {
SOURCES += ../../plugins/rawhid/pjrc_rawhid_unix.cpp SOURCES += ../../plugins/rawhid/pjrc_rawhid_unix.cpp
LIBS += -lusb LIBS += -lusb
} }
unix:SOURCES += ../../libs/qextserialport/src/posix_qextserialport.cpp
unix:!macx:SOURCES += ../../libs/qextserialport/src/qextserialenumerator_unix.cpp
macx {
SOURCES += ../../libs/qextserialport/src/qextserialenumerator_osx.cpp
LIBS += -framework IOKit -framework CoreFoundation
}
win32 {
SOURCES += ../../libs/qextserialport/src/win_qextserialport.cpp \
../../libs/qextserialport/src/qextserialenumerator_win.cpp
DEFINES += WINVER=0x0501 # needed for mingw to pull in appropriate dbt business...probably a better way to do this
LIBS += -lsetupapi
}