2004-11-30 17:46:48 +00:00
//=========================================================================//
// //
// PonyProg - Serial Device Programmer //
// //
2017-04-18 01:25:22 +02:00
// Copyright (C) 1997-2017 Claudio Lanconelli //
2004-11-30 17:46:48 +00:00
// //
2007-04-20 10:58:20 +00:00
// http://ponyprog.sourceforge.net //
2004-11-30 17:46:48 +00:00
// //
//-------------------------------------------------------------------------//
// //
// 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 COPYING); if not, write to the //
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
// //
//-------------------------------------------------------------------------//
//=========================================================================//
# include "types.h"
# include "pic12bus.h"
# include "errcode.h"
2017-04-18 01:25:22 +02:00
# include <QDebug>
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
# include "e2cmdw.h"
# ifdef __linux__
2008-01-10 23:12:55 +00:00
//# include <asm/io.h>
2004-11-30 17:46:48 +00:00
# include <unistd.h>
# else
2017-04-18 01:25:22 +02:00
# ifdef __BORLANDC__
# define __inline__
2004-11-30 17:46:48 +00:00
# else // _MICROSOFT_ VC++
2017-04-18 01:25:22 +02:00
# define __inline__ __inline
2004-11-30 17:46:48 +00:00
# define _export
# endif
# endif
2017-04-18 01:25:22 +02:00
# define MAX_PROG_PULSES 8
2004-11-30 17:46:48 +00:00
// Constructor
Pic12Bus : : Pic12Bus ( BusInterface * ptr )
: BusIO ( ptr ) ,
2017-04-18 01:25:22 +02:00
// DataMask(0xff),
ProgMask ( 0x0fff ) , //12bit instruction
ReadProgCode ( 0x04 ) , //Read Data from Program Memory *
LoadProgCode ( 0x02 ) , //Load Data for Program Memory *
// ReadDataCode(0x05), //Read Data from Data Memory *
// LoadDataCode(0x03), //Load Data for Data Memory *
// LoadConfigCode(0x00), //Load Configuration *
IncAddressCode ( 0x06 ) , //Increment Address *
// EraseProgMem(0x09), //Bulk Erase Program Memory *
// EraseDataMem(0x0b), //Bulk Erase Data Memory *
BeginProgCode ( 0x08 ) , //Begin Erase Programming Cycle *
// BeginProgOnlyCode(0x18) //Begin Programming Only Cycle
EndProgCode ( 0x0e )
2004-11-30 17:46:48 +00:00
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Pic12Bus() " ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
OverProgrammingMult = 11 ; //Default OverProgramming X value (x11)
OverProgrammingAdd = 0 ; //Default OverProgramming + value (+0)
2004-11-30 17:46:48 +00:00
}
// Desctructor
Pic12Bus : : ~ Pic12Bus ( )
{
2017-04-18 01:25:22 +02:00
// Close();
2004-11-30 17:46:48 +00:00
}
void Pic12Bus : : SetDelay ( )
{
2017-04-18 01:25:22 +02:00
int val = E2Profile : : GetPICSpeed ( ) ;
2009-11-15 13:33:22 +00:00
int n ;
2017-04-29 01:56:50 +02:00
switch ( val )
2009-11-15 13:33:22 +00:00
{
2017-05-01 15:55:40 +02:00
case TURBO :
n = 1 ;
break ;
2017-04-18 01:25:22 +02:00
2017-05-01 15:55:40 +02:00
case FAST :
n = 3 ;
break ;
2017-04-18 01:25:22 +02:00
2017-05-01 15:55:40 +02:00
case SLOW :
n = 20 ;
break ;
2017-04-18 01:25:22 +02:00
2017-05-01 15:55:40 +02:00
case VERYSLOW :
n = 100 ;
break ;
2017-04-18 01:25:22 +02:00
2017-05-01 15:55:40 +02:00
case ULTRASLOW :
n = 1000 ;
break ;
2017-04-18 01:25:22 +02:00
2017-05-01 15:55:40 +02:00
default :
n = 8 ; //Default (< 100KHz)
break ;
2009-11-15 13:33:22 +00:00
}
2017-04-18 01:25:22 +02:00
2009-11-15 13:33:22 +00:00
BusIO : : SetDelay ( n ) ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " PIC12Bus::SetDelay() = " < < n ;
2004-11-30 17:46:48 +00:00
}
int Pic12Bus : : SendDataBit ( int b )
{
2017-04-18 01:25:22 +02:00
setCLK ( ) ; //set SCK high
2004-11-30 17:46:48 +00:00
bitDI ( b ) ;
WaitUsec ( shot_delay ) ;
2017-04-18 01:25:22 +02:00
clearCLK ( ) ; //device latch data bit now!
2004-11-30 17:46:48 +00:00
WaitUsec ( shot_delay ) ;
return OK ;
}
// returns a negative number in case of error, 0 or 1 otherwise
int Pic12Bus : : RecDataBit ( )
{
2009-11-16 22:29:18 +00:00
register uint8_t b ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
setCLK ( ) ; //set SCK high (Pic output data now)
2004-11-30 17:46:48 +00:00
WaitUsec ( shot_delay ) ;
2017-04-18 01:25:22 +02:00
b = getDO ( ) ; // sampling data on falling edge
2004-11-30 17:46:48 +00:00
clearCLK ( ) ;
WaitUsec ( shot_delay ) ;
return b ;
}
// OK, ora ci alziamo di un livello: operiamo sul byte
int Pic12Bus : : SendDataWord ( long wo , int wlen )
{
int k ;
clearCLK ( ) ;
clearDI ( ) ;
//transmit lsb first
for ( k = 0 ; k < wlen ; k + + )
2017-04-18 01:25:22 +02:00
{
SendDataBit ( wo & ( 1 < < k ) ) ;
}
2004-11-30 17:46:48 +00:00
setDI ( ) ;
//1 usec from a command to the next
2017-04-18 01:25:22 +02:00
WaitUsec ( shot_delay / 4 + 1 ) ;
2004-11-30 17:46:48 +00:00
return OK ;
}
long Pic12Bus : : RecDataWord ( int wlen )
{
int k ;
long val = 0 ;
clearCLK ( ) ;
setDI ( ) ;
//receive lsb first
for ( k = 0 ; k < wlen ; k + + )
2017-04-29 01:56:50 +02:00
if ( RecDataBit ( ) )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
val | = 1 < < k ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
WaitUsec ( shot_delay / 4 + 1 ) ;
2004-11-30 17:46:48 +00:00
return val ;
}
int Pic12Bus : : Reset ( void )
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Reset() IN " ;
2004-11-30 17:46:48 +00:00
SetDelay ( ) ;
2017-04-18 01:25:22 +02:00
SetMCLR ( ) ; //First bogus entry to charge capacitors
WaitMsec ( 200 ) ; //150
2004-11-30 17:46:48 +00:00
clearDI ( ) ;
2017-04-18 01:25:22 +02:00
ClearMCLR ( ) ; //Now reset the micro
setCLK ( ) ; //keep Vdd on
2004-11-30 17:46:48 +00:00
WaitMsec ( 20 ) ;
2017-04-18 01:25:22 +02:00
clearCLK ( ) ; //Prepare for Program mode entry
2004-11-30 17:46:48 +00:00
WaitMsec ( 10 ) ;
2017-04-18 01:25:22 +02:00
SetMCLR ( ) ; //Program mode entry
2004-11-30 17:46:48 +00:00
WaitMsec ( 10 ) ;
current_address = - 1 ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Reset() OUT " ;
2004-11-30 17:46:48 +00:00
return OK ;
}
2009-11-16 23:40:43 +00:00
long Pic12Bus : : ReadConfig ( uint16_t & data )
2004-11-30 17:46:48 +00:00
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::ReadConfig( " < < ( hex ) < < data < < ( dec ) < < " ) IN " ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
// Reset();
2004-11-30 17:46:48 +00:00
2009-11-16 22:29:18 +00:00
uint8_t * bp = ( uint8_t * ) & data ;
2004-11-30 17:46:48 +00:00
2009-11-15 13:33:22 +00:00
//Read Program Code
2004-11-30 17:46:48 +00:00
SendCmdCode ( ReadProgCode ) ;
2009-11-16 23:40:43 +00:00
uint16_t val = RecvProgCode ( ) ;
2004-11-30 17:46:48 +00:00
if ( val = = ProgMask )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
val = 0xffff ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
# ifdef _BIG_ENDIAN_
2009-11-16 22:29:18 +00:00
* bp + + = ( uint8_t ) ( val > > 8 ) ;
* bp + + = ( uint8_t ) ( val & 0xFF ) ;
2004-11-30 17:46:48 +00:00
# else
2009-11-16 22:29:18 +00:00
* bp + + = ( uint8_t ) ( val & 0xFF ) ;
* bp + + = ( uint8_t ) ( val > > 8 ) ;
2004-11-30 17:46:48 +00:00
# endif
IncAddress ( 1 ) ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::ReadConfig( " < < ( hex ) < < data < < ( dec ) < < " ) OUT " ;
2004-11-30 17:46:48 +00:00
return OK ;
}
2017-04-18 01:25:22 +02:00
2009-11-16 23:40:43 +00:00
long Pic12Bus : : WriteConfig ( uint16_t data )
2004-11-30 17:46:48 +00:00
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::WriteConfig( " < < ( hex ) < < data < < ( dec ) < < " ) IN " ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
// Reset();
2004-11-30 17:46:48 +00:00
2009-11-16 22:29:18 +00:00
uint8_t * bp = ( uint8_t * ) & data ;
2009-11-16 23:40:43 +00:00
uint16_t val ;
2004-11-30 17:46:48 +00:00
//Write Program code
2017-04-18 01:25:22 +02:00
# ifdef _BIG_ENDIAN_
2009-11-16 23:40:43 +00:00
val = ( uint16_t ) ( * bp + + ) < < 8 ;
val | = ( uint16_t ) ( * bp + + ) ;
2004-11-30 17:46:48 +00:00
# else
2009-11-16 23:40:43 +00:00
val = ( uint16_t ) ( * bp + + ) ;
val | = ( uint16_t ) ( * bp + + ) < < 8 ;
2004-11-30 17:46:48 +00:00
# endif
int k ;
2017-04-18 01:25:22 +02:00
2004-11-30 17:46:48 +00:00
for ( k = 100 ; k > 0 ; k - - )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
ProgramPulse ( val , 0 ) ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
IncAddress ( 1 ) ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::WriteConfig( " < < ( hex ) < < data < < ( dec ) < < " ) OUT " ;
2004-11-30 17:46:48 +00:00
return OK ;
}
long Pic12Bus : : BlankCheck ( long length )
{
2017-04-18 01:25:22 +02:00
length > > = 1 ; //contatore da byte a word
2004-11-30 17:46:48 +00:00
2017-05-02 17:54:17 +02:00
ReadStart ( ) ;
2009-11-15 13:33:22 +00:00
//Point to first location
2017-04-18 01:25:22 +02:00
// SendCmdCode(IncAddressCode);
2004-11-30 17:46:48 +00:00
long len ;
2017-04-18 01:25:22 +02:00
for ( len = 0 ; len < length - 1 ; len + + ) //Skip last location (RC calibration)
2004-11-30 17:46:48 +00:00
{
//Read Program Code
SendCmdCode ( ReadProgCode ) ;
2017-04-18 01:25:22 +02:00
2017-04-29 01:56:50 +02:00
if ( CompareSingleWord ( 0xffff , RecvProgCode ( ) , ProgMask ) )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
break ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
2017-05-02 17:54:17 +02:00
if ( ReadProgress ( len * 100 / length ) )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
break ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
2009-11-15 13:33:22 +00:00
IncAddress ( 1 ) ;
2004-11-30 17:46:48 +00:00
}
2017-04-18 01:25:22 +02:00
2017-05-02 17:54:17 +02:00
ReadEnd ( ) ;
2004-11-30 17:46:48 +00:00
return ( len = = length ) ;
}
2009-11-16 22:29:18 +00:00
long Pic12Bus : : Read ( int addr , uint8_t * data , long length , int page_size )
2004-11-30 17:46:48 +00:00
{
long len ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Read( " < < addr < < " , " < < ( hex ) < < data < < " , " < < ( dec ) < < length < < " ) IN " ;
2017-05-02 17:54:17 +02:00
ReadStart ( ) ;
2017-04-18 01:25:22 +02:00
length > > = 1 ; //contatore da byte a word
2004-11-30 17:46:48 +00:00
2009-11-15 13:33:22 +00:00
//Point to first location
2017-04-18 01:25:22 +02:00
// SendCmdCode(IncAddressCode);
2004-11-30 17:46:48 +00:00
for ( len = 0 ; len < length ; len + + )
{
//Read Program Code
SendCmdCode ( ReadProgCode ) ;
2009-11-16 23:40:43 +00:00
uint16_t val = RecvProgCode ( ) ;
2004-11-30 17:46:48 +00:00
if ( val = = ProgMask )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
val = 0xffff ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
# ifdef _BIG_ENDIAN_
2009-11-16 22:29:18 +00:00
* data + + = ( uint8_t ) ( val > > 8 ) ;
* data + + = ( uint8_t ) ( val & 0xFF ) ;
2004-11-30 17:46:48 +00:00
# else
2009-11-16 22:29:18 +00:00
* data + + = ( uint8_t ) ( val & 0xFF ) ;
* data + + = ( uint8_t ) ( val > > 8 ) ;
2004-11-30 17:46:48 +00:00
# endif
IncAddress ( 1 ) ;
2017-05-02 17:54:17 +02:00
if ( ReadProgress ( len * 100 / length ) )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
break ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
}
2017-04-18 01:25:22 +02:00
2017-05-02 17:54:17 +02:00
ReadEnd ( ) ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
len < < = 1 ; //contatore da word a byte
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Read() = " < < len < < " OUT " ;
2004-11-30 17:46:48 +00:00
return len ;
}
2009-11-16 22:29:18 +00:00
long Pic12Bus : : Write ( int addr , uint8_t const * data , long length , int page_size )
2004-11-30 17:46:48 +00:00
{
long len ;
int rv = OK ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Write( " < < addr < < " , " < < ( hex ) < < data < < " , " < < ( dec ) < < length < < " ) IN " ;
2017-05-02 17:54:17 +02:00
WriteStart ( ) ;
2017-04-18 01:25:22 +02:00
length > > = 1 ; //contatore da byte a word
2004-11-30 17:46:48 +00:00
//The address pointer should already point to first address
//location (via a ConfigRead or IncAddress)
//Program cycle
for ( len = 0 ; len < length ; len + + )
{
2009-11-16 23:40:43 +00:00
uint16_t val ;
2004-11-30 17:46:48 +00:00
//Write Program code
2017-04-18 01:25:22 +02:00
# ifdef _BIG_ENDIAN_
2009-11-16 23:40:43 +00:00
val = ( uint16_t ) ( * data + + ) < < 8 ;
val | = ( uint16_t ) ( * data + + ) ;
2004-11-30 17:46:48 +00:00
# else
2009-11-16 23:40:43 +00:00
val = ( uint16_t ) ( * data + + ) ;
val | = ( uint16_t ) ( * data + + ) < < 8 ;
2004-11-30 17:46:48 +00:00
# endif
2017-04-18 01:25:22 +02:00
rv = WriteProgWord ( val , length - 1 ) ;
2004-11-30 17:46:48 +00:00
2017-04-29 01:56:50 +02:00
if ( rv ! = OK )
2004-11-30 17:46:48 +00:00
{
len = rv ;
break ;
2009-11-15 13:33:22 +00:00
}
2004-11-30 17:46:48 +00:00
2017-05-02 17:54:17 +02:00
if ( WriteProgress ( len * 100 / length ) )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
break ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
}
2017-04-18 01:25:22 +02:00
2017-05-02 17:54:17 +02:00
WriteEnd ( ) ;
2004-11-30 17:46:48 +00:00
if ( len > 0 )
2017-04-18 01:25:22 +02:00
{
len < < = 1 ; //contatore da word a byte
}
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::Write() = " < < len < < " ** " < < GetLastProgrammedAddress ( ) < < " OUT " ;
2004-11-30 17:46:48 +00:00
return len ;
}
2009-11-16 23:40:43 +00:00
int Pic12Bus : : WriteProgWord ( uint16_t val , long rc_addr )
2004-11-30 17:46:48 +00:00
{
int k ;
int rval = OK ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::WriteProgWord( " < < ( hex ) < < val < < " , " < < ( dec ) < < current_address < < " ) IN " ;
2004-11-30 17:46:48 +00:00
//Check for RC calibration location
if ( current_address = = rc_addr )
{
//Check for blank (erased cells)
//Programma la RC calibration solamente se la locazione e` cancellata
// e il valore da pgrogrammare corrisponde ad una MOVLW xx (0x0Cxx)
SendCmdCode ( ReadProgCode ) ;
2017-04-18 01:25:22 +02:00
2017-04-29 01:56:50 +02:00
if ( CompareSingleWord ( RecvProgCode ( ) , 0xffff , ProgMask ) = = 0 & &
CompareSingleWord ( val , 0x0C00 , ( ProgMask & 0xff00 ) ) = = 0 )
2008-01-27 23:38:17 +00:00
{
2008-02-04 17:18:20 +00:00
SetLastProgrammedAddress ( current_address < < 1 ) ;
2004-11-30 17:46:48 +00:00
for ( k = 1 ; k < = MAX_PROG_PULSES ; k + + )
{
2017-04-29 01:56:50 +02:00
if ( ProgramPulse ( val , 1 ) = = OK )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
break ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
}
2017-04-18 01:25:22 +02:00
2004-11-30 17:46:48 +00:00
if ( k > MAX_PROG_PULSES )
{
2017-04-18 01:25:22 +02:00
rval = E2ERR_WRITEFAILED ; //Write error
2004-11-30 17:46:48 +00:00
}
else
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::WriteProgWord(): Npulses = " < < k ;
2004-11-30 17:46:48 +00:00
k * = OverProgrammingMult ;
k + = OverProgrammingAdd ;
2017-04-18 01:25:22 +02:00
2004-11-30 17:46:48 +00:00
while ( k - - )
2017-04-18 01:25:22 +02:00
{
ProgramPulse ( val , 0 ) ; //Program pulse without test
}
2004-11-30 17:46:48 +00:00
}
2009-11-15 13:33:22 +00:00
}
2004-11-30 17:46:48 +00:00
IncAddress ( 1 ) ;
}
else
{
//Check for blank (erased cells)
SendCmdCode ( ReadProgCode ) ;
2017-04-18 01:25:22 +02:00
2017-04-29 01:56:50 +02:00
if ( CompareSingleWord ( RecvProgCode ( ) , 0xffff , ProgMask ) )
2004-11-30 17:46:48 +00:00
{
rval = E2ERR_BLANKCHECKFAILED ;
}
else
{
//Skip FFF words
2017-04-29 01:56:50 +02:00
if ( CompareSingleWord ( val , 0xffff , ProgMask ) ! = 0 )
2004-11-30 17:46:48 +00:00
{
2008-02-04 17:18:20 +00:00
SetLastProgrammedAddress ( current_address < < 1 ) ;
2004-11-30 17:46:48 +00:00
for ( k = 1 ; k < = MAX_PROG_PULSES ; k + + )
{
2017-04-29 01:56:50 +02:00
if ( ProgramPulse ( val , 1 ) = = OK )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
break ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
}
2017-04-18 01:25:22 +02:00
2004-11-30 17:46:48 +00:00
if ( k > MAX_PROG_PULSES )
{
2017-04-18 01:25:22 +02:00
rval = E2ERR_WRITEFAILED ; //Write error
2004-11-30 17:46:48 +00:00
}
else
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::WriteProgWord(): Npulses = " < < k ;
2004-11-30 17:46:48 +00:00
k * = OverProgrammingMult ;
k + = OverProgrammingAdd ;
2017-04-18 01:25:22 +02:00
2004-11-30 17:46:48 +00:00
while ( k - - )
2017-04-18 01:25:22 +02:00
{
ProgramPulse ( val , 0 ) ; //Program pulse without test
}
2004-11-30 17:46:48 +00:00
}
}
IncAddress ( 1 ) ;
}
2009-11-15 13:33:22 +00:00
}
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::WriteProgWord() = " < < rval < < " OUT " ;
2004-11-30 17:46:48 +00:00
return rval ;
}
void Pic12Bus : : IncAddress ( int n )
{
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::IncAddress( " < < n < < " ) IN " ;
2004-11-30 17:46:48 +00:00
while ( n - - )
{
SendCmdCode ( IncAddressCode ) ;
current_address + + ;
}
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::IncAddress() OUT ** cur_addr = " < < current_address ;
2004-11-30 17:46:48 +00:00
}
2009-11-16 23:40:43 +00:00
int Pic12Bus : : ProgramPulse ( uint16_t val , int verify , int width )
2004-11-30 17:46:48 +00:00
{
int rval = OK ;
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::ProgramPulse( " < < ( hex ) < < val < < " , " < < ( dec ) < < verify < < " , " < < width < < " ) IN " ;
2004-11-30 17:46:48 +00:00
SendCmdCode ( LoadProgCode ) ;
SendProgCode ( val ) ;
2017-04-18 01:25:22 +02:00
SendCmdCode ( BeginProgCode ) ; //Start programming pulse
2004-11-30 17:46:48 +00:00
WaitUsec ( width ) ;
2017-04-18 01:25:22 +02:00
SendCmdCode ( EndProgCode ) ; //Stop programming pulse
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
WaitUsec ( 1000 ) ; //wait between pulses
2004-11-30 17:46:48 +00:00
//Verify programmed location
if ( verify )
{
SendCmdCode ( ReadProgCode ) ;
rval = CompareSingleWord ( val , RecvProgCode ( ) , ProgMask ) ;
2009-11-15 13:33:22 +00:00
}
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
qDebug ( ) < < " Pic12Bus::ProgramPulse() = " < < rval < < " OUT " ;
2004-11-30 17:46:48 +00:00
return rval ;
}
2009-11-16 23:40:43 +00:00
int Pic12Bus : : CompareSingleWord ( uint16_t data1 , uint16_t data2 , uint16_t mask )
2004-11-30 17:46:48 +00:00
{
return ( data1 & mask ) ! = ( data2 & mask ) ;
}
2009-11-16 23:40:43 +00:00
int Pic12Bus : : CompareMultiWord ( uint8_t * data1 , uint8_t * data2 , long length , int split )
2004-11-30 17:46:48 +00:00
{
int retval = 0 ;
2017-04-29 01:56:50 +02:00
if ( data1 = = 0 | | data2 = = 0 | | ( length & 1 ) ! = 0 )
2017-04-18 01:25:22 +02:00
{
2004-11-30 17:46:48 +00:00
return BADPARAM ;
2017-04-18 01:25:22 +02:00
}
2004-11-30 17:46:48 +00:00
if ( ! split )
{
2009-11-16 23:40:43 +00:00
long k ;
2017-04-18 01:25:22 +02:00
2004-11-30 17:46:48 +00:00
for ( k = 0 ; k < length ; k + = 2 )
{
2009-11-16 23:40:43 +00:00
uint16_t val1 , val2 ;
2004-11-30 17:46:48 +00:00
2017-04-18 01:25:22 +02:00
# ifdef _BIG_ENDIAN_
2009-11-16 23:40:43 +00:00
val1 = ( uint16_t ) ( * data1 + + ) < < 8 ;
val1 | = ( uint16_t ) ( * data1 + + ) ;
2004-11-30 17:46:48 +00:00
2009-11-16 23:40:43 +00:00
val2 = ( uint16_t ) ( * data2 + + ) < < 8 ;
val2 | = ( uint16_t ) ( * data2 + + ) ;
2004-11-30 17:46:48 +00:00
# else
2009-11-16 23:40:43 +00:00
val1 = ( uint16_t ) ( * data1 + + ) ;
val1 | = ( uint16_t ) ( * data1 + + ) < < 8 ;
2004-11-30 17:46:48 +00:00
2009-11-16 23:40:43 +00:00
val2 = ( uint16_t ) ( * data2 + + ) ;
val2 | = ( uint16_t ) ( * data2 + + ) < < 8 ;
2004-11-30 17:46:48 +00:00
# endif
2017-04-18 01:25:22 +02:00
2017-04-29 01:56:50 +02:00
if ( ( retval = CompareSingleWord ( val1 , val2 , ProgMask ) ) )
2017-04-18 01:25:22 +02:00
{
break ; //Stop if a difference
}
2004-11-30 17:46:48 +00:00
}
}
else
{
retval = memcmp ( data1 , data2 , length ) ;
}
return retval ;
}