|
|
/*------------------------------------------------------------------------------
|
|
|
-- This file is a part of the SocExplorer Software
|
|
|
-- Copyright (C) 2011, Plasma Physics Laboratory - CNRS
|
|
|
--
|
|
|
-- 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()));
|
|
|
QObject::connect(this,SIGNAL(addReadBytes(int)),this->UI,SLOT(addReadBytes(int)));
|
|
|
QObject::connect(this,SIGNAL(addWritenBytes(int)),this->UI,SLOT(addWritenBytes(int)));
|
|
|
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);
|
|
|
QMutexLocker lock(portMutex);
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
#ifdef WIN32
|
|
|
usleep(1000);
|
|
|
#endif
|
|
|
timeout.restart();
|
|
|
int avail = 0;
|
|
|
do
|
|
|
{
|
|
|
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);
|
|
|
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();
|
|
|
QMutexLocker lock(portMutex);
|
|
|
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))
|
|
|
{
|
|
|
QMutexLocker lock(portMutex);
|
|
|
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);
|
|
|
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);
|
|
|
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);
|
|
|
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);
|
|
|
}
|
|
|
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);
|
|
|
}
|
|
|
emit this->addReadBytes(read);
|
|
|
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))
|
|
|
{
|
|
|
QMutexLocker lock(portMutex);
|
|
|
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);
|
|
|
writen=0;
|
|
|
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);
|
|
|
emit this->addWritenBytes(writen*4);
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|