ahbuartplugin.cpp
490 lines
| 16.6 KiB
| text/x-c
|
CppLexer
/ ahbuartplugin / ahbuartplugin.cpp
r0 | /*------------------------------------------------------------------------------ | |||
Jeandet Alexis
|
r4 | -- This file is a part of the SocExplorer Software | ||
Jeandet Alexis
|
r11 | -- Copyright (C) 2011, Plasma Physics Laboratory - CNRS | ||
r0 | -- | |||
-- 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 | ||||
-------------------------------------------------------------------------------*/ | ||||
/*-- Author : Alexis Jeandet | ||||
-- Mail : alexis.jeandet@lpp.polytechnique.fr | ||||
----------------------------------------------------------------------------*/ | ||||
#include <socexplorerengine.h> | ||||
#include "ahbuartplugin.h" | ||||
#include <unistd.h> | ||||
#include <errno.h> | ||||
#include <QApplication> | ||||
#include <QProgressBar> | ||||
#include <stdio.h> | ||||
#include <QThread> | ||||
#include "ahbuartpywrapper.h" | ||||
#include <QCompleter> | ||||
#include <QStringList> | ||||
#include <QLineEdit> | ||||
#include <socexplorerproxy.h> | ||||
ahbuartplugin::ahbuartplugin(QWidget *parent):socexplorerplugin(parent,false) | ||||
{ | ||||
this->port =(rs232port_t)NULL; | ||||
this->portMutex = new QMutex(QMutex::Recursive); | ||||
this->UI = new ahbUartPluginUI(); | ||||
this->setWidget((QWidget*)this->UI); | ||||
QObject::connect(this,SIGNAL(activateSig(bool)),this->UI,SLOT(setConnected(bool))); | ||||
QObject::connect(this->UI,SIGNAL(connectPortsig(QString,int)),this,SLOT(togglePort(QString,int))); | ||||
this->pyObject = new ahbuartPywrapper(this); | ||||
QObject::connect(((ahbuartPywrapper*)this->pyObject),SIGNAL(open(QString,int)),this,SLOT(open(QString,int))); | ||||
QObject::connect(((ahbuartPywrapper*)this->pyObject),SIGNAL(close()),this,SLOT(close())); | ||||
QObject::connect(((ahbuartPywrapper*)this->pyObject),SIGNAL(ReadBytes(uint,uint)),this,SLOT(ReadBytes(uint,uint))); | ||||
QObject::connect(((ahbuartPywrapper*)this->pyObject),SIGNAL(WriteBytes(uint,QList<QVariant>)),this,SLOT(WriteBytes(uint,QList<QVariant>))); | ||||
QObject::connect(this->UI,SIGNAL(rescanPorts()),this,SLOT(updatePortList())); | ||||
r31 | QObject::connect(this,SIGNAL(addReadBytes(int)),this->UI,SLOT(addReadBytes(int))); | |||
QObject::connect(this,SIGNAL(addWritenBytes(int)),this->UI,SLOT(addWritenBytes(int))); | ||||
r0 | this->portListcompleter = NULL; | |||
this->scanDone = false; | ||||
updatePortList(); | ||||
} | ||||
ahbuartplugin::~ahbuartplugin() | ||||
{ | ||||
if(this->port!=(rs232port_t)NULL) | ||||
{ | ||||
rs232close(this->port); | ||||
this->port = (rs232port_t)NULL; | ||||
} | ||||
this->UI->close(); | ||||
this->UI->~ahbUartPluginUI(); | ||||
} | ||||
void ahbuartplugin::closeMe() | ||||
{ | ||||
if(this->port!=(rs232port_t)NULL) | ||||
{ | ||||
rs232close(this->port); | ||||
this->port = (rs232port_t)NULL; | ||||
} | ||||
emit this->closePlugin(this); | ||||
} | ||||
int ahbuartplugin::registermenu(QMainWindow *menuHolder) | ||||
{ | ||||
this->menu = menuHolder->menuBar()->addMenu(tr("&AHB UART")); | ||||
this->closeAction = this->menu->addAction(tr("Close plugin")); | ||||
QObject::connect(this->closeAction,SIGNAL(triggered()),this,SLOT(closeMe())); | ||||
return 1; | ||||
} | ||||
bool ahbuartplugin::checkConnection() | ||||
{ | ||||
QTime timeout; | ||||
char test[5] ={(char)0x80,(char)0x80,(char)0,(char)0,(char)0}; | ||||
char test2[1024]; | ||||
int writen =0; | ||||
int read = 0; | ||||
timeout.start(); | ||||
SocExplorerEngine::message(this,"Check connection",2); | ||||
Jeandet Alexis
|
r30 | QMutexLocker lock(portMutex); | ||
r0 | while(writen!=5) | |||
{ | ||||
writen+=rs232write(this->port,test+writen,5-writen); | ||||
if(timeout.elapsed()>1000) | ||||
{ | ||||
SocExplorerEngine::message(this,"Can't write any data on serial port",2); | ||||
return false; | ||||
} | ||||
} | ||||
Jeandet Alexis
|
r5 | #ifdef WIN32 | ||
usleep(1000); | ||||
#endif | ||||
r0 | timeout.restart(); | |||
r33 | int avail = 0; | |||
do | ||||
r0 | { | |||
r33 | avail = rs232availablebytes(this->port); | |||
if(timeout.elapsed()>1000) | ||||
{ | ||||
if(avail) | ||||
rs232read(this->port,test2,avail); | ||||
SocExplorerEngine::message(this,"Connection Error",2); | ||||
return false; | ||||
} | ||||
}while(avail<4); | ||||
read = rs232read(this->port,test2,avail); | ||||
r0 | if(read>0) | |||
{ | ||||
SocExplorerEngine::message(this,"Connection Ok",2); | ||||
return true; | ||||
} | ||||
else | ||||
{ | ||||
SocExplorerEngine::message(this,"Connection Error",2); | ||||
return false; | ||||
} | ||||
} | ||||
void ahbuartplugin::connectPort(QString PortName, int baudrate) | ||||
{ | ||||
QTime timeout; | ||||
SocExplorerEngine::message(this,"Try to connect to port "+PortName,2); | ||||
timeout.start(); | ||||
Jeandet Alexis
|
r30 | QMutexLocker lock(portMutex); | ||
r0 | if(this->port==(rs232port_t)NULL) | |||
{ | ||||
SocExplorerEngine::message(this,"Open port "+PortName,2); | ||||
this->port=rs232open((char*)PortName.toStdString().c_str()); | ||||
} | ||||
if(this->port!=badPortValue) | ||||
{ | ||||
SocExplorerEngine::message(this,"Port opened "+PortName,2); | ||||
SocExplorerEngine::message(this,"Configure port "+PortName,2); | ||||
rs232setup(this->port,8,baudrate,rs232parityNo,rs232OneStop); | ||||
char test[7] ={(char)0x55,(char)0x51,(char)0x80,(char)0x80,(char)0x0,(char)0x0,(char)0x14}; | ||||
char test2[1024]; | ||||
SAFEWRITE(test,1,timeout,2000,return); | ||||
SAFEWRITE((test+1),1,timeout,2000,return); | ||||
rs232read(this->port,test2,512); | ||||
int read = 0; | ||||
for(int i=0;i<10;i++) | ||||
{ | ||||
SocExplorerEngine::message(this,"Send test patern :0x55,0x55,0x80,0x80,0x0,0x0,0x14",2); | ||||
SAFEWRITE(test+2,5,timeout,2000,return); | ||||
SocExplorerEngine::message(this,"Read Result",2); | ||||
read=rs232read(this->port,test2+read,16); | ||||
SocExplorerEngine::message(this,QString("Get ") + QString::number(read) + " bytes",2); | ||||
if(read>0) | ||||
{ | ||||
SocExplorerEngine::message(this,"Flush port ",2); | ||||
while(rs232read(this->port,test2,1)>0); | ||||
this->Connected = true; | ||||
SocExplorerEngine::message(this,QString("Connection success on ")+PortName,2); | ||||
emit this->activate(true); | ||||
if(this->scanDone==false) | ||||
{ | ||||
socexplorerproxy::loadChildSysDriver(this,"AMBA_PLUGIN"); | ||||
this->scanDone=true; | ||||
} | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
SocExplorerEngine::message(this,QString("Port not opened ")+PortName,2); | ||||
this->port = (rs232port_t)NULL; | ||||
this->Connected = false; | ||||
emit this->activateSig(false); | ||||
return; | ||||
} | ||||
if(this->Connected == false) | ||||
{ | ||||
SocExplorerEngine::message(this,QString("Port not opened ")+PortName,2); | ||||
rs232close(this->port); | ||||
this->port = (rs232port_t)NULL; | ||||
emit this->activateSig(false); | ||||
} | ||||
} | ||||
bool ahbuartplugin::open(QString PortName,int baudrate) | ||||
{ | ||||
if(this->port!=(rs232port_t)NULL) | ||||
this->close(); | ||||
this->UI->setconfig(PortName,baudrate); | ||||
this->connectPort(PortName,baudrate); | ||||
return (this->port!=(rs232port_t)NULL); | ||||
} | ||||
void ahbuartplugin::close() | ||||
{ | ||||
if(this->port!=(rs232port_t)NULL) | ||||
{ | ||||
rs232close(this->port); | ||||
this->port = (rs232port_t)NULL; | ||||
this->Connected = false; | ||||
emit this->activateSig(false); | ||||
} | ||||
} | ||||
void ahbuartplugin::togglePort(QString PortName,int baudrate) | ||||
{ | ||||
if(this->port!=(rs232port_t)NULL) | ||||
{ | ||||
this->close(); | ||||
} | ||||
else | ||||
{ | ||||
this->connectPort(PortName,baudrate); | ||||
} | ||||
} | ||||
unsigned int ahbuartplugin::Read(unsigned int *Value,unsigned int count,unsigned int address) | ||||
{ | ||||
QTime timeout; | ||||
timeout.start(); | ||||
unsigned int read=0; | ||||
unsigned int cnt=count; | ||||
unsigned int nextUpdateTrig=0,updateStep=512; | ||||
SocExplorerEngine::message(this,QString("Read ")+ QString::number(count) + QString(" words @0x")+ QString::number(address,16),2); | ||||
if((this->port!= badPortValue)||(this->port!=(rs232port_t)NULL)) | ||||
{ | ||||
Jeandet Alexis
|
r30 | QMutexLocker lock(portMutex); | ||
r0 | if(!this->checkConnection()) | |||
{ | ||||
this->Connected = false; | ||||
emit this->activateSig(false); | ||||
this->portMutex->unlock(); | ||||
return 0; | ||||
} | ||||
QProgressBar* progress=NULL; | ||||
if(cnt>128) | ||||
progress= SocExplorerEngine::getProgressBar("Reading on uart @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count); | ||||
char CMD[5]; | ||||
char* result = (char*)malloc(count*4); | ||||
while(count>32) | ||||
{ | ||||
CMD[0] = 0x80 | (32-1); | ||||
CMD[1] = (char)((address>>24)&0xFF); | ||||
CMD[2] = (char)((address>>16)&0xFF); | ||||
CMD[3] = (char)((address>>8)&0xFF); | ||||
CMD[4] = (char)((address)&0xFF); | ||||
SAFEWRITE(CMD,5,timeout,1000,return 0); | ||||
r33 | timeout.restart(); | |||
int avail=0; | ||||
do{ | ||||
avail=rs232availablebytes(this->port); | ||||
if(timeout.elapsed()>1000) | ||||
{ | ||||
rs232close(this->port); | ||||
this->port = (rs232port_t)NULL; | ||||
this->Connected = false; | ||||
emit this->activateSig(false); | ||||
return 0; | ||||
} | ||||
}while(avail<(32*4)); | ||||
rs232read(this->port,result+((cnt-count)*4),32*4); | ||||
r0 | count-=32; | |||
address+=32*4; | ||||
if(cnt>128) | ||||
{ | ||||
if((cnt-count)>=nextUpdateTrig) | ||||
{ | ||||
progress->setValue(cnt-count); | ||||
qApp->processEvents(); | ||||
nextUpdateTrig+=updateStep; | ||||
} | ||||
} | ||||
} | ||||
if(count>0) | ||||
{ | ||||
CMD[0] = 0x80 | (count-1); | ||||
CMD[1] = (char)((address>>24)&0xFF); | ||||
CMD[2] = (char)((address>>16)&0xFF); | ||||
CMD[3] = (char)((address>>8)&0xFF); | ||||
CMD[4] = (char)((address)&0xFF); | ||||
SAFEWRITE(CMD,5,timeout,1000,return 0); | ||||
r33 | timeout.restart(); | |||
int avail=0; | ||||
do{ | ||||
avail=rs232availablebytes(this->port); | ||||
if(timeout.elapsed()>1000) | ||||
{ | ||||
rs232close(this->port); | ||||
this->port = (rs232port_t)NULL; | ||||
this->Connected = false; | ||||
emit this->activateSig(false); | ||||
return 0; | ||||
} | ||||
}while(avail<(count*4)); | ||||
rs232read(this->port,result+((cnt-count)*4),count*4); | ||||
r0 | } | |||
if(cnt>128) | ||||
{ | ||||
progress->setValue(cnt-count); | ||||
qApp->processEvents(); | ||||
} | ||||
for(int i=0;(unsigned int)i<cnt;i++) | ||||
{ | ||||
for(int j =0;j<4;j++) | ||||
{ | ||||
Value[i]= ((unsigned char)(result[i*4+j])) + Value[i]*256; | ||||
} | ||||
read = cnt*4; | ||||
} | ||||
if(cnt>128) | ||||
SocExplorerEngine::deleteProgressBar(progress); | ||||
free(result); | ||||
} | ||||
r31 | emit this->addReadBytes(read); | |||
r0 | return read/4; | |||
} | ||||
unsigned int ahbuartplugin::Write(unsigned int *Value,unsigned int count, unsigned int address) | ||||
{ | ||||
QTime timeout; | ||||
timeout.start(); | ||||
unsigned int writen=0; | ||||
unsigned int nextUpdateTrig=0,updateStep=512; | ||||
SocExplorerEngine::message(this,QString("Write ")+ QString::number(count) + QString(" words @0x")+ QString::number(address,16),2); | ||||
if((this->port!= badPortValue)||(this->port!=(rs232port_t)NULL)) | ||||
{ | ||||
Jeandet Alexis
|
r30 | QMutexLocker lock(portMutex); | ||
r0 | if(!this->checkConnection()) | |||
{ | ||||
emit this->activateSig(false); | ||||
this->Connected = false; | ||||
this->portMutex->unlock(); | ||||
return 0; | ||||
} | ||||
QProgressBar* progress = NULL; | ||||
if(count>128) | ||||
progress = SocExplorerEngine::getProgressBar("Writing on uart @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count); | ||||
int offset = 0; | ||||
char* CMD= (char*)malloc((32*4)+5); | ||||
r34 | writen=0; | |||
r0 | while(count>32) | |||
{ | ||||
CMD[0] = 0xC0 | (32-1); | ||||
CMD[1] = (char)(((unsigned int)address>>24)&0xFF); | ||||
CMD[2] = (char)(((unsigned int)address>>16)&0xFF); | ||||
CMD[3] = (char)(((unsigned int)address>>8)&0xFF); | ||||
CMD[4] = (char)(((unsigned int)address)&0xFF); | ||||
for(int i=0;i<32;i++) | ||||
{ | ||||
CMD[(i*4)+5] = (char)(((unsigned int)Value[i+offset]>>24)&0xFF); | ||||
CMD[(i*4)+6] = (char)(((unsigned int)Value[i+offset]>>16)&0xFF); | ||||
CMD[(i*4)+7] = (char)(((unsigned int)Value[i+offset]>>8)&0xFF); | ||||
CMD[(i*4)+8] = (char)(((unsigned int)Value[i+offset])&0xFF); | ||||
} | ||||
SAFEWRITE(CMD,((32*4)+5),timeout,1000,return 0); | ||||
writen+=32; | ||||
count-=32; | ||||
offset+=32; | ||||
address+=32*4; | ||||
if(offset>=nextUpdateTrig && progress!=NULL) | ||||
{ | ||||
progress->setValue(offset); | ||||
qApp->processEvents(); | ||||
nextUpdateTrig +=updateStep; | ||||
} | ||||
} | ||||
if(count>0) | ||||
{ | ||||
CMD[0] = 0xC0 | (count-1); | ||||
CMD[1] = (char)(((unsigned int)address>>24)&0xFF); | ||||
CMD[2] = (char)(((unsigned int)address>>16)&0xFF); | ||||
CMD[3] = (char)(((unsigned int)address>>8)&0xFF); | ||||
CMD[4] = (char)(((unsigned int)address)&0xFF); | ||||
for(int i=0;(unsigned int) i<(count);i++) | ||||
{ | ||||
CMD[(i*4)+5] = (char)(((unsigned int)Value[i+offset]>>24)&0xFF); | ||||
CMD[(i*4)+6] = (char)(((unsigned int)Value[i+offset]>>16)&0xFF); | ||||
CMD[(i*4)+7] = (char)(((unsigned int)Value[i+offset]>>8)&0xFF); | ||||
CMD[(i*4)+8] = (char)(((unsigned int)Value[i+offset])&0xFF); | ||||
} | ||||
SAFEWRITE(CMD,((count*4)+5),timeout,1000,return 0); | ||||
writen+=count; | ||||
} | ||||
if(progress!=NULL) | ||||
{ | ||||
progress->setValue(writen); | ||||
qApp->processEvents(); | ||||
SocExplorerEngine::deleteProgressBar(progress); | ||||
} | ||||
free(CMD); | ||||
r34 | emit this->addWritenBytes(writen*4); | |||
r0 | return writen; | |||
} | ||||
return 0; | ||||
} | ||||
void ahbuartplugin::updatePortList() | ||||
{ | ||||
if(this->portListcompleter==(QCompleter*)NULL) | ||||
{ | ||||
this->portListcompleter=new QCompleter(this); | ||||
this->portListcompleter->setCaseSensitivity(Qt::CaseInsensitive); | ||||
this->portListcompleterModel = new QStringListModel(this); | ||||
this->portListcompleter->setModel(this->portListcompleterModel); | ||||
this->UI->setCompleter(this->portListcompleter); | ||||
} | ||||
rs232portslist_t* portlist = rs232getportlist(); | ||||
rs232portslist_t* portlistenum = portlist; | ||||
QStringList wordList; | ||||
while(portlistenum!=NULL) | ||||
{ | ||||
wordList << portlistenum->name; | ||||
portlistenum = portlistenum->next; | ||||
} | ||||
rs232deleteportlist(portlist); | ||||
this->portListcompleterModel->setStringList(wordList); | ||||
} | ||||
QVariantList ahbuartplugin::ReadBytes(unsigned int address, unsigned int count) | ||||
{ | ||||
unsigned int data[(count/4)+1]; | ||||
QVariantList result; | ||||
this->Read(data,(count/4)+1,address); | ||||
for(unsigned int i = 0;i<count/4;i++) | ||||
{ | ||||
result.append(QVariant((int)(0x0FF&(data[i]>>24)))); | ||||
result.append(QVariant((int)(0x0FF&(data[i]>>16)))); | ||||
result.append(QVariant((int)(0x0FF&(data[i]>>8)))); | ||||
result.append(QVariant((int)(0x0FF&(data[i])))); | ||||
} | ||||
for(int i=0;i<(count%4);i++) | ||||
{ | ||||
result.append(QVariant((int)(0x0FF&(data[count/4]>>((3-i)*8))))); | ||||
} | ||||
return result; | ||||
} | ||||
void ahbuartplugin::WriteBytes(unsigned int address, QList<QVariant> dataList) | ||||
{ | ||||
unsigned int data[dataList.count()/4]; | ||||
for(int i = 0;i<(dataList.count()/4);i++) | ||||
{ | ||||
data[i] = 0x0FF & ((unsigned int)dataList.at(4*i).toUInt()); | ||||
data[i] = (data[i]<<8) + (0x0FF & ((unsigned int)dataList.at((4*i)+1).toUInt())); | ||||
data[i] = (data[i]<<8) + (0x0FF & ((unsigned int)dataList.at((4*i)+2).toUInt())); | ||||
data[i] = (data[i]<<8) + (0x0FF & ((unsigned int)dataList.at((4*i)+3).toUInt())); | ||||
} | ||||
this->Write(data,dataList.count()/4,address); | ||||
} | ||||