dirs refactoring
This commit is contained in:
10
modules/drivers/CMakeLists.txt
Normal file
10
modules/drivers/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
file(GLOB MAIN_SOURCES "*.c")
|
||||
file(GLOB_RECURSE JLINK_SOURCES "jlink_jtag/*.c")
|
||||
file(GLOB_RECURSE FTDI_SOURCES "ftdi_jtag/*.c")
|
||||
file(GLOB_RECURSE GPIO_SOURCES "linux_gpio_jtag/*.c")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
|
||||
add_library(drivers ${MAIN_SOURCES} ${FTDI_SOURCES} ${GPIO_SOURCES} ${JLINK_SOURCES})
|
||||
65
modules/drivers/drivers_list.c
Normal file
65
modules/drivers/drivers_list.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers_list.h
|
||||
* @brief drivers list
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
#include "drv_loader.h"
|
||||
|
||||
#include "jtag_core/jtag_core_internal.h"
|
||||
#include "jtag_core/jtag_core.h"
|
||||
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "./lpt_jtag/lpt_jtag_drv.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
#include "./linux_gpio_jtag/linux_gpio_jtag_drv.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(WIN32)
|
||||
#include "./ftdi_jtag/ftdi_jtag_drv.h"
|
||||
#include "./jlink_jtag/jlink_jtag_drv.h"
|
||||
#endif
|
||||
|
||||
#include "drivers_list.h"
|
||||
|
||||
const drv_entry staticdrvs[] =
|
||||
{
|
||||
#ifdef WIN32
|
||||
#if !defined(_WIN64)
|
||||
{(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,0},
|
||||
{(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,1},
|
||||
{(DRV_GETMODULEINFOS)drv_LPT_libGetDrv,2},
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__linux__) || defined(WIN32)
|
||||
{(DRV_GETMODULEINFOS)drv_FTDI_libGetDrv,0},
|
||||
{(DRV_GETMODULEINFOS)drv_JLINK_libGetDrv,0},
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
{(DRV_GETMODULEINFOS)drv_LinuxGPIO_libGetDrv,0},
|
||||
#endif
|
||||
{(DRV_GETMODULEINFOS)-1,0}
|
||||
};
|
||||
33
modules/drivers/drivers_list.h
Normal file
33
modules/drivers/drivers_list.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers_list.h
|
||||
* @brief drivers list struct
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
typedef struct _drv_entry
|
||||
{
|
||||
DRV_GETMODULEINFOS getinfosfunc;
|
||||
int sub_drv_id;
|
||||
}drv_entry;
|
||||
|
||||
extern const drv_entry staticdrvs[];
|
||||
|
||||
|
||||
120
modules/drivers/drv_loader.c
Normal file
120
modules/drivers/drv_loader.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drv_loader.c
|
||||
* @brief driver loader
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "drv_loader.h"
|
||||
|
||||
#include "jtag_core/jtag_core_internal.h"
|
||||
#include "jtag_core/jtag_core.h"
|
||||
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
|
||||
#include "drivers_list.h"
|
||||
|
||||
#include "jtag_core/dbg_logs.h"
|
||||
|
||||
int GetDrvInfo(void * jc_ctx,unsigned long infotype,void * returnvalue,const char * drv_id,const char * drv_desc,drv_ptr * drv_func)
|
||||
{
|
||||
if(jc_ctx)
|
||||
{
|
||||
if(returnvalue)
|
||||
{
|
||||
switch(infotype)
|
||||
{
|
||||
case GET_DRV_ID:
|
||||
*(char**)(returnvalue)=(char*)drv_id;
|
||||
break;
|
||||
|
||||
case GET_DRV_DESCRIPTION:
|
||||
strcpy(returnvalue, (char*)drv_desc);
|
||||
break;
|
||||
|
||||
case GET_DRV_FUNCPTR:
|
||||
memcpy(returnvalue,drv_func,sizeof(drv_ptr));
|
||||
break;
|
||||
|
||||
case GET_DRV_DETECT:
|
||||
*((int*)(returnvalue)) = drv_func->drv_Detect(jc_ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
return JTAG_CORE_BAD_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
return JTAG_CORE_NO_ERROR;
|
||||
}
|
||||
}
|
||||
return JTAG_CORE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
int jtagcore_loaddriver(jtag_core * jc, int id, char * parameters)
|
||||
{
|
||||
int i,ret;
|
||||
i = 0;
|
||||
|
||||
while (staticdrvs[i].getinfosfunc != (DRV_GETMODULEINFOS)-1 )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( (id >> 8) < i)
|
||||
{
|
||||
if (jc->io_functions.drv_DeInit)
|
||||
{
|
||||
jc->io_functions.drv_DeInit(jc);
|
||||
memset(&jc->io_functions, 0, sizeof(drv_ptr));
|
||||
}
|
||||
|
||||
staticdrvs[id>>8].getinfosfunc(jc, id & 0xFF, GET_DRV_FUNCPTR, &jc->io_functions);
|
||||
|
||||
if( jc->io_functions.drv_Init )
|
||||
{
|
||||
ret = jc->io_functions.drv_Init(jc, id & 0xFF,0);
|
||||
if (ret < 0)
|
||||
{
|
||||
jtagcore_logs_printf(jc, MSG_ERROR, "jtagcore_loaddriver : Can't load the driver !\r\n");
|
||||
memset(&jc->io_functions, 0, sizeof(drv_ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc, MSG_INFO_0, "jtagcore_loaddriver : Probe Driver 0x%.8X loaded...\r\n", id);
|
||||
}
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
fail:
|
||||
jtagcore_logs_printf(jc, MSG_ERROR, "jtagcore_loaddriver : Driver ID not found !\r\n");
|
||||
|
||||
return JTAG_CORE_NOT_FOUND;
|
||||
};
|
||||
|
||||
50
modules/drivers/drv_loader.h
Normal file
50
modules/drivers/drv_loader.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drv_loader.h
|
||||
* @brief driver functions definitions
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
enum {
|
||||
GET_DRV_ID = 1,
|
||||
GET_DRV_DESCRIPTION,
|
||||
GET_DRV_FUNCPTR,
|
||||
GET_DRV_DETECT
|
||||
};
|
||||
|
||||
typedef int (*DRV_DETECT) (void* jtag_core);
|
||||
typedef int (*DRV_INIT) (void* jtag_core,int sub_drv,char * params);
|
||||
typedef int (*DRV_TXRXDATA) (void* jtag_core, unsigned char * str_out, unsigned char * str_in, int size);
|
||||
typedef int (*DRV_TXTMS) (void* jtag_core, unsigned char * str_out, int size);
|
||||
typedef int (*DRV_GETMODULEINFOS) (void* jtag_core,int sub_drv,unsigned int infotype, void * returnvalue);
|
||||
typedef int (*DRV_DEINIT) (void* jtag_core);
|
||||
|
||||
typedef struct drv_ptr_
|
||||
{
|
||||
DRV_DETECT drv_Detect;
|
||||
DRV_INIT drv_Init;
|
||||
DRV_DEINIT drv_DeInit;
|
||||
DRV_TXTMS drv_TX_TMS;
|
||||
DRV_TXRXDATA drv_TXRX_DATA;
|
||||
DRV_GETMODULEINFOS drv_Get_ModInfos;
|
||||
} drv_ptr;
|
||||
|
||||
int GetDrvInfo(void * jc_ctx, unsigned long infotype, void * returnvalue, const char * drv_id, const char * drv_desc, drv_ptr * drv_func);
|
||||
954
modules/drivers/ftdi_jtag/ftdi_jtag_drv.c
Normal file
954
modules/drivers/ftdi_jtag/ftdi_jtag_drv.c
Normal file
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ftdi_jtag_drv.c
|
||||
* @brief FTDI based probes driver
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(WIN32)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "../drv_loader.h"
|
||||
#include "jtag_core/jtag_core_internal.h"
|
||||
#include "jtag_core/jtag_core.h"
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
#include "jtag_core/dbg_logs.h"
|
||||
#include "os_interface/os_interface.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ftd2xx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define MACH_WORD long long
|
||||
#else
|
||||
#define MACH_WORD int
|
||||
#endif
|
||||
|
||||
typedef struct _drv_desc
|
||||
{
|
||||
char drv_id[128];
|
||||
char drv_desc[128];
|
||||
int id;
|
||||
int ftdi_index;
|
||||
}drv_desc;
|
||||
|
||||
#define PROBE_GENERIC_FTDI 0
|
||||
|
||||
#define MAX_PROBES_FTDI 8
|
||||
|
||||
static drv_desc subdrv_list[MAX_PROBES_FTDI]=
|
||||
{
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0},
|
||||
{"USB_GENERIC_FTDI_PROBE","GENERIC USB FTDI PROBE",PROBE_GENERIC_FTDI,0}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Command Processor for MPSSE and MCU Host Bus Emulation Modes
|
||||
//
|
||||
// The data shifting commands are made up of the following definitions:
|
||||
// Bit 7 : 0
|
||||
// Bit 6 : Do write TMS
|
||||
// Bit 5 : Do read TDO
|
||||
// Bit 4 : Do write TDI
|
||||
// Bit 3 : LSB first = 1 else MSB first = 0
|
||||
// Bit 2 : -ve CLK on read
|
||||
// Bit 1 : bit mode = 1 else byte mode = 0
|
||||
// Bit 0 : -ve CLK on write
|
||||
|
||||
// The write commands to TDI take effect when bits 7 and 6 are '0'. Read TDO will operate with TMS output or TDI output or on its own.
|
||||
|
||||
// Clock Data Bytes Out on +ve clock edge MSB first (no read)
|
||||
// 0x10, LengthL, LengthH, [Byte1..Byte65536 (max)]
|
||||
|
||||
#define OP_WR_TMS (0x1 << 6)
|
||||
#define OP_RD_TDO (0x1 << 5)
|
||||
#define OP_WR_TDI (0x1 << 4)
|
||||
#define OP_LSB_FIRST (0x1 << 3)
|
||||
#define OP_FEDGE_RD (0x1 << 2)
|
||||
#define OP_BIT_MODE (0x1 << 1)
|
||||
#define OP_FEDGE_WR (0x1 << 0)
|
||||
|
||||
#define CMD_ENABLE_LOOPBACK 0x84
|
||||
#define CMD_DISABLE_LOOPBACK 0x85
|
||||
#define CMD_SET_DIVISOR 0x86 // +0xValueL, 0xValueH
|
||||
#define CMD_WAIT_IO_HIGH 0x88
|
||||
#define CMD_WAIT_IO_LOW 0x89
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static FT_HANDLE ftdih = NULL;
|
||||
static FT_DEVICE ftdi_device;
|
||||
|
||||
static int trst_oe_pin, trst_state_pin;
|
||||
static int srst_oe_pin, srst_state_pin;
|
||||
static int led_pin;
|
||||
|
||||
static unsigned char low_direction;
|
||||
static unsigned char low_polarity;
|
||||
static unsigned char low_output;
|
||||
|
||||
static unsigned char high_output;
|
||||
static unsigned char high_polarity;
|
||||
static unsigned char high_direction;
|
||||
|
||||
unsigned char ftdi_out_buf[64 * 1024];
|
||||
unsigned char ftdi_in_buf[64 * 1024];
|
||||
|
||||
#if !defined(WIN32)
|
||||
|
||||
int Sleep( unsigned int timeout_ms )
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout_ms/1000;
|
||||
tv.tv_usec = (timeout_ms%1000) * 1000;
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(FTDILIB)
|
||||
|
||||
typedef FT_STATUS(WINAPI * FT_OPEN)(DWORD deviceNumber, FT_HANDLE *pHandle);
|
||||
typedef FT_STATUS(WINAPI * FT_OPENEX)(PVOID pArg1, DWORD Flags, FT_HANDLE *pHandle);
|
||||
typedef FT_STATUS(WINAPI * FT_READ)(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesReturned);
|
||||
typedef FT_STATUS(WINAPI * FT_WRITE)(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesWritten);
|
||||
typedef FT_STATUS(WINAPI * FT_GETSTATUS)(FT_HANDLE ftHandle, DWORD *dwRxBytes, DWORD *dwTxBytes, DWORD *dwEventDWord);
|
||||
typedef FT_STATUS(WINAPI * FT_PURGE)(FT_HANDLE ftHandle, ULONG Mask);
|
||||
typedef FT_STATUS(WINAPI * FT_SETUSBPARAMETERS)(FT_HANDLE ftHandle, ULONG ulInTransferSize, ULONG ulOutTransferSize);
|
||||
typedef FT_STATUS(WINAPI * FT_SETLATENCYTIMER)(FT_HANDLE ftHandle, UCHAR ucLatency);
|
||||
typedef FT_STATUS(WINAPI * FT_SETEVENTNOTIFICATION)(FT_HANDLE ftHandle, DWORD dwEventMask, PVOID pvArg);
|
||||
typedef FT_STATUS(WINAPI * FT_CLOSE)(FT_HANDLE ftHandle);
|
||||
typedef FT_STATUS(WINAPI * FT_LISTDEVICES)(LPVOID pArg1, LPVOID pArg2, DWORD Flags);
|
||||
typedef FT_STATUS(WINAPI * FT_SETBITMODE)(FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucEnable);
|
||||
typedef FT_STATUS(WINAPI * FT_SETTIMEOUTS)(FT_HANDLE ftHandle, ULONG ReadTimeout, ULONG WriteTimeout);
|
||||
typedef FT_STATUS(WINAPI * FT_GETQUEUESTATUS)(FT_HANDLE ftHandle, DWORD *dwRxBytes);
|
||||
typedef FT_STATUS(WINAPI * FT_GETDEVICEINFO)(FT_HANDLE ftHandle, FT_DEVICE *lpftDevice, LPDWORD lpdwID, PCHAR SerialNumber, PCHAR Description, LPVOID Dummy);
|
||||
typedef FT_STATUS(WINAPI * FT_RESETDEVICE)(FT_HANDLE ftHandle);
|
||||
typedef FT_STATUS(WINAPI * FT_SETCHARS)(FT_HANDLE ftHandle, UCHAR EventChar, UCHAR EventCharEnabled, UCHAR ErrorChar, UCHAR ErrorCharEnabled);
|
||||
|
||||
FT_OPEN pFT_Open;
|
||||
FT_OPENEX pFT_OpenEx;
|
||||
FT_READ pFT_Read;
|
||||
FT_WRITE pFT_Write;
|
||||
FT_GETSTATUS pFT_GetStatus;
|
||||
FT_PURGE pFT_Purge;
|
||||
FT_SETUSBPARAMETERS pFT_SetUSBParameters;
|
||||
FT_SETLATENCYTIMER pFT_SetLatencyTimer;
|
||||
FT_SETEVENTNOTIFICATION pFT_SetEventNotification;
|
||||
FT_CLOSE pFT_Close;
|
||||
FT_LISTDEVICES pFT_ListDevices;
|
||||
FT_SETBITMODE pFT_SetBitMode;
|
||||
FT_SETTIMEOUTS pFT_SetTimeouts;
|
||||
FT_GETQUEUESTATUS pFT_GetQueueStatus;
|
||||
FT_GETDEVICEINFO pFT_GetDeviceInfo;
|
||||
FT_RESETDEVICE pFT_ResetDevice;
|
||||
FT_SETCHARS pFT_SetChars;
|
||||
|
||||
#else
|
||||
#define pFT_Open FT_Open
|
||||
#define pFT_OpenEx FT_OpenEx
|
||||
#define pFT_Read FT_Read
|
||||
#define pFT_Write FT_Write
|
||||
#define pFT_GetStatus FT_GetStatus
|
||||
#define pFT_Purge FT_Purge
|
||||
#define pFT_SetUSBParameters FT_SetUSBParameters
|
||||
#define pFT_SetLatencyTimer FT_SetLatencyTimer
|
||||
#define pFT_SetEventNotification FT_SetEventNotification
|
||||
#define pFT_Close FT_Close
|
||||
#define pFT_ListDevices FT_ListDevices
|
||||
#define pFT_SetBitMode FT_SetBitMode
|
||||
#define pFT_SetTimeouts FT_SetTimeouts
|
||||
#define pFT_GetQueueStatus FT_GetQueueStatus
|
||||
#define pFT_GetDeviceInfo FT_GetDeviceInfo
|
||||
#define pFT_ResetDevice FT_ResetDevice
|
||||
#define pFT_SetChars FT_SetChars
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int ft2232_set_data_bits_low_byte(unsigned char value, unsigned char direction)
|
||||
{
|
||||
FT_STATUS status;
|
||||
DWORD dw_bytes_written = 0;
|
||||
unsigned char buf[3];
|
||||
|
||||
buf[0] = 0x80; // command "set data bits low byte"
|
||||
buf[1] = value; // value
|
||||
buf[2] = direction; // direction
|
||||
|
||||
status = pFT_Write(ftdih, buf, sizeof(buf), &dw_bytes_written);
|
||||
if ( (status != FT_OK) || (dw_bytes_written != sizeof(buf) ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft2232_set_data_bits_high_byte(unsigned char value, unsigned char direction)
|
||||
{
|
||||
FT_STATUS status;
|
||||
DWORD dw_bytes_written = 0;
|
||||
unsigned char buf[3];
|
||||
|
||||
buf[0] = 0x82; // command "set data bits high byte"
|
||||
buf[1] = value; // value
|
||||
buf[2] = direction; // direction
|
||||
|
||||
status = pFT_Write(ftdih, buf, sizeof(buf), &dw_bytes_written);
|
||||
if ( (status != FT_OK) || ( dw_bytes_written != sizeof(buf) ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft2232h_enable_rtck(int enable)
|
||||
{
|
||||
FT_STATUS status;
|
||||
DWORD dw_bytes_written = 0;
|
||||
unsigned char buf;
|
||||
|
||||
buf = enable ? 0x96 : 0x97;
|
||||
|
||||
status = pFT_Write(ftdih, &buf, sizeof(buf), &dw_bytes_written);
|
||||
if ( (status != FT_OK) || ( dw_bytes_written != sizeof(buf) ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_FTDI_Detect(jtag_core * jc)
|
||||
{
|
||||
int numDevs,i;
|
||||
FT_STATUS status;
|
||||
char SerialNumber[512];
|
||||
|
||||
status = pFT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
|
||||
if (status != FT_OK && !numDevs)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_ListDevices : Error %x !\r\n",status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while( i<numDevs && i<MAX_PROBES_FTDI )
|
||||
{
|
||||
status = pFT_ListDevices((LPVOID)(MACH_WORD)i, SerialNumber, FT_LIST_BY_INDEX | FT_OPEN_BY_DESCRIPTION);
|
||||
if (status != FT_OK)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_ListDevices : Error %x !\r\n",status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(subdrv_list[i].drv_id,SerialNumber);
|
||||
strcpy(subdrv_list[i].drv_desc,SerialNumber);
|
||||
strcat(subdrv_list[i].drv_desc," ");
|
||||
|
||||
status = pFT_ListDevices((LPVOID)(MACH_WORD)i, SerialNumber, FT_LIST_BY_INDEX | FT_OPEN_BY_SERIAL_NUMBER);
|
||||
if (status != FT_OK)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_ListDevices : Error %x !\r\n",status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcat(subdrv_list[i].drv_desc,SerialNumber);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
jtagcore_logs_printf( jc, MSG_INFO_1, "drv_FTDI_Detect : %d interface(s) found !\r\n", numDevs );
|
||||
|
||||
return numDevs;
|
||||
|
||||
}
|
||||
|
||||
void update_gpio_state(int index,int state)
|
||||
{
|
||||
if( index >=0 )
|
||||
{
|
||||
if(index < 8)
|
||||
{
|
||||
if(state)
|
||||
low_output |= (0x01<<index);
|
||||
else
|
||||
low_output &= ~(0x01<<index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(state)
|
||||
high_output |= (0x01<<(index - 8));
|
||||
else
|
||||
high_output &= ~(0x01<<(index - 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int drv_FTDI_Init(jtag_core * jc, int sub_drv, char * params)
|
||||
{
|
||||
FT_STATUS status;
|
||||
DWORD deviceID;
|
||||
char SerialNumber[16];
|
||||
char Description[64];
|
||||
char tmp_str[64];
|
||||
int numDevs;
|
||||
int baseclock, divisor, tckfreq;
|
||||
DWORD devIndex;
|
||||
DWORD nbRead,nbtosend;
|
||||
int i;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
if(lib_handle == NULL)
|
||||
lib_handle = LoadLibrary("ftd2xx.dll");
|
||||
|
||||
if (lib_handle)
|
||||
{
|
||||
pFT_Write = (FT_WRITE)GetProcAddress(lib_handle, "FT_Write");
|
||||
if (!pFT_Write)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_Read = (FT_READ)GetProcAddress(lib_handle, "FT_Read");
|
||||
if (!pFT_Read)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_GetStatus = (FT_GETSTATUS)GetProcAddress(lib_handle, "FT_GetStatus");
|
||||
if (!pFT_GetStatus)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_Open = (FT_OPEN)GetProcAddress(lib_handle, "FT_Open");
|
||||
if (!pFT_Open)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_Close = (FT_CLOSE)GetProcAddress(lib_handle, "FT_Close");
|
||||
if (!pFT_Close)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_Purge = (FT_PURGE)GetProcAddress(lib_handle, "FT_Purge");
|
||||
if (!pFT_Purge)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_SetUSBParameters = (FT_SETUSBPARAMETERS)GetProcAddress(lib_handle, "FT_SetUSBParameters");
|
||||
if (!pFT_SetUSBParameters)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_SetLatencyTimer = (FT_SETLATENCYTIMER)GetProcAddress(lib_handle, "FT_SetLatencyTimer");
|
||||
if (!pFT_SetLatencyTimer)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_SetEventNotification = (FT_SETEVENTNOTIFICATION)GetProcAddress(lib_handle, "FT_SetEventNotification");
|
||||
if (!pFT_SetEventNotification)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_OpenEx = (FT_OPENEX)GetProcAddress(lib_handle, "FT_OpenEx");
|
||||
if (!pFT_OpenEx)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_ListDevices = (FT_LISTDEVICES)GetProcAddress(lib_handle, "FT_ListDevices");
|
||||
if (!pFT_ListDevices)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_SetBitMode = (FT_SETBITMODE)GetProcAddress(lib_handle, "FT_SetBitMode");
|
||||
if (!pFT_SetBitMode)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_SetTimeouts = (FT_SETTIMEOUTS)GetProcAddress(lib_handle, "FT_SetTimeouts");
|
||||
if (!pFT_SetTimeouts)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_GetQueueStatus = (FT_GETQUEUESTATUS)GetProcAddress(lib_handle, "FT_GetQueueStatus");
|
||||
if (!pFT_GetQueueStatus)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_GetDeviceInfo = (FT_GETDEVICEINFO)GetProcAddress(lib_handle, "FT_GetDeviceInfo");
|
||||
if (!pFT_GetDeviceInfo)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_ResetDevice = (FT_RESETDEVICE)GetProcAddress(lib_handle, "FT_ResetDevice");
|
||||
if (!pFT_ResetDevice)
|
||||
goto loadliberror;
|
||||
|
||||
pFT_SetChars = (FT_SETCHARS)GetProcAddress(lib_handle, "FT_SetChars");
|
||||
if (!pFT_SetChars)
|
||||
goto loadliberror;
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_FTDI_Init : Can't open ftd2xx.dll !\r\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
status = pFT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
|
||||
if (status != FT_OK && !numDevs)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_ListDevices : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
devIndex = sub_drv;
|
||||
status = pFT_ListDevices((LPVOID)(MACH_WORD)devIndex, SerialNumber, FT_LIST_BY_INDEX | FT_OPEN_BY_SERIAL_NUMBER);
|
||||
if (status != FT_OK)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_ListDevices : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
status = pFT_OpenEx(SerialNumber, FT_OPEN_BY_SERIAL_NUMBER, &ftdih);
|
||||
if (status != FT_OK)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_OpenEx : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
status = pFT_ResetDevice(ftdih);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_ResetDevice : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
status = pFT_GetQueueStatus(ftdih, &nbRead);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_GetQueueStatus : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
if ( nbRead > 0)
|
||||
pFT_Read(ftdih, &ftdi_in_buf, nbRead, &nbRead);
|
||||
|
||||
//Set USB request transfer sizes to 64K
|
||||
status = pFT_SetUSBParameters(ftdih, 65536, 65535);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetUSBParameters : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
//Disable event and error characters
|
||||
status = pFT_SetChars(ftdih, 0, 0, 0, 0);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetChars : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
//Sets the read and write timeouts in milliseconds
|
||||
status = pFT_SetTimeouts(ftdih, 5000, 5000);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetTimeouts : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
//Set the latency timer (default is 16mS)
|
||||
status = pFT_SetLatencyTimer(ftdih, 2);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetLatencyTimer : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
//Reset controller
|
||||
status = pFT_SetBitMode(ftdih, 0x0, 0x00);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetBitMode : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
//Enable MPSSE mode
|
||||
status = pFT_SetBitMode(ftdih, 0x0, 0x02);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetBitMode : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
status = pFT_SetBitMode(ftdih, 0x0b, 2);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_SetBitMode : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
status = pFT_GetDeviceInfo(ftdih, &ftdi_device, &deviceID,
|
||||
SerialNumber, Description, NULL);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_GetDeviceInfo : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
/*
|
||||
Olimex ARM-USB-OCD-H JTAG signals
|
||||
|
||||
VREF – voltage follower input for the output buffers adjust JTAG signals as per your target board voltage levels
|
||||
ADBUS0 -> TCK; (out)
|
||||
ADBUS1 -> TDI; (out)
|
||||
ADBUS2 -> TDO; (in)
|
||||
ADBUS3 -> TMS; (out)
|
||||
ADBUS4 -> 0 to enable JTAG buffers; (GPIOL0) (out)
|
||||
ADBUS5 -> 0 if target present; (GPIOL1) (in)
|
||||
ADBUS6 -> TSRST in; (GPIOL2) (in)
|
||||
ADBUS7 -> RTCK; (in) (GPIOL3) (in)
|
||||
|
||||
ACBUS0 -> TRST; (GPIOH0)
|
||||
ACBUS1 -> SRST; (GPIOH1)
|
||||
ACBUS2 -> TRST buffer enable (GPIOH2)
|
||||
ACBUS3 -> RED LED; (GPIOH3)
|
||||
*/
|
||||
|
||||
low_direction = 0x00;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
sprintf(tmp_str,"PROBE_FTDI_SET_PIN_DIR_ADBUS%d",i);
|
||||
if( jtagcore_getEnvVarValue( jc, tmp_str) > 0 )
|
||||
{
|
||||
low_direction |= (0x01<<i);
|
||||
}
|
||||
}
|
||||
|
||||
low_output = 0x00;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
sprintf(tmp_str,"PROBE_FTDI_SET_PIN_DEFAULT_STATE_ADBUS%d",i);
|
||||
if( jtagcore_getEnvVarValue( jc, tmp_str) > 0 )
|
||||
{
|
||||
low_output |= (0x01<<i);
|
||||
}
|
||||
}
|
||||
|
||||
low_polarity = 0;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
sprintf(tmp_str,"PROBE_FTDI_SET_PIN_POLARITY_ADBUS%d",i);
|
||||
if( jtagcore_getEnvVarValue( jc, tmp_str) > 0 )
|
||||
{
|
||||
low_polarity |= (0x01<<i);
|
||||
}
|
||||
}
|
||||
|
||||
high_direction = 0x00;
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
sprintf(tmp_str,"PROBE_FTDI_SET_PIN_DIR_ACBUS%d",i);
|
||||
if( jtagcore_getEnvVarValue( jc, tmp_str) > 0 )
|
||||
{
|
||||
high_direction |= (0x01<<i);
|
||||
}
|
||||
}
|
||||
|
||||
high_output = 0x00;
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
sprintf(tmp_str,"PROBE_FTDI_SET_PIN_DEFAULT_STATE_ACBUS%d",i);
|
||||
if( jtagcore_getEnvVarValue( jc, tmp_str) > 0 )
|
||||
{
|
||||
high_output |= (0x01<<i);
|
||||
}
|
||||
}
|
||||
|
||||
high_polarity = 0x00;
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
sprintf(tmp_str,"PROBE_FTDI_SET_PIN_POLARITY_ACBUS%d",i);
|
||||
if( jtagcore_getEnvVarValue( jc, tmp_str) > 0 )
|
||||
{
|
||||
high_polarity |= (0x01<<i);
|
||||
}
|
||||
}
|
||||
|
||||
trst_oe_pin = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_SET_TRST_OE_PINNUM" );
|
||||
trst_state_pin = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_SET_TRST_STATE_PINNUM" );
|
||||
|
||||
srst_oe_pin = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_SET_SRST_OE_PINNUM" );
|
||||
srst_state_pin = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_SET_SRST_STATE_PINNUM" );
|
||||
|
||||
led_pin = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_SET_CONNECTION_LED_PINNUM" );
|
||||
|
||||
/* jtag reset */
|
||||
update_gpio_state(trst_oe_pin,1);
|
||||
update_gpio_state(trst_state_pin,1);
|
||||
|
||||
update_gpio_state(srst_oe_pin,1);
|
||||
update_gpio_state(srst_state_pin,0);
|
||||
|
||||
/* turn red LED off */
|
||||
update_gpio_state(led_pin,0);
|
||||
|
||||
ft2232_set_data_bits_low_byte( (unsigned char)(low_output ^ low_polarity), low_direction);
|
||||
ft2232_set_data_bits_high_byte( (unsigned char)(high_output ^ high_polarity), high_direction);
|
||||
|
||||
// Clock divisor
|
||||
// 0x86 ValueL ValueH
|
||||
// FT2232D/H
|
||||
// TCK clock = (12Mhz or 60Mhz)/ ((1 + ([ValueH << 8 | ValueL]))*2)
|
||||
|
||||
baseclock = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_INTERNAL_FREQ_KHZ");
|
||||
tckfreq = jtagcore_getEnvVarValue( jc, "PROBE_FTDI_TCK_FREQ_KHZ");
|
||||
if( baseclock <= 0 || tckfreq <= 0){
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_FTDI_Init : Invalid probe clock settings !\r\n");
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
divisor = ( ( baseclock / tckfreq ) - 2 ) / 2;
|
||||
|
||||
nbtosend = 0;
|
||||
ftdi_out_buf[nbtosend++] = CMD_SET_DIVISOR;
|
||||
ftdi_out_buf[nbtosend++] = divisor & 0xFF;
|
||||
ftdi_out_buf[nbtosend++] = (divisor>>8) & 0xFF;
|
||||
|
||||
status = pFT_Write(ftdih, ftdi_out_buf, nbtosend, &nbtosend);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_Write : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
|
||||
#if 0 // Loopback
|
||||
nbtosend = 0;
|
||||
ftdi_out_buf[nbtosend++] = CMD_ENABLE_LOOPBACK;
|
||||
|
||||
status = pFT_Write(ftdih, ftdi_out_buf, nbtosend, &nbtosend);
|
||||
if (status != FT_OK) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pFT_Write : Error %x !\r\n",status);
|
||||
goto loadliberror;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(jtagcore_getEnvVarValue( jc, "PROBE_FTDI_JTAG_ENABLE_RTCK") > 0)
|
||||
{
|
||||
ft2232h_enable_rtck(1);
|
||||
}
|
||||
|
||||
/* Delay... */
|
||||
genos_pause(jtagcore_getEnvVarValue( jc, "PROBE_FTDI_JTAG_TRST_DELAY_MS"));
|
||||
|
||||
/* turn red LED on */
|
||||
update_gpio_state(led_pin,1);
|
||||
|
||||
/* Release system & jtag reset */
|
||||
update_gpio_state(trst_state_pin,0);
|
||||
update_gpio_state(srst_state_pin,0);
|
||||
|
||||
ft2232_set_data_bits_low_byte( (unsigned char)(low_output ^ low_polarity), low_direction);
|
||||
ft2232_set_data_bits_high_byte( (unsigned char)(high_output ^ high_polarity), high_direction);
|
||||
|
||||
jtagcore_logs_printf(jc,MSG_INFO_0,"drv_FTDI_Init : Probe Driver loaded successfully...\r\n");
|
||||
|
||||
return 0;
|
||||
|
||||
loadliberror:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int drv_FTDI_DeInit(jtag_core * jc)
|
||||
{
|
||||
pFT_Close(ftdih);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_FTDI_TDOTDI_xfer(jtag_core * jc, unsigned char * str_out, unsigned char * str_in, int size)
|
||||
{
|
||||
int wr_bit_index,rd_bit_index;
|
||||
int i,payloadsize;
|
||||
unsigned char bitscnt;
|
||||
int rounded_size;
|
||||
DWORD nbRead,nbtosend;
|
||||
FT_STATUS status;
|
||||
unsigned char opcode,data;
|
||||
|
||||
rd_bit_index = 0;
|
||||
wr_bit_index = 0;
|
||||
|
||||
memset(ftdi_out_buf, 0, sizeof(ftdi_out_buf));
|
||||
memset(ftdi_in_buf, 0, sizeof(ftdi_in_buf));
|
||||
|
||||
if (size)
|
||||
{
|
||||
// Set the first TMS/DOUT bit
|
||||
if ( str_out[wr_bit_index] & JTAG_STR_TMS )
|
||||
{
|
||||
if( str_in )
|
||||
opcode = ( OP_WR_TMS | OP_LSB_FIRST | OP_BIT_MODE | OP_FEDGE_WR | OP_RD_TDO ); // with TDO read back
|
||||
else
|
||||
opcode = ( OP_WR_TMS | OP_LSB_FIRST | OP_BIT_MODE | OP_FEDGE_WR );
|
||||
|
||||
nbtosend = 0;
|
||||
|
||||
ftdi_out_buf[nbtosend++] = opcode;
|
||||
ftdi_out_buf[nbtosend++] = 0x00; // Size field : 1 Bit
|
||||
|
||||
data = 0x7F; // TMS state set
|
||||
|
||||
if (str_out[wr_bit_index] & JTAG_STR_DOUT)
|
||||
data |= 0x80; // Bit 7: TDI/DO pin state
|
||||
|
||||
wr_bit_index++;
|
||||
|
||||
ftdi_out_buf[nbtosend++] = data; // Data field
|
||||
|
||||
status = pFT_Write(ftdih, ftdi_out_buf, nbtosend, &nbtosend);
|
||||
|
||||
if ( opcode & OP_RD_TDO )
|
||||
{
|
||||
status = pFT_GetQueueStatus(ftdih, &nbRead);
|
||||
while (nbRead < 1 && (status == FT_OK))
|
||||
{
|
||||
Sleep(3);
|
||||
status = pFT_GetQueueStatus(ftdih, &nbRead);
|
||||
}
|
||||
|
||||
status = pFT_Read(ftdih, &ftdi_in_buf, nbRead, &nbRead);
|
||||
|
||||
// bits are shifted in from MSB to LSB ...
|
||||
if ( ftdi_in_buf[0] & 0x80 )
|
||||
{
|
||||
str_in[rd_bit_index++] = JTAG_STR_DOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_in[rd_bit_index++] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( wr_bit_index >= size )
|
||||
return 0;
|
||||
|
||||
rounded_size = (size - wr_bit_index) & ~(0x7);
|
||||
if( rounded_size )
|
||||
{
|
||||
// byte(s) buffer transmission/reception
|
||||
|
||||
if( str_in )
|
||||
opcode = ( OP_WR_TDI | OP_LSB_FIRST | OP_FEDGE_WR | OP_RD_TDO );
|
||||
else
|
||||
opcode = ( OP_WR_TDI | OP_LSB_FIRST | OP_FEDGE_WR );
|
||||
|
||||
nbtosend = 0;
|
||||
|
||||
ftdi_out_buf[nbtosend++] = opcode;
|
||||
ftdi_out_buf[nbtosend++] = ( ( (rounded_size>>3)-1 ) & 0xff ); // (Size-1) Low byte
|
||||
ftdi_out_buf[nbtosend++] = ( ( (rounded_size>>3)-1 ) >> 8 ); // (Size-1) High byte
|
||||
|
||||
ftdi_out_buf[nbtosend] = 0x00;
|
||||
|
||||
i = 0;
|
||||
payloadsize = 0;
|
||||
while (payloadsize < rounded_size)
|
||||
{
|
||||
if (str_out[wr_bit_index] & JTAG_STR_DOUT)
|
||||
{
|
||||
ftdi_out_buf[nbtosend] |= (0x01 << (i & 0x7));
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (!(i & 0x7))
|
||||
{
|
||||
nbtosend++;
|
||||
ftdi_out_buf[nbtosend] = 0x00;
|
||||
}
|
||||
|
||||
payloadsize++;
|
||||
wr_bit_index++;
|
||||
}
|
||||
|
||||
status = pFT_Write(ftdih, ftdi_out_buf, nbtosend, &nbtosend);
|
||||
|
||||
if (str_in)
|
||||
{
|
||||
do
|
||||
{
|
||||
Sleep(3);
|
||||
status = pFT_GetQueueStatus(ftdih, &nbRead);
|
||||
} while (nbRead < (unsigned long)(rounded_size >> 3) && (status == FT_OK ));
|
||||
|
||||
status = pFT_Read(ftdih, &ftdi_in_buf, nbRead, &nbRead);
|
||||
|
||||
for (i = 0; i < rounded_size; i++)
|
||||
{
|
||||
if (ftdi_in_buf[i >> 3] & (0x01 << (i & 7)))
|
||||
{
|
||||
str_in[rd_bit_index++] = JTAG_STR_DOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_in[rd_bit_index++] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send the remaining bits...
|
||||
while( wr_bit_index < size )
|
||||
{
|
||||
if( str_in )
|
||||
opcode = ( OP_WR_TDI | OP_LSB_FIRST | OP_BIT_MODE | OP_FEDGE_WR | OP_RD_TDO ); //bit mode with TDO read back
|
||||
else
|
||||
opcode = ( OP_WR_TDI | OP_LSB_FIRST | OP_BIT_MODE | OP_FEDGE_WR ); //bit mode
|
||||
|
||||
nbtosend = 0;
|
||||
|
||||
bitscnt = (size - wr_bit_index);
|
||||
if( bitscnt > 8 )
|
||||
{
|
||||
bitscnt = 8;
|
||||
}
|
||||
|
||||
ftdi_out_buf[nbtosend++] = opcode;
|
||||
ftdi_out_buf[nbtosend++] = (bitscnt - 1) & 7; // Size field
|
||||
ftdi_out_buf[nbtosend] = 0x00;
|
||||
|
||||
i = 0;
|
||||
while( i < bitscnt )
|
||||
{
|
||||
if (str_out[wr_bit_index++] & JTAG_STR_DOUT)
|
||||
ftdi_out_buf[nbtosend] |= 0x01 << i; // Data field
|
||||
|
||||
i++;
|
||||
}
|
||||
nbtosend++;
|
||||
|
||||
status = pFT_Write(ftdih, ftdi_out_buf, nbtosend, &nbtosend);
|
||||
|
||||
if ( opcode & OP_RD_TDO )
|
||||
{
|
||||
do
|
||||
{
|
||||
Sleep(3);
|
||||
status = pFT_GetQueueStatus(ftdih, &nbRead);
|
||||
} while ( ( nbRead < 1 ) && ( status == FT_OK ) );
|
||||
|
||||
status = pFT_Read(ftdih, &ftdi_in_buf, nbRead, &nbRead);
|
||||
|
||||
// bits are shifted in from MSB to LSB ...
|
||||
i = 0;
|
||||
while( i < bitscnt )
|
||||
{
|
||||
if ( ftdi_in_buf[0] & (0x01 << ( (8 - bitscnt) + i ) ) )
|
||||
{
|
||||
str_in[rd_bit_index++] = JTAG_STR_DOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_in[rd_bit_index++] = 0x00;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_FTDI_TMS_xfer(jtag_core * jc, unsigned char * str_out, int size)
|
||||
{
|
||||
int i;
|
||||
int wr_bit_index;
|
||||
DWORD nbtosend;
|
||||
FT_STATUS status;
|
||||
unsigned char bitscnt;
|
||||
unsigned char opcode;
|
||||
|
||||
status = FT_OK;
|
||||
|
||||
memset(ftdi_out_buf, 0, sizeof(ftdi_out_buf));
|
||||
memset(ftdi_in_buf, 0, sizeof(ftdi_in_buf));
|
||||
|
||||
wr_bit_index = 0;
|
||||
while( wr_bit_index < size )
|
||||
{
|
||||
opcode = ( OP_WR_TMS | OP_LSB_FIRST | OP_BIT_MODE | OP_FEDGE_WR );
|
||||
|
||||
nbtosend = 0;
|
||||
|
||||
bitscnt = (size - wr_bit_index);
|
||||
if( bitscnt > 7 )
|
||||
{
|
||||
bitscnt = 7;
|
||||
}
|
||||
|
||||
ftdi_out_buf[nbtosend++] = opcode;
|
||||
ftdi_out_buf[nbtosend++] = (bitscnt - 1); // Size field
|
||||
ftdi_out_buf[nbtosend] = 0x00;
|
||||
|
||||
i = 0;
|
||||
while( i < bitscnt )
|
||||
{
|
||||
if (str_out[wr_bit_index++] & JTAG_STR_TMS)
|
||||
ftdi_out_buf[nbtosend] |= 0x01 << i; // Data field
|
||||
|
||||
i++;
|
||||
}
|
||||
nbtosend++;
|
||||
|
||||
status = pFT_Write(ftdih, ftdi_out_buf, nbtosend, &nbtosend);
|
||||
}
|
||||
|
||||
if (status != FT_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int drv_FTDI_libGetDrv(jtag_core * jc,int sub_drv,unsigned int infotype,void * returnvalue)
|
||||
{
|
||||
|
||||
drv_ptr drv_funcs =
|
||||
{
|
||||
(DRV_DETECT) drv_FTDI_Detect,
|
||||
(DRV_INIT) drv_FTDI_Init,
|
||||
(DRV_DEINIT) drv_FTDI_DeInit,
|
||||
(DRV_TXTMS) drv_FTDI_TMS_xfer,
|
||||
(DRV_TXRXDATA) drv_FTDI_TDOTDI_xfer,
|
||||
(DRV_GETMODULEINFOS) drv_FTDI_libGetDrv
|
||||
};
|
||||
|
||||
return GetDrvInfo(
|
||||
jc,
|
||||
infotype,
|
||||
returnvalue,
|
||||
subdrv_list[sub_drv].drv_id,
|
||||
subdrv_list[sub_drv].drv_desc,
|
||||
&drv_funcs
|
||||
);
|
||||
}
|
||||
26
modules/drivers/ftdi_jtag/ftdi_jtag_drv.h
Normal file
26
modules/drivers/ftdi_jtag/ftdi_jtag_drv.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ftdi_jtag_drv.h
|
||||
* @brief FTDI based probes driver entry point definition
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
int drv_FTDI_libGetDrv(jtag_core * jc,int sub_drv, unsigned int infotype,void * returnvalue);
|
||||
389
modules/drivers/jlink_jtag/jlink_jtag_drv.c
Normal file
389
modules/drivers/jlink_jtag/jlink_jtag_drv.c
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file jlink_jtag_drv.c
|
||||
* @brief JLINK based probes driver
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../drv_loader.h"
|
||||
#include "jtag_core/jtag_core_internal.h"
|
||||
#include "jtag_core/jtag_core.h"
|
||||
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
|
||||
#include "jtag_core/dbg_logs.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
// Compiling on Windows
|
||||
#include <windows.h>
|
||||
#elif defined(__linux__)
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#error "Unsupported OS (only available on Windows or Linux)"
|
||||
#endif
|
||||
|
||||
typedef struct _drv_desc
|
||||
{
|
||||
char *drv_id;
|
||||
char *drv_desc;
|
||||
int id;
|
||||
}drv_desc;
|
||||
|
||||
#define PROBE_JLINK_ARM 0
|
||||
|
||||
const static drv_desc subdrv_list[]=
|
||||
{
|
||||
{"JLINK_ARM","USB JLINK ARM",PROBE_JLINK_ARM}
|
||||
};
|
||||
|
||||
unsigned char jlink_out_tms_buf[64 * 1024];
|
||||
unsigned char jlink_out_tdi_buf[64 * 1024];
|
||||
unsigned char jlink_in_buf[64 * 1024];
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define MODULE_NAME "JLink_x64.dll"
|
||||
#else
|
||||
#define MODULE_NAME "JLinkARM.dll"
|
||||
#endif
|
||||
|
||||
typedef const char* (WINAPIV * JL_OPENEX)(const char* pfLog, void*);
|
||||
typedef int (WINAPIV * JL_JTAG_STORERAW)(const unsigned char* pTDI, const unsigned char* pTMS, unsigned int NumBits);
|
||||
typedef int (WINAPIV * JL_JTAG_STOREGETRAW)(const unsigned char* pTDI, unsigned char* pTDO, const unsigned char* pTMS, unsigned int NumBits);
|
||||
typedef void (WINAPIV * JL_JTAG_SYNCBITS)(void);
|
||||
typedef void (WINAPIV * JL_SETSPEED)(unsigned int Speed);
|
||||
typedef void (WINAPIV * JL_SETRESETDELAY)(int ms);
|
||||
typedef void (WINAPIV * JL_RESETPULLSRESET)(unsigned char OnOff);
|
||||
typedef void (WINAPIV * JL_RESET)(void);
|
||||
typedef int (WINAPIV * JL_HASERROR)(void);
|
||||
typedef void (WINAPIV * JL_CLOSE)(void);
|
||||
|
||||
#else
|
||||
|
||||
#define MODULE_NAME "./libjlinkarm.so"
|
||||
|
||||
#if defined(__i386__)
|
||||
#define __cdecl __attribut__((cdecl))
|
||||
#else // __x86_64__ and others...
|
||||
#define __cdecl
|
||||
#endif
|
||||
|
||||
typedef void* HMODULE;
|
||||
|
||||
typedef const char* (__cdecl * JL_OPENEX)(const char* pfLog, void*);
|
||||
typedef int (__cdecl * JL_JTAG_STORERAW)(const unsigned char* pTDI, const unsigned char* pTMS, unsigned int NumBits);
|
||||
typedef int (__cdecl * JL_JTAG_STOREGETRAW)(const unsigned char* pTDI, unsigned char* pTDO, const unsigned char* pTMS, unsigned int NumBits);
|
||||
typedef void (__cdecl * JL_JTAG_SYNCBITS)(void);
|
||||
typedef void (__cdecl * JL_SETSPEED)(unsigned int Speed);
|
||||
typedef void (__cdecl * JL_SETRESETDELAY)(int ms);
|
||||
typedef void (__cdecl * JL_RESETPULLSRESET)(unsigned char OnOff);
|
||||
typedef void (__cdecl * JL_RESET)(void);
|
||||
typedef int (__cdecl * JL_HASERROR)(void);
|
||||
typedef void (__cdecl * JL_CLOSE)(void);
|
||||
|
||||
void* GetProcAddress(HMODULE handle, const char* name)
|
||||
{
|
||||
if(!handle || !name)
|
||||
return NULL;
|
||||
|
||||
dlerror();
|
||||
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
|
||||
bool FreeLibrary(HMODULE handle)
|
||||
{
|
||||
dlerror();
|
||||
if(0 != dlclose(handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HMODULE LoadLibrary(const char* path)
|
||||
{
|
||||
dlerror();
|
||||
return dlopen(path, RTLD_NOW);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static HMODULE lib_handle = 0;
|
||||
|
||||
JL_OPENEX pJLINKARM_OpenEx;
|
||||
JL_JTAG_STORERAW pJLINKARM_JTAG_StoreRaw;
|
||||
JL_JTAG_STOREGETRAW pJLINKARM_JTAG_StoreGetRaw;
|
||||
JL_JTAG_SYNCBITS pJLINKARM_JTAG_SyncBits;
|
||||
JL_SETSPEED pJLINKARM_SetSpeed;
|
||||
JL_SETRESETDELAY pJLINKARM_SetResetDelay;
|
||||
JL_RESETPULLSRESET pJLINKARM_ResetPullsRESET;
|
||||
JL_RESET pJLINKARM_Reset;
|
||||
JL_HASERROR pJLINKARM_HasError;
|
||||
JL_CLOSE pJLINKARM_Close;
|
||||
|
||||
int drv_JLINK_Detect(jtag_core * jc)
|
||||
{
|
||||
if(lib_handle == NULL) {
|
||||
lib_handle = LoadLibrary(MODULE_NAME);
|
||||
}
|
||||
|
||||
if (lib_handle)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_INFO_1,"drv_JLINK_Detect : %s JLink library found !\r\n",MODULE_NAME);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_INFO_1,"drv_JLINK_Detect : %s JLink library not found !\r\n",MODULE_NAME);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void * drv_JLINK_GetDrvFunc(jtag_core * jc, HMODULE libh, char * function_name)
|
||||
{
|
||||
void * function_ptr;
|
||||
|
||||
function_ptr = (void *)GetProcAddress(libh, function_name);
|
||||
if (!function_ptr)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_JLINK_GetDrvFunc : Can't get %s function !\r\n",function_name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return function_ptr;
|
||||
}
|
||||
|
||||
int drv_JLINK_Init(jtag_core * jc, int sub_drv, char * params)
|
||||
{
|
||||
const char* sError;
|
||||
|
||||
if(lib_handle == NULL) {
|
||||
lib_handle = LoadLibrary(MODULE_NAME);
|
||||
}
|
||||
|
||||
if (lib_handle)
|
||||
{
|
||||
pJLINKARM_OpenEx = (JL_OPENEX)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_OpenEx");
|
||||
if (!pJLINKARM_OpenEx)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_JTAG_StoreRaw = (JL_JTAG_STORERAW)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_JTAG_StoreRaw");
|
||||
if (!pJLINKARM_JTAG_StoreRaw)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_JTAG_StoreGetRaw = (JL_JTAG_STOREGETRAW)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_JTAG_StoreGetRaw");
|
||||
if (!pJLINKARM_JTAG_StoreGetRaw)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_JTAG_SyncBits = (JL_JTAG_SYNCBITS)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_JTAG_SyncBits");
|
||||
if (!pJLINKARM_JTAG_SyncBits)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_SetSpeed = (JL_SETSPEED)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_SetSpeed");
|
||||
if (!pJLINKARM_SetSpeed)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_SetResetDelay = (JL_SETRESETDELAY)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_SetResetDelay");
|
||||
if (!pJLINKARM_SetResetDelay)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_ResetPullsRESET = (JL_RESETPULLSRESET)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_ResetPullsRESET");
|
||||
if (!pJLINKARM_ResetPullsRESET)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_Reset = (JL_RESET)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_Reset");
|
||||
if (!pJLINKARM_Reset)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_HasError = (JL_HASERROR)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_HasError");
|
||||
if (!pJLINKARM_HasError)
|
||||
goto loadliberror;
|
||||
|
||||
pJLINKARM_Close = (JL_CLOSE)drv_JLINK_GetDrvFunc(jc, lib_handle, "JLINKARM_Close");
|
||||
if (!pJLINKARM_Close)
|
||||
goto loadliberror;
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_JLINK_Init : Can't load JLinkARM.dll !\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sError = pJLINKARM_OpenEx(NULL, 0);
|
||||
if (sError) {
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"pJLINKARM_OpenEx : Error 0x%x !\r\n",sError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pJLINKARM_SetSpeed(1000); // 1 Mhz
|
||||
|
||||
jtagcore_logs_printf(jc,MSG_INFO_0,"drv_JLINK_Init : Probe Driver loaded successfully...\r\n");
|
||||
|
||||
return 0;
|
||||
|
||||
loadliberror:
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_JLINK_Init : Something wrong happened ! JLink probe support not enabled.\r\n");
|
||||
|
||||
FreeLibrary(lib_handle);
|
||||
|
||||
lib_handle = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int drv_JLINK_DeInit(jtag_core * jc)
|
||||
{
|
||||
pJLINKARM_Close();
|
||||
FreeLibrary(lib_handle);
|
||||
lib_handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_JLINK_TDOTDI_xfer(jtag_core * jc, unsigned char * str_out, unsigned char * str_in, int size)
|
||||
{
|
||||
int i;
|
||||
int bitoffset;
|
||||
|
||||
memset(jlink_out_tms_buf, 0, sizeof(jlink_out_tms_buf));
|
||||
memset(jlink_out_tdi_buf, 0, sizeof(jlink_out_tdi_buf));
|
||||
|
||||
if (!str_in)
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
i = 0;
|
||||
bitoffset = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
jlink_out_tms_buf[bitoffset >> 3] |= (0x01 << (bitoffset & 7));
|
||||
|
||||
if (str_out[i] & JTAG_STR_DOUT)
|
||||
jlink_out_tdi_buf[bitoffset >> 3] |= (0x01 << (bitoffset & 7));
|
||||
|
||||
bitoffset++;
|
||||
i++;
|
||||
}
|
||||
|
||||
pJLINKARM_JTAG_StoreRaw(jlink_out_tdi_buf, jlink_out_tms_buf, bitoffset);
|
||||
pJLINKARM_JTAG_SyncBits();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
memset(jlink_in_buf, 0, sizeof(jlink_in_buf));
|
||||
|
||||
i = 0;
|
||||
bitoffset = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
jlink_out_tms_buf[bitoffset >> 3] |= (0x01 << (bitoffset & 7));
|
||||
|
||||
if (str_out[i] & JTAG_STR_DOUT)
|
||||
jlink_out_tdi_buf[bitoffset >> 3] |= (0x01 << (bitoffset & 7));
|
||||
|
||||
bitoffset++;
|
||||
i++;
|
||||
}
|
||||
|
||||
pJLINKARM_JTAG_StoreGetRaw(jlink_out_tdi_buf, jlink_in_buf, jlink_out_tms_buf, bitoffset);
|
||||
pJLINKARM_JTAG_SyncBits();
|
||||
|
||||
i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (jlink_in_buf[i >> 3] & (0x01 << (i & 7)))
|
||||
{
|
||||
str_in[i] = JTAG_STR_DOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
str_in[i] = 0x00;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_JLINK_TMS_xfer(jtag_core * jc, unsigned char * str_out, int size)
|
||||
{
|
||||
int bitoffset,i;
|
||||
|
||||
memset(jlink_out_tms_buf, 0, sizeof(jlink_out_tms_buf));
|
||||
memset(jlink_out_tdi_buf, 0, sizeof(jlink_out_tdi_buf));
|
||||
|
||||
if (size)
|
||||
{
|
||||
i = 0;
|
||||
bitoffset = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
jlink_out_tms_buf[bitoffset >> 3] |= (0x01 << (bitoffset & 7));
|
||||
|
||||
bitoffset++;
|
||||
i++;
|
||||
}
|
||||
|
||||
pJLINKARM_JTAG_StoreRaw(jlink_out_tdi_buf, jlink_out_tms_buf, bitoffset);
|
||||
pJLINKARM_JTAG_SyncBits();
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_JLINK_libGetDrv(jtag_core * jc,int sub_drv,unsigned int infotype,void * returnvalue)
|
||||
{
|
||||
drv_ptr drv_funcs =
|
||||
{
|
||||
(DRV_DETECT) drv_JLINK_Detect,
|
||||
(DRV_INIT) drv_JLINK_Init,
|
||||
(DRV_DEINIT) drv_JLINK_DeInit,
|
||||
(DRV_TXTMS) drv_JLINK_TMS_xfer,
|
||||
(DRV_TXRXDATA) drv_JLINK_TDOTDI_xfer,
|
||||
(DRV_GETMODULEINFOS) drv_JLINK_libGetDrv
|
||||
};
|
||||
|
||||
return GetDrvInfo(
|
||||
jc,
|
||||
infotype,
|
||||
returnvalue,
|
||||
subdrv_list[sub_drv].drv_id,
|
||||
subdrv_list[sub_drv].drv_desc,
|
||||
&drv_funcs
|
||||
);
|
||||
}
|
||||
|
||||
26
modules/drivers/jlink_jtag/jlink_jtag_drv.h
Normal file
26
modules/drivers/jlink_jtag/jlink_jtag_drv.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file jlink_jtag_drv.h
|
||||
* @brief JLINK based probes driver entry point definition
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
int drv_JLINK_libGetDrv(jtag_core * jc,int sub_drv, unsigned int infotype,void * returnvalue);
|
||||
452
modules/drivers/linux_gpio_jtag/linux_gpio_jtag_drv.c
Normal file
452
modules/drivers/linux_gpio_jtag/linux_gpio_jtag_drv.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file linux_gpio_jtag_drv.c
|
||||
* @brief jtag linux gpio probes driver
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../drv_loader.h"
|
||||
#include "jtag_core/jtag_core_internal.h"
|
||||
#include "jtag_core/jtag_core.h"
|
||||
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
|
||||
#include "os_interface/os_interface.h"
|
||||
|
||||
#include "jtag_core/dbg_logs.h"
|
||||
|
||||
char linux_gpio_base[512];
|
||||
|
||||
#define IGNORE_PORT 0
|
||||
#define READ_PORT 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* name;
|
||||
int gpio_num;
|
||||
int dir;
|
||||
int state;
|
||||
int old_state;
|
||||
int negate_polarity;
|
||||
int handle;
|
||||
}io_defs;
|
||||
|
||||
#define TMS_INDEX 0
|
||||
#define TDO_INDEX 1
|
||||
#define TDI_INDEX 2
|
||||
#define TCK_INDEX 3
|
||||
|
||||
io_defs gpio_var_names[]=
|
||||
{
|
||||
{(const char*)"PROBE_LINUXGPIO_TMS_PIN",-1,1,0,-1,0,-1},
|
||||
{(const char*)"PROBE_LINUXGPIO_TDO_PIN",-1,0,0,-1,0,-1},
|
||||
{(const char*)"PROBE_LINUXGPIO_TDI_PIN",-1,1,0,-1,0,-1},
|
||||
{(const char*)"PROBE_LINUXGPIO_TCK_PIN",-1,1,0,-1,0,-1},
|
||||
{(const char*)NULL,-1,-1,0,-1,-1}
|
||||
};
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
static int putp(int tdi, int tms, int rp)
|
||||
{
|
||||
int tdo = -1;
|
||||
int ret;
|
||||
char tmp_str[512];
|
||||
char rd_value;
|
||||
|
||||
tmp_str[0] = '0';
|
||||
tmp_str[1] = '\n';
|
||||
tmp_str[2] = 0;
|
||||
|
||||
rd_value = 0;
|
||||
|
||||
if (rp == READ_PORT)
|
||||
{
|
||||
|
||||
rd_value = 0;
|
||||
lseek(gpio_var_names[TDO_INDEX].handle, 0, SEEK_SET);
|
||||
ret = read(gpio_var_names[TDO_INDEX].handle,&rd_value,1);
|
||||
if(ret < 1)
|
||||
goto wr_error;
|
||||
|
||||
if(rd_value >= '0' && rd_value <='1')
|
||||
{
|
||||
gpio_var_names[TDO_INDEX].old_state = gpio_var_names[TDO_INDEX].state;
|
||||
tdo = (rd_value - '0') ^ (gpio_var_names[TDO_INDEX].negate_polarity&1);
|
||||
gpio_var_names[TDO_INDEX].state = tdo;
|
||||
}
|
||||
}
|
||||
|
||||
if( gpio_var_names[TMS_INDEX].old_state != (tms&1))
|
||||
{
|
||||
tmp_str[0] = '0' + ((tms&1) ^ (gpio_var_names[TMS_INDEX].negate_polarity&1));
|
||||
|
||||
ret = write(gpio_var_names[TMS_INDEX].handle,tmp_str,2);
|
||||
if(ret < 2)
|
||||
goto wr_error;
|
||||
|
||||
gpio_var_names[TMS_INDEX].old_state = (tms&1);
|
||||
}
|
||||
|
||||
if( gpio_var_names[TDI_INDEX].old_state != (tdi&1))
|
||||
{
|
||||
tmp_str[0] = '0' + ((tdi&1) ^ (gpio_var_names[TDI_INDEX].negate_polarity&1));
|
||||
ret = write(gpio_var_names[TDI_INDEX].handle,tmp_str,2);
|
||||
if(ret < 2)
|
||||
goto wr_error;
|
||||
|
||||
gpio_var_names[TDI_INDEX].old_state = (tdi&1);
|
||||
}
|
||||
|
||||
tmp_str[0] = '0' + (gpio_var_names[TCK_INDEX].negate_polarity&1);
|
||||
ret = write(gpio_var_names[TCK_INDEX].handle,tmp_str,2);
|
||||
if(ret < 2)
|
||||
goto wr_error;
|
||||
|
||||
gpio_var_names[TCK_INDEX].old_state = 0;
|
||||
|
||||
tmp_str[0] = '0' + (1 ^ (gpio_var_names[TCK_INDEX].negate_polarity&1));
|
||||
ret = write(gpio_var_names[TCK_INDEX].handle,tmp_str,2);
|
||||
if(ret < 2)
|
||||
goto wr_error;
|
||||
|
||||
gpio_var_names[TCK_INDEX].old_state = 1;
|
||||
|
||||
tmp_str[0] = '0' + (gpio_var_names[TCK_INDEX].negate_polarity&1);
|
||||
ret = write(gpio_var_names[TCK_INDEX].handle,tmp_str,2);
|
||||
if(ret < 2)
|
||||
goto wr_error;
|
||||
|
||||
gpio_var_names[TCK_INDEX].old_state = 0;
|
||||
|
||||
return tdo;
|
||||
|
||||
wr_error:
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int drv_LinuxGPIO_Detect(jtag_core * jc)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
char tmp_str[1024];
|
||||
FILE * f;
|
||||
|
||||
if( jtagcore_getEnvVarValue( jc, "PROBE_GPIO_LINUX_ENABLE") > 0)
|
||||
{
|
||||
jtagcore_getEnvVar( jc, "PROBE_GPIO_LINUX_BASE_FOLDER", (char*)&linux_gpio_base);
|
||||
|
||||
strncpy(tmp_str, linux_gpio_base, sizeof(tmp_str) - 1);
|
||||
genos_strndstcat(tmp_str,"/export",sizeof(tmp_str));
|
||||
tmp_str[sizeof(tmp_str) - 1] = '\0';
|
||||
|
||||
f = fopen(tmp_str,"rb");
|
||||
if(f)
|
||||
{
|
||||
fclose(f);
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LinuxGPIO_Detect : JTAG GPIO interface enabled\r\n",tmp_str);
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LinuxGPIO_Detect : Can't open %s !\r\n",tmp_str);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
static int exportGPIO(char * path_base,int pin)
|
||||
{
|
||||
char tmp_str[512];
|
||||
FILE * f;
|
||||
|
||||
strcpy(tmp_str,path_base);
|
||||
strcat(tmp_str,"/export");
|
||||
|
||||
f = fopen(tmp_str,"w");
|
||||
if(!f)
|
||||
{
|
||||
return JTAG_CORE_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
fprintf(f,"%d\n", pin);
|
||||
fclose(f);
|
||||
|
||||
return JTAG_CORE_NO_ERROR;
|
||||
}
|
||||
|
||||
static int setdirGPIO(char * path_base,int pin,int dir)
|
||||
{
|
||||
char tmp_str[1024];
|
||||
char tmp_str2[64];
|
||||
FILE * f;
|
||||
|
||||
strncpy(tmp_str,path_base,sizeof(tmp_str)-1);
|
||||
snprintf(tmp_str2,sizeof(tmp_str2)-1,"/gpio%d/direction",pin);
|
||||
genos_strndstcat(tmp_str,tmp_str2,sizeof(tmp_str));
|
||||
tmp_str[sizeof(tmp_str) - 1] = '\0';
|
||||
|
||||
f = fopen(tmp_str,"w");
|
||||
if(!f)
|
||||
{
|
||||
return JTAG_CORE_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
if(dir)
|
||||
fprintf(f,"out\n");
|
||||
else
|
||||
fprintf(f,"in\n");
|
||||
|
||||
fclose(f);
|
||||
|
||||
return JTAG_CORE_NO_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int drv_LinuxGPIO_Init(jtag_core * jc, int sub_drv,char * params)
|
||||
{
|
||||
int probe_detected;
|
||||
|
||||
probe_detected = 0;
|
||||
|
||||
if( jtagcore_getEnvVarValue( jc, "PROBE_LINUXGPIO_ENABLE") <= 0)
|
||||
{
|
||||
return JTAG_CORE_NO_PROBE;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
int i;
|
||||
char tmp_str[1024];
|
||||
|
||||
jtagcore_getEnvVar( jc, "PROBE_LINUXGPIO_BASE_FOLDER", (char*)&linux_gpio_base);
|
||||
|
||||
i = 0;
|
||||
while(gpio_var_names[i].name)
|
||||
{
|
||||
gpio_var_names[i].gpio_num = jtagcore_getEnvVarValue( jc, (char*)gpio_var_names[i].name);
|
||||
|
||||
strncpy(tmp_str,(char*)gpio_var_names[i].name,sizeof(tmp_str) - 1);
|
||||
tmp_str[sizeof(tmp_str) - 1] = '\0';
|
||||
|
||||
genos_strndstcat(tmp_str,"_INVERT_POLARITY",sizeof(tmp_str));
|
||||
tmp_str[sizeof(tmp_str) - 1] = '\0';
|
||||
|
||||
gpio_var_names[i].negate_polarity = jtagcore_getEnvVarValue( jc, (char*)tmp_str);
|
||||
|
||||
if( exportGPIO(linux_gpio_base, gpio_var_names[i].gpio_num) != JTAG_CORE_NO_ERROR )
|
||||
break;
|
||||
|
||||
if( setdirGPIO(linux_gpio_base, gpio_var_names[i].gpio_num, gpio_var_names[i].dir) != JTAG_CORE_NO_ERROR )
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(!gpio_var_names[i].name)
|
||||
{
|
||||
probe_detected = 1;
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
snprintf(tmp_str,sizeof(tmp_str),"%s/gpio%d/value",linux_gpio_base,gpio_var_names[i].gpio_num);
|
||||
|
||||
if(gpio_var_names[i].handle != -1)
|
||||
close(gpio_var_names[i].handle);
|
||||
|
||||
if(gpio_var_names[i].dir)
|
||||
gpio_var_names[i].handle = open(tmp_str, O_WRONLY);
|
||||
else
|
||||
gpio_var_names[i].handle = open(tmp_str, O_RDONLY);
|
||||
|
||||
if(gpio_var_names[i].handle < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == 4 )
|
||||
{
|
||||
// init gpio
|
||||
putp(0, 0, IGNORE_PORT);
|
||||
putp(0, 0, IGNORE_PORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
probe_detected = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(probe_detected)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_INFO_0,"drv_LinuxGPIO_Init : Probe Driver loaded successfully...\r\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LinuxGPIO_Init : No probe found !\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int drv_LinuxGPIO_DeInit(jtag_core * jc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_LinuxGPIO_TDOTDI_xfer(jtag_core * jc, unsigned char * str_out, unsigned char * str_in, int size)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
if (!str_in)
|
||||
{
|
||||
while (i < size)
|
||||
{
|
||||
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
{
|
||||
gpio_var_names[TMS_INDEX].state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_var_names[TMS_INDEX].state = 0;
|
||||
}
|
||||
|
||||
if (str_out[i] & JTAG_STR_DOUT)
|
||||
{
|
||||
gpio_var_names[TDI_INDEX].state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_var_names[TDI_INDEX].state = 0;
|
||||
}
|
||||
|
||||
putp(gpio_var_names[TDI_INDEX].state, gpio_var_names[TMS_INDEX].state, IGNORE_PORT);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i < size)
|
||||
{
|
||||
if (str_out[i] & JTAG_STR_DOUT)
|
||||
{
|
||||
gpio_var_names[TDI_INDEX].state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_var_names[TDI_INDEX].state = 0;
|
||||
}
|
||||
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
{
|
||||
gpio_var_names[TMS_INDEX].state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_var_names[TMS_INDEX].state = 0;
|
||||
}
|
||||
|
||||
str_in[i] = putp(gpio_var_names[TDI_INDEX].state, gpio_var_names[TMS_INDEX].state, READ_PORT);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int drv_LinuxGPIO_TMS_xfer(jtag_core * jc, unsigned char * str_out, int size)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
int i;
|
||||
|
||||
gpio_var_names[TDI_INDEX].state = 0;
|
||||
|
||||
i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
{
|
||||
gpio_var_names[TMS_INDEX].state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_var_names[TMS_INDEX].state = 0;
|
||||
}
|
||||
|
||||
putp(gpio_var_names[TDI_INDEX].state, gpio_var_names[TMS_INDEX].state, IGNORE_PORT);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int drv_LinuxGPIO_libGetDrv(jtag_core * jc, int sub_drv, unsigned int infotype,void * returnvalue)
|
||||
{
|
||||
|
||||
drv_ptr drv_funcs =
|
||||
{
|
||||
(DRV_DETECT) drv_LinuxGPIO_Detect,
|
||||
(DRV_INIT) drv_LinuxGPIO_Init,
|
||||
(DRV_DEINIT) drv_LinuxGPIO_DeInit,
|
||||
(DRV_TXTMS) drv_LinuxGPIO_TMS_xfer,
|
||||
(DRV_TXRXDATA) drv_LinuxGPIO_TDOTDI_xfer,
|
||||
(DRV_GETMODULEINFOS) drv_LinuxGPIO_libGetDrv
|
||||
};
|
||||
|
||||
return GetDrvInfo(
|
||||
jc,
|
||||
infotype,
|
||||
returnvalue,
|
||||
"LINUX_GPIO",
|
||||
"GENERIC LINUX GPIO JTAG",
|
||||
&drv_funcs
|
||||
);
|
||||
}
|
||||
26
modules/drivers/linux_gpio_jtag/linux_gpio_jtag_drv.h
Normal file
26
modules/drivers/linux_gpio_jtag/linux_gpio_jtag_drv.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file linux_gpio_jtag_drv.h
|
||||
* @brief jtag linux gpio probes driver
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
int drv_LinuxGPIO_libGetDrv(jtag_core * jc,int sub_drv,unsigned int infotype,void * returnvalue);
|
||||
426
modules/drivers/lpt_jtag/lpt_jtag_drv.c
Normal file
426
modules/drivers/lpt_jtag/lpt_jtag_drv.c
Normal file
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lpt_jtag_drv.c
|
||||
* @brief parallel port probes driver
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
#ifndef _WIN64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <conio.h>
|
||||
#endif
|
||||
|
||||
#include "../drv_loader.h"
|
||||
#include "jtag_core/jtag_core_internal.h"
|
||||
#include "jtag_core/jtag_core.h"
|
||||
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
|
||||
#include "jtag_core/dbg_logs.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HANDLE h;
|
||||
|
||||
#endif
|
||||
|
||||
#define LPT1 0x3bc
|
||||
#define LPT2 0x378
|
||||
#define LPT3 0x278
|
||||
|
||||
#define IGNORE_PORT 0
|
||||
#define READ_PORT 1
|
||||
|
||||
unsigned short lpt_address;
|
||||
|
||||
|
||||
int sub_probe_id;
|
||||
|
||||
typedef struct _drv_desc
|
||||
{
|
||||
char *drv_id;
|
||||
char *drv_desc;
|
||||
int id;
|
||||
}drv_desc;
|
||||
|
||||
#define PROBE_INSIGHT_IJC 0
|
||||
#define PROBE_ALTERA_BYTEBLASTER 1
|
||||
#define PROBE_MACRAIGOR_WIGGLER 2
|
||||
|
||||
const static drv_desc subdrv_list[]=
|
||||
{
|
||||
{"LPT_INSIGHT_JTAG","LPT Memec IJC-4",PROBE_INSIGHT_IJC},
|
||||
{"LPT_ALTERA_BYTEBLASTER_JTAG","LPT Altera ByteBlaster",PROBE_ALTERA_BYTEBLASTER},
|
||||
{"LPT_MACRAIGOR_WIGGLERJTAG","LPT Macgraigor Wiggler",PROBE_MACRAIGOR_WIGGLER}
|
||||
};
|
||||
|
||||
void out_io_port( unsigned short port, unsigned char data )
|
||||
{
|
||||
#if defined(WIN32)
|
||||
_outp( port, data );
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned char in_io_port( unsigned short port )
|
||||
{
|
||||
#if defined(WIN32)
|
||||
return _inp( port );
|
||||
#else
|
||||
return 0x00;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int test_port(void)
|
||||
{
|
||||
// search for valid parallel port
|
||||
out_io_port(LPT1, 0x55);
|
||||
if ((int)in_io_port(LPT1) == 0x55)
|
||||
{
|
||||
return LPT1;
|
||||
}
|
||||
|
||||
out_io_port(LPT2, 0x55);
|
||||
if ((int)in_io_port(LPT2) == 0x55)
|
||||
{
|
||||
return LPT2;
|
||||
}
|
||||
|
||||
out_io_port(LPT3, 0x55);
|
||||
if ((int)in_io_port(LPT3) == 0x55)
|
||||
{
|
||||
return LPT3;
|
||||
}
|
||||
|
||||
return(0); // return zero if none found
|
||||
}
|
||||
|
||||
int putp(int tdi, int tms, int rp)
|
||||
{
|
||||
int tdo = -1;
|
||||
int lpt_data;
|
||||
|
||||
switch (sub_probe_id)
|
||||
{
|
||||
case PROBE_INSIGHT_IJC:
|
||||
// Insight/Xilinx :
|
||||
// D4 : TDO DRV LOW (AL)
|
||||
// D3 : OE (AL)
|
||||
// D1 : TCK (AH)
|
||||
// D2 : TMS (AH)
|
||||
// D0 : TDI (AH) (To device)
|
||||
// OnLine :TDO (AH) (From device)
|
||||
|
||||
lpt_data = 0x10; //Output to TDO off / Outputs enabled
|
||||
if (tms == 1) lpt_data |= 0x04;
|
||||
if (tdi == 1) lpt_data |= 0x01;
|
||||
|
||||
out_io_port(lpt_address, (unsigned char)lpt_data); // TCK low
|
||||
|
||||
lpt_data |= 0x02;
|
||||
out_io_port(lpt_address, (unsigned char)lpt_data); // TCK high
|
||||
|
||||
if (rp == READ_PORT)
|
||||
{
|
||||
tdo = ((int)in_io_port((unsigned short)(lpt_address + 1)) & 0x10) >> 4; // get TDO data
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PROBE_ALTERA_BYTEBLASTER:
|
||||
// Byteblaster :
|
||||
// AutoF : OE (AH)
|
||||
// D0 : TCK (AH)
|
||||
// D1 : TMS (AH)
|
||||
// D6 : TDI (AH) (To device)
|
||||
// BUSY : TDO (AL) (From device)
|
||||
// D4 : Loopback test out (AH)
|
||||
// Ack : Loopback test in (AH)
|
||||
|
||||
lpt_data = 0x00;
|
||||
|
||||
if (tms == 1) lpt_data |= 0x02;
|
||||
if (tdi == 1) lpt_data |= 0x40;
|
||||
|
||||
out_io_port(lpt_address, (unsigned char)lpt_data); // TCK low
|
||||
|
||||
lpt_data |= 0x01;
|
||||
out_io_port(lpt_address, (unsigned char)lpt_data); // TCK high
|
||||
|
||||
if (rp == READ_PORT)
|
||||
{
|
||||
tdo = (((int)in_io_port((unsigned short)(lpt_address + 1)) & 0x80) >> 7) ^ 1; // get TDO data
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PROBE_MACRAIGOR_WIGGLER:
|
||||
// Macraigor Wiggler :
|
||||
// AutoF : OE (AH)
|
||||
// D0 : RST (AH)
|
||||
// D1 : TMS (AH)
|
||||
// D2 : TCK (AH)
|
||||
// D3 : TDI (AH) (To device)
|
||||
// D4 : TRST (AH)
|
||||
// D7 : "PC VCC"
|
||||
// BUSY : TDO (AL) (From device)
|
||||
// D6 : Loopback test out (AH)
|
||||
// Error : Loopback test in (AH)
|
||||
|
||||
lpt_data = 0x10 | 0x80; //Set PC VCC & TRST to 1
|
||||
|
||||
if (tms == 1) lpt_data |= 0x02;
|
||||
if (tdi == 1) lpt_data |= 0x08;
|
||||
|
||||
out_io_port(lpt_address, (unsigned char)lpt_data); // TCK low
|
||||
|
||||
lpt_data |= 0x04;
|
||||
out_io_port(lpt_address, (unsigned char)lpt_data); // TCK high
|
||||
|
||||
if (rp == READ_PORT)
|
||||
{
|
||||
tdo = (((int)in_io_port((unsigned short)(lpt_address + 1)) & 0x80) >> 7) ^ 1; // get TDO data
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return tdo;
|
||||
}
|
||||
|
||||
int drv_LPT_Detect(jtag_core * jc)
|
||||
{
|
||||
|
||||
#if defined(WIN32)
|
||||
h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LPT_Init : Can't load giveio !\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LPT_Detect : giveio enabled !\r\n");
|
||||
#endif
|
||||
|
||||
lpt_address = test_port(); // find a valid parallel port address
|
||||
if (!lpt_address)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LPT_Init : No LPT port found !\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
int drv_LPT_Init(jtag_core * jc, int sub_drv,char * params)
|
||||
{
|
||||
int probe_detected;
|
||||
|
||||
#if defined(WIN32)
|
||||
h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LPT_Init : Can't load giveio !\r\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
lpt_address = test_port(); // find a valid parallel port address
|
||||
if (!lpt_address)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LPT_Init : No LPT port found !\r\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
sub_probe_id = subdrv_list[sub_drv].id;
|
||||
|
||||
switch(sub_probe_id)
|
||||
{
|
||||
case PROBE_ALTERA_BYTEBLASTER:
|
||||
probe_detected = 1;
|
||||
|
||||
/*
|
||||
// Loop back test
|
||||
out_io_port(lpt_address, 0x00);
|
||||
if( in_io_port(lpt_address + 1) & 0x40)
|
||||
{
|
||||
probe_detected = 0;
|
||||
}
|
||||
|
||||
out_io_port(lpt_address, 0x10);
|
||||
if( !(in_io_port(lpt_address + 1) & 0x40))
|
||||
{
|
||||
probe_detected = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// Enable outputs.
|
||||
if(probe_detected)
|
||||
out_io_port((unsigned short)(lpt_address + 0x02), 0x02);
|
||||
break;
|
||||
|
||||
default:
|
||||
probe_detected = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(probe_detected)
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_INFO_0,"drv_LPT_Init : Probe Driver loaded successfully...\r\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
jtagcore_logs_printf(jc,MSG_ERROR,"drv_LPT_Init : No probe found !\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int drv_LPT_DeInit(jtag_core * jc)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
CloseHandle(h);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_LPT_TDOTDI_xfer(jtag_core * jc, unsigned char * str_out, unsigned char * str_in, int size)
|
||||
{
|
||||
int i;
|
||||
int tms, tdi;
|
||||
|
||||
|
||||
if (size)
|
||||
{
|
||||
if (str_out[0] & JTAG_STR_TMS)
|
||||
{
|
||||
tms = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tms = 0;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (!str_in)
|
||||
{
|
||||
while (i < size)
|
||||
{
|
||||
|
||||
if (str_out[i] & JTAG_STR_DOUT)
|
||||
{
|
||||
tdi = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdi = 0;
|
||||
}
|
||||
|
||||
putp(tdi, tms, IGNORE_PORT);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i < size)
|
||||
{
|
||||
|
||||
if (str_out[i] & JTAG_STR_DOUT)
|
||||
{
|
||||
tdi = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdi = 0;
|
||||
}
|
||||
|
||||
str_in[i] = putp(tdi, tms, READ_PORT);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_LPT_TMS_xfer(jtag_core * jc, unsigned char * str_out, int size)
|
||||
{
|
||||
int i;
|
||||
int tms, tdi;
|
||||
|
||||
tdi = 0;
|
||||
i = 0;
|
||||
|
||||
while (i < size)
|
||||
{
|
||||
if (str_out[i] & JTAG_STR_TMS)
|
||||
{
|
||||
tms = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tms = 0;
|
||||
}
|
||||
|
||||
putp(tdi, tms, IGNORE_PORT);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_LPT_libGetDrv(jtag_core * jc, int sub_drv, unsigned int infotype,void * returnvalue)
|
||||
{
|
||||
|
||||
drv_ptr drv_funcs =
|
||||
{
|
||||
(DRV_DETECT) drv_LPT_Detect,
|
||||
(DRV_INIT) drv_LPT_Init,
|
||||
(DRV_DEINIT) drv_LPT_DeInit,
|
||||
(DRV_TXTMS) drv_LPT_TMS_xfer,
|
||||
(DRV_TXRXDATA) drv_LPT_TDOTDI_xfer,
|
||||
(DRV_GETMODULEINFOS) drv_LPT_libGetDrv
|
||||
};
|
||||
|
||||
return GetDrvInfo(
|
||||
jc,
|
||||
infotype,
|
||||
returnvalue,
|
||||
subdrv_list[sub_drv].drv_id,
|
||||
subdrv_list[sub_drv].drv_desc,
|
||||
&drv_funcs
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
26
modules/drivers/lpt_jtag/lpt_jtag_drv.h
Normal file
26
modules/drivers/lpt_jtag/lpt_jtag_drv.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* JTAG Core library
|
||||
* Copyright (c) 2008 - 2024 Viveris Technologies
|
||||
*
|
||||
* JTAG Core 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; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* JTAG Core 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 JTAG Core library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lpt_jtag_drv.h
|
||||
* @brief parallel port probes driver entry point definition
|
||||
* @author Jean-François DEL NERO <Jean-Francois.DELNERO@viveris.fr>
|
||||
*/
|
||||
|
||||
int drv_LPT_libGetDrv(jtag_core * jc,int sub_drv,unsigned int infotype,void * returnvalue);
|
||||
Reference in New Issue
Block a user