ponyprog/SrcPony/microbus.cpp
2019-08-11 01:47:26 +02:00

238 lines
4.9 KiB
C++

//=========================================================================//
// //
// PonyProg - Serial Device Programmer //
// //
// Copyright (C) 1997-2019 Claudio Lanconelli //
// //
// http://ponyprog.sourceforge.net //
// //
//-------------------------------------------------------------------------//
// //
// 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 version2 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 (see LICENSE); if not, write to the //
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
// //
//=========================================================================//
#include "types.h"
#include "globals.h"
#include "e2profil.h"
#include "microbus.h"
#include "errcode.h"
#include "e2cmdw.h"
#include <QDebug>
#include <QtCore>
MicroWireBus::MicroWireBus(BusInterface *ptr)
: BusIO(ptr)
{
qDebug() << __PRETTY_FUNCTION__;
}
MicroWireBus::~MicroWireBus()
{
qDebug() << __PRETTY_FUNCTION__;
}
void MicroWireBus::SetDelay()
{
int val = E2Profile::GetMicroWireSpeed();
int n;
switch (val)
{
case TURBO:
n = 1; // as fast as your PC can
break;
case FAST:
n = 5;
break;
case SLOW:
n = 50;
break;
case VERYSLOW:
n = 200;
break;
case ULTRASLOW:
n = 800;
break;
default:
n = 10; //Default (< 100KHz)
break;
}
Q_CHECK_PTR(busI);
busI->SetDelay(n);
qDebug() << __PRETTY_FUNCTION__ << "=" << n;
}
int MicroWireBus::SendDataBit(int b)
{
//clearCLK(); //si assicura che SCK low
//bitDI(b);
//ShotDelay();
//setCLK(); //device latch data bit now!
//ShotDelay();
//clearCLK();
int err = OK;
busI->xferBit(err, b, SPI_MODE_0 | xMODE_WRONLY);
return err;
}
int MicroWireBus::RecDataBit()
{
//clearCLK(); //si assicura che SCK low
//ShotDelay();
//setCLK();
//ShotDelay();
//b = getDO();
//clearCLK();
int err = OK;
int rv = busI->xferBit(err, 1, SPI_MODE_1 | xMODE_RDONLY);
if (err == OK)
{
return rv;
}
else
{
return err;
}
}
int MicroWireBus::RecDataBitShort()
{
clearCLK(); //be sure SCK low
ShotDelay();
return getDO();
}
int MicroWireBus::SendDataWord(int wo, int wlen, bool lsb)
{
int err = OK;
clearCLK();
busI->xferWord(err, wo, SPI_MODE_0 | xMODE_WRONLY, wlen, lsb);
clearDI();
return err;
}
//Standard Receive data word
int MicroWireBus::RecDataWord(int wlen, bool lsb)
{
int err = OK;
clearCLK();
int rv = busI->xferWord(err, 0xffff, SPI_MODE_1 | xMODE_RDONLY, wlen, lsb);
if (err == OK)
{
return rv;
}
else
{
return err;
}
}
//Receive Data word with the first clock pulse shortened.
// In case of the device doesn't leave a clock pulse to switch
// from DataOut to DataIn after the command
int MicroWireBus::RecDataWordShort(int wlen, bool lsb)
{
int valb = 0, valw = 0;
Q_ASSERT(wlen > 1);
clearCLK();
valb = RecDataBitShort() ? 1 : 0;
valw = RecDataWord(wlen - 1, lsb);
if (lsb)
{
return (valw << 1) | valb;
}
else
{
return (valb << (wlen - 1)) | valw;
}
}
int MicroWireBus::WaitReadyAfterWrite(long timeout)
{
clearCLK();
ClearReset(); //27/05/98
ShotDelay();
SetReset(); //27/05/98
ShotDelay();
clearCLK();
long k;
for (k = timeout; k > 0 && !getDO(); k--)
{
WaitUsec(1);
}
qDebug() << __PRETTY_FUNCTION__ << "=" << k;
return k ? OK : E2P_TIMEOUT;
}
int MicroWireBus::Reset(void)
{
qDebug() << __PRETTY_FUNCTION__;
SetDelay();
clearCLK();
//clearDI(); //27/05/98
setDI();
ClearReset(); //Pulse the reset
WaitMsec(1); //27/05/98
SetReset();
WaitMsec(50);
return OK;
}
int MicroWireBus::CalcAddressSize(int mem_size) const
{
if (mem_size-- <= 0)
{
return -1;
}
int k;
for (k = 15; k > 0; k--)
{
if (mem_size & (1 << k))
{
break;
}
}
return k + 1;
}