Spectrum Digital Target

Interface

Document Revision 0.2

April 23, 2001

 

 

 

 

 

 

 

 

 

 

1.       Introduction_ 3

1.1     Who Should Use This Product 3

2.       Block Diagram_ 4

3.       Interface Basics 6

3.1     Support Files 33

4.       Configuration Interface 50

4.1     CreateHndl() 81

Input 84

Output 93

4.2     FreeHndl() 133

Input 136

Output 139

4.3     SetOptions() 145

Input 150

Output 154

4.4     GetOptions() NOT supported in version 1_ 216

4.5     FreeOptions() 219

Input 222

Output 225

4.6     Connect() 229

Input 232

Output 235

4.7     Disconnect() 238

Input 241

Output 244

4.8     GetErrorString() Not supported in version 1_ 249

5.       Register Interface 255

5.1     ReadByName() 269

Input 272

Output 278

5.2     WriteByName() 284

Input 287

Output 293

6.       Memory Interface 344

6.1     Read(),Write(), Fill() 409

Input 412

Output 430

7.       Event Interface 466

7.1     Add() 499

Input 502

Output 514

7.2     Delete() 523

Input 526

Output 530

8.       Execution Interface 534

8.1     Reset() 552

Input 555

Output 558

8.2     Continue() 561

Input 564

Output 567

8.3     Suspend() 570

Input 574

Output 577

8.4     Step() 580

Input 584

Output 588

8.5     UserMode() 591

Input 594

Output 597

8.6     IsRunning() 600

Input 603

Output 606

8.7     IsEvent() 610

Input 613

Output 617

9.       SDTI.H_ 752

10.     C2xx Details 1318

10.1       C2xx Register Names 1319

11.     C54x Details 1353

11.1       C54x Register Names 1354

11.2       C54x Extended Address Support 1401

 

 

 

 

 

 

 


 

1.     Introduction

This document covers the specification for the Spectrum Digital Target Interface.  A simple C based interface to basic emulation and debug capabilities of various DSP and microprocessor devices.

 

1.1     Who Should Use This Product

This product is aimed at the test engineer wanting to automate production test of an end product.  To use this product you should be proficient in the following:

1.        Structured C programming.

2.        Use of Microsoft Visual Studio 6.0.

3.        Use of hardware and software development tools for the intended processor.

4.        Use of dynamic link libraries and their nuances in a Win32 environment.


 

2.      Block Diagram

The following block diagram shows a typical use of the target interface when used in the Spectrum Digital Flash Programmer application. When used in conjunction with a TI DSP the target interface sits on top of the standard sdgoxxx.dvr driver used with Code Composer.  The sdgoxxx.dvr files will load the appropriate emulation drivers based on the emulator address and type specified in the sdopts.cfg file.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 


3.     Interface Basics

The interface is generic in nature and designed to support a wide range of processors without compile time dependencies.  This allows an application like a Flash Programmer to support a wide range of devices without being recompiled or reconfigured for each device type supported.   When used with a TI processor the interface becomes a thin layer that maps generic functions into specifics of a proprietary interface.  This has the advantage of reusing existing well known drivers from Code Composer products but supplementing them with a more generic non- proprietary documented interface. 

 

A working example of the interface can be found in the Spectrum Digital Perl utility.   In this example Perl is used for writing test scripts.  These scripts are then converted from Perl functions to target function calls via the Spectrum Digital Target Interface, or SDTI.  The SDTI consists of 5 major functional interfaces:

 

1.       Configuration:             For configuring the interface and specifying operating modes.

2.       Register:                       For accessing target registers.

3.       Memory:                        For accessing target memory.

4.       Events:                           For managing events, i.e. breakpoints

5.       Execution:                     For run control

 

When connecting to the SDTI driver “sdtsrv.dll” you make one function call to get all the methods for the interface then use the above interfaces.  Example:

SD_TARGET_INTERFACE *pSd;

 

                SDTI_GetInterface( &pSd, FAMILY_TMS320C2XX);

 

                pSd->pCfg->CreateHndl(…);             // Create a handle for an instance of the C2xx

                pSD->pCfg->Connect(…); // Make a physical connection to the C2xx

                pSd->pExe->Reset(…);                       // Reset the C2xx DSP

 

All interfaces contain version information for compatibility checking.  SDTI uses one interface header file named sdti.h which is included by the application.  This file also contains interface details for the various types used by SDTI.

 

All functions in the interface return TRUE (1) or FALSE (0).  A return value of TRUE indicates success.  A return value of FALSE indicates failure.  When an error does occur it is queued in the event queue.

 

SDTI treats errors, status changes, target events (breakpoints) as events and queues them into the event queue.  The application can periodically check the event queue to dequeue the events.  The event queue is built as a FIFO.


 

3.1     Support Files

The user application links to the SDSTRV.DLL file.  This dll will likewise make runtime linkage to other Spectrum Digital drivers and support files.  These will be the same files as used in a typical Code Composer emulator driver install when used with a TI processor.  Following is a list of required files for the C2xx:

 

Sdtsrv.dll               - Top level dll

Sdtsrv.lib               - MSVC generated library file that allows implicit linkage by the application

Sdgo2xx.dvr         - The standard C2xx Code Composer emulation driver

Sddllmgt.dll         - The Spectrum Digital DLL manager/loader

Sdspi515.dll         - The XDS510PP_PLUS and SPI515 emulation driver

Sdiont.sys              - The WinNT driver required for WinNT4/5 installs

Sdopts.cfg             - The standard Spectrum Digital configuration file.

 

If you have used Code Composer or the SDFlash programming utility you should be familiar with most of the files and file structure. 

 

The remainder of this document covers the interface details for the SDTI interface.  A working example of the interface is provided with the SDPerl project for both the C2xx and C54x devices.  The header file sdti.h also contains a number of comments on the interface and the associated data types.

 

See the SDPerl documentation for install and build details.   The currently supported SDTI interface runs on Win98, WinNT4, and Win2K.  Win95 is not supported or tested.

 

4.     Configuration Interface

The configuration interface is defined as:

 

typedef struct sdf_cfg

{

    int      StructSz;           // Size of this structure

    int      Version;            // Interface major version                   

    int      Revision;           // Interface minor revision       

 

    // Create/Free handle for debug instance

    BOOL     (*CreateHndl)  ( SDTI_HNDL *pHndl, char *pLibPath, char *pLibName,

                                                char *pFamily );

    BOOL     (*FreeHndl)    ( SDTI_HNDL Hndl );

 

    // Option setup prior to connecting to the target

    BOOL     (*SetOptions)   ( SDTI_HNDL Hndl, char *pOptsString );

    BOOL     (*GetOptions)   ( SDTI_HNDL Hndl, int  MaxString,

                               char *pOptsString );

    BOOL     (*FreeOptions)  ( SDTI_HNDL Hndl );

 

 

    // Connect/Disconnect from the target

    BOOL     (*Connect)      ( SDTI_HNDL Hndl                     );  

    BOOL     (*Disconnect)   ( SDTI_HNDL Hndl                     );

 

    // Get an error string based on the error code

    BOOL     (*GetErrorString) ( SDTI_HNDL Hndl, int Error, int MaxString,

                                                 char *pErrString );

} SDF_CFG, *PSDF_CFG;


 

4.1     CreateHndl()

CreateHndl will create an instance for the specified processor but will not make a connection to the processor.   This must be the first function called, as it will return a handle that is required by all other functions.  The specified driver/dll pointed to by pLibPath\pLibName will be loaded and verified for the proper interface and processor family.  Call CreateHndl for each processor you wish to access.  You do not have to call CreateHndl processors that you are not accessing, i.e. in bypass.

 

Input

SDTI_HNDL *pHndl     Pointer to return handle

 

char *pLibPath             Path to low level driver, “c:\ti\drivers”

 

char *pLibName             Name of the low level driver, “sdgoxxx.dvr”

 

char *pFamily        Processor family, used for interface verification

 

Output

Returns TRUE or FALSE. 

 

Notes

The sdgoxxxx.dvr drivers require a specific interface be exposed for sdtsrv.dll.  If you are using an older sdgoxxx.dvr this interface may not be exposed.   In this case CreatHndl will return FALSE.  The sdgoxxxx.dvr files shipped in the SDPerl and SDFlash utilities have the proper interface exposed.

The following code fragment gets the SDTI interface and then attempts to create a handle for one instance.

 

SDTI_GetInterface( (void **)&pIntf, (char *)(m_sDspFamily.c_str()) );

 

if( pIntf != NULL )

{

m_pIntf = (void *)pIntf;

 

       if( pIntf->pCfg != NULL )

       {

            if( pIntf->pCfg->CreateHndl != NULL)

                Success = pIntf->pCfg->CreateHndl( &SdTiHndl,

                                              (driver_path[0] == '\0')

                                                 ? NULL : driver_path, 

                                              (driver_name[0] == '\0')

                                                 ? NULL : driver_name, 

                                                 (char *)(m_sDspFamily.c_str())  );

 

 

                     // If we failed then return error.  If we got a handle go

                     // ahead and free it for safety.

                     if( Success == FALSE )

                     {

                           if( SdTiHndl != NULL )

                           {

                                  if( pIntf->pCfg->FreeHndl != NULL)

                                         pIntf->pCfg->FreeHndl( m_SdTiHndl );

                           }

                           return( -1 );

                     }

       }

}

 


 

4.2      FreeHndl()

FreeHndl will free the resources created by CreatHndl including the associated instance of the driver/dll specified in CreateHndl.  If still connected to the target then FreeHndl will disconnect from the target before freeing.  Once the handle is freed no more calls can be made to that processor until a new handle is created.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 


 

 

 

4.3     SetOptions()

SetOptions provides a means to set target specific options prior to making a connection to the target.  Once a target is connected many of the options cannot be modified unless you disconnect from the target. For example you cannot change the port address of the attached emulator after you have connected. You can make multiple calls to SetOptions or a single call with multiple options.   When passing multiple options each option is comma delimited with no spaces.  Example:

 

Char MyOptions[] = “EmuPortAddr=0x378,DevBoardName=\\ti\\cc\\bin\\brd\\ccBrd0.dat,DevProdName=cpu_0”

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

char *pOptsString    Pointer to a comma delimited set of options

 

Output

Returns TRUE or FALSE. 

 

Supported Options

EmuPortAddr

                                Emulator port address, to match sdopts.cfg

EmulatorId

                                Emulator port ID, to match sdopts.cfg

DevBoardName

                                Path\name of the board file.

DevProcName

                                Name of the cpu that you want to attach to.  Must match the name in your board file.

DevConnectRealtime

                                Start the emulation session in realtime mode if supported by the processor.

DevRunOnDisconnect

                                Let the processor run in native non-emulation mode when disconnected.

 

The following options are set to defaults internally by Spectrum Digital.  The user should not modify these.  They are included here for completeness

DevEnableMemoryMapChecking

Disable memory map checking.  Set to disabled as memory map checking is not supported.

DevMaxMemoryBlockSize

                                Set the maximum memory block size in target words that can be accesses in one call.

DevForceStatusCheck

When the processor is halted full status checking is not performed.  Enable this to force a full status check.  Safe but slow.


The following example sets up the EmuPortAddr, DevBoardName, and DevProcName if the user has provided valid input to the application.

 

if( pIntf->pCfg->SetOptions != NULL )

              {

 

                     // Set the emulator port address

                     ::memset( opts, 0,MAX_NAME_SIZE);

                     ::strcpy( opts, "EmuPortAddr=0x" );

                     if( !m_sEmulatorAddress.empty() )

                           ::strcat(opts,m_sEmulatorAddress.c_str());

                     else

                           ::strcat(opts,"378");

                     pIntf->pCfg->SetOptions( m_SdTiHndl, opts );

 

                     // Set the board file path

                     ::memset( opts, 0,MAX_NAME_SIZE);

                     ::strcpy( opts, "DevBoardName=" );

                     if( !m_sBoardFile.empty() )

                     {

                           ::strncat(opts,m_sBoardFile.c_str(),

  MAX_NAME_SIZE-14 );

                           pIntf->pCfg->SetOptions( m_SdTiHndl, opts );

                     }

 

 

                     // Set the processor name.  The name is max of 8 characters

                     // per TI name spec.

                     ::memset( opts, 0,MAX_NAME_SIZE);

                     ::strcpy( opts, "DevProcName=" );

                     if( !m_sProcessorName.empty() )

                     {

                           ::strncat(opts,m_sProcessorName.c_str(),8 );

                           pIntf->pCfg->SetOptions( m_SdTiHndl, opts );

                     }

 

            }

 

4.4     GetOptions() NOT supported in version 1

Will be supported in a future version.

 

4.5     FreeOptions()

FreeOptions will free the current options and return to the default state.  FreeOptions can only be called with in the disconnected state.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 


 

4.6     Connect()

Connect will attempt to make a physical connection to the target processor.  When used with a Spectrum Digital emulator this will include loading low level emulation drivers as required, initializing the drivers then making the target connection.  The target connection will be made using the default options or those setup with the SetOptions function.  Following a call to Connect, you can then check to see if the target processor is running or halted and retrieve any errors that may have occurred.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 

 

4.7     Disconnect()

Disconnect will make a physical disconnection from the connected target processor.  When disconnected no emulation accesses are allowed.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 

 

Notes

When disconnected the user may cycle power on the target(s).  When a subsequent Connect is made the emulation drivers will be reinitialized. In a multiprocessor environment ALL processors have to be disconnected before power is removed.

4.8     GetErrorString() Not supported in version 1

Will be supported in a future version.  You can still get an error number from the event queue for all errors.  If the error is generated in the SDTI interface then an SDTI interface error will be queued.  If the error originates is a lower layer of software then that lower level error will be queued.  See the sdti.h file for SDTI error codes.

 


 

 

5.     Register Interface

The register interface is defined as:

 

typedef struct sdf_reg

{

    int      StructSz;           // Size of this structure

    int      Version;            // Interface major version                   

    int      Revision;           // Interface minor revision       

 

    BOOL     (*ReadByName) ( SDTI_HNDL Hndl, char *pRegName, TREG *pReg );

    BOOL     (*WriteByName)( SDTI_HNDL Hndl, char *pRegName, TREG *pReg );

}SDF_REG, *PSDF_REG;

 

All processor registers are accessed using a name string.  The register name corresponds to the data book name for the register.  For each processor a file named stdi_regxxx.c is provided which contains all the registers and their access size used by SDTI.  The user can include this C file in the application or simply use the data contained in this file for register accesses.

5.1     ReadByName()

Read ONE register by name.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

char *pRegName             Register name string

TREG *pReg           Pointer to structure to hold the returned register data.

 

 

Output

Returns TRUE or FALSE. 

 

Notes

TREG is a union of all registers sizes so use the proper access type for each register based on the support file sdti_regxxx.c.

 

5.2     WriteByName()

Write ONE register by name.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

char *pRegName             Register name string

TREG *pReg           Pointer to structure to hold the input register data.

 

 

Output

Returns TRUE or FALSE. 

 

Notes

TREG is a union of all registers sizes so use the proper access type for each register based on the support file sdti_regxxx.c.


The following example shows a 16-bit and 32-bit register write.  The C54x example is using the extended PC model, which requires special handling.

 

BOOL CFixedPointDSP::RunFromSymbol(char * name)

{

       struct SYMBOL * s;

       TREG Pc;

 

       SD_TARGET_INTERFACE * pIntf = (SD_TARGET_INTERFACE *)m_pIntf;

 

       if(!(      ( pIntf        != NULL )

              && ( m_SdTiHndl    != NULL )

              && (m_isConnected  == TRUE )))

              return( FALSE );

 

       s = find_sym(name);

       if (s == (struct SYMBOL *)NULL )

          return( FALSE );   

 

 

       if( pIntf->pReg->WriteByName != NULL)

       {

              if( m_dsp == DSP_C54X )

              {

                     Pc.Reg32 = s->symaddr >> 16;

                     if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_VAL", &Pc )==FALSE )

                           return( FALSE );

 

                     Pc.Reg32 = s->symaddr;

                     if( pIntf->pReg->WriteByName( m_SdTiHndl, "EXT_PC", &Pc )==FALSE )

                           return( FALSE );

              }

              else

              {

                     Pc.Reg32 = s->symaddr;

 

                     if( pIntf->pReg->WriteByName( m_SdTiHndl, "PC", &Pc ) == FALSE )

                           return( FALSE );

              }

       }

 

       return( TRUE );

}

 


 

6.     Memory Interface

The memory interface is defined as:

 

typedef struct sdf_mem

{

    int      StructSz;           // Size of this structure

    int      Version;            // Interface major version                    

    int      Revision;           // Interface minor revision       

   

    BOOL     (*Read)      ( SDTI_HNDL Hndl, TMEM_DESC *pMem );

    BOOL     (*Write)     ( SDTI_HNDL Hndl, TMEM_DESC *pMem );

    BOOL     (*Fill)      ( SDTI_HNDL Hndl, TMEM_DESC *pMem );

}SDF_MEM, *PSDF_MEM;

 

To support a wide range of memory types and processors a generic method of specifying memory is used.  This is a combination of both DSP and non-DSP memory types.

 

MEM_SPACE tells SDTI which memory bus or space to use for the access. 

 

typedef enum mem_space

{

    M_NATURAL = 0,          // Natural space for processor, !Harvard

    M_PROGRAM,              // Program space

    M_DATA,                 // Data space

    M_IO                    // I/O space

}MEM_SPACE, * PMEM_SPACE;

 

MEM_ACCESS_SIZE tells SDTI what type of memory access to make for the associated memory space. In general the M_SIZE_NATURAL should be used for non-DSP processors.   However on some processors a smaller access size must be made to certain memory ranges.  When loading a TI COFF file the type M_COFF should be used for dual endian processors.  This preserves the special handling of  COFF for those TI processors. 

 

 

typedef enum mem_access_size

{

    M_SIZE_NATURAL = 0,     // Natural size of processor memory bus

    M_SIZE8,                // 8-Bit

    M_SIZE16,               // 16-Bit

    M_SIZE32,               // 32-Bit

    M_SIZE64,               // 64-Bit

    M_COFF                  // Preserve TI-COFF accesses

}MEM_ACCESS_SIZE, * PMEM_ACCESS_SIZE;

 

M_SIZE_NATURAL is defined as the natural access size for the attached processor.  For each processor supported this corresponds to the following:

 

Processor             M_SIZE_NATURAL (native type)    M_COFF Needed

C2xx                        M_SIZE16                                                                             No

C54x                        M_SIZE16                                                                             No

C27x                        M_SIZE16                                                                             No

C55x                        M_SIZE8                                                                               No

ARM7                    M_SIZE32                                                                             Yes

 

SDTI uses an unsigned long for all memory addresses.

typedef unsigned long   MEM_TADDR;  // 32 Bit memory address


 

 

For version 1 of the memory interface the Asize and Bsize must be the same.  In future versions a variable Bsize will be supported.  This will allow SDTI to insert/extract target data into an application specified data format.  Memory functions pass the following descriptor:

 

typedef struct tmem

{

    MEM_TADDR           Taddr;      // Target address

    MEM_SPACE           Space;      // Target memory space

    MEM_ACCESS_SIZE     Asize;      // Target memory access size

    MEM_ACCESS_SIZE     Bsize;      // Host memory buffer access size

    unsigned long       Length;     // Number of elements in ACCESS_SIZE

    void            *   pData;      // Src/Dst data

} TMEM_DESC, *PTMEM_DESC;

 

6.1     Read(),Write(), Fill()

Access a block of target memory.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

TMEM_DESC *pMem       Pointer to memory access descriptor

   

pMem->Taddr

                Starting target address.

pMem->Space

                Memory space to access.

pMem->Asize

                Access size for the memory.

pMem->Bsize

Buffer size for the memory access.  Must be set to Asize for version 1 of the SDTI.

pMem->Length

                Number of Asize elements to access.

pMem->pData

Pointer to the input/output data buffer.   The buffer type should match the size in bits of Asize.  For example for MSIZE_16 the buffer should be defined as unsigned short, or short.

 

 

Output

Returns TRUE or FALSE. 

 


 

The following code fragment is reading COFF data and writing to the target.  This fragment shows support for a program and data space write as well as an 8-bit and 16-bit write.  The 16-bit write is for the C54x/C2xx while the 8 bit is for the C55xx.   Neither of these processors requires special handling of COFF data.

 

for( i=1; i<= NumSections; i++ )

{

    if (  COFFR_IsLoadSection( pCoffHndl, (short)i )

                              != COFF_NOLOADSECT_ERR )

    {

COFFR_GetSectData( pCoffHndl,

                         (short)i,

                          RetBuffer,

                          0,

                         LOCTOBYTE(pCoffHndl, pSectionHdr->s_size),

                         &ActualBytesRead );

 

       TempSection = *pSectionHdr;

       Tmem.Taddr    = pSectionHdr->s_vaddr;

       Tmem.Space    = (pSectionHdr->s_page == 0) ? M_PROGRAM : M_DATA;

       Tmem.Asize    = (m_BytesPerWord == 1) ? M_SIZE8 : M_SIZE16;

       Tmem.Bsize    = (m_BytesPerWord == 1) ? M_SIZE8 : M_SIZE16;

       Tmem.Length   = ActualBytesRead/m_BytesPerWord;

       Tmem.pData    = (void *)(RetBuffer);

       if( pIntf->pMem->Write( m_SdTiHndl, &Tmem ) == FALSE )

       {

              Success = FALSE;

              break;

       }

 

     }/* End of COFFR_IsLoadSection */

     pSectionHdr++;

  }

7.     Event Interface

The user can set conditions on the target to generate events.  Many events are generated by the emulation software or target automatically however other events like software breakpoints need user-defined conditions to cause an event.   The event interface is defined as follows:

 

 

typedef struct sdf_evt

{

    int             StructSz;           // Size of this structure

    int             Version;            // Interface major version                   

    int             Revision;           // Interface minor revision           

   

    BOOL     (*Add)       ( SDTI_HNDL Hndl, TEVT_DESC *pEvt );

    BOOL     (*Delete)    ( SDTI_HNDL Hndl, unsigned EvtId );

}SDF_EVT, *PSDF_EVT;

 

The EVT_TYPE specifies the type of event that has been queued.   To set up a software breakpoint condition you must Add an event of type EVT_SWBP.

 

typedef enum evt_type

{

    EVT_NONE     = 0,               // No event

    EVT_HALT,                       // Target halted, by user or non-brkpoint

    EVT_SWBP,                       // Software

    EVT_HWIAQ,                      // Hardware break, Instruction

    EVT_HWDATA                      // Hardware break, Data access

}EVT_TYPE, * PEVT_TYPE;

 

 

typedef struct tevt

{

    unsigned            EvtId;      // The event Id

    MEM_TADDR           Taddr;      // Target address

    MEM_SPACE           Space;      // Target memory space

    EVT_TYPE            Type;       // Type of breakpoint

} TEVT_DESC, *PTEVT_DESC;

7.1     Add()

Add a breakpoint event condition.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

TEVT_DESC *pEvt       Pointer to the event descriptor

 

       PEvt->Taddr

              Target address to add the event.

       PEvt->Space

              Target memory space to add the event.

       PEvt->Type

              Type of event.

 

 

Output

Returns TRUE or FALSE. 

 

pEvt->EvtId

An id number used to identify the event for use by Delete.

 

Notes

Version 1 of SDTI limits events that can be added to software breakpoints (EVT_SWBP) in program memory (M_PROGRAM).

 

7.2     Delete()

Delete an event that was set with event Add.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

unsigned EvtId             The event id returned from Add()

 

Output

Returns TRUE or FALSE. 


 

8.     Execution Interface

 

typedef struct sdf_exe

{

    int             StructSz;           // Size of this structure

    int             Version;            // Interface major version                   

    int             Revision;           // Interface minor revision           

   

    BOOL     (*Reset)      ( SDTI_HNDL Hndl );

    BOOL     (*Continue)   ( SDTI_HNDL Hndl );

    BOOL     (*Suspend)    ( SDTI_HNDL Hndl );

    BOOL     (*Step)       ( SDTI_HNDL Hndl, unsigned long Count );

    BOOL     (*UserMode)   ( SDTI_HNDL Hndl );

    BOOL     (*IsRunning)  ( SDTI_HNDL Hndl );

    BOOL     (*IsEvent)    ( SDTI_HNDL Hndl, TEVT_STAT_DESC *pEvtStat );

 

}SDF_EXE, *PSDF_EXE;

 

8.1     Reset()

Perform target processor reset.  Following a Reset the target processor should be in a suspend state. However you should make a call to IsRunning to verify this condition.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 

 

8.2     Continue()

Continue target processor execution from its current state.  If a breakpoint is pending then step over the breakpoint and continue.  Following a Continue the target processor should be in a non-suspend state until it is stopped by the user or executes and event condition that would suspend execution.  Interrupts are active during Continue if enabled by the target application.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 

 

8.3     Suspend()

Suspend target processor execution. Following a Suspend the target processor should be in a suspend state. However you should make a call to IsRunning to verify this condition.

 

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 

 

8.4     Step()

Step the target processor Count instructions or until an event occurs, with interrupts disabled. Following a Step the target processor should be in a suspend state. However you should make a call to IsRunning to verify this condition.

 

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

Unsigned long              Count

 

Output

Returns TRUE or FALSE. 

 

8.5     UserMode()

Return the target processor to user mode and continue execution.   The caller must remove breakpoints prior to calling UserMode.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 

 

8.6     IsRunning()

Is the processor running or not suspended?   The target is considered to be running until it is successfully suspended.

 

Input

SDTI_HNDL Hndl             Handle created by CreateHndl()

 

Output

Returns TRUE or FALSE. 


 

8.7     IsEvent()

Is there an event in the event queue? 

 

Input

SDTI_HNDL Hndl                    Handle created by CreateHndl()

TEVT_STAT_DESC *pEvtStat   Pointer to return a pending event

 

Output

Returns TRUE or FALSE.

 

EvtStat.  If pEvtStat is not NULL and an event is pending then the top pending event is returned.

                pEvtStat->EvtId

Queued event Id. This Id is an incrementing number which corresponds to the Nth event queued. This is NOT the event Id that was returned from Evt->Add().

pEvtStat->Taddr  

       An address associated with the event/error if applicable, else 0.

 

pEvtStat->Space  

       The space associated with the event/error if applicable, else 0.

 

pEvtStat->Type 

       The type of non-system event if applicable else, 0.   

 

   

pEvtStat->System

       The type of system event if applicable else, 0.

 

pEvtStat->Error

       The associated error if applicable else, 0.

 

Notes

All events are returned via IsEvent.  If you simply want to know if an event is pending then call IsEvent with pEvtStat=NULL.  This allows the application to test for the occurrence of an event but defer processing to later.  IsEvent will return TRUE as long as 1 or more events remain in the queue.  To dequeue an event you have to call IsEvent with pEvtStat as non-NULL.  The event queue includes both target events as well at target/system errors.  So while processing events you have to distinguish between events and errors.

 


 

Processing Error Events

 

The following code fragment is an example of error event processing.  If a valid error event occurs then a message is printed to let the user know if this is an SDTI error or OTIS driver error.  OTIS errors come from the sdgoxxx.dvr and lower level drivers.

 

 

BOOL CFixedPointDSP::CheckEvents( void )

{

    TEVT_STAT_DESC    StatEvt;

    BOOL              isEvt;

    SD_TARGET_INTERFACE * pIntf = (SD_TARGET_INTERFACE *)m_pIntf;

      

   if(    ( pIntf      == NULL)

       || ( m_SdTiHndl == NULL ))

              return( FALSE );

 

    // Get the target event if there is one

    isEvt = pIntf->pExe->IsEvent( m_SdTiHndl, &StatEvt );

 

    if( isEvt )

    {

       if( StatEvt.System == EVT_SYS_NONE )

       {

              // This should not occur but here for safety

              if( StatEvt.Error )

              {

                     //If we have a DISCONNECTED error then return isEvt==FALSE.

                     //If you are disconnected you will always get a disconnected

                     //error, i.e. an endless loop

                     //

                     if( StatEvt.Error == CFG_ERR_DISCONNECTED )

                           return( FALSE );

                     else

                           OutputMessage(0,"MSG: Execution event detected\n");

              }

       }

       else

       {

              // If system warning event then do not send error message.

              // These are for internal processing.  Return that we saw

              // an event so that caller can continue processing other

              // events as required.

              if( StatEvt.System == EVT_SYS_WARN )

                     return( isEvt );

              else

              {

                     //If we have a DISCONNECTED error then return isEvt==FALSE.

                     //If you are disconnected you will always get a disconnected

                     //error, i.e. an endless loop

                     //

                     if( StatEvt.Error == CFG_ERR_DISCONNECTED )

                           return( FALSE );

 

                     // Real errors in SDTI or OTIS

                     if( StatEvt.Error > (CFG_ERR_GENERIC -1 ) )

                           ::sprintf( m_ErrMsg,"ERR: SDTI error,

                                         Error =  %d\n",StatEvt.Error);

                     else if ( StatEvt.Error < 0 )    

                     ::sprintf( m_ErrMsg,"ERR: OTIS error,

                                         Error = %d\n",StatEvt.Error);

 

              OutputMessage(0, m_ErrMsg );

              }

       }

   }

   return( isEvt );


 

The following code fragment shows the use of  pExe->Continue followed by a wait for breakpoint loop.

 

                // Clear the event queue before starting new execution.

       while( CheckEvents() );

 

       if( pIntf->pExe->Continue != NULL)

              if( pIntf->pExe->Continue( m_SdTiHndl ) == FALSE )

                     goto EXIT_TARG_EXECUTE;

    

       // Set the timeout and loop looking for an error or breakpoint event

       timeout = m_nEraseTimeout*TIMEOUT;

 

       do

       {

              TEVT_STAT_DESC    StatEvt;

              BOOL              isEvt;

 

              isEvt = pIntf->pExe->IsEvent( m_SdTiHndl, &StatEvt );

              if( isEvt )

              {

                     if( StatEvt.System )

                           goto EXIT_TARG_EXECUTE;

 

                     if( StatEvt.Type == EVT_SWBP )

                           break;

              }

              else

                     Sleep(1);

 

       }while( timeout-- );

 

       if ( timeout < 0 )

       {

              OutputMessage(0,"ERR: Exceeded algorithm initialization timeout.\n");

 

              goto EXIT_TARG_EXECUTE;

       }

 

               


 

9.     SDTI.H

 

/*H***************************************************************************

*

* $Archive:: /TI/product/sdtsrv/user/Sdti.h                                  $

* $Revision:: 3                                                              $

* $Date:: 11/30/00 8:44a                                                     $

* $Author:: Tonyc                                                            $

*

* DESCRIPTION:

*

* USAGE/LIMITATIONS:

*

* NOTES:

*  

* (C) Copyright 2000 by Spectrum Digital Incorporated

* All rights reserved

*

*H***************************************************************************/

 

#ifndef sdti_h

#define sdti_h

 

/*---- compilation control switches ----------------------------------------*/

 

/*****************************************************************************

* INCLUDE FILES (minimize nesting of header files)

*****************************************************************************/

#if defined( _WIN32 )

    #if (_MSC_VER >= 900 )

       #define       WIN32_LEAN_AND_MEAN

       #define       INC_OLE2

       #define       NOSERVICE

    #endif

 

    #include <windows.h>

#else 

    #include <stdlib.h>

    #include <string.h>

    #include <file.h>

       // Define BOOL if not in a WIN32 environment

       #define BOOL int  

#endif

/*---- system and platform files -------------------------------------------*/

 

/*---- program files -------------------------------------------------------*/

 

/*****************************************************************************

* FILE CONTENT

*****************************************************************************/

#ifdef __cplusplus

extern "C" {

#endif


 

/*****************************************************************************

* FUNCTIONAL AREA DETAIL

*****************************************************************************/

//----------------------------------------------------------------------------

// Interface Version/Revision

//

#define SDTI_VERSION        1

#define SDTI_REVISION       1

 

//----------------------------------------------------------------------------

// Sub-Interface Version/Revision

//

#define SDTI_CFG_VERSION        1

#define SDTI_CFG_REVISION       1

 

#define SDTI_REG_VERSION        1

#define SDTI_REG_REVISION       1

 

#define SDTI_MEM_VERSION        1

#define SDTI_MEM_REVISION       1

 

#define SDTI_EVT_VERSION        1

#define SDTI_EVT_REVISION       1

 

#define SDTI_EXE_VERSION        1

#define SDTI_EXE_REVISION       1

 

//----------------------------------------------------------------------------

// Interface handle

//

typedef void * SDTI_HNDL;

 

//----------------------------------------------------------------------------

// Target register types

//

typedef unsigned char  TREG_8;                  // 8-bit register

typedef unsigned short TREG_16;                 // 16-bit register

typedef unsigned long  TREG_32;                 // 32-bit register

 

typedef struct treg_64                                 // 33-64 bit register

{

    unsigned long   RegL;

    unsigned long   RegH;

}TREG_64, *PTREG_64;

 

typedef union treg

{

    TREG_8   Reg8;

    TREG_16  Reg16;

    TREG_32  Reg32;

    TREG_64  Reg64;

}TREG, * PTREG;

 

// TREG_DESC is used by sdti_regXXX.c to describe each target register

//

typedef struct treg_desc

{

    char    *pRegName;            // Register name, hopefully match the data book

    int     RegSize;       // Read/Write size of the register

    int     RegId;                // An Id for the register, not really used

} TREG_DESC, * PTREG_DESC;


 

//----------------------------------------------------------------------------

// Target memory types

//

// For Harvard devices the memory space can be Program or Data.  For

// compatibility with TI DSP there is also an I/O space.

// If the processor is not Harvard then use the default of M_NATURAL.

//

// MEM_ACCESS_SIZE provides a way to force target processor accesses

// to a certain access boundary.  This is generally required by byte

// addressable processors with I/O device access size restrictions.

// Some common rules to apply:

//

// 1) If your processor is a 16 bit fixed point DSP that can only

//    perform 16 bit read/writes then use M_SIZE16 or M_SIZE_NATURAL.

//

// 2) If your processor is a 32 bit fixed point DSP that can only

//    perform 32 bit read/writes then use M_SIZE32 or M_SIZE_NATURAL.

//

// 3) If you processor is a byte addressable machine and you are

//    fetching program or data memory then M_SIZE_NATURAL is recommended.

//    Else, use the size that matches your processor bus width.

//

// 4) For other cases use the size that matches the access restrictions

//    of your I/O or memory devices.

//

// The arguments in TMEM_DESC are pretty obvious with exception

// of Asize and Bsize.  Asize is the access size of the processor

// memory read/write operation, see rules above.  Bsize is the

// size of an element in the read/write buffer.  By having the

// Bsize option the user can pass in a pointer to a 32 bit buffer

// that only has 16 bits of valid data in each 32 bit element.

// Example:

//    unsigned long  *pD32;

//    unsigned short *pD16;

//

//    *pD32++ = (unsigned long)(*pD16++) & 0x0000FFFFL;

//

// Another example is when the buffer size is smaller then the

// target processor access size.  This is generally the case

// on a fixed point DSP where you want "char" data that is

// 8 bit instead of the 16 bit DSP "char".

// Example:

//     unsigned char *pD8;   // Host 8 bit char data

//     unsigned char *pD16;  // DSP 16 bit data

// 

//     *pD8++ = (unsigned char)(*pD16++);

//

// When the Asize and Bsize do not match the unused data bits

// are set to zero.

//

typedef enum mem_space

{

    M_NATURAL = 0,          // Natural space for processor, !Harvard

    M_PROGRAM,              // Program space

    M_DATA,                 // Data space

    M_IO                    // I/O space

}MEM_SPACE, * PMEM_SPACE;

 

typedef enum mem_access_size

{

    M_SIZE_NATURAL = 0,     // Natural size of processor memory bus

    M_SIZE8,                // 8-Bit

    M_SIZE16,               // 16-Bit

    M_SIZE32,               // 32-Bit

    M_SIZE64,               // 64-Bit

    M_COFF                  // Preserve TI-COFF accesses

}MEM_ACCESS_SIZE, * PMEM_ACCESS_SIZE;

 

typedef unsigned long   MEM_TADDR;  // 32 Bit memory address

 

typedef struct tmem

{

    MEM_TADDR           Taddr;      // Target address

    MEM_SPACE           Space;      // Target memory space

    MEM_ACCESS_SIZE     Asize;      // Target memory access size

    MEM_ACCESS_SIZE     Bsize;      // Host memory buffer access size

    unsigned long       Length;     // Number of elements in ACCESS_SIZE

    void            *   pData;      // Src/Dst data

} TMEM_DESC, *PTMEM_DESC;

 

//----------------------------------------------------------------------------

// Target event types

//

typedef enum evt_type

{

    EVT_NONE     = 0,               // No event

    EVT_HALT,                       // Target halted, by user or non-brkpoint

    EVT_SWBP,                       // Software

    EVT_HWIAQ,                      // Hardware break, Instruction

    EVT_HWDATA                      // Hardware break, Data access

}EVT_TYPE, * PEVT_TYPE;

 

typedef enum evt_system

{

    EVT_SYS_NONE     = 0,           // No event

       EVT_SYS_WARN,                   // Generic warning, not an error

    EVT_SYS_ERROR,                  // Generic non-target error

    EVT_SYS_TARGET,                 // Generic target error

    EVT_SYS_TARGET_DISCONNECT,      // Target is disconnected

    EVT_SYS_TARGET_LOSSPOWER,       // Target lost power

    EVT_SYS_TARGET_TIMED_OUT,       // Target operation timed out

    EVT_SYS_TARGET_IN_RESET,        // Target is being held in reset

    EVT_SYS_TARGET_NOT_READY,       // Target is being held not ready

    EVT_SYS_TARGET_BUS_FAULT,       // Target performed a bus fault    

}EVT_SYSTEM, * PEVT_SYSTEM;

 

typedef struct tevt

{

    unsigned            EvtId;      // The event Id

    MEM_TADDR           Taddr;      // Target address

    MEM_SPACE           Space;      // Target memory space

    EVT_TYPE            Type;       // Type of breakpoint

} TEVT_DESC, *PTEVT_DESC;

 

typedef struct tevt_stat

{

    // Event information that pertains to breakpoint type events

    unsigned            EvtId;      // The event Id

    MEM_TADDR           Taddr;      // Target address

    MEM_SPACE           Space;      // Target memory space

    EVT_TYPE            Type;       // Type of breakpoint

   

    // Event information that pertains to error type events

    EVT_SYSTEM          System;     // System events

    int                 Error;

}TEVT_STAT_DESC, *PTEVT__STAT_DESC;


 

 

/*A***************************************************************************

* NAME:  Spectrum Digital Target Interface

*

* USAGE: Interface that can sit on top of GTI, OTI or others.  The

*        interface is processor independent and you can specify your

*        "cpu" family during initialization.  Further, argument options that

*        do not cleanly fit into generic data types are passed in as

*        strings.  This allows any number of options to be supported without

*        continually changing the interface.

*

* CONNECTION:

*        The interface has only 1 external function "SDTI_GetInterface. The

*        user calls this functions to get a pointer to the "Interface" which

*        contains configuration information plus all the functions (methods)

*        for the interface. You then access functions as follows:

*

*        pIntf->pCfg->Init(...);

*        pIntf->pCfg->Open(...);

*

*        The function SDTI_GetInterface includes a parameter pTargetFamily.

*        This parameter specifies which target processor you are targeting.

*        If the requested target family is not supported then NULL is

*        returned for the interface.

*

*        This style of interface is most significant when  built as

*        a DLL and explicitly loaded by the caller.  In this case you only

*        have to get a reference to one function "SDTI_GetInterface" then

*        call it to get everything you need to know about the interface.

*

* VERSION/REVISION:

*         The interface provides a version/revision.  The caller should

*         always check for interface version/revision compatibility. 

*         "Version" changes when a significant change to the interface

*         occurs that would effect backward compatibility.  "Revision"

*         changes when a minor change occurs that would not affect backward

*         compatibility.  You can also use sizeof( SD_TARGET_INTERFACE )

*         and compare to "StructSz" for another level of checking.

*

* RETURN :

*         Return types follow the Microsoft convention

*         1 - True/Success.  The function completed without error.

*         0 - False/Failure. The function did not complete without error.

*         The error will be queued into the event queue.

*

* POINTERS :

*         Again following the Microsoft convention all pointer arguments

*         are checked for NULL.  If a pointer is NULL then input arguments

*         are not used and return arguments are not returned.  Example,

*         if you call GetLastError and set pErrString to NULL then no

*         error string is returned. 

*A***************************************************************************/


 

//----------------------------------------------------------------------------

// Interface config functions

//

// CreateHndl : Create a handle for this debug instance.  If pLibPath and

//              pLibName are not NULL then use the specified debug library.

//              Else, pDevName must hold the name of the processor family

//              to connect to.  If all three parameters are provided then

//              pFamily will be used to validate the loaded lib..

//              A valid handle is returned except in the rare case of

//              insufficent host memory.  Thus you can call GetLastError

//              if there is an error during CreateHndl.

//

// FreeHndl :   Free the handle from CreateHndl.  Closes the open

//              debug session if required.  You MUST always call

//              this to release resources if CreateHndl returns

//              a valid handle. FreeHndl will automaticly "Disconnect"

//              if the debug session is still "Connected".

//

// SetOptions : Set the options for this debug session. Options are

//              generally setup prior to connecting to a target.

//              Options are in the form of "EmulatorId=378,...",

//              using a comma seperator and null terminator.  Once

//              connected some options cannot be changed until you

//              disconnect, for example your EmulatorId.

//

// GetOptions : Return the current options.  MaxString is the maximum

//              size of the return string.            

//

// FreeOptions : Free the current options and return to the default

//               state. FreeOptions can only be called when in the

//               disconnected state.  You can change current options

//               by calling SetOptions with the restriction that not

//               all options can be changed while in the connected

//               state.

//

// Connect :     Make a debug connection to the target.  Once connected the

//               target is ready for a debug session.

//

// Disconnect : Disconnect from the debug session. Once disconnected no

//              more target accesses are allowed.

//

// GetErrorString : Get an error string based on the error number

//

//

//----------------------------------------------------------------------------

// Valid device families for the function CreatHndl

#define FAMILY_TMS320C5X               "TMS320C5X"

#define FAMILY_TMS320C3X               "TMS320C3X"

#define FAMILY_TMS320VC3X              "TMS320VC3X"

#define FAMILY_TMS320C4X               "TMS320C4X"

#define FAMILY_TMS320C2XX              "TMS320C2XX"

#define FAMILY_TMS320C54X              "TMS320C54X"  

#define FAMILY_TMS320C6XX              "TMS320C6XX"

#define FAMILY_TMS320C55XX             "TMS320C55XX"

#define FAMILY_TMSR470                 "TMSR470"

#define FAMILY_TMS320C27XX             "TMS320C27XX"


 

typedef struct sdf_cfg

{

    int      StructSz;           // Size of this structure

    int      Version;            // Interface major version                   

    int      Revision;           // Interface minor revision       

 

    // Create/Free handle for debug instance

    BOOL     (*CreateHndl)  ( SDTI_HNDL *pHndl, char *pLibPath, char *pLibName,

                                                char *pFamily );

    BOOL     (*FreeHndl)    ( SDTI_HNDL Hndl );

 

    // Option setup prior to connecting to the target

       BOOL     (*SetOptions)   ( SDTI_HNDL Hndl, char *pOptsString );

    BOOL     (*GetOptions)   ( SDTI_HNDL Hndl, int  MaxString,

                               char *pOptsString );

    BOOL     (*FreeOptions)  ( SDTI_HNDL Hndl );

 

 

    // Connect/Disconnect from the target

    BOOL     (*Connect)      ( SDTI_HNDL Hndl                     );  

    BOOL     (*Disconnect)   ( SDTI_HNDL Hndl                     );

 

    // Get an error string based on the error code

    BOOL     (*GetErrorString) ( SDTI_HNDL Hndl, int Error, int MaxString,

                                                 char *pErrString );

} SDF_CFG, *PSDF_CFG;

 

//----------------------------------------------------------------------------

// Register functions

//

// ReadByName  : Read a target register using the "common" register name as

//               the identifier.

// WriteByName : Write a target register using the "common" register name as

//               the identifier.

//

// Each processor has a register mapping file named "sdti_regCPU.c" where

// CPU is a processor identifier.  Each register is defined as:

//     { "Name", Size, Id }

//     C54x Example:

//        {"IMR",      sizeof(TREG_16),         0 },

//        {"IFR",      sizeof(TREG_16),         1 },

//

typedef struct sdf_reg

{

    int      StructSz;           // Size of this structure

    int      Version;            // Interface major version                   

    int      Revision;           // Interface minor revision       

 

    BOOL     (*ReadByName) ( SDTI_HNDL Hndl, char *pRegName, TREG *pReg );

    BOOL     (*WriteByName)( SDTI_HNDL Hndl, char *pRegName, TREG *pReg );

}SDF_REG, *PSDF_REG;

 

//----------------------------------------------------------------------------

// Memory functions

//

// Read  : Read a block of memory.

// Write : Write a block of memory.

// Fill  : Fill a block of memory.

//

// The user can specify a memory type, i.e. program, data, i/o for Harvard(TI),

// or natural for others.

// The user then specifies if the access size is to be 8,16,32,64 bit.

// The length of the block is in "access size" elements.

//

// Data in the memory buffer is passed in host endianess format for the

// specified access size.

//

typedef struct sdf_mem

{

    int      StructSz;           // Size of this structure

    int      Version;            // Interface major version                   

    int      Revision;           // Interface minor revision       

   

    BOOL     (*Read)      ( SDTI_HNDL Hndl, TMEM_DESC *pMem );

    BOOL     (*Write)     ( SDTI_HNDL Hndl, TMEM_DESC *pMem );

    BOOL     (*Fill)      ( SDTI_HNDL Hndl, TMEM_DESC *pMem );

}SDF_MEM, *PSDF_MEM;

 

 

//----------------------------------------------------------------------------

// Event functions

//

// Add    : Add an event.  An event Id is returned.

// Delete : Delete an event based on EvtId.

//

typedef struct sdf_evt

{

    int             StructSz;           // Size of this structure

    int             Version;            // Interface major version                   

    int             Revision;           // Interface minor revision           

   

    BOOL     (*Add)       ( SDTI_HNDL Hndl, TEVT_DESC *pEvt );

    BOOL     (*Delete)    ( SDTI_HNDL Hndl, unsigned EvtId );

}SDF_EVT, *PSDF_EVT; 

 

//----------------------------------------------------------------------------

// Execution functions

//

// Reset : Do a hardware or software reset on the connected target.

// Continue : Continue target execution from the current program address.

// Suspend  : Suspend target execution.

// Step  : Step "Count" assembly instructions with interrupts off.

// UserMode : Continue target execution in user mode, i.e. connected but

//            debug disabled.

// IsRunning : Is the target processor running or suspended.  The

//             target is considered "running" until it is SUCCESSFULLY

//             suspended. 

// IsEvent : Is an event pending. If pEvtStat is not NULL then return the

//             pending event.

//           

// IsEvent returns all events, i.e. breakpoints, errors, status, etc..

// As long as events are in the queue IsEvent will return "TRUE".

//

typedef struct sdf_exe

{

    int             StructSz;           // Size of this structure

    int             Version;            // Interface major version                   

    int             Revision;           // Interface minor revision           

   

    BOOL     (*Reset)      ( SDTI_HNDL Hndl );

    BOOL     (*Continue)   ( SDTI_HNDL Hndl );

    BOOL     (*Suspend)    ( SDTI_HNDL Hndl );

    BOOL     (*Step)       ( SDTI_HNDL Hndl, unsigned long Count );

    BOOL     (*UserMode)   ( SDTI_HNDL Hndl );

    BOOL     (*IsRunning)  ( SDTI_HNDL Hndl );

    BOOL     (*IsEvent)    ( SDTI_HNDL Hndl, TEVT_STAT_DESC *pEvtStat );

 

}SDF_EXE, *PSDF_EXE;

 

 

typedef struct sd_target_interface

{

    int             StructSz;           // Size of this structure

    int             Version;            // Interface major version                   

    int             Revision;           // Interface minor revision                 

    int             Type;               // Interface type        

    int             isInitalized;       // True if intf. autoinit

    char    *       Name;               // Interface name, will contain the

                                        // target family name

    unsigned long   Flags;              // Operation flags          

 

    SDF_CFG       * pCfg;               // Interface config functions

    SDF_REG       * pReg;               // Register functions

    SDF_MEM       * pMem;               // Memory functions

    SDF_EVT       * pEvt;               // Event functions

    SDF_EXE       * pExe;               // Execution functions

 

}SD_TARGET_INTERFACE, *PSD_TARGET_INTERFACE ;


 

typedef enum sdti_errors

{

    ERR_NONE            = 0,

 

    // Config errors

    CFG_ERR_GENERIC     = 4000,

    GFG_ERR_HOST_MALLOC,                // Fail host memory malloc

    CFG_ERR_LIB_HANDLE,                 // Could not get targ lib handle

    CFG_ERR_LIB_INTERFACE,              // Invalid lib interface

    CFG_ERR_LIB_VERSION,                // Invalid lib version

    CFG_ERR_FAMILY,                     // Invalid processor family

    CFG_ERR_UNKNOWN_OPTION,             // Unknown/unsupported option

    CFG_ERR_HANDLE,                     // Passed handle is invalid

    CFG_ERR_DISCONNECTED,               // Invalid action when targ disconnected

   

    // Register errors

    REG_ERR_GENERIC = 5000,

    REG_ERR_NAME,                       // Invalid register name

 

    // Memory errors

    MEM_ERR_GENERIC = 6000,

    MEM_ERR_SPACE,                      // Invalid memory space

    MEM_ERR_ACCESS_SIZE,                // Access size not supported

    MEM_ERR_ADDRESS,                    // Invalid or out of range address

 

    // Event errors

    EVT_ERR_GENERIC = 7000,

    EVT_ERR_ADDRESS,                    // Invalid or out of range address

    EVT_ERR_SPACE,                      // Invalid memory space

    EVT_ERR_TYPE,                       // Unsupported event type

 

    // Execution errors

    EXE_ERR_GENERIC = 8000,

    EXE_ERR_TARGET_RUNNING              // Invalid action while running

}SDTI_ERRORS, * PSDTI_ERRORS;

 

 

/*---- global data declarations --------------------------------------------*/

 

/*---- global function prototypes ------------------------------------------*/

#ifdef GLOBAL

    #undef GLOBAL

#endif

#ifdef sdti_c

   #define GLOBAL

#else

   #define GLOBAL extern

#endif

 

GLOBAL int

SDTI_GetInterface( void ** pInterface, char *pFamily );

 

#ifdef __cplusplus

}

#endif

 

#endif /* inf_h ------- END OF FILE ----------------------------------------*/


10.     C2xx Details

10.1     C2xx Register Names

The C2xx supports the following register names and sizes.  This is extracted from sdti_reg2xx.c.

 

#define NOT_USED  0

 

TREG_DESC SDTI_RegDef_2xx[] =

{

    {"PC",       sizeof(TREG_16),        NOT_USED},  // PC

    {"AR0",      sizeof(TREG_16),        NOT_USED},  // FP

    {"AR1",      sizeof(TREG_16),        NOT_USED},  // SP

    {"AR2",      sizeof(TREG_16),        NOT_USED},

    {"AR3",      sizeof(TREG_16),        NOT_USED},

    {"AR4",      sizeof(TREG_16),        NOT_USED},

    {"AR5",      sizeof(TREG_16),        NOT_USED},

    {"AR6",      sizeof(TREG_16),        NOT_USED},

    {"AR7",      sizeof(TREG_16),        NOT_USED},

    {"ACC",      sizeof(TREG_32),        NOT_USED},

    {"ACCH",     sizeof(TREG_16),        NOT_USED},

    {"ACCL",     sizeof(TREG_16),        NOT_USED},

    {"PR",       sizeof(TREG_32),        NOT_USED},

    {"PRH",      sizeof(TREG_16),        NOT_USED},

    {"PRL",      sizeof(TREG_16),        NOT_USED},

    {"TR",       sizeof(TREG_16),        NOT_USED},

    {"GREG",     sizeof(TREG_16),        NOT_USED},

    {"IFR",      sizeof(TREG_16),        NOT_USED},

    {"IMR",      sizeof(TREG_16),        NOT_USED},

    {"ST0",      sizeof(TREG_16),        NOT_USED},

    {"ST1",      sizeof(TREG_16),        NOT_USED},

    {"TOS",      sizeof(TREG_16),        NOT_USED},

    {"RPTC",     sizeof(TREG_16),        NOT_USED},

    {(char *)NULL,             0,        NOT_USED}

};


 

11.     C54x Details

11.1     C54x Register Names

The C54x supports the following register names and sizes.  This is extracted from sdti_reg54x.c.

 

#define NOT_USED  0

 

TREG_DESC SDTI_RegDef_54x[] =

{

    {"PC",       sizeof(TREG_16),        NOT_USED},  // PC

    {"SP",       sizeof(TREG_16),        NOT_USED},  // SP

    {"AR0",      sizeof(TREG_16),        NOT_USED},  //

    {"AR1",      sizeof(TREG_16),        NOT_USED},

    {"AR2",      sizeof(TREG_16),        NOT_USED},

    {"AR3",      sizeof(TREG_16),        NOT_USED},

    {"AR4",      sizeof(TREG_16),        NOT_USED},

    {"AR5",      sizeof(TREG_16),        NOT_USED},

    {"AR6",      sizeof(TREG_16),        NOT_USED},

    {"AR7",      sizeof(TREG_16),        NOT_USED},

    {"A",        sizeof(TREG_32),        NOT_USED},

    {"AL",       sizeof(TREG_16),        NOT_USED},

    {"AH",       sizeof(TREG_16),        NOT_USED},

    {"AG",       sizeof(TREG_16),        NOT_USED},

    {"B",        sizeof(TREG_32),        NOT_USED},

    {"BL",       sizeof(TREG_16),        NOT_USED},

    {"BH",       sizeof(TREG_16),        NOT_USED},

    {"BG",       sizeof(TREG_16),        NOT_USED},

    {"IMR",      sizeof(TREG_16),        NOT_USED},

    {"IFR",      sizeof(TREG_16),        NOT_USED},

    {"ST0",      sizeof(TREG_16),        NOT_USED},

    {"ST1",      sizeof(TREG_16)         NOT_USED},

    {"TREG",     sizeof(TREG_16),        NOT_USED},

    {"TRN",      sizeof(TREG_16),        NOT_USED},

    {"BK",       sizeof(TREG_16),        NOT_USED},

    {"BRC",      sizeof(TREG_16),        NOT_USED},

    {"RSA",      sizeof(TREG_16),        NOT_USED},

    {"REA",      sizeof(TREG_16),        NOT_USED},

    {"PMST",     sizeof(TREG_16),        NOT_USED},

    {"EXT_PC",   sizeof(TREG_32),        NOT_USED},

    {"PMR_ADDR", sizeof(TREG_16),        NOT_USED},

    {"PMR_PAGE", sizeof(TREG_16),        NOT_USED},

    {"PMR_MASK", sizeof(TREG_16),        NOT_USED},

    {"PMR_RANGE",sizeof(TREG_16),        NOT_USED},

    {"PMR_VAL",  sizeof(TREG_16),        NOT_USED},

    {"PMR_ACTIVE",sizeof(TREG_16),       NOT_USED},

    {(char *)NULL,             0,        NOT_USED}

};


 

11.2     C54x Extended Address Support

The C54x supports extended addressing but does require some setup.  The following code example shows how to setup the C54x for extended addressing.

 

BOOL CFixedPointDSP::SetupExtendedAddressing( void )

{

 

       TREG Reg;

 

       SD_TARGET_INTERFACE * pIntf = (SD_TARGET_INTERFACE *)m_pIntf;

 

       if(!(     ( pIntf        != NULL)

                     && ( m_SdTiHndl   != NULL )

                     && (m_isConnected == TRUE )))

                     return( FALSE );

 

       if(     (  m_dsp == DSP_C54X )

              &&  ( pIntf->pReg->WriteByName != NULL ))

       {

 

 

              //PMR_ADDR    = 0x001E

              Reg.Reg32 = 0x001E;

              if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_ADDR", &Reg ) == FALSE )

                     return( FALSE );

 

              //PMR_PAGE        = 1

              Reg.Reg32 = 1;

              if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_PAGE", &Reg ) == FALSE )

                     return( FALSE );

 

              //PMR_MASK        = 0x007F

              Reg.Reg32 = 0x007F;

              if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_MASK", &Reg ) == FALSE )

                     return( FALSE );

 

              //PMR_RANGE       = 0x8000

              Reg.Reg32 = 0x8000;

              if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_RANGE", &Reg ) == FALSE )

                     return( FALSE );

 

              //PMR_VAL = 0

              Reg.Reg32 = 0;

              if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_VAL", &Reg ) == FALSE )

                     return( FALSE );

 

              //PMR_ACTIVE      = 1 to enable, 0 to disable

              Reg.Reg32 = 1;

              if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_ACTIVE", &Reg ) == FALSE )

                     return( FALSE );

       }

 

       return( TRUE );

}


 

To set the PC on the C54x requires that you first write the PMR_VAL with the upper byte of the extended address then write the entire 32bit extended PC value to EXT_PC. The following code example is setting the C54x PC when passed the name of a function.

 

BOOL CFixedPointDSP::RunFromSymbol(char * name)

{

       struct SYMBOL * s;

       TREG Pc;

 

       SD_TARGET_INTERFACE * pIntf = (SD_TARGET_INTERFACE *)m_pIntf;

 

       if(!(      ( pIntf        != NULL )

              && ( m_SdTiHndl    != NULL )

              && (m_isConnected  == TRUE )))

              return( FALSE );

 

       s = find_sym(name);

       if (s == (struct SYMBOL *)NULL )

          return( FALSE );   

 

 

       if( pIntf->pReg->WriteByName != NULL)

       {

              if( m_dsp == DSP_C54X )

              {

                     Pc.Reg32 = s->symaddr >> 16;

                     if( pIntf->pReg->WriteByName( m_SdTiHndl, "PMR_VAL", &Pc )==FALSE )

                           return( FALSE );

 

                     Pc.Reg32 = s->symaddr;

                     if( pIntf->pReg->WriteByName( m_SdTiHndl, "EXT_PC", &Pc )==FALSE )

                           return( FALSE );

              }

              else

              {

                     Pc.Reg32 = s->symaddr;

 

                     if( pIntf->pReg->WriteByName( m_SdTiHndl, "PC", &Pc ) == FALSE )

                           return( FALSE );

              }

       }

 

       return( TRUE );

}