/***************************************************************************
* Copyright ( C ) 2003 - 2005 by David Saxton *
* david @ bluehaze . org *
* *
* 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 2 of the License , or *
* ( at your option ) any later version . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# ifndef NO_GPSIM
# include "canvasitemparts.h"
# include "circuitdocument.h"
# include "docmanager.h"
# include "gpsimprocessor.h"
# include "libraryitem.h"
# include "logic.h"
# include "ktechlab.h"
# include "micropackage.h"
# include "picinfo.h"
# include "microlibrary.h"
# include "piccomponent.h"
# include "piccomponentpin.h"
# include "projectmanager.h"
# include <kdebug.h>
# include <kiconloader.h>
# include <tdelocale.h>
# include <tdemessagebox.h>
# include <tqguardedptr.h>
# include <tqstringlist.h>
# include "gpsim/ioports.h"
# include "gpsim/pic-processor.h"
const TQString _def_PICComponent_fileName = i18n ( " <Enter location of PIC Program> " ) ;
Item * PICComponent : : construct ( ItemDocument * itemDocument , bool newItem , const char * id )
{
return new PICComponent ( ( ICNDocument * ) itemDocument , newItem , id ) ;
}
LibraryItem * PICComponent : : libraryItem ( )
{
TQStringList IDs ;
IDs < < " ec/pic " < < " ec/picitem " < < " ec/picitem_18pin " ;
return new LibraryItem (
IDs ,
" PIC " ,
i18n ( " Integrated Circuits " ) ,
" ic2.png " ,
LibraryItem : : lit_component ,
PICComponent : : construct ) ;
}
PICComponent : : PICComponent ( ICNDocument * icnDocument , bool newItem , const char * id )
: Component ( icnDocument , newItem , id ? id : " pic " )
{
m_name = i18n ( " PIC Micro " ) ;
m_desc = i18n ( " The PIC component allows the simulation of a PIC program.<br><br> "
" The loadable PIC program must be one of the following formats: "
" <ul><li>Assembly (.asm)</li> "
" <li>FlowCode (.flowcode)</li> "
" <li>Symbol file (.cod)</li> "
" <li>Microbe (.microbe, .basic)</li> "
" <li>C source (.c)</li></ul> "
" Doubleclick on the PIC component to open up the program source file.<br><br> "
" If the program source file is of type assembly, then the the opened text file will automatically be linked to the simulation. "
" You can control the program from the text document using the debug controls.<br><br> "
" Explanation of buttons: "
" <ul><li>Play - Run the PIC program from the point at which it was paused, or from the start otherwise.</li> "
" <li>Pause - Pause the simulation at the current execution point.</li> "
" <li>Stop - Reset all parts of the simulation.</li> "
" <li>Reload - Reread the PIC program from disk and restart gpsim.</li></ul> " ) ;
m_bCreatedInitialPackage = false ;
m_bLoadingProgram = false ;
m_pGpsim = 0L ;
Bring mail_forward, mail_new, mail_replyall, mail_reply, mail_send, player_pause, player_play, player_stop, player_rew, player_fwd, player_start, player_end, rotate_ccw, rotate_cw, window_fullscreen, window_nofullscreen, window_new, viewmagfit, viewmag+, viewmag1, and viewmag- icons into XDG compliance
10 years ago
addButton ( " run " , TQRect ( ) , TDEGlobal : : iconLoader ( ) - > loadIcon ( " media-playback-start " , TDEIcon : : Small ) ) ;
addButton ( " pause " , TQRect ( ) , TDEGlobal : : iconLoader ( ) - > loadIcon ( " media-playback-pause " , TDEIcon : : Small ) ) ;
addButton ( " reset " , TQRect ( ) , TDEGlobal : : iconLoader ( ) - > loadIcon ( " process-stop " , TDEIcon : : Small ) ) ;
addButton ( " reload " , TQRect ( ) , TDEGlobal : : iconLoader ( ) - > loadIcon ( " reload " , TDEIcon : : Small ) ) ;
if ( icnDocument - > ktechlab ( ) )
connect ( icnDocument - > ktechlab ( ) , TQT_SIGNAL ( recentFileAdded ( const KURL & ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
connect ( ProjectManager : : self ( ) , TQT_SIGNAL ( projectOpened ( ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
connect ( ProjectManager : : self ( ) , TQT_SIGNAL ( projectClosed ( ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
connect ( ProjectManager : : self ( ) , TQT_SIGNAL ( projectCreated ( ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
connect ( ProjectManager : : self ( ) , TQT_SIGNAL ( subprojectCreated ( ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
connect ( ProjectManager : : self ( ) , TQT_SIGNAL ( filesAdded ( ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
connect ( ProjectManager : : self ( ) , TQT_SIGNAL ( filesRemoved ( ) ) , this , TQT_SLOT ( slotUpdateFileList ( ) ) ) ;
createProperty ( " program " , Variant : : Type : : FileName ) ;
property ( " program " ) - > setCaption ( i18n ( " Program " ) ) ;
property ( " program " ) - > setFilter ( " *.flowcode *.asm *.cod *.basic|All Supported Files \n *.flowcode|FlowCode (*.flowcode) \n *.cod|Symbol File (*.cod) \n *.asm|Assembly Code (*.asm) \n *.basic *.microbe|Microbe (*.basic, *.microbe) \n *.c|C (*.c)*|All Files " ) ;
// Used for restoring the pins on file loading before we have had a change
// to compile the PIC program
createProperty ( " lastPackage " , Variant : : Type : : String ) ;
property ( " lastPackage " ) - > setHidden ( true ) ;
// //HACK This is to enable loading with pre-0.3 files (which didn't set a "lastPackage"
// // property). This will allow a P16F84 PIC to be initialized (which agrees with pre-0.3
// // behaviour), but it will also load it if
// This to allow loading of the PIC component from pre-0.3 files (which didn't set a
// "lastPackage" property).
if ( ! newItem )
property ( " lastPackage " ) - > setValue ( " P16F84 " ) ;
slotUpdateFileList ( ) ;
slotUpdateBtns ( ) ;
initPackage ( 0 ) ;
}
PICComponent : : ~ PICComponent ( )
{
deletePICComponentPins ( ) ;
delete m_pGpsim ;
}
void PICComponent : : dataChanged ( )
{
initPIC ( false ) ;
}
void PICComponent : : initPIC ( bool forceReload )
{
if ( ! m_bCreatedInitialPackage )
{
// We are still being created, so other connectors will be expecting us to
// have grown pins soonish.
MicroInfo * microInfo = MicroLibrary : : self ( ) - > microInfoWithID ( dataString ( " lastPackage " ) ) ;
if ( microInfo )
initPackage ( microInfo ) ;
}
TQString newProgram = KURL ( dataString ( " program " ) ) . path ( ) ;
bool newFile = ( m_picFile ! = newProgram ) ;
if ( ! newFile & & ! forceReload )
return ;
delete m_pGpsim ;
m_pGpsim = 0L ;
switch ( GpsimProcessor : : isValidProgramFile ( newProgram ) )
{
case GpsimProcessor : : DoesntExist :
if ( newProgram = = _def_PICComponent_fileName & & ! newProgram . isEmpty ( ) )
break ;
KMessageBox : : sorry ( 0l , i18n ( " The file \" %1 \" does not exist. " ) . arg ( newProgram ) ) ;
m_picFile = TQString ( ) ;
break ;
case GpsimProcessor : : IncorrectType :
if ( newProgram = = _def_PICComponent_fileName & & ! newProgram . isEmpty ( ) )
break ;
KMessageBox : : sorry ( 0L , i18n ( " \" %1 \" is not a valid PIC program. \n The file must exist, and the extension should be \" .cod \" , \" .asm \" , \" .flowcode \" , \" .basic \" , \" .microbe \" or \" .c \" . \n \" .hex \" is allowed, provided that there is a corresponding \" .cod \" file. " ) . arg ( newProgram ) ) ;
m_picFile = TQString ( ) ;
break ;
case GpsimProcessor : : Valid :
m_picFile = newProgram ;
m_symbolFile = createSymbolFile ( ) ;
break ;
}
slotUpdateBtns ( ) ;
}
void PICComponent : : deletePICComponentPins ( )
{
const PICComponentPinMap : : iterator picComponentMapEnd = m_picComponentPinMap . end ( ) ;
for ( PICComponentPinMap : : iterator it = m_picComponentPinMap . begin ( ) ; it ! = picComponentMapEnd ; + + it )
delete it . data ( ) ;
m_picComponentPinMap . clear ( ) ;
}
void PICComponent : : initPackage ( MicroInfo * microInfo )
{
MicroPackage * microPackage = microInfo ? microInfo - > package ( ) : 0l ;
if ( microPackage )
{
m_bCreatedInitialPackage = true ;
//BEGIN Get pin IDs
TQStringList allPinIDs = microPackage - > pinIDs ( ) ;
TQStringList ioPinIDs = microPackage - > pinIDs ( PicPin : : type_bidir | PicPin : : type_input | PicPin : : type_open ) ;
// Now, we make the unwanted pin ids blank, so a pin is not created for them
const TQStringList : : iterator allPinIDsEnd = allPinIDs . end ( ) ;
for ( TQStringList : : iterator it = allPinIDs . begin ( ) ; it ! = allPinIDsEnd ; + + it )
{
if ( ! ioPinIDs . contains ( * it ) )
* it = " " ;
}
//END Get pin IDs
//BEGIN Remove old stuff
// Remove old text
TextMap textMapCopy = m_textMap ;
const TextMap : : iterator textMapEnd = textMapCopy . end ( ) ;
for ( TextMap : : iterator it = textMapCopy . begin ( ) ; it ! = textMapEnd ; + + it )
removeDisplayText ( it . key ( ) ) ;
// Remove the old pins
deletePICComponentPins ( ) ;
// Remove old nodes
NodeMap nodeMapCopy = m_nodeMap ;
const NodeMap : : iterator nodeMapEnd = nodeMapCopy . end ( ) ;
for ( NodeMap : : iterator it = nodeMapCopy . begin ( ) ; it ! = nodeMapEnd ; + + it )
{
if ( ! ioPinIDs . contains ( it . key ( ) ) )
removeNode ( it . key ( ) ) ;
}
removeElements ( ) ;
//END Remove old stuff
//BEGIN Create new stuff
initDIPSymbol ( allPinIDs , 80 ) ;
initDIP ( allPinIDs ) ;
PicPinMap picPinMap = microPackage - > pins ( PicPin : : type_bidir | PicPin : : type_input | PicPin : : type_open ) ;
const PicPinMap : : iterator picPinMapEnd = picPinMap . end ( ) ;
for ( PicPinMap : : iterator it = picPinMap . begin ( ) ; it ! = picPinMapEnd ; + + it )
m_picComponentPinMap [ it . key ( ) ] = new PICComponentPin ( this , it . data ( ) ) ;
//END Create new stuff
removeDisplayText ( " no_file " ) ;
addDisplayText ( " picid " , TQRect ( offsetX ( ) , offsetY ( ) - 16 , width ( ) , 16 ) , microInfo - > id ( ) ) ;
}
else
{
setSize ( - 48 , - 72 , 96 , 144 ) ;
removeDisplayText ( " picid " ) ;
addDisplayText ( " no_file " , sizeRect ( ) , i18n ( " (No \n program \n loaded) " ) ) ;
}
//BEGIN Update button positions
int leftpos = ( width ( ) - 88 ) / 2 + offsetX ( ) ;
button ( " run " ) - > setOriginalRect ( TQRect ( leftpos , height ( ) + 4 + offsetY ( ) , 20 , 20 ) ) ;
button ( " pause " ) - > setOriginalRect ( TQRect ( leftpos + 23 , height ( ) + 4 + offsetY ( ) , 20 , 20 ) ) ;
button ( " reset " ) - > setOriginalRect ( TQRect ( leftpos + 46 , height ( ) + 4 + offsetY ( ) , 20 , 20 ) ) ;
button ( " reload " ) - > setOriginalRect ( TQRect ( leftpos + 69 , height ( ) + 4 + offsetY ( ) , 20 , 20 ) ) ;
updateAttachedPositioning ( ) ;
//END Update button positions
}
void PICComponent : : attachPICComponentPins ( )
{
if ( ! m_pGpsim | | ! m_pGpsim - > picProcessor ( ) )
return ;
pic_processor * picProcessor = m_pGpsim - > picProcessor ( ) ;
const PICComponentPinMap : : iterator end = m_picComponentPinMap . end ( ) ;
for ( PICComponentPinMap : : iterator it = m_picComponentPinMap . begin ( ) ; it ! = end ; + + it )
it . data ( ) - > attach ( picProcessor - > get_pin ( it . key ( ) ) ) ;
}
void PICComponent : : slotUpdateFileList ( )
{
TQStringList preFileList ;
if ( p_icnDocument & & p_icnDocument - > ktechlab ( ) )
preFileList + = p_icnDocument - > ktechlab ( ) - > recentFiles ( ) ;
TQStringList fileList ;
if ( ProjectInfo * info = ProjectManager : : self ( ) - > currentProject ( ) )
{
const KURL : : List urls = info - > childOutputURLs ( ProjectItem : : AllTypes , ProjectItem : : ProgramOutput ) ;
KURL : : List : : const_iterator urlsEnd = urls . end ( ) ;
for ( KURL : : List : : const_iterator it = urls . begin ( ) ; it ! = urlsEnd ; + + it )
fileList < < ( * it ) . path ( ) ;
}
const TQStringList : : iterator end = preFileList . end ( ) ;
for ( TQStringList : : iterator it = preFileList . begin ( ) ; it ! = end ; + + it )
{
TQString file = KURL ( * it ) . path ( ) ;
if ( ( file . endsWith ( " .flowcode " ) | | file . endsWith ( " .asm " ) | | file . endsWith ( " .cod " ) | | file . endsWith ( " .basic " ) | | file . endsWith ( " .microbe " ) ) & & ! fileList . contains ( file ) ) {
fileList . append ( file ) ;
}
}
TQString fileName = dataString ( " program " ) ;
property ( " program " ) - > setAllowed ( fileList ) ;
property ( " program " ) - > setValue ( fileName . isEmpty ( ) ? _def_PICComponent_fileName : fileName ) ;
}
void PICComponent : : buttonStateChanged ( const TQString & id , bool state )
{
if ( ! state )
return ;
if ( id = = " reload " )
{
programReload ( ) ;
return ;
}
if ( ! m_pGpsim )
return ;
if ( id = = " run " )
m_pGpsim - > setRunning ( true ) ;
else if ( id = = " pause " )
m_pGpsim - > setRunning ( false ) ;
else if ( id = = " reset " )
{
m_pGpsim - > reset ( ) ;
// Set all pin outputs to low
const PICComponentPinMap : : iterator end = m_picComponentPinMap . end ( ) ;
for ( PICComponentPinMap : : iterator it = m_picComponentPinMap . begin ( ) ; it ! = end ; + + it )
it . data ( ) - > resetOutput ( ) ;
}
slotUpdateBtns ( ) ;
}
bool PICComponent : : mouseDoubleClickEvent ( const EventInfo & eventInfo )
{
Q_UNUSED ( eventInfo ) ;
if ( m_picFile . isEmpty ( ) | | ( m_picFile = = _def_PICComponent_fileName ) )
return false ;
( void ) DocManager : : self ( ) - > openURL ( m_picFile ) ;
return true ;
}
TQString PICComponent : : createSymbolFile ( )
{
m_bLoadingProgram = true ;
slotUpdateBtns ( ) ;
return GpsimProcessor : : generateSymbolFile ( dataString ( " program " ) , this , TQT_SLOT ( slotCODCreationSucceeded ( ) ) , TQT_SLOT ( slotCODCreationFailed ( ) ) ) ;
}
void PICComponent : : slotCODCreationSucceeded ( )
{
m_bLoadingProgram = false ;
delete m_pGpsim ;
m_pGpsim = new GpsimProcessor ( m_symbolFile ) ;
if ( m_pGpsim - > codLoadStatus ( ) = = GpsimProcessor : : CodSuccess )
{
MicroInfo * microInfo = m_pGpsim - > microInfo ( ) ;
property ( " lastPackage " ) - > setValue ( microInfo - > id ( ) ) ;
initPackage ( microInfo ) ;
connect ( m_pGpsim , TQT_SIGNAL ( runningStatusChanged ( bool ) ) , this , TQT_SLOT ( slotUpdateBtns ( ) ) ) ;
attachPICComponentPins ( ) ;
}
else
{
m_pGpsim - > displayCodLoadStatus ( ) ;
delete m_pGpsim ;
m_pGpsim = 0l ;
}
slotUpdateBtns ( ) ;
}
void PICComponent : : slotCODCreationFailed ( )
{
m_bLoadingProgram = false ;
slotUpdateBtns ( ) ;
}
void PICComponent : : programReload ( )
{
delete m_pGpsim ;
m_pGpsim = 0L ;
initPIC ( true ) ;
slotUpdateBtns ( ) ;
}
void PICComponent : : slotUpdateBtns ( )
{
// We can get called by the destruction of gpsim after our canvas has been set to NULL
if ( ! canvas ( ) )
return ;
button ( " run " ) - > setEnabled ( m_pGpsim & & ! m_pGpsim - > isRunning ( ) ) ;
button ( " pause " ) - > setEnabled ( m_pGpsim & & m_pGpsim - > isRunning ( ) ) ;
button ( " reset " ) - > setEnabled ( m_pGpsim ) ;
button ( " reload " ) - > setEnabled ( ! m_bLoadingProgram & & ( dataString ( " program " ) ! = _def_PICComponent_fileName ) ) ;
canvas ( ) - > setChanged ( button ( " run " ) - > boundingRect ( ) ) ;
canvas ( ) - > setChanged ( button ( " pause " ) - > boundingRect ( ) ) ;
canvas ( ) - > setChanged ( button ( " reset " ) - > boundingRect ( ) ) ;
canvas ( ) - > setChanged ( button ( " reload " ) - > boundingRect ( ) ) ;
}
# include "piccomponent.moc"
# endif