Permalink
Browse files

JTAG now works. Tidy needed.

  • Loading branch information...
1 parent 25a8d00 commit afa007cd70b3b47253d43a41c0e9164794798478 makestuff committed Mar 17, 2013
Showing with 174 additions and 79 deletions.
  1. +100 −24 jtag.c
  2. +4 −0 libfpgalink.h
  3. +62 −55 nero.c
  4. +8 −0 prog.h
View
@@ -118,19 +118,21 @@ static FLStatus populateMap(const char *portConfig, const char *ptr, const char
ptr++;
ch = *ptr++;
} while ( ch == ',' );
- *endPtr = ptr - 1;
+ if ( endPtr ) {
+ *endPtr = ptr - 1;
+ }
cleanup:
return returnCode;
}
-static FLStatus portMap(struct FLContext *handle, uint8 patchClass, uint8 port, uint8 bit, const char **error) {
+static FLStatus portMap(struct FLContext *handle, PatchOp patchOp, uint8 port, uint8 bit, const char **error) {
FLStatus returnCode = FL_SUCCESS;
union {
uint16 word;
uint8 bytes[2];
} index, value;
int uStatus;
- index.bytes[0] = patchClass;
+ index.bytes[0] = (uint8)patchOp;
index.bytes[1] = port;
value.bytes[0] = bit;
value.bytes[1] = 0x00;
@@ -292,13 +294,13 @@ static FLStatus xProgram(struct FLContext *handle, ProgOp progOp, const char *po
}
// Map the CCLK bit & the SelectMAP data bus
- fStatus = portMap(handle, 3, cclkPort, cclkBit, error);
+ fStatus = portMap(handle, PATCH_TCK, cclkPort, cclkBit, error);
CHECK_STATUS(fStatus, "xProgram()", fStatus);
if ( progOp == PROG_PARALLEL ) {
- fStatus = portMap(handle, 4, dataPort, 0x00, error);
+ fStatus = portMap(handle, PATCH_D8, dataPort, 0x00, error);
CHECK_STATUS(fStatus, "xProgram()", fStatus);
} else if ( progOp == PROG_SERIAL ) {
- fStatus = portMap(handle, 1, dataPort, dataBit[0], error);
+ fStatus = portMap(handle, PATCH_TDI, dataPort, dataBit[0], error);
CHECK_STATUS(fStatus, "xProgram()", fStatus);
}
@@ -419,24 +421,77 @@ static FLStatus xProgram(struct FLContext *handle, ProgOp progOp, const char *po
return returnCode;
}
-static FLStatus jtagGetPorts(const char *portConfig, const char *ptr, uint8 *maskList, uint8 *ddrList, uint8 *portList, const char **error) {
+static FLStatus jtagConfigPorts(struct FLContext *handle, const char *portConfig, const char *ptr, uint8 *maskList, uint8 *ddrList, uint8 *portList, const char **error) {
FLStatus returnCode = FL_SUCCESS;
+ FLStatus fStatus;
uint8 thisPort, thisBit;
PinState pinMap[5*8] = {0,};
char ch;
- GET_PAIR(thisPort, thisBit, "jtagGetPorts"); // TDO
- SET_BIT(thisPort, thisBit, LOW, "jtagGetPorts");
- GET_PAIR(thisPort, thisBit, "jtagGetPorts"); // TDI
- SET_BIT(thisPort, thisBit, INPUT, "jtagGetPorts");
- GET_PAIR(thisPort, thisBit, "jtagGetPorts"); // TMS
- SET_BIT(thisPort, thisBit, INPUT, "jtagGetPorts");
- GET_PAIR(thisPort, thisBit, "jtagGetPorts"); // TCK
- SET_BIT(thisPort, thisBit, LOW, "jtagGetPorts");
+
+ GET_PAIR(thisPort, thisBit, "jtagConfigPorts"); // TDO
+ SET_BIT(thisPort, thisBit, INPUT, "jtagConfigPorts");
+ fStatus = portMap(handle, PATCH_TDO, thisPort, thisBit, error);
+ CHECK_STATUS(fStatus, "jtagConfigPorts()", fStatus);
+
+ GET_PAIR(thisPort, thisBit, "jtagConfigPorts"); // TDI
+ SET_BIT(thisPort, thisBit, LOW, "jtagConfigPorts");
+ fStatus = portMap(handle, PATCH_TDI, thisPort, thisBit, error);
+ CHECK_STATUS(fStatus, "jtagConfigPorts()", fStatus);
+
+ GET_PAIR(thisPort, thisBit, "jtagConfigPorts"); // TMS
+ SET_BIT(thisPort, thisBit, LOW, "jtagConfigPorts");
+ fStatus = portMap(handle, PATCH_TMS, thisPort, thisBit, error);
+ CHECK_STATUS(fStatus, "jtagConfigPorts()", fStatus);
+
+ GET_PAIR(thisPort, thisBit, "jtagConfigPorts"); // TCK
+ SET_BIT(thisPort, thisBit, LOW, "jtagConfigPorts");
+ fStatus = portMap(handle, PATCH_TCK, thisPort, thisBit, error);
+ CHECK_STATUS(fStatus, "jtagConfigPorts()", fStatus);
+
makeMasks(pinMap, maskList, ddrList, portList);
cleanup:
return returnCode;
}
+static FLStatus playSVF(struct FLContext *handle, const char *svfFile, const char **error) {
+ FLStatus returnCode = FL_SUCCESS;
+ FLStatus fStatus;
+ struct Buffer csvfBuf = {0,};
+ BufferStatus bStatus;
+ int cStatus;
+ uint32 maxBufSize;
+ bool isCompressed;
+
+ const char *const ext = svfFile + strlen(svfFile) - 5;
+ if ( !handle->isNeroCapable ) {
+ errRender(error, "playSVF(): This device does not support NeroJTAG");
+ FAIL(FL_PROTOCOL_ERR);
+ }
+ bStatus = bufInitialise(&csvfBuf, 0x20000, 0, error);
+ CHECK_STATUS(bStatus, "playSVF()", FL_ALLOC_ERR);
+ if ( strcmp(".svf", ext+1) == 0 ) {
+ fStatus = flLoadSvfAndConvertToCsvf(svfFile, &csvfBuf, &maxBufSize, error);
+ CHECK_STATUS(fStatus, "playSVF()", fStatus);
+ isCompressed = false;
+ } else if ( strcmp(".xsvf", ext) == 0 ) {
+ fStatus = flLoadXsvfAndConvertToCsvf(svfFile, &csvfBuf, &maxBufSize, error);
+ CHECK_STATUS(fStatus, "playSVF()", fStatus);
+ isCompressed = false;
+ } else if ( strcmp(".csvf", ext) == 0 ) {
+ bStatus = bufAppendFromBinaryFile(&csvfBuf, svfFile, error);
+ CHECK_STATUS(bStatus, "playSVF()", FL_FILE_ERR);
+ isCompressed = true;
+ } else {
+ errRender(error, "playSVF(): Filename should have .svf, .xsvf or .csvf extension");
+ FAIL(FL_FILE_ERR);
+ }
+ cStatus = csvfPlay(handle, csvfBuf.data, isCompressed, error);
+ CHECK_STATUS(cStatus, "playSVF()", FL_JTAG_ERR);
+cleanup:
+ bufDestroy(&csvfBuf);
+ return returnCode;
+}
+
static FLStatus jProgram(struct FLContext *handle, const char *portConfig, const char *progFile, const char **error) {
FLStatus returnCode = FL_SUCCESS;
FLStatus fStatus;
@@ -445,7 +500,7 @@ static FLStatus jProgram(struct FLContext *handle, const char *portConfig, const
char ch;
int i;
EXPECT_CHAR(':', "jProgram");
- fStatus = jtagGetPorts(portConfig, ptr, maskList, ddrList, portList, error);
+ fStatus = jtagConfigPorts(handle, portConfig, ptr, maskList, ddrList, portList, error);
CHECK_STATUS(fStatus, "jProgram()", fStatus);
ptr += 8;
ch = *ptr;
@@ -473,7 +528,7 @@ static FLStatus jProgram(struct FLContext *handle, const char *portConfig, const
}
fStatus = flFifoMode(handle, false, error);
- CHECK_STATUS(fStatus, "xProgram()", fStatus);
+ CHECK_STATUS(fStatus, "jProgram()", fStatus);
printf("Disabled FIFO mode\n");
@@ -492,12 +547,8 @@ static FLStatus jProgram(struct FLContext *handle, const char *portConfig, const
printf("Configured ports\n");
-
-
-
-
-
-
+ fStatus = playSVF(handle, progFile, error);
+ CHECK_STATUS(fStatus, "jProgram()", fStatus);
for ( i = 0; i < 5; i++ ) {
mask = maskList[i];
@@ -558,6 +609,31 @@ DLLEXPORT(FLStatus) flProgram(struct FLContext *handle, const char *portConfig,
return returnCode;
}
+DLLEXPORT(FLStatus) flPortConfig(struct FLContext *handle, const char *portConfig, const char **error) {
+ FLStatus returnCode = FL_SUCCESS;
+ FLStatus fStatus;
+ PinState pinMap[5*8] = {0,};
+ uint8 maskList[5], ddrList[5], portList[5], mask;
+ int i;
+ fStatus = populateMap(portConfig, portConfig, NULL, pinMap, error);
+ CHECK_STATUS(fStatus, "flPortConfig()", fStatus);
+ makeMasks(pinMap, maskList, ddrList, portList);
+ for ( i = 0; i < 5; i++ ) {
+ mask = maskList[i];
+ if ( mask ) {
+ fStatus = flPortAccess(
+ handle, i,
+ mask, ddrList[i], portList[i],
+ NULL,
+ error
+ );
+ CHECK_STATUS(fStatus, "flPortConfig()", fStatus);
+ }
+ }
+cleanup:
+ return returnCode;
+}
+
// Play an SVF, XSVF or CSVF file into the JTAG chain.
//
DLLEXPORT(FLStatus) flPlaySVF(struct FLContext *handle, const char *svfFile, const char *portConfig, const char **error) {
@@ -568,7 +644,7 @@ DLLEXPORT(FLStatus) flPlaySVF(struct FLContext *handle, const char *svfFile, con
int cStatus;
uint32 maxBufSize;
bool isCompressed;
-
+
const char *const ext = svfFile + strlen(svfFile) - 5;
if ( !handle->isNeroCapable ) {
errRender(error, "flPlaySVF(): This device does not support NeroJTAG");
View
@@ -681,6 +681,10 @@ extern "C" {
DLLEXPORT(FLStatus) flProgram(
struct FLContext *handle, const char *portConfig, const char *progFile, const char **error
) WARN_UNUSED_RESULT;
+
+ DLLEXPORT(FLStatus) flPortConfig(
+ struct FLContext *handle, const char *portConfig, const char **error
+ ) WARN_UNUSED_RESULT;
//@}
#ifdef __cplusplus
View
@@ -201,54 +201,60 @@ NeroStatus neroShift(
const char **error)
{
NeroStatus returnCode, nStatus;
- uint32 numBytes;
+ uint32 numBytes = bitsToBytes(numBits);
uint16 chunkSize;
- ProgOp progOp;
uint8 mode = 0x00;
bool isSending = false;
- bool isReceiving = false;
if ( inData == ONES ) {
mode |= bmSENDONES;
} else if ( inData != ZEROS ) {
isSending = true;
}
- if ( outData ) {
- isReceiving = true;
- }
if ( isLast ) {
mode |= bmISLAST;
}
if ( isSending ) {
- if ( isReceiving ) {
- progOp = PROG_JTAG_ISSENDING_ISRECEIVING;
+ if ( outData ) {
+ nStatus = beginShift(handle, numBits, PROG_JTAG_ISSENDING_ISRECEIVING, mode, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_BEGIN_SHIFT);
+ while ( numBytes ) {
+ chunkSize = (numBytes >= 64) ? 64 : (uint16)numBytes;
+ nStatus = doSend(handle, inData, chunkSize, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_SEND);
+ inData += chunkSize;
+ nStatus = doReceive(handle, outData, chunkSize, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_RECEIVE);
+ outData += chunkSize;
+ numBytes -= chunkSize;
+ }
} else {
- progOp = PROG_JTAG_ISSENDING_NOTRECEIVING;
+ nStatus = beginShift(handle, numBits, PROG_JTAG_ISSENDING_NOTRECEIVING, mode, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_BEGIN_SHIFT);
+ while ( numBytes ) {
+ chunkSize = (numBytes >= 64) ? 64 : (uint16)numBytes;
+ nStatus = doSend(handle, inData, chunkSize, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_SEND);
+ inData += chunkSize;
+ numBytes -= chunkSize;
+ }
}
} else {
- if ( isReceiving ) {
- progOp = PROG_JTAG_NOTSENDING_ISRECEIVING;
+ if ( outData ) {
+ nStatus = beginShift(handle, numBits, PROG_JTAG_NOTSENDING_ISRECEIVING, mode, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_BEGIN_SHIFT);
+ while ( numBytes ) {
+ chunkSize = (numBytes >= 64) ? 64 : (uint16)numBytes;
+ nStatus = doReceive(handle, outData, chunkSize, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_RECEIVE);
+ outData += chunkSize;
+ numBytes -= chunkSize;
+ }
} else {
- progOp = PROG_JTAG_NOTSENDING_NOTRECEIVING;
+ nStatus = beginShift(handle, numBits, PROG_JTAG_NOTSENDING_NOTRECEIVING, mode, error);
+ CHECK_STATUS(nStatus, "neroShift()", NERO_BEGIN_SHIFT);
}
}
- nStatus = beginShift(handle, numBits, progOp, mode, error);
- CHECK_STATUS(nStatus, "neroShift()", NERO_BEGIN_SHIFT);
- numBytes = bitsToBytes(numBits);
- while ( numBytes ) {
- chunkSize = (numBytes>=handle->endpointSize) ? handle->endpointSize : (uint16)numBytes;
- if ( isSending ) {
- nStatus = doSend(handle, inData, chunkSize, error);
- CHECK_STATUS(nStatus, "neroShift()", NERO_SEND);
- inData += chunkSize;
- }
- if ( isReceiving ) {
- nStatus = doReceive(handle, outData, chunkSize, error);
- CHECK_STATUS(nStatus, "neroShift()", NERO_RECEIVE);
- outData += chunkSize;
- }
- numBytes -= chunkSize;
- }
return NERO_SUCCESS;
cleanup:
return returnCode;
@@ -303,32 +309,6 @@ NeroStatus neroClocks(struct FLContext *handle, uint32 numClocks, const char **e
// -------------------------------------------------------------------------------------------------
// Implementation of private functions
// -------------------------------------------------------------------------------------------------
-static NeroStatus portMap(
- struct FLContext *handle, uint8 patchClass, uint8 port, uint8 bit, const char **error)
-{
- NeroStatus returnCode = NERO_SUCCESS;
- union {
- uint16 word;
- uint8 bytes[2];
- } index, value;
- index.bytes[0] = patchClass;
- index.bytes[1] = port;
- value.bytes[0] = bit;
- value.bytes[1] = 0x00;
- int uStatus = usbControlWrite(
- handle->device,
- 0x90, // bRequest
- value.word, // wValue
- index.word, // wIndex
- NULL, // no data
- 0, // wLength
- 1000, // timeout (ms)
- error
- );
- CHECK_STATUS(uStatus, "portMap()", NERO_PORTMAP);
-cleanup:
- return returnCode;
-}
// Kick off a shift operation on the micro. This will be followed by a bunch of sends and receives.
//
@@ -490,3 +470,30 @@ static NeroStatus setJtagMode(struct FLContext *handle, bool enable, const char
cleanup:
return returnCode;
}
+
+static NeroStatus portMap(
+ struct FLContext *handle, uint8 patchClass, uint8 port, uint8 bit, const char **error)
+{
+ NeroStatus returnCode = NERO_SUCCESS;
+ union {
+ uint16 word;
+ uint8 bytes[2];
+ } index, value;
+ index.bytes[0] = patchClass;
+ index.bytes[1] = port;
+ value.bytes[0] = bit;
+ value.bytes[1] = 0x00;
+ int uStatus = usbControlWrite(
+ handle->device,
+ 0x90, // bRequest
+ value.word, // wValue
+ index.word, // wIndex
+ NULL, // no data
+ 0, // wLength
+ 1000, // timeout (ms)
+ error
+ );
+ CHECK_STATUS(uStatus, "portMap()", NERO_PORTMAP);
+cleanup:
+ return returnCode;
+}
View
@@ -18,6 +18,14 @@
#define PROG_H
typedef enum {
+ PATCH_TDO,
+ PATCH_TDI,
+ PATCH_TMS,
+ PATCH_TCK,
+ PATCH_D8
+} PatchOp;
+
+typedef enum {
PROG_NOP,
PROG_JTAG_ISSENDING_ISRECEIVING,
PROG_JTAG_ISSENDING_NOTRECEIVING,

0 comments on commit afa007c

Please sign in to comment.