Files
tinio/cylib/cyjtag.c
2017-10-21 16:30:05 +02:00

248 lines
9.4 KiB
C

/*
* JTAG routines of Cypress USB Serial
* Copyright (C) 2013 Cypress Semiconductor
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CyUSBCommon.h"
/*
* This API enables the Jtag module
*/
CY_RETURN_STATUS CyJtagEnable (
CY_HANDLE handle
)
{
UINT16 wValue, wIndex, wLength;
UINT16 bmRequestType, bmRequest;
int rStatus;
CY_DEVICE *device;
libusb_device_handle *devHandle;
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
if (handle == NULL){
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
return CY_ERROR_INVALID_HANDLE;
}
device = (CY_DEVICE *)handle;
devHandle = device->devHandle;
if (device->deviceType != CY_TYPE_JTAG) {
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
return CY_ERROR_REQUEST_FAILED;
}
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
bmRequest = CY_JTAG_ENABLE_CMD;
wValue = 0x00;
wIndex = 0;
wLength = 0;
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
wValue, wIndex, NULL, wLength, ioTimeout);
if (rStatus >= 0){
CY_DEBUG_PRINT_INFO ("CY: JTAG enable successfully \n");
return CY_SUCCESS;
}
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
CY_DEBUG_PRINT_ERROR ("CY:Time out error ..function is %s \n", __func__);
return CY_ERROR_IO_TIMEOUT;
}
else {
CY_DEBUG_PRINT_ERROR ("CY: Error in function %s ...libusb error is %d!\n", __func__, rStatus);
return CY_ERROR_REQUEST_FAILED;
}
}
/*
* This API disables the Jtag module
*/
CY_RETURN_STATUS CyJtagDisable (
CY_HANDLE handle
)
{
UINT16 wValue, wIndex, wLength;
UINT16 bmRequestType, bmRequest;
int rStatus;
CY_DEVICE *device;
libusb_device_handle *devHandle;
UINT32 ioTimeout = CY_USB_SERIAL_TIMEOUT;
if (handle == NULL){
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
return CY_ERROR_INVALID_HANDLE;
}
device = (CY_DEVICE *)handle;
devHandle = device->devHandle;
if (device->deviceType != CY_TYPE_JTAG) {
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
return CY_ERROR_REQUEST_FAILED;
}
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
bmRequest = CY_JTAG_DISABLE_CMD;
wValue = 0x00;
wIndex = 0;
wLength = 0;
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
wValue, wIndex, NULL, wLength, ioTimeout);
if (rStatus >= 0){
CY_DEBUG_PRINT_INFO ("CY: JTAG disable successfully \n");
return CY_SUCCESS;
}
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
CY_DEBUG_PRINT_ERROR ("CY:Time out error while enabling JTAG ..\n");
return CY_ERROR_IO_TIMEOUT;
}
else {
CY_DEBUG_PRINT_ERROR ("CY:Error while enabling JTAG ...libusb error is %d function is %s!\n", rStatus, __func__);
return CY_ERROR_REQUEST_FAILED;
}
}
/*
* This API is used to do jtag write
*/
CY_RETURN_STATUS CyJtagWrite (
CY_HANDLE handle,
CY_DATA_BUFFER *writeBuffer,
UINT32 ioTimeout
)
{
int rStatus = 0;
CY_DEVICE *device;
libusb_device_handle *devHandle;
UINT16 wValue, wIndex, wLength;
UINT16 bmRequestType, bmRequest;
if (handle == NULL){
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
return CY_ERROR_INVALID_HANDLE;
}
if ((writeBuffer == NULL) || (writeBuffer->buffer == NULL) || (writeBuffer->length == 0)){
CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter.. Function is %s \n", __func__);
return CY_ERROR_INVALID_PARAMETER;
}
device = (CY_DEVICE *)handle;
devHandle = device->devHandle;
if (device->deviceType != CY_TYPE_JTAG) {
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
return CY_ERROR_REQUEST_FAILED;
}
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
bmRequest = CY_JTAG_WRITE_CMD;
wValue = writeBuffer->length;
wIndex = 0;
wLength = 0;
writeBuffer->transferCount = 0;
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
wValue, wIndex, NULL, wLength, ioTimeout);
if (rStatus < 0){
CY_DEBUG_PRINT_ERROR ("CY: JTAG Vendor command failed %d...function is %s \n", rStatus, __func__);
return CY_ERROR_REQUEST_FAILED;
}
rStatus = libusb_bulk_transfer (devHandle, CY_JTAG_OUT_EP, writeBuffer->buffer, writeBuffer->length,
(int*)&(writeBuffer->transferCount), ioTimeout);
if ((rStatus == CY_SUCCESS)) {
CY_DEBUG_PRINT_ERROR ("CY: Number of bytes written is .... %d \n", writeBuffer->transferCount);
return CY_SUCCESS;
}
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
CY_DEBUG_PRINT_ERROR ("CY:TimeOut error ...Function is %s %d\n", __func__, writeBuffer->transferCount);
return CY_ERROR_IO_TIMEOUT;
}
else if (rStatus == LIBUSB_ERROR_PIPE){
CY_DEBUG_PRINT_ERROR ("CY:Pipe error Function is %s \n", __func__);
CyResetPipe (handle, CY_JTAG_OUT_EP);
return CY_ERROR_PIPE_HALTED;
}
else if (rStatus == LIBUSB_ERROR_OVERFLOW){
CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow..Function is %s \n", __func__);
return CY_ERROR_BUFFER_OVERFLOW;
}
else if (rStatus == LIBUSB_ERROR_NO_DEVICE) {
CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected ....Function is %s \n", __func__);
return CY_ERROR_DEVICE_NOT_FOUND;
}
else {
CY_DEBUG_PRINT_ERROR ("CY: Error in Function %s...Libusb Error is %d !\n", __func__, rStatus);
return CY_ERROR_REQUEST_FAILED;
}
}
/*
This API is used to read JTAG data from device interface
*/
CY_RETURN_STATUS CyJtagRead (
CY_HANDLE handle,
CY_DATA_BUFFER *readBuffer,
UINT32 ioTimeout
)
{
int rStatus;
CY_DEVICE *device;
libusb_device_handle *devHandle;
UINT16 wValue, wIndex, wLength;
UINT16 bmRequestType, bmRequest;
bmRequestType = CY_VENDOR_REQUEST_HOST_TO_DEVICE;
bmRequest = CY_JTAG_READ_CMD;
wValue = readBuffer->length;
wIndex = 0;
wLength = 0;
if (handle == NULL){
CY_DEBUG_PRINT_ERROR ("CY:Error invalid handle.. Function is %s \n", __func__);
return CY_ERROR_INVALID_HANDLE;
}
if ((readBuffer == NULL) || (readBuffer->buffer == NULL) || (readBuffer->length == 0)){
CY_DEBUG_PRINT_ERROR ("CY:Error invalid parameter.. Function is %s \n", __func__);
return CY_ERROR_INVALID_PARAMETER;
}
device = (CY_DEVICE *)handle;
devHandle = device->devHandle;
if (device->deviceType != CY_TYPE_JTAG) {
CY_DEBUG_PRINT_ERROR ("CY:Error device type is not jtag ... Function is %s \n", __func__);
return CY_ERROR_REQUEST_FAILED;
}
readBuffer->transferCount = 0;
rStatus = libusb_control_transfer (devHandle, bmRequestType, bmRequest,
wValue, wIndex, NULL, wLength, ioTimeout);
if (rStatus < 0){
CY_DEBUG_PRINT_INFO ("CY: JTAG Vendor Command failed %d.. Function is %s \n", rStatus, __func__);
return CY_ERROR_REQUEST_FAILED;
}
rStatus = libusb_bulk_transfer (devHandle, CY_JTAG_IN_EP, readBuffer->buffer, readBuffer->length,
(int*)&(readBuffer->transferCount), ioTimeout);
if (rStatus == CY_SUCCESS){
CY_DEBUG_PRINT_ERROR ("CY: Number of bytes read is .... %d \n", readBuffer->transferCount);
return CY_SUCCESS;
}
else if (rStatus == LIBUSB_ERROR_TIMEOUT){
CY_DEBUG_PRINT_ERROR ("CY:TimeOut error ...Function is %s \n", __func__);
return CY_ERROR_IO_TIMEOUT;
}
else if (rStatus == LIBUSB_ERROR_PIPE){
CY_DEBUG_PRINT_ERROR ("CY:Pipe error Function is %s \n", __func__);
CyResetPipe (handle, CY_JTAG_IN_EP);
return CY_ERROR_PIPE_HALTED;
}
else if (rStatus == LIBUSB_ERROR_OVERFLOW){
CY_DEBUG_PRINT_ERROR ("CY:Error Buffer Overflow..Function is %s \n", __func__);
return CY_ERROR_BUFFER_OVERFLOW;
}
else if (rStatus == LIBUSB_ERROR_NO_DEVICE) {
CY_DEBUG_PRINT_ERROR ("CY: Device Disconnected ....Function is %s \n", __func__);
return CY_ERROR_DEVICE_NOT_FOUND;
}
else {
CY_DEBUG_PRINT_ERROR ("CY: Error in function is %s ...Libusb Error is %d!\n", __func__, rStatus);
return CY_ERROR_REQUEST_FAILED;
}
}