dirs refactoring

This commit is contained in:
2025-02-16 12:38:13 +01:00
parent 054165ed84
commit a61fe778e6
60 changed files with 67 additions and 53 deletions

View 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})

View 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}
};

View 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[];

View 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;
};

View 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);

View 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
);
}

View 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);

View 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
);
}

View 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);

View 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
);
}

View 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);

View 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

View 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);