Пример #1
0
// Play the CSVF stream into the JTAG port.
//
FLStatus csvfPlay(struct FLContext *handle, const uint8 *csvfData, const char **error) {
	FLStatus returnCode = FL_SUCCESS;
	FLStatus fStatus;
	uint8 thisByte, numBits;
	uint32 numBytes;
	uint8 *tdoPtr, *tdiPtr;
	uint8 i;
	uint32 xsdrSize = 0;
	uint32 xruntest = 0;
	uint8 tdoMask[CSVF_BUF_SIZE];
	uint8 tdiData[CSVF_BUF_SIZE];
	uint8 tdoData[CSVF_BUF_SIZE];
	uint8 tdoExpected[CSVF_BUF_SIZE];
	
	char data[CSVF_BUF_SIZE*2+1];
	char mask[CSVF_BUF_SIZE*2+1];
	char expected[CSVF_BUF_SIZE*2+1];
	
	uint8 *tdiAll;
	const uint8 *ptr = csvfData;

	fStatus = jtagClockFSM(handle, 0x0000001F, 6, error);  // Reset TAP, goto Run-Test/Idle
	CHECK_STATUS(fStatus, "csvfPlay()", fStatus);

	thisByte = *ptr++;
	while ( thisByte != XCOMPLETE ) {
		switch ( thisByte ) {
		case XTDOMASK:
			#ifdef DEBUG
				printf("XTDOMASK(");
			#endif
			numBytes = bitsToBytes(xsdrSize);
			tdoPtr = tdoMask;
			while ( numBytes-- ) {
				thisByte = *ptr++;
				#ifdef DEBUG
					printf("%02X", thisByte);
				#endif
				*tdoPtr++ = thisByte;
			}
			#ifdef DEBUG
				printf(")\n");
			#endif
			break;

		case XRUNTEST:
			xruntest = *ptr++;
			xruntest <<= 8;
			xruntest |= *ptr++;
			xruntest <<= 8;
			xruntest |= *ptr++;
			xruntest <<= 8;
			xruntest |= *ptr++;
			#ifdef DEBUG
				printf("XRUNTEST(%08X)\n", xruntest);
			#endif
			break;

		case XSIR:
			fStatus = jtagClockFSM(handle, 0x00000003, 4, error);  // -> Shift-IR
			CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			numBits = *ptr++;
			#ifdef DEBUG
				printf("XSIR(%02X, ", numBits);
			#endif
			numBytes = bitsToBytes(numBits);
			tdiPtr = tdiData;
			while ( numBytes-- ) {
				thisByte = *ptr++;
				#ifdef DEBUG
					printf("%02X", thisByte);
				#endif
				*tdiPtr++ = thisByte;
			}
			#ifdef DEBUG
				printf(")\n");
			#endif
			fStatus = jtagShift(handle, numBits, tdiData, NULL, true, error);  // -> Exit1-DR
			CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			fStatus = jtagClockFSM(handle, 0x00000001, 2, error);  // -> Run-Test/Idle
			CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			if ( xruntest ) {
				fStatus = jtagClocks(handle, xruntest, error);
				CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			}
			break;

		case XSDRSIZE:
			xsdrSize = *ptr++;
			xsdrSize <<= 8;
			xsdrSize |= *ptr++;
			xsdrSize <<= 8;
			xsdrSize |= *ptr++;
			xsdrSize <<= 8;
			xsdrSize |= *ptr++;
			#ifdef DEBUG
				printf("XSDRSIZE(%08X)\n", xsdrSize);
			#endif
			break;

		case XSDRTDO:
			numBytes = bitsToBytes(xsdrSize);
			tdiPtr = tdiData;
			tdoPtr = tdoExpected;
			while ( numBytes-- ) {
				*tdiPtr++ = *ptr++;
				*tdoPtr++ = *ptr++;
			}
			numBytes = bitsToBytes(xsdrSize);
			i = 0;
			do {
				fStatus = jtagClockFSM(handle, 0x00000001, 3, error);  // -> Shift-DR
				CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
				fStatus = jtagShift(handle, xsdrSize, tdiData, tdoData, true, error);  // -> Exit1-DR
				CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
				fStatus = jtagClockFSM(handle, 0x0000001A, 6, error);  // -> Run-Test/Idle
				CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
				if ( xruntest ) {
					fStatus = jtagClocks(handle, xruntest, error);
					CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
				}
				i++;
				#ifdef DEBUG
					dumpSimple(tdoData, numBytes, data);
					dumpSimple(tdoMask, numBytes, mask);
					dumpSimple(tdoExpected, numBytes, expected);
					printf("XSDRTDO(attempt: %d; mask: %s; expecting: %s; got: %s)\n", i, mask, expected, data);
				#endif
			} while ( tdoMatchFailed(tdoData, tdoMask, tdoExpected, numBytes) && i < 32 );

			if ( i == 32 ) {
				dumpSimple(tdoData, numBytes, data);
				dumpSimple(tdoMask, numBytes, mask);
				dumpSimple(tdoExpected, numBytes, expected);
				errRender(
					error,
					"csvfPlay(): XSDRTDO failed:\n  Got: %s\n  Mask: %s\n  Expecting: %s",
					data, mask, expected);
				FAIL(FL_PROG_SVF_COMPARE);
			}
			break;

		case XSDR:
			#ifdef DEBUG
				// TODO: Need to print actual TDO data too
				printf("XSDR(%08X)\n", xsdrSize);
			#endif
			fStatus = jtagClockFSM(handle, 0x00000001, 3, error);  // -> Shift-DR
			CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			numBytes = bitsToBytes(xsdrSize);
			tdiAll = malloc(numBytes);
			tdiPtr = tdiAll;
			while ( numBytes-- ) {
				*tdiPtr++ = *ptr++;
			}
			fStatus = jtagShift(handle, xsdrSize, tdiAll, NULL, true, error);  // -> Exit1-DR
			free(tdiAll);
			CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			fStatus = jtagClockFSM(handle, 0x00000001, 2, error);  // -> Run-Test/Idle
			CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			if ( xruntest ) {
				fStatus = jtagClocks(handle, xruntest, error);
				CHECK_STATUS(fStatus, "csvfPlay()", fStatus);
			}
			break;

		default:
			errRender(error, "csvfPlay(): Unsupported command 0x%02X", thisByte);
			FAIL(FL_PROG_SVF_UNKNOWN_CMD);
		}
		thisByte = *ptr++;
	}
cleanup:
	return returnCode;
}
Пример #2
0
// Called when a vendor command is received
//
uint8 handleVendorCommand(uint8 cmd) {
	switch(cmd) {

	// Set various mode bits, or fetch status information
	//
	case CMD_MODE_STATUS:
		if ( SETUP_TYPE == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR) ) {
			xdata uint16 wBits = SETUP_VALUE();
			xdata uint16 wMask = SETUP_INDEX();
			if ( wMask & MODE_JTAG ) {
				// When in JTAG mode, the JTAG lines are driven; tristate otherwise
				jtagSetEnabled(wBits & MODE_JTAG ? true : false);
			}
		} else {
			// Get STATUS: return the diagnostic byte
			while ( EP0CS & bmEPBUSY );
			EP0BUF[0] = 'N';                     // Magic bytes (my cat's name)
			EP0BUF[1] = 'E';
			EP0BUF[2] = 'M';
			EP0BUF[3] = 'I';
			EP0BUF[4] = m_diagnosticCode;        // Last operation diagnostic code
			EP0BUF[5] = (IOA & bmBIT2) ? 0 : 1;  // Flags
			EP0BUF[6] = 0x11;                    // NeroJTAG endpoints
			EP0BUF[7] = 0x26;                    // CommFPGA endpoints
			EP0BUF[8] = 0x00;                    // Reserved
			EP0BUF[9] = 0x00;                    // Reserved
			EP0BUF[10] = 0x00;                   // Reserved
			EP0BUF[11] = 0x00;                   // Reserved
			EP0BUF[12] = 0x00;                   // Reserved
			EP0BUF[13] = 0x00;                   // Reserved
			EP0BUF[14] = 0x00;                   // Reserved
			EP0BUF[15] = 0x00;                   // Reserved
			
			// Return status packet to host
			EP0BCH = 0;
			SYNCDELAY;
			EP0BCL = 16;
		}
		return true;

	// Clock data into and out of the JTAG chain. Reads from EP2OUT and writes to EP4IN.
	//
	case CMD_JTAG_CLOCK_DATA:
		if ( SETUP_TYPE == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR) ) {
			EP0BCL = 0x00;                                     // Allow host transfer in
			while ( EP0CS & bmEPBUSY );                        // Wait for data
			jtagShiftBegin(*((uint32 *)EP0BUF), SETUPDAT[2]);  // Init numBits & flagByte
			return true;
			// Now that numBits & flagByte are set, this operation will continue in mainLoop()...
		}
		break;
		
	// Clock an (up to) 32-bit pattern LSB-first into TMS to change JTAG TAP states
	//
	case CMD_JTAG_CLOCK_FSM:
		if ( SETUP_TYPE == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR) ) {
			EP0BCL = 0x00;                                   // Allow host transfer in
			while ( EP0CS & bmEPBUSY );                      // Wait for data
			jtagClockFSM(*((uint32 *)EP0BUF), SETUPDAT[2]);  // Bit pattern, transitionCount
			return true;
		}
		break;
		
	// Execute a number of JTAG clocks.
	//
	case CMD_JTAG_CLOCK:
		if ( SETUP_TYPE == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR) ) {
			jtagClocks(*((uint32 *)(SETUPDAT+2)));
			return true;
		}
		break;

	// Set various mode bits, or fetch status information
	//
	case CMD_PORT_IO:
		if ( SETUP_TYPE == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR) ) {
			const xdata uint8 portSelect = SETUPDAT[4];
			const xdata uint8 mask = SETUPDAT[5];
			xdata uint8 ddrWrite = SETUPDAT[2];
			xdata uint8 portWrite = SETUPDAT[3];

			//usartSendString("Got: ");
			//usartSendByteHex(portSelect);
			//usartSendByteHex(mask);
			//usartSendByteHex(ddrWrite);
			//usartSendByteHex(portWrite);
			//usartSendByte('\r');

			if ( portSelect > 4 ) {
				return false;  // illegal port
			}
			portWrite &= mask;
			ddrWrite &= mask;
			pins[portSelect] &= ~mask;  // clear existing relevant bits
			pins[portSelect] |= portWrite; 
			ddrs[portSelect] &= ~mask;
			ddrs[portSelect] |= ddrWrite;
			(*maskFunc[JTAG_PORT])();

			// Get the state of the port D & B lines:
			while ( EP0CS & bmEPBUSY );
			switch ( portSelect ) {
			case 0:
				OEA = ddrs[0];
				IOA = pins[0];
				EP0BUF[0] = IOA;
				break;
			case 2:
				OEC = ddrs[2];
				IOC = pins[2];
				EP0BUF[0] = IOC;
				break;
			case 3:
				OED = ddrs[3];
				IOD = pins[3];
				EP0BUF[0] = IOD;
				break;
			case 4:
				OEE = ddrs[4];
				IOE = pins[4];
				EP0BUF[0] = IOE;
				break;
			default:
				EP0BUF[0] = 0xAA;
				break;
			}
			EP0BCH = 0;
			SYNCDELAY;
			EP0BCL = 1;
			return true;
		}
		break;

	// Command to talk to the EEPROM
	//
	case CMD_READ_WRITE_EEPROM:
		if ( SETUP_TYPE == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR) ) {
			// It's an IN operation - read from prom and send to host
			xdata uint16 address = SETUP_VALUE();
			xdata uint16 length = SETUP_LENGTH();
			xdata uint16 chunkSize;
			xdata uint8 i;
			while ( length ) {
				while ( EP0CS & bmEPBUSY );
				chunkSize = length < EP0BUF_SIZE ? length : EP0BUF_SIZE;
				for ( i = 0; i < chunkSize; i++ ) {
					EP0BUF[i] = 0x23;
				}
				promRead(SETUPDAT[4], address, chunkSize, EP0BUF);
				EP0BCH = 0;
				SYNCDELAY;
				EP0BCL = chunkSize;
				address += chunkSize;
				length -= chunkSize;
			}
		} else if ( SETUP_TYPE == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR) ) {
			// It's an OUT operation - read from host and send to prom
			xdata uint16 address = SETUP_VALUE();
			xdata uint16 length = SETUP_LENGTH();
			xdata uint16 chunkSize;
			while ( length ) {
				EP0BCL = 0x00; // allow pc transfer in
				while ( EP0CS & bmEPBUSY ); // wait for data
				chunkSize = EP0BCL;
				promWrite(SETUPDAT[4], address, chunkSize, EP0BUF);
				address += chunkSize;
				length -= chunkSize;
			}
		}
		return true;

	case CMD_SELECTMAP:
		if ( SETUP_TYPE == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR) ) {
			// return the status byte and micro-controller mode
			while ( EP0CS & bmEPBUSY ); // can't do this until EP0 is ready
			EP0BUF[0] = 0xF0;
			EP0BUF[1] = 0x0D;
			EP0BUF[2] = 0x1E;
			EP0BCH=0;
			SYNCDELAY;
			EP0BCL=3;
		} else if ( SETUP_TYPE == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR) ) {
			smapProgBegin(MAKEDWORD(SETUP_VALUE(), SETUP_INDEX()));
		}
		return true;
	}
	return false;  // unrecognised command
}