##// END OF EJS Templates
Étiquette socexplorer-plugins-0.7-7 enlevée
Étiquette socexplorer-plugins-0.7-7 enlevée

File last commit:

r66:a69da3403983 default
r101:10745beb94ab default
Show More
ahbuartplugin.cpp
549 lines | 18.9 KiB | text/x-c | CppLexer
/*------------------------------------------------------------------------------
-- 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 <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;
}
this->UI->setSystemSpeed(this->detectSpeed());
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=1024;
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++)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
// for(int j =0;j<4;j++)
// {
// Value[i]= ((unsigned char)(result[i*4+j])) + Value[i]*256;
// }
Value[i]= socexplorerBswap32(((uint32_t*)result)[i]);
#elif __BYTE_ORDER == __BIG_ENDIAN
Value[i]= ((uint32_t*)result)[i];
#endif
}
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=1024;
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++)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
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);
#elif __BYTE_ORDER == __BIG_ENDIAN
CMD[(i*4)+5] = (char)(((unsigned int)Value[i+offset])&0xFF);
CMD[(i*4)+6] = (char)(((unsigned int)Value[i+offset]>>8)&0xFF);
CMD[(i*4)+7] = (char)(((unsigned int)Value[i+offset]>>16)&0xFF);
CMD[(i*4)+8] = (char)(((unsigned int)Value[i+offset]>>24)&0xFF);
#endif
}
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++)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
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);
#elif __BYTE_ORDER == __BIG_ENDIAN
CMD[(i*4)+5] = (char)(((unsigned int)Value[i+offset])&0xFF);
CMD[(i*4)+6] = (char)(((unsigned int)Value[i+offset]>>8)&0xFF);
CMD[(i*4)+7] = (char)(((unsigned int)Value[i+offset]>>16)&0xFF);
CMD[(i*4)+8] = (char)(((unsigned int)Value[i+offset]>>24)&0xFF);
#endif
}
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);
}
int ahbuartplugin::detectSpeed()
{
//scaler = (((system_clk*10)/(baudrate*8))-5)/10
unsigned int ahbUartBaseAddress = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01,0x007,0);
// unsigned int dsuBaseAddress = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01,0x0017,0);
unsigned int dsuBaseAddress = 0x90000000;
unsigned int scaler = 0,dsuVal1=0,dsuVal2=0;
int speed=0;
QElapsedTimer time;
if(dsuBaseAddress!=-1)
{
time.start();
if( this->Read(&dsuVal1,1,dsuBaseAddress+0x08)==1)
{
usleep(1000*1000);
qint64 el = time.elapsed();
this->Read(&dsuVal2,1,dsuBaseAddress+0x08);
if(dsuVal1!=dsuVal2)
return ((dsuVal2-dsuVal1)/el)*1000;
}
}
if(ahbUartBaseAddress!=-1)
{
if( this->Read(&scaler,1,ahbUartBaseAddress+0x0C)==1)
{
scaler&=0x3FFFF;
speed = (int)(((double)scaler*10.0)+5.0)*((double)this->UI->baudRate()/10.0)*8.0;
// speed = (int)((double)(scaler+1)*8.0*(double)this->UI->baudRate());
}
}
return speed;
}
void ahbuartplugin::postInstantiationTrigger()
{
if(this->scanDone && this->Connected)
{
this->UI->setSystemSpeed(this->detectSpeed());
}
}