URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk
- from Rev 1778 to Rev 1779
- ↔ Reverse comparison
Rev 1778 → Rev 1779
/or_debug_proxy/includes/gdb.h
0,0 → 1,187
/*$$HEADER*/ |
/******************************************************************************/ |
/* */ |
/* H E A D E R I N F O R M A T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Project Name : OpenRISC Debug Proxy |
// File Name : gdb.h |
// Prepared By : jb, rmd |
// Project Start : 2008-10-01 |
|
/*$$COPYRIGHT NOTICE*/ |
/******************************************************************************/ |
/* */ |
/* C O P Y R I G H T N O T I C E */ |
/* */ |
/******************************************************************************/ |
/* |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; |
version 2.1 of the License, a copy of which is available from |
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. |
|
This library 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 |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
*/ |
|
/*$$CHANGE HISTORY*/ |
/******************************************************************************/ |
/* */ |
/* C H A N G E H I S T O R Y */ |
/* */ |
/******************************************************************************/ |
|
// Date Version Description |
//------------------------------------------------------------------------ |
// 081101 First revision, adapted from existing "jp" |
// debug proxy. jb, rmd |
|
#ifndef GDB_H |
#define GDB_H |
|
#include <sys/types.h> |
#include <inttypes.h> |
|
extern void HandleServerSocket(void); |
extern void handle_rsp (void); |
int GetServerSocket(const char* name, const char* proto, int port); |
extern void JTAGRequest(void); |
void setup_or32(void); |
void gdb_close(); |
|
extern int err; |
|
/* All JTAG chains. */ |
enum jtag_chains |
{ |
SC_GLOBAL, /* 0 Global BS Chain */ |
SC_RISC_DEBUG, /* 1 RISC Debug Interface chain */ |
SC_RISC_TEST, /* 2 RISC Test Chain */ |
SC_TRACE, /* 3 Trace Chain */ |
SC_REGISTER, /* 4 Register Chain */ |
SC_WISHBONE, /* 5 Memory chain */ |
SC_BLOCK, /* 6 Block Chains */ |
}; |
|
/* See JTAG documentation about these. */ |
#define JI_SIZE (4) |
enum jtag_instr |
{ |
JI_EXTEST, |
JI_SAMPLE_PRELOAD, |
JI_IDCODE, |
JI_CHAIN_SELECT, |
JI_INTEST, |
JI_CLAMP, |
JI_CLAMPZ, |
JI_HIGHZ, |
JI_DEBUG, |
JI_BYPASS = 0xF |
}; |
|
/* JTAG registers. */ |
#define JTAG_MODER (0x0) |
#define JTAG_TSEL (0x1) |
#define JTAG_QSEL (0x2) |
#define JTAG_SSEL (0x3) |
#define JTAG_RISCOP (0x4) |
#define JTAG_RECWP0 (0x10) |
#define JTAG_RECBP0 (0x1b) |
|
/* This is repeated from gdb tm-or1k.h There needs to be |
a better mechanism for tracking this, but I don't see |
an easy way to share files between modules. */ |
|
typedef enum { |
JTAG_COMMAND_READ = 1, |
JTAG_COMMAND_WRITE = 2, |
JTAG_COMMAND_BLOCK_READ = 3, |
JTAG_COMMAND_BLOCK_WRITE = 4, |
JTAG_COMMAND_CHAIN = 5, |
} JTAG_proxy_protocol_commands; |
|
/* Each transmit structure must begin with an integer |
which specifies the type of command. Information |
after this is variable. Make sure to have all information |
aligned properly. If we stick with 32 bit integers, it |
should be portable onto every platform. These structures |
will be transmitted across the network in network byte |
order. |
*/ |
|
typedef struct { |
uint32_t command; |
uint32_t length; |
uint32_t address; |
uint32_t data_H; |
uint32_t data_L; |
} JTAGProxyWriteMessage; |
|
typedef struct { |
uint32_t command; |
uint32_t length; |
uint32_t address; |
} JTAGProxyReadMessage; |
|
typedef struct { |
uint32_t command; |
uint32_t length; |
uint32_t address; |
int32_t nRegisters; |
uint32_t data[1]; |
} JTAGProxyBlockWriteMessage; |
|
typedef struct { |
uint32_t command; |
uint32_t length; |
uint32_t address; |
int32_t nRegisters; |
} JTAGProxyBlockReadMessage; |
|
typedef struct { |
uint32_t command; |
uint32_t length; |
uint32_t chain; |
} JTAGProxyChainMessage; |
|
/* The responses are messages specific, however convention |
states the first word should be an error code. Again, |
sticking with 32 bit integers should provide maximum |
portability. */ |
|
typedef struct { |
int32_t status; |
} JTAGProxyWriteResponse; |
|
typedef struct { |
int32_t status; |
uint32_t data_H; |
uint32_t data_L; |
} JTAGProxyReadResponse; |
|
typedef struct { |
int32_t status; |
} JTAGProxyBlockWriteResponse; |
|
typedef struct { |
int32_t status; |
int32_t nRegisters; |
uint32_t data[1]; |
/* uint32_t data[nRegisters-1] still unread */ |
} JTAGProxyBlockReadResponse; |
|
typedef struct { |
int32_t status; |
} JTAGProxyChainResponse; |
|
|
#endif /* GDB_H */ |
/or_debug_proxy/includes/win_FTCJTAG.h
0,0 → 1,236
/*++ |
|
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009 |
|
|
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability. |
|
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact. |
|
Copyright (c) 2005 Future Technology Devices International Ltd. |
|
Module Name: |
|
ftcjtag.h |
|
Abstract: |
|
API DLL for FT2232C Dual Device setup to simulate the Joint Test Action Group(JTAG) synchronous protocol. |
FTCJTAG library definitions |
|
Environment: |
|
kernel & user mode |
|
Revision History: |
|
07/02/05 kra Created. |
|
--*/ |
|
|
#ifndef win_FTCJTAG_H |
#define win_FTCJTAG_H |
|
|
// The following ifdef block is the standard way of creating macros |
// which make exporting from a DLL simpler. All files within this DLL |
// are compiled with the FTCJTAG_EXPORTS symbol defined on the command line. |
// This symbol should not be defined on any project that uses this DLL. |
// This way any other project whose source files include this file see |
// FTCJTAG_API functions as being imported from a DLL, whereas this DLL |
// sees symbols defined with this macro as being exported. |
|
#ifdef FTCJTAG_EXPORTS |
#define FTCJTAG_API __declspec(dllexport) |
#else |
#define FTCJTAG_API __declspec(dllimport) |
#endif |
|
typedef DWORD FTC_HANDLE; |
typedef ULONG FTC_STATUS; |
|
#define TEST_LOGIC_STATE 1 |
#define RUN_TEST_IDLE_STATE 2 |
#define PAUSE_TEST_DATA_REGISTER_STATE 3 |
#define PAUSE_INSTRUCTION_REGISTER_STATE 4 |
#define SHIFT_TEST_DATA_REGISTER_STATE 5 |
#define SHIFT_INSTRUCTION_REGISTER_STATE 6 |
|
#define FTC_SUCCESS 0 // FTC_OK |
#define FTC_INVALID_HANDLE 1 // FTC_INVALID_HANDLE |
#define FTC_DEVICE_NOT_FOUND 2 //FTC_DEVICE_NOT_FOUND |
#define FTC_DEVICE_NOT_OPENED 3 //FTC_DEVICE_NOT_OPENED |
#define FTC_IO_ERROR 4 //FTC_IO_ERROR |
#define FTC_INSUFFICIENT_RESOURCES 5 // FTC_INSUFFICIENT_RESOURCES |
|
#define FTC_FAILED_TO_COMPLETE_COMMAND 20 // cannot change, error code mapped from FT2232c classes |
#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 21 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_DEVICE_NAME_INDEX 22 // cannot change, error code mapped from FT2232c classes |
#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 23 // cannot change, error code mapped from FT2232c classes |
#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 24 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_DEVICE_NAME 25 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_LOCATION_ID 26 // cannot change, error code mapped from FT2232c classes |
#define FTC_DEVICE_IN_USE 27 // cannot change, error code mapped from FT2232c classes |
#define FTC_TOO_MANY_DEVICES 28 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_CLOCK_DIVISOR 29 |
#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 30 |
#define FTC_INVALID_NUMBER_BITS 31 |
#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 32 |
#define FTC_INVALID_NUMBER_BYTES 33 |
#define FTC_NUMBER_BYTES_TOO_SMALL 34 |
#define FTC_INVALID_TAP_CONTROLLER_STATE 35 |
#define FTC_NULL_READ_DATA_BUFFER_POINTER 36 |
#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 37 |
#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 38 |
#define FTC_NO_COMMAND_SEQUENCE 39 |
#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 40 |
#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 41 |
#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 42 |
#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 43 |
#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 44 |
#define FTC_INVALID_LANGUAGE_CODE 45 |
#define FTC_INVALID_STATUS_CODE 46 |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_GetNumDevices(LPDWORD lpdwNumDevices); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_GetDeviceNameLocID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_OpenEx(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_Open(FTC_HANDLE *pftHandle); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_Close(FTC_HANDLE ftHandle); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_InitDevice(FTC_HANDLE ftHandle, DWORD dwClockDivisor); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_GetClock(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_SetClock(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_SetLoopback(FTC_HANDLE ftHandle, BOOL bLoopbackState); |
|
typedef struct Ft_Input_Output_Pins{ |
BOOL bPin1InputOutputState; |
BOOL bPin1LowHighState; |
BOOL bPin2InputOutputState; |
BOOL bPin2LowHighState; |
BOOL bPin3InputOutputState; |
BOOL bPin3LowHighState; |
BOOL bPin4InputOutputState; |
BOOL bPin4LowHighState; |
}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS; |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_SetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData, |
BOOL bControlHighInputOutputPins, |
PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData); |
|
typedef struct Ft_Low_High_Pins{ |
BOOL bPin1LowHighState; |
BOOL bPin2LowHighState; |
BOOL bPin3LowHighState; |
BOOL bPin4LowHighState; |
}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS; |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_GetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_LOW_HIGH_PINS pLowPinsInputData, |
BOOL bControlHighInputOutputPins, |
PFTC_LOW_HIGH_PINS pHighPinsInputData); |
|
#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes |
|
typedef BYTE WriteDataByteBuffer[MAX_WRITE_DATA_BYTES_BUFFER_SIZE]; |
typedef WriteDataByteBuffer *PWriteDataByteBuffer; |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_Write(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
#define MAX_READ_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes |
|
typedef BYTE ReadDataByteBuffer[MAX_READ_DATA_BYTES_BUFFER_SIZE]; |
typedef ReadDataByteBuffer *PReadDataByteBuffer; |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_Read(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_WriteRead(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_ClearCmdSequence(void); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_AddWriteCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_AddReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_AddWriteReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 131071 // 128K bytes |
|
typedef BYTE ReadCmdSequenceDataByteBuffer[MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE]; |
typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer; |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_ClearDeviceCmdSequence(FTC_HANDLE ftHandle); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_AddDeviceWriteCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_AddDeviceReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_AddDeviceWriteReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_ExecuteCmdSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, |
LPDWORD lpdwNumBytesReturned); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize); |
|
FTCJTAG_API |
FTC_STATUS WINAPI JTAG_GetErrorCodeString(LPSTR lpLanguage, FTC_STATUS StatusCode, |
LPSTR lpErrorMessageBuffer, DWORD dwBufferSize); |
|
|
#ifdef __cplusplus |
} |
#endif |
|
|
#endif /* win_FTCJTAG_H */ |
/or_debug_proxy/includes/ftd2xx.h
0,0 → 1,952
/*++ |
|
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009 |
|
|
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability. |
|
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact. |
|
Copyright (c) 2001-2006 Future Technology Devices International Ltd. |
|
Module Name: |
|
ftd2xx.h |
|
Abstract: |
|
Native USB interface for FTDI FT8U232/245/2232C |
FTD2XX library definitions |
|
Environment: |
|
kernel & user mode |
|
Revision History: |
|
13/03/01 awm Created. |
13/01/03 awm Added device information support. |
19/03/03 awm Added FT_W32_CancelIo. |
12/06/03 awm Added FT_StopInTask and FT_RestartInTask. |
18/09/03 awm Added FT_SetResetPipeRetryCount. |
10/10/03 awm Added FT_ResetPort. |
/03/04 st modified for linux users |
12/10/04 st added FT_SetVIDPID |
|
|
--*/ |
|
|
#ifndef FTD2XX_H |
#define FTD2XX_H |
|
#ifndef _WINDOWS |
#include <pthread.h> |
#define WINAPI |
#endif |
|
// The following ifdef block is the standard way of creating macros |
// which make exporting from a DLL simpler. All files within this DLL |
// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. |
// This symbol should not be defined on any project that uses this DLL. |
// This way any other project whose source files include this file see |
// FTD2XX_API functions as being imported from a DLL, whereas this DLL |
// sees symbols defined with this macro as being exported. |
|
#ifdef FTD2XX_EXPORTS |
#define FTD2XX_API __declspec(dllexport) |
#else |
#define FTD2XX_API __declspec(dllimport) |
#endif |
|
#ifndef _WINDOWS |
#include "WinTypes.h" |
#ifdef FTD2XX_API |
#undef FTD2XX_API |
#define FTD2XX_API |
#endif |
#endif |
typedef struct _EVENT_HANDLE{ |
pthread_cond_t eCondVar; |
pthread_mutex_t eMutex; |
int iVar; |
} EVENT_HANDLE; |
|
typedef DWORD *FT_HANDLE; |
|
typedef ULONG FT_STATUS; |
|
// |
// Device status |
// |
enum { |
FT_OK, |
FT_INVALID_HANDLE, |
FT_DEVICE_NOT_FOUND, |
FT_DEVICE_NOT_OPENED, |
FT_IO_ERROR, |
FT_INSUFFICIENT_RESOURCES, |
FT_INVALID_PARAMETER, |
FT_INVALID_BAUD_RATE, //7 |
|
FT_DEVICE_NOT_OPENED_FOR_ERASE, |
FT_DEVICE_NOT_OPENED_FOR_WRITE, |
FT_FAILED_TO_WRITE_DEVICE, |
FT_EEPROM_READ_FAILED, |
FT_EEPROM_WRITE_FAILED, |
FT_EEPROM_ERASE_FAILED, |
FT_EEPROM_NOT_PRESENT, |
FT_EEPROM_NOT_PROGRAMMED, |
FT_INVALID_ARGS, |
FT_NOT_SUPPORTED, |
FT_OTHER_ERROR |
}; |
|
|
#define FT_SUCCESS(status) ((status) == FT_OK) |
|
// |
// FT_OpenEx Flags |
// |
|
#define FT_OPEN_BY_SERIAL_NUMBER 1 |
#define FT_OPEN_BY_DESCRIPTION 2 |
#define FT_OPEN_BY_LOCATION 4 |
// |
// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags |
// |
|
#define FT_LIST_NUMBER_ONLY 0x80000000 |
#define FT_LIST_BY_INDEX 0x40000000 |
#define FT_LIST_ALL 0x20000000 |
|
#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) |
|
// |
// Baud Rates |
// |
|
#define FT_BAUD_300 300 |
#define FT_BAUD_600 600 |
#define FT_BAUD_1200 1200 |
#define FT_BAUD_2400 2400 |
#define FT_BAUD_4800 4800 |
#define FT_BAUD_9600 9600 |
#define FT_BAUD_14400 14400 |
#define FT_BAUD_19200 19200 |
#define FT_BAUD_38400 38400 |
#define FT_BAUD_57600 57600 |
#define FT_BAUD_115200 115200 |
#define FT_BAUD_230400 230400 |
#define FT_BAUD_460800 460800 |
#define FT_BAUD_921600 921600 |
|
// |
// Word Lengths |
// |
|
#define FT_BITS_8 (UCHAR) 8 |
#define FT_BITS_7 (UCHAR) 7 |
#define FT_BITS_6 (UCHAR) 6 |
#define FT_BITS_5 (UCHAR) 5 |
|
// |
// Stop Bits |
// |
|
#define FT_STOP_BITS_1 (UCHAR) 0 |
#define FT_STOP_BITS_1_5 (UCHAR) 1 |
#define FT_STOP_BITS_2 (UCHAR) 2 |
|
// |
// Parity |
// |
|
#define FT_PARITY_NONE (UCHAR) 0 |
#define FT_PARITY_ODD (UCHAR) 1 |
#define FT_PARITY_EVEN (UCHAR) 2 |
#define FT_PARITY_MARK (UCHAR) 3 |
#define FT_PARITY_SPACE (UCHAR) 4 |
|
// |
// Flow Control |
// |
|
#define FT_FLOW_NONE 0x0000 |
#define FT_FLOW_RTS_CTS 0x0100 |
#define FT_FLOW_DTR_DSR 0x0200 |
#define FT_FLOW_XON_XOFF 0x0400 |
|
// |
// Purge rx and tx buffers |
// |
#define FT_PURGE_RX 1 |
#define FT_PURGE_TX 2 |
|
// |
// Events |
// |
|
typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); |
|
#define FT_EVENT_RXCHAR 1 |
#define FT_EVENT_MODEM_STATUS 2 |
|
// |
// Timeouts |
// |
|
#define FT_DEFAULT_RX_TIMEOUT 300 |
#define FT_DEFAULT_TX_TIMEOUT 300 |
|
// |
// Device types |
// |
|
typedef ULONG FT_DEVICE; |
|
enum { |
FT_DEVICE_BM, |
FT_DEVICE_AM, |
FT_DEVICE_100AX, |
FT_DEVICE_UNKNOWN, |
FT_DEVICE_2232C, |
FT_DEVICE_232R |
}; |
|
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
FTD2XX_API |
FT_STATUS WINAPI FT_Open( |
int deviceNumber, |
FT_HANDLE *pHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_OpenEx( |
PVOID pArg1, |
DWORD Flags, |
FT_HANDLE *pHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_ListDevices( |
PVOID pArg1, |
PVOID pArg2, |
DWORD Flags |
); |
|
FTD2XX_API |
FT_STATUS FT_SetVIDPID( |
DWORD dwVID, |
DWORD dwPID |
); |
|
FTD2XX_API |
FT_STATUS FT_GetVIDPID( |
DWORD * pdwVID, |
DWORD * pdwPID |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_Close( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_Read( |
FT_HANDLE ftHandle, |
LPVOID lpBuffer, |
DWORD nBufferSize, |
LPDWORD lpBytesReturned |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_Write( |
FT_HANDLE ftHandle, |
LPVOID lpBuffer, |
DWORD nBufferSize, |
LPDWORD lpBytesWritten |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_IoCtl( // Linux, OS X: Not supported |
FT_HANDLE ftHandle, |
DWORD dwIoControlCode, |
LPVOID lpInBuf, |
DWORD nInBufSize, |
LPVOID lpOutBuf, |
DWORD nOutBufSize, |
LPDWORD lpBytesReturned, |
LPOVERLAPPED lpOverlapped |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetBaudRate( |
FT_HANDLE ftHandle, |
ULONG BaudRate |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetDivisor( |
FT_HANDLE ftHandle, |
USHORT Divisor |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetDataCharacteristics( |
FT_HANDLE ftHandle, |
UCHAR WordLength, |
UCHAR StopBits, |
UCHAR Parity |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetFlowControl( |
FT_HANDLE ftHandle, |
USHORT FlowControl, |
UCHAR XonChar, |
UCHAR XoffChar |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_ResetDevice( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetDtr( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_ClrDtr( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetRts( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_ClrRts( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetModemStatus( |
FT_HANDLE ftHandle, |
ULONG *pModemStatus |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetChars( |
FT_HANDLE ftHandle, |
UCHAR EventChar, |
UCHAR EventCharEnabled, |
UCHAR ErrorChar, |
UCHAR ErrorCharEnabled |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_Purge( |
FT_HANDLE ftHandle, |
ULONG Mask |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetTimeouts( |
FT_HANDLE ftHandle, |
ULONG ReadTimeout, |
ULONG WriteTimeout |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetQueueStatus( |
FT_HANDLE ftHandle, |
DWORD *dwRxBytes |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetEventNotification( |
FT_HANDLE ftHandle, |
DWORD Mask, |
PVOID Param |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetStatus( |
FT_HANDLE ftHandle, |
DWORD *dwRxBytes, |
DWORD *dwTxBytes, |
DWORD *dwEventDWord |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetBreakOn( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetBreakOff( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetWaitMask( // Linux, OS X: Not supported |
FT_HANDLE ftHandle, |
DWORD Mask |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_WaitOnMask( // Linux, OS X: Not supported |
FT_HANDLE ftHandle, |
DWORD *Mask |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetEventStatus( |
FT_HANDLE ftHandle, |
DWORD *dwEventDWord |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_ReadEE( |
FT_HANDLE ftHandle, |
DWORD dwWordOffset, |
LPWORD lpwValue |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_WriteEE( |
FT_HANDLE ftHandle, |
DWORD dwWordOffset, |
WORD wValue |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EraseEE( |
FT_HANDLE ftHandle |
); |
|
// |
// structure to hold program data for FT_Program function |
// |
typedef struct ft_program_data { |
|
DWORD Signature1; // Header - must be 0x00000000 |
DWORD Signature2; // Header - must be 0xffffffff |
DWORD Version; // Header - FT_PROGRAM_DATA version |
// 0 = original |
// 1 = FT2232C extensions |
// 2 = FT232R extensions |
|
WORD VendorId; // 0x0403 |
WORD ProductId; // 0x6001 |
char *Manufacturer; // "FTDI" |
char *ManufacturerId; // "FT" |
char *Description; // "USB HS Serial Converter" |
char *SerialNumber; // "FT000001" if fixed, or NULL |
WORD MaxPower; // 0 < MaxPower <= 500 |
WORD PnP; // 0 = disabled, 1 = enabled |
WORD SelfPowered; // 0 = bus powered, 1 = self powered |
WORD RemoteWakeup; // 0 = not capable, 1 = capable |
// |
// Rev4 extensions |
// |
UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise |
UCHAR IsoIn; // non-zero if in endpoint is isochronous |
UCHAR IsoOut; // non-zero if out endpoint is isochronous |
UCHAR PullDownEnable; // non-zero if pull down enabled |
UCHAR SerNumEnable; // non-zero if serial number to be used |
UCHAR USBVersionEnable; // non-zero if chip uses USBVersion |
WORD USBVersion; // BCD (0x0200 => USB2) |
// |
// FT2232C extensions |
// |
UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise |
UCHAR IsoInA; // non-zero if in endpoint is isochronous |
UCHAR IsoInB; // non-zero if in endpoint is isochronous |
UCHAR IsoOutA; // non-zero if out endpoint is isochronous |
UCHAR IsoOutB; // non-zero if out endpoint is isochronous |
UCHAR PullDownEnable5; // non-zero if pull down enabled |
UCHAR SerNumEnable5; // non-zero if serial number to be used |
UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion |
WORD USBVersion5; // BCD (0x0200 => USB2) |
UCHAR AIsHighCurrent; // non-zero if interface is high current |
UCHAR BIsHighCurrent; // non-zero if interface is high current |
UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO |
UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target |
UCHAR IFAIsFastSer; // non-zero if interface is Fast serial |
UCHAR AIsVCP; // non-zero if interface is to use VCP drivers |
UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO |
UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target |
UCHAR IFBIsFastSer; // non-zero if interface is Fast serial |
UCHAR BIsVCP; // non-zero if interface is to use VCP drivers |
// |
// FT232R extensions |
// |
UCHAR UseExtOsc; // Use External Oscillator |
UCHAR HighDriveIOs; // High Drive I/Os |
UCHAR EndpointSize; // Endpoint size |
|
UCHAR PullDownEnableR; // non-zero if pull down enabled |
UCHAR SerNumEnableR; // non-zero if serial number to be used |
|
UCHAR InvertTXD; // non-zero if invert TXD |
UCHAR InvertRXD; // non-zero if invert RXD |
UCHAR InvertRTS; // non-zero if invert RTS |
UCHAR InvertCTS; // non-zero if invert CTS |
UCHAR InvertDTR; // non-zero if invert DTR |
UCHAR InvertDSR; // non-zero if invert DSR |
UCHAR InvertDCD; // non-zero if invert DCD |
UCHAR InvertRI; // non-zero if invert RI |
|
UCHAR Cbus0; // Cbus Mux control |
UCHAR Cbus1; // Cbus Mux control |
UCHAR Cbus2; // Cbus Mux control |
UCHAR Cbus3; // Cbus Mux control |
UCHAR Cbus4; // Cbus Mux control |
|
UCHAR RIsVCP; // zero if using VCP drivers |
|
} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; |
|
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_Program( |
FT_HANDLE ftHandle, |
PFT_PROGRAM_DATA pData |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_ProgramEx( |
FT_HANDLE ftHandle, |
PFT_PROGRAM_DATA lpData, |
char *Manufacturer, |
char *ManufacturerId, |
char *Description, |
char *SerialNumber |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_Read( |
FT_HANDLE ftHandle, |
PFT_PROGRAM_DATA pData |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_ReadEx( |
FT_HANDLE ftHandle, |
PFT_PROGRAM_DATA lpData, |
char *Manufacturer, |
char *ManufacturerId, |
char *Description, |
char *SerialNumber |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_UASize( |
FT_HANDLE ftHandle, |
LPDWORD lpdwSize |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_UAWrite( |
FT_HANDLE ftHandle, |
PUCHAR pucData, |
DWORD dwDataLen |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_EE_UARead( |
FT_HANDLE ftHandle, |
PUCHAR pucData, |
DWORD dwDataLen, |
LPDWORD lpdwBytesRead |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetLatencyTimer( |
FT_HANDLE ftHandle, |
UCHAR ucLatency |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetLatencyTimer( |
FT_HANDLE ftHandle, |
PUCHAR pucLatency |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetBitMode( |
FT_HANDLE ftHandle, |
UCHAR ucMask, |
UCHAR ucEnable |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetBitMode( |
FT_HANDLE ftHandle, |
PUCHAR pucMode |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetUSBParameters( |
FT_HANDLE ftHandle, |
ULONG ulInTransferSize, |
ULONG ulOutTransferSize |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetDeadmanTimeout( |
FT_HANDLE ftHandle, |
ULONG ulDeadmanTimeout // -1 for infinite (2.6 kernels only). High +ve number for 2.4 kernels |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetDeviceInfo( |
FT_HANDLE ftHandle, |
FT_DEVICE *lpftDevice, |
LPDWORD lpdwID, |
PCHAR SerialNumber, |
PCHAR Description, |
LPVOID Dummy |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_StopInTask( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_RestartInTask( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_SetResetPipeRetryCount( // Linux, OS X: Not supported |
FT_HANDLE ftHandle, |
DWORD dwCount |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_ResetPort( // Linux, OS X: Not supported |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_CyclePort( // Linux, OS X: Not supported |
FT_HANDLE ftHandle |
); |
|
|
// |
// Win32-type functions |
// |
|
FTD2XX_API |
FT_HANDLE WINAPI FT_W32_CreateFile( |
LPCSTR lpszName, |
DWORD dwAccess, |
DWORD dwShareMode, |
LPSECURITY_ATTRIBUTES lpSecurityAttributes, |
DWORD dwCreate, |
DWORD dwAttrsAndFlags, |
HANDLE hTemplate |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_CloseHandle( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_ReadFile( |
FT_HANDLE ftHandle, |
LPVOID lpBuffer, |
DWORD nBufferSize, |
LPDWORD lpBytesReturned, |
LPOVERLAPPED lpOverlapped |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_WriteFile( |
FT_HANDLE ftHandle, |
LPVOID lpBuffer, |
DWORD nBufferSize, |
LPDWORD lpBytesWritten, |
LPOVERLAPPED lpOverlapped |
); |
|
FTD2XX_API |
DWORD WINAPI FT_W32_GetLastError( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_GetOverlappedResult( // Linux, OS X: Not supported |
FT_HANDLE ftHandle, |
LPOVERLAPPED lpOverlapped, |
LPDWORD lpdwBytesTransferred, |
BOOL bWait |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_CancelIo( // Linux, OS X: Not supported |
FT_HANDLE ftHandle |
); |
|
|
// |
// Win32 COMM API type functions |
// |
typedef struct _FTCOMSTAT { |
DWORD fCtsHold : 1; |
DWORD fDsrHold : 1; |
DWORD fRlsdHold : 1; |
DWORD fXoffHold : 1; |
DWORD fXoffSent : 1; |
DWORD fEof : 1; |
DWORD fTxim : 1; |
DWORD fReserved : 25; |
DWORD cbInQue; |
DWORD cbOutQue; |
} FTCOMSTAT, *LPFTCOMSTAT; |
|
typedef struct _FTDCB { |
DWORD DCBlength; /* sizeof(FTDCB) */ |
DWORD BaudRate; /* Baudrate at which running */ |
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ |
DWORD fParity: 1; /* Enable parity checking */ |
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ |
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ |
DWORD fDtrControl:2; /* DTR Flow control */ |
DWORD fDsrSensitivity:1; /* DSR Sensitivity */ |
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ |
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ |
DWORD fInX: 1; /* Enable input X-ON/X-OFF */ |
DWORD fErrorChar: 1; /* Enable Err Replacement */ |
DWORD fNull: 1; /* Enable Null stripping */ |
DWORD fRtsControl:2; /* Rts Flow control */ |
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ |
DWORD fDummy2:17; /* Reserved */ |
WORD wReserved; /* Not currently used */ |
WORD XonLim; /* Transmit X-ON threshold */ |
WORD XoffLim; /* Transmit X-OFF threshold */ |
BYTE ByteSize; /* Number of bits/byte, 4-8 */ |
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ |
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ |
char XonChar; /* Tx and Rx X-ON character */ |
char XoffChar; /* Tx and Rx X-OFF character */ |
char ErrorChar; /* Error replacement char */ |
char EofChar; /* End of Input character */ |
char EvtChar; /* Received Event character */ |
WORD wReserved1; /* Fill for now. */ |
} FTDCB, *LPFTDCB; |
|
typedef struct _FTTIMEOUTS { |
DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ |
DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ |
DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ |
DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ |
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ |
} FTTIMEOUTS,*LPFTTIMEOUTS; |
|
|
FTD2XX_API |
BOOL WINAPI FT_W32_ClearCommBreak( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_ClearCommError( |
FT_HANDLE ftHandle, |
LPDWORD lpdwErrors, |
LPFTCOMSTAT lpftComstat |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_EscapeCommFunction( |
FT_HANDLE ftHandle, |
DWORD dwFunc |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_GetCommModemStatus( |
FT_HANDLE ftHandle, |
LPDWORD lpdwModemStatus |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_GetCommState( |
FT_HANDLE ftHandle, |
LPFTDCB lpftDcb |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_GetCommTimeouts( |
FT_HANDLE ftHandle, |
FTTIMEOUTS *pTimeouts |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_PurgeComm( |
FT_HANDLE ftHandle, |
DWORD dwMask |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_SetCommBreak( |
FT_HANDLE ftHandle |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_SetCommMask( |
FT_HANDLE ftHandle, |
ULONG ulEventMask |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_SetCommState( |
FT_HANDLE ftHandle, |
LPFTDCB lpftDcb |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_SetCommTimeouts( |
FT_HANDLE ftHandle, |
FTTIMEOUTS *pTimeouts |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_SetupComm( |
FT_HANDLE ftHandle, |
DWORD dwReadBufferSize, |
DWORD dwWriteBufferSize |
); |
|
FTD2XX_API |
BOOL WINAPI FT_W32_WaitCommEvent( |
FT_HANDLE ftHandle, |
PULONG pulEvent, |
LPOVERLAPPED lpOverlapped |
); |
|
// |
// Device information |
// |
|
typedef struct _ft_device_list_info_node { |
ULONG Flags; |
ULONG Type; |
ULONG ID; |
DWORD LocId; |
char SerialNumber[16]; |
char Description[64]; |
FT_HANDLE ftHandle; |
} FT_DEVICE_LIST_INFO_NODE; |
|
FTD2XX_API |
FT_STATUS WINAPI FT_CreateDeviceInfoList( |
LPDWORD lpdwNumDevs |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetDeviceInfoList( |
FT_DEVICE_LIST_INFO_NODE *pDest, |
LPDWORD lpdwNumDevs |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetDeviceInfoDetail( |
DWORD dwIndex, |
LPDWORD lpdwFlags, |
LPDWORD lpdwType, |
LPDWORD lpdwID, |
LPDWORD lpdwLocId, |
LPVOID lpSerialNumber, |
LPVOID lpDescription, |
FT_HANDLE *pftHandle |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetDriverVersion( |
FT_HANDLE ftHandle, |
LPDWORD lpdwVersion |
); |
|
FTD2XX_API |
FT_STATUS WINAPI FT_GetLibraryVersion( |
LPDWORD lpdwVersion |
); |
|
// |
// Events |
// |
|
#define EV_RXCHAR 0x0001 // Any Character received |
#define EV_RXFLAG 0x0002 // Received certain character |
#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty |
#define EV_CTS 0x0008 // CTS changed state |
#define EV_DSR 0x0010 // DSR changed state |
#define EV_RLSD 0x0020 // RLSD changed state |
#define EV_BREAK 0x0040 // BREAK received |
#define EV_ERR 0x0080 // Line status error occurred |
#define EV_RING 0x0100 // Ring signal detected |
#define EV_PERR 0x0200 // Printer error occured |
#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full |
#define EV_EVENT1 0x0800 // Provider specific event 1 |
#define EV_EVENT2 0x1000 // Provider specific event 2 |
|
// |
// Escape Functions |
// |
|
#define SETXOFF 1 // Simulate XOFF received |
#define SETXON 2 // Simulate XON received |
#define SETRTS 3 // Set RTS high |
#define CLRRTS 4 // Set RTS low |
#define SETDTR 5 // Set DTR high |
#define CLRDTR 6 // Set DTR low |
#define RESETDEV 7 // Reset device if possible |
#define SETBREAK 8 // Set the device break line. |
#define CLRBREAK 9 // Clear the device break line. |
|
// |
// PURGE function flags. |
// |
#define PURGE_TXABORT 0x0001 // Kill the pending/current writes to the comm port. |
#define PURGE_RXABORT 0x0002 // Kill the pending/current reads to the comm port. |
#define PURGE_TXCLEAR 0x0004 // Kill the transmit queue if there. |
#define PURGE_RXCLEAR 0x0008 // Kill the typeahead buffer if there. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus |
} |
#endif |
|
|
#endif /* FTD2XX_H */ |
|
|
|
|
|
|
/or_debug_proxy/includes/usb_functions.h
0,0 → 1,82
/*$$HEADER*/ |
/******************************************************************************/ |
/* */ |
/* H E A D E R I N F O R M A T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Project Name : OpenRISC Debug Proxy |
// File Name : usb_functions.h |
// Prepared By : jb |
// Project Start : 2008-10-01 |
|
/*$$COPYRIGHT NOTICE*/ |
/******************************************************************************/ |
/* */ |
/* C O P Y R I G H T N O T I C E */ |
/* */ |
/******************************************************************************/ |
/* |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; |
version 2.1 of the License, a copy of which is available from |
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. |
|
This library 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 |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
*/ |
|
/*$$CHANGE HISTORY*/ |
/******************************************************************************/ |
/* */ |
/* C H A N G E H I S T O R Y */ |
/* */ |
/******************************************************************************/ |
|
// Date Version Description |
//------------------------------------------------------------------------ |
// 081101 First revision jb |
|
|
#ifndef CYGWIN_COMPILE |
#include "WinTypes.h" |
#endif |
#include <stdint.h> // for uint_t types |
/* Function prototypes */ |
uint32_t crc_calc(uint32_t crc, uint32_t input_bit); |
/* Crc of current read or written data. */ |
extern uint32_t crc_r, crc_w; |
|
int retry_do(); |
void retry_ok(); |
|
void usb_close_device_handle(); |
void usb_write_stream (uint32_t stream, uint32_t num_bits, DWORD dwTapControllerState); |
void usb_readwritewrite_stream (uint32_t num_bits); |
uint32_t usb_read_stream(uint32_t num_bits, DWORD dwTapControllerState); |
uint32_t bit_reverse_data(uint32_t data, uint32_t length); |
|
void usb_set_tap_ir(uint32_t ir); |
void usb_dbg_test(); |
int usb_dbg_reset(); |
int usb_dbg_set_chain(int chain); |
int usb_dbg_command(uint32_t type, uint32_t adr, uint32_t len); |
int usb_dbg_ctrl(uint32_t reset, uint32_t stall); |
int usb_dbg_ctrl_read(uint32_t *reset, uint32_t *stall); |
int usb_dbg_go(unsigned char *data, uint16_t len, uint32_t read); |
|
int usb_dbg_wb_read32(uint32_t adr, uint32_t *data); |
int usb_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len); |
int usb_dbg_wb_write32(uint32_t adr, uint32_t data); |
int usb_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len); |
int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data); |
int usb_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data); |
int usb_dbg_cpu0_write(uint32_t adr, uint32_t data); |
int usb_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data); |
/or_debug_proxy/includes/usb_driver_calls.h
0,0 → 1,90
/*$$HEADER*/ |
/******************************************************************************/ |
/* */ |
/* H E A D E R I N F O R M A T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Project Name : OpenRISC Debug Proxy |
// File Name : usb_functions.h |
// Prepared By : jb |
// Project Start : 2008-10-01 |
|
/*$$COPYRIGHT NOTICE*/ |
/******************************************************************************/ |
/* */ |
/* C O P Y R I G H T N O T I C E */ |
/* */ |
/******************************************************************************/ |
/* |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; |
version 2.1 of the License, a copy of which is available from |
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. |
|
This library 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 |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
*/ |
|
/*$$CHANGE HISTORY*/ |
/******************************************************************************/ |
/* */ |
/* C H A N G E H I S T O R Y */ |
/* */ |
/******************************************************************************/ |
|
// Date Version Description |
//------------------------------------------------------------------------ |
// 090301 1.0 Generic header file for modules containing the |
// platform specific D2XX MPSSE JTAG driver calls. jb |
// |
|
#ifndef CYGWIN_COMPILE |
#include "FT2232cMpsseJtag.h" |
#else |
#include "win_FTCJTAG.h" |
#endif |
|
// Function prototypes |
FTC_STATUS |
FT2232_USB_JTAG_WriteDataToExternalDevice( |
//FTC_HANDLE ftHandle, |
BOOL bInstructionTestData, |
DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, |
DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
|
FTC_STATUS |
FT2232_USB_JTAG_ReadDataFromExternalDevice( |
//FTC_HANDLE ftHandle, |
BOOL bInstructionTestData, |
DWORD dwNumBitsToRead, |
PReadDataByteBuffer pReadDataBuffer, |
LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
FTC_STATUS |
FT2232_USB_JTAG_WriteReadDataToFromExternalDevice( |
//FTC_HANDLE ftHandle, |
BOOL bInstructionTestData, |
DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, |
DWORD dwNumBytesToWrite, |
PReadDataByteBuffer pReadDataBuffer, |
LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
|
FTC_STATUS |
FT2232_USB_JTAG_CloseDevice(); |
|
int init_usb_jtag(); |
|
|
/or_debug_proxy/includes/WinTypes.h
0,0 → 1,87
#ifndef __WINDOWS_TYPES__ |
#define __WINDOWS_TYPES__ |
|
#define MAX_NUM_DEVICES 50 |
#include <sys/time.h> |
|
typedef unsigned long DWORD; |
typedef unsigned long ULONG; |
typedef unsigned short USHORT; |
typedef short SHORT; |
typedef unsigned char UCHAR; |
typedef unsigned short WORD; |
typedef unsigned char BYTE; |
typedef unsigned char *LPBYTE; |
typedef int BOOL; |
typedef char BOOLEAN; |
typedef char CHAR; |
typedef int *LPBOOL; |
typedef unsigned char *PUCHAR; |
typedef const char *LPCSTR; |
typedef char *PCHAR; |
typedef void *PVOID; |
typedef void *HANDLE; |
typedef long LONG; |
typedef int INT; |
typedef unsigned int UINT; |
typedef char *LPSTR; |
typedef char *LPTSTR; |
typedef DWORD *LPDWORD; |
typedef WORD *LPWORD; |
typedef ULONG *PULONG; |
typedef PVOID LPVOID; |
typedef void VOID; |
typedef unsigned long long int ULONGLONG; |
|
typedef struct _OVERLAPPED { |
DWORD Internal; |
DWORD InternalHigh; |
DWORD Offset; |
DWORD OffsetHigh; |
HANDLE hEvent; |
} OVERLAPPED, *LPOVERLAPPED; |
|
typedef struct _SECURITY_ATTRIBUTES { |
DWORD nLength; |
LPVOID lpSecurityDescriptor; |
BOOL bInheritHandle; |
} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES; |
|
typedef struct timeval SYSTEMTIME; |
typedef struct timeval FILETIME; |
#ifndef TRUE |
#define TRUE 1 |
#endif |
#ifndef FALSE |
#define FALSE 0 |
#endif |
|
// |
// Modem Status Flags |
// |
#define MS_CTS_ON ((DWORD)0x0010) |
#define MS_DSR_ON ((DWORD)0x0020) |
#define MS_RING_ON ((DWORD)0x0040) |
#define MS_RLSD_ON ((DWORD)0x0080) |
|
// |
// Error Flags |
// |
|
#define CE_RXOVER 0x0001 // Receive Queue overflow |
#define CE_OVERRUN 0x0002 // Receive Overrun Error |
#define CE_RXPARITY 0x0004 // Receive Parity Error |
#define CE_FRAME 0x0008 // Receive Framing error |
#define CE_BREAK 0x0010 // Break Detected |
#define CE_TXFULL 0x0100 // TX Queue is full |
#define CE_PTO 0x0200 // LPTx Timeout |
#define CE_IOE 0x0400 // LPTx I/O Error |
#define CE_DNS 0x0800 // LPTx Device not selected |
#define CE_OOP 0x1000 // LPTx Out-Of-Paper |
#define CE_MODE 0x8000 // Requested mode unsupported |
|
#ifndef INVALID_HANDLE_VALUE |
#define INVALID_HANDLE_VALUE 0xFFFFFFFF |
#endif |
|
#endif |
/or_debug_proxy/includes/FT2232cMpsseJtag.h
0,0 → 1,424
/*++ |
|
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009 |
|
|
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability. |
|
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact. |
|
Copyright (c) 2005 Future Technology Devices International Ltd. |
|
Module Name: |
|
ft2232cmpssejtag.h |
|
Abstract: |
|
FT2232C Dual Device Device Class Declaration/Definition. |
|
Environment: |
|
kernel & user mode |
|
Revision History: |
|
07/02/05 kra Created. |
24/08/05 kra Added new function JTAG_GenerateClockPulses and new error code FTC_INVALID_NUMBER_CLOCK_PULSES |
16/09/05 kra Version 1.50 - Added break statements after DLL_THREAD_ATTACH and DLL_THREAD_DETACH for multiple threaded applications |
08/03/06 ana Version 1.08 - fix byte boundry mising bit. |
19/11/08 Rene Baumann Port FTCJTAG to Linux. |
|
--*/ |
|
#ifndef FT2232cMpsseJtag_H |
#define FT2232cMpsseJtag_H |
|
//#include <windows.h> |
|
#include "FT2232c.h" |
//#include "FTCJTAG.h" -- All required bits now included in this file. WinAPI things in there not needed here |
|
|
// Defines from FTCJTAG.h |
|
typedef DWORD FTC_HANDLE; |
typedef ULONG FTC_STATUS; |
|
#define TEST_LOGIC_STATE 1 |
#define RUN_TEST_IDLE_STATE 2 |
#define PAUSE_TEST_DATA_REGISTER_STATE 3 |
#define PAUSE_INSTRUCTION_REGISTER_STATE 4 |
#define SHIFT_TEST_DATA_REGISTER_STATE 5 |
#define SHIFT_INSTRUCTION_REGISTER_STATE 6 |
|
#define FTC_SUCCESS 0 // FTC_OK |
#define FTC_INVALID_HANDLE 1 // FTC_INVALID_HANDLE |
#define FTC_DEVICE_NOT_FOUND 2 //FTC_DEVICE_NOT_FOUND |
#define FTC_DEVICE_NOT_OPENED 3 //FTC_DEVICE_NOT_OPENED |
#define FTC_IO_ERROR 4 //FTC_IO_ERROR |
#define FTC_INSUFFICIENT_RESOURCES 5 // FTC_INSUFFICIENT_RESOURCES |
|
#define FTC_FAILED_TO_COMPLETE_COMMAND 20 // cannot change, error code mapped from FT2232c classes |
#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 21 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_DEVICE_NAME_INDEX 22 // cannot change, error code mapped from FT2232c classes |
#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 23 // cannot change, error code mapped from FT2232c classes |
#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 24 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_DEVICE_NAME 25 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_LOCATION_ID 26 // cannot change, error code mapped from FT2232c classes |
#define FTC_DEVICE_IN_USE 27 // cannot change, error code mapped from FT2232c classes |
#define FTC_TOO_MANY_DEVICES 28 // cannot change, error code mapped from FT2232c classes |
#define FTC_INVALID_CLOCK_DIVISOR 29 |
#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 30 |
#define FTC_INVALID_NUMBER_BITS 31 |
#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 32 |
#define FTC_INVALID_NUMBER_BYTES 33 |
#define FTC_NUMBER_BYTES_TOO_SMALL 34 |
#define FTC_INVALID_TAP_CONTROLLER_STATE 35 |
#define FTC_NULL_READ_DATA_BUFFER_POINTER 36 |
#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 37 |
#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 38 |
#define FTC_NO_COMMAND_SEQUENCE 39 |
#define FTC_INVALID_NUMBER_CLOCK_PULSES 40 |
#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 41 |
#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 42 |
#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 43 |
#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 44 |
#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 45 |
#define FTC_INVALID_LANGUAGE_CODE 46 |
#define FTC_INVALID_STATUS_CODE 47 |
|
|
typedef struct Ft_Input_Output_Pins{ |
BOOL bPin1InputOutputState; |
BOOL bPin1LowHighState; |
BOOL bPin2InputOutputState; |
BOOL bPin2LowHighState; |
BOOL bPin3InputOutputState; |
BOOL bPin3LowHighState; |
BOOL bPin4InputOutputState; |
BOOL bPin4LowHighState; |
}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS; |
typedef struct Ft_Low_High_Pins{ |
BOOL bPin1LowHighState; |
BOOL bPin2LowHighState; |
BOOL bPin3LowHighState; |
BOOL bPin4LowHighState; |
}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS; |
#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes |
|
typedef BYTE WriteDataByteBuffer[MAX_WRITE_DATA_BYTES_BUFFER_SIZE]; |
typedef WriteDataByteBuffer *PWriteDataByteBuffer; |
|
|
#define MAX_READ_DATA_BYTES_BUFFER_SIZE 65536 // 64k bytes |
|
typedef BYTE ReadDataByteBuffer[MAX_READ_DATA_BYTES_BUFFER_SIZE]; |
typedef ReadDataByteBuffer *PReadDataByteBuffer; |
|
#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 131071 // 128K bytes |
|
typedef BYTE ReadCmdSequenceDataByteBuffer[MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE]; |
typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer; |
|
|
// end defines from FTCJTAG.h |
|
|
#define DEVICE_CHANNEL_A " A" |
#define DEVICE_CHANNEL_B " B" |
|
#define DLL_VERSION_NUM "1.8" |
|
#define USB_INPUT_BUFFER_SIZE 65536 // 64K |
#define USB_OUTPUT_BUFFER_SIZE 65536 // 64K |
|
const BYTE FT_EVENT_VALUE = 0; |
const BYTE FT_ERROR_VALUE = 0; |
|
#define DEVICE_READ_TIMEOUT_INFINITE 0 |
#define DEVICE_WRITE_TIMEOUT 5000 // 5 seconds |
|
#define MIN_CLOCK_DIVISOR 0 // equivalent to 6MHz |
#define MAX_CLOCK_DIVISOR 65535 // equivalent to 91Hz |
|
#define MIN_NUM_BITS 2 // specifies the minimum number of bits that can be written or read to/from an external device |
#define MAX_NUM_BITS 524280 // specifies the maximum number of bits that can be written or read to/from an external device |
#define MIN_NUM_BYTES 1 // specifies the minimum number of bytes that can be written to an external device |
#define MAX_NUM_BYTES 65535 // specifies the maximum number of bytes that can be written to an external device |
|
#define NUMBITSINBYTE 8 |
|
#define MIN_NUM_CLOCK_PULSES 1 // specifies the minimum number of clock pulses that a FT2232C dual device can generate |
#define MAX_NUM_CLOCK_PULSES 2000000000 // specifies the maximum number of clock pulses that a FT2232C dual device can generate |
|
#define NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE 32000 //4000 |
|
#define PIN1_HIGH_VALUE 1 |
#define PIN2_HIGH_VALUE 2 |
#define PIN3_HIGH_VALUE 4 |
#define PIN4_HIGH_VALUE 8 |
|
#define NUM_WRITE_COMMAND_BYTES 18 |
#define NUM_READ_COMMAND_BYTES 18 |
#define NUM_WRITE_READ_COMMAND_BYTES 19 |
|
#define MAX_ERROR_MSG_SIZE 250 |
|
const CHAR ENGLISH[3] = "EN"; |
|
const CHAR EN_Common_Errors[FTC_INSUFFICIENT_RESOURCES + 1][MAX_ERROR_MSG_SIZE] = { |
"", |
"Invalid device handle.", |
"Device not found.", |
"Device not opened.", |
"General device IO error.", |
"Insufficient resources available to execute function."}; |
|
const CHAR EN_New_Errors[(FTC_INVALID_STATUS_CODE - FTC_FAILED_TO_COMPLETE_COMMAND) + 1][MAX_ERROR_MSG_SIZE] = { |
"Failed to complete command.", |
"Failed to synchronize the device MPSSE interface.", |
"Invalid device name index.", |
"Pointer to device name buffer is null.", |
"Buffer to contain device name is too small.", |
"Invalid device name.", |
"Invalid device location identifier.", |
"Device already in use by another application.", |
"More than one device detected.", |
"Invalid clock divisor. Valid range is 0 - 65535.", |
"Pointer to input output buffer is null.", |
"Invalid number of bits. Valid range 2 to 524280. 524280 bits is equivalent to 64K bytes", |
"Pointer to write data buffer is null.", |
"Invalid size of write data buffer. Valid range is 1 - 65535", |
"Buffer to contain number of bits is too small.", |
"Invalid Test Access Port(TAP) controller state.", |
"Pointer to read data buffer is null.", |
"Command sequence buffer is full. Valid range is 1 - 131070 ie 128K bytes.", |
"Pointer to read command sequence data buffer is null.", |
"No command sequence found.", |
"Invalid number of clock pulses. Valid range is 1 - 2000,000,000.", |
"Pointer to dll version number buffer is null.", |
"Buffer to contain dll version number is too small.", |
"Pointer to language code buffer is null.", |
"Pointer to error message buffer is null.", |
"Buffer to contain error message is too small.", |
"Unsupported language code.", |
"Unknown status code = "}; |
|
const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD = '\x19'; |
const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD = '\x1B'; |
const BYTE CLK_DATA_BYTES_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x28'; |
const BYTE CLK_DATA_BITS_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x2A'; |
const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x39'; |
const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD = '\x3B'; |
|
const BYTE CLK_DATA_TMS_NO_READ_CMD = '\x4B'; |
const BYTE CLK_DATA_TMS_READ_CMD = '\x6B'; |
|
const BYTE SET_LOW_BYTE_DATA_BITS_CMD = '\x80'; |
const BYTE GET_LOW_BYTE_DATA_BITS_CMD = '\x81'; |
const BYTE SET_HIGH_BYTE_DATA_BITS_CMD = '\x82'; |
const BYTE GET_HIGH_BYTE_DATA_BITS_CMD = '\x83'; |
const BYTE SET_CLOCK_FREQUENCY_CMD = '\x86'; |
const BYTE SEND_ANSWER_BACK_IMMEDIATELY_CMD = '\x87'; |
|
enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister, ShiftInstructionRegister, Undefined}; |
|
#define NUM_JTAG_TMS_STATES 6 |
|
// go from current JTAG state to new JTAG state -> tlr rti pdr pir sdr sir |
const BYTE TestLogicResetToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x01', '\x00', '\x0A', '\x16', '\x02', '\x06'}; |
const BYTE RunTestIdleToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x07', '\x00', '\x05', '\x0B', '\x01', '\x03'}; |
const BYTE PauseDataRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x17', '\x2F', '\x01', '\x0F'}; |
const BYTE PauseInstructionRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x17', '\x2F', '\x07', '\x01'}; |
const BYTE ShiftDataRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x01', '\x2F', '\x00', '\x00'}; |
const BYTE ShiftInstructionRegToNewJTAGState[NUM_JTAG_TMS_STATES] = {'\x1F', '\x03', '\x17', '\x01', '\x00', '\x00'}; |
|
// number of TMS clocks to go from current JTAG state to new JTAG state -> tlr rti pdr pir sdr sir |
const BYTE TestLogicResetToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {1, 1, 5, 6, 4, 5}; |
const BYTE RunTestIdleToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {3, 5, 4, 5, 3, 4}; |
const BYTE PauseDataRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 3, 6, 7, 2, 6}; |
const BYTE PauseInstructionRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 3, 6, 7, 5, 2}; |
const BYTE ShiftDataRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 3, 2, 7, 0, 0}; |
const BYTE ShiftInstructionRegToNewJTAGStateNumTMSClocks[NUM_JTAG_TMS_STATES] = {5, 4, 6, 2, 0, 0}; |
|
#define NO_LAST_DATA_BIT 0 |
|
#define NUM_COMMAND_SEQUENCE_READ_DATA_BYTES 2 |
#define INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE 100 |
#define COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT 10 |
|
typedef DWORD ReadCommandSequenceData[NUM_COMMAND_SEQUENCE_READ_DATA_BYTES]; |
typedef ReadCommandSequenceData *PReadCommandSequenceData; |
|
typedef PReadCommandSequenceData ReadCommandsSequenceData[1]; |
typedef ReadCommandsSequenceData *PReadCommandsSequenceData; |
|
typedef struct Ft_Device_Cmd_Sequence_Data{ |
DWORD hDevice; // handle to the opened and initialized FT2232C dual type device |
DWORD dwNumBytesToSend; |
POutputByteBuffer pCommandsSequenceDataOutPutBuffer; |
DWORD dwSizeReadCommandsSequenceDataBuffer; |
PReadCommandsSequenceData pReadCommandsSequenceDataBuffer; |
DWORD dwNumReadCommandSequences; |
}FTC_DEVICE_CMD_SEQUENCE_DATA, *PFTC_DEVICE_CMD_SEQUENCE_DATA; |
|
|
static DWORD dwSavedLowPinsDirection = 0; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene |
static DWORD dwSavedLowPinsValue = 0; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene |
static JtagStates CurrentJtagState = Undefined; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene |
static DWORD dwNumOpenedDevices = 0; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene |
static FTC_DEVICE_CMD_SEQUENCE_DATA OpenedDevicesCommandsSequenceData[MAX_NUM_DEVICES]; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene |
static INT iCommandsSequenceDataDeviceIndex = -1; // Removed from FT2232cMpsseJtag class to avoid segmentation fault. Rene |
|
|
//---------------------------------------------------------------------------- |
class FT2232cMpsseJtag : private FT2232c |
{ |
private: |
// Moved out from this class to avoid segmentation fault. --> DWORD dwSavedLowPinsDirection; // Rene |
// Moved out from this class to avoid segmentation fault. --> DWORD dwSavedLowPinsValue; // Rene |
// Moved out from this class to avoid segmentation fault. --> JtagStates CurrentJtagState; // Rene |
// Moved out from this class to avoid segmentation fault. --> DWORD dwNumOpenedDevices; // Rene |
// Moved out from this class to avoid segmentation fault. --> FTC_DEVICE_CMD_SEQUENCE_DATA OpenedDevicesCommandsSequenceData[MAX_NUM_DEVICES]; // Rene |
// Moved out from this class to avoid segmentation fault. --> INT iCommandsSequenceDataDeviceIndex; // Rene |
|
FTC_STATUS CheckWriteDataToExternalDeviceBitsBytesParameters(DWORD dwNumBitsToWrite, DWORD dwNumBytesToWrite); |
|
void AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer); |
FTC_STATUS SetDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor); |
FTC_STATUS InitDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor); |
void SetJTAGToNewState(DWORD dwNewJtagState, DWORD dwNumTmsClocks, BOOL bDoReadOperation); |
DWORD MoveJTAGFromOneStateToAnother(JtagStates NewJtagState, DWORD dwLastDataBit, BOOL bDoReadOperation); |
FTC_STATUS ResetTAPContollerExternalDeviceSetToTestIdleMode(FTC_HANDLE ftHandle); |
FTC_STATUS SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
DWORD dwLowPinsDirection, DWORD dwLowPinsValue, |
BOOL bControlHighInputOutputPins, |
DWORD dwHighPinsDirection, DWORD dwHighPinsValue); |
void GetGeneralPurposeInputOutputPinsInputStates(DWORD dwInputStatesReturnedValue, PFTC_LOW_HIGH_PINS pPinsInputData); |
FTC_STATUS GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_LOW_HIGH_PINS pLowPinsInputData, |
BOOL bControlHighInputOutputPins, |
PFTC_LOW_HIGH_PINS pHighPinsInputData); |
void AddWriteCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
void GetNumDataBytesToRead(DWORD dwNumBitsToRead, LPDWORD lpdwNumDataBytesToRead, LPDWORD lpdwNumRemainingDataBits); |
FTC_STATUS GetDataFromExternalDevice(FTC_HANDLE ftHandle, DWORD dwNumBitsToRead, DWORD dwNumTmsClocks, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned); |
DWORD AddReadCommandToOutputBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
FTC_STATUS ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
DWORD AddWriteReadCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, |
DWORD dwNumBytesToWrite, DWORD dwTapControllerState); |
FTC_STATUS WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
FTC_STATUS GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses); |
|
void ProcessReadCommandsSequenceBytes(PInputByteBuffer pInputBuffer, DWORD dwNumBytesRead, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, |
LPDWORD lpdwNumBytesReturned); |
DWORD GetTotalNumCommandsSequenceDataBytesToRead (void); |
void CopyReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pDestinationBuffer, PReadCommandsSequenceData pSourceBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer); |
FTC_STATUS AddReadCommandSequenceData(DWORD dwNumBitsToRead, DWORD dwNumTmsClocks); |
void CreateReadCommandsSequenceDataBuffer(void); |
PReadCommandsSequenceData CreateReadCommandsSequenceDataBuffer(DWORD dwSizeReadCmdsSequenceDataBuffer); |
void DeleteReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pReadCmdsSequenceDataBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer); |
|
FTC_STATUS CreateDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle); |
void ClearDeviceCommandSequenceData(FTC_HANDLE ftHandle); |
DWORD GetNumBytesInCommandsSequenceDataBuffer(void); |
DWORD GetCommandsSequenceDataDeviceIndex(FTC_HANDLE ftHandle); |
void DeleteDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle); |
|
FTC_STATUS AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
FTC_STATUS AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
|
public: |
FT2232cMpsseJtag(void); |
~FT2232cMpsseJtag(void); |
|
|
FTC_STATUS JTAG_GetNumDevices(LPDWORD lpdwNumDevices); |
FTC_STATUS JTAG_GetDeviceNameLocationID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID); |
//FTC_STATUS JTAG_GetDeviceNameLocID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID); |
FTC_STATUS JTAG_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle); |
//FTC_STATUS JTAG_OpenEx(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle); |
FTC_STATUS JTAG_OpenDevice(FTC_HANDLE *pftHandle); |
//FTC_STATUS JTAG_Open(FTC_HANDLE *pftHandle); |
FTC_STATUS JTAG_CloseDevice(FTC_HANDLE ftHandle); |
//FTC_STATUS JTAG_Close(FTC_HANDLE ftHandle); |
FTC_STATUS JTAG_InitDevice(FTC_HANDLE ftHandle, DWORD dwClockFrequencyValue); |
FTC_STATUS JTAG_GetClock(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz); |
FTC_STATUS JTAG_SetClock(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz); |
FTC_STATUS JTAG_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState); |
//FTC_STATUS JTAG_SetLoopback(FTC_HANDLE ftHandle, BOOL bLoopbackState); |
FTC_STATUS JTAG_SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
//FTC_STATUS JTAG_SetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData, |
BOOL bControlHighInputOutputPins, |
PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData); |
FTC_STATUS JTAG_GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
//FTC_STATUS JTAG_GetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_LOW_HIGH_PINS pLowPinsInputData, |
BOOL bControlHighInputOutputPins, |
PFTC_LOW_HIGH_PINS pHighPinsInputData); |
FTC_STATUS JTAG_WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
//FTC_STATUS JTAG_Write(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, |
//FTC_STATUS JTAG_Read(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
//FTC_STATUS JTAG_WriteRead(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses); |
//FTC_STATUS JTAG_GenerateClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses); |
FTC_STATUS JTAG_ClearCommandSequence(void); |
//FTC_STATUS JTAG_ClearCmdSequence(void); |
FTC_STATUS JTAG_AddWriteCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
//FTC_STATUS JTAG_AddWriteCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_AddReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
//FTC_STATUS JTAG_AddReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
FTC_STATUS JTAG_AddWriteReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
//FTC_STATUS JTAG_AddWriteReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_ClearDeviceCommandSequence(FTC_HANDLE ftHandle); |
//FTC_STATUS JTAG_ClearDeviceCmdSequence(FTC_HANDLE ftHandle); |
FTC_STATUS JTAG_AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
//FTC_STATUS JTAG_AddDeviceWriteCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
//FTC_STATUS JTAG_AddDeviceReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
FTC_STATUS JTAG_AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
//FTC_STATUS JTAG_AddDeviceWriteReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
FTC_STATUS JTAG_ExecuteCommandSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, |
//FTC_STATUS JTAG_ExecuteCmdSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, |
LPDWORD lpdwNumBytesReturned); |
FTC_STATUS JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize); |
FTC_STATUS JTAG_GetErrorCodeString(LPSTR lpLanguage, FTC_STATUS StatusCode, |
LPSTR lpErrorMessageBuffer, DWORD dwBufferSize); |
}; |
|
#endif /* FT2232cMpsseJtag_H */ |
/or_debug_proxy/includes/FT2232c.h
0,0 → 1,186
/*++ |
|
FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009 |
|
|
The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability. |
|
This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact. |
|
Copyright (c) 2005 Future Technology Devices International Ltd. |
|
Module Name: |
|
FT2232c.h |
|
Abstract: |
|
FT2232C Dual Type Devices Base Class Declaration/Definition. |
|
Environment: |
|
kernel & user mode |
|
Revision History: |
|
07/02/05 kra Created. |
25/08/05 kra Windows 2000 Professional always sets the USB buffer size to 4K ie 4096 |
19/11/08 Rene Baumann Port FTCJTAG to Linux. |
|
--*/ |
|
#ifndef FT2232c_H |
#define FT2232c_H |
|
//#include <windows.h> |
|
#include "ftd2xx.h" |
|
typedef DWORD FTC_HANDLE; |
typedef ULONG FTC_STATUS; |
|
#define FTC_SUCCESS 0 //FTC_OK |
#define FTC_INVALID_HANDLE 1 //FTC_INVALID_HANDLE |
#define FTC_DEVICE_NOT_FOUND 2 //FTC_DEVICE_NOT_FOUND |
#define FTC_DEVICE_NOT_OPENED 3 //FTC_DEVICE_NOT_OPENED |
#define FTC_IO_ERROR 4 //FTC_IO_ERROR |
#define FTC_INSUFFICIENT_RESOURCES 5 //FTC_INSUFFICIENT_RESOURCES |
|
#define FTC_FAILED_TO_COMPLETE_COMMAND 20 |
#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 21 |
#define FTC_INVALID_DEVICE_NAME_INDEX 22 |
#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 23 |
#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 24 |
#define FTC_INVALID_DEVICE_NAME 25 |
#define FTC_INVALID_LOCATION_ID 26 |
#define FTC_DEVICE_IN_USE 27 |
#define FTC_TOO_MANY_DEVICES 28 |
|
#define MAX_NUM_DEVICE_NAME_CHARS 64 |
#define MAX_NUM_SERIAL_NUMBER_CHARS 16 |
|
typedef struct Ft_Device_Data{ |
DWORD dwProcessId; // process identifier of the calling process ie application |
char szDeviceName[MAX_NUM_DEVICE_NAME_CHARS]; // pointer to the name of a FT2232C dual type device |
DWORD dwLocationID; // the location identifier of a FT2232C dual type device |
DWORD hDevice; // handle to the opened and initialized FT2232C dual type device |
}FTC_DEVICE_DATA, *PFTC_DEVICE_DATA; |
|
typedef DWORD FT2232CDeviceIndexes[MAX_NUM_DEVICES]; |
|
#define DEVICE_STRING_BUFF_SIZE 64 |
|
#define DEVICE_CHANNEL_A " A" |
|
typedef char SerialNumber[MAX_NUM_SERIAL_NUMBER_CHARS]; |
|
const BYTE DEVICE_LATENCY_TIMER_VALUE = 16; // 16 milliseconds |
|
#define OUTPUT_BUFFER_SIZE 131071 // 128K bytes |
|
typedef BYTE OutputByteBuffer[OUTPUT_BUFFER_SIZE]; |
typedef OutputByteBuffer *POutputByteBuffer; |
|
#define INPUT_BUFFER_SIZE 131071 // 128K bytes |
|
typedef BYTE InputByteBuffer[INPUT_BUFFER_SIZE]; |
typedef InputByteBuffer *PInputByteBuffer; |
|
#define CONVERT_1MS_TO_100NS 10000 |
|
#define MAX_COMMAND_TIMEOUT_PERIOD 5000 // 5 seconds |
|
// 25/08/05 - Windows 2000 Professional always sets the USB buffer size to 4K ie 4096 |
#define MAX_NUM_BYTES_USB_WRITE 4096 //32768 // 32KB |
#define MAX_NUM_BYTES_USB_WRITE_READ 4096 //32768 // 32KB |
#define MAX_NUM_BYTES_USB_READ 32768 // 32KB |
|
#define DEBUG_LIST_DEVICE 0 |
|
const BYTE MPSSE_INTERFACE_MASK = '\x00'; |
const BYTE RESET_MPSSE_INTERFACE = '\x00'; |
const BYTE ENABLE_MPSSE_INTERFACE = '\x02'; |
|
const __uint16_t DEVICE_OPENED_FLAG = '\x0001'; |
|
const int BASE_CLOCK_FREQUENCY_12_MHZ = 12000000; |
|
const BYTE AA_ECHO_CMD_1 = '\xAA'; |
const BYTE AB_ECHO_CMD_2 = '\xAB'; |
|
const BYTE TURN_ON_LOOPBACK_CMD = '\x84'; |
const BYTE TURN_OFF_LOOPBACK_CMD = '\x85'; |
|
const BYTE BAD_COMMAND_RESPONSE = '\xFA'; |
|
|
|
class FT2232c |
{ |
private: |
// Moved to FT2232c.cpp to avoid segmentation fault. --> UINT uiNumOpenedDevices; // Rene |
// Moved to FT2232c.cpp to avoid segmentation fault. --> FTC_DEVICE_DATA OpenedDevices[MAX_NUM_DEVICES]; // Rene |
// Moved to FT2232c.cpp to avoid segmentation fault. --> OutputByteBuffer OutputBuffer; // Rene |
// Moved to FT2232c.cpp to avoid segmentation fault. --> DWORD dwNumBytesToSend; // Rene |
|
|
BOOLEAN FTC_DeviceInUse(LPSTR lpDeviceName, DWORD dwLocationID); |
BOOLEAN FTC_DeviceOpened(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle); |
FTC_STATUS FTC_IsDeviceNameLocationIDValid(LPSTR lpDeviceName, DWORD dwLocationID); |
|
FTC_STATUS FTC_IsDeviceFT2232CType(LPSTR lpDeviceName, LPBOOL lpbFT2232CTypeDevice); |
|
|
|
|
public: |
FT2232c(void); |
~FT2232c(void); |
|
protected: |
FTC_STATUS FTC_GetNumDevices(LPDWORD lpdwNumDevices, FT2232CDeviceIndexes *FT2232CIndexes); |
FTC_STATUS FTC_GetNumNotOpenedDevices(LPDWORD lpdwNumNotOpenedDevices, FT2232CDeviceIndexes *FT2232CIndexes); |
FTC_STATUS FTC_GetDeviceNameLocationID(DWORD dwDeviceIndex, LPSTR lpDeviceName, DWORD dwBufferSize, LPDWORD lpdwLocationID); |
FTC_STATUS FTC_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle); |
FTC_STATUS FTC_OpenDevice(FTC_HANDLE *pftHandle); |
FTC_STATUS FTC_CloseDevice(FTC_HANDLE ftHandle); |
void FTC_GetClockFrequencyValues(DWORD dwClockFrequencyValue, LPDWORD lpdwClockFrequencyHz); |
FTC_STATUS FTC_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState); |
|
void FTC_InsertDeviceHandle(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE ftHandle); |
FTC_STATUS FTC_IsDeviceHandleValid(FTC_HANDLE ftHandle); |
void FTC_RemoveDeviceHandle(FTC_HANDLE ftHandle); |
|
FTC_STATUS FTC_ResetUSBDevicePurgeUSBInputBuffer(FTC_HANDLE ftHandle); |
FTC_STATUS FTC_SetDeviceUSBBufferSizes(FTC_HANDLE ftHandle, DWORD InputBufferSize, DWORD OutputBufferSize); |
FTC_STATUS FTC_SetDeviceSpecialCharacters(FTC_HANDLE ftHandle, BOOLEAN bEventEnabled, UCHAR EventCharacter, |
BOOLEAN bErrorEnabled, UCHAR ErrorCharacter); |
FTC_STATUS FTC_SetReadWriteDeviceTimeouts(FTC_HANDLE ftHandle, DWORD dwReadTimeoutmSec, DWORD dwWriteTimeoutmSec); |
FTC_STATUS FTC_SetDeviceLatencyTimer(FTC_HANDLE ftHandle, BYTE LatencyTimermSec); |
FTC_STATUS FTC_ResetMPSSEInterface(FTC_HANDLE ftHandle); |
FTC_STATUS FTC_EnableMPSSEInterface(FTC_HANDLE ftHandle); |
FTC_STATUS FTC_SendReceiveCommandFromMPSSEInterface(FTC_HANDLE ftHandle, BOOLEAN bSendEchoCommandContinuouslyOnce, BYTE EchoCommand, LPBOOL lpbCommandEchod); |
FTC_STATUS FTC_SynchronizeMPSSEInterface(FTC_HANDLE ftHandle); |
BOOLEAN FTC_Timeout(SYSTEMTIME StartSystemTime, DWORD dwTimeoutmSecs); |
FTC_STATUS FTC_GetNumberBytesFromDeviceInputBuffer(FTC_HANDLE ftHandle, LPDWORD lpdwNumBytesDeviceInputBuffer); |
|
void FTC_ClearOutputBuffer(void); |
DWORD FTC_GetNumBytesInOutputBuffer(void); |
void FTC_AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer); |
FTC_STATUS FTC_SendBytesToDevice(FTC_HANDLE ftHandle); |
FTC_STATUS FTC_ReadBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, |
DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead); |
FTC_STATUS FTC_ReadFixedNumBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, |
DWORD dwNumBytesToRead, LPDWORD lpdwNumDataBytesRead); |
FTC_STATUS FTC_SendReadBytesToFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, |
DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead); |
|
FTC_STATUS FTC_SendCommandsSequenceToDevice(FTC_HANDLE ftHandle); |
FTC_STATUS FTC_ReadCommandsSequenceBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer, |
DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead); |
}; |
|
|
|
#endif /* FT2232c_H */ |
|
/or_debug_proxy/includes/vpi_functions.h
0,0 → 1,91
/*$$HEADER*/ |
/******************************************************************************/ |
/* */ |
/* H E A D E R I N F O R M A T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Project Name : OpenRISC Debug Proxy |
// File Name : usb_functions.h |
// Prepared By : jb |
// Project Start : 2008-10-01 |
|
/*$$COPYRIGHT NOTICE*/ |
/******************************************************************************/ |
/* */ |
/* C O P Y R I G H T N O T I C E */ |
/* */ |
/******************************************************************************/ |
/* |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; |
version 2.1 of the License, a copy of which is available from |
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. |
|
This library 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 |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
*/ |
|
/*$$CHANGE HISTORY*/ |
/******************************************************************************/ |
/* */ |
/* C H A N G E H I S T O R Y */ |
/* */ |
/******************************************************************************/ |
|
// Date Version Description |
//------------------------------------------------------------------------ |
// 081101 First revision jb |
|
//TODO: Make this port variable (at both ends!!) |
// HARDCODED port for communications with functions attached to RTL sim via VPI |
#define VPI_PORT 54002 |
|
#ifdef DEBUG_VPI |
#define debug printf |
#else |
#define debug |
#endif |
|
#ifdef DEBUG2_VPI |
#define debug2 printf |
#else |
#define debug2 |
#endif |
|
|
/* VPI communication function prototyopes */ |
void get_response_from_vpi(); |
void get_data_from_vpi(); |
void get_block_data_from_vpi(uint32_t len, uint32_t *data); |
void send_data_to_vpi(uint32_t data); |
void send_block_data_to_vpi(uint32_t len, uint32_t *data); |
void send_address_to_vpi(uint32_t address); |
void send_command_to_vpi(char CMD); |
|
int vpi_connect(); |
|
void vpi_dbg_test(); |
int vpi_dbg_reset(); |
int vpi_dbg_set_chain(uint32_t chain); |
int vpi_dbg_ctrl(uint32_t reset, uint32_t stall); |
int vpi_dbg_ctrl_read(uint32_t *reset, uint32_t *stall); |
|
int vpi_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data); |
int vpi_dbg_cpu0_write(uint32_t adr, uint32_t data); |
int vpi_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data); |
int vpi_dbg_cpu0_read(uint32_t adr, uint32_t *data); |
int vpi_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len); |
int vpi_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len); |
int vpi_dbg_wb_write32(uint32_t adr, uint32_t data); |
int vpi_dbg_wb_read32(uint32_t adr, uint32_t *data); |
|
|
|
/or_debug_proxy/includes/win_FTCJTAG_ptrs.h
0,0 → 1,131
#ifndef _WIN_FTCJTAG_PTRS_H_ |
#define _WIN_FTCJTAG_PTRS_H_ |
|
|
typedef FTC_STATUS _stdcall (*jtagGetNumDevicesPtr)(LPDWORD lpdwNumDevices); |
jtagGetNumDevicesPtr jtagGetNumDevices; |
|
typedef FTC_STATUS _stdcall (*jtagInitDevicePtr)(FTC_HANDLE ftHandle, DWORD dwClockDivisor); |
jtagInitDevicePtr jtagInitDevice; |
|
typedef FTC_STATUS _stdcall (*jtagOpenPtr)(FTC_HANDLE *pftHandle); |
jtagOpenPtr jtagOpen; |
|
typedef FTC_STATUS _stdcall (*jtagOpenExPtr)(LPSTR lpDeviceName, DWORD dwLocationIO, FTC_HANDLE *pftHandle); |
jtagOpenExPtr jtagOpenEx; |
|
typedef FTC_STATUS _stdcall (*jtagGetDeviceNameLocIDPtr)(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID); |
jtagGetDeviceNameLocIDPtr jtagGetDeviceNameLocID; |
|
typedef FTC_STATUS _stdcall (*jtagClosePtr)(FTC_HANDLE ftHandle); |
jtagClosePtr jtagClose; |
|
|
typedef FTC_STATUS _stdcall (*jtagGetClockPtr)(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz); |
jtagGetClockPtr jtagGetClock; |
|
|
typedef FTC_STATUS _stdcall (*jtagSetClockPtr)(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz); |
jtagSetClockPtr jtagSetClock; |
|
typedef FTC_STATUS _stdcall (*jtagSetLoopbackPtr)(FTC_HANDLE ftHandle, BOOL bLoopbackState); |
jtagSetLoopbackPtr jtagSetLoopback; |
|
|
typedef FTC_STATUS _stdcall (*jtagSetGPIOsPtr)(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData, |
BOOL bControlHighInputOutputPins, |
PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData); |
jtagSetGPIOsPtr jtagSetGPIOs; |
|
|
typedef FTC_STATUS _stdcall (*jtagGetGPIOsPtr)(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins, |
PFTC_LOW_HIGH_PINS pLowPinsInputData, |
BOOL bControlHighInputOutputPins, |
PFTC_LOW_HIGH_PINS pHighPinsInputData); |
jtagGetGPIOsPtr jtagGetGPIOs; |
|
|
typedef FTC_STATUS _stdcall (*jtagWritePtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
jtagWritePtr jtagWrite; |
|
|
typedef FTC_STATUS _stdcall (*jtagReadPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
jtagReadPtr jtagRead; |
|
|
typedef FTC_STATUS _stdcall (*jtagWriteReadPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned, |
DWORD dwTapControllerState); |
jtagWriteReadPtr jtagWriteRead; |
|
|
typedef FTC_STATUS _stdcall (*jtagAddWriteCmdPtr)(BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
jtagAddWriteCmdPtr jtagAddWriteCmd; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagAddReadCmdPtr)(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
jtagAddReadCmdPtr jtagAddReadCmd; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagAddWriteReadCmdPtr)(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
jtagAddWriteReadCmdPtr jtagAddWriteReadCmd; |
|
|
|
|
typedef FTC_STATUS _stdcall (*jtagClearDeviceCmdSequencePtr)(FTC_HANDLE ftHandle); |
jtagClearDeviceCmdSequencePtr jtagClearDeviceCmdSequence; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteCmdPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
jtagAddDeviceWriteCmdPtr jtagAddDeviceWriteCmd; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagAddDeviceReadCmdPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState); |
jtagAddDeviceReadCmdPtr jtagAddDeviceReadCmd; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteReadCmdPtr)(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead, |
PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite, |
DWORD dwTapControllerState); |
jtagAddDeviceWriteReadCmdPtr jtagAddDeviceWriteReadCmd; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagExecuteCmdSequencePtr)(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer, |
LPDWORD lpdwNumBytesReturned); |
jtagExecuteCmdSequencePtr jtagExecuteCmdSequence; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagGetDllVersionPtr)(LPSTR lpDllVersionBuffer, DWORD dwBufferSize); |
jtagGetDllVersionPtr jtagGetDllVersion; |
|
|
|
typedef FTC_STATUS _stdcall (*jtagGetErrorCodeStringPtr)(LPSTR lpLanguage, FTC_STATUS StatusCode, |
LPSTR lpErrorMessageBuffer, DWORD dwBufferSize); |
jtagGetErrorCodeStringPtr jtagGetErrorCodeString; |
|
|
int getFTDIJTAGFunctions (); |
|
|
#endif /* _WIN_FTCJTAG_PTRS_H_ */ |
/or_debug_proxy/includes/or_debug_proxy.h
0,0 → 1,163
/*$$HEADER*/ |
/******************************************************************************/ |
/* */ |
/* H E A D E R I N F O R M A T I O N */ |
/* */ |
/******************************************************************************/ |
|
// Project Name : OpenRISC Debug Proxy |
// File Name : or_debug_proxy.h |
// Prepared By : jb |
// Project Start : 2008-10-01 |
|
/*$$COPYRIGHT NOTICE*/ |
/******************************************************************************/ |
/* */ |
/* C O P Y R I G H T N O T I C E */ |
/* */ |
/******************************************************************************/ |
/* |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; |
version 2.1 of the License, a copy of which is available from |
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. |
|
This library 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 |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
*/ |
|
/*$$CHANGE HISTORY*/ |
/******************************************************************************/ |
/* */ |
/* C H A N G E H I S T O R Y */ |
/* */ |
/******************************************************************************/ |
|
// Date Version Description |
//------------------------------------------------------------------------ |
// 081101 First revision jb |
|
#ifndef _OR_DEBUG_PROXY_H_ |
#define _OR_DEBUG_PROXY_H_ |
|
#ifndef DEBUG_CMDS |
#define DEBUG_CMDS 0 // Output the actual commands being sent to the debug unit |
#endif |
|
#ifndef DEBUG_USB_DRVR_FUNCS |
#define DEBUG_USB_DRVR_FUNCS 0 // Generate debug output from the USB driver functions |
#endif |
|
#ifndef DEBUG_GDB_BLOCK_DATA |
#define DEBUG_GDB_BLOCK_DATA 0 // GDB Socket Block data print out |
#endif |
|
// This one is defined sometimes in the makefile, so check first |
#ifndef DEBUG_GDB |
#define DEBUG_GDB 0 // GDB RSP Debugging output enabled |
#endif |
|
#ifndef DEBUG_GDB_DUMP_DATA |
#define DEBUG_GDB_DUMP_DATA 0 // GDB Socket Debugging - output all data we return to GDB client |
#endif |
|
#define Boolean uint32_t |
#define false 0 |
#define true 1 |
|
/* Selects crc trailer size in bits. Currently supported: 8 */ |
#define CRC_SIZE (8) |
|
#include <stdint.h> |
|
extern int serverPort; |
extern int server_fd; |
|
extern int vpi_fd; // should be the descriptor for our connection to the VPI server |
|
extern int current_chain; |
extern int dbg_chain; |
|
#define DBGCHAIN_SIZE 4 // Renamed from DC_SIZE due to definition clash with something in <windows.h> --jb 090302 |
#define DC_STATUS_SIZE 4 |
|
#define DC_WISHBONE 0 |
#define DC_CPU0 1 |
#define DC_CPU1 2 |
|
// Manually figure the 5-bit reversed values again if they change |
#define DI_GO 0 |
#define DI_READ_CMD 1 |
#define DI_WRITE_CMD 2 |
#define DI_READ_CTRL 3 |
#define DI_WRITE_CTRL 4 |
|
#define DBG_CRC_SIZE 32 |
#define DBG_CRC_POLY 0x04c11db7 |
|
#define DBG_ERR_OK 0 |
#define DBG_ERR_INVALID_ENDPOINT 3 |
#define DBG_ERR_CRC 8 |
|
#define NUM_SOFT_RETRIES 3 |
#define NUM_HARD_RETRIES 3 |
#define NUM_ACCESS_RETRIES 10 |
|
/* setup connection with the target */ |
void dbg_test(); |
/* perform a reset of the debug chain (not of system!) */ |
int dbg_reset(); |
/* set instruction register of JTAG TAP */ |
int dbg_set_tap_ir(uint32_t ir); |
/* Set "scan chain" of debug unit (NOT JTAG TAP!) */ |
int dbg_set_chain(uint32_t chain); |
/* read a word from wishbone */ |
int dbg_wb_read32(uint32_t adr, uint32_t *data); |
/* write a word to wishbone */ |
int dbg_wb_write32(uint32_t adr, uint32_t data); |
/* read a block from wishbone */ |
int dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len); |
/* write a block to wishbone */ |
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len); |
/* read a register from cpu */ |
int dbg_cpu0_read(uint32_t adr, uint32_t *data); |
/* read a register from cpu module */ |
int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data); |
/* write a cpu register */ |
int dbg_cpu0_write(uint32_t adr, uint32_t data); |
/* write a cpu module register */ |
int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data); |
|
void print_usage(); // Self explanatory |
|
void check(char *fn, uint32_t l, uint32_t i); |
|
/* Possible errors are listed here. */ |
enum enum_errors /* modified <chris@asics.ws> CZ 24/05/01 */ |
{ |
/* Codes > 0 are for system errors */ |
|
ERR_NONE = 0, |
ERR_CRC = -1, |
ERR_MEM = -2, |
JTAG_PROXY_INVALID_COMMAND = -3, |
JTAG_PROXY_SERVER_TERMINATED = -4, |
JTAG_PROXY_NO_CONNECTION = -5, |
JTAG_PROXY_PROTOCOL_ERROR = -6, |
JTAG_PROXY_COMMAND_NOT_IMPLEMENTED = -7, |
JTAG_PROXY_INVALID_CHAIN = -8, |
JTAG_PROXY_INVALID_ADDRESS = -9, |
JTAG_PROXY_ACCESS_EXCEPTION = -10, /* Write to ROM */ |
JTAG_PROXY_INVALID_LENGTH = -11, |
JTAG_PROXY_OUT_OF_MEMORY = -12, |
}; |
|
#endif /* _OR_DEBUG_PROXY_H_ */ |
|
/or_debug_proxy/lib/FTCJTAG.dll
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
or_debug_proxy/lib/FTCJTAG.dll
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: or_debug_proxy/src/win_usb_driver_calls.c
===================================================================
--- or_debug_proxy/src/win_usb_driver_calls.c (nonexistent)
+++ or_debug_proxy/src/win_usb_driver_calls.c (revision 1779)
@@ -0,0 +1,477 @@
+/*$$HEADER*/
+/******************************************************************************/
+/* */
+/* H E A D E R I N F O R M A T I O N */
+/* */
+/******************************************************************************/
+
+// Project Name : OpenRISC Debug Proxy
+// File Name : win_usb_driver_calls.c
+// Prepared By : jb
+// Project Start : 2008-10-01
+
+/*$$COPYRIGHT NOTICE*/
+/******************************************************************************/
+/* */
+/* C O P Y R I G H T N O T I C E */
+/* */
+/******************************************************************************/
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License, a copy of which is available from
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*$$DESCRIPTION*/
+/******************************************************************************/
+/* */
+/* D E S C R I P T I O N */
+/* */
+/******************************************************************************/
+//
+// Some generically named functions for interfacing to the JTAG driver
+// functions, making the code calling these platform independant. The correct
+// driver calling file (either Cygwin or Linux driver) is included at compile
+// time.
+// Also included in this file is the USB-JTAG chip initialisation function.
+//
+
+
+/*$$CHANGE HISTORY*/
+/******************************************************************************/
+/* */
+/* C H A N G E H I S T O R Y */
+/* */
+/******************************************************************************/
+
+// Date Version Description
+//------------------------------------------------------------------------
+// 081101 First revision jb
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "win_FTCJTAG.h"
+
+#include "win_FTCJTAG_ptrs.h"
+
+#include "usb_driver_calls.h"
+
+#include "or_debug_proxy.h"
+
+
+// Load the pointers and loading functions of the FTCJTAG driver
+int getFTDIJTAGFunctions (){
+
+ HINSTANCE hLib;
+
+ /* Load the library */
+ hLib = LoadLibrary("lib/FTCJTAG.dll");
+
+ if (hLib == NULL) {
+ printf("Loading of library file \"FTCJTAG.dll\" failed!\n");
+ return -1;
+ }
+
+
+ /* get the address of the functions */
+ jtagGetNumDevices = (jtagGetNumDevicesPtr) GetProcAddress(hLib, "JTAG_GetNumDevices");
+
+ if (jtagGetNumDevices == NULL) {
+ printf("GetProcAddress for JTAG_GetNumDevices Failed.\n");
+ return -1;
+ }
+
+ jtagInitDevice = (jtagInitDevicePtr) GetProcAddress(hLib, "JTAG_InitDevice");
+ if (jtagInitDevice == NULL) {
+ printf("GetProcAddress for JTAG_InitDevice Failed.\n");
+ return -1;
+ }
+
+ jtagOpen = (jtagOpenPtr) GetProcAddress(hLib, "JTAG_Open");
+ if (jtagOpen == NULL) {
+ printf("GetProcAddress for JTAG_Open Failed.\n");
+ return -1;
+ }
+
+ jtagOpenEx = (jtagOpenExPtr) GetProcAddress(hLib, "JTAG_OpenEx");
+ if (jtagOpenEx == NULL) {
+ printf("GetProcAddress for JTAG_OpenEx Failed.\n");
+ return -1;
+ }
+
+ jtagGetDeviceNameLocID = (jtagGetDeviceNameLocIDPtr) GetProcAddress(hLib, "JTAG_GetDeviceNameLocID");
+ if (jtagGetDeviceNameLocID == NULL) {
+ printf("GetProcAddress for Failed JTAG_GetDeviceNameLocID.\n");
+ return -1;
+ }
+
+ jtagClose = (jtagClosePtr) GetProcAddress(hLib, "JTAG_Close");
+ if (jtagClose == NULL) {
+ printf("GetProcAddress for JTAG_Close Failed.\n");
+ return -1;
+ }
+
+ jtagGetClock = (jtagGetClockPtr) GetProcAddress(hLib, "JTAG_GetClock");
+ if (jtagGetClock == NULL) {
+ printf("GetProcAddress for JTAG_GetClock Failed.\n");
+ return -1;
+ }
+
+ jtagSetClock = (jtagSetClockPtr) GetProcAddress(hLib, "JTAG_SetClock");
+ if (jtagSetClock == NULL) {
+ printf("GetProcAddress for JTAG_SetClock Failed.\n");
+ return -1;
+ }
+
+ jtagSetLoopback = (jtagSetLoopbackPtr) GetProcAddress(hLib, "JTAG_SetLoopback");
+ if (jtagSetLoopback == NULL) {
+ printf("GetProcAddress for JTAG_SetLoopback Failed.\n");
+ return -1;
+ }
+
+ jtagSetGPIOs = (jtagSetGPIOsPtr) GetProcAddress(hLib, "JTAG_SetGPIOs");
+ if (jtagSetGPIOs == NULL) {
+ printf("GetProcAddress for JTAG_SetGPIOs Failed.\n");
+ return -1;
+ }
+
+ jtagGetGPIOs = (jtagGetGPIOsPtr) GetProcAddress(hLib, "JTAG_GetGPIOs");
+ if (jtagGetGPIOs == NULL) {
+ printf("GetProcAddress for JTAG_GetGPIOs Failed.\n");
+ return -1;
+ }
+
+ jtagWrite = (jtagWritePtr) GetProcAddress(hLib, "JTAG_Write");
+ if (jtagWrite == NULL) {
+ printf("GetProcAddress for JTAG_Write Failed.\n");
+ return -1;
+ }
+
+ jtagRead = (jtagReadPtr) GetProcAddress(hLib, "JTAG_Read");
+ if (jtagRead == NULL) {
+ printf("GetProcAddress for JTAG_Read Failed.\n");
+ return -1;
+ }
+
+ jtagWriteRead = (jtagWriteReadPtr) GetProcAddress(hLib, "JTAG_WriteRead");
+ if (jtagWriteRead == NULL) {
+ printf("GetProcAddress for JTAG_WriteRead Failed.\n");
+ return -1;
+ }
+
+ jtagAddWriteCmd = (jtagAddWriteCmdPtr) GetProcAddress(hLib, "JTAG_AddWriteCmd");
+ if (jtagAddWriteCmd == NULL) {
+ printf("GetProcAddress for JTAG_AddWriteCmd Failed.\n");
+ return -1;
+ }
+
+ jtagAddReadCmd = (jtagAddReadCmdPtr) GetProcAddress(hLib, "JTAG_AddReadCmd");
+ if (jtagAddReadCmd == NULL) {
+ printf("GetProcAddress for JTAG_AddReadCmd Failed.\n");
+ return -1;
+ }
+
+ jtagAddWriteReadCmd = (jtagAddWriteReadCmdPtr) GetProcAddress(hLib, "JTAG_AddWriteReadCmd");
+ if (jtagAddWriteReadCmd == NULL) {
+ printf("GetProcAddress for JTAG_AddWriteReadCmd Failed.\n");
+ return -1;
+ }
+
+ jtagClearDeviceCmdSequence = (jtagClearDeviceCmdSequencePtr) GetProcAddress(hLib, "JTAG_ClearDeviceCmdSequence");
+ if (jtagClearDeviceCmdSequence == NULL) {
+ printf("GetProcAddress for Failed.\n JTAG_ClearDeviceCmdSequence");
+ return -1;
+ }
+
+ jtagAddDeviceReadCmd = (jtagAddDeviceReadCmdPtr) GetProcAddress(hLib, "JTAG_AddDeviceReadCmd");
+ if (jtagAddDeviceReadCmd == NULL) {
+ printf("GetProcAddress for Failed JTAG_AddDeviceReadCmd.\n");
+ return -1;
+ }
+
+ jtagAddDeviceWriteReadCmd = (jtagAddDeviceWriteReadCmdPtr) GetProcAddress(hLib, "JTAG_AddDeviceWriteReadCmd");
+ if (jtagAddDeviceWriteReadCmd == NULL) {
+ printf("GetProcAddress for Failed.\n JTAG_AddDeviceWriteReadCmd");
+ return -1;
+ }
+
+ jtagExecuteCmdSequence = (jtagExecuteCmdSequencePtr) GetProcAddress(hLib, "JTAG_ExecuteCmdSequence");
+ if (jtagExecuteCmdSequence == NULL) {
+ printf("GetProcAddress for Failed JTAG_ExecuteCmdSequence.\n");
+ return -1;
+ }
+
+ jtagGetDllVersion = (jtagGetDllVersionPtr) GetProcAddress(hLib, "JTAG_GetDllVersion");
+ if (jtagGetDllVersion == NULL) {
+ printf("GetProcAddress for JTAG_GetDllVersion Failed.\n");
+ return -1;
+ }
+
+ jtagGetErrorCodeString = (jtagGetErrorCodeStringPtr) GetProcAddress(hLib, "JTAG_GetErrorCodeString");
+ if (jtagGetErrorCodeString == NULL) {
+ printf("GetProcAddress for Failed JTAG_GetErrorCodeString.\n");
+ return -1;
+ }
+
+ // = (Ptr) GetProcAddress(hLib, "");
+ //if ( == NULL) {
+ // printf("GetProcAddress for Failed.\n");
+ // return -1;
+ // }
+
+ return 0;
+
+}
+
+
+// Global USB JTAG device handle
+FTC_HANDLE ftHandle;
+
+FTC_STATUS
+FT2232_USB_JTAG_WriteDataToExternalDevice(
+ //FTC_HANDLE ftHandle,
+ BOOL bInstructionTestData,
+ DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer,
+ DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ // Return the appropritae call to the Windows driver
+ return (jtagWrite)(
+ ftHandle,
+ bInstructionTestData,
+ dwNumBitsToWrite,
+ pWriteDataBuffer,
+ dwNumBytesToWrite,
+ dwTapControllerState);
+
+}
+
+
+// Read data from external device
+FTC_STATUS
+FT2232_USB_JTAG_ReadDataFromExternalDevice(
+ //FTC_HANDLE ftHandle,
+ BOOL bInstructionTestData,
+ DWORD dwNumBitsToRead,
+ PReadDataByteBuffer pReadDataBuffer,
+ LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+
+{
+ return (jtagRead)(
+ ftHandle,
+ bInstructionTestData,
+ dwNumBitsToRead,
+ pReadDataBuffer,
+ lpdwNumBytesReturned,
+ dwTapControllerState);
+
+}
+
+
+
+
+
+
+// Write Read
+FTC_STATUS
+FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(
+ //FTC_HANDLE ftHandle,
+ BOOL bInstructionTestData,
+ DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer,
+ DWORD dwNumBytesToWrite,
+ PReadDataByteBuffer pReadDataBuffer,
+ LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+{
+
+ return (jtagWriteRead)(
+ ftHandle,
+ bInstructionTestData,
+ dwNumBitsToWriteRead,
+ pWriteDataBuffer,
+ dwNumBytesToWrite,
+ pReadDataBuffer,
+ lpdwNumBytesReturned,
+ dwTapControllerState);
+
+}
+
+
+
+// Close device
+FTC_STATUS
+FT2232_USB_JTAG_CloseDevice()
+{
+ return (jtagClose)(ftHandle);
+}
+
+
+
+
+// Set clock frequency
+// Frequency = 12Mhz/((1+divisor)*2),
+// divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz
+#define USB_JTAG_CLK_DIVIDER 0
+
+int init_usb_jtag()
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDevices = 0;
+ char szDeviceName[100];
+ DWORD dwLocationID = 0;
+ // Made global: FTC_HANDLE ftHandle;
+ DWORD dwClockFrequencyHz = 0;
+ FTC_INPUT_OUTPUT_PINS LowInputOutputPinsData;
+ FTC_INPUT_OUTPUT_PINS HighInputOutputPinsData;
+ FTC_LOW_HIGH_PINS LowPinsInputData;
+ FTC_LOW_HIGH_PINS HighPinsInputData;
+ BOOL bPerformCommandSequence = false;
+
+ DWORD dwLoopCntr = 0;
+ char szDllVersion[10];
+
+ Status = (jtagGetNumDevices)(&dwNumDevices);
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG_GetNumDevices returned Status: 0x%x and %d devices\n",
+ Status, dwNumDevices);
+
+
+
+ if (dwNumDevices == 0)
+ {
+ printf("Error: USB debug cable not detected\nPlease ensure the device is attached and correctly installed\n\n");
+ exit(-1);
+ }
+
+
+ Status = (jtagGetDllVersion)(szDllVersion, 10);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG_GetDLLVersion returned Status: 0x%x and version %s\n",
+ Status, szDllVersion);
+
+
+ // To do: Iterate through dwNumDevices by index number ,looking for the ORSoC Device, "ORSoC OpenRISC debug cable A\0",
+
+ if ((Status == FTC_SUCCESS) && (dwNumDevices > 0))
+ {
+ if (dwNumDevices == 1)
+ {
+ Status = (jtagGetDeviceNameLocID)(0,szDeviceName,50, &dwLocationID);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG_GetDeviceNameLocID: %s at: 0x%x\n",
+ szDeviceName, dwLocationID);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = (jtagOpenEx)(szDeviceName, dwLocationID, &ftHandle);
+
+ }
+ }
+ else
+ {
+ if (dwNumDevices == 2)
+ {
+ Status=(jtagGetDeviceNameLocID)(1,szDeviceName,50,&dwLocationID);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = (jtagOpenEx)(szDeviceName, dwLocationID, &ftHandle);
+ }
+ }
+ }
+ }
+
+
+ if ((Status == FTC_SUCCESS) && (dwNumDevices > 0))
+ {
+ Status = (jtagInitDevice)(ftHandle, 0);
+
+ // Set clock frequency
+ // Frequency = 12Mhz/((1+divisor)*2),
+ // divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz
+ if (Status == FTC_SUCCESS)
+ Status = (jtagSetClock)(ftHandle, USB_JTAG_CLK_DIVIDER,
+ &dwClockFrequencyHz);
+
+
+ if (Status == FTC_SUCCESS){
+ printf("USB JTAG interface initialised\n");
+ Status = (jtagGetClock)(5, &dwClockFrequencyHz);
+ }
+
+ if (Status == FTC_SUCCESS)
+ { // true=output, false=input
+ LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 -
+ // set ADBUS4 to output 0 to enable JTAG buffers on Olimex devices
+ LowInputOutputPinsData.bPin2InputOutputState = true; //ADBUS5
+ LowInputOutputPinsData.bPin3InputOutputState = true;
+ LowInputOutputPinsData.bPin4InputOutputState = true;
+ //ADBUS4 = 0 (enable JTAG buffers on Olimex devices)
+ LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4
+ LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5
+ LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7
+
+ HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2
+ HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3
+ HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3LowHighState = true; // ACBUS2
+ HighInputOutputPinsData.bPin4LowHighState =true; // ACBUS3
+
+ Status = (jtagSetGPIOs)(ftHandle, true, &LowInputOutputPinsData,
+ true, &HighInputOutputPinsData);
+
+ if (Status == FTC_SUCCESS)
+ Status = (jtagGetGPIOs)(ftHandle, true, &LowPinsInputData,
+ true, &HighPinsInputData);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG low gpio pins values: (ADBUS7-ADBUS4):%x%x%x%x\n",
+ (LowPinsInputData.bPin4LowHighState==true),
+ (LowPinsInputData.bPin3LowHighState==true),
+ (LowPinsInputData.bPin2LowHighState==true),
+ (LowPinsInputData.bPin1LowHighState==true));
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG high gpio pins values: (ACBUS3-ACBUS0): %x%x%x%x\n",
+ (HighPinsInputData.bPin4LowHighState==true),
+ (HighPinsInputData.bPin3LowHighState==true),
+ (HighPinsInputData.bPin2LowHighState==true),
+ (HighPinsInputData.bPin1LowHighState==true));
+ }
+ }
+
+ if (Status == FTC_SUCCESS)
+ return 0;
+ else
+ return 1;
+
+}
Index: or_debug_proxy/src/usb_functions.c
===================================================================
--- or_debug_proxy/src/usb_functions.c (nonexistent)
+++ or_debug_proxy/src/usb_functions.c (revision 1779)
@@ -0,0 +1,1069 @@
+/*$$HEADER*/
+/******************************************************************************/
+/* */
+/* H E A D E R I N F O R M A T I O N */
+/* */
+/******************************************************************************/
+
+// Project Name : OpenRISC Debug Proxy
+// File Name : usb_functions.c
+// Prepared By : jb
+// Project Start : 2008-10-01
+
+/*$$COPYRIGHT NOTICE*/
+/******************************************************************************/
+/* */
+/* C O P Y R I G H T N O T I C E */
+/* */
+/******************************************************************************/
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License, a copy of which is available from
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*$$DESCRIPTION*/
+/******************************************************************************/
+/* */
+/* D E S C R I P T I O N */
+/* */
+/******************************************************************************/
+//
+// Code calling the FT2232 JTAG MPSSE driver functions. Does a majority of the
+// fiddly work when interfacing to the system via its debug module.
+//
+
+
+/*$$CHANGE HISTORY*/
+/******************************************************************************/
+/* */
+/* C H A N G E H I S T O R Y */
+/* */
+/******************************************************************************/
+// Date Version Description
+//------------------------------------------------------------------------
+// 081101 First revision jb
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#ifdef CYGWIN_COMPILE
+#include
+#include "win_FTCJTAG.h"
+#else // We're on Linux or Mac OS X
+#include "WinTypes.h" // We still use things from here in this file - TODO: remove this dependency
+#include "FT2232cMpsseJtag.h"
+#endif
+
+#include "gdb.h"
+
+#include "usb_functions.h"
+
+#include "or_debug_proxy.h"
+
+#include "usb_driver_calls.h"
+
+// Global JTAG signals for reading/writing
+DWORD dwNumBytesReturned = 0;
+
+/* Crc of current read or written data. */
+uint32_t crc_r, crc_w = 0;
+
+/* Generates new crc, sending in new bit input_bit */
+uint32_t crc_calc(uint32_t crc, uint32_t input_bit) {
+ uint32_t d = (input_bit) ? 0xfffffff : 0x0000000;
+ uint32_t crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000;
+ crc <<= 1;
+ return crc ^ ((d ^ crc_32) & DBG_CRC_POLY);
+}
+
+// Speedy bit reversing algorithms for base2 lengths
+// Thanks to: http://aggregate.org/MAGIC/#Bit%20Reversal
+uint32_t bit_reverse_swar_2(uint32_t x)
+{
+ x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
+ return x;
+}
+uint32_t bit_reverse_swar_4(uint32_t x)
+{
+ x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
+ x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
+ return x;
+}
+uint32_t bit_reverse_swar_8(uint32_t x)
+{
+ x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
+ x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
+ x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
+ return x;
+}
+uint32_t bit_reverse_swar_16(uint32_t x)
+{
+ x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
+ x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
+ x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
+ x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8));
+ return x;
+}
+uint32_t bit_reverse_swar_32(uint32_t x)
+{
+ x=(((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1));
+ x=(((x&0xcccccccc)>>2)|((x&0x33333333)<<2));
+ x=(((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4));
+ x=(((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8));
+ x=(((x&0xffff0000)>>16)|((x&0x0000ffff)<<16)); // We could be on 64-bit arch!
+ return x;
+}
+
+uint32_t bit_reverse_data(uint32_t data, uint32_t length){
+ if (length == 2) return bit_reverse_swar_2(data);
+ if (length == 4) return bit_reverse_swar_4(data);
+ if (length == 8) return bit_reverse_swar_8(data);
+ if (length == 16) return bit_reverse_swar_16(data);
+ if (length == 32) return bit_reverse_swar_32(data);
+ // Long and laborious way - hopefully never gets called anymore!
+ uint32_t i,reverse=0;
+ for (i=0;i>i)&1)<<(length-1-i));
+ return reverse;
+}
+// Constants that are used a lot, and were 5 bits, so might as well precalculate them
+// These are from or_debug_proxy.h, so if the original values change these
+// should be recalculated!!
+const uint8_t DI_GO_5BITREVERSED = 0x00;
+const uint8_t DI_READ_CMD_5BITREVERSED = 0x10;
+const uint8_t DI_WRITE_CMD_5BITREVERSED = 0x08;
+const uint8_t DI_READ_CTRL_5BITREVERSED = 0x18;
+const uint8_t DI_WRITE_CTRL_5BITREVERSED = 0x04;
+
+
+void usb_dbg_test() {
+
+ uint32_t npc, ppc, r1;
+ unsigned char stalled;
+
+
+
+ printf("Stalling or1k\n");
+ err = dbg_cpu0_write_ctrl(0, 0x01); // stall or1k
+
+ err = dbg_cpu0_read_ctrl(0, &stalled);
+ if (!(stalled & 0x1)) {
+ printf("or1k should be stalled\n"); // check stall or1k
+ exit(1);
+ }
+
+ /* Clear Debug Reason Register (DRR) 0x3015 */
+ err = dbg_cpu0_write((6 << 11) + 21, 0);
+ err = dbg_cpu0_read((0 << 11) + 16, &npc); /* Read NPC */
+ err = dbg_cpu0_read((0 << 11) + 18, &ppc); /* Read PPC */
+ err = dbg_cpu0_read(0x401, &r1); /* Read R1 */
+
+ if (err)
+ {
+ printf("Jtag error %d occured; exiting.", err);
+ FT2232_USB_JTAG_CloseDevice();
+ exit(1);
+ }
+ printf("Read npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1);
+
+ return;
+}
+
+/*
+void ensure_or1k_stalled();
+
+// Function to check if the processor is stalled, if not, stall it.
+// this is useful in the event that GDB thinks the processor is stalled, but has, in fact
+// been hard reset on the board and is running.
+void ensure_or1k_stalled()
+{
+ unsigned char stalled;
+ dbg_cpu0_read_ctrl(0, &stalled);
+ if ((stalled & 0x1) != 0x1)
+ {
+ if (DEBUG_CMDS)
+ printf("Processor not stalled, like we thought\n");
+
+ // Set the TAP controller to its OR1k chain
+ usb_set_tap_ir(JI_DEBUG);
+ current_chain = -1;
+
+ // Processor isn't stalled, contrary to what we though, so stall it
+ printf("Stalling or1k\n");
+ dbg_cpu0_write_ctrl(0, 0x01); // stall or1k
+
+ }
+}
+*/
+/*---------------------------------------------------------------------------*/
+/*!Write up to 32-bits to the JTAG bus via the USB device
+
+Write up to 32-bits to the JTAG bus.
+
+@param[in] stream This should store the data to be written to the bus
+@param[in] num_bits Number of bits to write on the JTAG bus
+@param[in] dwTapControllerState State to leave the JTAG TAP in when done */
+/*---------------------------------------------------------------------------*/
+void usb_write_stream (uint32_t stream, uint32_t num_bits, DWORD dwTapControllerState){
+ FTC_STATUS Status = FTC_SUCCESS;
+ uint32_t i,num_bytes;
+ WriteDataByteBuffer WriteDataBuffer;
+
+ if ((num_bits/8)>0)num_bytes=(num_bits/8);
+ else num_bytes=1;
+ // First clear the buffer for the amount of data we're shifting in
+ // Bytewise copy the stream into WriteDataBuffer, LSB first
+
+ // This means if we want to send things MSb first, we need to pass them
+ // to this function wrapped with a call to bit_reverse_data(data,length)
+
+ for (i=0; i<(num_bytes)+1;i++)
+ WriteDataBuffer[i] = ((stream >>(8*i)) & (0xff));
+
+ // Now generate the CRC for what we're sending
+ // data should be presented MSb first (at bit0)
+ for (i=0;i>i)&1));
+
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ {
+ printf("\nusb_write_stream: num_bytes=%d, WriteDataBuffer contents for %d bits:",num_bytes,num_bits);
+ for (i=0;iJTAG_WriteDataToExternalDevice(ftHandle, false, num_bits,
+ // &WriteDataBuffer, num_bytes, dwTapControllerState);
+ // Platform independant function call
+ Status = FT2232_USB_JTAG_WriteDataToExternalDevice(false, num_bits,
+ &WriteDataBuffer, num_bytes, dwTapControllerState);
+
+ if (Status != FTC_SUCCESS)
+ printf("Write to USB device failed: status code: %ld\n",Status);
+
+}
+
+/*---------------------------------------------------------------------------*/
+/*!Read up to 32-bits off the JTAG bus via the USB device
+
+The return value of this should remain uint32_t as we're returning all the
+data in a signal variable. We never need more than 32-bits in a single read
+when using this function.
+
+@param[in] num_bits Number of bits to read off from the USB
+@param[in] dwTapControllerState State to leave the JTAG TAP in when done
+@return: The data read from the USB device */
+/*---------------------------------------------------------------------------*/
+uint32_t usb_read_stream(uint32_t num_bits, DWORD dwTapControllerState){
+ ReadDataByteBuffer ReadDataBuffer;
+ FTC_STATUS Status = FTC_SUCCESS;
+ uint32_t returnVal =0;
+ uint32_t i;
+
+ // Platform independant driver call
+ Status = FT2232_USB_JTAG_ReadDataFromExternalDevice(false, num_bits, &ReadDataBuffer, &dwNumBytesReturned, dwTapControllerState);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("usb_read_stream: returned Status: 0x%lx from reading %u bits, \n",
+ Status,num_bits);
+
+ if (Status == FTC_SUCCESS){
+
+ for(i=0;i>(i%8))&0x1)<<(num_bits-1-i);
+ }
+ }
+ // Generate the CRC for read
+ for (i=0;i>(num_bits-1-i))&1));
+
+ return returnVal;
+}
+
+/* Sets TAP instruction register */
+void usb_set_tap_ir(uint32_t ir) {
+
+ WriteDataByteBuffer WriteDataBuffer;
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ WriteDataBuffer[0] = ir;
+
+ // Using global ftHandle, writing to TAP instruction register 4 bits,
+ //Status = pFT2232cMpsseJtag->JTAG_WriteDataToExternalDevice(ftHandle, true,
+ //JI_SIZE, &WriteDataBuffer, 1, RUN_TEST_IDLE_STATE);
+ // Platform independant driver call
+
+ Status = FT2232_USB_JTAG_WriteDataToExternalDevice(true, JI_SIZE, &WriteDataBuffer, 1, RUN_TEST_IDLE_STATE);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("USB JTAG write of %x to instruction register returned Status: 0x%lx\n",
+ ir, Status);
+ current_chain = -1;
+}
+
+
+/* Resets JTAG, and sets DEBUG scan chain */
+int usb_dbg_reset() {
+
+ // uint32_t err;
+ uint32_t id;
+ uint32_t reinit_count=0;
+ retry_jtag_init:
+ if (init_usb_jtag() > 0)
+ return DBG_ERR_CRC;
+
+ // Set ID code instruction in IR
+ usb_set_tap_ir(JI_IDCODE);
+
+ // Now read out the IDCODE for the device
+ id = usb_read_stream(32, RUN_TEST_IDLE_STATE);
+
+ // if read ID was rubbish retry init - this is probably NOT the best way to do this...
+ if ((id == 0xffffffff) | (id == 0x00000002) | (id == 0x00000000)) {
+ //pFT2232cMpsseJtag->JTAG_CloseDevice(gFtHandle);
+ // Platform independant driver call
+ FT2232_USB_JTAG_CloseDevice();
+ if (reinit_count++ > 4){
+ printf("JTAG TAP ID read error. Unable to detect TAP controller. \nPlease ensure debugger is connected to target correctly.\n");
+ exit(1);
+ }
+ goto retry_jtag_init;
+ }
+
+ printf("JTAG ID = %08x\n", id & 0xffffffff);
+
+ /* select debug scan chain and stay in it forever */
+ usb_set_tap_ir(JI_DEBUG);
+ current_chain = -1;
+ return DBG_ERR_OK;
+}
+
+/* counts retries and returns zero if we should abort */
+static int retry_no = 0;
+int retry_do() {
+
+ unsigned char stalled;
+
+ //printf("RETRY\n");
+ if (retry_no == 0)
+ printf("Communication error. Retrying\n");
+
+ // Odds are if we're having a communication problem, we should
+ // just reconnect to the processor. It's probably just been reset.
+ /*
+ FT2232_USB_JTAG_CloseDevice();// Close the device
+
+ if (init_usb_jtag() > 0)
+ {
+ if (retry_no >= NUM_HARD_RETRIES)
+ return 1;
+ else
+ return 0;
+ }
+ */
+ usb_set_tap_ir(JI_DEBUG);
+
+ current_chain = -1;
+
+ if (retry_no == 1)
+ sleep(1);
+
+ else if ( retry_no < NUM_SOFT_RETRIES)
+ return 1; // Just attempt again
+ if ((retry_no >= NUM_SOFT_RETRIES) && (retry_no < NUM_SOFT_RETRIES + NUM_HARD_RETRIES) )
+ {
+ // Attempt a stall of the processor and then we'll try again
+ //usb_dbg_test();
+ printf("Stalling or1k\n");
+ err = dbg_cpu0_write_ctrl(0, 0x01); // stall or1k
+
+ err = dbg_cpu0_read_ctrl(0, &stalled);
+ if (!(stalled & 0x1)) {
+ printf("or1k should be stalled\n"); // check stall or1k
+ FT2232_USB_JTAG_CloseDevice();// Close the device
+ exit(1);
+ }
+
+ retry_no++;
+ return 1;
+ }
+ else // Unable to get the processor going again, return 0
+ return 0;
+
+}
+
+/* resets retry counter */
+void retry_ok() {
+ retry_no = 0;
+}
+
+/* Sets scan chain. */
+int usb_dbg_set_chain(int chain) {
+ uint32_t status, crc_generated, crc_read;
+ dbg_chain = chain;
+
+ try_again:
+ if (current_chain == chain) return DBG_ERR_OK;
+ current_chain = -1;
+ if (DEBUG_CMDS) printf("\n");
+ if (DEBUG_CMDS) printf("set_chain %i\n", chain);
+
+ crc_w = 0xffffffff; // reset crc write variable
+
+ // CRC generated in usb_read/write_stream functions
+
+ usb_write_stream((((bit_reverse_data(chain,DBGCHAIN_SIZE) & 0xf) << 1) | 1),
+ DBGCHAIN_SIZE+1 , PAUSE_TEST_DATA_REGISTER_STATE);
+
+ usb_write_stream(bit_reverse_data(crc_w, DBG_CRC_SIZE),DBG_CRC_SIZE,
+ PAUSE_TEST_DATA_REGISTER_STATE);
+
+ crc_r = 0xffffffff; // reset the crc_r variable
+
+ status = (usb_read_stream(DC_STATUS_SIZE,
+ PAUSE_TEST_DATA_REGISTER_STATE) & 0xf);
+
+ crc_generated = crc_r;
+
+ crc_read = usb_read_stream(DBG_CRC_SIZE, RUN_TEST_IDLE_STATE);
+ //printf("%x %x %x\n",status, crc_generated, crc_read);
+
+ /* CRCs must match, otherwise retry */
+ if (crc_read != crc_generated) {
+ if (retry_do()) goto try_again;
+ else return DBG_ERR_CRC;
+ }
+ /* we should read expected status value, otherwise retry */
+ if (status != 0) {
+ if (retry_do()) goto try_again;
+ else return status;
+ }
+
+ /* reset retry counter */
+ retry_ok();
+
+ current_chain = chain;
+ return DBG_ERR_OK;
+}
+
+
+
+/* sends out a command with 32bit address and 16bit length, if len >= 0 */
+int usb_dbg_command(uint32_t type, uint32_t adr, uint32_t len) {
+ uint32_t i,status, crc_generated, crc_read;
+
+ // JTAG driver things
+ FTC_STATUS Status = FTC_SUCCESS;
+ WriteDataByteBuffer WriteDataBuffer;
+ ReadDataByteBuffer ReadDataBuffer;
+
+ try_again:
+ usb_dbg_set_chain(dbg_chain);
+ if (DEBUG_CMDS) printf("\n");
+ if (DEBUG_CMDS) printf("comm %d %d %8x \n", type,len,adr);
+
+ //Calculate CRCs first
+ crc_w = 0xffffffff;
+
+ for (i=0;i> i) & 1);
+ //crc_w = crc_calc(crc_w,
+ // ((bit_reverse_data((DI_WRITE_CMD & 0xf),DBGCHAIN_SIZE+1))>>i)&1);
+
+ for (i=0;i<4;i++)
+ crc_w = crc_calc(crc_w,((bit_reverse_data(type,4))>>i)&1);
+
+ for (i=0;i<32;i++)
+ crc_w = crc_calc(crc_w,((bit_reverse_data(adr,32))>>i)&1);
+
+ assert(len > 0);
+ for (i=0;i<16;i++)
+ crc_w = crc_calc(crc_w,((bit_reverse_data(len-1,16))>>i)&1);
+
+
+
+ // Now pack the write data buffer
+ // 1-bit 0, 4-bits cmd, 4-bit type, 32-bit adr, 32-bit CRC
+ // [0]
+ //bits 0-4
+ WriteDataBuffer[0]=(DI_WRITE_CMD_5BITREVERSED);
+ //bits 5-7
+ WriteDataBuffer[0] |= ((bit_reverse_data(type,4)&0x7)<<5);
+ // [1]
+ // bit 0 - last bit of type
+ WriteDataBuffer[1] = ((bit_reverse_data(type,4)&0x08)>>3);
+ //bits 1-7 - first 7 bits of adr
+ WriteDataBuffer[1] |= ((bit_reverse_data(adr,32)&0x07f)<<1);
+ //[2-4] 24 bits of adr
+ for(i=0;i<3;i++)
+ WriteDataBuffer[2+i] = (bit_reverse_data(adr,32)>>(7+(i*8)))&0xff;
+ // [5] last bit of adr in bit 0, first 7 bits of len-1 follow
+ WriteDataBuffer[5] = (bit_reverse_data(adr,32)>>31)&1;
+ WriteDataBuffer[5] |= (bit_reverse_data(len-1,16)&0x7f)<<1;
+ // [6] bits 7-14 of (len-1)
+ WriteDataBuffer[6] = (bit_reverse_data(len-1,16)>>7)&0xff;
+ // [7] - last bit of len-1 and first 7 bits of the CRC
+ WriteDataBuffer[7] = (bit_reverse_data(len-1,16)>>15)&1;
+ //Reverse the CRC first
+ crc_w = bit_reverse_data(crc_w, DBG_CRC_SIZE);
+ WriteDataBuffer[7] |= (crc_w&0x7f)<<1;
+ //[8-10] next 24 bits (7-30) of crc_w
+ WriteDataBuffer[8] = (crc_w>>7)&0xff;
+ WriteDataBuffer[9] = (crc_w>>15)&0xff;
+ WriteDataBuffer[10] = (crc_w>>23)&0xff;
+ //[11] final bit of crc_w
+ WriteDataBuffer[11] = (crc_w>>31)&1;
+
+ // Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE);
+ // Platform independant driver call
+ Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE);
+
+ if (Status != FTC_SUCCESS)
+ printf("USB write fail - code %ld\b",Status);
+
+ // Now look through the read data
+
+ // From bit1 of ReadDataBuffer[11] we should have our 4-bit status
+ status = (ReadDataBuffer[11] >> 1) & 0xf;
+
+ // Now extract the received CRC
+ crc_read = 0;
+ //first 3 bits (0-2)
+ crc_read |= (ReadDataBuffer[11] >> 5) & 0x7;
+ // middle 3 bytes (bits 3 to 26)
+ for (i=0;i<3;i++)
+ crc_read |= ((ReadDataBuffer[12+i]&0xff) << ((i*8)+3));
+ // last 5 bits from ReadDataBuffer[15]
+ crc_read |= (ReadDataBuffer[15]&0x1f)<<27;
+
+ // Now calculate CRC on status
+ crc_r = 0xffffffff;
+ for(i=0;i>i)&1);
+
+ crc_generated = crc_r;
+ // Now bit reverse status and crc_read as we unpacked them
+ // with the MSb going to the LSb
+ status = bit_reverse_data(status, DC_STATUS_SIZE);
+ crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE);
+
+ //printf("%x %x %x\n", status, crc_read, crc_generated);
+ /* CRCs must match, otherwise retry */
+ if (crc_read != crc_generated) {
+ //exit(1);//remove later
+ if (retry_do()) goto try_again;
+ else return DBG_ERR_CRC;
+ }
+ /* we should read expected status value, otherwise retry */
+ if (status != 0) {
+ //exit(1);//remove later
+ if (retry_do()) goto try_again;
+ else return status;
+ }
+ /* reset retry counter */
+ retry_ok();
+
+ return DBG_ERR_OK;
+}
+
+
+/* writes a ctrl reg */
+int usb_dbg_ctrl(uint32_t reset, uint32_t stall) {
+ uint32_t i,status, crc_generated, crc_read;
+
+ // JTAG driver things
+ FTC_STATUS Status = FTC_SUCCESS;
+ WriteDataByteBuffer WriteDataBuffer;
+ ReadDataByteBuffer ReadDataBuffer;
+
+try_again:
+ usb_dbg_set_chain(dbg_chain);
+ if (DEBUG_CMDS) printf("\n");
+ if (DEBUG_CMDS) printf("ctrl\n");
+ if (DEBUG_CMDS) printf("reset %x stall %x\n", reset, stall);
+
+ crc_w = 0xffffffff;
+ // Try packing everyhing we want to send into one write buffer
+ //Calculate CRCs first
+ for (i=0;i>i)&1);
+ //crc_w = crc_calc(crc_w,
+ // ((bit_reverse_data((DI_WRITE_CTRL & 0xf),DBGCHAIN_SIZE+1))>>i)&1);
+ crc_w = crc_calc(crc_w,(reset&1));
+ crc_w = crc_calc(crc_w,(stall&1));
+ for (i=0;i<50;i++)
+ crc_w = crc_calc(crc_w,0);
+
+
+
+ // Now pack the write data buffer
+ // 1-bit 0, 4-bits cmd, 52-bits CPU control register data (only first 2 matter)
+ //bits 0-4
+ WriteDataBuffer[0]=(DI_WRITE_CTRL_5BITREVERSED);
+ // bit 5
+ WriteDataBuffer[0] |= (reset)<<(DBGCHAIN_SIZE+1);
+ // bit 6
+ WriteDataBuffer[0] |= (stall)<<(DBGCHAIN_SIZE+2);
+ // Clear the next 48 bits
+ for (i=1; i<16;i++) //actually clear more than just the next 50 bits
+ WriteDataBuffer[i] = 0;
+
+ //Reverse the CRC first
+ crc_w = bit_reverse_data(crc_w, DBG_CRC_SIZE);
+ //Now load in the CRC, but take note of fact
+ // that bit 0 of buffer[7] is last 0 from cmd register data
+ // fill up from WriteDataBuffer[7-11]
+ for (i=0;i<4;i++)
+ WriteDataBuffer[7+i] = ((crc_w<<1)>>(i*8))&0xff;
+ //Final bit, shift in and make sure is the only thing int he buffer
+ WriteDataBuffer[11]=0|((crc_w>>31)&1);
+
+
+ //Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE);
+ // Platform independant driver call
+ Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,89+4+32 , &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE);
+
+
+ if (Status != FTC_SUCCESS)
+ printf("USB write fail - code %ld\b",Status);
+
+ // Now look through the read data
+
+ // From bit1 of ReadDataBuffer[11] we should have our 4-bit status
+ status = (ReadDataBuffer[11] >> 1) & 0xf;
+
+ // Now extract the received CRC
+ crc_read = 0;
+ //first 3 bits (0-2)
+ crc_read |= (ReadDataBuffer[11] >> 5) & 0x7;
+ // middle 3 bytes (bits 3 to 26)
+ for (i=0;i<3;i++)
+ crc_read |= ((ReadDataBuffer[12+i]&0xff) << ((i*8)+3));
+ // last 5 bits from ReadDataBuffer[15]
+ crc_read |= (ReadDataBuffer[15]&0x1f)<<27;
+
+
+ // Now calculate CRC on status and crc_read
+ crc_r = 0xffffffff;
+ for(i=0;i>i)&1);
+
+ crc_generated = crc_r;
+ // Now bit reverse status and crc_read as we unpacked them
+ // with the MSb going to the LSb
+ status = bit_reverse_data(status, DC_STATUS_SIZE);
+ crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE);
+
+ /* CRCs must match, otherwise retry */
+ //printf("%x %x %x\n", status, crc_read, crc_generated);
+ if (crc_read != crc_generated) {
+ //exit(1);//Remove later!!
+ if (retry_do()) goto try_again;
+ else return DBG_ERR_CRC;
+ }
+ /* we should read expected status value, otherwise retry */
+ if (status != 0) {
+ //exit(1);//Remove later!!
+ if (retry_do()) goto try_again;
+ else return status;
+ }
+
+ /* reset retry counter */
+ retry_ok();
+ return DBG_ERR_OK;
+}
+
+
+/* reads control register */
+int usb_dbg_ctrl_read(uint32_t *reset, uint32_t *stall) {
+ uint32_t i, status, crc_generated, crc_read;
+
+ // JTAG driver things
+ FTC_STATUS Status = FTC_SUCCESS;
+ WriteDataByteBuffer WriteDataBuffer;
+ ReadDataByteBuffer ReadDataBuffer;
+
+
+ try_again:
+ usb_dbg_set_chain(dbg_chain);
+ if (DEBUG_CMDS) printf("\n");
+ if (DEBUG_CMDS) printf("ctrl_read\n");
+
+ crc_w = 0xffffffff;
+ // Try packing everyhing we want to send into one write buffer
+ //Calculate CRCs first
+ for (i=0;i>i)&1);
+ //crc_w = crc_calc(crc_w,
+ //((bit_reverse_data((DI_READ_CTRL & 0xf),DBGCHAIN_SIZE+1))>>i)&1);
+
+
+ // Now pack the write data buffer
+ // 1-bit 0, 4-bits cmd, 32-bit CRC
+ //bits 0-4
+ WriteDataBuffer[0]=(DI_READ_CTRL_5BITREVERSED);
+ // Clear the next 48 bits
+ for (i=1; i<16;i++) //actually clear more than just the next 50 bits
+ WriteDataBuffer[i] = 0;
+
+ //Reverse the CRC first
+ crc_w = bit_reverse_data(crc_w, DBG_CRC_SIZE);
+ //Now load in the CRC
+ //First 3 bits go in last 3 bits of buffer[0]
+ WriteDataBuffer[0] |= (crc_w & 0x7)<<5;
+ // The rest of crc_w goes in buffer[1-4]
+ for (i=0;i<3;i++)
+ WriteDataBuffer[1+i] = ((crc_w>>3)>>(i*8))&0xff;
+ //Final bit of write buffer with CRC
+ WriteDataBuffer[4] = ((crc_w>>3)>>(24))&0x1f;
+
+
+
+ //Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,5+32+52+4+32, &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE);
+ // Platform independant driver call
+ Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,5+32+52+4+32, &WriteDataBuffer, 16, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE);
+ if (Status != FTC_SUCCESS)
+ printf("USB read fail - code %ld\b",Status);
+
+ // Now look through the read data
+ //0 - 1+4-bit status, 3-bits CRC
+ //1,2,3 - CRC
+ //4 - first 5 bits CRC, last 3, control reg bits (first 3)
+ //5,6,7,8,9,10 - control reg data (48 bits)
+ //11 - bit0 - control reg data, bit 1-4 status bits, bits 5-7 CRC
+ //12, 13 14 - CRC
+ // 15 bits 0-4 CRC
+ // Starting from bit1 of ReadDataBuffer[11] we should have our 4-bit status
+ status = (ReadDataBuffer[11] >> 1) & 0xf;
+
+ //reset bit should be in ReadDataBuffer[4] as bit 5
+ *reset = (ReadDataBuffer[4] >> 5) & 1;
+ //stalled bit should be in ReadDataBuffer[4] as bit 6
+ *stall = (ReadDataBuffer[4] >> 6) & 1;
+ // Now extract the received CRC
+ crc_read = 0;
+ //first 3 bits (0-2) of CRC are in bits 5-7 of ReadDataBuffer[11]
+ crc_read |= (ReadDataBuffer[11] >> 5) & 0x7;
+ // middle 3 bytes (bits 3 to 26)
+ for (i=0;i<3;i++)
+ crc_read |= ((ReadDataBuffer[12+i]&0xff) << ((i*8)+3));
+ // last 5 bits from ReadDataBuffer[15]
+ crc_read |= (ReadDataBuffer[15]&0x1f)<<27;
+
+ if (DEBUG_CMDS) printf("reset bit %x stalled bit %x:\n",
+ ((ReadDataBuffer[4] >> 5) & 1), ((ReadDataBuffer[4] >> 6) & 1));
+
+ // Now calculate CRC on status and crc_read
+ crc_r = 0xffffffff;
+
+ crc_r = crc_calc(crc_r, ((ReadDataBuffer[4] >> 5) & 1));
+ crc_r = crc_calc(crc_r, ((ReadDataBuffer[4] >> 6) & 1));
+ for(i=0;i<50;i++)
+ crc_r = crc_calc(crc_r,0);
+ for(i=0;i>i)&1);
+
+ crc_generated = crc_r;
+ // Now bit reverse status and crc_read as we unpacked them
+ // with the MSb going to the LSb
+ status = bit_reverse_data(status, DC_STATUS_SIZE);
+ crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE);
+
+ /* CRCs must match, otherwise retry */
+ //printf("%x %x %x\n", status, crc_generated, crc_read);
+ if (crc_read != crc_generated) {
+ if (retry_do()) goto try_again;
+ else return DBG_ERR_CRC;
+ }
+ /* we should read expected status value, otherwise retry */
+ if (status != 0) {
+ if (retry_do()) goto try_again;
+ else return status;
+ }
+ /* reset retry counter */
+ retry_ok();
+ return DBG_ERR_OK;
+}
+
+
+/* issues a burst read/write */
+int usb_dbg_go(unsigned char *data, uint16_t len, uint32_t read) {
+ uint32_t status, crc_generated, crc_read;
+ int i,j;
+ uint8_t data_byte;
+
+ // JTAG driver things
+ FTC_STATUS Status = FTC_SUCCESS;
+ WriteDataByteBuffer WriteDataBuffer;
+ ReadDataByteBuffer ReadDataBuffer;
+
+ try_again:
+ usb_dbg_set_chain(dbg_chain);
+ if (DEBUG_CMDS) printf("\n");
+ if (DEBUG_CMDS) printf("go len is %d, read is %d\n", len, read);
+
+ crc_w = 0xffffffff;
+ // Try packing everyhing we want to send into one write buffer
+ //Calculate CRCs first
+ for (i=0;i>i)&1);
+ //crc_w = crc_calc(crc_w,
+ // ((bit_reverse_data((DI_GO & 0xf),DBGCHAIN_SIZE+1))>>i)&1);
+ // Set first 5 bits of WriteDataBuffer up to
+ // be the GO command and 0 first bit
+ WriteDataBuffer[0]=DI_GO_5BITREVERSED;
+
+ if (read)
+ {
+ // Do GO command for a read
+ // 0 then 4-bit go command, then 32-bit CRC for the last 5 bits
+ // Then read (len+1)*8 + 4-bit status + 32-bit CRC
+
+
+ // Reverse crc_w
+ crc_w = bit_reverse_data(crc_w,DBG_CRC_SIZE);
+
+ // Now pack in the 32-bit CRC as we're not
+ // writing anything else after it
+ //First 3 bits of each byte go in last 3 bits of buffer[i],
+ // next 5 go in buffer[i+1]
+ for(i=0;i<4;i++){
+ WriteDataBuffer[i] |= ((crc_w>>(i*8))&0x07)<<5;
+ WriteDataBuffer[i+1] = ((crc_w>>(i*8))>>3)&0x1f;
+ }
+
+ // Should have data up to WriteDataBuffer[4] bit 4
+ // Read data should start at ReadDataBuffer[4] bit 5
+
+ //Clear the rest of the write buffer
+ for(i=5;i<(10+len);i++)
+ WriteDataBuffer[i]=0;
+ }
+ if (!read){
+ // If we're writing we put in the 5 command bits, (len+1)*8 data bits,
+ // and then the 32-bit CRC do first 3 bits, then next 5 bits in
+ // each of the for loops iterations
+ for(i=0;i>3)&0x1f);
+ }
+
+ // Now update the CRC for the data we just wrote
+ for (i=0;i>j)&1));
+ }
+
+ // Reverse crc_w
+ crc_w = bit_reverse_data(crc_w,DBG_CRC_SIZE);
+
+ // If we have len=4 for example, we will write to
+ // WriteDataBuffer[4]'s first 5 bits
+
+ // So now load in the 32-bit CRC from there
+ for(i=0;i<4;i++){
+ WriteDataBuffer[len+i] |= ((crc_w>>(i*8))&0x07)<<5;
+ WriteDataBuffer[len+i+1] = ((crc_w>>(i*8))>>3)&0x1f;
+ }
+ // Should have data up to WriteDataBuffer[4+len] bit 4
+ // Read data should start at ReadDataBuffer[4+len] bit 5
+
+ }
+
+ //Status = pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(gFtHandle,false,(5+(len*8)+32+36), &WriteDataBuffer, (6+len+4), &ReadDataBuffer,&dwNumBytesReturned,RUN_TEST_IDLE_STATE);
+ Status = FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(false,(5+(len*8)+32+36), &WriteDataBuffer, (6+len+4), &ReadDataBuffer,&dwNumBytesReturned,RUN_TEST_IDLE_STATE);
+
+ if (Status != FTC_SUCCESS)
+ printf("USB write fail - code %ld\n",Status);
+
+ crc_r = 0xffffffff;
+
+ if (read){
+ // Look through our data, starting from ReadDataBuffer[4] bit 5
+ // We receive len bytes, starting at ReadDataBuffer[4] bit 5, so
+ // unpack like so
+ if (DEBUG_USB_DRVR_FUNCS) printf("USB read data buffer: ");
+ for(i=0;i>5)&0x07;
+ // then next 5 from next ReadDataBuffer byte
+ data[i] |= (ReadDataBuffer[4+i+1]&0x1f)<<3;
+
+ // Now calculate the CRC for this byte
+ for(j=0;j<8;j++)
+ crc_r = crc_calc(crc_r, (data[i]>>j)&1);
+
+ // Now bit reverse the byte as it was read in MSb first but
+ // written to LSb first
+ data[i] = bit_reverse_data(data[i],8);
+
+ if (DEBUG_USB_DRVR_FUNCS) printf("%2x",data[i]);
+ }
+ if (DEBUG_USB_DRVR_FUNCS) printf("\n");
+
+ // Should be up to ReadDataBuffer[4+len] bit 5 for data
+ status = (ReadDataBuffer[4+len]>>5)&0x07;
+ status |= (ReadDataBuffer[4+len+1]&1)<<3;
+ // Now get out crc_read
+ crc_read = 0;
+ for(i=0;i<4;i++){
+ crc_read |= ((ReadDataBuffer[4+len+1+i]>>1)&0x7f)<<(i*8);
+ crc_read |= ((ReadDataBuffer[4+len+1+i+1]&0x1)<<7)<<(i*8);
+ }
+
+ for(i=0;i<4;i++)
+ crc_r = crc_calc(crc_r, (status>>i)&1);
+ }
+ if (!read){
+ // Just extract our 4-bits of status and CRC
+ status = (ReadDataBuffer[4+len]>>5)&0x07;
+ status |= (ReadDataBuffer[4+len+1]&1)<<3;
+
+ // extract crc_read from the ReadDataBuffer
+ crc_read = 0;
+ for(i=0;i<4;i++){
+ crc_read |= ((ReadDataBuffer[4+len+1+i]>>1)&0x7f)<<(i*8);
+ crc_read |= ((ReadDataBuffer[4+len+1+i+1]&1)<<7)<<(i*8);
+ }
+ // Calculate our own CRC from the status value
+ for(i=0;i<4;i++)
+ crc_r = crc_calc(crc_r, (status>>i)&1);
+
+ }
+
+ crc_generated = crc_r;
+ // Now bit reverse status and crc_read as we unpacked them
+ // with the MSb going to the LSb
+ status = bit_reverse_data(status, DC_STATUS_SIZE);
+ crc_read = bit_reverse_data(crc_read, DBG_CRC_SIZE);
+
+
+ /* CRCs must match, otherwise retry */
+ if (crc_read != crc_generated) {
+ if (DEBUG_CMDS || DEBUG_USB_DRVR_FUNCS)printf("CRC mismatch: %x %x %x\n", status, crc_read, crc_generated);
+ if (retry_do()) goto try_again;
+ else return DBG_ERR_CRC;
+ }
+ /* we should read expected status value, otherwise retry */
+ if (status != 0) {
+ if (retry_do()) goto try_again;
+ else return status;
+ }
+
+ retry_ok();
+ return DBG_ERR_OK;
+}
+
+/* read a word from wishbone */
+int usb_dbg_wb_read32(uint32_t adr, uint32_t *data) {
+ // uint32_t err;
+ if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err;
+ if ((err = usb_dbg_command(0x6, adr, 4))) return err;
+ if ((err = usb_dbg_go((unsigned char*)data, 4, 1))) return err;
+ *data = ntohl(*data);
+ return err;
+}
+
+/* write a word to wishbone */
+int usb_dbg_wb_write32(uint32_t adr, uint32_t data) {
+ // uint32_t err;
+ data = ntohl(data);
+ if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err;
+ if ((err = usb_dbg_command(0x2, adr, 4))) return err;
+ if ((err = usb_dbg_go((unsigned char*)&data, 4, 0))) return err;
+ return DBG_ERR_OK;
+}
+
+/* read a block from wishbone */
+int usb_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len) {
+ uint32_t i; // err;
+ //printf("%08x %08x\n", adr, len);
+ if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err;
+ if ((err = usb_dbg_command(0x6, adr, len))) return err;
+ if ((err = usb_dbg_go((unsigned char*)data, len, 1))) return err;
+ uint32_t * data_uint32 = (uint32_t *) data; // data[i] gives us a proper 64-bit wide word on a 64-bit arch, so cast back to network sized data when ntohl'ing
+ for (i = 0; i < len / 4; i ++) data_uint32[i] = ntohl(data_uint32[i]);
+ //printf("%08x\n", err);
+ return DBG_ERR_OK;
+}
+
+
+/* write a block to wishbone */
+int usb_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) {
+ uint32_t i; //, err;
+ uint32_t * data_uint32 = (uint32_t *) data; // data[i] gives us a proper 64-bit wide word on a 64-bit arch, so cast back to network sized data when ntohl'ing
+ for (i = 0; i < len / 4; i ++) data_uint32[i] = ntohl(data_uint32[i]);
+ if ((err = usb_dbg_set_chain(DC_WISHBONE))) return err;
+ if ((err = usb_dbg_command(0x2, adr, len))) return err;
+ if ((err = usb_dbg_go((unsigned char*)data, len, 0))) return err;
+ return DBG_ERR_OK;
+}
+
+
+/* read a register from cpu */
+int usb_dbg_cpu0_read(uint32_t adr, uint32_t *data) {
+ // uint32_t err;
+ if ((err = usb_dbg_set_chain(DC_CPU0))) return err;
+ if ((err = usb_dbg_command(0x6, adr, 4))) return err;
+ if ((err = usb_dbg_go((unsigned char*)data, 4, 1))) return err;
+ *data = ntohl(*data);
+ return DBG_ERR_OK;
+}
+
+/* write a cpu register */
+int usb_dbg_cpu0_write(uint32_t adr, uint32_t data) {
+ // uint32_t err;
+ data = ntohl(data);
+ if ((err = usb_dbg_set_chain(DC_CPU0))) return err;
+ if ((err = usb_dbg_command(0x2, adr, 4))) return err;
+ if ((err = usb_dbg_go((unsigned char*)&data, 4, 0))) return err;
+ return DBG_ERR_OK;
+}
+
+/* write a cpu module register */
+int usb_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) {
+ // no ensuring that or1k is stalled here, becuase we're call this from that function
+ if ((err = usb_dbg_set_chain(DC_CPU0))) return err;
+ if ((err = usb_dbg_ctrl(data & 2, data &1))) return err;
+ return DBG_ERR_OK;
+}
+
+/* read a register from cpu module */
+int usb_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) {
+ // no ensuring that or1k is stalled here, becuase we're call this from that function
+ uint32_t r, s;
+ if ((err = usb_dbg_set_chain(DC_CPU0))) return err;
+ if ((err = usb_dbg_ctrl_read(&r, &s))) return err;
+ *data = (r << 1) | s;
+ return DBG_ERR_OK;
+}
+
+/* Function to close the device handle. Is called when closing the app */
+void usb_close_device_handle()
+{
+ FT2232_USB_JTAG_CloseDevice();
+}
Index: or_debug_proxy/src/linux_usb_driver_calls.c
===================================================================
--- or_debug_proxy/src/linux_usb_driver_calls.c (nonexistent)
+++ or_debug_proxy/src/linux_usb_driver_calls.c (revision 1779)
@@ -0,0 +1,428 @@
+/*$$HEADER*/
+/******************************************************************************/
+/* */
+/* H E A D E R I N F O R M A T I O N */
+/* */
+/******************************************************************************/
+
+// Project Name : OpenRISC Debug Proxy
+// File Name : linux_usb_driver_calls.c
+// Prepared By : jb
+// Project Start : 2008-10-01
+
+/*$$COPYRIGHT NOTICE*/
+/******************************************************************************/
+/* */
+/* C O P Y R I G H T N O T I C E */
+/* */
+/******************************************************************************/
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License, a copy of which is available from
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*$$DESCRIPTION*/
+/******************************************************************************/
+/* */
+/* D E S C R I P T I O N */
+/* */
+/******************************************************************************/
+//
+// Some generically named functions for interfacing to the JTAG driver
+// functions, making the code calling these platform independant. The correct
+// driver calling file (either Cygwin or Linux driver) is included at compile
+// time.
+// Also included in this file is the USB-JTAG chip initialisation function.
+//
+
+
+/*$$CHANGE HISTORY*/
+/******************************************************************************/
+/* */
+/* C H A N G E H I S T O R Y */
+/* */
+/******************************************************************************/
+
+// Date Version Description
+//------------------------------------------------------------------------
+// 081101 First revision jb
+
+#include
+
+#include "WinTypes.h"
+
+#include "usb_driver_calls.h"
+
+#include "usb_functions.h"
+#include "or_debug_proxy.h"
+
+#include "FT2232cMpsseJtag.h"
+
+static FT2232cMpsseJtag *pFT2232cMpsseJtag = NULL;
+
+// Global USB JTAG device handle
+FTC_HANDLE ftHandle;
+
+// Write data to external device:
+//FTC_STATUS FT2232cMpsseJtag::JTAG_WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+
+FTC_STATUS
+FT2232_USB_JTAG_WriteDataToExternalDevice(
+ //FTC_HANDLE ftHandle,
+ BOOL bInstructionTestData,
+ DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer,
+ DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ // Call the driver from the libary compiled in Linux
+ return pFT2232cMpsseJtag->JTAG_WriteDataToExternalDevice(
+ ftHandle,
+ bInstructionTestData,
+ dwNumBitsToWrite,
+ pWriteDataBuffer,
+ dwNumBytesToWrite,
+ dwTapControllerState);
+}
+
+
+// Read data from external device
+FTC_STATUS
+FT2232_USB_JTAG_ReadDataFromExternalDevice(
+ //FTC_HANDLE ftHandle,
+ BOOL bInstructionTestData,
+ DWORD dwNumBitsToRead,
+ PReadDataByteBuffer pReadDataBuffer,
+ LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+
+{
+ return pFT2232cMpsseJtag->JTAG_ReadDataFromExternalDevice(
+ ftHandle,
+ bInstructionTestData,
+ dwNumBitsToRead,
+ pReadDataBuffer,
+ lpdwNumBytesReturned,
+ dwTapControllerState);
+
+}
+
+
+
+
+
+
+// Write Read
+FTC_STATUS
+FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(
+ //FTC_HANDLE ftHandle,
+ BOOL bInstructionTestData,
+ DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer,
+ DWORD dwNumBytesToWrite,
+ PReadDataByteBuffer pReadDataBuffer,
+ LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+{
+
+ return pFT2232cMpsseJtag->JTAG_WriteReadDataToFromExternalDevice(
+ ftHandle,
+ bInstructionTestData,
+ dwNumBitsToWriteRead,
+ pWriteDataBuffer,
+ dwNumBytesToWrite,
+ pReadDataBuffer,
+ lpdwNumBytesReturned,
+ dwTapControllerState);
+
+}
+
+
+
+// Close device
+FTC_STATUS
+FT2232_USB_JTAG_CloseDevice()
+{
+ return pFT2232cMpsseJtag->JTAG_CloseDevice(ftHandle);
+}
+
+
+
+// Set clock frequency
+// Frequency = 12Mhz/((1+divisor)*2),
+// divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz
+#define USB_JTAG_CLK_DIVIDER 0
+
+int init_usb_jtag()
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDevices = 0;
+ //char szDeviceName[100];
+ //char szDeviceName[] = "Dual RS232 A"; // Original, unmodified FT2232 device name
+ // We now open the device by its name
+ char szDeviceName[] = "ORSoC OpenRISC debug cable A\0"; // ORSoC debug cable UART A name
+ DWORD dwLocationID = 0;
+ DWORD dwClockFrequencyHz = 0;
+ FTC_INPUT_OUTPUT_PINS LowInputOutputPinsData;
+ FTC_INPUT_OUTPUT_PINS HighInputOutputPinsData;
+ FTC_LOW_HIGH_PINS LowPinsInputData;
+ FTC_LOW_HIGH_PINS HighPinsInputData;
+
+ //char szDllVersion[10];
+
+ // Has been changed to hardcode load device named "ORSoC OpenRISC debug cable A"; - jb 090301
+
+ /*
+ //Status = JTAG_GetNumDevices(&dwNumDevices);
+ Status = pFT2232cMpsseJtag->JTAG_GetNumDevices(&dwNumDevices);
+ if (DEBUG_USB_DRVR_FUNCS)
+ {
+ if (Status == FTC_SUCCESS)
+ printf("JTAG_GetNumDevices detected %ld available FT2232x device(s) connected to the system.\n", dwNumDevices);
+ else
+ {
+ printf("GetNumDevices failed with status code 0x%lx\n", Status);
+ exit(-1);
+ }
+ }
+
+ if (dwNumDevices == 0)
+ {
+ printf("Error: USB Debugger device not detected\n");
+ exit(-1);
+ }
+
+ Status = pFT2232cMpsseJtag->JTAG_GetDllVersion(szDllVersion, 10);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG_GetDLLVersion returned Status: 0x%lx and version %s\n", Status, szDllVersion);
+
+ */
+ dwNumDevices = 1;
+
+ if (Status == FTC_SUCCESS)
+ {
+
+
+ if (dwNumDevices == 1)
+ {
+ /*
+ Status = pFT2232cMpsseJtag->JTAG_GetDeviceNameLocationID(0,szDeviceName,50, &dwLocationID);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ // In the Windows version it shows Dual RS323 A at: 0x321
+ printf("JTAG_GetDeviceNameLocID: %s at: 0x%lx\n", szDeviceName, dwLocationID);
+ */
+ dwLocationID = 0;
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = pFT2232cMpsseJtag->JTAG_OpenSpecifiedDevice(szDeviceName,dwLocationID, &ftHandle);
+ }
+ }
+ else
+ // When there's more than 1 device, will just open first device. Perhaps implement selection menu for
+ // users in event that there's more than 1, but for now just hard code this to open the same device
+ {
+ //if (dwNumDevices == 2)
+ //{
+ Status=pFT2232cMpsseJtag->JTAG_GetDeviceNameLocationID(1,szDeviceName,50,&dwLocationID);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = pFT2232cMpsseJtag->JTAG_OpenSpecifiedDevice(szDeviceName, dwLocationID, &ftHandle);
+ }
+ //}
+ }
+
+ // Try initialising and obtaining a handle to a specific device
+ if (Status == FTC_SUCCESS)
+ {
+ printf("Initialising USB JTAG interface\n");
+ Status = pFT2232cMpsseJtag->JTAG_InitDevice(ftHandle, 0);
+
+ // Set clock frequency
+ // Frequency = 12Mhz/((1+divisor)*2),
+ // divisor=1000 => Freq=5995Hz~=6kHz, divisor=500=>Freq=12kHz
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("Setting JTAG clock frequency. Divisor = %d, TCK ~= %dkHz.\n", USB_JTAG_CLK_DIVIDER, (12000000/((USB_JTAG_CLK_DIVIDER+1)*2))/1000);
+ if (Status == FTC_SUCCESS)
+ Status = pFT2232cMpsseJtag->JTAG_SetClock(ftHandle, USB_JTAG_CLK_DIVIDER, &dwClockFrequencyHz);
+
+ if (Status == FTC_SUCCESS){
+
+ Status = pFT2232cMpsseJtag->JTAG_GetClock(5, &dwClockFrequencyHz);
+ }
+
+ }
+
+ //if (Status == FTC_SUCCESS)
+ // Status = JTAG_SetLoopback(ftHandle, true);
+ if (Status == FTC_SUCCESS)
+ {
+ if (DEBUG_USB_DRVR_FUNCS) // Let LED blink
+ {
+ // true=output, false=input
+ LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4
+ LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5
+ LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7
+ LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4
+ LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5
+ LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7
+
+ HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0 Output
+ HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1 Output
+ HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2 Output
+ HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3 Output
+ HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3LowHighState = true; // ACBUS2 LED RXLEDA A1 OFF
+ HighInputOutputPinsData.bPin4LowHighState = false; // ACBUS3 LED TXLEDA A2 ON
+
+ Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle,
+ true,
+ &LowInputOutputPinsData,
+ true,
+ &HighInputOutputPinsData);
+
+ LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4
+ LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5
+ LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7
+ LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4
+ LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5
+ LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7
+
+ HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2
+ HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3
+ HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3LowHighState = false; // ACBUS2 LED RXLEDA A1 ON
+ HighInputOutputPinsData.bPin4LowHighState = true; // ACBUS3 LED TXLEDA A2 OFF
+
+ Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle,
+ true,
+ &LowInputOutputPinsData,
+ true,
+ &HighInputOutputPinsData);
+
+ LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 -
+ LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5
+ LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7
+ LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4
+ LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5
+ LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7
+
+ HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2
+ HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3
+ HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3LowHighState = true; // ACBUS2 LED RXLEDA A1 OFF
+ HighInputOutputPinsData.bPin4LowHighState = true; // ACBUS3 LED TXLEDA A2 OFF
+
+ Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle,
+ true,
+ &LowInputOutputPinsData,
+ true,
+ &HighInputOutputPinsData);
+
+ LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 -
+ LowInputOutputPinsData.bPin2InputOutputState = true; // ADBUS5
+ LowInputOutputPinsData.bPin3InputOutputState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4InputOutputState = true; // ADBUS7
+ LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4
+ LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5
+ LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7
+
+ HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2
+ HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3
+ HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3LowHighState = false; // ACBUS2 LED RXLEDA A1 ON
+ HighInputOutputPinsData.bPin4LowHighState = false; // ACBUS3 LED TXLEDA A2 ON
+
+ Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle,
+ true,
+ &LowInputOutputPinsData,
+ true,
+ &HighInputOutputPinsData);
+ }
+
+ // Setup GPIO pins for JTAG
+ LowInputOutputPinsData.bPin1InputOutputState = true; // ADBUS4 -
+ // set ADBUS4 to output 0 to enable JTAG buffers on Olimex devices
+ LowInputOutputPinsData.bPin2InputOutputState = true; //ADBUS5
+ LowInputOutputPinsData.bPin3InputOutputState = true;
+ LowInputOutputPinsData.bPin4InputOutputState = true;
+ //ADBUS4 = 0 (enable JTAG buffers on Olimex devices)
+ LowInputOutputPinsData.bPin1LowHighState = false; // ADBUS4
+ LowInputOutputPinsData.bPin2LowHighState = false; // ADBUS5
+ LowInputOutputPinsData.bPin3LowHighState = true; // ADBUS6
+ LowInputOutputPinsData.bPin4LowHighState = true; // ADBUS7
+
+ HighInputOutputPinsData.bPin1InputOutputState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2InputOutputState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3InputOutputState = true; // ACBUS2
+ HighInputOutputPinsData.bPin4InputOutputState = true; // ACBUS3
+ HighInputOutputPinsData.bPin1LowHighState = true; // ACBUS0
+ HighInputOutputPinsData.bPin2LowHighState = true; // ACBUS1
+ HighInputOutputPinsData.bPin3LowHighState = false; // ACBUS2 LED RXLEDA A1 ON
+ HighInputOutputPinsData.bPin4LowHighState = true; // ACBUS3
+
+ Status = pFT2232cMpsseJtag->JTAG_SetGeneralPurposeInputOutputPins(ftHandle,
+ true,
+ &LowInputOutputPinsData,
+ true,
+ &HighInputOutputPinsData);
+
+ if (Status == FTC_SUCCESS)
+ Status = pFT2232cMpsseJtag->JTAG_GetGeneralPurposeInputOutputPins(ftHandle, true, &LowPinsInputData,
+ true, &HighPinsInputData);
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG low gpio pins values: (ADBUS7-ADBUS4):%x%x%x%x\n",
+ (LowPinsInputData.bPin4LowHighState==true),
+ (LowPinsInputData.bPin3LowHighState==true),
+ (LowPinsInputData.bPin2LowHighState==true),
+ (LowPinsInputData.bPin1LowHighState==true));
+
+ if (DEBUG_USB_DRVR_FUNCS)
+ printf("JTAG high gpio pins values: (ACBUS3-ACBUS0): %x%x%x%x\n",
+ (HighPinsInputData.bPin4LowHighState==true),
+ (HighPinsInputData.bPin3LowHighState==true),
+ (HighPinsInputData.bPin2LowHighState==true),
+ (HighPinsInputData.bPin1LowHighState==true));
+ }
+ }
+
+
+ if (Status == FTC_SUCCESS)
+ return 0;
+ else
+ return 1;
+
+}
Index: or_debug_proxy/src/FT2232cMpsseJtag.cpp
===================================================================
--- or_debug_proxy/src/FT2232cMpsseJtag.cpp (nonexistent)
+++ or_debug_proxy/src/FT2232cMpsseJtag.cpp (revision 1779)
@@ -0,0 +1,2017 @@
+/*++
+
+FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009
+
+
+The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability.
+
+This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact.
+
+Copyright (c) 2005 Future Technology Devices International Ltd.
+
+Module Name:
+
+ FT2232cMpsseJtag.cpp
+
+Abstract:
+
+ FT2232C Dual Device Device Class Implementation.
+
+Environment:
+
+ kernel & user mode
+
+Revision History:
+
+ 07/02/05 kra Created.
+ 24/08/05 kra Added new function JTAG_GenerateClockPulses and new error code FTC_INVALID_NUMBER_CLOCK_PULSES
+
+--*/
+
+#define WIO_DEFINED
+
+#include
+#include
+//#include // -- Possibly not needed, trying without -jb
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// included for sched_yield() calls,
+// used in place of Windows' Sleep(0) calls,
+// however may not be good idea, not sure it's
+// exactly the same thing!! -- Julius
+#include
+
+
+#include "FT2232cMpsseJtag.h"
+
+
+FTC_STATUS FT2232cMpsseJtag::CheckWriteDataToExternalDeviceBitsBytesParameters(DWORD dwNumBitsToWrite, DWORD dwNumBytesToWrite)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumBytesForNumBits = 0;
+
+ if (((dwNumBitsToWrite >= MIN_NUM_BITS) && (dwNumBitsToWrite <= MAX_NUM_BITS)) &&
+ ((dwNumBytesToWrite >= MIN_NUM_BYTES) && (dwNumBytesToWrite <= MAX_NUM_BYTES)))
+ {
+ dwNumBytesForNumBits = (dwNumBitsToWrite / NUMBITSINBYTE);
+
+ if ((dwNumBitsToWrite % NUMBITSINBYTE) > 0)
+ dwNumBytesForNumBits = dwNumBytesForNumBits + 1;
+
+ if (dwNumBytesForNumBits > dwNumBytesToWrite)
+ Status = FTC_NUMBER_BYTES_TOO_SMALL;
+ }
+ else
+ {
+ if ((dwNumBitsToWrite < MIN_NUM_BITS) || (dwNumBitsToWrite > MAX_NUM_BITS))
+ Status = FTC_INVALID_NUMBER_BITS;
+ else
+ Status = FTC_INVALID_NUMBER_BYTES;
+ }
+
+ return Status;
+}
+
+void FT2232cMpsseJtag::AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer)
+{
+ DWORD dwNumBytesToSend_temp = 0;
+
+ if (iCommandsSequenceDataDeviceIndex == -1)
+ FTC_AddByteToOutputBuffer(dwOutputByte, bClearOutputBuffer);
+ else
+ {
+ // This is used when you are building up a sequence of commands ie write, read and write/read
+ dwNumBytesToSend_temp = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend;
+
+ (*OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pCommandsSequenceDataOutPutBuffer)[dwNumBytesToSend_temp] = (dwOutputByte & '\xFF');
+
+ dwNumBytesToSend_temp = dwNumBytesToSend_temp + 1;
+
+ OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend = dwNumBytesToSend_temp;
+ }
+}
+
+FTC_STATUS FT2232cMpsseJtag::SetDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ AddByteToOutputBuffer(SET_CLOCK_FREQUENCY_CMD, true);
+ AddByteToOutputBuffer(dwClockDivisor, false);
+ AddByteToOutputBuffer((dwClockDivisor >> 8), false);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::InitDataInOutClockFrequency(FTC_HANDLE ftHandle, DWORD dwClockDivisor)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ // set general purpose I/O low pins 1-4 all to input except TDO
+ AddByteToOutputBuffer(SET_LOW_BYTE_DATA_BITS_CMD, true);
+
+ dwSavedLowPinsValue = (dwSavedLowPinsValue & '\xF0');
+ dwSavedLowPinsValue = (dwSavedLowPinsValue | '\x08'); // TDI,TCK start low
+ AddByteToOutputBuffer(dwSavedLowPinsValue, false);
+
+ dwSavedLowPinsDirection = (dwSavedLowPinsDirection & '\xF0');
+ dwSavedLowPinsDirection = (dwSavedLowPinsDirection | '\x0B');
+ AddByteToOutputBuffer(dwSavedLowPinsDirection, false);
+
+ // set general purpose I/O high pins 1-4 all to input
+ AddByteToOutputBuffer(SET_HIGH_BYTE_DATA_BITS_CMD, false);
+ AddByteToOutputBuffer(0, false);
+ AddByteToOutputBuffer(0, false);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ SetDataInOutClockFrequency(ftHandle, dwClockDivisor);
+
+ return Status;
+}
+
+// This procedure sets the JTAG to a new state
+void FT2232cMpsseJtag::SetJTAGToNewState(DWORD dwNewJtagState, DWORD dwNumTmsClocks, BOOL bDoReadOperation)
+{
+ if ((dwNumTmsClocks >= 1) && (dwNumTmsClocks <= 7))
+ {
+ if (bDoReadOperation == TRUE)
+ AddByteToOutputBuffer(CLK_DATA_TMS_READ_CMD, false);
+ else
+ AddByteToOutputBuffer(CLK_DATA_TMS_NO_READ_CMD, false);
+
+ AddByteToOutputBuffer(((dwNumTmsClocks - 1) & '\xFF'), false);
+ AddByteToOutputBuffer((dwNewJtagState & '\xFF'), false);
+ }
+}
+
+// This function returns the number of TMS clocks to work out the last bit of TDO
+DWORD FT2232cMpsseJtag::MoveJTAGFromOneStateToAnother(JtagStates NewJtagState, DWORD dwLastDataBit, BOOL bDoReadOperation)
+{
+ DWORD dwNumTmsClocks = 0;
+
+ if (CurrentJtagState == Undefined)
+ {
+ SetJTAGToNewState('\x7F', 7, false);
+ CurrentJtagState = TestLogicReset;
+ }
+
+ switch (CurrentJtagState)
+ {
+ case TestLogicReset:
+ dwNumTmsClocks = TestLogicResetToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((TestLogicResetToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ case RunTestIdle:
+ dwNumTmsClocks = RunTestIdleToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((RunTestIdleToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ case PauseDataRegister:
+ dwNumTmsClocks = PauseDataRegToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((PauseDataRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ case PauseInstructionRegister:
+ dwNumTmsClocks = PauseInstructionRegToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((PauseInstructionRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ case ShiftDataRegister:
+ dwNumTmsClocks = ShiftDataRegToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((ShiftDataRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ case ShiftInstructionRegister:
+ dwNumTmsClocks = ShiftInstructionRegToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((ShiftInstructionRegToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ default :
+ // Added default state -- Julius
+ dwNumTmsClocks = TestLogicResetToNewJTAGStateNumTMSClocks[NewJtagState];
+ SetJTAGToNewState((TestLogicResetToNewJTAGState[NewJtagState] | (dwLastDataBit << 7)), dwNumTmsClocks, bDoReadOperation);
+ break;
+ }
+
+ CurrentJtagState = NewJtagState;
+
+ return dwNumTmsClocks;
+}
+
+FTC_STATUS FT2232cMpsseJtag::ResetTAPContollerExternalDeviceSetToTestIdleMode(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ // set I/O low bits all out except TDO
+ AddByteToOutputBuffer(SET_LOW_BYTE_DATA_BITS_CMD, true);
+
+ dwSavedLowPinsValue = (dwSavedLowPinsValue & '\xFF');
+ // TDI,TCK start low
+ dwSavedLowPinsValue = (dwSavedLowPinsValue | '\x08');
+ AddByteToOutputBuffer(dwSavedLowPinsValue, false);
+
+ dwSavedLowPinsDirection = (dwSavedLowPinsDirection & '\xFF');
+ dwSavedLowPinsDirection = (dwSavedLowPinsDirection | '\x0B');
+ AddByteToOutputBuffer(dwSavedLowPinsDirection, false);
+
+ //MoveJTAGFromOneStateToAnother(TestLogicReset, 1, false);JtagStates
+ MoveJTAGFromOneStateToAnother(Undefined, 1, false);
+
+ MoveJTAGFromOneStateToAnother(RunTestIdle, NO_LAST_DATA_BIT, FALSE);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
+ DWORD dwLowPinsDirection, DWORD dwLowPinsValue,
+ BOOL bControlHighInputOutputPins,
+ DWORD dwHighPinsDirection, DWORD dwHighPinsValue)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ if (bControlLowInputOutputPins != false)
+ {
+ // output on the general purpose I/O low pins 1-4
+ AddByteToOutputBuffer(SET_LOW_BYTE_DATA_BITS_CMD, true);
+
+ // shift left by 4 bits ie move general purpose I/O low pins 1-4 from bits 0-3 to bits 4-7
+ dwLowPinsValue = ((dwLowPinsValue & '\x0F') << 4);
+
+ dwSavedLowPinsValue = (dwSavedLowPinsValue & '\x0F');
+ dwSavedLowPinsValue = (dwSavedLowPinsValue | dwLowPinsValue);
+ AddByteToOutputBuffer(dwSavedLowPinsValue, false);
+
+ // shift left by 4 bits ie move general purpose I/O low pins 1-4 from bits 0-3 to bits 4-7
+ dwLowPinsDirection = ((dwLowPinsDirection & '\x0F') << 4);
+
+ dwSavedLowPinsDirection = (dwSavedLowPinsDirection & '\x0F');
+ dwSavedLowPinsDirection = (dwSavedLowPinsDirection | dwLowPinsDirection);
+ AddByteToOutputBuffer(dwSavedLowPinsDirection, false);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+ }
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (bControlHighInputOutputPins != false)
+ {
+ // output on the general purpose I/O high pins 1-4
+ AddByteToOutputBuffer(SET_HIGH_BYTE_DATA_BITS_CMD, true);
+
+ dwHighPinsValue = (dwHighPinsValue & '\x0F');
+ AddByteToOutputBuffer(dwHighPinsValue, false);
+
+ dwHighPinsDirection = (dwHighPinsDirection & '\x0F');
+ AddByteToOutputBuffer(dwHighPinsDirection, false);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+ }
+ }
+
+ return Status;
+}
+
+void FT2232cMpsseJtag::GetGeneralPurposeInputOutputPinsInputStates(DWORD dwInputStatesReturnedValue, PFTC_LOW_HIGH_PINS pPinsInputData)
+{
+ if ((dwInputStatesReturnedValue & PIN1_HIGH_VALUE) == PIN1_HIGH_VALUE)
+ pPinsInputData->bPin1LowHighState = TRUE;
+
+ if ((dwInputStatesReturnedValue & PIN2_HIGH_VALUE) == PIN2_HIGH_VALUE)
+ pPinsInputData->bPin2LowHighState = TRUE;
+
+ if ((dwInputStatesReturnedValue & PIN3_HIGH_VALUE) == PIN3_HIGH_VALUE)
+ pPinsInputData->bPin3LowHighState = TRUE;
+
+ if ((dwInputStatesReturnedValue & PIN4_HIGH_VALUE) == PIN4_HIGH_VALUE)
+ pPinsInputData->bPin4LowHighState = TRUE;
+}
+
+FTC_STATUS FT2232cMpsseJtag::GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
+ PFTC_LOW_HIGH_PINS pLowPinsInputData,
+ BOOL bControlHighInputOutputPins,
+ PFTC_LOW_HIGH_PINS pHighPinsInputData)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ InputByteBuffer InputBuffer;
+ DWORD dwNumBytesRead = 0;
+ DWORD dwNumBytesDeviceInputBuffer;
+
+ pLowPinsInputData->bPin1LowHighState = false;
+ pLowPinsInputData->bPin2LowHighState = false;
+ pLowPinsInputData->bPin3LowHighState = false;
+ pLowPinsInputData->bPin4LowHighState = false;
+ pHighPinsInputData->bPin1LowHighState = false;
+ pHighPinsInputData->bPin2LowHighState = false;
+ pHighPinsInputData->bPin3LowHighState = false;
+ pHighPinsInputData->bPin4LowHighState = false;
+
+ // Put in this small delay incase the application programmer does a get GPIOs immediately after a set GPIOs
+ //Sleep(5);
+ // Removed Sleep() call and replaced with linux sleep to give up
+ // timeslice - sched_yield() -- not sure is best idea! -- Julius
+ sched_yield();
+
+ if (bControlLowInputOutputPins != false)
+ {
+ // Get the number of bytes in the device input buffer
+ Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumBytesDeviceInputBuffer > 0)
+ Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ // get the states of the general purpose I/O low pins 1-4
+ AddByteToOutputBuffer(GET_LOW_BYTE_DATA_BITS_CMD, true);
+ AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false);
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_GetNumberBytesFromDeviceInputBuffer(ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ // shift right by 4 bits ie move general purpose I/O low pins 1-4 from bits 4-7 to bits 0-3
+ GetGeneralPurposeInputOutputPinsInputStates((InputBuffer[0] >> 4), pLowPinsInputData);
+ }
+ }
+ }
+ }
+ }
+
+ if (bControlHighInputOutputPins != false)
+ {
+ // Get the number of bytes in the device input buffer
+ Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumBytesDeviceInputBuffer > 0)
+ Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ // get the states of the general purpose I/O high pins 1-4
+ AddByteToOutputBuffer(GET_HIGH_BYTE_DATA_BITS_CMD, true);
+ AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false);
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_GetNumberBytesFromDeviceInputBuffer(ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ GetGeneralPurposeInputOutputPinsInputStates(InputBuffer[0], pHighPinsInputData);
+ }
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
+void FT2232cMpsseJtag::AddWriteCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ DWORD dwModNumBitsToWrite = 0;
+ DWORD dwDataBufferIndex = 0;
+ DWORD dwNumDataBytes = 0;
+ DWORD dwNumRemainingDataBits = 0;
+ DWORD dwLastDataBit = 0;
+ DWORD dwDataBitIndex = 0;
+
+ // adjust for bit count of 1 less than no of bits
+ dwModNumBitsToWrite = (dwNumBitsToWrite - 1);
+
+ if (bInstructionTestData == false)
+ MoveJTAGFromOneStateToAnother(ShiftDataRegister, NO_LAST_DATA_BIT, false);
+ else
+ MoveJTAGFromOneStateToAnother(ShiftInstructionRegister, NO_LAST_DATA_BIT, false);
+
+ dwNumDataBytes = (dwModNumBitsToWrite / 8);
+
+ if (dwNumDataBytes > 0)
+ {
+ // Number of whole bytes
+ dwNumDataBytes = (dwNumDataBytes - 1);
+
+ // clk data bytes out on -ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumDataBytes & '\xFF'), false);
+ AddByteToOutputBuffer(((dwNumDataBytes / 256) & '\xFF'), false);
+
+ // now add the data bytes to go out
+ do
+ {
+ AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false);
+ dwDataBufferIndex = (dwDataBufferIndex + 1);
+ }
+ while (dwDataBufferIndex < (dwNumDataBytes + 1));
+ }
+
+ dwNumRemainingDataBits = (dwModNumBitsToWrite % 8);
+
+ if (dwNumRemainingDataBits > 0)
+ {
+ dwNumRemainingDataBits = (dwNumRemainingDataBits - 1);
+
+ //clk data bits out on -ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumRemainingDataBits & '\xFF'), false);
+ AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false);
+ }
+
+ // get last bit
+ dwLastDataBit = (*pWriteDataBuffer)[dwDataBufferIndex];
+ dwDataBitIndex = (dwNumBitsToWrite % 8);
+
+ if (dwDataBitIndex == 0)
+ dwLastDataBit = (dwLastDataBit >> ((8 - dwDataBitIndex) - 1));
+ else
+ dwLastDataBit = (dwLastDataBit >> (dwDataBitIndex - 1));
+
+ // end it in state passed in, take 1 off the dwTapControllerState variable to correspond with JtagStates enumerated types
+ MoveJTAGFromOneStateToAnother(JtagStates((dwTapControllerState - 1)), dwLastDataBit, false);
+}
+
+FTC_STATUS FT2232cMpsseJtag::WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ FTC_ClearOutputBuffer();
+
+ AddWriteCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer,
+ dwNumBytesToWrite, dwTapControllerState);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ return Status;
+}
+
+void FT2232cMpsseJtag::GetNumDataBytesToRead(DWORD dwNumBitsToRead, LPDWORD lpdwNumDataBytesToRead, LPDWORD lpdwNumRemainingDataBits)
+{
+ DWORD dwModNumBitsToRead = 0;
+ DWORD dwNumDataBytesToRead = 0;
+ DWORD dwNumRemainingDataBits = 0;
+
+ // adjust for bit count of 1 less than no of bits
+ dwModNumBitsToRead = (dwNumBitsToRead - 1);
+
+ // Number of whole bytes to read
+ dwNumDataBytesToRead = (dwModNumBitsToRead / 8);
+
+ // number of remaining bits
+ dwNumRemainingDataBits = (dwModNumBitsToRead % 8);
+
+ // increase the number of whole bytes if bits left over
+ if (dwNumRemainingDataBits > 0)
+ dwNumDataBytesToRead = (dwNumDataBytesToRead + 1);
+
+ // adjust for SHR of incoming byte
+ dwNumRemainingDataBits = (8 - dwNumRemainingDataBits);
+
+ // add 1 for TMS read byte
+ dwNumDataBytesToRead = (dwNumDataBytesToRead + 1);
+
+ *lpdwNumDataBytesToRead = dwNumDataBytesToRead;
+ *lpdwNumRemainingDataBits = dwNumRemainingDataBits;
+}
+
+// This will work out the number of whole bytes to read and adjust for the TMS read
+FTC_STATUS FT2232cMpsseJtag::GetDataFromExternalDevice(FTC_HANDLE ftHandle, DWORD dwNumBitsToRead, DWORD dwNumTmsClocks,
+ PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumReadDataBytes = 0;
+ DWORD dwNumRemainingDataBits = 0;
+ DWORD dwNumDataBytesRead = 0;
+ // DWORD dwNumBytesDeviceInputBuffer = 0;
+ InputByteBuffer InputBuffer;
+ DWORD dwBytesReadIndex = 0;
+ BYTE LastDataBit = 0;
+
+ GetNumDataBytesToRead(dwNumBitsToRead, &dwNumReadDataBytes, &dwNumRemainingDataBits);
+
+ Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, &InputBuffer, dwNumReadDataBytes, &dwNumDataBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ // adjust last 2 bytes
+ if (dwNumRemainingDataBits < 8)
+ {
+ InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] >> dwNumRemainingDataBits);
+ LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1));
+ LastDataBit = (LastDataBit & '\x80'); // strip the rest
+ InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] | (LastDataBit >> (dwNumRemainingDataBits - 1)));
+
+ dwNumReadDataBytes = (dwNumReadDataBytes - 1);
+
+ for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++)
+ (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex];
+ }
+ else // case for 0 bit shift in data + TMS read bit
+ {
+ LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1));
+ LastDataBit = (LastDataBit >> 7); // strip the rest
+ InputBuffer[dwNumReadDataBytes - 1] = LastDataBit;
+
+ for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++)
+ (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex];
+ }
+
+ *lpdwNumBytesReturned = dwNumReadDataBytes;
+ }
+
+ return Status;
+}
+
+DWORD FT2232cMpsseJtag::AddReadCommandToOutputBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState)
+{
+ DWORD dwModNumBitsToRead = 0;
+ DWORD dwNumDataBytes = 0;
+ DWORD dwNumRemainingDataBits = 0;
+ DWORD dwNumTmsClocks = 0;
+
+ // adjust for bit count of 1 less than no of bits
+ dwModNumBitsToRead = (dwNumBitsToRead - 1);
+
+ if (bInstructionTestData == false)
+ MoveJTAGFromOneStateToAnother(ShiftDataRegister, NO_LAST_DATA_BIT, false);
+ else
+ MoveJTAGFromOneStateToAnother(ShiftInstructionRegister, NO_LAST_DATA_BIT, false);
+
+ dwNumDataBytes = (dwModNumBitsToRead / 8);
+
+ if (dwNumDataBytes > 0)
+ {
+ // Number of whole bytes
+ dwNumDataBytes = (dwNumDataBytes - 1);
+
+ // clk data bytes out on -ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BYTES_IN_ON_POS_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumDataBytes & '\xFF'), false);
+ AddByteToOutputBuffer(((dwNumDataBytes / 256) & '\xFF'), false);
+ }
+
+ // number of remaining bits
+ dwNumRemainingDataBits = (dwModNumBitsToRead % 8);
+
+ if (dwNumRemainingDataBits > 0)
+ {
+ dwNumRemainingDataBits = (dwNumRemainingDataBits - 1);
+
+ //clk data bits out on -ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BITS_IN_ON_POS_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumRemainingDataBits & '\xFF'), false);
+ }
+
+ // end it in state passed in, take 1 off the dwTapControllerState variable to correspond with JtagStates enumerated types
+ dwNumTmsClocks = MoveJTAGFromOneStateToAnother(JtagStates((dwTapControllerState - 1)), NO_LAST_DATA_BIT, true);
+
+ return dwNumTmsClocks;
+}
+
+FTC_STATUS FT2232cMpsseJtag::ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
+ PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumTmsClocks = 0;
+
+ FTC_ClearOutputBuffer();
+
+ dwNumTmsClocks = AddReadCommandToOutputBuffer(bInstructionTestData, dwNumBitsToRead, dwTapControllerState);
+
+ AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = GetDataFromExternalDevice(ftHandle, dwNumBitsToRead, dwNumTmsClocks, pReadDataBuffer, lpdwNumBytesReturned);
+
+ return Status;
+}
+
+DWORD FT2232cMpsseJtag::AddWriteReadCommandDataToOutPutBuffer(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer,
+ DWORD dwNumBytesToWrite, DWORD dwTapControllerState)
+{
+ DWORD dwModNumBitsToWriteRead = 0;
+ DWORD dwNumWriteDataBytes = 0;
+ DWORD dwDataBufferIndex = 0;
+ DWORD dwNumRemainingDataBits = 0;
+ DWORD dwLastDataBit = 0;
+ DWORD dwDataBitIndex = 0;
+ DWORD dwNumTmsClocks = 0;
+
+ // adjust for bit count of 1 less than no of bits
+ dwModNumBitsToWriteRead = (dwNumBitsToWriteRead - 1);
+
+ if (bInstructionTestData == false)
+ MoveJTAGFromOneStateToAnother(ShiftDataRegister, NO_LAST_DATA_BIT, false);
+ else
+ MoveJTAGFromOneStateToAnother(ShiftInstructionRegister, NO_LAST_DATA_BIT, false);
+
+ dwNumWriteDataBytes = (dwModNumBitsToWriteRead / 8);
+
+ if (dwNumWriteDataBytes > 0)
+ {
+ // Number of whole bytes
+ dwNumWriteDataBytes = (dwNumWriteDataBytes - 1);
+
+ // clk data bytes out on -ve in +ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BYTES_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumWriteDataBytes & '\xFF'), false);
+ AddByteToOutputBuffer(((dwNumWriteDataBytes / 256) & '\xFF'), false);
+
+ // now add the data bytes to go out
+ do
+ {
+ AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false);
+ dwDataBufferIndex = (dwDataBufferIndex + 1);
+ }
+ while (dwDataBufferIndex < (dwNumWriteDataBytes + 1));
+ }
+
+ dwNumRemainingDataBits = (dwModNumBitsToWriteRead % 8);
+
+ if (dwNumRemainingDataBits > 0)
+ {
+ dwNumRemainingDataBits = (dwNumRemainingDataBits - 1);
+
+ // clk data bits out on -ve in +ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BITS_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumRemainingDataBits & '\xFF'), false);
+ AddByteToOutputBuffer((*pWriteDataBuffer)[dwDataBufferIndex], false);
+ }
+
+ // get last bit
+ dwLastDataBit = (*pWriteDataBuffer)[dwDataBufferIndex];
+ dwDataBitIndex = (dwNumBitsToWriteRead % 8);
+
+ if (dwDataBitIndex == 8)
+ dwLastDataBit = (dwLastDataBit >> ((8 - dwDataBitIndex) - 1));
+ else
+ dwLastDataBit = (dwLastDataBit >> (dwDataBitIndex - 1));
+
+ // end it in state passed in, take 1 off the dwTapControllerState variable to correspond with JtagStates enumerated types
+ dwNumTmsClocks = MoveJTAGFromOneStateToAnother(JtagStates((dwTapControllerState - 1)), dwLastDataBit, true);
+
+ return dwNumTmsClocks;
+}
+
+FTC_STATUS FT2232cMpsseJtag::WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumRemainingDataBits = 0;
+ BYTE LastDataBit = 0;
+ DWORD dwNumTmsClocks = 0;
+ DWORD dwNumReadDataBytes = 0;
+ InputByteBuffer InputBuffer;
+ DWORD dwNumDataBytesRead = 0;
+ DWORD dwBytesReadIndex = 0;
+
+ FTC_ClearOutputBuffer();
+
+ dwNumTmsClocks = AddWriteReadCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWriteRead,
+ pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState);
+
+ AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false);
+
+ GetNumDataBytesToRead(dwNumBitsToWriteRead, &dwNumReadDataBytes, &dwNumRemainingDataBits);
+
+ Status = FTC_SendReadBytesToFromDevice(ftHandle, &InputBuffer, dwNumReadDataBytes, &dwNumDataBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ // adjust last 2 bytes
+ if (dwNumRemainingDataBits < 8)
+ {
+ InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] >> dwNumRemainingDataBits);
+ LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1));
+ LastDataBit = (LastDataBit & '\x80'); // strip the rest
+ InputBuffer[dwNumReadDataBytes - 2] = (InputBuffer[dwNumReadDataBytes - 2] | (LastDataBit >> (dwNumRemainingDataBits - 1)));
+
+ dwNumReadDataBytes = (dwNumReadDataBytes - 1);
+
+ for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++)
+ (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex];
+ }
+ else // case for 0 bit shift in data + TMS read bit
+ {
+ LastDataBit = (InputBuffer[dwNumReadDataBytes - 1] << (dwNumTmsClocks - 1));
+ LastDataBit = (LastDataBit >> 7); // strip the rest
+ InputBuffer[dwNumReadDataBytes - 1] = LastDataBit;
+
+ for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++)
+ (*pReadDataBuffer)[dwBytesReadIndex] = InputBuffer[dwBytesReadIndex];
+ }
+
+ *lpdwNumBytesReturned = dwNumReadDataBytes;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwTotalNumClockPulsesBytes = 0;
+ DWORD dwNumClockPulsesByteBlocks = 0;
+ DWORD dwNumClockPulsesByteBlockCntr = 0;
+ DWORD dwNumClockPulsesBytes = 0;
+ DWORD dwNumRemainingClockPulsesBits = 0;
+ // DWORD dwDataBufferIndex = 0;
+
+ MoveJTAGFromOneStateToAnother(RunTestIdle, NO_LAST_DATA_BIT, FALSE);
+
+ dwTotalNumClockPulsesBytes = (dwNumClockPulses / NUMBITSINBYTE);
+
+ if (dwTotalNumClockPulsesBytes > 0)
+ {
+ dwNumClockPulsesByteBlocks = (dwTotalNumClockPulsesBytes / NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE);
+
+ do
+ {
+ if (dwNumClockPulsesByteBlockCntr < dwNumClockPulsesByteBlocks)
+ dwNumClockPulsesBytes = NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE;
+ else
+ dwNumClockPulsesBytes = (dwTotalNumClockPulsesBytes - (dwNumClockPulsesByteBlockCntr * NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE));
+
+ if (dwNumClockPulsesBytes > 0)
+ {
+ // Number of whole bytes
+ dwNumClockPulsesBytes = (dwNumClockPulsesBytes - 1);
+
+ // clk data bytes out on -ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumClockPulsesBytes & '\xFF'), false);
+ AddByteToOutputBuffer(((dwNumClockPulsesBytes / 256) & '\xFF'), false);
+
+ DWORD dwDataBufferIndex = 0;
+
+ // now add the data bytes ie 0 to go out with the clock pulses
+ do
+ {
+ AddByteToOutputBuffer(0, false);
+ dwDataBufferIndex = (dwDataBufferIndex + 1);
+ }
+ while (dwDataBufferIndex < (dwNumClockPulsesBytes + 1));
+ }
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+
+ dwNumClockPulsesByteBlockCntr = (dwNumClockPulsesByteBlockCntr + 1);
+ }
+ while ((dwNumClockPulsesByteBlockCntr <= dwNumClockPulsesByteBlocks) && (Status == FTC_SUCCESS));
+ }
+
+ if (Status == FTC_SUCCESS)
+ {
+ dwNumRemainingClockPulsesBits = (dwNumClockPulses % NUMBITSINBYTE);
+
+ if (dwNumRemainingClockPulsesBits > 0)
+ {
+ dwNumRemainingClockPulsesBits = (dwNumRemainingClockPulsesBits - 1);
+
+ //clk data bits out on -ve clk LSB
+ AddByteToOutputBuffer(CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD, false);
+ AddByteToOutputBuffer((dwNumRemainingClockPulsesBits & '\xFF'), false);
+ AddByteToOutputBuffer('\xFF', false);
+
+ Status = FTC_SendBytesToDevice(ftHandle);
+ }
+ }
+
+ //MoveJTAGFromOneStateToAnother(RunTestIdle, NO_LAST_DATA_BIT, FALSE);
+
+ //Status = FTC_SendBytesToDevice(ftHandle);
+
+ return Status;
+}
+
+void FT2232cMpsseJtag::ProcessReadCommandsSequenceBytes(PInputByteBuffer pInputBuffer, DWORD dwNumBytesRead, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
+ LPDWORD lpdwNumBytesReturned)
+{
+ DWORD CommandSequenceIndex = 0;
+ PReadCommandsSequenceData pReadCommandsSequenceDataBuffer;
+ DWORD dwNumReadCommandSequences;
+ PReadCommandSequenceData pReadCmdSequenceData;
+ DWORD dwNumBitsToRead = 0;
+ DWORD dwNumTmsClocks = 0;
+ DWORD dwNumReadDataBytes = 0;
+ DWORD dwNumRemainingDataBits = 0;
+ BYTE LastDataBit = 0;
+ DWORD dwBytesReadIndex = 0;
+ DWORD dwNumReadBytesProcessed = 0;
+ DWORD dwTotalNumBytesRead = 0;
+ DWORD dwNumBytesReturned = 0;
+
+ if (iCommandsSequenceDataDeviceIndex != -1)
+ {
+ pReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer;
+ dwNumReadCommandSequences = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences;
+
+ for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwNumReadCommandSequences); CommandSequenceIndex++)
+ {
+ pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[CommandSequenceIndex];
+ dwNumBitsToRead = (*pReadCmdSequenceData)[0];
+ dwNumTmsClocks = (*pReadCmdSequenceData)[1];
+
+ GetNumDataBytesToRead(dwNumBitsToRead, &dwNumReadDataBytes, &dwNumRemainingDataBits);
+
+ dwNumReadBytesProcessed = (dwNumReadBytesProcessed + dwNumReadDataBytes);
+
+ // adjust last 2 bytes
+ if (dwNumRemainingDataBits < 8)
+ {
+ (*pInputBuffer)[dwNumReadBytesProcessed - 2] = ((*pInputBuffer)[dwNumReadBytesProcessed - 2] >> dwNumRemainingDataBits);
+ LastDataBit = ((*pInputBuffer)[dwNumReadBytesProcessed - 1] << (dwNumTmsClocks - 1));
+ LastDataBit = (LastDataBit & '\x80'); // strip the rest
+ (*pInputBuffer)[dwNumReadBytesProcessed - 2] = ((*pInputBuffer)[dwNumReadBytesProcessed - 2] | (LastDataBit >> (dwNumRemainingDataBits - 1)));
+
+ dwNumReadDataBytes = (dwNumReadDataBytes - 1);
+
+ for (dwBytesReadIndex = 0; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++)
+ (*pReadCmdSequenceDataBuffer)[(dwBytesReadIndex + dwNumBytesReturned)] = (*pInputBuffer)[(dwBytesReadIndex + dwTotalNumBytesRead)];
+ }
+ else // case for 0 bit shift in data + TMS read bit
+ {
+ LastDataBit = ((*pInputBuffer)[dwNumReadBytesProcessed - 1] << (dwNumTmsClocks - 1));
+ LastDataBit = (LastDataBit >> 7); // strip the rest
+ (*pInputBuffer)[dwNumReadBytesProcessed - 1] = LastDataBit;
+
+ for (dwBytesReadIndex = 0; dwBytesReadIndex < dwNumReadDataBytes; dwBytesReadIndex++)
+ (*pReadCmdSequenceDataBuffer)[(dwBytesReadIndex + dwNumBytesReturned)] = (*pInputBuffer)[(dwBytesReadIndex + dwTotalNumBytesRead)];
+ }
+
+ dwTotalNumBytesRead = dwNumReadBytesProcessed;
+
+ dwNumBytesReturned = (dwNumBytesReturned + dwNumReadDataBytes);
+ }
+ }
+
+ *lpdwNumBytesReturned = dwNumBytesReturned;
+}
+
+DWORD FT2232cMpsseJtag::GetTotalNumCommandsSequenceDataBytesToRead(void)
+{
+ DWORD dwTotalNumBytesToBeRead = 0;
+ DWORD CommandSequenceIndex = 0;
+ PReadCommandsSequenceData pReadCommandsSequenceDataBuffer;
+ DWORD dwNumReadCommandSequences = 0;
+ PReadCommandSequenceData pReadCmdSequenceData;
+ DWORD dwNumBitsToRead = 0;
+ DWORD dwNumDataBytesToRead = 0;
+ DWORD dwNumRemainingDataBits = 0;
+
+ if (iCommandsSequenceDataDeviceIndex != -1)
+ {
+ pReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer;
+ dwNumReadCommandSequences = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences;
+
+ for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwNumReadCommandSequences); CommandSequenceIndex++)
+ {
+ pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[CommandSequenceIndex];
+ dwNumBitsToRead = (*pReadCmdSequenceData)[0];
+
+ GetNumDataBytesToRead(dwNumBitsToRead, &dwNumDataBytesToRead, &dwNumRemainingDataBits);
+
+ dwTotalNumBytesToBeRead = (dwTotalNumBytesToBeRead + dwNumDataBytesToRead);
+ }
+ }
+
+ return dwTotalNumBytesToBeRead;
+}
+
+void FT2232cMpsseJtag::CopyReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pDestinationBuffer, PReadCommandsSequenceData pSourceBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer)
+{
+ DWORD CommandSequenceIndex = 0;
+ PReadCommandSequenceData pReadCmdSequenceData;
+ DWORD dwNumBitsToRead = 0;
+ DWORD dwNumTmsClocks = 0;
+
+ for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwSizeReadCommandsSequenceDataBuffer); CommandSequenceIndex++)
+ {
+ pReadCmdSequenceData = (*pSourceBuffer)[CommandSequenceIndex];
+ dwNumBitsToRead = (*pReadCmdSequenceData)[0];
+ dwNumTmsClocks = (*pReadCmdSequenceData)[1];
+
+ pReadCmdSequenceData = (*pDestinationBuffer)[CommandSequenceIndex];
+ (*pReadCmdSequenceData)[0] = dwNumBitsToRead;
+ (*pReadCmdSequenceData)[1] = dwNumTmsClocks;
+ }
+}
+
+FTC_STATUS FT2232cMpsseJtag::AddReadCommandSequenceData(DWORD dwNumBitsToRead, DWORD dwNumTmsClocks)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwSizeReadCommandsSequenceDataBuffer;
+ PReadCommandsSequenceData pReadCommandsSequenceDataBuffer;
+ DWORD dwNumReadCommandSequences;
+ PReadCommandsSequenceData pTmpReadCmdsSequenceDataBuffer;
+ PReadCommandSequenceData pReadCmdSequenceData;
+
+ if (iCommandsSequenceDataDeviceIndex != -1)
+ {
+ dwSizeReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwSizeReadCommandsSequenceDataBuffer;
+ pReadCommandsSequenceDataBuffer = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer;
+ dwNumReadCommandSequences = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences;
+
+ if (dwNumReadCommandSequences > (dwSizeReadCommandsSequenceDataBuffer - 1))
+ {
+ pTmpReadCmdsSequenceDataBuffer = CreateReadCommandsSequenceDataBuffer(dwSizeReadCommandsSequenceDataBuffer);
+
+ if (pTmpReadCmdsSequenceDataBuffer != NULL)
+ {
+ // Temporary save the contents of the read commands sequence data buffer
+ CopyReadCommandsSequenceDataBuffer(pTmpReadCmdsSequenceDataBuffer, pReadCommandsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer);
+
+ DeleteReadCommandsSequenceDataBuffer(pReadCommandsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer);
+
+ // Increase the size of the read commands sequence data buffer
+ pReadCommandsSequenceDataBuffer = CreateReadCommandsSequenceDataBuffer((dwSizeReadCommandsSequenceDataBuffer + COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT));
+
+ if (pReadCommandsSequenceDataBuffer != NULL)
+ {
+ CopyReadCommandsSequenceDataBuffer(pReadCommandsSequenceDataBuffer, pTmpReadCmdsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer);
+
+ DeleteReadCommandsSequenceDataBuffer(pTmpReadCmdsSequenceDataBuffer, dwSizeReadCommandsSequenceDataBuffer);
+
+ dwSizeReadCommandsSequenceDataBuffer = (dwSizeReadCommandsSequenceDataBuffer + COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT);
+
+ OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwSizeReadCommandsSequenceDataBuffer = dwSizeReadCommandsSequenceDataBuffer;
+ OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pReadCommandsSequenceDataBuffer = pReadCommandsSequenceDataBuffer;
+ }
+ else
+ Status = FTC_INSUFFICIENT_RESOURCES;
+ }
+ else
+ Status = FTC_INSUFFICIENT_RESOURCES;
+ }
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumReadCommandSequences > 0)
+ pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[(dwNumReadCommandSequences - 1)];
+
+ pReadCmdSequenceData = (*pReadCommandsSequenceDataBuffer)[dwNumReadCommandSequences];
+
+ (*pReadCmdSequenceData)[0] = dwNumBitsToRead;
+ (*pReadCmdSequenceData)[1] = dwNumTmsClocks;
+
+ dwNumReadCommandSequences = (dwNumReadCommandSequences + 1);
+
+ OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences = dwNumReadCommandSequences;
+ }
+ }
+
+ return Status;
+}
+
+PReadCommandsSequenceData FT2232cMpsseJtag::CreateReadCommandsSequenceDataBuffer(DWORD dwSizeReadCmdsSequenceDataBuffer)
+{
+ PReadCommandsSequenceData pReadCmdsSequenceDataBuffer;
+ DWORD CommandSequenceIndex = 0;
+ PReadCommandSequenceData pReadCmdSequenceData;
+
+ pReadCmdsSequenceDataBuffer = PReadCommandsSequenceData(new ReadCommandsSequenceData[dwSizeReadCmdsSequenceDataBuffer]);
+
+ if (pReadCmdsSequenceDataBuffer != NULL)
+ {
+ for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwSizeReadCmdsSequenceDataBuffer); CommandSequenceIndex++)
+ {
+ pReadCmdSequenceData = PReadCommandSequenceData(new ReadCommandSequenceData);
+
+ (*pReadCmdsSequenceDataBuffer)[CommandSequenceIndex] = pReadCmdSequenceData;
+ }
+ }
+
+ return pReadCmdsSequenceDataBuffer;
+}
+
+void FT2232cMpsseJtag::DeleteReadCommandsSequenceDataBuffer(PReadCommandsSequenceData pReadCmdsSequenceDataBuffer, DWORD dwSizeReadCommandsSequenceDataBuffer)
+{
+ DWORD CommandSequenceIndex = 0;
+ PReadCommandSequenceData pReadCmdSequenceData;
+
+ for (CommandSequenceIndex = 0; (CommandSequenceIndex < dwSizeReadCommandsSequenceDataBuffer); CommandSequenceIndex++)
+ {
+ pReadCmdSequenceData = (*pReadCmdsSequenceDataBuffer)[CommandSequenceIndex];
+
+ delete [] pReadCmdSequenceData;
+ }
+
+ delete [] pReadCmdsSequenceDataBuffer;
+}
+
+FTC_STATUS FT2232cMpsseJtag::CreateDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwDeviceIndex = 0;
+ BOOLEAN bDeviceDataBuffersCreated = false;
+
+ for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceDataBuffersCreated); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == 0)
+ {
+ bDeviceDataBuffersCreated = true;
+
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer = POutputByteBuffer(new OutputByteBuffer);
+
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer != NULL)
+ {
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer = CreateReadCommandsSequenceDataBuffer(INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE);
+
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer != NULL)
+ {
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = ftHandle;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwSizeReadCommandsSequenceDataBuffer = INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumReadCommandSequences = 0;
+ }
+ else
+ {
+ delete [] OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer;
+
+ Status = FTC_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ Status = FTC_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ if ((Status == FTC_SUCCESS) && (bDeviceDataBuffersCreated == true))
+ dwNumOpenedDevices = dwNumOpenedDevices + 1;
+
+ return Status;
+}
+
+void FT2232cMpsseJtag::ClearDeviceCommandSequenceData(FTC_HANDLE ftHandle)
+{
+ DWORD dwDeviceIndex = 0;
+ BOOLEAN bDeviceHandleFound = false;
+
+ if (ftHandle != 0)
+ {
+ for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == ftHandle)
+ {
+ bDeviceHandleFound = true;
+
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumReadCommandSequences = 0;
+ }
+ }
+ }
+ else
+ {
+ // This code is executed if there is only one device connected to the system, this code is here just in case
+ // that a device was unplugged from the system, while the system was still running
+ for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice != 0)
+ {
+ bDeviceHandleFound = true;
+
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumReadCommandSequences = 0;
+ }
+ }
+ }
+}
+
+DWORD FT2232cMpsseJtag::GetNumBytesInCommandsSequenceDataBuffer(void)
+{
+ DWORD dwNumBytesToSend_temp = 0;
+
+ if (iCommandsSequenceDataDeviceIndex != -1)
+ // Get the number commands to be executed in sequence ie write, read and write/read
+ dwNumBytesToSend_temp = OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend;
+
+ return dwNumBytesToSend_temp;
+}
+
+DWORD FT2232cMpsseJtag::GetCommandsSequenceDataDeviceIndex(FTC_HANDLE ftHandle)
+{
+ DWORD dwDeviceIndex = 0;
+ BOOLEAN bDeviceHandleFound = false;
+ INT iCmdsSequenceDataDeviceIndex = 0;
+
+ if (ftHandle != 0)
+ {
+ for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == ftHandle)
+ {
+ bDeviceHandleFound = true;
+
+ iCmdsSequenceDataDeviceIndex = dwDeviceIndex;
+ }
+ }
+ }
+ else
+ {
+ // This code is executed if there is only one device connected to the system, this code is here just in case
+ // that a device was unplugged from the system, while the system was still running
+ for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice != 0)
+ {
+ bDeviceHandleFound = true;
+
+ iCmdsSequenceDataDeviceIndex = dwDeviceIndex;
+ }
+ }
+ }
+
+ return iCmdsSequenceDataDeviceIndex;
+}
+
+void FT2232cMpsseJtag::DeleteDeviceCommandsSequenceDataBuffers(FTC_HANDLE ftHandle)
+{
+ DWORD dwDeviceIndex = 0;
+ BOOLEAN bDeviceHandleFound = false;
+ POutputByteBuffer pCmdsSequenceDataOutPutBuffer;
+
+ for (dwDeviceIndex = 0; ((dwDeviceIndex < MAX_NUM_DEVICES) && !bDeviceHandleFound); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice == ftHandle)
+ {
+ bDeviceHandleFound = true;
+
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = 0;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwNumBytesToSend = 0;
+ pCmdsSequenceDataOutPutBuffer = OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer;
+ delete [] pCmdsSequenceDataOutPutBuffer;
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer = NULL;
+ DeleteReadCommandsSequenceDataBuffer(OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer,
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwSizeReadCommandsSequenceDataBuffer);
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer = NULL;
+ }
+ }
+
+ if ((dwNumOpenedDevices > 0) && bDeviceHandleFound)
+ dwNumOpenedDevices = dwNumOpenedDevices - 1;
+}
+
+FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumCommandDataBytes = 0;
+
+ if (pWriteDataBuffer != NULL)
+ {
+ Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWrite, dwNumBytesToWrite);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE))
+ {
+ dwNumCommandDataBytes = (NUM_WRITE_COMMAND_BYTES + dwNumBytesToWrite);
+
+ iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle);
+
+ if ((GetNumBytesInCommandsSequenceDataBuffer() + dwNumCommandDataBytes) < OUTPUT_BUFFER_SIZE)
+ AddWriteCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer,
+ dwNumBytesToWrite, dwTapControllerState);
+ else
+ Status = FTC_COMMAND_SEQUENCE_BUFFER_FULL;
+
+ // Reset to indicate that you are not building up a sequence of commands
+ iCommandsSequenceDataDeviceIndex = -1;
+ }
+ else
+ Status = FTC_INVALID_TAP_CONTROLLER_STATE;
+ }
+ }
+ else
+ Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER;
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumTmsClocks = 0;
+
+ if ((dwNumBitsToRead >= MIN_NUM_BITS) && (dwNumBitsToRead <= MAX_NUM_BITS))
+ {
+ if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE))
+ {
+ iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle);
+
+ if ((GetNumBytesInCommandsSequenceDataBuffer() + NUM_READ_COMMAND_BYTES) < OUTPUT_BUFFER_SIZE)
+ {
+ dwNumTmsClocks = AddReadCommandToOutputBuffer(bInstructionTestData, dwNumBitsToRead, dwTapControllerState);
+
+ Status = AddReadCommandSequenceData(dwNumBitsToRead, dwNumTmsClocks);
+ }
+ else
+ Status = FTC_COMMAND_SEQUENCE_BUFFER_FULL;
+
+ // Reset to indicate that you are not building up a sequence of commands
+ iCommandsSequenceDataDeviceIndex = -1;
+ }
+ else
+ Status = FTC_INVALID_TAP_CONTROLLER_STATE;
+ }
+ else
+ Status = FTC_INVALID_NUMBER_BITS;
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumCommandDataBytes = 0;
+ DWORD dwNumTmsClocks = 0;
+
+ if (pWriteDataBuffer != NULL)
+ {
+ Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWriteRead, dwNumBytesToWrite);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE))
+ {
+ dwNumCommandDataBytes = (NUM_WRITE_READ_COMMAND_BYTES + dwNumBytesToWrite);
+
+ iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle);
+
+ if ((GetNumBytesInCommandsSequenceDataBuffer() + dwNumCommandDataBytes) < OUTPUT_BUFFER_SIZE)
+ {
+ dwNumTmsClocks = AddWriteReadCommandDataToOutPutBuffer(bInstructionTestData, dwNumBitsToWriteRead, pWriteDataBuffer,
+ dwNumBytesToWrite, dwTapControllerState);
+
+ Status = AddReadCommandSequenceData(dwNumBitsToWriteRead, dwNumTmsClocks);
+ }
+ else
+ Status = FTC_COMMAND_SEQUENCE_BUFFER_FULL;
+
+ // Reset to indicate that you are not building up a sequence of commands
+ iCommandsSequenceDataDeviceIndex = -1;
+ }
+ else
+ Status = FTC_INVALID_TAP_CONTROLLER_STATE;
+ }
+ }
+ else
+ Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER;
+
+ return Status;
+}
+
+FT2232cMpsseJtag::FT2232cMpsseJtag(void)
+{
+ DWORD dwDeviceIndex = 0;
+
+ CurrentJtagState = Undefined;
+
+ dwSavedLowPinsDirection = 0;
+ dwSavedLowPinsValue = 0;
+
+ dwNumOpenedDevices = 0;
+
+ for (dwDeviceIndex = 0; (dwDeviceIndex < MAX_NUM_DEVICES); dwDeviceIndex++)
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = 0;
+
+ iCommandsSequenceDataDeviceIndex = -1;
+}
+
+FT2232cMpsseJtag::~FT2232cMpsseJtag(void)
+{
+ DWORD dwDeviceIndex = 0;
+ POutputByteBuffer pCmdsSequenceDataOutPutBuffer;
+
+ if (dwNumOpenedDevices > 0)
+ {
+ for (dwDeviceIndex = 0; (dwDeviceIndex < MAX_NUM_DEVICES); dwDeviceIndex++)
+ {
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice != 0)
+ {
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].hDevice = 0;
+
+ pCmdsSequenceDataOutPutBuffer = OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer;
+
+ if (pCmdsSequenceDataOutPutBuffer != NULL)
+ delete [] pCmdsSequenceDataOutPutBuffer;
+
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].pCommandsSequenceDataOutPutBuffer = NULL;
+
+ if (OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer != NULL)
+ DeleteReadCommandsSequenceDataBuffer(OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer,
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].dwSizeReadCommandsSequenceDataBuffer);
+
+ OpenedDevicesCommandsSequenceData[dwDeviceIndex].pReadCommandsSequenceDataBuffer = NULL;
+ }
+ }
+ }
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetNumDevices(LPDWORD lpdwNumDevices)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ FT2232CDeviceIndexes FT2232CIndexes;
+
+ *lpdwNumDevices = 0;
+
+ Status = FTC_GetNumDevices(lpdwNumDevices, &FT2232CIndexes);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetDeviceNameLocationID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_GetDeviceNameLocID(DWORD dwDeviceNameIndex, LPSTR lpDeviceNameBuffer, DWORD dwBufferSize, LPDWORD lpdwLocationID)
+{
+ return FTC_GetDeviceNameLocationID(dwDeviceNameIndex, lpDeviceNameBuffer, dwBufferSize, lpdwLocationID);
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_OpenEx(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_OpenSpecifiedDevice(lpDeviceName, dwLocationID, pftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = CreateDeviceCommandsSequenceDataBuffers(*pftHandle);
+
+ if (Status != FTC_SUCCESS)
+ {
+ FTC_CloseDevice(*pftHandle);
+
+ *pftHandle = 0;
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_OpenDevice(FTC_HANDLE *pftHandle)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_Open(FTC_HANDLE *pftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_OpenDevice(pftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = CreateDeviceCommandsSequenceDataBuffers(*pftHandle);
+
+ if (Status != FTC_SUCCESS)
+ {
+ // FTC_CloseDevice(*pftHandle);
+ FTC_CloseDevice(*pftHandle);
+
+ *pftHandle = 0;
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_CloseDevice(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_CloseDevice(ftHandle);
+
+ DeleteDeviceCommandsSequenceDataBuffers(ftHandle);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_InitDevice(FTC_HANDLE ftHandle, DWORD dwClockDivisor)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwClockDivisor >= MIN_CLOCK_DIVISOR) && (dwClockDivisor <= MAX_CLOCK_DIVISOR))
+ {
+ Status = FTC_ResetUSBDevicePurgeUSBInputBuffer(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_SetDeviceUSBBufferSizes(ftHandle, USB_INPUT_BUFFER_SIZE, USB_OUTPUT_BUFFER_SIZE);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_SetDeviceSpecialCharacters(ftHandle, false, FT_EVENT_VALUE, false, FT_ERROR_VALUE);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_SetReadWriteDeviceTimeouts(ftHandle, DEVICE_READ_TIMEOUT_INFINITE, DEVICE_WRITE_TIMEOUT);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_SetDeviceLatencyTimer(ftHandle, DEVICE_LATENCY_TIMER_VALUE);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_ResetMPSSEInterface(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_EnableMPSSEInterface(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_SynchronizeMPSSEInterface(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_ResetUSBDevicePurgeUSBInputBuffer(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ //Sleep(20); // wait for all the USB stuff to complete
+ // Removed Sleep() call and replaced with linux sleep to give up
+ // timeslice - sched_yield() -- not sure is best idea! -- Julius
+ sched_yield();
+
+ if (Status == FTC_SUCCESS)
+ Status = InitDataInOutClockFrequency(ftHandle, dwClockDivisor);
+
+ if (Status == FTC_SUCCESS)
+ // Status = FTC_SetDeviceLoopbackState(ftHandle, false);
+ Status = FTC_SetDeviceLoopbackState(ftHandle, false);
+
+ if (Status == FTC_SUCCESS)
+ //Sleep(20); // wait for all the USB stuff to complete
+ // Removed Sleep() call and replaced with linux sleep to give up
+ // timeslice - sched_yield() -- not sure is best idea! -- Julius
+ sched_yield();
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_ResetUSBDevicePurgeUSBInputBuffer(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ //Sleep(20); // wait for all the USB stuff to complete
+ // Removed Sleep() call and replaced with linux sleep to give up
+ // timeslice - sched_yield() -- not sure is best idea! -- Julius
+ sched_yield();
+
+ if (Status == FTC_SUCCESS)
+ Status = ResetTAPContollerExternalDeviceSetToTestIdleMode(ftHandle);
+ }
+ else
+ Status = FTC_INVALID_CLOCK_DIVISOR;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetClock(DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ if ((dwClockDivisor >= MIN_CLOCK_DIVISOR) && (dwClockDivisor <= MAX_CLOCK_DIVISOR))
+ FTC_GetClockFrequencyValues(dwClockDivisor, lpdwClockFrequencyHz);
+ else
+ Status = FTC_INVALID_CLOCK_DIVISOR;
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_SetClock(FTC_HANDLE ftHandle, DWORD dwClockDivisor, LPDWORD lpdwClockFrequencyHz)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwClockDivisor >= MIN_CLOCK_DIVISOR) && (dwClockDivisor <= MAX_CLOCK_DIVISOR))
+ {
+ Status = SetDataInOutClockFrequency(ftHandle, dwClockDivisor);
+
+ if (Status == FTC_SUCCESS)
+ FTC_GetClockFrequencyValues(dwClockDivisor, lpdwClockFrequencyHz);
+ }
+ else
+ Status = FTC_INVALID_CLOCK_DIVISOR;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_SetLoopback(FTC_HANDLE ftHandle, BOOL bLoopbackState)
+{
+ return FTC_SetDeviceLoopbackState(ftHandle, bLoopbackState);
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_SetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_SetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
+ PFTC_INPUT_OUTPUT_PINS pLowInputOutputPinsData,
+ BOOL bControlHighInputOutputPins,
+ PFTC_INPUT_OUTPUT_PINS pHighInputOutputPinsData)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwLowPinsDirection = 0;
+ DWORD dwLowPinsValue = 0;
+ DWORD dwHighPinsDirection = 0;
+ DWORD dwHighPinsValue = 0;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((pLowInputOutputPinsData != NULL) && (pHighInputOutputPinsData != NULL))
+ {
+ if (pLowInputOutputPinsData->bPin1InputOutputState != false)
+ dwLowPinsDirection = (dwLowPinsDirection | '\x01');
+ if (pLowInputOutputPinsData->bPin2InputOutputState != false)
+ dwLowPinsDirection = (dwLowPinsDirection | '\x02');
+ if (pLowInputOutputPinsData->bPin3InputOutputState != false)
+ dwLowPinsDirection = (dwLowPinsDirection | '\x04');
+ if (pLowInputOutputPinsData->bPin4InputOutputState != false)
+ dwLowPinsDirection = (dwLowPinsDirection | '\x08');
+ if (pLowInputOutputPinsData->bPin1LowHighState != false)
+ dwLowPinsValue = (dwLowPinsValue | '\x01');
+ if (pLowInputOutputPinsData->bPin2LowHighState != false)
+ dwLowPinsValue = (dwLowPinsValue | '\x02');
+ if (pLowInputOutputPinsData->bPin3LowHighState != false)
+ dwLowPinsValue = (dwLowPinsValue | '\x04');
+ if (pLowInputOutputPinsData->bPin4LowHighState != false)
+ dwLowPinsValue = (dwLowPinsValue | '\x08');
+
+ if (pHighInputOutputPinsData->bPin1InputOutputState != false)
+ dwHighPinsDirection = (dwHighPinsDirection | '\x01');
+ if (pHighInputOutputPinsData->bPin2InputOutputState != false)
+ dwHighPinsDirection = (dwHighPinsDirection | '\x02');
+ if (pHighInputOutputPinsData->bPin3InputOutputState != false)
+ dwHighPinsDirection = (dwHighPinsDirection | '\x04');
+ if (pHighInputOutputPinsData->bPin4InputOutputState != false)
+ dwHighPinsDirection = (dwHighPinsDirection | '\x08');
+ if (pHighInputOutputPinsData->bPin1LowHighState != false)
+ dwHighPinsValue = (dwHighPinsValue | '\x01');
+ if (pHighInputOutputPinsData->bPin2LowHighState != false)
+ dwHighPinsValue = (dwHighPinsValue | '\x02');
+ if (pHighInputOutputPinsData->bPin3LowHighState != false)
+ dwHighPinsValue = (dwHighPinsValue | '\x04');
+ if (pHighInputOutputPinsData->bPin4LowHighState != false)
+ dwHighPinsValue = (dwHighPinsValue | '\x08');
+
+ Status = SetGeneralPurposeInputOutputPins(ftHandle, bControlLowInputOutputPins,
+ dwLowPinsDirection, dwLowPinsValue,
+ bControlHighInputOutputPins,
+ dwHighPinsDirection, dwHighPinsValue);
+ }
+ else
+ Status = FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetGeneralPurposeInputOutputPins(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_GetGPIOs(FTC_HANDLE ftHandle, BOOL bControlLowInputOutputPins,
+ PFTC_LOW_HIGH_PINS pLowPinsInputData,
+ BOOL bControlHighInputOutputPins,
+ PFTC_LOW_HIGH_PINS pHighPinsInputData)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((pLowPinsInputData != NULL) && (pHighPinsInputData != NULL))
+ Status = GetGeneralPurposeInputOutputPins(ftHandle, bControlLowInputOutputPins, pLowPinsInputData,
+ bControlHighInputOutputPins, pHighPinsInputData);
+ else
+ Status = FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_WriteDataToExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_Write(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (pWriteDataBuffer != NULL)
+ {
+ Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWrite, dwNumBytesToWrite);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE))
+ Status = WriteDataToExternalDevice(ftHandle, bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer,
+ dwNumBytesToWrite, dwTapControllerState);
+ else
+ Status = FTC_INVALID_TAP_CONTROLLER_STATE;
+ }
+ }
+ else
+ Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_ReadDataFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_Read(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead,
+ PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (pReadDataBuffer != NULL)
+ {
+ if ((dwNumBitsToRead >= MIN_NUM_BITS) && (dwNumBitsToRead <= MAX_NUM_BITS))
+ {
+ if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE))
+ Status = ReadDataFromExternalDevice(ftHandle, bInstructionTestData, dwNumBitsToRead, pReadDataBuffer,
+ lpdwNumBytesReturned, dwTapControllerState);
+ else
+ Status = FTC_INVALID_TAP_CONTROLLER_STATE;
+ }
+ else
+ Status = FTC_INVALID_NUMBER_BITS;
+ }
+ else
+ Status = FTC_NULL_READ_DATA_BUFFER_POINTER;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_WriteReadDataToFromExternalDevice(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_WriteRead(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ PReadDataByteBuffer pReadDataBuffer, LPDWORD lpdwNumBytesReturned,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((pWriteDataBuffer != NULL) && (pReadDataBuffer != NULL))
+ {
+ Status = CheckWriteDataToExternalDeviceBitsBytesParameters(dwNumBitsToWriteRead, dwNumBytesToWrite);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwTapControllerState >= TEST_LOGIC_STATE) && (dwTapControllerState <= SHIFT_INSTRUCTION_REGISTER_STATE))
+ Status = WriteReadDataToFromExternalDevice(ftHandle, bInstructionTestData, dwNumBitsToWriteRead,
+ pWriteDataBuffer, dwNumBytesToWrite, pReadDataBuffer,
+ lpdwNumBytesReturned, dwTapControllerState);
+ else
+ Status = FTC_INVALID_TAP_CONTROLLER_STATE;
+ }
+ }
+ else
+ {
+ if (pWriteDataBuffer == NULL)
+ Status = FTC_NULL_WRITE_DATA_BUFFER_POINTER;
+ else
+ Status = FTC_NULL_READ_DATA_BUFFER_POINTER;
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GenerateTCKClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_GenerateClockPulses(FTC_HANDLE ftHandle, DWORD dwNumClockPulses)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((dwNumClockPulses >= MIN_NUM_CLOCK_PULSES) && (dwNumClockPulses <= MAX_NUM_CLOCK_PULSES))
+ Status = GenerateTCKClockPulses(ftHandle, dwNumClockPulses);
+ else
+ Status = FTC_INVALID_NUMBER_CLOCK_PULSES;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_ClearCommandSequence(void)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_ClearCmdSequence(void)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDevices;
+ FT2232CDeviceIndexes FT2232CIndexes;
+
+ Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumDevices == 1)
+ ClearDeviceCommandSequenceData(0);
+ else
+ Status = FTC_TOO_MANY_DEVICES;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ //DWORD dwNumCommandDataBytes = 0;
+ DWORD dwNumDevices;
+ FT2232CDeviceIndexes FT2232CIndexes;
+
+ Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumDevices == 1)
+ // ftHandle parameter set to 0 to indicate only one device present in the system
+ Status = AddDeviceWriteCommand(0, bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState);
+ else
+ Status = FTC_TOO_MANY_DEVICES;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_AddReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ //DWORD dwNumTmsClocks = 0;
+ DWORD dwNumDevices;
+ FT2232CDeviceIndexes FT2232CIndexes;
+
+ Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumDevices == 1)
+ // ftHandle parameter set to 0 to indicate only one device present in the system
+ Status = AddDeviceReadCommand(0, bInstructionTestData, dwNumBitsToRead, dwTapControllerState);
+ else
+ Status = FTC_TOO_MANY_DEVICES;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteReadCommand(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteReadCmd(BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ //DWORD dwNumCommandDataBytes = 0;
+ //DWORD dwNumTmsClocks = 0;
+ DWORD dwNumDevices;
+ FT2232CDeviceIndexes FT2232CIndexes;
+
+ Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumDevices == 1)
+ // ftHandle parameter set to 0 to indicate only one device present in the system
+ Status = AddDeviceWriteReadCommand(0, bInstructionTestData, dwNumBitsToWriteRead, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState);
+ else
+ Status = FTC_TOO_MANY_DEVICES;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_ClearDeviceCommandSequence(FTC_HANDLE ftHandle)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_ClearDeviceCmdSequence(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ ClearDeviceCommandSequenceData(ftHandle);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWrite,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = AddDeviceWriteCommand(ftHandle, bInstructionTestData, dwNumBitsToWrite, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState)
+//FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToRead, DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = AddDeviceReadCommand(ftHandle, bInstructionTestData, dwNumBitsToRead, dwTapControllerState);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteReadCommand(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteReadCmd(FTC_HANDLE ftHandle, BOOL bInstructionTestData, DWORD dwNumBitsToWriteRead,
+ PWriteDataByteBuffer pWriteDataBuffer, DWORD dwNumBytesToWrite,
+ DWORD dwTapControllerState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ Status = AddDeviceWriteReadCommand(ftHandle, bInstructionTestData, dwNumBitsToWriteRead, pWriteDataBuffer, dwNumBytesToWrite, dwTapControllerState);
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_ExecuteCommandSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
+//FTC_STATUS FT2232cMpsseJtag::JTAG_ExecuteCmdSequence(FTC_HANDLE ftHandle, PReadCmdSequenceDataByteBuffer pReadCmdSequenceDataBuffer,
+ LPDWORD lpdwNumBytesReturned)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumCmdSequenceBytes = 0;
+ DWORD dwCmdSequenceByteIndex = 0;
+ InputByteBuffer InputBuffer;
+ DWORD dwTotalNumBytesToBeRead = 0;
+ DWORD dwNumBytesRead = 0;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (pReadCmdSequenceDataBuffer != NULL)
+ {
+ iCommandsSequenceDataDeviceIndex = GetCommandsSequenceDataDeviceIndex(ftHandle);
+
+ dwNumCmdSequenceBytes = GetNumBytesInCommandsSequenceDataBuffer();
+
+ if (dwNumCmdSequenceBytes > 0)
+ {
+ AddByteToOutputBuffer(SEND_ANSWER_BACK_IMMEDIATELY_CMD, false);
+
+ FTC_ClearOutputBuffer();
+
+ dwNumCmdSequenceBytes = GetNumBytesInCommandsSequenceDataBuffer();
+
+ // Transfer sequence of commands for specified device to output buffer for transmission to device
+ for (dwCmdSequenceByteIndex = 0; (dwCmdSequenceByteIndex < dwNumCmdSequenceBytes); dwCmdSequenceByteIndex++)
+ FTC_AddByteToOutputBuffer((*OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].pCommandsSequenceDataOutPutBuffer)[dwCmdSequenceByteIndex], false);
+
+ OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumBytesToSend = 0;
+
+ Status = FTC_SendCommandsSequenceToDevice(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences > 0)
+ {
+ // Calculate the total number of bytes to be read, as a result of a command sequence
+ dwTotalNumBytesToBeRead = GetTotalNumCommandsSequenceDataBytesToRead();
+
+ Status = FTC_ReadCommandsSequenceBytesFromDevice(ftHandle, &InputBuffer, dwTotalNumBytesToBeRead, &dwNumBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ // Process all bytes received and return them in the read data buffer
+ ProcessReadCommandsSequenceBytes(&InputBuffer, dwNumBytesRead, pReadCmdSequenceDataBuffer, lpdwNumBytesReturned);
+ }
+ }
+ }
+
+ OpenedDevicesCommandsSequenceData[iCommandsSequenceDataDeviceIndex].dwNumReadCommandSequences = 0;
+ }
+ else
+ Status = FTC_NO_COMMAND_SEQUENCE;
+
+ iCommandsSequenceDataDeviceIndex = -1;
+ }
+ else
+ Status = FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetDllVersion(LPSTR lpDllVersionBuffer, DWORD dwBufferSize)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ if (lpDllVersionBuffer != NULL)
+ {
+ if (dwBufferSize > strlen(DLL_VERSION_NUM))
+ strcpy(lpDllVersionBuffer, DLL_VERSION_NUM);
+ else
+ Status = FTC_DLL_VERSION_BUFFER_TOO_SMALL;
+ }
+ else
+ Status = FTC_NULL_DLL_VERSION_BUFFER_POINTER;
+
+ return Status;
+}
+
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetErrorCodeString(LPSTR lpLanguage, FTC_STATUS StatusCode,
+ LPSTR lpErrorMessageBuffer, DWORD dwBufferSize)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ CHAR szErrorMsg[MAX_ERROR_MSG_SIZE];
+ INT iCharCntr = 0;
+
+ if ((lpLanguage != NULL) && (lpErrorMessageBuffer != NULL))
+ {
+ for (iCharCntr = 0; (iCharCntr < MAX_ERROR_MSG_SIZE); iCharCntr++)
+ szErrorMsg[iCharCntr] = '\0';
+
+ if (((StatusCode >= FTC_SUCCESS) && (StatusCode <= FTC_INSUFFICIENT_RESOURCES)) ||
+ ((StatusCode >= FTC_FAILED_TO_COMPLETE_COMMAND) && (StatusCode <= FTC_INVALID_STATUS_CODE)))
+ {
+ if (strcmp(lpLanguage, ENGLISH) == 0)
+ {
+ if ((StatusCode >= FTC_SUCCESS) && (StatusCode <= FTC_INSUFFICIENT_RESOURCES))
+ strcpy(szErrorMsg, EN_Common_Errors[StatusCode]);
+ else
+ strcpy(szErrorMsg, EN_New_Errors[(StatusCode - FTC_FAILED_TO_COMPLETE_COMMAND)]);
+ }
+ else
+ {
+ strcpy(szErrorMsg, EN_New_Errors[FTC_INVALID_LANGUAGE_CODE - FTC_FAILED_TO_COMPLETE_COMMAND]);
+
+ Status = FTC_INVALID_LANGUAGE_CODE;
+ }
+ }
+ else
+ {
+ sprintf(szErrorMsg, "%s%d", EN_New_Errors[FTC_INVALID_STATUS_CODE - FTC_FAILED_TO_COMPLETE_COMMAND], (int)StatusCode);
+
+ Status = FTC_INVALID_STATUS_CODE;
+ }
+
+ if (dwBufferSize > strlen(szErrorMsg))
+ strcpy(lpErrorMessageBuffer, szErrorMsg);
+ else
+ Status = FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ if (lpLanguage == NULL)
+ Status = FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER;
+ else
+ Status = FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER;
+ }
+
+ return Status;
+}
Index: or_debug_proxy/src/FT2232c.cpp
===================================================================
--- or_debug_proxy/src/FT2232c.cpp (nonexistent)
+++ or_debug_proxy/src/FT2232c.cpp (revision 1779)
@@ -0,0 +1,1161 @@
+/*++
+
+FTC MPSSE Interface DLLs - Copyright © FTDI Ltd. 2009
+
+
+The source code to the FTCI2C, FTCJTAG and FTCSPI DLLs is provided as-is and no warranty is made as to its function or reliability.
+
+This source code may be freely modified and redistributed, provided that the FTDI Ltd. copyright notice remains intact.
+
+Copyright (c) 2005 Future Technology Devices International Ltd.
+
+Module Name:
+
+ FT2232c.cpp
+
+Abstract:
+
+ FT2232C Dual Type Devices Base Class Implementation.
+
+Environment:
+
+ kernel & user mode
+
+Revision History:
+
+ 07/02/05 kra Created.
+ 25/08/05 kra Windows 2000 Professional always sets the USB buffer size to 4K ie 4096
+ 19/11/08 Rene Baumann Port FTCJTAG to Linux.
+
+--*/
+
+
+#include
+#include
+#include
+//#include // -- Possibly not needed, trying without -jb
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+
+#include "FT2232c.h"
+#include "WinTypes.h"
+
+
+//couple of simple string functions
+ char* strupr(char *string);
+ char* strlwr(char *string);
+
+ static UINT uiNumOpenedDevices = 0; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene
+ static FTC_DEVICE_DATA OpenedDevices[MAX_NUM_DEVICES]; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene
+ static OutputByteBuffer OutputBuffer; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene
+ static DWORD dwNumBytesToSend = 0; // Removed from class FT2232c in FT2232c.h to avoid segmentation fault. Rene
+
+
+BOOLEAN FT2232c::FTC_DeviceInUse(LPSTR lpDeviceName, DWORD dwLocationID)
+{
+ BOOLEAN bDeviceInUse = false;
+ DWORD dwProcessId = 0;
+ BOOLEAN bLocationIDFound = false;
+ INT iDeviceCntr = 0;
+
+ if (uiNumOpenedDevices > 0)
+ {
+ //dwProcessId = GetCurrentProcessId();
+ dwProcessId = getpid(); //Changed windows call to linux\s getpid()
+
+ for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bLocationIDFound); iDeviceCntr++)
+ {
+ // Only check device name and location id not the current application
+ if (OpenedDevices[iDeviceCntr].dwProcessId != dwProcessId)
+ {
+ if (strcmp(OpenedDevices[iDeviceCntr].szDeviceName, lpDeviceName) == 0)
+ {
+ if (OpenedDevices[iDeviceCntr].dwLocationID == dwLocationID)
+ bLocationIDFound = true;
+ }
+ }
+ }
+
+ if (bLocationIDFound)
+ bDeviceInUse = true;
+ }
+
+ return bDeviceInUse;
+}
+
+BOOLEAN FT2232c::FTC_DeviceOpened(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle)
+{
+ BOOLEAN bDeviceOpen = false;
+ DWORD dwProcessId = 0;
+ BOOLEAN bLocationIDFound = false;
+ INT iDeviceCntr = 0;
+
+ if (uiNumOpenedDevices > 0)
+ {
+ //dwProcessId = GetCurrentProcessId();
+ dwProcessId = getpid(); //Changed windows call to linux one
+
+ for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bLocationIDFound); iDeviceCntr++)
+ {
+ if (OpenedDevices[iDeviceCntr].dwProcessId == dwProcessId)
+ {
+ if (strcmp(OpenedDevices[iDeviceCntr].szDeviceName, lpDeviceName) == 0)
+ {
+ if (OpenedDevices[iDeviceCntr].dwLocationID == dwLocationID)
+ {
+ // Device has already been opened by this application, so just return the handle to the device
+ *pftHandle = OpenedDevices[iDeviceCntr].hDevice;
+ bLocationIDFound = true;
+ }
+ }
+ }
+ }
+
+ if (bLocationIDFound)
+ bDeviceOpen = true;
+ }
+
+ return bDeviceOpen;
+}
+
+FTC_STATUS FT2232c::FTC_IsDeviceNameLocationIDValid(LPSTR lpDeviceName, DWORD dwLocationID)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumOfDevices = 0;
+ FT2232CDeviceIndexes FT2232CIndexes;
+ DWORD dwFlags = 0;
+ DWORD dwDeviceType = 0;
+ DWORD dwProductVendorID = 0;
+ DWORD dwLocID = 0;
+ SerialNumber szSerialNumber;
+ char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1];
+ FT_HANDLE ftHandle;
+ BOOL bDeviceNameFound = false;
+ DWORD dwDeviceIndex = 0;
+
+ // Get the number of devices connected to the system
+ Status = FTC_GetNumDevices(&dwNumOfDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumOfDevices > 0)
+ {
+ do
+ {
+ Status = FT_GetDeviceInfoDetail(FT2232CIndexes[dwDeviceIndex], &dwFlags, &dwDeviceType, &dwProductVendorID,
+ &dwLocID, szSerialNumber, szDeviceNameBuffer, &ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (strcmp(szDeviceNameBuffer, lpDeviceName) == 0)
+ bDeviceNameFound = true;
+ }
+ dwDeviceIndex++;
+ }
+ while ((dwDeviceIndex < dwNumOfDevices) && (Status == FTC_SUCCESS) && (bDeviceNameFound == false));
+
+ if (bDeviceNameFound == TRUE)
+ {
+ if (dwLocID != dwLocationID)
+ Status = FTC_INVALID_LOCATION_ID;
+ }
+ else
+ Status = FTC_INVALID_DEVICE_NAME;
+ }
+ else
+ Status = FTC_DEVICE_NOT_FOUND;
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_IsDeviceFT2232CType(LPSTR lpDeviceName, LPBOOL lpbFT2232CTypeDevice)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ LPSTR pszStringSearch;
+
+ *lpbFT2232CTypeDevice = false;
+
+ // Search for the last occurrence of the channel string ie ' A'
+ if ((pszStringSearch = strstr(strupr(lpDeviceName), DEVICE_CHANNEL_A)) != NULL)
+ {
+ // Ensure the last two characters of the device name is ' A' ie channel A
+ if (strlen(pszStringSearch) == 2)
+ *lpbFT2232CTypeDevice = true;
+ }
+
+ return Status;
+}
+
+FT2232c::FT2232c(void)
+{
+ INT iDeviceCntr = 0;
+
+ uiNumOpenedDevices = 0;
+
+ for (iDeviceCntr = 0; (iDeviceCntr < MAX_NUM_DEVICES); iDeviceCntr++)
+ OpenedDevices[iDeviceCntr].dwProcessId = 0;
+
+ dwNumBytesToSend = 0;
+}
+
+FT2232c::~FT2232c(void)
+{
+
+}
+
+FTC_STATUS FT2232c::FTC_GetNumDevices(LPDWORD lpdwNumDevices, FT2232CDeviceIndexes *FT2232CIndexes)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumOfDevices = 0;
+ DWORD dwDeviceIndex = 0;
+ DWORD dwFlags = 0;
+ DWORD dwDeviceType = 0;
+ DWORD dwProductVendorID = 0;
+ SerialNumber szSerialNumber;
+ char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1];
+ FT_HANDLE ftHandle;
+ DWORD dwLocationID;
+ DWORD i;
+ BOOL bFT2232CTypeDevice = false;
+
+ *lpdwNumDevices = 0;
+
+ // Get the number of devices connected to the system
+ Status = FT_CreateDeviceInfoList(&dwNumOfDevices);
+
+if(DEBUG_LIST_DEVICE){
+ FT_STATUS ftStatus;
+ FT_DEVICE_LIST_INFO_NODE *devInfo;
+ DWORD numDevs;
+ // create the device information list
+ ftStatus = FT_CreateDeviceInfoList(&numDevs);
+ if (ftStatus == FT_OK) {
+ printf("Number of devices is %ld\n",numDevs);
+ }
+ if (numDevs > 0) {
+ // allocate storage for list based on numDevs
+ devInfo =
+ (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs);
+ // get the device information list
+ ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs);
+ if (ftStatus == FT_OK) {
+ for ( i = 0; i < numDevs; i++) {
+ printf("Dev %ld:\n",i);
+ printf(" Flags=0x%lx\n",devInfo[i].Flags);
+ printf(" Type=0x%lx\n",devInfo[i].Type);
+ printf(" ID=0x%lx\n",devInfo[i].ID);
+ printf(" LocId=0x%lx\n",devInfo[i].LocId);
+ printf(" SerialNumber=%s\n",devInfo[i].SerialNumber);
+ printf(" Description=%s\n",devInfo[i].Description);
+ printf(" ftHandle=0x%lx\n",(unsigned long int)devInfo[i].ftHandle);
+ }
+ }
+ }
+}
+
+
+
+
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumOfDevices > 0)
+ {
+ do
+ {
+ // Devices previously opened by another application, results in 0 being returned for dwflags, dwDeviceType,
+ // dwProductVendorID, dwLocationID and ftHandle and empty being returned in szSerialNumber and
+ // szDeviceNameBuffer. This problem is in the FTD2XX.DLL.
+ Status = FT_GetDeviceInfoDetail(dwDeviceIndex, &dwFlags, &dwDeviceType, &dwProductVendorID,
+ &dwLocationID, szSerialNumber, szDeviceNameBuffer, &ftHandle);
+ // The flag value is a 4-byte bit map containing miscellaneous data as defined in the - Type Definitions.
+ // Bit 0 (least significant bit) of this number indicates if the port is open (1) or closed (0).
+ // Bit 1 indicates if the device is enumerated as a high-speed USB device (2) or a full-speed USB device (0).
+ // The remaining bits (2 - 31) are reserved.
+
+ // dwDeviceType = 4 --> FT_DEVICE_2232C see FT_DEVICE in ftd2xx.h
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_IsDeviceFT2232CType(szDeviceNameBuffer, &bFT2232CTypeDevice);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (bFT2232CTypeDevice == TRUE)
+ {
+ // The number of devices returned is, not opened devices ie channel A plus devices opened by the
+ // calling application. Devices previously opened by another application are not included in this
+ // number.
+ (*FT2232CIndexes)[*lpdwNumDevices] = dwDeviceIndex;
+
+ *lpdwNumDevices = *lpdwNumDevices + 1;
+ }
+ }
+ }
+ else
+ {
+ // if a device has already been opened by another application, the FT_GetDeviceInfoDetail call will
+ // return an INVALID_HANDLE error code, ignore this error code and continue
+ if (Status == FTC_INVALID_HANDLE)
+ Status = FTC_SUCCESS;
+ }
+
+ dwDeviceIndex++;
+ }
+ while ((dwDeviceIndex < dwNumOfDevices) && (Status == FTC_SUCCESS));
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_GetNumNotOpenedDevices(LPDWORD lpdwNumNotOpenedDevices, FT2232CDeviceIndexes *FT2232CIndexes)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumOfDevices = 0;
+ DWORD dwDeviceIndex = 0;
+ DWORD dwFlags = 0;
+ DWORD dwDeviceType = 0;
+ DWORD dwProductVendorID = 0;
+ SerialNumber szSerialNumber;
+ char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1];
+ FT_HANDLE ftHandle;
+ DWORD dwLocationID;
+ BOOL bFT2232CTypeDevice = false;
+
+ *lpdwNumNotOpenedDevices = 0;
+
+ // Get the number of devices connected to the system
+ Status = FT_CreateDeviceInfoList(&dwNumOfDevices);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumOfDevices > 0)
+ {
+ do
+ {
+ Status = FT_GetDeviceInfoDetail(dwDeviceIndex, &dwFlags, &dwDeviceType, &dwProductVendorID,
+ &dwLocationID, szSerialNumber, szDeviceNameBuffer, &ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_IsDeviceFT2232CType(szDeviceNameBuffer, &bFT2232CTypeDevice);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if ((bFT2232CTypeDevice == TRUE) && ((dwFlags & DEVICE_OPENED_FLAG) == 0))
+ {
+ (*FT2232CIndexes)[*lpdwNumNotOpenedDevices] = dwDeviceIndex;
+
+ *lpdwNumNotOpenedDevices = *lpdwNumNotOpenedDevices + 1;
+ }
+ }
+ }
+ else
+ {
+ // if a device has already been opened by another application, the FT_GetDeviceInfoDetail call will
+ // return an INVALID_HANDLE error code, ignore this error code and continue
+ if (Status == FTC_INVALID_HANDLE)
+ Status = FTC_SUCCESS;
+ }
+
+ dwDeviceIndex++;
+ }
+ while ((dwDeviceIndex < dwNumOfDevices) && (Status == FTC_SUCCESS));
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_GetDeviceNameLocationID(DWORD dwDeviceIndex, LPSTR lpDeviceName, DWORD dwBufferSize, LPDWORD lpdwLocationID)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDevices = 0;
+ FT2232CDeviceIndexes FT2232CIndexes;
+ DWORD dwFlags = 0;
+ DWORD dwDeviceType = 0;
+ DWORD dwProductVendorID = 0;
+ SerialNumber szSerialNumber;
+ char szDeviceNameBuffer[DEVICE_STRING_BUFF_SIZE + 1];
+ FT_HANDLE ftHandle;
+
+ if (lpDeviceName != NULL)
+ {
+ Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumDevices > 0)
+ {
+ if (dwDeviceIndex < dwNumDevices)
+ {
+ Status = FT_GetDeviceInfoDetail(FT2232CIndexes[dwDeviceIndex], &dwFlags, &dwDeviceType, &dwProductVendorID,
+ lpdwLocationID, szSerialNumber, szDeviceNameBuffer, &ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (strlen(szDeviceNameBuffer) <= dwBufferSize)
+ strcpy(lpDeviceName, szDeviceNameBuffer);
+ else
+ Status = FTC_DEVICE_NAME_BUFFER_TOO_SMALL;
+ }
+ }
+ else
+ Status = FTC_INVALID_DEVICE_NAME_INDEX;
+ }
+ else
+ Status = FTC_DEVICE_NOT_FOUND;
+ }
+ }
+ else
+ Status = FTC_NULL_DEVICE_NAME_BUFFER_POINTER;
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_OpenSpecifiedDevice(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE *pftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ FT_HANDLE ftHandle;
+
+ if (lpDeviceName != NULL)
+ {
+
+ // Caused driver to remove both devices loaded by ftdi_sio in /dev/
+ // We wish the second, /dev/ttyUSB1 to remain to connect a terminal
+ // program to it. - jb 090301
+ //Status = FTC_IsDeviceNameLocationIDValid(lpDeviceName, dwLocationID);
+
+ if (Status == FTC_SUCCESS)
+ {
+
+ if (!FTC_DeviceInUse(lpDeviceName, dwLocationID))
+ {
+
+ if (!FTC_DeviceOpened(lpDeviceName, dwLocationID, pftHandle))
+ {
+
+ // To open a device in Linux the FT_OPEN_BY_DESCRIPTION has to be used. Rene
+ Status = FT_OpenEx((PVOID)lpDeviceName, FT_OPEN_BY_DESCRIPTION, &ftHandle);
+ // Linux das not return the LocationID
+ // Status = FT_OpenEx((PVOID)dwLocationID, FT_OPEN_BY_LOCATION, &ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ *pftHandle = (DWORD)ftHandle;
+
+ FTC_InsertDeviceHandle(lpDeviceName, dwLocationID, *pftHandle);
+ }
+
+ }
+
+ }
+ else
+ Status = FTC_DEVICE_IN_USE;
+ }
+ }
+ else
+ Status = FTC_NULL_DEVICE_NAME_BUFFER_POINTER;
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_OpenDevice(FTC_HANDLE *pftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDevices = 0;
+ FT2232CDeviceIndexes FT2232CIndexes;
+ char szDeviceName[DEVICE_STRING_BUFF_SIZE + 1];
+ DWORD dwLocationID;
+
+ Status = FTC_GetNumDevices(&dwNumDevices, &FT2232CIndexes);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumDevices == 1)
+ {
+ Status = FTC_GetDeviceNameLocationID(FT2232CIndexes[0], szDeviceName, (DEVICE_STRING_BUFF_SIZE + 1), &dwLocationID);
+
+ if (Status == FTC_SUCCESS)
+ Status = FTC_OpenSpecifiedDevice(szDeviceName, dwLocationID, pftHandle);
+ }
+ else
+ {
+ if (dwNumDevices == 0)
+ Status = FTC_DEVICE_NOT_FOUND;
+ else
+ Status = FTC_TOO_MANY_DEVICES;
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_CloseDevice(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FT_Close((FT_HANDLE)ftHandle);
+
+ FTC_RemoveDeviceHandle(ftHandle);
+ }
+
+ return Status;
+}
+
+void FT2232c::FTC_GetClockFrequencyValues(DWORD dwClockFrequencyValue, LPDWORD lpdwClockFrequencyHz)
+{
+ *lpdwClockFrequencyHz = (BASE_CLOCK_FREQUENCY_12_MHZ / ((1 + dwClockFrequencyValue) * 2));
+}
+
+FTC_STATUS FT2232c::FTC_SetDeviceLoopbackState(FTC_HANDLE ftHandle, BOOL bLoopbackState)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+
+ Status = FTC_IsDeviceHandleValid(ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (bLoopbackState == false)
+ // turn off loopback
+ FTC_AddByteToOutputBuffer(TURN_OFF_LOOPBACK_CMD, true);
+ else
+ // turn on loopback
+ FTC_AddByteToOutputBuffer(TURN_ON_LOOPBACK_CMD, true);
+
+ FTC_SendBytesToDevice(ftHandle);
+ }
+
+ return Status;
+}
+
+void FT2232c::FTC_InsertDeviceHandle(LPSTR lpDeviceName, DWORD dwLocationID, FTC_HANDLE ftHandle)
+{
+ DWORD dwProcessId = 0;
+ INT iDeviceCntr = 0;
+ BOOLEAN bDeviceftHandleInserted = false;
+
+ if (uiNumOpenedDevices < MAX_NUM_DEVICES)
+ {
+ //dwProcessId = GetCurrentProcessId();
+ dwProcessId = getpid(); //Changed windows call to linux\s getpid()
+
+ for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bDeviceftHandleInserted); iDeviceCntr++)
+ {
+ if (OpenedDevices[iDeviceCntr].dwProcessId == 0)
+ {
+ OpenedDevices[iDeviceCntr].dwProcessId = dwProcessId;
+ strcpy(OpenedDevices[iDeviceCntr].szDeviceName, lpDeviceName);
+ OpenedDevices[iDeviceCntr].dwLocationID = dwLocationID;
+ OpenedDevices[iDeviceCntr].hDevice = ftHandle;
+
+ uiNumOpenedDevices = uiNumOpenedDevices + 1;
+
+ bDeviceftHandleInserted = true;
+ }
+ }
+ }
+}
+
+FTC_STATUS FT2232c::FTC_IsDeviceHandleValid(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwProcessId = 0;
+ INT iDeviceCntr = 0;
+ BOOLEAN bDevicempHandleFound = false;
+
+ if ((uiNumOpenedDevices > 0) && (ftHandle > 0))
+ {
+ //dwProcessId = GetCurrentProcessId();
+ dwProcessId = getpid(); //Changed windows call to linux\s getpid()
+
+ for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bDevicempHandleFound); iDeviceCntr++)
+ {
+ if (OpenedDevices[iDeviceCntr].dwProcessId == dwProcessId)
+ {
+ if (OpenedDevices[iDeviceCntr].hDevice == ftHandle)
+ bDevicempHandleFound = true;
+ }
+ }
+
+ if (!bDevicempHandleFound)
+ Status = FTC_INVALID_HANDLE;
+ }
+ else
+ Status = FTC_INVALID_HANDLE;
+
+ return Status;
+}
+
+
+void FT2232c::FTC_RemoveDeviceHandle(FTC_HANDLE ftHandle)
+{
+ DWORD dwProcessId = 0;
+ INT iDeviceCntr = 0;
+ BOOLEAN bDevicempHandleFound = false;
+
+ if (uiNumOpenedDevices > 0)
+ {
+ //dwProcessId = GetCurrentProcessId();
+ dwProcessId = getpid(); //Changed windows call to linux\s getpid()
+
+ for (iDeviceCntr = 0; ((iDeviceCntr < MAX_NUM_DEVICES) && !bDevicempHandleFound); iDeviceCntr++)
+ {
+ if (OpenedDevices[iDeviceCntr].dwProcessId == dwProcessId)
+ {
+ if (OpenedDevices[iDeviceCntr].hDevice == ftHandle)
+ {
+ OpenedDevices[iDeviceCntr].dwProcessId = 0;
+ strcpy(OpenedDevices[iDeviceCntr].szDeviceName, "");
+ OpenedDevices[iDeviceCntr].dwLocationID = 0;
+ OpenedDevices[iDeviceCntr].hDevice = 0;
+
+ uiNumOpenedDevices = uiNumOpenedDevices - 1;
+
+ bDevicempHandleFound = true;
+ }
+ }
+ }
+ }
+}
+
+FTC_STATUS FT2232c::FTC_ResetUSBDevicePurgeUSBInputBuffer(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ InputByteBuffer InputBuffer;
+ DWORD dwNumBytesRead = 0;
+ DWORD dwNumBytesDeviceInputBuffer;
+
+ Status = FT_ResetDevice((FT_HANDLE)ftHandle);
+
+ if (Status == FTC_SUCCESS)
+ {
+ // Get the number of bytes in the device input buffer
+ Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumBytesDeviceInputBuffer > 0)
+ FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+ }
+ }
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_SetDeviceUSBBufferSizes(FTC_HANDLE ftHandle, DWORD InputBufferSize, DWORD OutputBufferSize)
+{
+ return FT_SetUSBParameters((FT_HANDLE)ftHandle, InputBufferSize, OutputBufferSize);
+}
+
+FTC_STATUS FT2232c::FTC_SetDeviceSpecialCharacters(FTC_HANDLE ftHandle, BOOLEAN bEventEnabled, UCHAR EventCharacter,
+ BOOLEAN bErrorEnabled, UCHAR ErrorCharacter)
+{
+ UCHAR EventCharEnabled = UCHAR(bEventEnabled);
+ UCHAR ErrorCharEnabled = UCHAR(bErrorEnabled);
+
+ // Set the special characters for the device. disable event and error characters
+ return FT_SetChars((FT_HANDLE)ftHandle, EventCharacter, EventCharEnabled, ErrorCharacter, ErrorCharEnabled);
+}
+
+FTC_STATUS FT2232c::FTC_SetReadWriteDeviceTimeouts(FTC_HANDLE ftHandle, DWORD dwReadTimeoutmSec, DWORD dwWriteTimeoutmSec)
+{
+ // Sets the read and write timeouts in milli-seconds for the device
+ return FT_SetTimeouts((FT_HANDLE)ftHandle, dwReadTimeoutmSec, dwWriteTimeoutmSec);
+}
+
+FTC_STATUS FT2232c::FTC_SetDeviceLatencyTimer(FTC_HANDLE ftHandle, BYTE LatencyTimermSec)
+{
+ // Set the device latency timer to a number of milliseconds
+ return FT_SetLatencyTimer((FT_HANDLE)ftHandle, LatencyTimermSec);
+}
+
+FTC_STATUS FT2232c::FTC_ResetMPSSEInterface(FTC_HANDLE ftHandle)
+{
+ return FT_SetBitMode((FT_HANDLE)ftHandle, MPSSE_INTERFACE_MASK, RESET_MPSSE_INTERFACE);
+}
+
+FTC_STATUS FT2232c::FTC_EnableMPSSEInterface(FTC_HANDLE ftHandle)
+{
+ return FT_SetBitMode((FT_HANDLE)ftHandle, MPSSE_INTERFACE_MASK, ENABLE_MPSSE_INTERFACE);
+}
+
+FTC_STATUS FT2232c::FTC_SendReceiveCommandFromMPSSEInterface(FTC_HANDLE ftHandle, BOOLEAN bSendEchoCommandContinuouslyOnce, BYTE EchoCommand, LPBOOL lpbCommandEchod)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumBytesDeviceInputBuffer = 0;
+ //SYSTEMTIME StartTime;
+ InputByteBuffer InputBuffer;
+ DWORD dwNumBytesRead = 0;
+ DWORD dwByteCntr = 0;
+ BOOL bBadCommandResponse = false;
+
+ // New timeout detection variables for linux build -- Julius
+ struct timeval tv;
+ time_t time_start; // to store number of seconds since unix epoch
+
+
+ *lpbCommandEchod = false;
+
+ if (!bSendEchoCommandContinuouslyOnce)
+ {
+ // Causes the device to echo back the command character and wait in command mode
+ FTC_AddByteToOutputBuffer(EchoCommand, true);
+ FTC_SendBytesToDevice(ftHandle);
+ }
+
+ // Windows only time functions - removed for linux library build -- Julius
+ //GetLocalTime(&StartTime);
+ gettimeofday(&tv, NULL);
+ time_start = tv.tv_sec;
+
+ do
+ {
+ // Send the echo command every time round the loop
+ if (bSendEchoCommandContinuouslyOnce)
+ {
+ // Causes the device to echo back the command character and wait in command mode
+ FTC_AddByteToOutputBuffer(EchoCommand, true);
+ FTC_SendBytesToDevice(ftHandle);
+ }
+
+ // Get the number of bytes in the device input buffer
+ Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ //Sleep(0); // give up timeslice - not exist in linux!
+ // perhaps #include and do a sched_yield();
+ // This basically checks if the time we took from the first GetLocalTime was bigger than
+ // MAX_COMMAND_TIMEOUT_PERIOD
+ //if (FTC_Timeout(StartTime, MAX_COMMAND_TIMEOUT_PERIOD))
+ gettimeofday(&tv, NULL);
+ if ((tv.tv_sec - time_start) > (MAX_COMMAND_TIMEOUT_PERIOD/1000))
+ Status = FTC_FAILED_TO_COMPLETE_COMMAND;
+
+
+
+ }
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumBytesDeviceInputBuffer > 0)
+ {
+ FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ if (dwNumBytesRead > 0)
+ {
+ dwByteCntr = 0;
+
+ do
+ {
+ if (dwByteCntr <= (dwNumBytesRead - 1))
+ {
+ if (InputBuffer[dwByteCntr] == BAD_COMMAND_RESPONSE)
+ bBadCommandResponse = true;
+ else
+ {
+ if (bBadCommandResponse == TRUE)
+ {
+ if (InputBuffer[dwByteCntr] == EchoCommand)
+ *lpbCommandEchod = true;
+ }
+
+ bBadCommandResponse = false;
+ }
+ }
+
+ dwByteCntr = dwByteCntr + 1;
+ }
+ while ((dwByteCntr < dwNumBytesRead) && (*lpbCommandEchod == false));
+ }
+ }
+ }
+ }
+ while ((*lpbCommandEchod == false) && (Status == FTC_SUCCESS));
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_SynchronizeMPSSEInterface(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumBytesDeviceInputBuffer = 0;
+ InputByteBuffer InputBuffer;
+ DWORD dwNumBytesRead = 0;
+ BOOL bCommandEchod = false;
+
+ // Get the number of bytes in the device input buffer
+ Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (dwNumBytesDeviceInputBuffer > 0)
+ FTC_ReadBytesFromDevice(ftHandle, &InputBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ Status = FTC_SendReceiveCommandFromMPSSEInterface(ftHandle, TRUE, AA_ECHO_CMD_1, &bCommandEchod);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (bCommandEchod == TRUE)
+ {
+ Status = FTC_SendReceiveCommandFromMPSSEInterface(ftHandle, FALSE, AB_ECHO_CMD_2, &bCommandEchod);
+
+ if (Status == FTC_SUCCESS)
+ {
+ if (bCommandEchod == false)
+ Status = FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE;
+ }
+ }
+ else
+ Status = FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE;
+ }
+ }
+
+ return Status;
+}
+
+/*
+BOOLEAN FT2232c::FTC_Timeout(SYSTEMTIME StartSystemTime, DWORD dwTimeoutmSecs)
+{
+ BOOLEAN bTimoutExpired = false;
+ FILETIME StartFileTime;
+ ULARGE_INTEGER StartTime;
+ SYSTEMTIME EndSystemTime;
+ FILETIME EndFileTime;
+ ULARGE_INTEGER EndTime;
+ ULONGLONG ulTimeoutmSecs = dwTimeoutmSecs * CONVERT_1MS_TO_100NS; //10000;
+
+ GetLocalTime(&EndSystemTime);
+
+ SystemTimeToFileTime(&StartSystemTime, &StartFileTime);
+
+ StartTime.LowPart = StartFileTime.dwLowDateTime;
+ StartTime.HighPart = StartFileTime.dwHighDateTime;
+
+ SystemTimeToFileTime(&EndSystemTime, &EndFileTime);
+
+ EndTime.LowPart = EndFileTime.dwLowDateTime;
+ EndTime.HighPart = EndFileTime.dwHighDateTime;
+
+ if ((EndTime.QuadPart - StartTime.QuadPart) > ulTimeoutmSecs)
+ bTimoutExpired = true;
+
+ return bTimoutExpired;
+ }*/
+
+FTC_STATUS FT2232c::FTC_GetNumberBytesFromDeviceInputBuffer(FTC_HANDLE ftHandle, LPDWORD lpdwNumBytesDeviceInputBuffer)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ //SYSTEMTIME StartTime;
+
+ // New timeout detection variables for linux build -- Julius
+ struct timeval tv;
+ time_t time_start; // to store number of seconds since unix epoch
+
+
+ // Windows only time functions - removed for linux library build -- Julius
+ //GetLocalTime(&StartTime);
+ gettimeofday(&tv, NULL);
+ time_start = tv.tv_sec;
+
+
+ do
+ {
+ // Get the number of bytes in the device input buffer
+ Status = FT_GetQueueStatus((FT_HANDLE)ftHandle, lpdwNumBytesDeviceInputBuffer);
+
+ if (Status == FTC_SUCCESS)
+ {
+ //Sleep(0); // give up timeslice - not exist in linux!
+ // perhaps #include and do a sched_yield();
+ // This basically checks if the time we took from the first GetLocalTime was bigger than
+ // MAX_COMMAND_TIMEOUT_PERIOD
+ //if (FTC_Timeout(StartTime, MAX_COMMAND_TIMEOUT_PERIOD))
+ gettimeofday(&tv, NULL);
+ if ((tv.tv_sec - time_start) > (MAX_COMMAND_TIMEOUT_PERIOD / 1000))
+ Status = FTC_FAILED_TO_COMPLETE_COMMAND;
+ }
+ }
+ while ((*lpdwNumBytesDeviceInputBuffer == 0) && (Status == FTC_SUCCESS));
+
+ return Status;
+}
+
+void FT2232c::FTC_ClearOutputBuffer(void)
+{
+ dwNumBytesToSend = 0;
+}
+
+void FT2232c::FTC_AddByteToOutputBuffer(DWORD dwOutputByte, BOOL bClearOutputBuffer)
+{
+ if (bClearOutputBuffer == TRUE)
+ dwNumBytesToSend = 0;
+
+ OutputBuffer[dwNumBytesToSend] = (dwOutputByte & '\xFF');
+
+ dwNumBytesToSend = dwNumBytesToSend + 1;
+}
+
+DWORD FT2232c::FTC_GetNumBytesInOutputBuffer(void)
+{
+ return dwNumBytesToSend;
+}
+
+FTC_STATUS FT2232c::FTC_SendBytesToDevice(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDataBytesToSend = 0;
+ DWORD dwNumBytesSent = 0;
+ DWORD dwTotalNumBytesSent = 0;
+
+ if (dwNumBytesToSend > MAX_NUM_BYTES_USB_WRITE)
+ {
+ do
+ {
+ // 25/08/05 - Can only use 4096 byte block as Windows 2000 Professional does not allow you to alter the USB buffer size
+ // 25/08/05 - Windows 2000 Professional always sets the USB buffer size to 4K ie 4096
+ if ((dwTotalNumBytesSent + MAX_NUM_BYTES_USB_WRITE) <= dwNumBytesToSend)
+ dwNumDataBytesToSend = MAX_NUM_BYTES_USB_WRITE;
+ else
+ dwNumDataBytesToSend = (dwNumBytesToSend - dwTotalNumBytesSent);
+
+ // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of
+ // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains
+ // the actual number of bytes sent to a FT2232C dual type device.
+ Status = FT_Write((FT_HANDLE)ftHandle, &OutputBuffer[dwTotalNumBytesSent], dwNumDataBytesToSend, &dwNumBytesSent);
+
+ dwTotalNumBytesSent = dwTotalNumBytesSent + dwNumBytesSent;
+ }
+ while ((dwTotalNumBytesSent < dwNumBytesToSend) && (Status == FTC_SUCCESS));
+ }
+ else
+ {
+ // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of
+ // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains
+ // the actual number of bytes sent to a FT2232C dual type device.
+ Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
+ }
+
+
+ dwNumBytesToSend = 0;
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_ReadBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
+ DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead)
+{
+ // This function reads data from a FT2232C dual type device. The dwNumBytesToRead variable specifies the maximum
+ // number of bytes to be read from a FT2232C dual type device. The lpdwNumBytesRead variable contains the actual
+ // number of bytes read from a FT2232C dual type device, which may range from zero to the actual number of bytes
+ // requested, depending on how many have been received at the time of the request + the read timeout value.
+ // The bytes read from a FT2232C dual type device, will be returned in the input buffer.
+ return FT_Read((FT_HANDLE)ftHandle, InputBuffer, dwNumBytesToRead, lpdwNumBytesRead);
+}
+
+FTC_STATUS FT2232c::FTC_ReadFixedNumBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
+ DWORD dwNumBytesToRead, LPDWORD lpdwNumDataBytesRead)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumBytesDeviceInputBuffer = 0;
+ InputByteBuffer TmpInputByteBuffer;
+ DWORD dwNumBytesRead = 0;
+ DWORD dwBytesReadIndex = 0;
+
+ do
+ {
+ Status = FTC_GetNumberBytesFromDeviceInputBuffer(ftHandle, &dwNumBytesDeviceInputBuffer);
+
+ if ((Status == FTC_SUCCESS) && (dwNumBytesDeviceInputBuffer > 0))
+ {
+ Status = FTC_ReadBytesFromDevice(ftHandle, &TmpInputByteBuffer, dwNumBytesDeviceInputBuffer, &dwNumBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ for (dwBytesReadIndex = 0 ; dwBytesReadIndex < dwNumBytesRead; dwBytesReadIndex++)
+ {
+ (*InputBuffer)[*lpdwNumDataBytesRead] = TmpInputByteBuffer[dwBytesReadIndex];
+ *lpdwNumDataBytesRead = (*lpdwNumDataBytesRead + 1);
+ }
+ }
+ }
+ }
+ while ((*lpdwNumDataBytesRead < dwNumBytesToRead) && (Status == FTC_SUCCESS));
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_SendReadBytesToFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
+ DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumBytesSent = 0;
+ DWORD dwNumControlSendBytes = 0;
+ DWORD dwNumDataBytesRead = 0;
+
+ if (dwNumBytesToSend > MAX_NUM_BYTES_USB_WRITE_READ)
+ {
+ // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of
+ // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains
+ // the actual number of bytes sent to a FT2232C dual type device.
+ Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, MAX_NUM_BYTES_USB_WRITE_READ, &dwNumBytesSent);
+
+ if (Status == FTC_SUCCESS)
+ {
+ dwNumControlSendBytes = (dwNumBytesToSend - dwNumBytesToRead);
+
+ Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, (MAX_NUM_BYTES_USB_WRITE_READ - dwNumControlSendBytes), &dwNumDataBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FT_Write((FT_HANDLE)ftHandle, &OutputBuffer[dwNumBytesSent], (dwNumBytesToSend - dwNumBytesSent), &dwNumBytesSent);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, (dwNumBytesToRead - dwNumDataBytesRead), &dwNumDataBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ *lpdwNumBytesRead = dwNumDataBytesRead;
+ }
+ }
+ }
+ }
+ else
+ {
+ // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of
+ // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains
+ // the actual number of bytes sent to a FT2232C dual type device.
+ Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
+
+ if (Status == FTC_SUCCESS)
+ {
+ Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, dwNumBytesToRead, &dwNumDataBytesRead);
+
+ if (Status == FTC_SUCCESS)
+ *lpdwNumBytesRead = dwNumDataBytesRead;
+ }
+ }
+
+ dwNumBytesToSend = 0;
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_SendCommandsSequenceToDevice(FTC_HANDLE ftHandle)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDataBytesToSend = 0;
+ DWORD dwNumBytesSent = 0;
+ DWORD dwTotalNumBytesSent = 0;
+
+ if (dwNumBytesToSend > MAX_NUM_BYTES_USB_WRITE)
+ {
+ do
+ {
+ if ((dwTotalNumBytesSent + MAX_NUM_BYTES_USB_WRITE) <= dwNumBytesToSend)
+ dwNumDataBytesToSend = MAX_NUM_BYTES_USB_WRITE;
+ else
+ dwNumDataBytesToSend = (dwNumBytesToSend - dwTotalNumBytesSent);
+
+ // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of
+ // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains
+ // the actual number of bytes sent to a FT2232C dual type device.
+ Status = FT_Write((FT_HANDLE)ftHandle, &OutputBuffer[dwTotalNumBytesSent], dwNumDataBytesToSend, &dwNumBytesSent);
+
+ dwTotalNumBytesSent = dwTotalNumBytesSent + dwNumBytesSent;
+ }
+ while ((dwTotalNumBytesSent < dwNumBytesToSend) && (Status == FTC_SUCCESS));
+ }
+ else
+ {
+ // This function sends data to a FT2232C dual type device. The dwNumBytesToSend variable specifies the number of
+ // bytes in the output buffer to be sent to a FT2232C dual type device. The dwNumBytesSent variable contains
+ // the actual number of bytes sent to a FT2232C dual type device.
+ Status = FT_Write((FT_HANDLE)ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent);
+ }
+
+ dwNumBytesToSend = 0;
+
+ return Status;
+}
+
+FTC_STATUS FT2232c::FTC_ReadCommandsSequenceBytesFromDevice(FTC_HANDLE ftHandle, PInputByteBuffer InputBuffer,
+ DWORD dwNumBytesToRead, LPDWORD lpdwNumBytesRead)
+{
+ FTC_STATUS Status = FTC_SUCCESS;
+ DWORD dwNumDataBytesToRead = 0;
+ DWORD dwNumBytesRead = 0;
+ DWORD dwTotalNumBytesRead = 0;
+
+ if (dwNumBytesToRead > MAX_NUM_BYTES_USB_READ)
+ {
+ do
+ {
+ if ((dwTotalNumBytesRead + MAX_NUM_BYTES_USB_WRITE_READ) <= dwNumBytesToRead)
+ dwNumDataBytesToRead = MAX_NUM_BYTES_USB_WRITE_READ;
+ else
+ dwNumDataBytesToRead = (dwNumBytesToRead - dwTotalNumBytesRead);
+
+ Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, dwNumDataBytesToRead, &dwNumBytesRead);
+
+ dwTotalNumBytesRead = dwTotalNumBytesRead + dwNumBytesRead;
+ }
+ while ((dwTotalNumBytesRead < dwNumBytesToRead) && (Status == FTC_SUCCESS));
+
+ *lpdwNumBytesRead = dwTotalNumBytesRead;
+ }
+ else
+ Status = FTC_ReadFixedNumBytesFromDevice(ftHandle, InputBuffer, dwNumBytesToRead, lpdwNumBytesRead);
+
+ return Status;
+}
+
+
+// Define strupr and strlwr - not included in standard gcc libraries
+
+
+//#if defined(__cplusplus) && __cplusplus
+// extern "C" {
+//#endif
+
+char* strupr(char *string)
+{
+ char *s;
+
+ if (string)
+ {
+ for (s = string; *s; ++s)
+ *s = toupper(*s);
+ }
+ return string;
+}
+
+char* strlwr(char *string)
+{
+ char *s;
+
+ if (string)
+ {
+ for (s = string; *s; ++s)
+ *s = tolower(*s);
+ }
+ return string;
+}
+
+//#if defined(__cplusplus) && __cplusplus
+//}
+//#endif
Index: or_debug_proxy/src/vpi_functions.c
===================================================================
--- or_debug_proxy/src/vpi_functions.c (nonexistent)
+++ or_debug_proxy/src/vpi_functions.c (revision 1779)
@@ -0,0 +1,613 @@
+/*$$HEADER*/
+/******************************************************************************/
+/* */
+/* H E A D E R I N F O R M A T I O N */
+/* */
+/******************************************************************************/
+
+// Project Name : OpenRISC Debug Proxy
+// File Name : vpi_functions.c
+// Prepared By : jb
+// Project Start : 2008-10-01
+
+/*$$COPYRIGHT NOTICE*/
+/******************************************************************************/
+/* */
+/* C O P Y R I G H T N O T I C E */
+/* */
+/******************************************************************************/
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License, a copy of which is available from
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*$$DESCRIPTION*/
+/******************************************************************************/
+/* */
+/* D E S C R I P T I O N */
+/* */
+/******************************************************************************/
+//
+// Implements communications with a Verilog RTL simulation via functions running
+// in the simulator, attached via VPI.
+//
+
+
+/*$$CHANGE HISTORY*/
+/******************************************************************************/
+/* */
+/* C H A N G E H I S T O R Y */
+/* */
+/******************************************************************************/
+
+// Date Version Description
+//------------------------------------------------------------------------
+// 081101 First revision jb
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "gdb.h"
+
+#include "or_debug_proxy.h"
+
+#include "vpi_functions.h"
+
+// Definition of MSG_WAITALL -- appears to be missing from Cygwin's sys/socket.h
+#ifdef CYGWIN_COMPILE
+#define MSG_WAITALL 0
+#endif
+
+// socket stuff for connection to the VPI interface
+int vpiPort = VPI_PORT;
+int vpi_fd; // should be the descriptor for our connection to the VPI server
+
+#ifdef RTL_SIM
+#define DBG_VPI 1
+#else
+#define DBG_VPI 0
+#endif
+
+//Protocol ensuring synchronisation with the jp-rtl_sim program
+
+// 1. jp-rtl_sim will first write a command byte
+// 2. jp-rtl_sim will then send the address if it's a read or write
+// or the data to write if it's a dbg_cpu_wr_ctrl (stall & reset bits)
+// 3. will then send data if we're writing and we sent address in 2
+// 4. wait for response from vpi functions
+
+// commands:
+// 4'h1 jtag set instruction register (input: instruction value)
+// 4'h2 set debug chain (dbg_set_command here) (input: chain value)
+// 4'h3 cpu_ctrl_wr (input: ctrl value (2 bits))
+// 4'h4 cpu_ctrl_rd (output: ctrl value (2bits))
+// 4'h5 cpu wr reg (inputs: address, data)
+// 4'h6 cpu rd reg (input: address; output: data)
+// 4'h7 wb wr 32 (inputs: address, data)
+// 4'h8 wb rd 32 (input: address; output: data)
+// 4'h9 wb wr block 32 (inputs: address, length, data)
+// 4'ha wb rd block 32 (inputs: address, length; output: data)
+// 4'hb reset
+// 4'hc read jtag id (output: data)
+
+#define CMD_JTAG_SET_IR 0x1
+#define CMD_SET_DEBUG_CHAIN 0x2
+#define CMD_CPU_CTRL_WR 0x3
+#define CMD_CPU_CTRL_RD 0x4
+#define CMD_CPU_WR_REG 0x5
+#define CMD_CPU_RD_REG 0x6
+#define CMD_WB_WR32 0x7
+#define CMD_WB_RD32 0x8
+#define CMD_WB_BLOCK_WR32 0x9
+#define CMD_WB_BLOCK_RD32 0xa
+#define CMD_RESET 0xb
+#define CMD_READ_JTAG_ID 0xc
+
+
+void send_command_to_vpi(char CMD)
+{
+ // first thing we do is send a command
+ // and wait for an ack
+ uint32_t n;
+ char cmd_resp;
+
+ n = write(vpi_fd,&CMD, 1); // send the command to the sim
+
+ if (n < 0) perror("ERROR writing to VPI socket");
+
+ n = recv(vpi_fd,&cmd_resp,1, MSG_WAITALL); // block and wait for the ack
+
+ if (n < 0) perror("ERROR Reading from VPI socket");
+
+ if (cmd_resp != CMD) perror("Response from RTL sim incorrect"); //check it acked with cmd
+
+ return;
+}
+
+void send_address_to_vpi(uint32_t address)
+{
+ // Now send address
+ uint32_t n;
+
+ char* send_buf;
+
+ address = htonl(address);
+
+ send_buf = (char *) &address;
+
+ n = write(vpi_fd,send_buf, 4); // send the address to the sim
+
+ if (n < 0) perror("ERROR writing to VPI socket");
+
+ return;
+}
+
+void send_data_to_vpi(uint32_t data)
+{
+ // Now send data
+ uint32_t n;
+
+ data = htonl(data);
+
+ char* send_buf;
+
+ send_buf = (char *) &data;
+
+ n = write(vpi_fd,send_buf, 4); // Write the data to the socket
+
+ if (n < 0) perror("ERROR writing to VPI socket");
+
+ return;
+
+}
+
+void send_block_data_to_vpi(uint32_t len, uint32_t *data)
+{
+ // Now send data
+ uint32_t n, i;
+
+ for (i = 0; i < (len/4); i++)
+ data[i] = htonl(data[i]);
+
+ char* send_buf;
+
+ send_buf = (char *) data;
+
+ n = write(vpi_fd,send_buf, len); // Write the data to the socket
+
+ if (n < 0) perror("ERROR writing to VPI socket");
+
+ return;
+
+}
+
+void get_data_from_vpi(uint32_t* data)
+{
+
+ uint32_t n;
+
+ uint32_t inc_data;
+
+ char* recv_buf;
+
+ recv_buf = (char*) &inc_data;
+
+ n = recv(vpi_fd,recv_buf,4, MSG_WAITALL); // block and wait for the data
+
+ if (n < 0) perror("ERROR Reading from VPI socket");
+
+ inc_data = ntohl(inc_data);
+
+ if (DBG_VPI) printf("get_data_from_vpi: 0x%.8x\n",inc_data);
+
+ *data = inc_data;
+
+ return;
+
+}
+
+void get_block_data_from_vpi(uint32_t len, uint32_t* data)
+{
+ uint32_t n, i;
+
+ char* recv_buf;
+
+ recv_buf = (char *) data;
+
+ n = recv(vpi_fd, recv_buf, len, MSG_WAITALL); // block and wait for the data
+
+ if (n < 0) perror("ERROR Reading from VPI socket");
+
+ // re-order host compliant style the recieved words
+ if (DBG_VPI) printf("get_block_data_from_vpi: %d bytes",len);
+ for (i = 0;i < (len/4); i++)
+ {
+ data[i] = ntohl(data[i]);
+
+ if (DBG_VPI) printf("0x%.8x ",data[i]);
+ }
+ if (DBG_VPI) printf("\n");
+
+ return;
+
+}
+
+void get_response_from_vpi()
+{
+ // Basically just wait for the response from VPI
+ // by blocking wait on recv
+
+ uint32_t n;
+ char tmp;
+
+ n = recv(vpi_fd,&tmp,1, MSG_WAITALL); // block and wait
+
+ if (n < 0) perror("ERROR Reading from VPI socket");
+
+ return;
+}
+
+/* Resets JTAG
+ Writes TRST=0
+ and TRST=1 */
+static void jp2_reset_JTAG() {
+
+ debug2("\nreset(");
+
+ send_command_to_vpi(CMD_RESET);
+
+ get_response_from_vpi();
+
+ debug2(")\n");
+
+}
+
+
+int vpi_connect() {
+ int sockfd;
+ struct sockaddr_in serv_addr;
+ struct hostent *server;
+ socklen_t flags;
+ char sTemp[256];
+
+ debug2("Started vpi_connect()\n");
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ //sockfd = socket(PF_INET, SOCK_STREAM, 0);
+
+ if (sockfd < 0) {
+ perror("ERROR opening socket");
+ goto socket_setup_exit;
+ }
+
+ server = gethostbyname("localhost");
+
+ if (server == NULL) {
+ fprintf(stderr,"ERROR, no such host\n");
+ goto socket_setup_exit;
+ }
+
+ /*
+ if(fcntl(sockfd, F_GETFL, &flags) < 0) {
+ sprintf(sTemp, "Unable to get flags for socket %d", sockfd);
+ perror(sTemp);
+ close(sockfd);
+ goto socket_setup_exit;
+ }
+
+ // Set the nonblocking flag
+ if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x",
+ sockfd, flags | O_NONBLOCK);
+ perror(sTemp);
+ close(sockfd);
+ goto socket_setup_exit;
+ }
+ */
+
+ bzero((char *) &serv_addr, sizeof(serv_addr));
+
+ serv_addr.sin_family = AF_INET;
+
+ bcopy(server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
+
+ serv_addr.sin_port = htons(vpiPort);
+
+ printf("Initialising connection with simulation\n");
+
+ if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
+ {
+ perror("Error connecting");
+ goto socket_setup_exit;
+ }
+
+ return sockfd;
+
+ socket_setup_exit:
+ if (vpi_fd) close(vpi_fd);
+ exit(1);
+
+}
+
+/* Resets JTAG, and sets DEBUG scan chain */
+ int vpi_dbg_reset() {
+
+ uint32_t id;
+
+ jp2_reset_JTAG();
+
+ /* set idcode jtag chain */
+ send_command_to_vpi(CMD_JTAG_SET_IR);
+
+ send_data_to_vpi(JI_IDCODE);
+
+ get_response_from_vpi();
+
+ /* now read out the jtag id */
+ send_command_to_vpi(CMD_READ_JTAG_ID);
+
+ //id = get_data_from_vpi();
+ get_data_from_vpi((uint32_t *)&id);
+
+ get_response_from_vpi();
+
+ printf("JTAG ID = %08x\n", (unsigned int) id);
+
+ /* now set the chain to debug */
+ send_command_to_vpi(CMD_JTAG_SET_IR);
+
+ send_data_to_vpi(JI_DEBUG);
+
+ get_response_from_vpi();
+
+ current_chain = -1;
+ return DBG_ERR_OK;
+}
+
+void vpi_dbg_test() {
+
+ uint32_t npc, ppc, r1;
+ unsigned char stalled;
+
+ printf(" Stall or1k\n");
+ dbg_cpu0_write_ctrl(0, 0x01); // stall or1k
+
+ dbg_cpu0_read_ctrl(0, &stalled);
+ if (!(stalled & 0x1)) {
+ printf(" or1k stall failed. Exiting\n"); // check stall or1k
+ if (vpi_fd) close(vpi_fd);
+ exit(1);
+ }
+
+ debug2(" Reading npc\n");
+ dbg_cpu0_read((0 << 11) + 16, &npc);
+ debug2(" Reading ppc\n");
+ dbg_cpu0_read((0 << 11) + 18, &ppc);
+ debug2(" Reading r1\n");
+ dbg_cpu0_read(0x401, &r1);
+ printf(" Read npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1);
+
+}
+
+/* Sets scan chain. */
+int vpi_dbg_set_chain(uint32_t chain) {
+ //uint32_t status, crc_generated, crc_read;
+
+ if (current_chain == chain)
+ return DBG_ERR_OK;
+
+ dbg_chain = chain;
+
+ send_command_to_vpi(CMD_SET_DEBUG_CHAIN);
+
+ send_data_to_vpi(chain);
+
+ get_response_from_vpi();
+
+ current_chain = chain;
+
+ return DBG_ERR_OK;
+}
+
+/* writes a ctrl reg */
+int vpi_dbg_ctrl(uint32_t reset, uint32_t stall)
+{
+
+ debug("\n");
+ debug2("ctrl\n");
+
+ vpi_dbg_set_chain(dbg_chain);
+
+ send_command_to_vpi(CMD_CPU_CTRL_WR);
+
+ //send_data_to_vpi(((reset & 0x1) | ((stall&0x1)<<1)));
+ send_data_to_vpi(((stall & 0x1) | ((reset&0x1)<<1)));
+
+ get_response_from_vpi();
+
+ return DBG_ERR_OK;
+}
+
+/* reads control register */
+int vpi_dbg_ctrl_read(uint32_t *reset, uint32_t *stall)
+{
+
+ uint32_t resp;
+
+ vpi_dbg_set_chain(dbg_chain);
+
+ debug("\n");
+ debug2("ctrl\n");
+
+ vpi_dbg_set_chain(dbg_chain);
+
+ send_command_to_vpi(CMD_CPU_CTRL_RD);
+
+ get_data_from_vpi((uint32_t *)&resp);
+
+ if (DBG_VPI) printf(" dbg_ctrl_read: 0x%.8x\n",resp);
+
+ get_response_from_vpi();
+
+ *reset = (resp & 0x00000001);
+
+ *stall = ((resp >> 1) & 0x00000001);
+
+ return DBG_ERR_OK;
+}
+
+/* read a word from wishbone */
+int vpi_dbg_wb_read32(uint32_t adr, uint32_t *data)
+{
+ //uint32_t resp;
+
+ vpi_dbg_set_chain(DC_WISHBONE);
+
+ send_command_to_vpi(CMD_WB_RD32);
+
+ send_address_to_vpi(adr);
+
+ get_data_from_vpi(data);
+
+ get_response_from_vpi();
+
+ return 0;
+}
+
+/* write a word to wishbone */
+int vpi_dbg_wb_write32(uint32_t adr, uint32_t data)
+{
+
+ vpi_dbg_set_chain(DC_WISHBONE);
+
+ send_command_to_vpi(CMD_WB_WR32);
+
+ send_address_to_vpi(adr);
+
+ send_data_to_vpi(data);
+
+ get_response_from_vpi();
+
+ return 0;
+}
+
+/* read a block from wishbone */
+int vpi_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len)
+{
+
+ // len is in B Y T E S ! !
+
+ if (DBG_VPI) printf("block read len: %d from addr: 0x%.8x\n",len, adr);
+
+ vpi_dbg_set_chain(DC_WISHBONE);
+
+ send_command_to_vpi(CMD_WB_BLOCK_RD32);
+
+ send_data_to_vpi(adr);
+
+ send_data_to_vpi(len);
+
+ get_block_data_from_vpi(len, data);
+
+ get_response_from_vpi();
+
+ return DBG_ERR_OK;
+}
+
+/* write a block to wishbone */
+int vpi_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len)
+{
+
+ vpi_dbg_set_chain(DC_WISHBONE);
+
+ send_command_to_vpi(CMD_WB_BLOCK_WR32);
+
+ send_data_to_vpi(adr);
+
+ send_data_to_vpi(len);
+
+ send_block_data_to_vpi(len, data);
+
+ get_response_from_vpi();
+
+ return DBG_ERR_OK;
+}
+
+/* read a register from cpu */
+int vpi_dbg_cpu0_read(uint32_t adr, uint32_t *data)
+{
+
+ vpi_dbg_set_chain(DC_CPU0);
+
+ send_command_to_vpi(CMD_CPU_RD_REG);
+
+ send_address_to_vpi(adr);
+
+ get_data_from_vpi(data);
+
+ get_response_from_vpi();
+
+ return 0;
+
+}
+
+/* write a cpu register */
+int vpi_dbg_cpu0_write(uint32_t adr, uint32_t data)
+{
+
+ vpi_dbg_set_chain(DC_CPU0);
+
+ send_command_to_vpi(CMD_CPU_WR_REG);
+
+ send_address_to_vpi(adr);
+
+ send_data_to_vpi(data);
+
+ get_response_from_vpi();
+
+ return 0;
+}
+
+
+/* write a cpu module register */
+int vpi_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) {
+ uint32_t err;
+ if ((err = vpi_dbg_set_chain(DC_CPU0))) return err;
+ if ((err = vpi_dbg_ctrl(data & 2, data &1))) return err;
+ return DBG_ERR_OK;
+}
+
+/* read a register from cpu module */
+int vpi_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) {
+ uint32_t err;
+ uint32_t r, s;
+ if ((err = vpi_dbg_set_chain(DC_CPU0))) return err;
+ if ((err = vpi_dbg_ctrl_read(&r, &s))) return err;
+ *data = (r << 1) | s;
+ return DBG_ERR_OK;
+}
Index: or_debug_proxy/src/or_debug_proxy.c
===================================================================
--- or_debug_proxy/src/or_debug_proxy.c (nonexistent)
+++ or_debug_proxy/src/or_debug_proxy.c (revision 1779)
@@ -0,0 +1,363 @@
+/*$$HEADER*/
+/******************************************************************************/
+/* */
+/* H E A D E R I N F O R M A T I O N */
+/* */
+/******************************************************************************/
+
+// Project Name : OpenRISC Debug Proxy
+// File Name : or_debug_proxy.c
+// Prepared By : jb
+// Project Start : 2008-10-01
+
+/*$$COPYRIGHT NOTICE*/
+/******************************************************************************/
+/* */
+/* C O P Y R I G H T N O T I C E */
+/* */
+/******************************************************************************/
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License, a copy of which is available from
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*$$DESCRIPTION*/
+/******************************************************************************/
+/* */
+/* D E S C R I P T I O N */
+/* */
+/******************************************************************************/
+//
+// The entry point for the OpenRISC debug proxy console application. Is
+// compilable under both Linux/Unix systems and Cygwin Windows.
+//
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Windows includes
+#ifdef CYGWIN_COMPILE
+#include
+#include "win_FTCJTAG.h"
+#include "win_FTCJTAG_ptrs.h"
+#else
+#include
+void catch_sigint(int sig_num); // First param must be "int"
+#endif
+
+#include "gdb.h"
+#include "usb_functions.h"
+#include "vpi_functions.h"
+#include "or_debug_proxy.h"
+
+// Defines of endpoint numbers
+#define ENDPOINT_TARGET_NONE 0
+#define ENDPOINT_TARGET_USB 1
+#define ENDPOINT_TARGET_VPI 2
+static int endpoint_target; // Either VPI interface via sockets, or the USB device
+
+#define GDB_PROTOCOL_JTAG 1
+#define GDB_PROTOCOL_RSP 2
+#define GDB_PROTOCOL_NONE 3
+
+int err; // Global error value
+
+/* Currently selected scan chain - just to prevent unnecessary transfers. */
+int current_chain = -1;
+
+/* The chain that should be currently selected. */
+int dbg_chain = -1;
+
+int main(int argc, char *argv[]) {
+
+ char *s;
+ int gdb_protocol = GDB_PROTOCOL_NONE;
+ endpoint_target = ENDPOINT_TARGET_NONE;
+ int inp_arg = 1;
+
+ // init our global error number
+ err = DBG_ERR_OK;
+
+ // Parse input options
+ if (argc < 3)
+ {
+ print_usage();
+ exit(1);
+ }
+
+ err = DBG_ERR_OK;
+ srand(getpid());
+
+ // Parse through the input, check what we've been given
+
+ while ( argv[inp_arg] != NULL )
+ {
+ if(strcmp(argv[inp_arg], "-j") == 0)
+ {
+ gdb_protocol = GDB_PROTOCOL_JTAG;
+ endpoint_target = ENDPOINT_TARGET_USB;
+ }
+ else if(strcmp(argv[inp_arg], "-r") == 0)
+ {
+ gdb_protocol = GDB_PROTOCOL_RSP;
+ endpoint_target = ENDPOINT_TARGET_USB;
+ }
+ else if(strcmp(argv[inp_arg], "-v") == 0)
+ {
+ gdb_protocol = GDB_PROTOCOL_RSP;
+ endpoint_target = ENDPOINT_TARGET_VPI;
+ }
+ else
+ {
+ serverPort = strtol(argv[2],&s,10);
+ }
+
+ inp_arg++;
+ }
+
+ if(endpoint_target == ENDPOINT_TARGET_NONE || gdb_protocol == GDB_PROTOCOL_NONE || serverPort > 65535 || *s != '\0')
+ {
+ print_usage();
+ exit(1);
+ }
+
+#ifdef CYGWIN_COMPILE
+ // Load the FTCJTAG DLL function pointers
+ if (getFTDIJTAGFunctions() < 0){
+ exit(-1);
+ }
+#endif
+
+#ifndef CYGWIN_COMPILE
+ // Install a signal handler to exit gracefully
+ // when we receive a sigint
+ signal(SIGINT, catch_sigint);
+#endif
+
+ /* Initialise connection to our OR1k system */
+ current_chain = -1;
+ /* USB Endpoint */
+ if (endpoint_target == ENDPOINT_TARGET_USB)
+ {
+ printf("\nConnecting to OR1k via USB debug cable\n\n");
+ if ((err = usb_dbg_reset())) goto JtagIfError;
+ dbg_test(); // Perform some tests
+ }
+ /* RTL simulation endpoint */
+ else if (endpoint_target == ENDPOINT_TARGET_VPI){
+ printf("\nConnecting to OR1k RTL simulation\n\n");
+ // Connect to the (hopefully) already running RTL simulation server running via VPI
+ vpi_fd = vpi_connect();
+
+ if ((err = vpi_dbg_reset())) goto JtagIfError;
+ vpi_dbg_test(); // Perform some tests
+ }
+
+ /* We have a connection to the target system. Now establish server connection. */
+ if(gdb_protocol == GDB_PROTOCOL_JTAG)
+ { // Connect to JTAG server
+ if((server_fd = GetServerSocket("or1ksim","tcp", serverPort))) {
+ // printf("JTAG Proxy server started on port %d\n", serverPort);
+ printf("Remote JTAG proxy server started on port %d\n", serverPort);
+ printf("Note: The OpenRISC remote JTAG protocol is now DEPRECATED. Please use GDB version 6.8 or later.\n");
+ printf("Press CTRL+c to exit.\n");
+ } else {
+ // fprintf(stderr,"Cannot start JTAG Proxy server on port %d\n", serverPort);
+ fprintf(stderr,"Cannot start Proxy server on port %d\n", serverPort);
+ exit(-1);
+ }
+
+ /* Do endless loop of checking and handle GDB requests. Ctrl-c exits. */
+ // HandleServerSocket(true);
+ HandleServerSocket();
+ return 0;
+ }
+ else if(gdb_protocol == GDB_PROTOCOL_RSP)
+ { // Connect to RSP server
+ /* RSP always starts stalled as though we have just reset the processor. */
+ // rsp_exception (EXCEPT_TRAP);
+ handle_rsp ();
+ // if((server_fd = GetServerSocket("or1ksim","tcp", serverPort))) {
+ }else {
+ fprintf(stderr,"Cannot start RSP Proxy server on port %d\n", serverPort);
+ exit(-1);
+ }
+
+
+JtagIfError:
+ fprintf(stderr,"Connection via USB debug cable failed (err = %d).\nPlease ensure the device is attached and correctly installed\n\n", err);
+ exit(-1);
+ return 0;
+}
+
+
+
+int dbg_reset()
+{
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_reset();
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_reset();
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+void dbg_test() {
+ if (endpoint_target == ENDPOINT_TARGET_USB) usb_dbg_test();
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) vpi_dbg_test();
+}
+
+/* Set TAP instruction register */
+int dbg_set_tap_ir(uint32_t ir) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) usb_set_tap_ir(ir);
+ else return DBG_ERR_INVALID_ENDPOINT;
+ return 0;
+}
+
+/* Sets scan chain. */
+int dbg_set_chain(uint32_t chain) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_set_chain(chain);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_set_chain(chain);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* sends out a command with 32bit address and 16bit length, if len >= 0 */
+int dbg_command(uint32_t type, uint32_t adr, uint32_t len) {
+ // This is never called by any of the VPI functions, so only USB endpoint
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_command(type,adr,len);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* writes a ctrl reg */
+int dbg_ctrl(uint32_t reset, uint32_t stall) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_ctrl(reset, stall);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_ctrl(reset, stall);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* reads control register */
+int dbg_ctrl_read(uint32_t *reset, uint32_t *stall) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_ctrl_read(reset, stall);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_ctrl_read(reset, stall);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* issues a burst read/write */
+int dbg_go(unsigned char *data, uint16_t len, uint32_t read) {
+ // Only USB endpouint32_t option here
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_go(data, len, read);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* read a word from wishbone */
+int dbg_wb_read32(uint32_t adr, uint32_t *data) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read32(adr, data);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read32(adr, data);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+
+/* write a word to wishbone */
+int dbg_wb_write32(uint32_t adr, uint32_t data) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_write32( adr, data);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_write32( adr, data);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* read a block from wishbone */
+int dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_read_block32( adr, data, len);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_read_block32( adr, data, len);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+
+/* write a block to wishbone */
+int dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_wb_write_block32( adr, data, len);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_wb_write_block32( adr, data, len);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* read a register from cpu */
+int dbg_cpu0_read(uint32_t adr, uint32_t *data) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read( adr, data);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read( adr, data);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* write a cpu register */
+int dbg_cpu0_write(uint32_t adr, uint32_t data) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write( adr, data);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write( adr, data);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+/* write a cpu module register */
+int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_write_ctrl( adr, data);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_write_ctrl( adr, data);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+
+/* read a register from cpu module */
+int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) {
+ if (endpoint_target == ENDPOINT_TARGET_USB) return usb_dbg_cpu0_read_ctrl( adr, data);
+ else if (endpoint_target == ENDPOINT_TARGET_VPI) return vpi_dbg_cpu0_read_ctrl( adr, data);
+ else return DBG_ERR_INVALID_ENDPOINT;
+}
+
+
+void test_sdram(void) {
+ return;
+}
+
+// Close down gracefully when we receive any kill signals
+void catch_sigint(int sig_num)
+{
+ // Close down any potentially open sockets and USB handles
+ if (vpi_fd) close(vpi_fd);
+ if (server_fd) close(server_fd);
+ usb_close_device_handle();
+ gdb_close();
+ printf("\nInterrupt signal received. Closing down connections and exiting\n\n");
+ exit(0);
+}
+
+void print_usage()
+{
+ printf("Invalid or insufficient arguments\n");
+ printf("\n");
+ printf("OpenRISC GDB proxy server usage: or_debug_proxy -server_type port\n");
+ printf("\n");
+ printf("server_type:\n");
+ printf("\t-r Start a server using RSP, connection to hadware target via\n\t USB\n");
+ printf("\t-j Start a server using legacy OR remote JTAG protocol, to\n\t hardware target via USB\n");
+ printf("\t-v Start a server using RSP, connection to RTL sim. VPI server\n\t target via sockets\n");
+ printf("\n");
+ printf("port:\n");
+ printf("\tAny free port within the usable range of 0 - 65535\n");
+ printf("\n");
+ printf("Example:\n");
+ printf("\tStart a GDB server on port 5555, using RSP, connecting to\n\thardware target via USB\n");
+ printf("\tor_debug_proxy -r 5555\n");
+ printf("\n");
+ fflush (stdout);
+}
Index: or_debug_proxy/src/gdb.c
===================================================================
--- or_debug_proxy/src/gdb.c (nonexistent)
+++ or_debug_proxy/src/gdb.c (revision 1779)
@@ -0,0 +1,4031 @@
+/*$$HEADER*/
+/******************************************************************************/
+/* */
+/* H E A D E R I N F O R M A T I O N */
+/* */
+/******************************************************************************/
+
+// Project Name : OpenRISC Debug Proxy
+// File Name : gdb.c
+// Prepared By : jb, rmd
+// Project Start : 2008-10-01
+
+/*$$COPYRIGHT NOTICE*/
+/******************************************************************************/
+/* */
+/* C O P Y R I G H T N O T I C E */
+/* */
+/******************************************************************************/
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation;
+ version 2.1 of the License, a copy of which is available from
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*$$DESCRIPTION*/
+/******************************************************************************/
+/* */
+/* D E S C R I P T I O N */
+/* */
+/******************************************************************************/
+//
+// Implements GDB stub for OpenRISC debug proxy.
+//
+
+
+/*$$CHANGE HISTORY*/
+/******************************************************************************/
+/* */
+/* C H A N G E H I S T O R Y */
+/* */
+/******************************************************************************/
+
+// Date Version Description
+//------------------------------------------------------------------------
+// 081101 Imported code from "jp" project jb
+// 090219 Adapted code from Jeremy Bennett's RSP server
+// for the or1ksim project. rmb
+// 090304 Finished RSP server code import, added extra
+// functions, adding stability when debugging on
+// a remote target. jb
+
+#ifdef CYGWIN_COMPILE
+
+#else
+// linux includes
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* Libraries for JTAG proxy server. */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/*! Name of the Or1ksim RSP service */
+#define OR1KSIM_RSP_SERVICE "or1ksim-rsp"
+
+#include "gdb.h" /* partially copied from gdb/config/or1k */
+#include "or_debug_proxy.h"
+
+#define MAX_GPRS (32)
+
+/* Indices of GDB registers that are not GPRs. Must match GDB settings! */
+#define PPC_REGNUM (MAX_GPRS + 0) /*!< Previous PC */
+#define NPC_REGNUM (MAX_GPRS + 1) /*!< Next PC */
+#define SR_REGNUM (MAX_GPRS + 2) /*!< Supervision Register */
+#define NUM_REGS (MAX_GPRS + 3) /*!< Total GDB registers */
+
+/* OR1k CPU registers address */
+#define NPC_CPU_REG_ADD 0x10 /* Next PC */
+#define SR_CPU_REG_ADD 0x11 /* Supervision Register */
+#define PPC_CPU_REG_ADD 0x12 /* Previous PC */
+#define DMR1_CPU_REG_ADD ((6 << 11) + 16) /* Debug Mode Register 1 (DMR1) 0x3010 */
+#define DMR2_CPU_REG_ADD ((6 << 11) + 17) /* Debug Mode Register 2 (DMR2) 0x3011 */
+#define DSR_CPU_REG_ADD ((6 << 11) + 20) /* Debug Stop Register (DSR) 0x3014 */
+#define DRR_CPU_REG_ADD ((6 << 11) + 21) /* Debug Reason Register (DRR) 0x3015 */
+
+/*! Trap instruction for OR32 */
+#define OR1K_TRAP_INSTR 0x21000001
+
+/*! The maximum number of characters in inbound/outbound buffers. The largest
+ packets are the 'G' packet, which must hold the 'G' and all the registers
+ with two hex digits per byte and the 'g' reply, which must hold all the
+ registers, and (in our implementation) an end-of-string (0)
+ character. Adding the EOS allows us to print out the packet as a
+ string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed
+ for register packets */
+#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1)
+
+/*! Size of the matchpoint hash table. Largest prime < 2^10 */
+#define MP_HASH_SIZE 1021
+
+/* Definition of special-purpose registers (SPRs). */
+#define MAX_SPRS (0x10000)
+
+#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/
+#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */
+#define SPR_DSR_TE 0x00002000 /* Trap exception */
+
+#define WORDSBIGENDIAN_N
+
+/* Definition of OR1K exceptions */
+#define EXCEPT_NONE 0x0000
+#define EXCEPT_RESET 0x0100
+#define EXCEPT_BUSERR 0x0200
+#define EXCEPT_DPF 0x0300
+#define EXCEPT_IPF 0x0400
+#define EXCEPT_TICK 0x0500
+#define EXCEPT_ALIGN 0x0600
+#define EXCEPT_ILLEGAL 0x0700
+#define EXCEPT_INT 0x0800
+#define EXCEPT_DTLBMISS 0x0900
+#define EXCEPT_ITLBMISS 0x0a00
+#define EXCEPT_RANGE 0x0b00
+#define EXCEPT_SYSCALL 0x0c00
+#define EXCEPT_FPE 0x0d00
+#define EXCEPT_TRAP 0x0e00
+
+// Changed to #defines from static const int's due to compile error
+// DRR (Debug Reason Register) Bits
+#define SPR_DRR_RSTE 0x00000001 //!< Reset
+#define SPR_DRR_BUSEE 0x00000002 //!< Bus error
+#define SPR_DRR_DPFE 0x00000004 //!< Data page fault
+#define SPR_DRR_IPFE 0x00000008 //!< Insn page fault
+#define SPR_DRR_TTE 0x00000010 //!< Tick timer
+#define SPR_DRR_AE 0x00000020 //!< Alignment
+#define SPR_DRR_IIE 0x00000040 //!< Illegal instruction
+#define SPR_DRR_IE 0x00000080 //!< Interrupt
+#define SPR_DRR_DME 0x00000100 //!< DTLB miss
+#define SPR_DRR_IME 0x00000200 //!< ITLB miss
+#define SPR_DRR_RE 0x00000400 //!< Range fault
+#define SPR_DRR_SCE 0x00000800 //!< System call
+#define SPR_DRR_FPE 0x00001000 //!< Floating point
+#define SPR_DRR_TE 0x00002000 //!< Trap
+
+
+/*! Definition of GDB target signals. Data taken from the GDB 6.8
+ source. Only those we use defined here. The exact meaning of
+ signal number is defined by the header `include/gdb/signals.h'
+ in the GDB source code. For an explanation of what each signal
+ means, see target_signal_to_string.*/
+enum target_signal {
+ TARGET_SIGNAL_NONE = 0,
+ TARGET_SIGNAL_INT = 2,
+ TARGET_SIGNAL_ILL = 4,
+ TARGET_SIGNAL_TRAP = 5,
+ TARGET_SIGNAL_FPE = 8,
+ TARGET_SIGNAL_BUS = 10,
+ TARGET_SIGNAL_SEGV = 11,
+ TARGET_SIGNAL_ALRM = 14,
+ TARGET_SIGNAL_USR2 = 31,
+ TARGET_SIGNAL_PWR = 32
+};
+
+/*! String to map hex digits to chars */
+static const char hexchars[]="0123456789abcdef";
+
+
+//! Is the NPC cached?
+
+//! Setting the NPC flushes the pipeline, so subsequent reads will return
+//! zero until the processor has refilled the pipeline. This will not be
+//! happening if the processor is stalled (as it is when GDB had control),
+//! so we must cache the NPC. As soon as the processor is unstalled, this
+//! cached value becomes invalid. So we must track the stall state, and if
+//! appropriate cache the NPC.
+enum stallStates {
+ STALLED,
+ UNSTALLED,
+ UNKNOWN
+} stallState;
+
+int npcIsCached; //!< Is the NPC cached - should be bool
+uint32_t npcCachedValue; //!< Cached value of the NPC
+
+
+
+
+/************************
+ JTAG Server Routines
+************************/
+int serverIP = 0;
+int serverPort = 0;
+int server_fd = 0;
+int gdb_fd = 0;
+
+static int tcp_level = 0;
+
+/* global to store what chain the debug unit is currently connected to
+(not the JTAG TAP, but the onchip debug module has selected) */
+int gdb_chain = -1;
+
+/*! Data structure for RSP buffers. Can't be null terminated, since it may
+ include zero bytes */
+struct rsp_buf
+{
+ char data[GDB_BUF_MAX];
+ int len;
+};
+
+/*! Enumeration of different types of matchpoint. These have explicit values
+ matching the second digit of 'z' and 'Z' packets. */
+enum mp_type {
+ BP_MEMORY = 0, // software-breakpoint Z0 break
+ BP_HARDWARE = 1, // hardware-breakpoint Z1 hbreak
+ WP_WRITE = 2, // write-watchpoint Z2 watch
+ WP_READ = 3, // read-watchpoint Z3 rwatch
+ WP_ACCESS = 4 // access-watchpoint Z4 awatch
+};
+
+/*! Data structure for a matchpoint hash table entry */
+struct mp_entry
+{
+ enum mp_type type; /*!< Type of matchpoint */
+ uint32_t addr; /*!< Address with the matchpoint */
+ uint32_t instr; /*!< Substituted instruction */
+ struct mp_entry *next; /*!< Next entry with this hash */
+};
+
+/*! Central data for the RSP connection */
+static struct
+{
+ int client_waiting; /*!< Is client waiting a response? */
+// Not used int proto_num; /*!< Number of the protocol used */
+ int client_fd; /*!< FD for talking to GDB */
+ int sigval; /*!< GDB signal for any exception */
+ uint32_t start_addr; /*!< Start of last run */
+ struct mp_entry *mp_hash[MP_HASH_SIZE]; /*!< Matchpoint hash table */
+} rsp;
+
+/* Forward declarations of static functions */
+static char *printTime(void);
+static int gdb_read(void*, int);
+static int gdb_write(void*, int);
+static void ProtocolClean(int, int32_t);
+static void GDBRequest(void);
+static void rsp_interrupt();
+static unsigned char rsp_peek();
+static struct rsp_buf *get_packet (void);
+static void rsp_init (void);
+static void set_npc (uint32_t addr);
+static uint32_t get_npc();
+static void rsp_check_for_exception();
+static int check_for_exception_vector(uint32_t ppc);
+static void rsp_exception (uint32_t except);
+static int get_rsp_char (void);
+static int hex (int c);
+static void rsp_get_client (void);
+static void rsp_client_request (void);
+static void rsp_client_close (void);
+static void client_close (char err);
+static void put_str_packet (const char *str);
+static void rsp_report_exception (void);
+static void put_packet (struct rsp_buf *p_buf);
+static void send_rsp_str (unsigned char *data, int len);
+static void rsp_query (struct rsp_buf *p_buf);
+static void rsp_vpkt (struct rsp_buf *p_buf);
+static void rsp_step (struct rsp_buf *p_buf);
+static void rsp_step_with_signal (struct rsp_buf *p_buf);
+static void rsp_step_generic (uint32_t addr, uint32_t except);
+static void rsp_continue (struct rsp_buf *p_buf);
+static void rsp_continue_with_signal (struct rsp_buf *p_buf);
+static void rsp_continue_generic (uint32_t addr, uint32_t except);
+static void rsp_read_all_regs (void);
+static void rsp_write_all_regs (struct rsp_buf *p_buf);
+static void rsp_read_mem (struct rsp_buf *p_buf);
+static void rsp_write_mem (struct rsp_buf *p_buf);
+static void rsp_write_mem_bin (struct rsp_buf *p_buf);
+static int rsp_unescape (char *data, int len);
+static void rsp_read_reg (struct rsp_buf *p_buf);
+static void rsp_write_reg (struct rsp_buf *p_buf);
+static void mp_hash_init (void);
+static void mp_hash_add (enum mp_type type, uint32_t addr, uint32_t instr);
+static struct mp_entry * mp_hash_lookup (enum mp_type type, uint32_t addr);
+static struct mp_entry * mp_hash_delete (enum mp_type type, uint32_t addr);
+static void rsp_remove_matchpoint (struct rsp_buf *p_buf);
+static void rsp_insert_matchpoint (struct rsp_buf *p_buf);
+static void rsp_command (struct rsp_buf *p_buf);
+static void rsp_set (struct rsp_buf *p_buf);
+static void rsp_restart (void);
+static void ascii2hex (char *dest,char *src);
+static void hex2ascii (char *dest, char *src);
+static uint32_t hex2reg (char *p_buf);
+static void reg2hex (uint32_t val, char *p_buf);
+static void swap_buf(char* p_buf, int len);
+static void set_stall_state (int state);
+static void gdb_ensure_or1k_stalled();
+static int gdb_set_chain(int chain);
+static int gdb_write_reg(uint32_t adr, uint32_t data);
+static int gdb_read_reg(uint32_t adr, uint32_t *data);
+static int gdb_write_block(uint32_t adr, uint32_t *data, int len);
+static int gdb_read_block(uint32_t adr, uint32_t *data, int len);
+
+char *printTime(void)
+{
+ time_t tid;
+ struct tm *strtm;
+ static char timeBuf[20];
+
+ time(&tid);
+ strtm = localtime(&tid);
+ sprintf(timeBuf,"[%.02d:%.02d:%.02d] ",strtm->tm_hour,strtm->tm_min,strtm->tm_sec);
+ return timeBuf;
+}
+
+/*---------------------------------------------------------------------------*/
+/*!Initialize the Remote Serial Protocol connection
+
+ Set up the central data structures. */
+/*---------------------------------------------------------------------------*/
+void
+rsp_init (void)
+{
+ /* Clear out the central data structure */
+ rsp.client_waiting = 0; /* GDB client is not waiting for us */
+ rsp.client_fd = -1; /* i.e. invalid */
+ rsp.sigval = 0; /* No exception */
+ rsp.start_addr = EXCEPT_RESET; /* Default restart point */
+
+ /* Set up the matchpoint hash table */
+ mp_hash_init ();
+
+ /* RSP always starts stalled as though we have just reset the processor. */
+ rsp_exception (EXCEPT_TRAP);
+
+ /* Setup the NPC caching variables */
+ stallState = STALLED;
+ // Force a caching of the NPC
+ npcIsCached = 0;
+ get_npc();
+
+} /* rsp_init () */
+
+/*---------------------------------------------------------------------------*/
+/*!Look for action on RSP
+
+ This function is called when the processor has stalled, which, except for
+ initialization, must be due to an interrupt.
+
+ If we have no RSP client, we get one. We can make no progress until the
+ client is available.
+
+ Then if the cause is an exception following a step or continue command, and
+ the exception not been notified to GDB, a packet reporting the cause of the
+ exception is sent.
+
+ The next client request is then processed. */
+/*---------------------------------------------------------------------------*/
+void
+handle_rsp (void)
+{
+ uint32_t temp_uint32;
+
+ rsp_init();
+
+ while (1){
+ /* If we have no RSP client, wait until we get one. */
+ while (-1 == rsp.client_fd)
+ {
+ rsp_get_client ();
+ rsp.client_waiting = 0; /* No longer waiting */
+ }
+
+ /* If we have an unacknowledged exception tell the GDB client. If this
+ exception was a trap due to a memory breakpoint, then adjust the NPC. */
+ if (rsp.client_waiting)
+ {
+
+ // Check for exception
+ rsp_check_for_exception();
+
+ if(DEBUG_GDB)
+ {
+ gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
+ printf("PPC is currently 0x%08x\n", temp_uint32);
+ }
+
+ // Get the PPC to check if we've hit a software breakpoint
+ gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
+
+ if ((TARGET_SIGNAL_TRAP == rsp.sigval) && (NULL != mp_hash_lookup (BP_MEMORY, temp_uint32)))
+ {
+ if (stallState != STALLED)
+ // This is a quick fix for a strange situation seen in some of the simulators where
+ // the sw bp would be detected, but the stalled state variable wasn't updated correctly
+ // indicating that last time it checked, it wasn't set but the processor has now hit the
+ // breakpoint. So run rsp_check_for_exception() to bring everything up to date.
+ rsp_check_for_exception();
+
+ if(DEBUG_GDB) printf("Software breakpoint hit at 0x%08x. Rolling back NPC to this instruction\n", temp_uint32);
+
+ set_npc (temp_uint32);
+
+ rsp_report_exception();
+ rsp.client_waiting = 0; /* No longer waiting */
+ }
+ else if(stallState == STALLED) {
+ // If we're here, the thing has stalled, but not because of a breakpoint we set
+ // report back the exception
+
+ rsp_report_exception();
+ rsp.client_waiting = 0; /* No longer waiting */
+
+ }
+ // Check if PPC is at a known exception vector
+ // (Illegal inst., unaligned access, etc.)
+ else if (check_for_exception_vector(temp_uint32))
+ {
+ rsp_report_exception();
+ rsp.client_waiting = 0;
+ }
+
+ if (rsp.client_waiting)
+ sleep(1);
+
+ }
+
+
+
+ // See if there's any incoming data from the client by peeking at the socket
+ if (rsp_peek() > 0)
+ {
+ if (rsp_peek() == 0x03 && (stallState != STALLED)) // ETX, end of text control char
+ {
+ // Got an interrupt command from GDB, this function should
+ // pull the packet off the socket and stall the processor.
+ // and then send a stop reply packet with signal TARGET_SIGNAL_NONE
+ rsp_interrupt();
+ rsp.client_waiting = 0;
+ }
+ else if (rsp.client_waiting == 0)
+ {
+ // Default handling of data from the client:
+ /* Get a RSP client request */
+ rsp_client_request ();
+ }
+ } /* end if (rsp_peek() > 0) */
+ }
+} /* handle_rsp () */
+
+
+/*
+ Check if processor is stalled - if it is, read the DRR
+ and return the target signal code
+*/
+static void rsp_check_for_exception()
+{
+
+ unsigned char stalled;
+ uint32_t drr;
+ err = dbg_cpu0_read_ctrl(0, &stalled); /* check if we're stalled */
+
+ if (!(stalled & 0x01))
+ {
+ // Processor not stalled. Just return;
+ return;
+ }
+
+ if (DEBUG_GDB) printf("rsp_check_for_exception() detected processor was stalled\nChecking DRR\n");
+
+ // We're stalled
+ stallState = STALLED;
+ npcIsCached = 0;
+
+ gdb_set_chain(SC_RISC_DEBUG);
+
+ // Now read the DRR (Debug Reason Register)
+ gdb_read_reg(DRR_CPU_REG_ADD, &drr);
+
+ if (DEBUG_GDB) printf("DRR: 0x%08x\n", drr);
+
+ switch ((int)(drr&0xffffffff))
+ {
+ case SPR_DRR_RSTE: rsp.sigval = TARGET_SIGNAL_PWR; break;
+ case SPR_DRR_BUSEE: rsp.sigval = TARGET_SIGNAL_BUS; break;
+ case SPR_DRR_DPFE: rsp.sigval = TARGET_SIGNAL_SEGV; break;
+ case SPR_DRR_IPFE: rsp.sigval = TARGET_SIGNAL_SEGV; break;
+ case SPR_DRR_TTE: rsp.sigval = TARGET_SIGNAL_ALRM; break;
+ case SPR_DRR_AE: rsp.sigval = TARGET_SIGNAL_BUS; break;
+ case SPR_DRR_IIE: rsp.sigval = TARGET_SIGNAL_ILL; break;
+ case SPR_DRR_IE: rsp.sigval = TARGET_SIGNAL_INT; break;
+ case SPR_DRR_DME: rsp.sigval = TARGET_SIGNAL_SEGV; break;
+ case SPR_DRR_IME: rsp.sigval = TARGET_SIGNAL_SEGV; break;
+ case SPR_DRR_RE: rsp.sigval = TARGET_SIGNAL_FPE; break;
+ case SPR_DRR_SCE: rsp.sigval = TARGET_SIGNAL_USR2; break;
+ case SPR_DRR_FPE: rsp.sigval = TARGET_SIGNAL_FPE; break;
+ case SPR_DRR_TE: rsp.sigval = TARGET_SIGNAL_TRAP; break;
+
+ default:
+ // This must be the case of single step (which does not set DRR)
+ rsp.sigval = TARGET_SIGNAL_TRAP; break;
+ }
+
+ if (DEBUG_GDB) printf("rsp.sigval: 0x%x\n", rsp.sigval);
+
+ return;
+}
+
+/*---------------------------------------------------------------------------*/
+/*!Check if PPC is in an exception vector that halts program flow
+
+Compare the provided PPC with known exception vectors that are fatal
+to a program's execution. Call rsp_exception(ppc) to set the appropriate
+sigval and return.
+
+@param[in] ppc Value of current PPC, as read from debug unit
+@return: 1 if we set a sigval and should return control to GDB, else 0 */
+/*---------------------------------------------------------------------------*/
+static int
+check_for_exception_vector(uint32_t ppc)
+{
+ switch(ppc)
+ {
+ // The following should return sigvals to GDB for processing
+ case EXCEPT_BUSERR:
+ case EXCEPT_ALIGN:
+ case EXCEPT_ILLEGAL:
+ case EXCEPT_TRAP: if(DEBUG_GDB)
+ printf("PPC at exception address\n");
+ rsp_exception(ppc);
+ return 1;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+/*!Note an exception for future processing
+
+ The simulator has encountered an exception. Record it here, so that a
+ future call to handle_exception will report it back to the client. The
+ signal is supplied in Or1ksim form and recorded in GDB form.
+
+ We flag up a warning if an exception is already pending, and ignore the
+ earlier exception.
+
+ @param[in] except The exception (Or1ksim form) */
+/*---------------------------------------------------------------------------*/
+void
+rsp_exception (uint32_t except)
+{
+ int sigval; /* GDB signal equivalent to exception */
+
+ switch (except)
+ {
+ case EXCEPT_RESET: sigval = TARGET_SIGNAL_PWR; break;
+ case EXCEPT_BUSERR: sigval = TARGET_SIGNAL_BUS; break;
+ case EXCEPT_DPF: sigval = TARGET_SIGNAL_SEGV; break;
+ case EXCEPT_IPF: sigval = TARGET_SIGNAL_SEGV; break;
+ case EXCEPT_TICK: sigval = TARGET_SIGNAL_ALRM; break;
+ case EXCEPT_ALIGN: sigval = TARGET_SIGNAL_BUS; break;
+ case EXCEPT_ILLEGAL: sigval = TARGET_SIGNAL_ILL; break;
+ case EXCEPT_INT: sigval = TARGET_SIGNAL_INT; break;
+ case EXCEPT_DTLBMISS: sigval = TARGET_SIGNAL_SEGV; break;
+ case EXCEPT_ITLBMISS: sigval = TARGET_SIGNAL_SEGV; break;
+ case EXCEPT_RANGE: sigval = TARGET_SIGNAL_FPE; break;
+ case EXCEPT_SYSCALL: sigval = TARGET_SIGNAL_USR2; break;
+ case EXCEPT_FPE: sigval = TARGET_SIGNAL_FPE; break;
+ case EXCEPT_TRAP: sigval = TARGET_SIGNAL_TRAP; break;
+
+ default:
+ fprintf (stderr, "Warning: Unknown RSP exception %u: Ignored\n", except);
+ return;
+ }
+
+ if ((0 != rsp.sigval) && (sigval != rsp.sigval))
+ {
+ fprintf (stderr, "Warning: RSP signal %d received while signal "
+ "%d pending: Pending exception replaced\n", sigval, rsp.sigval);
+ }
+
+ rsp.sigval = sigval; /* Save the signal value */
+
+} /* rsp_exception () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Get a new client connection.
+
+ Blocks until the client connection is available.
+
+ A lot of this code is copied from remote_open in gdbserver remote-utils.c.
+
+ This involves setting up a socket to listen on a socket for attempted
+ connections from a single GDB instance (we couldn't be talking to multiple
+ GDBs at once!).
+
+ The service is specified either as a port number in the Or1ksim configuration
+ (parameter rsp_port in section debug, default 51000) or as a service name
+ in the constant OR1KSIM_RSP_SERVICE.
+
+ The protocol used for communication is specified in OR1KSIM_RSP_PROTOCOL. */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_get_client (void)
+{
+ int tmp_fd; /* Temporary descriptor for socket */
+ int optval; /* Socket options */
+ struct sockaddr_in sock_addr; /* Socket address */
+ socklen_t len; /* Size of the socket address */
+
+ /* 0 is used as the RSP port number to indicate that we should use the
+ service name instead. */
+ if (0 == serverPort)
+ {
+ struct servent *service = getservbyname (OR1KSIM_RSP_SERVICE, "tcp");
+ if (NULL == service)
+ {
+ fprintf (stderr, "Warning: RSP unable to find service \"%s\": %s\n",
+ OR1KSIM_RSP_SERVICE, strerror (errno));
+ return;
+ }
+ serverPort = ntohs (service->s_port);
+ }
+
+ /* Open a socket on which we'll listen for clients */
+ tmp_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (tmp_fd < 0)
+ {
+ fprintf (stderr, "ERROR: Cannot open RSP socket\n");
+ exit (0);
+ }
+
+ /* Allow rapid reuse of the port on this socket */
+ optval = 1;
+ setsockopt (tmp_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval,
+ sizeof (optval));
+
+ /* Bind the port to the socket */
+ sock_addr.sin_family = PF_INET;
+ sock_addr.sin_port = htons (serverPort);
+ sock_addr.sin_addr.s_addr = INADDR_ANY;
+ if (bind (tmp_fd, (struct sockaddr *) &sock_addr, sizeof (sock_addr)))
+ {
+ fprintf (stderr, "ERROR: Cannot bind to RSP socket\n");
+ exit (0);
+ }
+
+ /* Listen for (at most one) client */
+ if (0 != listen (tmp_fd, 1))
+ {
+ fprintf (stderr, "ERROR: Cannot listen on RSP socket\n");
+ exit (0);
+ }
+
+ printf("Waiting for gdb connection on localhost:%d\n", serverPort);
+ fflush (stdout);
+
+ printf("Press CTRL+c to exit.\n");
+ fflush (stdout);
+
+ /* Accept a client which connects */
+ len = sizeof (sock_addr);
+ rsp.client_fd = accept (tmp_fd, (struct sockaddr *)&sock_addr, &len);
+
+ if (-1 == rsp.client_fd)
+ {
+ fprintf (stderr, "Warning: Failed to accept RSP client\n");
+ return;
+ }
+
+ /* Enable TCP keep alive process */
+ optval = 1;
+ setsockopt (rsp.client_fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval,
+ sizeof (optval));
+
+ /* Set socket to be non-blocking */
+
+ /* We do this because when we're given a continue, or step
+ instruction,command we set the processor stall off, then instnatly check
+ if it's stopped. If it hasn't then we drop through and wait for input
+ from GDB. Obviously this will cause problems when it will stop after we
+ do the check. So now, rsp_peek() has been implemented to simply check if
+ there's an incoming command from GDB (only interested in interrupt
+ commands), otherwise it returns back to and poll the processor's PPC and
+ stall bit. It can only do this if the socket is non-blocking.
+
+ At first test, simply adding this line appeared to give no problems with
+ the existing code. No "simulation" of blocking behaviour on the
+ non-blocking socket was required (in the event that a read/write throws
+ back a EWOULDBLOCK error, as was looked to be the case in the previous
+ GDB handling code) -- Julius
+ */
+ if (ioctl(rsp.client_fd, FIONBIO, (char *)&optval) > 0 )
+ {
+ perror("ioctl() failed");
+ close(rsp.client_fd);
+ close(tmp_fd);
+ exit(0);
+ }
+
+ /* Don't delay small packets, for better interactive response (disable
+ Nagel's algorithm) */
+ optval = 1;
+ setsockopt (rsp.client_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval,
+ sizeof (optval));
+
+ /* Socket is no longer needed */
+ close (tmp_fd); /* No longer need this */
+ signal (SIGPIPE, SIG_IGN); /* So we don't exit if client dies */
+
+ printf ("Remote debugging from host %s\n", inet_ntoa (sock_addr.sin_addr));
+} /* rsp_get_client () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Deal with a request from the GDB client session
+
+ In general, apart from the simplest requests, this function replies on
+ other functions to implement the functionality. */
+/*---------------------------------------------------------------------------*/
+static void rsp_client_request (void)
+{
+ struct rsp_buf *p_buf = get_packet (); /* Message sent to us */
+
+ // Null packet means we hit EOF or the link was closed for some other
+ // reason. Close the client and return
+ if (NULL == p_buf)
+ {
+ rsp_client_close ();
+ return;
+ }
+
+ if (DEBUG_GDB){
+ printf("%s-----------------------------------------------------\n", printTime());
+ printf ("Packet received %s: %d chars\n", p_buf->data, p_buf->len );
+ fflush (stdout);
+ }
+
+ switch (p_buf->data[0])
+ {
+ case '!':
+ /* Request for extended remote mode */
+ put_str_packet ("OK"); // OK = supports and has enabled extended mode.
+ return;
+
+ case '?':
+ /* Return last signal ID */
+ rsp_report_exception();
+ return;
+
+ case 'A':
+ /* Initialization of argv not supported */
+ fprintf (stderr, "Warning: RSP 'A' packet not supported: ignored\n");
+ put_str_packet ("E01");
+ return;
+
+ case 'b':
+ /* Setting baud rate is deprecated */
+ fprintf (stderr, "Warning: RSP 'b' packet is deprecated and not "
+ "supported: ignored\n");
+ return;
+
+ case 'B':
+ /* Breakpoints should be set using Z packets */
+ fprintf (stderr, "Warning: RSP 'B' packet is deprecated (use 'Z'/'z' "
+ "packets instead): ignored\n");
+ return;
+
+ case 'c':
+ /* Continue */
+ rsp_continue (p_buf);
+ return;
+
+ case 'C':
+ /* Continue with signal */
+ rsp_continue_with_signal (p_buf);
+ return;
+
+ case 'd':
+ /* Disable debug using a general query */
+ fprintf (stderr, "Warning: RSP 'd' packet is deprecated (define a 'Q' "
+ "packet instead: ignored\n");
+ return;
+
+ case 'D':
+ /* Detach GDB. Do this by closing the client. The rules say that
+ execution should continue. TODO. Is this really then intended
+ meaning? Or does it just mean that only vAttach will be recognized
+ after this? */
+ put_str_packet ("OK");
+ rsp_client_close ();
+ set_stall_state (0);
+ return;
+
+ case 'F':
+ /* File I/O is not currently supported */
+ fprintf (stderr, "Warning: RSP file I/O not currently supported: 'F' "
+ "packet ignored\n");
+ return;
+
+ case 'g':
+ rsp_read_all_regs ();
+ return;
+
+ case 'G':
+ rsp_write_all_regs (p_buf);
+ return;
+
+ case 'H':
+ /* Set the thread number of subsequent operations. For now ignore
+ silently and just reply "OK" */
+ put_str_packet ("OK");
+ return;
+
+ case 'i':
+ /* Single instruction step */
+ fprintf (stderr, "Warning: RSP cycle stepping not supported: target "
+ "stopped immediately\n");
+ rsp.client_waiting = 1; /* Stop reply will be sent */
+ return;
+
+ case 'I':
+ /* Single instruction step with signal */
+ fprintf (stderr, "Warning: RSP cycle stepping not supported: target "
+ "stopped immediately\n");
+ rsp.client_waiting = 1; /* Stop reply will be sent */
+ return;
+
+ case 'k':
+ /* Kill request. Do nothing for now. */
+ return;
+
+ case 'm':
+ /* Read memory (symbolic) */
+ rsp_read_mem (p_buf);
+ return;
+
+ case 'M':
+ /* Write memory (symbolic) */
+ rsp_write_mem (p_buf);
+ return;
+
+ case 'p':
+ /* Read a register */
+ rsp_read_reg (p_buf);
+ return;
+
+ case 'P':
+ /* Write a register */
+ rsp_write_reg (p_buf);
+ return;
+
+ case 'q':
+ /* Any one of a number of query packets */
+ rsp_query (p_buf);
+ return;
+
+ case 'Q':
+ /* Any one of a number of set packets */
+ rsp_set (p_buf);
+ return;
+
+ case 'r':
+ /* Reset the system. Deprecated (use 'R' instead) */
+ fprintf (stderr, "Warning: RSP 'r' packet is deprecated (use 'R' "
+ "packet instead): ignored\n");
+ return;
+
+ case 'R':
+ /* Restart the program being debugged. */
+ rsp_restart ();
+ return;
+
+ case 's':
+ /* Single step (one high level instruction). This could be hard without
+ DWARF2 info */
+ rsp_step (p_buf);
+ return;
+
+ case 'S':
+ /* Single step (one high level instruction) with signal. This could be
+ hard without DWARF2 info */
+ rsp_step_with_signal (p_buf);
+ return;
+
+ case 't':
+ /* Search. This is not well defined in the manual and for now we don't
+ support it. No response is defined. */
+ fprintf (stderr, "Warning: RSP 't' packet not supported: ignored\n");
+ return;
+
+ case 'T':
+ /* Is the thread alive. We are bare metal, so don't have a thread
+ context. The answer is always "OK". */
+ put_str_packet ("OK");
+ return;
+
+ case 'v':
+ /* Any one of a number of packets to control execution */
+ rsp_vpkt (p_buf);
+ return;
+
+ case 'X':
+ /* Write memory (binary) */
+ rsp_write_mem_bin (p_buf);
+ return;
+
+ case 'z':
+ /* Remove a breakpoint/watchpoint. */
+ rsp_remove_matchpoint (p_buf);
+ return;
+
+ case 'Z':
+ /* Insert a breakpoint/watchpoint. */
+ rsp_insert_matchpoint (p_buf);
+ return;
+
+ default:
+ /* Unknown commands are ignored */
+ fprintf (stderr, "Warning: Unknown RSP request %s\n", p_buf->data);
+ return;
+ }
+} /* rsp_client_request () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Close the connection to the client if it is open */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_client_close (void)
+{
+ if (-1 != rsp.client_fd)
+ {
+ close (rsp.client_fd);
+ rsp.client_fd = -1;
+ }
+} /* rsp_client_close () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Send a packet to the GDB client
+
+ Modeled on the stub version supplied with GDB. Put out the data preceded by
+ a '$', followed by a '#' and a one byte checksum. '$', '#', '*' and '}' are
+ escaped by preceding them with '}' and then XORing the character with
+ 0x20.
+
+ @param[in] p_buf The data to send */
+/*---------------------------------------------------------------------------*/
+static void
+put_packet (struct rsp_buf *p_buf)
+{
+ unsigned char data[GDB_BUF_MAX * 2];
+ int len;
+ int ch; /* Ack char */
+
+ /* Construct $#. Repeat until the GDB client
+ acknowledges satisfactory receipt. */
+ do
+ {
+ unsigned char checksum = 0; /* Computed checksum */
+ int count = 0; /* Index into the buffer */
+
+ if (DEBUG_GDB_DUMP_DATA){
+ printf ("Putting %s\n\n", p_buf->data);
+ fflush (stdout);
+ }
+
+ len = 0;
+ data[len++] = '$'; /* Start char */
+
+ /* Body of the packet */
+ for (count = 0; count < p_buf->len; count++)
+ {
+ unsigned char ch = p_buf->data[count];
+
+ /* Check for escaped chars */
+ if (('$' == ch) || ('#' == ch) || ('*' == ch) || ('}' == ch))
+ {
+ ch ^= 0x20;
+ checksum += (unsigned char)'}';
+ data[len++] = '}';
+ }
+
+ checksum += ch;
+ data[len++] = ch;
+ }
+
+ data[len++] = '#'; /* End char */
+
+ /* Computed checksum */
+ data[len++] = (hexchars[checksum >> 4]);
+ data[len++] = (hexchars[checksum % 16]);
+
+ send_rsp_str ((unsigned char *) &data, len);
+
+ /* Check for ack of connection failure */
+ ch = get_rsp_char ();
+ if (0 > ch)
+ {
+ return; /* Fail the put silently. */
+ }
+ }
+ while ('+' != ch);
+
+} /* put_packet () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Convenience to put a constant string packet
+
+ param[in] str The text of the packet */
+/*---------------------------------------------------------------------------*/
+static void
+put_str_packet (const char *str)
+{
+ struct rsp_buf buffer;
+ int len = strlen (str);
+
+ /* Construct the packet to send, so long as string is not too big,
+ otherwise truncate. Add EOS at the end for convenient debug printout */
+
+ if (len >= GDB_BUF_MAX)
+ {
+ fprintf (stderr, "Warning: String %s too large for RSP packet: "
+ "truncated\n", str);
+ len = GDB_BUF_MAX - 1;
+ }
+
+ strncpy (buffer.data, str, len);
+ buffer.data[len] = 0;
+ buffer.len = len;
+
+ put_packet (&buffer);
+
+} /* put_str_packet () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Get a packet from the GDB client
+
+ Modeled on the stub version supplied with GDB. The data is in a static
+ buffer. The data should be copied elsewhere if it is to be preserved across
+ a subsequent call to get_packet().
+
+ Unlike the reference implementation, we don't deal with sequence
+ numbers. GDB has never used them, and this implementation is only intended
+ for use with GDB 6.8 or later. Sequence numbers were removed from the RSP
+ standard at GDB 5.0.
+
+ @return A pointer to the static buffer containing the data */
+/*---------------------------------------------------------------------------*/
+static struct rsp_buf *
+get_packet (void)
+{
+ static struct rsp_buf buf; /* Survives the return */
+
+ /* Keep getting packets, until one is found with a valid checksum */
+ while (1)
+ {
+ unsigned char checksum; /* The checksum we have computed */
+ int count; /* Index into the buffer */
+ int ch; /* Current character */
+
+ /* Wait around for the start character ('$'). Ignore all other
+ characters */
+ ch = get_rsp_char ();
+
+ while (ch != '$')
+ {
+ if (-1 == ch)
+ {
+ return NULL; /* Connection failed */
+ }
+
+ ch = get_rsp_char ();
+
+ // Potentially handle an interrupt character (0x03) here
+ }
+
+ /* Read until a '#' or end of buffer is found */
+ checksum = 0;
+ count = 0;
+ while (count < GDB_BUF_MAX - 1)
+ {
+ ch = get_rsp_char ();
+
+ if(rsp.client_waiting && DEBUG_GDB)
+ {
+ printf("%x\n",ch);
+ }
+
+
+ /* Check for connection failure */
+ if (0 > ch)
+ {
+ return NULL;
+ }
+
+ /* If we hit a start of line char begin all over again */
+ if ('$' == ch)
+ {
+ checksum = 0;
+ count = 0;
+
+ continue;
+ }
+
+ /* Break out if we get the end of line char */
+ if ('#' == ch)
+ {
+ break;
+ }
+
+ /* Update the checksum and add the char to the buffer */
+
+ checksum = checksum + (unsigned char)ch;
+ buf.data[count] = (char)ch;
+ count = count + 1;
+ }
+
+ /* Mark the end of the buffer with EOS - it's convenient for non-binary
+ data to be valid strings. */
+ buf.data[count] = 0;
+ buf.len = count;
+
+ /* If we have a valid end of packet char, validate the checksum */
+ if ('#' == ch)
+ {
+ unsigned char xmitcsum; /* The checksum in the packet */
+
+ ch = get_rsp_char ();
+ if (0 > ch)
+ {
+ return NULL; /* Connection failed */
+ }
+ xmitcsum = hex (ch) << 4;
+
+ ch = get_rsp_char ();
+ if (0 > ch)
+ {
+ return NULL; /* Connection failed */
+ }
+
+ xmitcsum += hex (ch);
+
+ /* If the checksums don't match print a warning, and put the
+ negative ack back to the client. Otherwise put a positive ack. */
+ if (checksum != xmitcsum)
+ {
+ fprintf (stderr, "Warning: Bad RSP checksum: Computed "
+ "0x%02x, received 0x%02x\n", checksum, xmitcsum);
+
+ ch = '-';
+ send_rsp_str ((unsigned char *) &ch, 1); /* Failed checksum */
+ }
+ else
+ {
+ ch = '+';
+ send_rsp_str ((unsigned char *) &ch, 1); /* successful transfer */
+ break;
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Warning: RSP packet overran buffer\n");
+ }
+ }
+ return &buf; /* Success */
+} /* get_packet () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Put a single character out onto the client socket
+
+ This should only be called if the client is open, but we check for safety.
+
+ @param[in] c The character to put out */
+/*---------------------------------------------------------------------------*/
+static void
+send_rsp_str (unsigned char *data, int len)
+{
+ if (-1 == rsp.client_fd)
+ {
+ fprintf (stderr, "Warning: Attempt to write '%s' to unopened RSP "
+ "client: Ignored\n", data);
+ return;
+ }
+
+ /* Write until successful (we retry after interrupts) or catastrophic
+ failure. */
+ while (1)
+ {
+ switch (write (rsp.client_fd, data, len))
+ {
+ case -1:
+ /* Error: only allow interrupts or would block */
+ if ((EAGAIN != errno) && (EINTR != errno))
+ {
+ fprintf (stderr, "Warning: Failed to write to RSP client: "
+ "Closing client connection: %s\n",
+ strerror (errno));
+ rsp_client_close ();
+ return;
+ }
+
+ break;
+
+ case 0:
+ break; /* Nothing written! Try again */
+
+ default:
+ return; /* Success, we can return */
+ }
+ }
+} /* send_rsp_str () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Get a single character from the client socket
+
+ This should only be called if the client is open, but we check for safety.
+
+ @return The character read, or -1 on failure */
+/*---------------------------------------------------------------------------*/
+static int
+get_rsp_char ()
+{
+ if (-1 == rsp.client_fd)
+ {
+ fprintf (stderr, "Warning: Attempt to read from unopened RSP "
+ "client: Ignored\n");
+ return -1;
+ }
+
+ /* Non-blocking read until successful (we retry after interrupts) or
+ catastrophic failure. */
+ while (1)
+ {
+ unsigned char c;
+
+ switch (read (rsp.client_fd, &c, sizeof (c)))
+ {
+ case -1:
+ /* Error: only allow interrupts */
+ if ((EAGAIN != errno) && (EINTR != errno))
+ {
+ fprintf (stderr, "Warning: Failed to read from RSP client: "
+ "Closing client connection: %s\n",
+ strerror (errno));
+ rsp_client_close ();
+ return -1;
+ }
+
+ break;
+
+ case 0:
+ // EOF
+ rsp_client_close ();
+ return -1;
+
+ default:
+ return c & 0xff; /* Success, we can return (no sign extend!) */
+ }
+ }
+} /* get_rsp_char () */
+
+/*---------------------------------------------------------------------------*/
+/* !Peek at data coming into server from GDB
+
+ Useful for polling for ETX (0x3) chars being sent when GDB wants to
+ interrupt
+
+ @return the char we peeked, 0 otherwise */
+/*---------------------------------------------------------------------------*/
+static unsigned char
+rsp_peek()
+{
+ /*
+ if (-1 == rsp.client_fd)
+ {
+ fprintf (stderr, "Warning: Attempt to read from unopened RSP "
+ "client: Ignored\n");
+ return -1;
+ }
+ */
+ unsigned char c;
+ int n;
+ // Using recv here instead of read becuase we can pass the MSG_PEEK
+ // flag, which lets us look at what's on the socket, without actually
+ // taking it off
+
+ //if (DEBUG_GDB)
+ // printf("peeking at GDB socket...\n");
+ n = recv (rsp.client_fd, &c, sizeof (c), MSG_PEEK);
+ //if (DEBUG_GDB)
+ // printf("peeked, got n=%d, c=0x%x\n",n, c);
+
+ if (n == 0)
+ return 0;
+ else
+ return c;
+
+ // return c;
+}
+
+/*---------------------------------------------------------------------------*/
+/*!Handle an interrupt from GDB
+
+ Detect an interrupt from GDB and stall the processor */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_interrupt()
+{
+ unsigned char c;
+
+ if (read (rsp.client_fd, &c, sizeof (c)) <= 0)
+ {
+ // Had issues, just return
+ return;
+ }
+
+ // Ensure this is a ETX control char (0x3), currently, we only call this
+ // function when we've peeked and seen it, otherwise, ignore, return and pray
+ // things go back to normal...
+ if (c != 0x03)
+ {
+ printf("Warning: Interrupt character expected but not found on socket.\n");
+ return;
+ }
+
+ // Otherwise, it's an interrupt packet, stall the processor, and upon return
+ // to the main handle_rsp() loop, it will inform GDB.
+
+ if (DEBUG_GDB) printf("Interrupt received from GDB. Stalling processor.\n");
+
+ set_stall_state (1);
+
+ // Send a stop reply response, manually set rsp.sigval to TARGET_SIGNAL_NONE
+ rsp.sigval = TARGET_SIGNAL_NONE;
+ rsp_report_exception();
+ rsp.client_waiting = 0; /* No longer waiting */
+
+ return;
+
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*!"Unescape" RSP binary data
+
+ '#', '$' and '}' are escaped by preceding them by '}' and oring with 0x20.
+
+ This function reverses that, modifying the data in place.
+
+ @param[in] data The array of bytes to convert
+ @para[in] len The number of bytes to be converted
+
+ @return The number of bytes AFTER conversion */
+/*---------------------------------------------------------------------------*/
+static int
+rsp_unescape (char *data,
+ int len)
+{
+ int from_off = 0; /* Offset to source char */
+ int to_off = 0; /* Offset to dest char */
+
+ while (from_off < len)
+ {
+ /* Is it escaped */
+ if ( '}' == data[from_off])
+ {
+ from_off++;
+ data[to_off] = data[from_off] ^ 0x20;
+ }
+ else
+ {
+ data[to_off] = data[from_off];
+ }
+
+ from_off++;
+ to_off++;
+ }
+
+ return to_off;
+
+} /* rsp_unescape () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Initialize the matchpoint hash table
+
+ This is an open hash table, so this function clears all the links to
+ NULL. */
+/*---------------------------------------------------------------------------*/
+static void
+mp_hash_init (void)
+{
+ int i;
+
+ for (i = 0; i < MP_HASH_SIZE; i++)
+ {
+ rsp.mp_hash[i] = NULL;
+ }
+} /* mp_hash_init () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Add an entry to the matchpoint hash table
+
+ Add the entry if it wasn't already there. If it was there do nothing. The
+ match just be on type and addr. The instr need not match, since if this is
+ a duplicate insertion (perhaps due to a lost packet) they will be
+ different.
+
+ @param[in] type The type of matchpoint
+ @param[in] addr The address of the matchpoint
+ @para[in] instr The instruction to associate with the address */
+/*---------------------------------------------------------------------------*/
+static void
+mp_hash_add (enum mp_type type,
+ uint32_t addr,
+ uint32_t instr)
+{
+ int hv = addr % MP_HASH_SIZE;
+ struct mp_entry *curr;
+
+ /* See if we already have the entry */
+ for(curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
+ {
+ if ((type == curr->type) && (addr == curr->addr))
+ {
+ return; /* We already have the entry */
+ }
+ }
+
+ /* Insert the new entry at the head of the chain */
+ curr = (struct mp_entry*) malloc (sizeof (*curr));
+
+ curr->type = type;
+ curr->addr = addr;
+ curr->instr = instr;
+ curr->next = rsp.mp_hash[hv];
+
+ rsp.mp_hash[hv] = curr;
+
+} /* mp_hash_add () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Look up an entry in the matchpoint hash table
+
+ The match must be on type AND addr.
+
+ @param[in] type The type of matchpoint
+ @param[in] addr The address of the matchpoint
+
+ @return The entry deleted, or NULL if the entry was not found */
+/*---------------------------------------------------------------------------*/
+static struct mp_entry * mp_hash_lookup (enum mp_type type, uint32_t addr)
+{
+ int hv = addr % MP_HASH_SIZE;
+ struct mp_entry *curr;
+
+ /* Search */
+ for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
+ {
+ if ((type == curr->type) && (addr == curr->addr))
+ {
+ return curr; /* The entry found */
+ }
+ }
+
+ /* Not found */
+ return NULL;
+
+} /* mp_hash_lookup () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Delete an entry from the matchpoint hash table
+
+ If it is there the entry is deleted from the hash table. If it is not
+ there, no action is taken. The match must be on type AND addr.
+
+ The usual fun and games tracking the previous entry, so we can delete
+ things.
+
+ @note The deletion DOES NOT free the memory associated with the entry,
+ since that is returned. The caller should free the memory when they
+ have used the information.
+
+ @param[in] type The type of matchpoint
+ @param[in] addr The address of the matchpoint
+
+ @return The entry deleted, or NULL if the entry was not found */
+/*---------------------------------------------------------------------------*/
+static struct mp_entry *
+mp_hash_delete (enum mp_type type,
+ uint32_t addr)
+{
+ int hv = addr % MP_HASH_SIZE;
+ struct mp_entry *prev = NULL;
+ struct mp_entry *curr;
+
+ /* Search */
+ for (curr = rsp.mp_hash[hv]; NULL != curr; curr = curr->next)
+ {
+ if ((type == curr->type) && (addr == curr->addr))
+ {
+ /* Found - delete. Method depends on whether we are the head of
+ chain. */
+ if (NULL == prev)
+ {
+ rsp.mp_hash[hv] = curr->next;
+ }
+ else
+ {
+ prev->next = curr->next;
+ }
+
+ return curr; /* The entry deleted */
+ }
+
+ prev = curr;
+ }
+
+ /* Not found */
+ return NULL;
+
+} /* mp_hash_delete () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Utility to give the value of a hex char
+
+ @param[in] ch A character representing a hexadecimal digit. Done as -1,
+ for consistency with other character routines, which can use
+ -1 as EOF.
+
+ @return The value of the hex character, or -1 if the character is
+ invalid. */
+/*---------------------------------------------------------------------------*/
+static int hex (int c)
+{
+ return ((c >= 'a') && (c <= 'f')) ? c - 'a' + 10 :
+ ((c >= '0') && (c <= '9')) ? c - '0' :
+ ((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : -1;
+
+} /* hex () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Convert a register to a hex digit string
+
+ The supplied 32-bit value is converted to an 8 digit hex string according
+ the target endianism. It is null terminated for convenient printing.
+
+ @param[in] val The value to convert
+ @param[out] p_buf The buffer for the text string */
+/*---------------------------------------------------------------------------*/
+static void
+reg2hex (uint32_t val, char *p_buf)
+{
+ int n; /* Counter for digits */
+ int nyb_shift;
+
+ for (n = 0; n < 8; n++)
+ {
+#ifdef WORDSBIGENDIAN
+ if(n%2==0){
+ nyb_shift = n * 4 + 4;
+ }
+ else{
+ nyb_shift = n * 4 - 4;
+ }
+#else
+ nyb_shift = 28 - (n * 4);
+#endif
+ p_buf[n] = hexchars[(val >> nyb_shift) & 0xf];
+ }
+
+ p_buf[8] = 0; /* Useful to terminate as string */
+
+} /* reg2hex () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Convert a hex digit string to a register value
+
+ The supplied 8 digit hex string is converted to a 32-bit value according
+ the target endianism
+
+ @param[in] p_buf The buffer with the hex string
+
+ @return The value to convert */
+/*---------------------------------------------------------------------------*/
+static uint32_t
+hex2reg (char *p_buf)
+{
+ int n; /* Counter for digits */
+ uint32_t val = 0; /* The result */
+
+ for (n = 0; n < 8; n++)
+ {
+#ifdef WORDSBIGENDIAN
+ int nyb_shift = n * 4;
+#else
+ int nyb_shift = 28 - (n * 4);
+#endif
+ val |= hex (p_buf[n]) << nyb_shift;
+ }
+
+ return val;
+
+} /* hex2reg () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Convert an ASCII character string to pairs of hex digits
+
+ Both source and destination are null terminated.
+
+ @param[out] dest Buffer to store the hex digit pairs (null terminated)
+ @param[in] src The ASCII string (null terminated) */
+/*---------------------------------------------------------------------------*/
+static void ascii2hex (char *dest,
+ char *src)
+{
+ int i;
+
+ /* Step through converting the source string */
+ for (i = 0; src[i] != '\0'; i++)
+ {
+ char ch = src[i];
+
+ dest[i * 2] = hexchars[ch >> 4 & 0xf];
+ dest[i * 2 + 1] = hexchars[ch & 0xf];
+ }
+
+ dest[i * 2] = '\0';
+
+} /* ascii2hex () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Convert pairs of hex digits to an ASCII character string
+
+ Both source and destination are null terminated.
+
+ @param[out] dest The ASCII string (null terminated)
+ @param[in] src Buffer holding the hex digit pairs (null terminated) */
+/*---------------------------------------------------------------------------*/
+static void hex2ascii (char *dest,
+ char *src)
+{
+ int i;
+
+ /* Step through convering the source hex digit pairs */
+ for (i = 0; src[i * 2] != '\0' && src[i * 2 + 1] != '\0'; i++)
+ {
+ dest[i] = ((hex (src[i * 2]) & 0xf) << 4) | (hex (src[i * 2 + 1]) & 0xf);
+ }
+
+ dest[i] = '\0';
+
+} /* hex2ascii () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Set the program counter
+
+ This sets the value in the NPC SPR. Not completely trivial, since this is
+ actually cached in cpu_state.pc. Any reset of the NPC also involves
+ clearing the delay state and setting the pcnext global.
+
+ Only actually do this if the requested address is different to the current
+ NPC (avoids clearing the delay pipe).
+
+ @param[in] addr The address to use */
+/*---------------------------------------------------------------------------*/
+static void
+set_npc (uint32_t addr)
+{
+
+ // First set the chain
+ gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+
+
+ if (addr != get_npc())
+ {
+
+ gdb_write_reg(NPC_CPU_REG_ADD, addr);
+
+ if (STALLED == stallState)
+ {
+ if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written and locally cached \n", addr);
+ npcCachedValue = addr;
+ npcIsCached = 1;
+ }
+ else
+ {
+ if (DEBUG_GDB) printf("set_npc(): New NPC value (0x%08x) written \n", addr);
+ npcIsCached = 0;
+ }
+
+
+ }
+ else
+ return;
+
+
+} /* set_npc () */
+
+
+//! Read the value of the Next Program Counter (a SPR)
+
+//! Setting the NPC flushes the pipeline, so subsequent reads will return
+//! zero until the processor has refilled the pipeline. This will not be
+//! happening if the processor is stalled (as it is when GDB had control),
+//! so we must cache the NPC. As soon as the processor is unstalled, this
+//! cached value becomes invalid.
+
+//! If we are stalled and the value has been cached, use it. If we are stalled
+//! and the value has not been cached, cache it (for efficiency) and use
+//! it. Otherwise read the corresponding SPR.
+
+//! @return The value of the NPC
+static uint32_t get_npc ()
+{
+ uint32_t current_npc;
+
+ if (STALLED == stallState)
+ {
+ if (npcIsCached == 0)
+ {
+ err = gdb_set_chain(SC_RISC_DEBUG);
+ err = gdb_read_reg(NPC_CPU_REG_ADD, &npcCachedValue);
+ if(err > 0){
+ printf("Error %d reading NPC\n", err);
+ rsp_client_close ();
+ return 0;
+ }
+ if (DEBUG_GDB) printf("get_npc(): caching newly read NPC value (0x%08x)\n",npcCachedValue);
+
+
+ npcIsCached = 1;
+ }
+ else
+ if (DEBUG_GDB) printf("get_npc(): reading cached NPC value (0x%08x)\n",npcCachedValue);
+
+ return npcCachedValue;
+ }
+ else
+ {
+ err = gdb_read_reg(NPC_CPU_REG_ADD, ¤t_npc);
+ if(err > 0){
+ printf("Error %d reading NPC\n", err);
+ rsp_client_close ();
+ return 0;
+ }
+ return current_npc;
+
+ }
+} // get_npc ()
+
+
+
+/*---------------------------------------------------------------------------*/
+/*!Send a packet acknowledging an exception has occurred
+
+ This is only called if there is a client FD to talk to */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_report_exception (void)
+{
+ struct rsp_buf buffer;
+
+ /* Construct a signal received packet */
+ buffer.data[0] = 'S';
+ buffer.data[1] = hexchars[rsp.sigval >> 4];
+ buffer.data[2] = hexchars[rsp.sigval % 16];
+ buffer.data[3] = 0;
+ buffer.len = strlen (buffer.data);
+
+ put_packet (&buffer);
+
+} /* rsp_report_exception () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP continue request
+
+ Parse the command to see if there is an address. Uses the underlying
+ generic continue function, with EXCEPT_NONE.
+
+ @param[in] p_buf The full continue packet */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_continue (struct rsp_buf *p_buf)
+{
+ uint32_t addr; /* Address to continue from, if any */
+
+ // First set the chain
+ err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ if(err > 0){
+ printf("Error %d to set RISC Debug Interface chain in the CONTINUE command 'c'\n", err);
+ rsp_client_close ();
+ return;
+ }
+
+ if (0 == strcmp ("c", p_buf->data))
+ {
+ // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
+ /* ---------- NPC ---------- */
+ addr = get_npc();
+ }
+ else if (1 != sscanf (p_buf->data, "c%x", &addr))
+ {
+ fprintf (stderr,
+ "Warning: RSP continue address %s not recognized: ignored\n",
+ p_buf->data);
+
+ // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
+ /* ---------- NPC ---------- */
+ addr = get_npc();
+ }
+
+ if (DEBUG_GDB) printf("rsp_continue() --> Read NPC = 0x%08x\n", addr);
+
+ rsp_continue_generic (addr, EXCEPT_NONE);
+
+} /* rsp_continue () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP continue with signal request
+
+ Currently null. Will use the underlying generic continue function.
+
+ @param[in] p_buf The full continue with signal packet */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_continue_with_signal (struct rsp_buf *p_buf)
+{
+ printf ("RSP continue with signal '%s' received\n", p_buf->data);
+
+} /* rsp_continue_with_signal () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Generic processing of a continue request
+
+ The signal may be EXCEPT_NONE if there is no exception to be
+ handled. Currently the exception is ignored.
+
+ The single step flag is cleared in the debug registers and then the
+ processor is unstalled.
+
+ @param[in] addr Address from which to step
+ @param[in] except The exception to use (if any) */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_continue_generic (uint32_t addr,
+ uint32_t except)
+{
+ uint32_t temp_uint32;
+
+ /* Set the address as the value of the next program counter */
+ set_npc (addr);
+
+ /* Clear Debug Reason Register (DRR) 0x3015 */
+ // Arc sim --> cpu_state.sprs[SPR_DRR] = 0;
+ if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n");
+
+ /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
+ // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
+ if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n");
+ temp_uint32 &= ~SPR_DMR2_WGB;
+ if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n");
+
+ /* Clear the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
+ // Arc sim --> cpu_state.sprs[SPR_DMR1] &= ~SPR_DMR1_ST;
+ if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n");
+ temp_uint32 &= ~SPR_DMR1_ST;
+ if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n");
+
+ /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
+ // Arc sim --> cpu_state.sprs[SPR_DSR] |= SPR_DSR_TE;
+ if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n");
+ temp_uint32 |= SPR_DSR_TE;
+ if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n");
+
+ /* Unstall the processor */
+ set_stall_state (0);
+
+ /* Note the GDB client is now waiting for a reply. */
+ rsp.client_waiting = 1;
+
+} /* rsp_continue_generic () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP read all registers request
+
+ The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
+ (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
+ returned as a sequence of bytes in target endian order.
+
+ Each byte is packed as a pair of hex digits. */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_read_all_regs (void)
+{
+ struct rsp_buf buffer; /* Buffer for the reply */
+ int r; /* Register index */
+ uint32_t temp_uint32;
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+
+
+ // Read all GPRs
+ for (r = 0; r < MAX_GPRS; r++){
+
+ err = gdb_read_reg(0x400 + r, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_read_reg at reg. %d\n", err, r);
+ put_str_packet ("E01");
+ return;
+ }
+ reg2hex (temp_uint32, &(buffer.data[r * 8]));
+
+ if (DEBUG_GDB_DUMP_DATA){
+ switch(r % 4)
+ {
+ case 0:
+ printf("gpr%02d 0x%08x ", r, temp_uint32);
+ break;
+ case 1:
+ case 2:
+ printf("0x%08x ", temp_uint32);
+ break;
+ case 3:
+ printf("0x%08x\n", temp_uint32);
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+ /* ---------- PPC ---------- */
+ err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> PPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ reg2hex (temp_uint32, &(buffer.data[PPC_REGNUM * 8]));
+ if (DEBUG_GDB_DUMP_DATA) printf("PPC 0x%08x\n", temp_uint32);
+ /* ---------- NPC ---------- */
+ temp_uint32 = get_npc();
+ /*
+ err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> NPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ */
+ reg2hex (temp_uint32, &(buffer.data[NPC_REGNUM * 8]));
+ if (DEBUG_GDB_DUMP_DATA) printf("NPC 0x%08x\n", temp_uint32);
+ /* ---------- SR ---------- */
+ err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_read_reg read --> SP\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ reg2hex (temp_uint32, &(buffer.data[SR_REGNUM * 8]));
+ if (DEBUG_GDB_DUMP_DATA) printf("SR 0x%08x\n", temp_uint32);
+
+ /* Finalize the packet and send it */
+ buffer.data[NUM_REGS * 8] = 0;
+ buffer.len = NUM_REGS * 8;
+
+ put_packet (&buffer);
+ return;
+} /* rsp_read_all_regs () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP write all registers request
+
+ The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PPC
+ (i.e. SPR PPC), NPC (i.e. SPR NPC) and SR (i.e. SPR SR). Each register is
+ supplied as a sequence of bytes in target endian order.
+
+ Each byte is packed as a pair of hex digits.
+
+ @todo There is no error checking at present. Non-hex chars will generate a
+ warning message, but there is no other check that the right amount
+ of data is present. The result is always "OK".
+
+ @param[in] p_buf The original packet request. */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_write_all_regs (struct rsp_buf *p_buf)
+{
+ uint32_t regnum; /* Register index */
+ // char valstr[9]; /* Allow for EOS on the string */
+
+ // /* Check for valid data */
+ // if (0 != (strcmp ("G", p_buf->data)) && (GDB_BUF_MAX != strlen(p_buf->data)))
+ // {
+ // fprintf (stderr, "Warning: Failed to recognize RSP write register "
+ // "command: %s\n", p_buf->data);
+ // // put_str_packet ("E01");
+ // return;
+ // }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* ---------- GPRS ---------- */
+ for (regnum = 0; regnum < MAX_GPRS; regnum++)
+ {
+ err = gdb_write_reg(0x400 + regnum, hex2reg (&p_buf->data[regnum * 8 + 1]));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ }
+
+ /* ---------- PPC ---------- */
+ err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (&p_buf->data[PPC_REGNUM * 8 + 1]));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ /* ---------- SR ---------- */
+ err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (&p_buf->data[SR_REGNUM * 8 + 1]));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ /* ---------- NPC ---------- */
+ set_npc(hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
+ /*
+ err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (&p_buf->data[NPC_REGNUM * 8 + 1]));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ */
+ /* Acknowledge. TODO: We always succeed at present, even if the data was
+ defective. */
+ put_str_packet ("OK");
+} /* rsp_write_all_regs () */
+
+
+/*---------------------------------------------------------------------------*/
+/* Handle a RSP read memory (symbolic) request
+
+ Syntax is:
+
+ m,:
+
+ The response is the bytes, lowest address first, encoded as pairs of hex
+ digits.
+
+ The length given is the number of bytes to be read.
+
+ @note This function reuses p_buf, so trashes the original command.
+
+ @param[in] p_buf The command received */
+/*---------------------------------------------------------------------------*/
+static void rsp_read_mem (struct rsp_buf *p_buf)
+{
+ unsigned int addr; /* Where to read the memory */
+ int len; /* Number of bytes to read */
+ int off; /* Offset into the memory */
+ uint32_t temp_uint32 = 0;
+ char *rec_buf;
+
+
+ if (2 != sscanf (p_buf->data, "m%x,%x:", &addr, &len))
+ {
+ fprintf (stderr, "Warning: Failed to recognize RSP read memory "
+ "command: %s\n", p_buf->data);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Make sure we won't overflow the buffer (2 chars per byte) */
+ if ((len * 2) >= GDB_BUF_MAX)
+ {
+ fprintf (stderr, "Warning: Memory read %s too large for RSP packet: "
+ "truncated\n", p_buf->data);
+ len = (GDB_BUF_MAX - 1) / 2;
+ }
+
+ if(!(rec_buf = (char*)malloc(len))) {
+ put_str_packet ("E01");
+ ProtocolClean(0, JTAG_PROXY_OUT_OF_MEMORY);
+ return;
+ }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // Set chain 5 --> Wishbone Memory chain
+ err = gdb_set_chain(SC_WISHBONE);
+ if(err){
+ if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+
+ // Read the data from Wishbone Memory chain
+ err = gdb_read_block(addr, (uint32_t*)rec_buf, len);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Refill the buffer with the reply */
+ for( off = 0 ; off < len ; off ++ ) {
+ ;
+ temp_uint32 = (temp_uint32 << 8) | (0x000000ff & *(rec_buf + off));
+
+ if((off %4 ) == 3){
+ temp_uint32 = htonl(temp_uint32);
+ reg2hex (temp_uint32, &(p_buf->data[off * 2 - 6]));
+ }
+ if (DEBUG_GDB_BLOCK_DATA){
+ switch(off % 16)
+ {
+ case 3:
+ printf("Add 0x%08x Data 0x%08x ", addr + off - 3, temp_uint32);
+ break;
+ case 7:
+ case 11:
+ printf("0x%08x ", temp_uint32);
+ break;
+ case 15:
+ printf("0x%08x\n", temp_uint32);
+ break;
+ default:
+ break;
+ }
+ if ((len - off == 1) && (off % 16) < 15) printf("\n");
+ }
+ }
+
+ if (DEBUG_GDB && (err > 0)) printf("\nError %x\n", err);fflush (stdout);
+ free(rec_buf);
+ p_buf->data[off * 2] = 0; /* End of string */
+ p_buf->len = strlen (p_buf->data);
+ put_packet (p_buf);
+} /* rsp_read_mem () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP write memory (symbolic) request ("M")
+
+ Syntax is:
+
+ M,:
+
+ Example: M4015cc,2:c320#
+ (Write the value 0xc320 to address 0x4015cc.)
+
+ An example target response:
+ + $OK#
+
+ The data is the bytes, lowest address first, encoded as pairs of hex
+ digits.
+
+ The length given is the number of bytes to be written.
+
+ @note This function reuses p_buf, so trashes the original command.
+
+ @param[in] p_buf The command received */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_write_mem (struct rsp_buf *p_buf)
+{
+ unsigned int addr; /* Where to write the memory */
+ int len; /* Number of bytes to write */
+ char *symdat; /* Pointer to the symboli data */
+ int datlen; /* Number of digits in symbolic data */
+ int off; /* Offset into the memory */
+ int nibc; /* Nibbel counter */
+ uint32_t val;
+
+ if (2 != sscanf (p_buf->data, "M%x,%x:", &addr, &len))
+ {
+ fprintf (stderr, "Warning: Failed to recognize RSP write memory "
+ "command: %s\n", p_buf->data);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Find the start of the data and check there is the amount we expect. */
+ symdat = (char*) memchr ((const void *)p_buf->data, ':', GDB_BUF_MAX) + 1;
+ datlen = p_buf->len - (symdat - p_buf->data);
+
+ /* Sanity check */
+ if (len * 2 != datlen)
+ {
+ fprintf (stderr, "Warning: Write of %d digits requested, but %d digits "
+ "supplied: packet ignored\n", len * 2, datlen );
+ put_str_packet ("E01");
+ return;
+ }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+
+ // Set chain 5 --> Wishbone Memory chain
+ err = gdb_set_chain(SC_WISHBONE);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+
+ val = 0;
+ off = 0;
+ /* Write the bytes to memory */
+ for (nibc = 0; nibc < datlen; nibc++)
+ {
+ val |= 0x0000000f & hex (symdat[nibc]);
+ if(nibc % 8 == 7){
+ err = gdb_write_block(addr + off, &val, 4);
+ if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+ val = 0;
+ off += 4;
+ }
+ val <<= 4;
+ }
+ put_str_packet ("OK");
+} /* rsp_write_mem () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Read a single register
+
+ The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
+ (i.e. SPR NPC) and SR (i.e. SPR SR). The register is returned as a
+ sequence of bytes in target endian order.
+
+ Each byte is packed as a pair of hex digits.
+
+ @param[in] p_buf The original packet request. Reused for the reply. */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_read_reg (struct rsp_buf *p_buf)
+{
+ unsigned int regnum;
+ uint32_t temp_uint32;
+
+ /* Break out the fields from the data */
+ if (1 != sscanf (p_buf->data, "p%x", ®num))
+ {
+ fprintf (stderr, "Warning: Failed to recognize RSP read register "
+ "command: %s\n", p_buf->data);
+ put_str_packet ("E01");
+ return;
+ }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Get the relevant register */
+ if (regnum < MAX_GPRS)
+ {
+ err = gdb_read_reg(0x400 + regnum, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_read_reg at reg. %d \n", err, regnum);
+ put_str_packet ("E01");
+ return;
+ }
+ reg2hex (temp_uint32, p_buf->data);
+ }
+ else if (PPC_REGNUM == regnum) /* ---------- PPC ---------- */
+ {
+ err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ reg2hex (temp_uint32, p_buf->data);
+ }
+ else if (NPC_REGNUM == regnum) /* ---------- NPC ---------- */
+ {
+ temp_uint32 = get_npc();
+ /*
+ err = gdb_read_reg(NPC_CPU_REG_ADD, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ */
+ reg2hex (temp_uint32, p_buf->data);
+ }
+ else if (SR_REGNUM == regnum) /* ---------- SR ---------- */
+ {
+ err = gdb_read_reg(SR_CPU_REG_ADD, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_read_reg read --> PPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ reg2hex (temp_uint32, p_buf->data);
+ }
+ else
+ {
+ /* Error response if we don't know the register */
+ fprintf (stderr, "Warning: Attempt to read unknown register 0x%x: "
+ "ignored\n", regnum);
+ put_str_packet ("E01");
+ return;
+ }
+
+ p_buf->len = strlen (p_buf->data);
+ put_packet (p_buf);
+
+} /* rsp_read_reg () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Write a single register
+
+ The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
+ (i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a
+ sequence of bytes in target endian order.
+
+ Each byte is packed as a pair of hex digits.
+
+ @param[in] p_buf The original packet request. */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_write_reg (struct rsp_buf *p_buf)
+{
+ unsigned int regnum;
+ char valstr[9]; /* Allow for EOS on the string */
+ // int err = 0;
+
+ /* Break out the fields from the data */
+ if (2 != sscanf (p_buf->data, "P%x=%8s", ®num, valstr))
+ {
+ fprintf (stderr, "Warning: Failed to recognize RSP write register "
+ "command: %s\n", p_buf->data);
+ put_str_packet ("E01");
+ return;
+ }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Set the relevant register */
+ if (regnum < MAX_GPRS) /* ---------- GPRS ---------- */
+ {
+ err = gdb_write_reg(0x400 + regnum, hex2reg (valstr));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> GPRS\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ }
+ else if (PPC_REGNUM == regnum) /* ---------- PPC ---------- */
+ {
+ err = gdb_write_reg(PPC_CPU_REG_ADD, hex2reg (valstr));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> PPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ }
+ else if (NPC_REGNUM == regnum) /* ---------- NPC ---------- */
+ {
+ set_npc(hex2reg (valstr));
+ /*
+ err = gdb_write_reg(NPC_CPU_REG_ADD, hex2reg (valstr));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> NPC\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ */
+ }
+ else if (SR_REGNUM == regnum) /* ---------- SR ---------- */
+ {
+ err = gdb_write_reg(SR_CPU_REG_ADD, hex2reg (valstr));
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_write_reg write --> SR\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ }
+ else
+ {
+ /* Error response if we don't know the register */
+ fprintf (stderr, "Warning: Attempt to write unknown register 0x%x: "
+ "ignored\n", regnum);
+ put_str_packet ("E01");
+ return;
+ }
+
+ put_str_packet ("OK");
+
+} /* rsp_write_reg () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP query request
+
+ @param[in] p_buf The request */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_query (struct rsp_buf *p_buf)
+{
+ if (0 == strcmp ("qC", p_buf->data))
+ {
+ /* Return the current thread ID (unsigned hex). A null response
+ indicates to use the previously selected thread. Since we do not
+ support a thread concept, this is the appropriate response. */
+ put_str_packet ("");
+ }
+ else if (0 == strncmp ("qCRC", p_buf->data, strlen ("qCRC")))
+ {
+ /* Return CRC of memory area */
+ fprintf (stderr, "Warning: RSP CRC query not supported\n");
+ put_str_packet ("E01");
+ }
+ else if (0 == strcmp ("qfThreadInfo", p_buf->data))
+ {
+ /* Return info about active threads. We return just '-1' */
+ put_str_packet ("m-1");
+ }
+ else if (0 == strcmp ("qsThreadInfo", p_buf->data))
+ {
+ /* Return info about more active threads. We have no more, so return the
+ end of list marker, 'l' */
+ put_str_packet ("l");
+ }
+ else if (0 == strncmp ("qGetTLSAddr:", p_buf->data, strlen ("qGetTLSAddr:")))
+ {
+ /* We don't support this feature */
+ put_str_packet ("");
+ }
+ else if (0 == strncmp ("qL", p_buf->data, strlen ("qL")))
+ {
+ /* Deprecated and replaced by 'qfThreadInfo' */
+ fprintf (stderr, "Warning: RSP qL deprecated: no info returned\n");
+ put_str_packet ("qM001");
+ }
+ else if (0 == strcmp ("qOffsets", p_buf->data))
+ {
+ /* Report any relocation */
+ put_str_packet ("Text=0;Data=0;Bss=0");
+ }
+ else if (0 == strncmp ("qP", p_buf->data, strlen ("qP")))
+ {
+ /* Deprecated and replaced by 'qThreadExtraInfo' */
+ fprintf (stderr, "Warning: RSP qP deprecated: no info returned\n");
+ put_str_packet ("");
+ }
+ else if (0 == strncmp ("qRcmd,", p_buf->data, strlen ("qRcmd,")))
+ {
+ /* This is used to interface to commands to do "stuff" */
+ rsp_command (p_buf);
+ }
+ else if (0 == strncmp ("qSupported", p_buf->data, strlen ("qSupported")))
+ {
+ /* Report a list of the features we support. For now we just ignore any
+ supplied specific feature queries, but in the future these may be
+ supported as well. Note that the packet size allows for 'G' + all the
+ registers sent to us, or a reply to 'g' with all the registers and an
+ EOS so the buffer is a well formed string. */
+ setup_or32(); // setup cpu
+ char reply[GDB_BUF_MAX];
+ sprintf (reply, "PacketSize=%x", GDB_BUF_MAX);
+ put_str_packet (reply);
+ }
+ else if (0 == strncmp ("qSymbol:", p_buf->data, strlen ("qSymbol:")))
+ {
+ /* Offer to look up symbols. Nothing we want (for now). TODO. This just
+ ignores any replies to symbols we looked up, but we didn't want to
+ do that anyway! */
+ put_str_packet ("OK");
+ }
+ else if (0 == strncmp ("qThreadExtraInfo,", p_buf->data,
+ strlen ("qThreadExtraInfo,")))
+ {
+ /* Report that we are runnable, but the text must be hex ASCI
+ digits. For now do this by steam, reusing the original packet */
+ sprintf (p_buf->data, "%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
+ p_buf->len = strlen (p_buf->data);
+ put_packet (p_buf);
+ }
+ else if (0 == strncmp ("qXfer:", p_buf->data, strlen ("qXfer:")))
+ {
+ /* For now we support no 'qXfer' requests, but these should not be
+ expected, since they were not reported by 'qSupported' */
+ fprintf (stderr, "Warning: RSP 'qXfer' not supported: ignored\n");
+ put_str_packet ("");
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognized RSP query: ignored\n");
+ }
+} /* rsp_query () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP qRcmd request
+
+ The actual command follows the "qRcmd," in ASCII encoded to hex
+
+ @param[in] p_buf The request in full */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_command (struct rsp_buf *p_buf)
+{
+ char cmd[GDB_BUF_MAX];
+ unsigned int regno;
+ uint32_t temp_uint32;
+
+ hex2ascii (cmd, &(p_buf->data[strlen ("qRcmd,")]));
+
+ /* Work out which command it is */
+ if (0 == strncmp ("readspr ", cmd, strlen ("readspr")))
+ {
+ /* Parse and return error if we fail */
+ if( 1 != sscanf (cmd, "readspr %4x", ®no))
+ {
+ fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n", cmd);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* SPR out of range */
+ if (regno > MAX_SPRS)
+ {
+ fprintf (stderr, "Warning: qRcmd readspr %x too large: ignored\n",
+ regno);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Construct the reply */
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+
+ // special case for NPC
+ if(regno == NPC_CPU_REG_ADD)
+ temp_uint32 = get_npc();
+ else
+ {
+ err = gdb_read_reg(regno, &temp_uint32);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_command at reg. %x \n", err, regno);
+ }
+ else{
+ reg2hex (temp_uint32, cmd);
+ if (DEBUG_GDB) printf("Error %d Command readspr Read reg. %x = 0x%08x\n", err, regno, temp_uint32);
+ }
+ }
+
+ // pack the result into the buffer to send back
+ sprintf (cmd, "%8x", (unsigned int)temp_uint32);
+ ascii2hex (p_buf->data, cmd);
+ p_buf->len = strlen (p_buf->data);
+ put_packet (p_buf);
+ }
+ else if (0 == strncmp ("writespr ", cmd, strlen ("writespr")))
+ {
+ unsigned int regno;
+ uint32_t val;
+
+ /* Parse and return error if we fail */
+ if( 2 != sscanf (cmd, "writespr %4x %8x", ®no, &val))
+ {
+ fprintf (stderr, "Warning: qRcmd %s not recognized: ignored\n",
+ cmd);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* SPR out of range */
+ if (regno > MAX_SPRS)
+ {
+ fprintf (stderr, "Warning: qRcmd writespr %x too large: ignored\n",
+ regno);
+ put_str_packet ("E01");
+ return;
+ }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+
+ /* set the relevant register */
+ // special case for NPC
+ if(regno == NPC_CPU_REG_ADD)
+ set_npc(val);
+ else
+ {
+
+ err = gdb_write_reg(regno, val);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_command write Reg. %x = 0x%08x\n", err, regno, val);
+ put_str_packet ("E01");
+ return;
+ }
+ else{
+ if (DEBUG_GDB) printf("Error %d Command writespr Write reg. %x = 0x%08x\n", err, regno, val);
+ }
+ }
+ put_str_packet ("OK");
+ }
+} /* rsp_command () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP set request
+
+ @param[in] p_buf The request */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_set (struct rsp_buf *p_buf)
+{
+ if (0 == strncmp ("QPassSignals:", p_buf->data, strlen ("QPassSignals:")))
+ {
+ /* Passing signals not supported */
+ put_str_packet ("");
+ }
+ else if ((0 == strncmp ("QTDP", p_buf->data, strlen ("QTDP"))) ||
+ (0 == strncmp ("QFrame", p_buf->data, strlen ("QFrame"))) ||
+ (0 == strcmp ("QTStart", p_buf->data)) ||
+ (0 == strcmp ("QTStop", p_buf->data)) ||
+ (0 == strcmp ("QTinit", p_buf->data)) ||
+ (0 == strncmp ("QTro", p_buf->data, strlen ("QTro"))))
+ {
+ /* All tracepoint features are not supported. This reply is really only
+ needed to 'QTDP', since with that the others should not be
+ generated. */
+ put_str_packet ("");
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognized RSP set request: ignored\n");
+ }
+} /* rsp_set () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP restart request
+
+ For now we just put the program counter back to the one used with the last
+ vRun request. There is no point in unstalling the processor, since we'll
+ never get control back. */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_restart (void)
+{
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
+ put_str_packet ("E01");
+ return;
+ }
+ // OR32 Arc sim equivalent --> set_npc (rsp.start_addr);
+ /* Set NPC to reset vector 0x100 */
+ set_npc(rsp.start_addr);
+ /*
+ err = gdb_write_reg(NPC_CPU_REG_ADD, rsp.start_addr);
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in rsp_restart write Reg. %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
+ put_str_packet ("E01");
+ return;
+ }
+
+ else{
+ if (DEBUG_GDB) printf("Error %d Command Reset. Set NPC to Start vector %x = 0x%08x\n", err, NPC_CPU_REG_ADD, rsp.start_addr);
+ }
+ */
+} /* rsp_restart () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP step request
+
+ Parse the command to see if there is an address. Uses the underlying
+ generic step function, with EXCEPT_NONE.
+
+ @param[in] p_buf The full step packet */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_step (struct rsp_buf *p_buf)
+{
+ uint32_t addr; /* The address to step from, if any */
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // First set the chain
+ err = gdb_set_chain(SC_RISC_DEBUG); /* 1 RISC Debug Interface chain */
+ if(err > 0){
+ printf("Error %d to set RISC Debug Interface chain in the STEP command 's'\n", err);
+ rsp_client_close ();
+ return;
+ }
+
+ if (0 == strcmp ("s", p_buf->data))
+ {
+ // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
+ /* ---------- Npc ---------- */
+ addr = get_npc();
+ /*
+ err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
+ if(err > 0){
+ printf("Error %d to read NPC in the STEP command 's'\n", err);
+ rsp_client_close ();
+ return;
+ }
+ */
+ }
+ else if (1 != sscanf (p_buf->data, "s%x", &addr))
+ {
+ fprintf (stderr,
+ "Warning: RSP step address %s not recognized: ignored\n",
+ p_buf->data);
+
+ // Arc Sim Code --> addr = cpu_state.pc; /* Default uses current NPC */
+ /* ---------- NPC ---------- */
+ addr = get_npc();
+ /*
+ err = gdb_read_reg(NPC_CPU_REG_ADD, &addr);
+ if(err > 0){
+ printf("Error %d to read NPC in the STEP command 's'\n", err);
+ rsp_client_close ();
+ return;
+ }
+ */
+ }
+
+ //if (DEBUG_GDB) printf("rsp_step() --> Read NPC = 0x%08x\n", addr);
+ rsp_step_generic (addr, EXCEPT_NONE);
+
+} /* rsp_step () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP step with signal request
+
+ Currently null. Will use the underlying generic step function.
+
+ @param[in] p_buf The full step with signal packet */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_step_with_signal (struct rsp_buf *p_buf)
+{
+ printf ("RSP step with signal '%s' received\n", p_buf->data);
+
+} /* rsp_step_with_signal () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Generic processing of a step request
+
+ The signal may be EXCEPT_NONE if there is no exception to be
+ handled. Currently the exception is ignored.
+
+ The single step flag is set in the debug registers and then the processor
+ is unstalled.
+
+ @param[in] addr Address from which to step
+ @param[in] except The exception to use (if any) */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_step_generic (uint32_t addr,
+ uint32_t except)
+{
+ uint32_t temp_uint32;
+
+ /* Set the address as the value of the next program counter */
+
+ set_npc (addr);
+
+ /* Clear Debug Reason Register (DRR) 0x3015 */
+ // Arc sim --> cpu_state.sprs[SPR_DRR] = 0;
+ if(gdb_write_reg(DRR_CPU_REG_ADD, 0)) printf("Error write to DRR register\n");
+
+ /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) 0x3011 */
+ // Arc sim --> cpu_state.sprs[SPR_DMR2] &= ~SPR_DMR2_WGB;
+ if(gdb_read_reg(DMR2_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR2 register\n");
+ temp_uint32 &= ~SPR_DMR2_WGB;
+ if(gdb_write_reg(DMR2_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR2 register\n");
+
+ /* Set the single step trigger in Debug Mode Register 1 (DMR1) Register 0x3010 */
+ // Arc sim --> cpu_state.sprs[SPR_DMR1] |= SPR_DMR1_ST;
+ if(gdb_read_reg(DMR1_CPU_REG_ADD, &temp_uint32)) printf("Error read from DMR1 register\n");
+ temp_uint32 |= SPR_DMR1_ST;
+ if(gdb_write_reg(DMR1_CPU_REG_ADD, temp_uint32)) printf("Error write to DMR1 register\n");
+
+ /* Set traps to be handled by the debug unit in the Debug Stop Register (DSR) Register 0x3014 */
+ // Arc sim --> cpu_state.sprs[SPR_DSR] |= SPR_DSR_TE;
+ if(gdb_read_reg(DSR_CPU_REG_ADD, &temp_uint32)) printf("Error read from DSR register\n");
+ temp_uint32 |= SPR_DSR_TE;
+ if(gdb_write_reg(DSR_CPU_REG_ADD, temp_uint32)) printf("Error write to DSR register\n");
+
+ /* Unstall the processor */
+ set_stall_state (0);
+
+ /* Note the GDB client is now waiting for a reply. */
+ rsp.client_waiting = 1;
+
+} /* rsp_step_generic () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP 'v' packet
+
+ These are commands associated with executing the code on the target
+
+ @param[in] p_buf The request */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_vpkt (struct rsp_buf *p_buf)
+{
+ if (0 == strncmp ("vAttach;", p_buf->data, strlen ("vAttach;")))
+ {
+ /* Attaching is a null action, since we have no other process. We just
+ return a stop packet (using TRAP) to indicate we are stopped. */
+ put_str_packet ("S05");
+ return;
+ }
+ else if (0 == strcmp ("vCont?", p_buf->data))
+ {
+ /* For now we don't support this. */
+ put_str_packet ("");
+ return;
+ }
+ else if (0 == strncmp ("vCont", p_buf->data, strlen ("vCont")))
+ {
+ /* This shouldn't happen, because we've reported non-support via vCont?
+ above */
+ fprintf (stderr, "Warning: RSP vCont not supported: ignored\n" );
+ return;
+ }
+ else if (0 == strncmp ("vFile:", p_buf->data, strlen ("vFile:")))
+ {
+ /* For now we don't support this. */
+ fprintf (stderr, "Warning: RSP vFile not supported: ignored\n" );
+ put_str_packet ("");
+ return;
+ }
+ else if (0 == strncmp ("vFlashErase:", p_buf->data, strlen ("vFlashErase:")))
+ {
+ /* For now we don't support this. */
+ fprintf (stderr, "Warning: RSP vFlashErase not supported: ignored\n" );
+ put_str_packet ("E01");
+ return;
+ }
+ else if (0 == strncmp ("vFlashWrite:", p_buf->data, strlen ("vFlashWrite:")))
+ {
+ /* For now we don't support this. */
+ fprintf (stderr, "Warning: RSP vFlashWrite not supported: ignored\n" );
+ put_str_packet ("E01");
+ return;
+ }
+ else if (0 == strcmp ("vFlashDone", p_buf->data))
+ {
+ /* For now we don't support this. */
+ fprintf (stderr, "Warning: RSP vFlashDone not supported: ignored\n" );
+ put_str_packet ("E01");
+ return;
+ }
+ else if (0 == strncmp ("vRun;", p_buf->data, strlen ("vRun;")))
+ {
+ /* We shouldn't be given any args, but check for this */
+ if (p_buf->len > (int) strlen ("vRun;"))
+ {
+ fprintf (stderr, "Warning: Unexpected arguments to RSP vRun "
+ "command: ignored\n");
+ }
+
+ /* Restart the current program. However unlike a "R" packet, "vRun"
+ should behave as though it has just stopped. We use signal
+ 5 (TRAP). */
+ rsp_restart ();
+ put_str_packet ("S05");
+ }
+ else
+ {
+ fprintf (stderr, "Warning: Unknown RSP 'v' packet type %s: ignored\n",
+ p_buf->data);
+ put_str_packet ("E01");
+ return;
+ }
+} /* rsp_vpkt () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP write memory (binary) request
+
+ Syntax is:
+
+ X,:
+
+ Followed by the specified number of bytes as raw binary. Response should be
+ "OK" if all copied OK, E if error has occurred.
+
+ The length given is the number of bytes to be written. However the number
+ of data bytes may be greater, since '#', '$' and '}' are escaped by
+ preceding them by '}' and oring with 0x20.
+
+ @param[in] p_buf The command received */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_write_mem_bin (struct rsp_buf *p_buf)
+{
+ unsigned int addr; /* Where to write the memory */
+ int len; /* Number of bytes to write */
+ char *bindat; /* Pointer to the binary data */
+ int off = 0; /* Offset to start of binary data */
+ int newlen; /* Number of bytes in bin data */
+
+ if (2 != sscanf (p_buf->data, "X%x,%x:", &addr, &len))
+ {
+ fprintf (stderr, "Warning: Failed to recognize RSP write memory "
+ "command: %s\n", p_buf->data);
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Find the start of the data and "unescape" it */
+ bindat = p_buf->data;
+ while(off < GDB_BUF_MAX){
+ if(bindat[off] == ':'){
+ bindat = bindat + off + 1;
+ off++;
+ break;
+ }
+ off++;
+ }
+ if(off >= GDB_BUF_MAX){
+ put_str_packet ("E01");
+ return;
+ }
+
+ newlen = rsp_unescape (bindat, p_buf->len - off);
+
+ /* Sanity check */
+ if (newlen != len)
+ {
+ int minlen = len < newlen ? len : newlen;
+
+ fprintf (stderr, "Warning: Write of %d bytes requested, but %d bytes "
+ "supplied. %d will be written\n", len, newlen, minlen);
+ len = minlen;
+ }
+
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // Set chain 5 --> Wishbone Memory chain
+ err = gdb_set_chain(SC_WISHBONE);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Write the bytes to memory */
+ if (len)
+ {
+ swap_buf(bindat, len);
+
+ if (DEBUG_GDB_BLOCK_DATA){
+ uint32_t temp_uint32;
+ for (off = 0; off < len; off++){
+ temp_uint32 = (temp_uint32 << 8) | (0x000000ff & bindat[off]);
+ if((off %4 ) == 3){
+ temp_uint32 = htonl(temp_uint32);
+ }
+ switch(off % 16)
+ {
+ case 3:
+ printf("Add 0x%08x Data 0x%08x ", addr + off - 3, temp_uint32);
+ break;
+ case 7:
+ case 11:
+ printf("0x%08x ", temp_uint32);
+ break;
+ case 15:
+ printf("0x%08x\n", temp_uint32);
+ break;
+ default:
+ break;
+ }
+ if ((len - off == 1) && (off % 16) < 15) printf("\n");
+ }
+ }
+
+ err = gdb_write_block(addr, (uint32_t*)bindat, len);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+ if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
+ }
+ put_str_packet ("OK");
+
+} /* rsp_write_mem_bin () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP remove breakpoint or matchpoint request
+
+ For now only memory breakpoints are implemented, which are implemented by
+ substituting a breakpoint at the specified address. The implementation must
+ cope with the possibility of duplicate packets.
+
+ @todo This doesn't work with icache/immu yet
+
+ @param[in] p_buf The command received */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_remove_matchpoint (struct rsp_buf *p_buf)
+{
+ enum mp_type type; /* What sort of matchpoint */
+ uint32_t addr; /* Address specified */
+ int len; /* Matchpoint length (not used) */
+ struct mp_entry *mpe; /* Info about the replaced instr */
+
+ /* Break out the instruction */
+ if (3 != sscanf (p_buf->data, "z%1d,%x,%1d", (int *)&type, &addr, &len))
+ {
+ fprintf (stderr, "Warning: RSP matchpoint deletion request not "
+ "recognized: ignored\n");
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Sanity check that the length is 4 */
+ if (4 != len)
+ {
+ fprintf (stderr, "Warning: RSP matchpoint deletion length %d not "
+ "valid: 4 assumed\n", len);
+ len = 4;
+ }
+
+ /* Sort out the type of matchpoint */
+ switch (type)
+ {
+ case BP_MEMORY:
+ /* Memory breakpoint - replace the original instruction. */
+ mpe = mp_hash_delete (type, addr);
+
+ /* If the BP hasn't yet been deleted, put the original instruction
+ back. Don't forget to free the hash table entry afterwards. */
+ if (NULL != mpe)
+ {
+ // Arc Sim Code --> set_program32 (addr, mpe->instr);
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // Set chain 5 --> Wishbone Memory chain
+ err = gdb_set_chain(SC_WISHBONE);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+ err = gdb_write_block(addr, &mpe->instr, 4);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+ free (mpe);
+ }
+
+ put_str_packet ("OK");
+ return;
+
+ case BP_HARDWARE:
+ put_str_packet (""); /* Not supported */
+ return;
+
+ case WP_WRITE:
+ put_str_packet (""); /* Not supported */
+ return;
+
+ case WP_READ:
+ put_str_packet (""); /* Not supported */
+ return;
+
+ case WP_ACCESS:
+ put_str_packet (""); /* Not supported */
+ return;
+
+ default:
+ fprintf (stderr, "Warning: RSP matchpoint type %d not "
+ "recognized: ignored\n", type);
+ put_str_packet ("E01");
+ return;
+
+ }
+} /* rsp_remove_matchpoint () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Handle a RSP insert breakpoint or matchpoint request
+
+ For now only memory breakpoints are implemented, which are implemented by
+ substituting a breakpoint at the specified address. The implementation must
+ cope with the possibility of duplicate packets.
+
+ @todo This doesn't work with icache/immu yet
+
+ @param[in] p_buf The command received */
+/*---------------------------------------------------------------------------*/
+static void
+rsp_insert_matchpoint (struct rsp_buf *p_buf)
+{
+ enum mp_type type; /* What sort of matchpoint */
+ uint32_t addr; /* Address specified */
+ int len; /* Matchpoint length (not used) */
+ uint32_t instr;
+
+ /* Break out the instruction */
+ if (3 != sscanf (p_buf->data, "Z%1d,%x,%1d", (int *)&type, &addr, &len))
+ {
+ fprintf (stderr, "Warning: RSP matchpoint insertion request not "
+ "recognized: ignored\n");
+ put_str_packet ("E01");
+ return;
+ }
+
+ /* Sanity check that the length is 4 */
+ if (4 != len)
+ {
+ fprintf (stderr, "Warning: RSP matchpoint insertion length %d not "
+ "valid: 4 assumed\n", len);
+ len = 4;
+ }
+
+ /* Sort out the type of matchpoint */
+ switch (type)
+ {
+ case BP_MEMORY: // software-breakpoint Z0 break
+ /* Memory breakpoint - substitute a TRAP instruction */
+ // Make sure the processor is stalled
+ gdb_ensure_or1k_stalled();
+
+ // Set chain 5 --> Wishbone Memory chain
+ gdb_set_chain(SC_WISHBONE);
+
+ // Read the data from Wishbone Memory chain
+ // Arc Sim Code --> mp_hash_add (type, addr, eval_direct32 (addr, 0, 0));
+ gdb_read_block(addr, &instr, 4);
+
+ mp_hash_add (type, addr, instr);
+
+ // Arc Sim Code --> set_program32 (addr, OR1K_TRAP_INSTR);
+ instr = OR1K_TRAP_INSTR;
+ err = gdb_write_block(addr, &instr, 4);
+ if(err){
+ put_str_packet ("E01");
+ return;
+ }
+ put_str_packet ("OK");
+ return;
+
+ case BP_HARDWARE: // hardware-breakpoint Z1 hbreak
+ put_str_packet (""); /* Not supported */
+ return;
+
+ case WP_WRITE: // write-watchpoint Z2 watch
+ put_str_packet (""); /* Not supported */
+ return;
+
+ case WP_READ: // read-watchpoint Z3 rwatch
+ put_str_packet (""); /* Not supported */
+ return;
+
+ case WP_ACCESS: // access-watchpoint Z4 awatch
+ put_str_packet (""); /* Not supported */
+ return;
+
+ default:
+ fprintf (stderr, "Warning: RSP matchpoint type %d not "
+ "recognized: ignored\n", type);
+ put_str_packet ("E01");
+ return;
+ }
+} /* rsp_insert_matchpoint () */
+
+
+/*---------------------------------------------------------------------------
+Setup the or32 to init state
+
+---------------------------------------------------------------------------*/
+void setup_or32(void)
+{
+ uint32_t temp_uint32;
+ // First set the chain
+ err = gdb_set_chain(SC_REGISTER); /* 4 Register Chain */
+ if(err > 0){
+ if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err);
+ }
+ if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
+ if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );
+
+ if(gdb_write_reg(0x04, 0x00000001)) printf("Error write to register\n");
+ if (DEBUG_GDB) printf("Write to chain 4 SC_REGISTER at add 0x00000004 = 0x00000001\n");
+
+ // if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
+ // if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );
+
+ // if(gdb_read_reg(0x04, &temp_uint32)) printf("Error read from register\n");
+ // if (DEBUG_GDB) printf("Read from chain 4 SC_REGISTER at add 0x00000004 = 0x%08x\n", temp_uint32 );
+
+ if(gdb_write_reg(0x00, 0x01000001)) printf("Error write to register\n");
+ if (DEBUG_GDB) printf("Write to chain 4 SC_REGISTER at add 0x00000000 = 0x01000001\n");
+}
+
+// Function to check if the processor is stalled - if not then stall it.
+// this is useful in the event that GDB thinks the processor is stalled, but has, in fact
+// been hard reset on the board and is running.
+static void gdb_ensure_or1k_stalled()
+{
+ unsigned char stalled;
+ dbg_cpu0_read_ctrl(0, &stalled);
+ if ((stalled & 0x1) != 0x1)
+ {
+ if (DEBUG_GDB)
+ printf("Processor not stalled, like we thought\n");
+
+ // Set the TAP controller to its OR1k chain
+ dbg_set_tap_ir(JI_DEBUG);
+ gdb_chain = -1;
+
+ // Processor isn't stalled, contrary to what we though, so stall it
+ printf("Stalling or1k\n");
+ dbg_cpu0_write_ctrl(0, 0x01); // stall or1k
+ }
+}
+
+
+int gdb_read_reg(uint32_t adr, uint32_t *data) {
+ switch (gdb_chain) {
+ case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data) ? ERR_CRC : ERR_NONE;
+ case SC_REGISTER: return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ?
+ ERR_CRC : ERR_NONE;
+ case SC_WISHBONE: return dbg_wb_read32(adr, data) ? ERR_CRC : ERR_NONE;
+ case SC_TRACE: *data = 0; return 0;
+ default: return JTAG_PROXY_INVALID_CHAIN;
+ }
+}
+
+int gdb_write_reg(uint32_t adr, uint32_t data) {
+ switch (gdb_chain) { /* remap registers, to be compatible with jp1 */
+ case SC_RISC_DEBUG: if (adr == JTAG_RISCOP) adr = 0x00;
+ return dbg_cpu0_write(adr, data) ? ERR_CRC : ERR_NONE;
+ case SC_REGISTER: return dbg_cpu0_write_ctrl(adr, data) ? ERR_CRC : ERR_NONE;
+ case SC_WISHBONE: return dbg_wb_write32(adr, data) ? ERR_CRC : ERR_NONE;
+ case SC_TRACE: return 0;
+ default: return JTAG_PROXY_INVALID_CHAIN;
+ }
+}
+
+int gdb_read_block(uint32_t adr, uint32_t *data, int len) {
+ if (DEBUG_CMDS) printf("rb %d\n", gdb_chain);
+ switch (gdb_chain) {
+ case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ?
+ ERR_CRC : ERR_NONE;
+ default: return JTAG_PROXY_INVALID_CHAIN;
+ }
+}
+
+int gdb_write_block(uint32_t adr, uint32_t *data, int len) {
+ if (DEBUG_CMDS) printf("wb %d\n", gdb_chain);
+ switch (gdb_chain) {
+ case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ?
+ ERR_CRC : ERR_NONE;
+ default: return JTAG_PROXY_INVALID_CHAIN;
+ }
+}
+
+int gdb_set_chain(int chain) {
+ switch (chain) {
+ case SC_RISC_DEBUG:
+ case SC_REGISTER:
+ case SC_TRACE:
+ case SC_WISHBONE: gdb_chain = chain;
+ return ERR_NONE;
+ default: return JTAG_PROXY_INVALID_CHAIN;
+ }
+}
+
+/* Added by CZ 24/05/01 */
+int GetServerSocket(const char* name, const char* proto, int port) {
+ struct servent *service;
+ struct protoent *protocol;
+ struct sockaddr_in sa;
+ struct hostent *hp;
+ int sockfd;
+ char myname[256];
+ //int flags; --changed to socklen_t for c++?! -- Julius
+ socklen_t flags;
+ char sTemp[256];
+
+ /* First, get the protocol number of TCP */
+ if (!(protocol = getprotobyname(proto))) {
+ sprintf(sTemp, "Unable to load protocol \"%s\"", proto);
+ perror(sTemp);
+ return 0;
+ }
+ tcp_level = protocol->p_proto; /* Save for later */
+
+ /* If we weren't passed a non standard port, get the port
+ from the services directory. */
+ if (!port && (service = getservbyname(name, protocol->p_name)))
+ port = ntohs(service->s_port);
+
+ /* Create the socket using the TCP protocol */
+ if ((sockfd = socket(PF_INET, SOCK_STREAM, protocol->p_proto)) < 0) {
+ perror("Unable to create socket");
+ return 0;
+ }
+
+ flags = 1;
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
+ (const char*)&flags, sizeof(int)) < 0) {
+ sprintf(sTemp, "Can not set SO_REUSEADDR option on socket %d", sockfd);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ /* The server should also be non blocking. Get the current flags. */
+ if(fcntl(sockfd, F_GETFL, &flags) < 0) {
+ sprintf(sTemp, "Unable to get flags for socket %d", sockfd);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ /* Set the nonblocking flag */
+ if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x",
+ sockfd, flags | O_NONBLOCK);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ /* Find out what our address is */
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ gethostname(myname, sizeof(myname));
+ if(!(hp = gethostbyname(myname))) {
+ perror("Unable to read hostname");
+ close(sockfd);
+ return 0;
+ }
+
+ /* Bind our socket to the appropriate address */
+ sa.sin_family = hp->h_addrtype;
+ sa.sin_port = htons(port);
+ if(bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_in)) < 0) {
+ sprintf(sTemp, "Unable to bind socket %d to port %d", sockfd, port);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+ serverIP = sa.sin_addr.s_addr;
+ flags = sizeof(struct sockaddr_in);
+ if(getsockname(sockfd, (struct sockaddr*)&sa, &flags) < 0) {
+ sprintf(sTemp, "Unable to get socket information for socket %d", sockfd);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+ serverPort = ntohs(sa.sin_port);
+
+ /* Set the backlog to 1 connections */
+ if(listen(sockfd, 1) < 0) {
+ sprintf(sTemp, "Unable to set backlog on socket %d to %d", sockfd, 1);
+ perror(sTemp);
+ close(sockfd);
+ return 0;
+ }
+
+ return sockfd;
+}
+
+//void HandleServerSocket(Boolean block) {
+void HandleServerSocket(void) {
+ struct pollfd fds[2];
+ int n;
+ uint32_t temp_uint32;
+
+ rebuild:
+ n = 0;
+ if(!server_fd && !gdb_fd) return;
+
+ if(server_fd) {
+ fds[n].fd = server_fd;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ }
+ if(gdb_fd) {
+ fds[n].fd = gdb_fd;
+ fds[n].events = POLLIN;
+ fds[n++].revents = 0;
+ }
+
+ while(1) {
+ switch(poll(fds, n, -1)) {
+ case 0:
+ case -1:
+ if(errno == EINTR) continue;
+ perror("poll");
+ server_fd = 0;
+ return;
+ default:
+ /* Make sure to handle the gdb port first! */
+ if (gdb_fd && (fds[0].revents && !server_fd || fds[1].revents && server_fd))
+ {
+ int revents = server_fd ? fds[1].revents : fds[0].revents;
+ if (revents & POLLIN){
+ /* If we have an unacknowledged exception tell the GDB client. If this
+ exception was a trap due to a memory breakpoint, then adjust the NPC. */
+ if (rsp.client_waiting)
+ {
+ err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32);
+ if(err) printf("Error read from PPC register\n");
+ if ((TARGET_SIGNAL_TRAP == rsp.sigval) &&
+ (NULL != mp_hash_lookup (BP_MEMORY, temp_uint32)))
+ {
+ set_npc (temp_uint32);
+ }
+
+ rsp_report_exception();
+ rsp.client_waiting = 0; /* No longer waiting */
+ }
+ GDBRequest();
+ }
+ else {/* Error Occurred */
+ printf("\n%sSocket closed.\n",printTime());
+ //fprintf(stderr,
+ //"Received flags 0x%08x on gdb socket. Shutting down.\n", revents);
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+ }
+
+ // Go to blocking accept() instead of looping around through poll(),
+ // takes a loot of CPU resources and it doesn't work when
+ // reconnecting... Jonas Rosén
+ if(!gdb_fd)
+ {
+ JTAGRequest();
+ rsp.client_waiting = 0; /* No longer waiting */
+ goto rebuild;
+ }
+
+ if(fds[0].revents && server_fd) {
+ if(fds[0].revents & POLLIN) {
+ JTAGRequest();
+ rsp.client_waiting = 0; /* No longer waiting */
+ goto rebuild;
+ } else { /* Error Occurred */
+ fprintf(stderr,
+ "Received flags 0x%08x on server. Shutting down.\n",
+ fds[0].revents);
+ close(server_fd);
+ server_fd = 0;
+ serverPort = 0;
+ serverIP = 0;
+ return;
+ }
+ }
+ break;
+ } /* End of switch statement */
+ } /* End of while statement */
+}
+
+void JTAGRequest(void) {
+ struct sockaddr_in sa;
+ struct sockaddr* addr = (struct sockaddr*)&sa;
+ //int n = sizeof(struct sockaddr_in); --changed to socklen_t from int type
+ socklen_t n = sizeof(struct sockaddr_in);
+ int fd = accept(server_fd, addr, &n);
+ int on_off = 0; /* Turn off Nagel's algorithm on the socket */
+ int flags;
+ char sTemp[256];
+ if (DEBUG_GDB) printf("JTAGRequest\n");
+
+ if(fd < 0) {
+ /* This is valid, because a connection could have started,
+ and then terminated due to a protocol error or user
+ initiation before the accept could take place. */
+ if(errno != EWOULDBLOCK && errno != EAGAIN) {
+ perror("accept");
+ close(server_fd);
+ server_fd = 0;
+ serverPort = 0;
+ serverIP = 0;
+ }
+ return;
+ }
+
+ if(gdb_fd) {
+ close(fd);
+ return;
+ }
+
+ if(fcntl(fd, F_GETFL, &flags) < 0) {
+ sprintf(sTemp, "Unable to get flags for gdb socket %d", fd);
+ perror(sTemp);
+ close(fd);
+ return;
+ }
+
+ /* Rene
+ if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ sprintf(sTemp, "Unable to set flags for gdb socket %d to value 0x%08x",
+ fd, flags | O_NONBLOCK);
+ perror(sTemp);
+ close(fd);
+ return;
+ } Rene */
+
+ if(setsockopt(fd, tcp_level, TCP_NODELAY, &on_off, sizeof(int)) < 0) {
+ sprintf(sTemp, "Unable to disable Nagel's algorithm for socket %d.\nsetsockopt", fd);
+ perror(sTemp);
+ close(fd);
+ return;
+ }
+
+ printf("\n%sConnection established from %s on port %d\n", printTime(),inet_ntoa(sa.sin_addr),ntohs(sa.sin_port));
+ gdb_fd = fd;
+}
+
+
+/*---------------------------------------------------------------------------
+* Decode the GDB command.
+*
+*---------------------------------------------------------------------------*/
+static void GDBRequest(void) {
+ JTAGProxyWriteMessage msg_write;
+ JTAGProxyReadMessage msg_read;
+ JTAGProxyChainMessage msg_chain;
+ JTAGProxyWriteResponse resp_write;
+ JTAGProxyReadResponse resp_read;
+ JTAGProxyChainResponse resp_chain;
+ JTAGProxyBlockWriteMessage *msg_bwrite;
+ JTAGProxyBlockReadMessage msg_bread;
+ JTAGProxyBlockWriteResponse resp_bwrite;
+ JTAGProxyBlockReadResponse *resp_bread;
+ char *p_buf;
+ uint32_t command;
+ uint32_t length;
+ int len, i;
+
+ /* First, we must read the incomming command */
+ if(gdb_read(&command, sizeof(uint32_t)) < 0) {
+ client_close ('1');
+ return;
+ }
+ command = ntohl(command);
+
+ if(gdb_read(&length, sizeof(uint32_t)) < 0) {
+ client_close ('2');
+ return;
+ }
+ length = ntohl(length);
+ if (DEBUG_GDB) printf("\n%s-----------------------------------------------------\nCommand %d Length %d ", printTime(), command, length);
+
+ if (DEBUG_GDB){
+ switch(command){
+ case JTAG_COMMAND_READ:
+ printf("JTAG_COMMAND_READ \n");
+ break;
+ case JTAG_COMMAND_WRITE:
+ printf("JTAG_COMMAND_WRITE \n");
+ break;
+ case JTAG_COMMAND_BLOCK_READ:
+ printf("JTAG_COMMAND_BLOCK_READ \n");
+ break;
+ case JTAG_COMMAND_BLOCK_WRITE:
+ printf("JTAG_COMMAND_BLOCK_WRITE\n");
+ break;
+ case JTAG_COMMAND_CHAIN:
+ printf("JTAG_COMMAND_CHAIN \n");
+ break;
+ }
+ }
+
+ /* Now, verify the protocol and implement the command */
+ switch(command) {
+ case JTAG_COMMAND_WRITE:
+ if(length != sizeof(msg_write) - 8) {
+ ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ p_buf = (char*)&msg_write;
+ if(gdb_read(&p_buf[8], length) < 0) {
+ client_close ('3');
+ return;
+ }
+ msg_write.address = ntohl(msg_write.address);
+ msg_write.data_H = ntohl(msg_write.data_H);
+ msg_write.data_L = ntohl(msg_write.data_L);
+ err = gdb_write_reg(msg_write.address, msg_write.data_L);
+ resp_write.status = htonl(err);
+ if (DEBUG_GDB) printf("Write Reg to Chain %d at add 0x%08x -> H-Data 0x%08x L-Data 0x%08x Error %d",
+ gdb_chain, msg_write.address, msg_write.data_H, msg_write.data_L, err);fflush (stdout);
+ if(gdb_write(&resp_write, sizeof(resp_write)) < 0) {
+ client_close ('4');
+ return;
+ }
+ break;
+ case JTAG_COMMAND_READ:
+ if(length != sizeof(msg_read) - 8) {
+ ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ p_buf = (char*)&msg_read;
+ if(gdb_read(&p_buf[8], length) < 0) {
+ client_close ('5');
+ return;
+ }
+ msg_read.address = ntohl(msg_read.address);
+ err = gdb_read_reg(msg_read.address, (uint32_t *)&resp_read.data_L);
+ if (DEBUG_GDB) printf("Read Reg from Chain %d at add 0x%08x", gdb_chain, msg_read.address);
+ resp_read.status = htonl(err);
+ resp_read.data_H = 0;
+ resp_read.data_L = htonl(resp_read.data_L);
+ if(gdb_write(&resp_read, sizeof(resp_read)) < 0) {
+ client_close ('6');
+ return;
+ }
+ if (DEBUG_GDB) printf(" --> Data 0x%08x Error %d\n", htonl(resp_read.data_L), err);fflush (stdout);
+ break;
+ case JTAG_COMMAND_BLOCK_WRITE:
+ if(length < sizeof(JTAGProxyBlockWriteMessage)-8) {
+ ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ if(!(p_buf = (char*)malloc(8+length))) {
+ ProtocolClean(length, JTAG_PROXY_OUT_OF_MEMORY);
+ return;
+ }
+ msg_bwrite = (JTAGProxyBlockWriteMessage*)p_buf;
+ if(gdb_read(&p_buf[8], length) < 0) {
+ client_close ('5');
+ free(p_buf);
+ return;
+ }
+ msg_bwrite->address = ntohl(msg_bwrite->address);
+ msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
+ if (DEBUG_GDB) printf("Block Write to Chain %d start add 0x%08x Write %d (32 bit words):\n\n", gdb_chain, msg_bwrite->address, msg_bwrite->nRegisters);
+ for(i=0;inRegisters;i++) {
+ msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
+ if (DEBUG_GDB_BLOCK_DATA){
+ if ((i % 4) == 0) printf("Add 0x%08x Data 0x%08x ", msg_bwrite->address + (i * 4), msg_bwrite->data[i]);
+ else if ((i % 4) == 3) printf("0x%08x\n", msg_bwrite->data[i]);
+ else printf("0x%08x ", msg_bwrite->data[i]);
+
+ // add a new line on the last data, but not if it is the last one in the colum
+ if ((msg_bwrite->nRegisters - i == 1) && (i % 4) < 3) printf("\n");
+ }
+ }
+ err = gdb_write_block(msg_bwrite->address, (uint32_t*)msg_bwrite->data, msg_bwrite->nRegisters * 4);
+ if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout);
+ resp_bwrite.status = htonl(err);
+ free(p_buf);
+ msg_bwrite = (JTAGProxyBlockWriteMessage *)NULL;
+ p_buf = (char *)msg_bwrite;
+ if(gdb_write(&resp_bwrite, sizeof(resp_bwrite)) < 0) {
+ client_close ('4');
+ return;
+ }
+ break;
+ case JTAG_COMMAND_BLOCK_READ:
+ if(length != sizeof(msg_bread) - 8) {
+ ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ p_buf = (char*)&msg_bread;
+ if(gdb_read(&p_buf[8], length) < 0) {
+ client_close ('5');
+ return;
+ }
+ msg_bread.address = ntohl(msg_bread.address);
+ msg_bread.nRegisters = ntohl(msg_bread.nRegisters);
+ if (DEBUG_GDB) printf("Block Read from Chain %d start add 0x%08x Read %d (32 bit words):\n\n", gdb_chain, msg_bread.address, msg_bread.nRegisters);
+ len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1);
+ if(!(p_buf = (char*)malloc(len))) {
+ ProtocolClean(0, JTAG_PROXY_OUT_OF_MEMORY);
+ return;
+ }
+ resp_bread = (JTAGProxyBlockReadResponse*)p_buf;
+ err = gdb_read_block(msg_bread.address, (uint32_t*)resp_bread->data, msg_bread.nRegisters * 4);
+ for(i=0;idata[i] = htonl(resp_bread->data[i]);
+ if (DEBUG_GDB_BLOCK_DATA){
+ if ((i % 4) == 0) printf("Add 0x%08x Data 0x%08x ", msg_bread.address + (i * 4), htonl(resp_bread->data[i]));
+ else if ((i % 4) == 3) printf("0x%08x\n", htonl(resp_bread->data[i]));
+ else printf("0x%08x ", htonl(resp_bread->data[i]));
+ }
+ // add a new line on the last data, but not if it is the last one in the colum
+ if ((msg_bread.nRegisters - i == 1) && (i % 4) < 3) printf("\n");
+ }
+ resp_bread->status = htonl(err);
+ resp_bread->nRegisters = htonl(msg_bread.nRegisters);
+ if (DEBUG_GDB) printf("\nError %x\n", err);fflush (stdout);
+ if(gdb_write(resp_bread, len) < 0) {
+ client_close ('6');
+ free(p_buf);
+ return;
+ }
+ free(p_buf);
+ resp_bread = (JTAGProxyBlockReadResponse *)NULL;
+ p_buf = (char *)resp_bread;
+ break;
+ case JTAG_COMMAND_CHAIN:
+ if(length != sizeof(msg_chain) - 8) {
+ ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR);
+ return;
+ }
+ p_buf = (char*)&msg_chain;
+ if(gdb_read(&p_buf[8], sizeof(msg_chain)-8) < 0) {
+ client_close ('7');
+ return;
+ }
+ msg_chain.chain = htonl(msg_chain.chain);
+ err = gdb_set_chain(msg_chain.chain);
+ resp_chain.status = htonl(err);
+ if (DEBUG_GDB){
+ switch(msg_chain.chain){
+ case SC_GLOBAL: /* 0 Global BS Chain */
+ printf("Set Chain %d Global BS Chain Error %x\n", msg_chain.chain, err);
+ break;
+ case SC_RISC_DEBUG: /* 1 RISC Debug Interface chain */
+ printf("Set Chain %d RISC Debug Interface chain Error %x\n", msg_chain.chain, err);
+ break;
+ case SC_RISC_TEST: /* 2 RISC Test Chain */
+ printf("Set Chain %d RISC Test Chain Error %x\n", msg_chain.chain, err);
+ break;
+ case SC_TRACE: /* 3 Trace Chain */
+ printf("Set Chain %d Trace Chain Error %x\n", msg_chain.chain, err);
+ break;
+ case SC_REGISTER: /* 4 Register Chain */
+ printf("Set Chain %d Register Chain Error %x\n", msg_chain.chain, err);
+ break;
+ case SC_WISHBONE: /* 5 Memory chain */
+ printf("Set Chain %d Wishbone Memory chain Error %x\n", msg_chain.chain, err);
+ break;
+ case SC_BLOCK: /* 6 Block Chains */
+ printf("Set Chain %d Block Chains Error %x\n", msg_chain.chain, err);
+ break;
+ default: /* Invalid chain */
+ printf("Set Chain %d Invalid chain Error %x\n", msg_chain.chain, err);
+ break;
+ }
+ fflush (stdout);
+ }
+ if(gdb_write(&resp_chain, sizeof(resp_chain)) < 0) {
+ client_close ('8');
+ return;
+ }
+ break;
+ default:
+ perror("Unknown JTAG command.");fflush (stdout);
+ ProtocolClean(length, JTAG_PROXY_COMMAND_NOT_IMPLEMENTED);
+ break;
+ }
+}
+
+static void ProtocolClean(int length, int32_t err) {
+ char buffer[4096];
+
+ err = htonl(err);
+ if((gdb_read(buffer, length) < 0) || (gdb_write(&err, sizeof(err)) < 0) && gdb_fd) {
+ perror("gdb socket - 9");
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+}
+
+static int gdb_write(void* p_buf, int len) {
+ int n;
+ char* w_buf = (char*)p_buf;
+ struct pollfd block;
+
+ while(len) {
+ if((n = write(gdb_fd, w_buf, len)) < 0) {
+ switch(errno) {
+ case EWOULDBLOCK: /* or EAGAIN */
+ /* We've been called on a descriptor marked
+ for nonblocking I/O. We better simulate
+ blocking behavior. */
+ block.fd = gdb_fd;
+ block.events = POLLOUT;
+ block.revents = 0;
+ poll(&block, 1, -1);
+ continue;
+ case EINTR:
+ continue;
+ case EPIPE:
+ close(gdb_fd);
+ gdb_fd = 0;
+ return -1;
+ default:
+ return -1;
+ }
+ } else {
+ len -= n;
+ w_buf += n;
+ }
+ }
+ return 0;
+}
+
+static int gdb_read(void* p_buf, int len) {
+ int n;
+ char* r_buf = (char*)p_buf;
+ struct pollfd block;
+
+ while(len) {
+ if((n = read(gdb_fd, r_buf, len)) < 0) {
+ switch(errno) {
+ case EWOULDBLOCK: /* or EAGAIN */
+ /* We've been called on a descriptor marked
+ for nonblocking I/O. We better simulate
+ blocking behavior. */
+ block.fd = gdb_fd;
+ block.events = POLLIN;
+ block.revents = 0;
+ poll(&block, 1, -1);
+ continue;
+ case EINTR:
+ continue;
+ default:
+ return -1;
+ }
+ } else if(n == 0) {
+ close(gdb_fd);
+ gdb_fd = 0;
+ return -1;
+ } else {
+ len -= n;
+ r_buf += n;
+ }
+ }
+ return 0;
+}
+
+
+/*****************************************************************************
+* Close the connection to the client if it is open
+******************************************************************************/
+static void client_close (char err)
+{
+ if(gdb_fd) {
+ perror("gdb socket - " + err);
+ close(gdb_fd);
+ gdb_fd = 0;
+ }
+} /* client_close () */
+
+
+/*---------------------------------------------------------------------------*/
+/* Swap a buffer of 4-byte from 1234 to 4321
+
+ parameter[in] p_buf and len
+ parameter[out] none */
+/*---------------------------------------------------------------------------*/
+static void swap_buf(char* p_buf, int len)
+{
+ int temp;
+ int n = 0;
+
+ if (len > 2)
+ {
+ while(n < len){
+ // swap 0 and 3
+ temp = p_buf[n];
+ p_buf[n] = p_buf[n + 3];
+ p_buf[n + 3] = temp;
+ // swap 1 and 2
+ temp = p_buf[n + 1];
+ p_buf[n + 1] = p_buf[n + 2];
+ p_buf[n + 2] = temp;
+
+ n += 4;
+ }
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*!Set the stall state of the processor
+
+ @param[in] state If non-zero stall the processor. */
+/*---------------------------------------------------------------------------*/
+static void
+set_stall_state (int state)
+{
+
+ if(state == 0)
+ {
+ err = dbg_cpu0_write_ctrl(0, 0); /* unstall or1k */
+ stallState = UNSTALLED;
+ npcIsCached = 0;
+ rsp.sigval = TARGET_SIGNAL_NONE;
+ }
+ else
+ {
+ err = dbg_cpu0_write_ctrl(0, 0x01); /* stall or1k */
+ stallState = STALLED;
+ }
+
+ if(err > 0 && DEBUG_GDB)printf("Error %d in set_stall_state Stall state = %d\n", err, state);
+
+} /* set_stall_state () */
+
+
+/*---------------------------------------------------------------------------*/
+/*!Close down the connection with GDB in the event of a kill signal
+
+ */
+/*---------------------------------------------------------------------------*/
+void gdb_close()
+{
+ if (gdb_fd) close(gdb_fd);
+ // Maybe do other things here!
+}
Index: or_debug_proxy/README
===================================================================
--- or_debug_proxy/README (nonexistent)
+++ or_debug_proxy/README (revision 1779)
@@ -0,0 +1,325 @@
+===============================================================================
+-- OpenRISC Debug Proxy --
+===============================================================================
+
+===============================================================================
+-- Description --
+===============================================================================
+A console application that implements a GDB stub and various ways to
+communicate with an OpenRISC processor system. This done by initally making a
+connection to a target system before handling a connection from a GDB client
+and relaying debug commands. Connections to the target can be made in many
+ways, however debugging FPGA or ASIC targets will be through use of the ORSoC
+USB debug cable.
+===============================================================================
+-- Versions --
+===============================================================================
+0.1.0 090201 jb@orsoc.se
+0.1.1 090304 jb@orsoc.se
+0.1.2 090511 jb@orsoc.se
+
+===============================================================================
+-- Installation --
+===============================================================================
+
+The OR debug proxy application runs on multiple platforms only requiring
+slightly different driver configurations on each. Currently, Cygwin Windows,
+several Linux distos and Mac OS X (10.4 and above) are supported. All require
+installation of some form of the FTDI Chip FTD2XX driver. Instructions for
+each platform follow.
+
+-------------------------------------------------------------------------------
+-- Installation on Cygwin Windows --
+-------------------------------------------------------------------------------
+
+-- ORSoC OpenRISC USB debug cable driver installation --
+
+ As per the installation instructions included in FTDI Chip's D2XX Windows
+ driver. http://www.ftdichip.com/Drivers/D2XX.htm
+
+-- Compilation of the OpenRISC Debug Proxy application --
+
+ While in the same directory which this file is located in, run a simple
+ "make" command.
+
+ user@cygwin-host ~/or_debug_proxy
+ $ make
+
+ Run the resulting executable (or_debug_proxy.exe) for usage details.
+
+-------------------------------------------------------------------------------
+-- Installation on Linux
+-------------------------------------------------------------------------------
+
+-- ORSoC OpenRISC USB debug cable driver installation --
+
+Before we begin:
+
+It is required that the Linux distribution have a version 2.4 kernel, or
+above. This is due to the USB driver libraries by FTDI Chip used to interface
+with the USB debug device.
+
+The ORSoC USB debugger cable uses a FTDI dual UART/FIFO chip.
+
+An aside: These USB to serial devices typically trigger the loading of another
+FTDI driver when they're attached to the system. This is the ftdi_sio driver
+and now comes standard in newer kernels. This is of use to us, as one of the
+two serial devices will remain is a standard uart under /dev/ttyUSBx. However,
+to enable a high-speed JTAG interface with our hardware we require newer,
+specialised drivers from FTDI called the D2XX drivers.
+
+The Linux driver can be obtained from FTDI Chip's website,
+http://www.ftdichip.com, and is found under the links to "Drivers" and then
+"D2XX". At the time of writing, the latest version was libftd2xx 0.4.16 and
+could be downloaded directly off their site from
+http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.16.tar.gz
+
+Statically linked driver:
+
+The simplest way to enable these drivers is to link the application
+statically - that is, have a copy of the driver along with the debugging
+application. This is much simpler than the following driver installation
+instructions. Typically in the FTDI drivers there is also a directory called
+static_lib/ and this contains a driver that can be statically linked against
+when compiling. To compile the OpenRISC debug proxy like this, copy the file in
+that static_lib/ path into the lib/ directory under the or_debug_proxy/
+build directory, and do:
+
+ user@host:~/or_debug_proxy$ make or_debug_proxy_static
+
+This will result in the executable being statically linked to the driver file
+in the the lib/ folder.
+
+Dynamically linked driver install directions:
+
+Uncompress the driver package (tar xzvf libftd2xx0.4.16.tar.gz) and read the
+file "readme.dat" located inside, but don't complete their way of installing
+yet. Their installation method should be modified slightly to allow easier use
+of the USB device by users. Read the following before performing the install
+as per the instructions in "readme.dat", and ammend their installation process
+as you go.
+
+* In step 4, create an additional symbolic link, however this time with only a
+ trailing zero, like so:
+
+ user@host:/usr/local/lib$ ln -s libftd2xx.so.x.x.xx libftd2xx.so.0
+
+* Again, in step 6, create an additional symbolic link with only a trailing
+ zero:
+
+ user@host:/usr/lib$ ln -s /usr/local/lib/libftd2xx.so.x.x.xx libftd2xx.so.0
+
+* In step 7 (the following may vary depending on your distribution, however in
+ the most recent Ubuntu our suggested modification was required) instead of
+ the line provided in "readme.dat", use the following in your /etc/fstab file
+ (note the difference is a change from "usbdevfs" to "usbfs")
+
+ none /proc/bus/usb usbfs defaults,devmode=0666 0 0
+
+* The last step (mount -a) outlined in "readme.dat" can then be performed.
+
+-- Setting USB device permissions --
+
+Depending on the Linux distribution and how recent it is, the method for
+defining the permissions of the USB device when it's loaded by the kernel can
+vary.
+
+* Recent udev systems (most 2.6 kernel systems)
+
+There can be variations in the way udev organises its files for setting up
+rules and permissions of devices attached to the system, but the following
+should cover most systems.
+
+Do a listing of the udev rules directory
+
+ user@host:~$ ls /etc/udev/rules.d/
+
+There should be a file somewhere, with the word "permissions" in the name. On
+some systems it could be called "40-permissions.rules", on others possibly
+"020_permissions.rules". Locate the permissions file in /etc/udev/rules.d/
+and, as the super user (root), open the file to edit. The author prefers nano.
+
+ user@host:/etc/udev/rules.d$ sudo nano 40-permissions.rules
+ [sudo] password for user:
+
+Of course, editing as super user (sudo'ing) will require the ability to sudo.
+
+The following can differ from system to system. In this case, a recent version
+of Ubuntu, the file "40-permissions.rules" was present and will be edited.
+
+In this particular permissions file there are different sections, some with
+labels.
+
+Search for the lines with LABEL="usb_serial_start" and
+LABEL="usb_serial_end". In BETWEEN these two LABEL lines, insert two new lines
+containing the following:
+
+ # Permissions for ORSoC USB debugger FT2232 device
+ ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0666", GROUP="tty"
+
+If these LABEL="" lines cannot be found (for instance, different distros have
+their udev setup differently) insert the above line anywhere in the file. This
+is not a definite way of enabling these permissions, and udev exists in many
+forms and configurations, so if this does not work, please contact the author
+regarding the issue.
+
+* Fedora 9
+
+As an example of a slightly different system, Fedora 9 does not have a
+xx-permissions.rules file. The solution is to create a new file, but in this
+case choose the name "51-permissions.rules". It can have just the rule listed
+above:
+
+ # Permissions for ORSoC USB debugger FT2232 device
+ ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0666", GROUP="tty"
+
+The reason for the filename change is that the udev rules files are read in
+lexical order (i.e. the order they would appear in a dictionary). With Fedora
+9 the old FTDI driver is included as standard, and there is default rule in
+50-udev-default.rules, which would override anything in 40-permissions.rules
+(since it would be read first). By using the name 51-permissions.rules, our
+rule will override anything set in 50-udev-default.rules.
+
+If you find problems with permissions, then check that no later rules files
+are overriding settings.
+
+The devices whose permissions are set are /dev/ttyUSB0 /dev/ttyUSB1, the
+/dev/usbdevnnn for the USB slot (nnn) being used, and the files in
+/dev/bus/usb/nnn/xxx. They should all be in group tty and have permission
+rw-rw-rw.
+
+* Older systems, (early udev, devfs)
+
+None of these systems were tested, however it should be easy enough to locate
+the device by the vendor ID and product ID on the USB bus. See the Udev
+instructions above for these values.
+
+* Reloading the ftdi_sio driver
+
+If it is desired that the D2XX drivers be unloaded and the original ftdi_sio one
+reactivated (recreating the two /dev/ttyUSB devices), it is as simple as
+removing and replacing the USB dongle from the system. However, it can also be
+done at the prompt by first running as root "modprobe -r ftdi_sio", and then
+"modprobe ftdi_sio vendor=0x0403 product=0x6010", which totally removes and
+then reloads the device.
+
+-- Compilation of the OpenRISC Debug Proxy application --
+
+ While in the same directory which this file is located in, run a simple
+ "make" command.
+
+ user@host:~/or_debug_proxy$ make
+
+ The proxy application can then be run with the desired options, or for
+ usage details, run the program with no options specified.
+
+ user@host:~/or_debug_proxy$ ./or_debug_proxy
+
+ Invalid or insufficient arguments
+
+ OpenRISC GDB proxy server usage: or_debug_proxy -server_type port
+
+ server_type:
+ -r Start a server using RSP, connection to hadware target via
+ USB
+ -j Start a server using legacy OR remote JTAG protocol, to
+ hardware target via USB
+ -v Start a server using RSP, connection to RTL sim. VPI server
+ target via sockets
+
+ port_number:
+ Any free port within the usable range of 0 - 65535
+
+ Example:
+ Start a GDB server on port 5555, using RSP, connecting to
+ hardware target via USB
+ or_debug_proxy -r 5555
+
+
+* Platforms tested, and known to be working, on:
+ Ubuntu 8.04
+ Debian
+
+-------------------------------------------------------------------------------
+-- Installation on Mac OS X --
+-------------------------------------------------------------------------------
+
+-- ORSoC OpenRISC USB debug cable driver installation --
+
+ As per the installation instructions included in FTDI Chip's D2XX Mac OS X
+ driver. http://www.ftdichip.com/Drivers/D2XX.htm
+
+-- Compilation of the OpenRISC Debug Proxy application --
+
+ As per the Linux instructions.
+
+
+* Note: Tested on an Intel Mac, running OS X version 10.4
+
+
+
+===============================================================================
+-- Usage notes --
+===============================================================================
+
+When the program initialises it sets up some form of communication with an
+OpenRISC processor (developed and tested with a OR1k design similar to the
+ORPSoC design found in the OR1k project archive on OpenCores), either via a
+USB debug cable or via sockets interface to an RTL simulation. After this, it
+waits for a connection from GDB, and then the debugging session can begin.
+
+The proxy has been written to be robust, for example it will hopefully handle
+disruptions like processor crashes, hardware resets, and connection dropouts
+gracefully enough to not require a complete restart of the proxy and GDB.
+
+Some basic mechanics of the proxy are as follows:
+
+* When the program is "continued" from GDB, the proxy will poll the previous
+ program counter (PPC), checking it against the internal list of software
+ breakpoints, at second intervals to see if a software breakpoint has been
+ reached.
+
+* The one second polling also applies to "interrupt" (^C signals) from GDB,
+ which will cause the processor to be stalled, wherever it is, and control
+ returned to GDB (the proxy will await further commands from GDB.) It is
+ optional to implement this awareness of the interrupt signal from GDB, but
+ the developers have found this functionality extremely useful and thought
+ others might too.
+
+* Troubleshooting tip: If the proxy prints out the following line(s):
+ RSP step with signal 'S04' received
+ when attempting to continue, or single step, a program from GDB, it is
+ necessary to restart both the proxy and GDB before being continuing.
+ This bug is perhaps caused by changing the file GDB is debugging during the
+ same session.
+
+TODO List:
+ * Explicit char and short reading and writing ability:
+ Currently only full word writing and reading is supported by the proxy.
+ It would be great if individual words and chars could be read also. It
+ is possible to receive such requests from GDB, so there's no reason why
+ they shouldn't be supported. It should be simple enough to implement.
+ * Correct organisation of non-word aligned reading
+ There's some problems when reading a word from a non-word aligned
+ boundary. This should be possible, for instance in GDB, doing something
+ like "x/4 0x101" should read the four bytes starting at address 0x101
+ and should display them LSB first. However this doesn't appear to
+ function as intended.
+ * USB<->JTAG Driver TODO: Increase speed of the proxy
+ It appears that the current transfer rate of around 20k/s is due to
+ pauses in the driver. This was deteremined by profiling the proxy and
+ noticing that, over a 4-odd megabyte transfer from GDB, taking about 4
+ minutes, the proxy only executed for 2.5 seconds, and the three most
+ used functions, accounting for 50% of execution were functions in the
+ driver. This indicates that either better use of, or better
+ implementation of, the driver could dramatically increase speed.
+ * USB<->JTAG Driver TODO:
+ Get the latest version of the MPSSE function code (from
+ http://ftdichip.com/Projects/MPSSE/FTCJTAG/FTCJTAG_Source.zip at last
+ check) and update our Linux compatible version with the ones here. This
+ might provide improved stability or performance, but from the list of
+ improvements made to the files from our version it doesn't appear like
+ it would result in significant improvement in the proxy app.
+ * Better README
+ It would be nice to provide more important documentation of nuances of
+ the proxy operation
Index: or_debug_proxy/Makefile
===================================================================
--- or_debug_proxy/Makefile (nonexistent)
+++ or_debug_proxy/Makefile (revision 1779)
@@ -0,0 +1,141 @@
+#
+#****************************************************************************#
+# #
+# H E A D E R I N F O R M A T I O N #
+# #
+#****************************************************************************#
+
+# Project Name : OpenRISC Debug Proxy
+# File Name : Makefile
+# Prepared By : jb
+# Project Start : 2008-10-01
+
+#$$COPYRIGHT NOTICE#
+#****************************************************************************#
+# #
+# C O P Y R I G H T N O T I C E #
+# #
+#****************************************************************************#
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License, a copy of which is available from
+# http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+# USA.
+#
+
+#$$CHANGE HISTORY#
+#****************************************************************************#
+# #
+# C H A N G E H I S T O R Y #
+# #
+#****************************************************************************#
+
+# Date Version Description
+#------------------------------------------------------------------------
+# 090301 0.1.0 Makefile for OpenRISC debug proxy. jb
+# 2 Apr 09 0.1.1 Jeremy Bennett. Added static target
+
+#DBGCPPFLAGS=-D DEBUG_GDB=1
+#DBGCPPFLAGS=-D DEBUG_USB_DRVR_FUNCS=1
+#DBGCPPFLAGS=-D DEBUG_USB_DRVR_FUNCS=1 -D DEBUG_GDB=1 -D DEBUG_CMDS=1
+
+
+# Common Flags
+COMMON_CPPFLAGS = -I./includes
+COMMON_CXXFLAGS = -O2 -g
+COMMON_LDFLAGS = -Wall -g
+
+# Flags for static library
+STATIC_LIBDIR = lib
+STATIC_LIB = libftd2xx.a.0.4.16
+STATIC_LDFLAGS = $(COMMON_LDFLAGS) $(STATIC_LIBDIR)/$(STATIC_LIB) \
+ -lpthread -ldl
+
+#Determine whether we're on Cygwin
+ifndef OSTYPE
+ # Basically we're interested in finding out if we're
+ # in a cygwin environement, so let's find out this way
+ # Note: Typically in a bash environment, $OSTYPE is set
+ # but sometimes make can't figure it out. So we'll do it
+ # this way:
+ ifeq (CYGWIN, $(findstring CYGWIN, $(shell uname)))
+ OSTYPE=cygwin
+ endif
+endif
+
+ifeq ($(OSTYPE),cygwin)
+ OR_DEBUG_PROXY_SRC = src/or_debug_proxy.c \
+ src/gdb.c \
+ src/usb_functions.c \
+ src/win_usb_driver_calls.c \
+ src/vpi_functions.c
+ CXX = gcc
+ CPPFLAGS = $(COMMON_CPPFLAGS) -I./obj -DCYGWIN_COMPILE=1 $(DBGCPPFLAGS)
+ CXXFLAGS = $(COMMON_CXXFLAGS)
+ DYNAMIC_LDFLAGS = $(COMMON_LDFLAGS)
+ EXE = .exe
+else
+ OR_DEBUG_PROXY_SRC = src/or_debug_proxy.c \
+ src/gdb.c \
+ src/FT2232c.cpp \
+ src/FT2232cMpsseJtag.cpp \
+ src/usb_functions.c \
+ src/linux_usb_driver_calls.c \
+ src/vpi_functions.c
+ CXX = g++
+ CPPFLAGS = $(COMMON_CPPFLAGS) $(DBGCPPFLAGS)
+ CXXFLAGS = $(COMMON_CXXFLAGS)
+ DYNAMIC_LDFLAGS = $(COMMON_LDFLAGS) -lftd2xx
+ EXE =
+endif
+
+APP = or_debug_proxy
+APP_DYNAMIC = $(APP)$(EXE)
+APP_STATIC = $(APP)_static$(EXE)
+
+
+# -----------------------------------------------------------------------------
+# Build dynamic and static targets from scratch
+.PHONY: all
+all: clean $(APP_DYNAMIC)
+
+static: clean $(APP_STATIC)
+
+# Dynamic target
+$(APP_DYNAMIC): $(OR_DEBUG_PROXY_SRC)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $+ $(DYNAMIC_LDFLAGS) -o $@
+
+# Static target
+$(APP_STATIC): $(OR_DEBUG_PROXY_SRC) $(STATIC_LIBDIR)/$(STATIC_LIB)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $+ $(STATIC_LDFLAGS) -o $@
+ cp $(APP_STATIC) $(APP)
+
+# -----------------------------------------------------------------------------
+# Target for checking the static lib is in the place it should be
+$(STATIC_LIBDIR)/$(STATIC_LIB):
+ @echo
+ @echo "The static library, $(STATIC_LIB), is missing."
+ @echo "Please download the driver to build a statically linked version"
+ @echo "of this app. For Linux, try:"
+ @echo "\twget http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.16.tar.gz"
+ @echo "\ttar xzf libftd2xx0.4.16.tar.gz"
+ @echo "\tcp libftd2xx0.4.16/static_lib/libftd2xx.a.0.4.16 lib"
+ @echo
+ @exit 1
+# -----------------------------------------------------------------------------
+# Tidy up
+clean:
+ $(RM) $(APP_DYNAMIC)
+ $(RM) $(APP_STATIC)
+ find ./ -name "*~" | xargs $(RM)
Index: or_debug_proxy/TAGS
===================================================================
--- or_debug_proxy/TAGS (nonexistent)
+++ or_debug_proxy/TAGS (revision 1779)
@@ -0,0 +1,1155 @@
+
+src/FT2232c.cpp,2219
+ static UINT uiNumOpenedDevices 49,871
+ static FTC_DEVICE_DATA OpenedDevices[OpenedDevices50,1006
+ static OutputByteBuffer OutputBuffer;51,1141
+ static DWORD dwNumBytesToSend 52,1276
+BOOLEAN FT2232c::FTC_DeviceInUse(55,1418
+BOOLEAN FT2232c::FTC_DeviceOpened(87,2318
+FTC_STATUS FT2232c::FTC_IsDeviceNameLocationIDValid(122,3348
+FTC_STATUS FT2232c::FTC_IsDeviceFT2232CType(173,4788
+FT2232c::FT2232c(191,5306
+FT2232c::~FT2232c(203,5530
+FTC_STATUS FT2232c::FTC_GetNumDevices(208,5560
+FTC_STATUS FT2232c::FTC_GetNumNotOpenedDevices(313,9440
+FTC_STATUS FT2232c::FTC_GetDeviceNameLocationID(372,11236
+FTC_STATUS FT2232c::FTC_OpenSpecifiedDevice(418,12575
+FTC_STATUS FT2232c::FTC_OpenDevice(465,13870
+FTC_STATUS FT2232c::FTC_CloseDevice(496,14640
+void FT2232c::FTC_GetClockFrequencyValues(512,14923
+FTC_STATUS FT2232c::FTC_SetDeviceLoopbackState(517,15122
+void FT2232c::FTC_InsertDeviceHandle(538,15610
+FTC_STATUS FT2232c::FTC_IsDeviceHandleValid(566,16506
+void FT2232c::FTC_RemoveDeviceHandle(597,17292
+FTC_STATUS FT2232c::FTC_ResetUSBDevicePurgeUSBInputBuffer(628,18189
+FTC_STATUS FT2232c::FTC_SetDeviceUSBBufferSizes(652,18840
+FTC_STATUS FT2232c::FTC_SetDeviceSpecialCharacters(657,19047
+FTC_STATUS FT2232c::FTC_SetReadWriteDeviceTimeouts(667,19557
+FTC_STATUS FT2232c::FTC_SetDeviceLatencyTimer(673,19840
+FTC_STATUS FT2232c::FTC_ResetMPSSEInterface(679,20065
+FTC_STATUS FT2232c::FTC_EnableMPSSEInterface(684,20225
+FTC_STATUS FT2232c::FTC_SendReceiveCommandFromMPSSEInterface(689,20387
+FTC_STATUS FT2232c::FTC_SynchronizeMPSSEInterface(786,23320
+FTC_STATUS FT2232c::FTC_GetNumberBytesFromDeviceInputBuffer(853,25224
+void FT2232c::FTC_ClearOutputBuffer(891,26491
+void FT2232c::FTC_AddByteToOutputBuffer(896,26562
+DWORD FT2232c::FTC_GetNumBytesInOutputBuffer(906,26817
+FTC_STATUS FT2232c::FTC_SendBytesToDevice(911,26900
+FTC_STATUS FT2232c::FTC_ReadBytesFromDevice(952,28644
+FTC_STATUS FT2232c::FTC_ReadFixedNumBytesFromDevice(963,29472
+FTC_STATUS FT2232c::FTC_SendReadBytesToFromDevice(995,30577
+FTC_STATUS FT2232c::FTC_SendCommandsSequenceToDevice(1051,32797
+FTC_STATUS FT2232c::FTC_ReadCommandsSequenceBytesFromDevice(1089,34333
+char* strupr(1128,35572
+char* strlwr(1140,35750
+
+src/FT2232cMpsseJtag.cpp,4152
+#define WIO_DEFINED24,394
+FTC_STATUS FT2232cMpsseJtag::CheckWriteDataToExternalDeviceBitsBytesParameters(47,907
+void FT2232cMpsseJtag::AddByteToOutputBuffer(74,1752
+FTC_STATUS FT2232cMpsseJtag::SetDataInOutClockFrequency(93,2552
+FTC_STATUS FT2232cMpsseJtag::InitDataInOutClockFrequency(106,2916
+void FT2232cMpsseJtag::SetJTAGToNewState(135,3943
+DWORD FT2232cMpsseJtag::MoveJTAGFromOneStateToAnother(150,4493
+FTC_STATUS FT2232cMpsseJtag::ResetTAPContollerExternalDeviceSetToTestIdleMode(198,6628
+FTC_STATUS FT2232cMpsseJtag::SetGeneralPurposeInputOutputPins(224,7506
+void FT2232cMpsseJtag::GetGeneralPurposeInputOutputPinsInputStates(273,9398
+FTC_STATUS FT2232cMpsseJtag::GetGeneralPurposeInputOutputPins(288,10018
+void FT2232cMpsseJtag::AddWriteCommandDataToOutPutBuffer(383,13694
+FTC_STATUS FT2232cMpsseJtag::WriteDataToExternalDevice(448,16074
+void FT2232cMpsseJtag::GetNumDataBytesToRead(464,16707
+FTC_STATUS FT2232cMpsseJtag::GetDataFromExternalDevice(494,17733
+DWORD FT2232cMpsseJtag::AddReadCommandToOutputBuffer(541,19674
+FTC_STATUS FT2232cMpsseJtag::ReadDataFromExternalDevice(587,21283
+DWORD FT2232cMpsseJtag::AddWriteReadCommandDataToOutPutBuffer(608,22106
+FTC_STATUS FT2232cMpsseJtag::WriteReadDataToFromExternalDevice(676,24682
+FTC_STATUS FT2232cMpsseJtag::GenerateTCKClockPulses(732,27167
+void FT2232cMpsseJtag::ProcessReadCommandsSequenceBytes(809,29756
+DWORD FT2232cMpsseJtag::GetTotalNumCommandsSequenceDataBytesToRead(873,32805
+void FT2232cMpsseJtag::CopyReadCommandsSequenceDataBuffer(903,33999
+FTC_STATUS FT2232cMpsseJtag::AddReadCommandSequenceData(922,34800
+PReadCommandsSequenceData FT2232cMpsseJtag::CreateReadCommandsSequenceDataBuffer(988,38026
+void FT2232cMpsseJtag::DeleteReadCommandsSequenceDataBuffer(1009,38805
+FTC_STATUS FT2232cMpsseJtag::CreateDeviceCommandsSequenceDataBuffers(1024,39341
+void FT2232cMpsseJtag::ClearDeviceCommandSequenceData(1067,41106
+DWORD FT2232cMpsseJtag::GetNumBytesInCommandsSequenceDataBuffer(1102,42321
+DWORD FT2232cMpsseJtag::GetCommandsSequenceDataDeviceIndex(1113,42713
+void FT2232cMpsseJtag::DeleteDeviceCommandsSequenceDataBuffers(1149,43787
+FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteCommand(1176,45094
+FTC_STATUS FT2232cMpsseJtag::AddDeviceReadCommand(1214,46595
+FTC_STATUS FT2232cMpsseJtag::AddDeviceWriteReadCommand(1246,47733
+FT2232cMpsseJtag::FT2232cMpsseJtag(1289,49442
+FT2232cMpsseJtag::~FT2232cMpsseJtag(1306,49821
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetNumDevices(1336,51029
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetDeviceNameLocationID(1348,51286
+FTC_STATUS FT2232cMpsseJtag::JTAG_OpenSpecifiedDevice(1354,51701
+FTC_STATUS FT2232cMpsseJtag::JTAG_OpenDevice(1376,52264
+FTC_STATUS FT2232cMpsseJtag::JTAG_CloseDevice(1399,52742
+FTC_STATUS FT2232cMpsseJtag::JTAG_InitDevice(1410,52960
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetClock(1484,55524
+FTC_STATUS FT2232cMpsseJtag::JTAG_SetClock(1496,55882
+FTC_STATUS FT2232cMpsseJtag::JTAG_SetDeviceLoopbackState(1518,56470
+FTC_STATUS FT2232cMpsseJtag::JTAG_SetGeneralPurposeInputOutputPins(1524,56727
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetGeneralPurposeInputOutputPins(1588,59995
+FTC_STATUS FT2232cMpsseJtag::JTAG_WriteDataToExternalDevice(1610,61004
+FTC_STATUS FT2232cMpsseJtag::JTAG_ReadDataFromExternalDevice(1641,62248
+FTC_STATUS FT2232cMpsseJtag::JTAG_WriteReadDataToFromExternalDevice(1672,63494
+FTC_STATUS FT2232cMpsseJtag::JTAG_GenerateTCKClockPulses(1710,65169
+FTC_STATUS FT2232cMpsseJtag::JTAG_ClearCommandSequence(1728,65737
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteCommand(1748,66191
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddReadCommand(1772,67140
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddWriteReadCommand(1794,67903
+FTC_STATUS FT2232cMpsseJtag::JTAG_ClearDeviceCommandSequence(1819,68914
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteCommand(1832,69257
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceReadCommand(1847,69995
+FTC_STATUS FT2232cMpsseJtag::JTAG_AddDeviceWriteReadCommand(1860,70542
+FTC_STATUS FT2232cMpsseJtag::JTAG_ExecuteCommandSequence(1875,71312
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetDllVersion(1943,74065
+FTC_STATUS FT2232cMpsseJtag::JTAG_GetErrorCodeString(1960,74474
+
+src/gdb.c,4899
+#define OR1KSIM_RSP_SERVICE 95,3823
+#define MAX_GPRS 100,3957
+#define PPC_REGNUM 103,4058
+#define NPC_REGNUM 104,4113
+#define SR_REGNUM 105,4164
+#define NUM_REGS 106,4228
+#define NPC_CPU_REG_ADD 109,4325
+#define SR_CPU_REG_ADD 110,4376
+#define PPC_CPU_REG_ADD 111,4440
+#define DMR1_CPU_REG_ADD 112,4495
+#define DMR2_CPU_REG_ADD 113,4579
+#define DSR_CPU_REG_ADD 114,4663
+#define DRR_CPU_REG_ADD 115,4744
+#define OR1K_TRAP_INSTR 118,4862
+#define GDB_BUF_MAX 127,5371
+#define MP_HASH_SIZE 130,5477
+#define MAX_SPRS 133,5559
+#define SPR_DMR1_ST 135,5587
+#define SPR_DMR2_WGB 136,5646
+#define SPR_DSR_TE 137,5723
+#define WORDSBIGENDIAN_N139,5779
+#define EXCEPT_NONE 142,5841
+#define EXCEPT_RESET 143,5872
+#define EXCEPT_BUSERR 144,5900
+#define EXCEPT_DPF 145,5929
+#define EXCEPT_IPF 146,5955
+#define EXCEPT_TICK 147,5981
+#define EXCEPT_ALIGN 148,6008
+#define EXCEPT_ILLEGAL 149,6036
+#define EXCEPT_INT 150,6066
+#define EXCEPT_DTLBMISS 151,6092
+#define EXCEPT_ITLBMISS 152,6123
+#define EXCEPT_RANGE 153,6154
+#define EXCEPT_SYSCALL 154,6182
+#define EXCEPT_FPE 155,6212
+#define EXCEPT_TRAP 156,6238
+#define SPR_DRR_RSTE 160,6370
+#define SPR_DRR_BUSEE 161,6415
+#define SPR_DRR_DPFE 162,6464
+#define SPR_DRR_IPFE 163,6519
+#define SPR_DRR_TTE 164,6574
+#define SPR_DRR_AE 165,6624
+#define SPR_DRR_IIE 166,6673
+#define SPR_DRR_IE 167,6732
+#define SPR_DRR_DME 168,6781
+#define SPR_DRR_IME 169,6830
+#define SPR_DRR_RE 170,6879
+#define SPR_DRR_SCE 171,6930
+#define SPR_DRR_FPE 172,6981
+#define SPR_DRR_TE 173,7035
+enum target_signal 181,7389
+ TARGET_SIGNAL_NONE 182,7410
+ TARGET_SIGNAL_INT 183,7437
+ TARGET_SIGNAL_ILL 184,7464
+ TARGET_SIGNAL_TRAP 185,7491
+ TARGET_SIGNAL_FPE 186,7518
+ TARGET_SIGNAL_BUS 187,7545
+ TARGET_SIGNAL_SEGV 188,7572
+ TARGET_SIGNAL_ALRM 189,7599
+ TARGET_SIGNAL_USR2 190,7626
+ TARGET_SIGNAL_PWR 191,7653
+static const char hexchars[hexchars195,7724
+enum stallStates 206,8201
+ STALLED,207,8220
+ UNSTALLED,208,8231
+ UNKNOWN209,8244
+} stallState;210,8254
+unsigned int npcIsCached;212,8269
+unsigned long int npcCachedValue;213,8324
+unsigned int serverIP 221,8469
+unsigned int serverPort 222,8496
+unsigned int server_fd 223,8525
+unsigned int gdb_fd 224,8553
+static int tcp_level 226,8579
+int gdb_chain 230,8742
+struct rsp_buf234,8862
+ char data[data236,8879
+ int len;237,8906
+enum mp_type 242,9057
+ BP_MEMORY 243,9072
+ BP_HARDWARE 244,9126
+ WP_WRITE 245,9181
+ WP_READ 246,9236
+ WP_ACCESS 247,9292
+struct mp_entry251,9416
+ enum mp_type type;253,9434
+ unsigned long int addr;254,9489
+ unsigned long int instr;255,9553
+ struct mp_entry *next;next256,9614
+ int client_waiting;262,9739
+ int client_fd;264,9892
+ int sigval;265,9955
+ unsigned long int start_addr;266,10022
+ struct mp_entry *mp_hash[mp_hash267,10080
+} rsp;268,10154
+char *printTime(printTime333,13215
+rsp_init 351,13751
+handle_rsp 389,15042
+static void rsp_check_for_exception(485,17873
+check_for_exception_vector(549,20176
+rsp_exception 581,21215
+rsp_get_client 636,23409
+static void rsp_client_request 749,27487
+rsp_client_close 958,33010
+put_packet 979,33691
+put_str_packet 1043,35292
+get_packet 1082,36581
+send_rsp_str 1209,39656
+get_rsp_char 1255,40902
+rsp_peek(1305,42151
+rsp_interrupt(1341,43066
+rsp_unescape 1390,44513
+mp_hash_init 1425,45326
+mp_hash_add 1449,46095
+static struct mp_entry * mp_hash_lookup 1488,47173
+mp_hash_delete 1527,48408
+static int hex 1572,49618
+reg2hex 1591,50313
+hex2reg 1627,51215
+static void ascii2hex 1655,51985
+static void hex2ascii 1682,52727
+set_npc 1711,53656
+static unsigned long int get_npc 1757,54854
+rsp_report_exception 1802,55949
+rsp_continue 1827,56697
+rsp_continue_with_signal 1875,58135
+rsp_continue_generic 1895,58851
+rsp_read_all_regs 1944,60980
+rsp_write_all_regs 2043,63864
+static void rsp_read_mem 2125,66454
+rsp_write_mem 2234,69314
+rsp_read_reg 2310,71521
+rsp_write_reg 2406,74255
+rsp_query 2492,76742
+rsp_command 2596,80632
+rsp_set 2710,83678
+rsp_restart 2744,85009
+rsp_step 2783,86240
+rsp_step_with_signal 2845,88018
+rsp_step_generic 2865,88714
+rsp_vpkt 2913,90676
+rsp_write_mem_bin 3005,93702
+rsp_remove_matchpoint 3113,96509
+rsp_insert_matchpoint 3207,99190
+void setup_or32(3287,101693
+static void gdb_ensure_or1k_stalled(3314,103010
+int gdb_read_reg(3334,103506
+int gdb_write_reg(3345,103949
+int gdb_read_block(3356,104450
+int gdb_write_block(3365,104747
+int gdb_set_chain(3374,105046
+int GetServerSocket(3386,105312
+void HandleServerSocket(3482,108113
+void JTAGRequest(3573,110472
+static void GDBRequest(3635,112217
+static void ProtocolClean(3868,121116
+static int gdb_write(3879,121370
+static int gdb_read(3913,122144
+static void client_close 3951,123098
+static void swap_buf(3967,123542
+set_stall_state 3996,124170
+
+src/linux_usb_driver_calls.c,368
+static FT2232cMpsseJtag *pFT2232cMpsseJtag pFT2232cMpsseJtag72,3236
+FTC_HANDLE ftHandle;75,3321
+FT2232_USB_JTAG_WriteDataToExternalDevice(81,3523
+FT2232_USB_JTAG_ReadDataFromExternalDevice(102,4123
+FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(128,4674
+FT2232_USB_JTAG_CloseDevice(155,5373
+#define USB_JTAG_CLK_DIVIDER 165,5590
+int init_usb_jtag(167,5622
+
+src/or_debug_proxy.c,869
+#define ENDPOINT_TARGET_NONE 70,2831
+#define ENDPOINT_TARGET_USB 71,2862
+#define ENDPOINT_TARGET_VPI 72,2892
+static int endpoint_target;73,2922
+#define GDB_PROTOCOL_JTAG 75,3006
+#define GDB_PROTOCOL_RSP 76,3035
+#define GDB_PROTOCOL_NONE 77,3064
+int err 79,3094
+int current_chain 82,3185
+int dbg_chain 85,3261
+void check(88,3420
+int main(95,3572
+int dbg_reset(211,6849
+void dbg_test(218,7055
+int dbg_set_tap_ir(224,7240
+int dbg_set_chain(231,7414
+int dbg_command(238,7727
+int dbg_ctrl(245,8008
+int dbg_ctrl_read(252,8284
+int dbg_go(259,8586
+int dbg_wb_read32(266,8842
+int dbg_wb_write32(274,9148
+int dbg_wb_read_block32(281,9459
+int dbg_wb_write_block32(289,9805
+int dbg_cpu0_read(296,10152
+int dbg_cpu0_write(303,10455
+int dbg_cpu0_write_ctrl(310,10767
+int dbg_cpu0_read_ctrl(318,11099
+void test_sdram(325,11391
+void print_usage(329,11427
+
+src/usb_functions.c,816
+DWORD dwNumBytesReturned 88,3574
+int crc_r,91,3649
+int crc_r, crc_w 91,3649
+unsigned long crc_calc(94,3726
+int bit_reverse_data(101,3966
+void usb_dbg_test(108,4118
+void usb_write_stream 171,5758
+ULONGEST usb_read_stream(212,7196
+void usb_set_tap_ir(242,8183
+int usb_dbg_reset(264,8880
+static int retry_no 300,9926
+int retry_do(301,9951
+void retry_ok(354,11192
+int usb_dbg_set_chain(359,11252
+int usb_dbg_command(410,12646
+int usb_dbg_ctrl(555,17431
+int usb_dbg_ctrl_read(661,20837
+int usb_dbg_go(772,24725
+int usb_dbg_wb_read32(938,30218
+int usb_dbg_wb_write32(948,30548
+int usb_dbg_wb_read_block32(958,30886
+int usb_dbg_wb_write_block32(971,31346
+int usb_dbg_cpu0_read(982,31743
+int usb_dbg_cpu0_write(992,32072
+int usb_dbg_cpu0_write_ctrl(1002,32407
+int usb_dbg_cpu0_read_ctrl(1010,32740
+
+src/vpi_functions.c,1293
+#define MSG_WAITALL 83,3416
+unsigned int vpiPort 87,3498
+unsigned int vpi_fd;88,3531
+#define DBG_VPI 91,3633
+#define DBG_VPI 93,3657
+#define CMD_JTAG_SET_IR 118,4646
+#define CMD_SET_DEBUG_CHAIN 119,4674
+#define CMD_CPU_CTRL_WR 120,4706
+#define CMD_CPU_CTRL_RD 121,4734
+#define CMD_CPU_WR_REG 122,4762
+#define CMD_CPU_RD_REG 123,4789
+#define CMD_WB_WR32 124,4816
+#define CMD_WB_RD32 125,4840
+#define CMD_WB_BLOCK_WR32 126,4864
+#define CMD_WB_BLOCK_RD32 127,4894
+#define CMD_RESET 128,4924
+#define CMD_READ_JTAG_ID 129,4946
+void send_command_to_vpi(132,4977
+void send_address_to_vpi(152,5469
+void send_data_to_vpi(170,5771
+void send_block_data_to_vpi(189,6059
+void get_data_from_vpi(209,6413
+void get_block_data_from_vpi(234,6829
+void get_response_from_vpi(260,7385
+static void jp2_reset_JTAG(278,7709
+int vpi_connect(291,7853
+ int vpi_dbg_reset(358,9445
+void vpi_dbg_test(392,10071
+int vpi_dbg_set_chain(418,10719
+int vpi_dbg_ctrl(438,11061
+int vpi_dbg_ctrl_read(457,11420
+int vpi_dbg_wb_read32(485,11927
+int vpi_dbg_wb_write32(503,12230
+int vpi_dbg_wb_read_block32(520,12509
+int vpi_dbg_wb_write_block32(543,12959
+int vpi_dbg_cpu0_read(562,13298
+int vpi_dbg_cpu0_write(580,13575
+int vpi_dbg_cpu0_write_ctrl(598,13856
+int vpi_dbg_cpu0_read_ctrl(606,14111
+
+src/win_usb_driver_calls.c,337
+int getFTDIJTAGFunctions 82,3443
+FTC_HANDLE ftHandle;247,8553
+FT2232_USB_JTAG_WriteDataToExternalDevice(250,8586
+FT2232_USB_JTAG_ReadDataFromExternalDevice(272,9131
+FT2232_USB_JTAG_WriteReadDataToFromExternalDevice(298,9612
+FT2232_USB_JTAG_CloseDevice(325,10213
+#define USB_JTAG_CLK_DIVIDER 336,10407
+int init_usb_jtag(338,10439
+
+includes/FT2232c.h,2275
+#define FT2232c_H26,475
+typedef DWORD FTC_HANDLE;32,545
+typedef ULONG FTC_STATUS;33,572
+#define FTC_SUCCESS 35,601
+#define FTC_INVALID_HANDLE 36,634
+#define FTC_DEVICE_NOT_FOUND 37,685
+#define FTC_DEVICE_NOT_OPENED 38,740
+#define FTC_IO_ERROR 39,797
+#define FTC_INSUFFICIENT_RESOURCES 40,836
+#define FTC_FAILED_TO_COMPLETE_COMMAND 42,905
+#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 43,948
+#define FTC_INVALID_DEVICE_NAME_INDEX 44,999
+#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 45,1041
+#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 46,1089
+#define FTC_INVALID_DEVICE_NAME 47,1134
+#define FTC_INVALID_LOCATION_ID 48,1170
+#define FTC_DEVICE_IN_USE 49,1206
+#define FTC_TOO_MANY_DEVICES 50,1236
+#define MAX_NUM_DEVICE_NAME_CHARS 52,1271
+#define MAX_NUM_SERIAL_NUMBER_CHARS 53,1309
+typedef struct Ft_Device_Data{Ft_Device_Data55,1351
+ DWORD dwProcessId;56,1383
+ char szDeviceName[szDeviceName57,1490
+ DWORD dwLocationID;58,1596
+ DWORD hDevice;59,1706
+}FTC_DEVICE_DATA, *PFTC_DEVICE_DATA;PFTC_DEVICE_DATA60,1824
+typedef DWORD FT2232CDeviceIndexes[FT2232CDeviceIndexes62,1864
+#define DEVICE_STRING_BUFF_SIZE 64,1920
+#define DEVICE_CHANNEL_A 66,1958
+typedef char SerialNumber[SerialNumber68,1991
+const BYTE DEVICE_LATENCY_TIMER_VALUE 70,2050
+#define OUTPUT_BUFFER_SIZE 72,2116
+typedef BYTE OutputByteBuffer[OutputByteBuffer74,2168
+typedef OutputByteBuffer *POutputByteBuffer;POutputByteBuffer75,2220
+#define INPUT_BUFFER_SIZE 77,2268
+typedef BYTE InputByteBuffer[InputByteBuffer79,2319
+typedef InputByteBuffer *PInputByteBuffer;PInputByteBuffer80,2369
+#define CONVERT_1MS_TO_100NS 82,2415
+#define MAX_COMMAND_TIMEOUT_PERIOD 84,2453
+#define MAX_NUM_BYTES_USB_WRITE 87,2597
+#define MAX_NUM_BYTES_USB_WRITE_READ 88,2651
+#define MAX_NUM_BYTES_USB_READ 89,2710
+#define DEBUG_LIST_DEVICE 91,2758
+const BYTE MPSSE_INTERFACE_MASK 93,2790
+const BYTE RESET_MPSSE_INTERFACE 94,2835
+const BYTE ENABLE_MPSSE_INTERFACE 95,2879
+const __uint16_t DEVICE_OPENED_FLAG 97,2926
+const int BASE_CLOCK_FREQUENCY_12_MHZ 99,2978
+const BYTE AA_ECHO_CMD_1 101,3031
+const BYTE AB_ECHO_CMD_2 102,3067
+const BYTE TURN_ON_LOOPBACK_CMD 104,3105
+const BYTE TURN_OFF_LOOPBACK_CMD 105,3148
+const BYTE BAD_COMMAND_RESPONSE 107,3194
+class FT2232c111,3243
+
+includes/FT2232cMpsseJtag.h,8548
+#define FT2232cMpsseJtag_H28,727
+typedef DWORD FTC_HANDLE;38,949
+typedef ULONG FTC_STATUS;39,976
+#define TEST_LOGIC_STATE 41,1005
+#define RUN_TEST_IDLE_STATE 42,1033
+#define PAUSE_TEST_DATA_REGISTER_STATE 43,1064
+#define PAUSE_INSTRUCTION_REGISTER_STATE 44,1106
+#define SHIFT_TEST_DATA_REGISTER_STATE 45,1150
+#define SHIFT_INSTRUCTION_REGISTER_STATE 46,1192
+#define FTC_SUCCESS 48,1238
+#define FTC_INVALID_HANDLE 49,1271
+#define FTC_DEVICE_NOT_FOUND 50,1323
+#define FTC_DEVICE_NOT_OPENED 51,1378
+#define FTC_IO_ERROR 52,1435
+#define FTC_INSUFFICIENT_RESOURCES 53,1474
+#define FTC_FAILED_TO_COMPLETE_COMMAND 55,1544
+#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 56,1653
+#define FTC_INVALID_DEVICE_NAME_INDEX 57,1762
+#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 58,1871
+#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 59,1981
+#define FTC_INVALID_DEVICE_NAME 60,2090
+#define FTC_INVALID_LOCATION_ID 61,2199
+#define FTC_DEVICE_IN_USE 62,2308
+#define FTC_TOO_MANY_DEVICES 63,2417
+#define FTC_INVALID_CLOCK_DIVISOR 64,2526
+#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 65,2564
+#define FTC_INVALID_NUMBER_BITS 66,2613
+#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 67,2649
+#define FTC_INVALID_NUMBER_BYTES 68,2696
+#define FTC_NUMBER_BYTES_TOO_SMALL 69,2733
+#define FTC_INVALID_TAP_CONTROLLER_STATE 70,2772
+#define FTC_NULL_READ_DATA_BUFFER_POINTER 71,2817
+#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 72,2863
+#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 73,2908
+#define FTC_NO_COMMAND_SEQUENCE 74,2959
+#define FTC_INVALID_NUMBER_CLOCK_PULSES 75,2995
+#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 76,3039
+#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 77,3087
+#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 78,3132
+#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 79,3182
+#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 80,3232
+#define FTC_INVALID_LANGUAGE_CODE 81,3279
+#define FTC_INVALID_STATUS_CODE 82,3317
+typedef struct Ft_Input_Output_Pins{Ft_Input_Output_Pins85,3357
+ BOOL bPin1InputOutputState;86,3395
+ BOOL bPin1LowHighState;87,3427
+ BOOL bPin2InputOutputState;88,3455
+ BOOL bPin2LowHighState;89,3487
+ BOOL bPin3InputOutputState;90,3515
+ BOOL bPin3LowHighState;91,3547
+ BOOL bPin4InputOutputState;92,3575
+ BOOL bPin4LowHighState;93,3607
+}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS;PFTC_INPUT_OUTPUT_PINS94,3635
+typedef struct Ft_Low_High_Pins{Ft_Low_High_Pins95,3685
+ BOOL bPin1LowHighState;96,3719
+ BOOL bPin2LowHighState;97,3747
+ BOOL bPin3LowHighState;98,3775
+ BOOL bPin4LowHighState;99,3803
+}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS;PFTC_LOW_HIGH_PINS100,3831
+#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 101,3873
+typedef BYTE WriteDataByteBuffer[WriteDataByteBuffer103,3939
+typedef WriteDataByteBuffer *PWriteDataByteBuffer;PWriteDataByteBuffer104,4008
+#define MAX_READ_DATA_BYTES_BUFFER_SIZE 107,4064
+typedef BYTE ReadDataByteBuffer[ReadDataByteBuffer109,4129
+typedef ReadDataByteBuffer *PReadDataByteBuffer;PReadDataByteBuffer110,4196
+#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 112,4248
+typedef BYTE ReadCmdSequenceDataByteBuffer[ReadCmdSequenceDataByteBuffer114,4319
+typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer;PReadCmdSequenceDataByteBuffer115,4402
+#define DEVICE_CHANNEL_A 121,4513
+#define DEVICE_CHANNEL_B 122,4544
+#define DLL_VERSION_NUM 124,4577
+#define USB_INPUT_BUFFER_SIZE 126,4610
+#define USB_OUTPUT_BUFFER_SIZE 127,4656
+const BYTE FT_EVENT_VALUE 129,4704
+const BYTE FT_ERROR_VALUE 130,4736
+#define DEVICE_READ_TIMEOUT_INFINITE 132,4770
+#define DEVICE_WRITE_TIMEOUT 133,4810
+#define MIN_CLOCK_DIVISOR 135,4860
+#define MAX_CLOCK_DIVISOR 136,4915
+#define MIN_NUM_BITS 138,4972
+#define MAX_NUM_BITS 139,5097
+#define MIN_NUM_BYTES 140,5222
+#define MAX_NUM_BYTES 141,5335
+#define NUMBITSINBYTE 143,5450
+#define MIN_NUM_CLOCK_PULSES 145,5477
+#define MAX_NUM_CLOCK_PULSES 146,5606
+#define NUM_BYTE_CLOCK_PULSES_BLOCK_SIZE 148,5737
+#define PIN1_HIGH_VALUE 150,5794
+#define PIN2_HIGH_VALUE 151,5822
+#define PIN3_HIGH_VALUE 152,5850
+#define PIN4_HIGH_VALUE 153,5878
+#define NUM_WRITE_COMMAND_BYTES 155,5908
+#define NUM_READ_COMMAND_BYTES 156,5944
+#define NUM_WRITE_READ_COMMAND_BYTES 157,5979
+#define MAX_ERROR_MSG_SIZE 159,6022
+const CHAR ENGLISH[ENGLISH161,6056
+const CHAR EN_Common_Errors[EN_Common_Errors163,6089
+const CHAR EN_New_Errors[EN_New_Errors171,6365
+const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_LSB_FIRST_CMD 201,7930
+const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_LSB_FIRST_CMD 202,7996
+const BYTE CLK_DATA_BYTES_IN_ON_POS_CLK_LSB_FIRST_CMD 203,8061
+const BYTE CLK_DATA_BITS_IN_ON_POS_CLK_LSB_FIRST_CMD 204,8126
+const BYTE CLK_DATA_BYTES_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD 205,8190
+const BYTE CLK_DATA_BITS_OUT_ON_NEG_CLK_IN_ON_POS_CLK_LSB_FIRST_CMD 206,8270
+const BYTE CLK_DATA_TMS_NO_READ_CMD 208,8351
+const BYTE CLK_DATA_TMS_READ_CMD 209,8398
+const BYTE SET_LOW_BYTE_DATA_BITS_CMD 211,8444
+const BYTE GET_LOW_BYTE_DATA_BITS_CMD 212,8493
+const BYTE SET_HIGH_BYTE_DATA_BITS_CMD 213,8542
+const BYTE GET_HIGH_BYTE_DATA_BITS_CMD 214,8592
+const BYTE SET_CLOCK_FREQUENCY_CMD 215,8642
+const BYTE SEND_ANSWER_BACK_IMMEDIATELY_CMD 216,8688
+enum JtagStates 218,8745
+enum JtagStates {TestLogicReset,TestLogicReset218,8745
+enum JtagStates {TestLogicReset, RunTestIdle,218,8745
+enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister,218,8745
+enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister,218,8745
+enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister,218,8745
+enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister, ShiftInstructionRegister,218,8745
+enum JtagStates {TestLogicReset, RunTestIdle, PauseDataRegister, PauseInstructionRegister, ShiftDataRegister, ShiftInstructionRegister, Undefined}Undefined218,8745
+#define NUM_JTAG_TMS_STATES 220,8896
+const BYTE TestLogicResetToNewJTAGState[TestLogicResetToNewJTAGState223,9044
+const BYTE RunTestIdleToNewJTAGState[RunTestIdleToNewJTAGState224,9163
+const BYTE PauseDataRegToNewJTAGState[PauseDataRegToNewJTAGState225,9282
+const BYTE PauseInstructionRegToNewJTAGState[PauseInstructionRegToNewJTAGState226,9401
+const BYTE ShiftDataRegToNewJTAGState[ShiftDataRegToNewJTAGState227,9520
+const BYTE ShiftInstructionRegToNewJTAGState[ShiftInstructionRegToNewJTAGState228,9639
+const BYTE TestLogicResetToNewJTAGStateNumTMSClocks[TestLogicResetToNewJTAGStateNumTMSClocks231,9866
+const BYTE RunTestIdleToNewJTAGStateNumTMSClocks[RunTestIdleToNewJTAGStateNumTMSClocks232,9972
+const BYTE PauseDataRegToNewJTAGStateNumTMSClocks[PauseDataRegToNewJTAGStateNumTMSClocks233,10078
+const BYTE PauseInstructionRegToNewJTAGStateNumTMSClocks[PauseInstructionRegToNewJTAGStateNumTMSClocks234,10184
+const BYTE ShiftDataRegToNewJTAGStateNumTMSClocks[ShiftDataRegToNewJTAGStateNumTMSClocks235,10290
+const BYTE ShiftInstructionRegToNewJTAGStateNumTMSClocks[ShiftInstructionRegToNewJTAGStateNumTMSClocks236,10396
+#define NO_LAST_DATA_BIT 238,10504
+#define NUM_COMMAND_SEQUENCE_READ_DATA_BYTES 240,10534
+#define INIT_COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE 241,10582
+#define COMMAND_SEQUENCE_READ_DATA_BUFFER_SIZE_INCREMENT 242,10639
+typedef DWORD ReadCommandSequenceData[ReadCommandSequenceData244,10702
+typedef ReadCommandSequenceData *PReadCommandSequenceData;PReadCommandSequenceData245,10780
+typedef PReadCommandSequenceData ReadCommandsSequenceData[ReadCommandsSequenceData247,10842
+typedef ReadCommandsSequenceData *PReadCommandsSequenceData;PReadCommandsSequenceData248,10905
+typedef struct Ft_Device_Cmd_Sequence_Data{Ft_Device_Cmd_Sequence_Data250,10969
+ DWORD hDevice;251,11014
+ DWORD dwNumBytesToSend;252,11132
+ POutputByteBuffer pCommandsSequenceDataOutPutBuffer;253,11159
+ DWORD dwSizeReadCommandsSequenceDataBuffer;254,11215
+ PReadCommandsSequenceData pReadCommandsSequenceDataBuffer;255,11262
+ DWORD dwNumReadCommandSequences;256,11324
+}FTC_DEVICE_CMD_SEQUENCE_DATA, *PFTC_DEVICE_CMD_SEQUENCE_DATA;PFTC_DEVICE_CMD_SEQUENCE_DATA257,11360
+ static DWORD dwSavedLowPinsDirection 260,11428
+ static DWORD dwSavedLowPinsValue 261,11561
+ static JtagStates CurrentJtagState 262,11691
+ static DWORD dwNumOpenedDevices 263,11834
+ static FTC_DEVICE_CMD_SEQUENCE_DATA OpenedDevicesCommandsSequenceData[OpenedDevicesCommandsSequenceData264,11964
+ static INT iCommandsSequenceDataDeviceIndex 265,12129
+class FT2232cMpsseJtag 269,12352
+
+includes/ftd2xx.h,7279
+#define FTD2XX_H34,652
+#define WINAPI38,712
+#define FTD2XX_API 50,1258
+#define FTD2XX_API 52,1307
+#undef FTD2XX_API58,1419
+#define FTD2XX_API59,1438
+typedef struct _EVENT_HANDLE{_EVENT_HANDLE62,1474
+ pthread_cond_t eCondVar;63,1505
+ pthread_mutex_t eMutex;64,1532
+ int iVar;65,1558
+} EVENT_HANDLE;66,1570
+typedef DWORD *FT_HANDLE;FT_HANDLE68,1589
+typedef ULONG FT_STATUS;70,1621
+ FT_OK,76,1686
+ FT_INVALID_HANDLE,77,1695
+ FT_DEVICE_NOT_FOUND,78,1716
+ FT_DEVICE_NOT_OPENED,79,1739
+ FT_IO_ERROR,80,1763
+ FT_INSUFFICIENT_RESOURCES,81,1778
+ FT_INVALID_PARAMETER,82,1807
+ FT_INVALID_BAUD_RATE,83,1831
+ FT_DEVICE_NOT_OPENED_FOR_ERASE,85,1861
+ FT_DEVICE_NOT_OPENED_FOR_WRITE,86,1895
+ FT_FAILED_TO_WRITE_DEVICE,87,1929
+ FT_EEPROM_READ_FAILED,88,1958
+ FT_EEPROM_WRITE_FAILED,89,1983
+ FT_EEPROM_ERASE_FAILED,90,2009
+ FT_EEPROM_NOT_PRESENT,91,2035
+ FT_EEPROM_NOT_PROGRAMMED,92,2060
+ FT_INVALID_ARGS,93,2088
+ FT_NOT_SUPPORTED,94,2107
+ FT_OTHER_ERROR95,2127
+#define FT_SUCCESS(99,2152
+#define FT_OPEN_BY_SERIAL_NUMBER 105,2232
+#define FT_OPEN_BY_DESCRIPTION 106,2271
+#define FT_OPEN_BY_LOCATION 107,2310
+#define FT_LIST_NUMBER_ONLY 112,2420
+#define FT_LIST_BY_INDEX 113,2462
+#define FT_LIST_ALL 114,2501
+#define FT_LIST_MASK 116,2538
+#define FT_BAUD_300 122,2638
+#define FT_BAUD_600 123,2665
+#define FT_BAUD_1200 124,2692
+#define FT_BAUD_2400 125,2720
+#define FT_BAUD_4800 126,2748
+#define FT_BAUD_9600 127,2776
+#define FT_BAUD_14400 128,2804
+#define FT_BAUD_19200 129,2834
+#define FT_BAUD_38400 130,2864
+#define FT_BAUD_57600 131,2894
+#define FT_BAUD_115200 132,2924
+#define FT_BAUD_230400 133,2956
+#define FT_BAUD_460800 134,2988
+#define FT_BAUD_921600 135,3020
+#define FT_BITS_8 141,3081
+#define FT_BITS_7 142,3112
+#define FT_BITS_6 143,3143
+#define FT_BITS_5 144,3174
+#define FT_STOP_BITS_1 150,3231
+#define FT_STOP_BITS_1_5 151,3266
+#define FT_STOP_BITS_2 152,3302
+#define FT_PARITY_NONE 158,3360
+#define FT_PARITY_ODD 159,3395
+#define FT_PARITY_EVEN 160,3429
+#define FT_PARITY_MARK 161,3464
+#define FT_PARITY_SPACE 162,3499
+#define FT_FLOW_NONE 168,3564
+#define FT_FLOW_RTS_CTS 169,3600
+#define FT_FLOW_DTR_DSR 170,3636
+#define FT_FLOW_XON_XOFF 171,3672
+#define FT_PURGE_RX 176,3746
+#define FT_PURGE_TX 177,3777
+typedef void (*PFT_EVENT_HANDLER)PFT_EVENT_HANDLER183,3831
+#define FT_EVENT_RXCHAR 185,3882
+#define FT_EVENT_MODEM_STATUS 186,3914
+#define FT_DEFAULT_RX_TIMEOUT 192,3974
+#define FT_DEFAULT_TX_TIMEOUT 193,4011
+typedef ULONG FT_DEVICE;199,4077
+ FT_DEVICE_BM,202,4113
+ FT_DEVICE_AM,203,4132
+ FT_DEVICE_100AX,204,4151
+ FT_DEVICE_UNKNOWN,205,4173
+ FT_DEVICE_2232C,206,4197
+ FT_DEVICE_232R207,4216
+typedef struct ft_program_data 432,7971
+ DWORD Signature1;434,8007
+ DWORD Signature2;435,8061
+ DWORD Version;436,8114
+ WORD VendorId;441,8307
+ WORD ProductId;442,8337
+ char *Manufacturer;Manufacturer443,8368
+ char *ManufacturerId;ManufacturerId444,8402
+ char *Description;Description445,8435
+ char *SerialNumber;SerialNumber446,8487
+ WORD MaxPower;447,8543
+ WORD PnP;448,8586
+ WORD SelfPowered;449,8631
+ WORD RemoteWakeup;450,8690
+ UCHAR Rev4;454,8776
+ UCHAR IsoIn;455,8835
+ UCHAR IsoOut;456,8895
+ UCHAR PullDownEnable;457,8957
+ UCHAR SerNumEnable;458,9015
+ UCHAR USBVersionEnable;459,9079
+ WORD USBVersion;460,9142
+ UCHAR Rev5;464,9221
+ UCHAR IsoInA;465,9280
+ UCHAR IsoInB;466,9341
+ UCHAR IsoOutA;467,9402
+ UCHAR IsoOutB;468,9465
+ UCHAR PullDownEnable5;469,9528
+ UCHAR SerNumEnable5;470,9587
+ UCHAR USBVersionEnable5;471,9651
+ WORD USBVersion5;472,9714
+ UCHAR AIsHighCurrent;473,9760
+ UCHAR BIsHighCurrent;474,9826
+ UCHAR IFAIsFifo;475,9892
+ UCHAR IFAIsFifoTar;476,9950
+ UCHAR IFAIsFastSer;477,10022
+ UCHAR AIsVCP;478,10086
+ UCHAR IFBIsFifo;479,10152
+ UCHAR IFBIsFifoTar;480,10210
+ UCHAR IFBIsFastSer;481,10282
+ UCHAR BIsVCP;482,10346
+ UCHAR UseExtOsc;486,10445
+ UCHAR HighDriveIOs;487,10493
+ UCHAR EndpointSize;488,10536
+ UCHAR PullDownEnableR;490,10579
+ UCHAR SerNumEnableR;491,10638
+ UCHAR InvertTXD;493,10704
+ UCHAR InvertRXD;494,10751
+ UCHAR InvertRTS;495,10798
+ UCHAR InvertCTS;496,10845
+ UCHAR InvertDTR;497,10892
+ UCHAR InvertDSR;498,10939
+ UCHAR InvertDCD;499,10986
+ UCHAR InvertRI;500,11033
+ UCHAR Cbus0;502,11081
+ UCHAR Cbus1;503,11119
+ UCHAR Cbus2;504,11157
+ UCHAR Cbus3;505,11195
+ UCHAR Cbus4;506,11233
+ UCHAR RIsVCP;508,11273
+} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA;PFT_PROGRAM_DATA510,11324
+typedef struct _FTCOMSTAT 701,14908
+ DWORD fCtsHold 702,14937
+ DWORD fDsrHold 703,14962
+ DWORD fRlsdHold 704,14987
+ DWORD fXoffHold 705,15013
+ DWORD fXoffSent 706,15039
+ DWORD fEof 707,15065
+ DWORD fTxim 708,15086
+ DWORD fReserved 709,15108
+ DWORD cbInQue;710,15135
+ DWORD cbOutQue;711,15155
+} FTCOMSTAT, *LPFTCOMSTAT;LPFTCOMSTAT712,15176
+typedef struct _FTDCB 714,15206
+ DWORD DCBlength;715,15231
+ DWORD BaudRate;716,15296
+ DWORD fBinary:fBinary717,15361
+ DWORD fParity:fParity718,15426
+ DWORD fOutxCtsFlow:fOutxCtsFlow719,15491
+ DWORD fOutxDsrFlow:fOutxDsrFlow720,15556
+ DWORD fDtrControl:fDtrControl721,15621
+ DWORD fDsrSensitivity:fDsrSensitivity722,15686
+ DWORD fTXContinueOnXoff:fTXContinueOnXoff723,15751
+ DWORD fOutX:fOutX724,15817
+ DWORD fInX:fInX725,15882
+ DWORD fErrorChar:fErrorChar726,15947
+ DWORD fNull:fNull727,16012
+ DWORD fRtsControl:fRtsControl728,16077
+ DWORD fAbortOnError:fAbortOnError729,16142
+ DWORD fDummy2:fDummy2730,16212
+ WORD wReserved;731,16277
+ WORD XonLim;732,16342
+ WORD XoffLim;733,16407
+ BYTE ByteSize;734,16472
+ BYTE Parity;735,16537
+ BYTE StopBits;736,16602
+ char XonChar;737,16667
+ char XoffChar;738,16732
+ char ErrorChar;739,16797
+ char EofChar;740,16862
+ char EvtChar;741,16927
+ WORD wReserved1;742,16992
+} FTDCB, *LPFTDCB;LPFTDCB743,17057
+typedef struct _FTTIMEOUTS 745,17079
+ DWORD ReadIntervalTimeout;746,17109
+ DWORD ReadTotalTimeoutMultiplier;747,17189
+ DWORD ReadTotalTimeoutConstant;748,17269
+ DWORD WriteTotalTimeoutMultiplier;749,17349
+ DWORD WriteTotalTimeoutConstant;750,17429
+} FTTIMEOUTS,*LPFTTIMEOUTS;LPFTTIMEOUTS751,17509
+typedef struct _ft_device_list_info_node 837,18937
+ ULONG Flags;838,18981
+ ULONG Type;839,18996
+ ULONG ID;840,19013
+ DWORD LocId;841,19025
+ char SerialNumber[SerialNumber842,19040
+ char Description[Description843,19065
+ FT_HANDLE ftHandle;844,19089
+} FT_DEVICE_LIST_INFO_NODE;845,19111
+#define EV_RXCHAR 885,19781
+#define EV_RXFLAG 886,19844
+#define EV_TXEMPTY 887,19911
+#define EV_CTS 888,19973
+#define EV_DSR 889,20031
+#define EV_RLSD 890,20089
+#define EV_BREAK 891,20148
+#define EV_ERR 892,20203
+#define EV_RING 893,20270
+#define EV_PERR 894,20331
+#define EV_RX80FULL 895,20393
+#define EV_EVENT1 896,20467
+#define EV_EVENT2 897,20533
+#define SETXOFF 903,20632
+#define SETXON 904,20695
+#define SETRTS 905,20757
+#define CLRRTS 906,20810
+#define SETDTR 907,20862
+#define CLRDTR 908,20915
+#define RESETDEV 909,20967
+#define SETBREAK 910,21032
+#define CLRBREAK 911,21099
+#define PURGE_TXABORT 916,21204
+#define PURGE_RXABORT 917,21294
+#define PURGE_TXCLEAR 918,21383
+#define PURGE_RXCLEAR 919,21457
+
+includes/gdb.h,2617
+#define GDB_H49,2541
+enum enum_errors 64,2883
+ ERR_NONE 68,2992
+ ERR_CRC 69,3009
+ ERR_MEM 70,3026
+ JTAG_PROXY_INVALID_COMMAND 71,3043
+ JTAG_PROXY_SERVER_TERMINATED 72,3079
+ JTAG_PROXY_NO_CONNECTION 73,3117
+ JTAG_PROXY_PROTOCOL_ERROR 74,3151
+ JTAG_PROXY_COMMAND_NOT_IMPLEMENTED 75,3186
+ JTAG_PROXY_INVALID_CHAIN 76,3230
+ JTAG_PROXY_INVALID_ADDRESS 77,3264
+ JTAG_PROXY_ACCESS_EXCEPTION 78,3300
+ JTAG_PROXY_INVALID_LENGTH 79,3357
+ JTAG_PROXY_OUT_OF_MEMORY 80,3393
+enum jtag_chains84,3459
+ SC_GLOBAL,86,3482
+ SC_RISC_DEBUG,87,3527
+ SC_RISC_TEST,88,3583
+ SC_TRACE,89,3628
+ SC_REGISTER,90,3669
+ SC_WISHBONE,91,3713
+ SC_BLOCK,92,3755
+#define JI_SIZE 96,3849
+enum jtag_instr97,3870
+ JI_EXTEST,99,3892
+ JI_SAMPLE_PRELOAD,100,3908
+ JI_IDCODE,101,3932
+ JI_CHAIN_SELECT,102,3948
+ JI_INTEST,103,3970
+ JI_CLAMP,104,3986
+ JI_CLAMPZ,105,4001
+ JI_HIGHZ,106,4017
+ JI_DEBUG,107,4032
+ JI_BYPASS 108,4047
+ JI_BYPASS = 0xFxF108,4047
+#define JTAG_MODER 112,4100
+#define JTAG_TSEL 113,4127
+#define JTAG_QSEL 114,4154
+#define JTAG_SSEL 115,4181
+#define JTAG_RISCOP 116,4208
+#define JTAG_RECWP0 117,4235
+#define JTAG_RECBP0 118,4263
+ JTAG_COMMAND_READ 125,4478
+ JTAG_COMMAND_WRITE 126,4504
+ JTAG_COMMAND_BLOCK_READ 127,4531
+ JTAG_COMMAND_BLOCK_WRITE 128,4563
+ JTAG_COMMAND_CHAIN 129,4596
+} JTAG_proxy_protocol_commands;130,4623
+ uint32_t command;142,5042
+ uint32_t length;143,5063
+ uint32_t address;144,5083
+ uint32_t data_H;145,5104
+ uint32_t data_L;146,5124
+} JTAGProxyWriteMessage;147,5144
+ uint32_t command;150,5190
+ uint32_t length;151,5211
+ uint32_t address;152,5231
+} JTAGProxyReadMessage;153,5252
+ uint32_t command;156,5297
+ uint32_t length;157,5318
+ uint32_t address;158,5338
+ int32_t nRegisters;159,5359
+ uint32_t data[data160,5383
+} JTAGProxyBlockWriteMessage;161,5404
+ uint32_t command;164,5455
+ uint32_t length;165,5476
+ uint32_t address;166,5496
+ int32_t nRegisters;167,5517
+} JTAGProxyBlockReadMessage;168,5541
+ uint32_t command;171,5591
+ uint32_t length;172,5612
+ uint32_t chain;173,5632
+} JTAGProxyChainMessage;174,5651
+ int32_t status;182,5894
+} JTAGProxyWriteResponse;183,5913
+ int32_t status;186,5960
+ uint32_t data_H;187,5979
+ uint32_t data_L;188,5999
+} JTAGProxyReadResponse;189,6019
+ int32_t status;192,6067
+} JTAGProxyBlockWriteResponse;193,6086
+ int32_t status;196,6138
+ int32_t nRegisters;197,6157
+ uint32_t data[data198,6180
+} JTAGProxyBlockReadResponse;200,6251
+ int32_t status;203,6302
+} JTAGProxyChainResponse;204,6321
+
+includes/or_debug_proxy.h,878
+#define _OR_DEBUG_PROXY_H_48,2471
+#define DEBUG_CMDS 51,2521
+#define DEBUG_USB_DRVR_FUNCS 55,2643
+#define DEBUG_GDB_BLOCK_DATA 59,2770
+#define DEBUG_GDB 64,2933
+#define DEBUG_GDB_DUMP_DATA 68,3030
+#define Boolean 71,3138
+#define false 72,3159
+#define true 73,3176
+#define CRC_SIZE 76,3258
+#define DBGCHAIN_SIZE 86,3497
+#define DC_STATUS_SIZE 87,3622
+#define DC_WISHBONE 89,3653
+#define DC_CPU0 90,3682
+#define DC_CPU1 91,3711
+#define DI_GO 93,3742
+#define DI_READ_CMD 94,3768
+#define DI_WRITE_CMD 95,3794
+#define DI_READ_CTRL 96,3820
+#define DI_WRITE_CTRL 97,3846
+#define DBG_CRC_SIZE 99,3874
+#define DBG_CRC_POLY 100,3904
+#define DBG_ERR_OK 102,3944
+#define DBG_ERR_INVALID_ENDPOINT 103,3973
+#define DBG_ERR_CRC 104,4009
+#define NUM_SOFT_RETRIES 106,4040
+#define NUM_HARD_RETRIES 107,4069
+#define NUM_ACCESS_RETRIES 108,4098
+#define CHECK(139,5295
+
+includes/usb_functions.h,26
+#define ULONGEST 48,2413
+
+includes/vpi_functions.h,118
+#define VPI_PORT 49,2525
+#define debug 52,2566
+#define debug54,2593
+#define debug2 58,2633
+#define debug260,2661
+
+includes/win_FTCJTAG.h,3276
+#define win_FTCJTAG_H26,400
+#define FTCJTAG_API 38,950
+#define FTCJTAG_API 40,1000
+typedef DWORD FTC_HANDLE;43,1053
+typedef ULONG FTC_STATUS;44,1080
+#define TEST_LOGIC_STATE 46,1109
+#define RUN_TEST_IDLE_STATE 47,1137
+#define PAUSE_TEST_DATA_REGISTER_STATE 48,1168
+#define PAUSE_INSTRUCTION_REGISTER_STATE 49,1210
+#define SHIFT_TEST_DATA_REGISTER_STATE 50,1254
+#define SHIFT_INSTRUCTION_REGISTER_STATE 51,1296
+#define FTC_SUCCESS 53,1342
+#define FTC_INVALID_HANDLE 54,1375
+#define FTC_DEVICE_NOT_FOUND 55,1427
+#define FTC_DEVICE_NOT_OPENED 56,1482
+#define FTC_IO_ERROR 57,1539
+#define FTC_INSUFFICIENT_RESOURCES 58,1578
+#define FTC_FAILED_TO_COMPLETE_COMMAND 60,1648
+#define FTC_FAILED_TO_SYNCHRONIZE_DEVICE_MPSSE 61,1757
+#define FTC_INVALID_DEVICE_NAME_INDEX 62,1866
+#define FTC_NULL_DEVICE_NAME_BUFFER_POINTER 63,1975
+#define FTC_DEVICE_NAME_BUFFER_TOO_SMALL 64,2085
+#define FTC_INVALID_DEVICE_NAME 65,2194
+#define FTC_INVALID_LOCATION_ID 66,2303
+#define FTC_DEVICE_IN_USE 67,2412
+#define FTC_TOO_MANY_DEVICES 68,2521
+#define FTC_INVALID_CLOCK_DIVISOR 69,2630
+#define FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER 70,2668
+#define FTC_INVALID_NUMBER_BITS 71,2717
+#define FTC_NULL_WRITE_DATA_BUFFER_POINTER 72,2753
+#define FTC_INVALID_NUMBER_BYTES 73,2800
+#define FTC_NUMBER_BYTES_TOO_SMALL 74,2837
+#define FTC_INVALID_TAP_CONTROLLER_STATE 75,2876
+#define FTC_NULL_READ_DATA_BUFFER_POINTER 76,2921
+#define FTC_COMMAND_SEQUENCE_BUFFER_FULL 77,2967
+#define FTC_NULL_READ_CMDS_DATA_BUFFER_POINTER 78,3012
+#define FTC_NO_COMMAND_SEQUENCE 79,3063
+#define FTC_NULL_DLL_VERSION_BUFFER_POINTER 80,3099
+#define FTC_DLL_VERSION_BUFFER_TOO_SMALL 81,3147
+#define FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER 82,3192
+#define FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER 83,3242
+#define FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL 84,3292
+#define FTC_INVALID_LANGUAGE_CODE 85,3339
+#define FTC_INVALID_STATUS_CODE 86,3377
+typedef struct Ft_Input_Output_Pins{Ft_Input_Output_Pins119,4347
+ BOOL bPin1InputOutputState;120,4385
+ BOOL bPin1LowHighState;121,4417
+ BOOL bPin2InputOutputState;122,4445
+ BOOL bPin2LowHighState;123,4477
+ BOOL bPin3InputOutputState;124,4505
+ BOOL bPin3LowHighState;125,4537
+ BOOL bPin4InputOutputState;126,4565
+ BOOL bPin4LowHighState;127,4597
+}FTC_INPUT_OUTPUT_PINS, *PFTC_INPUT_OUTPUT_PINS;PFTC_INPUT_OUTPUT_PINS128,4625
+typedef struct Ft_Low_High_Pins{Ft_Low_High_Pins136,5010
+ BOOL bPin1LowHighState;137,5044
+ BOOL bPin2LowHighState;138,5072
+ BOOL bPin3LowHighState;139,5100
+ BOOL bPin4LowHighState;140,5128
+}FTC_LOW_HIGH_PINS, *PFTC_LOW_HIGH_PINS;PFTC_LOW_HIGH_PINS141,5156
+#define MAX_WRITE_DATA_BYTES_BUFFER_SIZE 149,5513
+typedef BYTE WriteDataByteBuffer[WriteDataByteBuffer151,5579
+typedef WriteDataByteBuffer *PWriteDataByteBuffer;PWriteDataByteBuffer152,5648
+#define MAX_READ_DATA_BYTES_BUFFER_SIZE 159,5972
+typedef BYTE ReadDataByteBuffer[ReadDataByteBuffer161,6037
+typedef ReadDataByteBuffer *PReadDataByteBuffer;PReadDataByteBuffer162,6104
+#define MAX_READ_CMDS_DATA_BYTES_BUFFER_SIZE 191,7554
+typedef BYTE ReadCmdSequenceDataByteBuffer[ReadCmdSequenceDataByteBuffer193,7625
+typedef ReadCmdSequenceDataByteBuffer *PReadCmdSequenceDataByteBuffer;PReadCmdSequenceDataByteBuffer194,7708
+
+includes/win_FTCJTAG_ptrs.h,2991
+#define _WIN_FTCJTAG_PTRS_H_2,30
+typedef FTC_STATUS _stdcall (*jtagGetNumDevicesPtr)jtagGetNumDevicesPtr5,65
+jtagGetNumDevicesPtr jtagGetNumDevices;6,143
+typedef FTC_STATUS _stdcall (*jtagInitDevicePtr)jtagInitDevicePtr8,186
+jtagInitDevicePtr jtagInitDevice;9,280
+typedef FTC_STATUS _stdcall (*jtagOpenPtr)jtagOpenPtr11,317
+jtagOpenPtr jtagOpen;12,385
+typedef FTC_STATUS _stdcall (*jtagOpenExPtr)jtagOpenExPtr14,410
+jtagOpenExPtr jtagOpenEx;15,520
+typedef FTC_STATUS _stdcall (*jtagGetDeviceNameLocIDPtr)jtagGetDeviceNameLocIDPtr17,549
+jtagGetDeviceNameLocIDPtr jtagGetDeviceNameLocID;18,703
+typedef FTC_STATUS _stdcall (*jtagClosePtr)jtagClosePtr20,756
+jtagClosePtr jtagClose;21,823
+typedef FTC_STATUS _stdcall (*jtagGetClockPtr)jtagGetClockPtr24,852
+jtagGetClockPtr jtagGetClock;25,953
+typedef FTC_STATUS _stdcall (*jtagSetClockPtr)jtagSetClockPtr28,988
+jtagSetClockPtr jtagSetClock;29,1110
+typedef FTC_STATUS _stdcall (*jtagSetLoopbackPtr)jtagSetLoopbackPtr31,1143
+jtagSetLoopbackPtr jtagSetLoopback;32,1237
+typedef FTC_STATUS _stdcall (*jtagSetGPIOsPtr)jtagSetGPIOsPtr35,1278
+jtagSetGPIOsPtr jtagSetGPIOs;39,1647
+typedef FTC_STATUS _stdcall (*jtagGetGPIOsPtr)jtagGetGPIOsPtr42,1682
+jtagGetGPIOsPtr jtagGetGPIOs;46,1935
+typedef FTC_STATUS _stdcall (*jtagWritePtr)jtagWritePtr49,1970
+jtagWritePtr jtagWrite;52,2200
+typedef FTC_STATUS _stdcall (*jtagReadPtr)jtagReadPtr55,2229
+jtagReadPtr jtagRead;58,2458
+typedef FTC_STATUS _stdcall (*jtagWriteReadPtr)jtagWriteReadPtr61,2485
+jtagWriteReadPtr jtagWriteRead;65,2791
+typedef FTC_STATUS _stdcall (*jtagAddWriteCmdPtr)jtagAddWriteCmdPtr68,2828
+jtagAddWriteCmdPtr jtagAddWriteCmd;71,3041
+typedef FTC_STATUS _stdcall (*jtagAddReadCmdPtr)jtagAddReadCmdPtr75,3084
+jtagAddReadCmdPtr jtagAddReadCmd;76,3213
+typedef FTC_STATUS _stdcall (*jtagAddWriteReadCmdPtr)jtagAddWriteReadCmdPtr80,3254
+jtagAddWriteReadCmdPtr jtagAddWriteReadCmd;83,3537
+typedef FTC_STATUS _stdcall (*jtagClearDeviceCmdSequencePtr)jtagClearDeviceCmdSequencePtr88,3590
+jtagClearDeviceCmdSequencePtr jtagClearDeviceCmdSequence;89,3674
+typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteCmdPtr)jtagAddDeviceWriteCmdPtr93,3739
+ jtagAddDeviceWriteCmdPtr jtagAddDeviceWriteCmd;96,3977
+typedef FTC_STATUS _stdcall (*jtagAddDeviceReadCmdPtr)jtagAddDeviceReadCmdPtr100,4039
+jtagAddDeviceReadCmdPtr jtagAddDeviceReadCmd;101,4195
+typedef FTC_STATUS _stdcall (*jtagAddDeviceWriteReadCmdPtr)jtagAddDeviceWriteReadCmdPtr105,4248
+jtagAddDeviceWriteReadCmdPtr jtagAddDeviceWriteReadCmd;108,4502
+typedef FTC_STATUS _stdcall (*jtagExecuteCmdSequencePtr)jtagExecuteCmdSequencePtr112,4565
+jtagExecuteCmdSequencePtr jtagExecuteCmdSequence;114,4743
+typedef FTC_STATUS _stdcall (*jtagGetDllVersionPtr)jtagGetDllVersionPtr118,4800
+jtagGetDllVersionPtr jtagGetDllVersion;119,4900
+typedef FTC_STATUS _stdcall (*jtagGetErrorCodeStringPtr)jtagGetErrorCodeStringPtr123,4947
+jtagGetErrorCodeStringPtr jtagGetErrorCodeString;125,5104
+
+includes/WinTypes.h,2042
+#define __WINDOWS_TYPES__2,26
+#define MAX_NUM_DEVICES 4,53
+typedef unsigned long DWORD;7,103
+typedef unsigned long ULONG;8,133
+typedef unsigned short USHORT;9,163
+typedef short SHORT;10,195
+typedef unsigned char UCHAR;11,219
+typedef unsigned short WORD;12,248
+typedef unsigned char BYTE;13,277
+typedef unsigned char *LPBYTE;LPBYTE14,305
+typedef int BOOL;15,336
+typedef char BOOLEAN;16,356
+typedef char CHAR;17,380
+typedef int *LPBOOL;LPBOOL18,401
+typedef unsigned char *PUCHAR;PUCHAR19,424
+typedef const char *LPCSTR;LPCSTR20,456
+typedef char *PCHAR;PCHAR21,484
+typedef void *PVOID;PVOID22,506
+typedef void *HANDLE;HANDLE23,529
+typedef long LONG;24,553
+typedef int INT;25,574
+typedef unsigned int UINT;26,593
+typedef char *LPSTR;LPSTR27,621
+typedef char *LPTSTR;LPTSTR28,644
+typedef DWORD *LPDWORD;LPDWORD29,668
+typedef WORD *LPWORD;LPWORD30,694
+typedef ULONG *PULONG;PULONG31,718
+typedef PVOID LPVOID;32,742
+typedef void VOID;33,765
+typedef unsigned long long int ULONGLONG;34,785
+typedef struct _OVERLAPPED 36,828
+ DWORD Internal;37,857
+ DWORD InternalHigh;38,874
+ DWORD Offset;39,895
+ DWORD OffsetHigh;40,910
+ HANDLE hEvent;41,929
+} OVERLAPPED, *LPOVERLAPPED;LPOVERLAPPED42,945
+typedef struct _SECURITY_ATTRIBUTES 44,975
+ DWORD nLength;45,1013
+ LPVOID lpSecurityDescriptor;46,1029
+ BOOL bInheritHandle;47,1059
+} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES;LPSECURITY_ATTRIBUTES48,1081
+typedef struct timeval SYSTEMTIME;50,1130
+typedef struct timeval FILETIME;51,1165
+#define TRUE 53,1211
+#define FALSE 56,1247
+#define MS_CTS_ON 62,1299
+#define MS_DSR_ON 63,1343
+#define MS_RING_ON 64,1387
+#define MS_RLSD_ON 65,1431
+#define CE_RXOVER 71,1498
+#define CE_OVERRUN 72,1560
+#define CE_RXPARITY 73,1621
+#define CE_FRAME 74,1681
+#define CE_BREAK 75,1742
+#define CE_TXFULL 76,1796
+#define CE_PTO 77,1852
+#define CE_IOE 78,1904
+#define CE_DNS 79,1958
+#define CE_OOP 80,2022
+#define CE_MODE 81,2079
+#define INVALID_HANDLE_VALUE 84,2175
+
+includes/usb_driver_calls.h,0