예제 #1
0
// Dump the selected range of the HexReader buffers as I2C records to the supplied buffer. This will
// split up large chunks into chunks 1023 bytes or smaller so chunk lengths fit in ten bits.
// (see TRM 3.4.3)
//
static I2CStatus dumpChunk(
	struct Buffer *destination, const struct Buffer *sourceData, const struct Buffer *sourceMask,
	uint16 address, uint16 length, const char **error)
{
	I2CStatus retVal = I2C_SUCCESS;
	BufferStatus bStatus;
	size_t i, startBlock;
	if ( length == 0 ) {
		return I2C_SUCCESS;
	}
	while ( length > 1023 ) {
		retVal = dumpChunk(destination, sourceData, sourceMask, address, 1023, error);
		CHECK_STATUS(retVal, retVal, cleanup, "dumpChunk()");
		address = (uint16)(address + 1023);
		length = (uint16)(length - 1023);
	}
	bStatus = bufAppendWordBE(destination, length, error);
	CHECK_STATUS(bStatus, I2C_BUFFER_ERROR, cleanup, "dumpChunk()");
	bStatus = bufAppendWordBE(destination, address, error);
	CHECK_STATUS(bStatus, I2C_BUFFER_ERROR, cleanup, "dumpChunk()");
	startBlock = destination->length;
	bStatus = bufAppendBlock(destination, sourceData->data + address, length, error);
	CHECK_STATUS(bStatus, I2C_BUFFER_ERROR, cleanup, "dumpChunk()");
	for ( i = 0; i < length; i++ ) {
		if ( sourceMask->data[address + i] == 0x00 ) {
			destination->data[startBlock + i] = 0x00;
		}
	}
cleanup:
	return retVal;
}
예제 #2
0
// Append a write command to the end of the write buffer.
//
DLLEXPORT(FLStatus) flAppendWriteChannelCommand(
	struct FLContext *handle, uint8 chan, uint32 count, const uint8 *data, const char **error)
{
	FLStatus retVal = FL_SUCCESS;
	BufferStatus bStatus;
	uint8 command[5];
	if ( !handle->writeBuffer.data ) {
		// write buffer is lazily initialised
		bStatus = bufInitialise(&handle->writeBuffer, 1024, 0x00, error);
		CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "flAppendWriteChannelCommand()");
	}
	command[0] = chan & 0x7F;
	flWriteLong(count, command+1);
	bStatus = bufAppendBlock(&handle->writeBuffer, command, 5, error);
	CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "flAppendWriteChannelCommand()");
	bStatus = bufAppendBlock(&handle->writeBuffer, data, count, error);
	CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "flAppendWriteChannelCommand()");
cleanup:
	return retVal;
}
예제 #3
0
// Finalise the I2C buffers. This involves writing the final record which resets the chip.
//
DLLEXPORT(I2CStatus) i2cFinalise(struct Buffer *buf, const char **error) {
	I2CStatus retVal = I2C_SUCCESS;
	BufferStatus bStatus;
	const uint8 lastRecord[] = {0x80, 0x01, 0xe6, 0x00, 0x00};
	CHECK_STATUS(
		buf->length < 8 || buf->data[0] != 0xC2, I2C_NOT_INITIALISED, cleanup,
		"i2cFinalise(): the buffer was not initialised");
	bStatus = bufAppendBlock(buf, lastRecord, 5, error);
	CHECK_STATUS(bStatus, I2C_BUFFER_ERROR, cleanup, "i2cFinalise()");
cleanup:
	return retVal;
}
예제 #4
0
파일: fx2.c 프로젝트: kulp/libfpgalink
FLStatus copyFirmwareAndRewriteIDs(
	const struct FirmwareInfo *fwInfo, uint16 vid, uint16 pid, uint16 did,
	struct Buffer *dest, const char **error)
{
	FLStatus retVal = FL_SUCCESS;  // Can return FL_ALLOC_ERR, FL_FX2_ERR and FL_INTERNAL_ERR
	BufferStatus bStatus;
	bStatus = bufAppendBlock(dest, fwInfo->data, fwInfo->length, error);
	CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "copyFirmwareAndRewriteIDs()");
	dest->data[fwInfo->vp]     = (uint8)(vid & 0xFF);
	dest->data[fwInfo->vp + 1] = (uint8)(vid >> 8);
	dest->data[fwInfo->vp + 2] = (uint8)(pid & 0xFF);
	dest->data[fwInfo->vp + 3] = (uint8)(pid >> 8);
	dest->data[fwInfo->vp + 4] = (uint8)(did & 0xFF);
	dest->data[fwInfo->vp + 5] = (uint8)(did >> 8);
cleanup:
	return retVal;
}
예제 #5
0
파일: fx2.c 프로젝트: bioak/libfpgalink
DLLEXPORT(FLStatus) flFlashStandardFirmware(
	struct FLContext *handle, const char *newVidPid, const char *jtagPort,
	 uint32 eepromSize, const char *xsvfFile, const char **error)
{
	FLStatus flStatus, returnCode;
	struct Buffer i2cBuf = {0,};
	BufferStatus bStatus;
	FX2Status fxStatus;
	uint32 fwSize, xsvfSize, initSize;
	uint16 newVid, newPid, newDid;
	uint8 port, tdoBit, tdiBit, tmsBit, tckBit;
	if ( !usbValidateVidPid(newVidPid) ) {
		errRender(error, "flFlashStandardFirmware(): The supplied new VID:PID \"%s\" is invalid; it should look like 04B4:8613", newVidPid);
		FAIL(FL_USB_ERR);
	}
	newVid = (uint16)strtoul(newVidPid, NULL, 16);
	newPid = (uint16)strtoul(newVidPid+5, NULL, 16);
	newDid = (strlen(newVidPid) == 14) ? (uint16)strtoul(newVidPid+10, NULL, 16) : 0x0000;
	if ( strlen(jtagPort) != 5 ) {
		errRender(error, "flFlashStandardFirmware(): JTAG port specification must be <C|D><tdoBit><tdiBit><tmsBit><tckBit>");
		FAIL(FL_FX2_ERR);
	}
	if ( (jtagPort[0] & 0xDF) == 'A' ) {
		port = 0;
	} else if ( (jtagPort[0] & 0xDF) == 'C' ) {
		port = 2;
	} else if ( (jtagPort[0] & 0xDF) == 'D' ) {
		port = 3;
	} else {
		errRender(error, "flFlashStandardFirmware(): JTAG port specification must be <A|C|D><tdoBit><tdiBit><tmsBit><tckBit>");
		FAIL(FL_FX2_ERR);
	}
	if  (jtagPort[1] < '0' || jtagPort[1] > '7' || jtagPort[2] < '0' || jtagPort[2] > '7' || jtagPort[3] < '0' || jtagPort[3] > '7' || jtagPort[4] < '0' || jtagPort[4] > '7' ) {
		errRender(error, "flFlashStandardFirmware(): JTAG port specification must be <A|C|D><tdoBit><tdiBit><tmsBit><tckBit>");
		FAIL(FL_FX2_ERR);
	}
	tdoBit = jtagPort[1] - '0';
	tdiBit = jtagPort[2] - '0';
	tmsBit = jtagPort[3] - '0';
	tckBit = jtagPort[4] - '0';
	if (
		port == 0 &&
		(isInvalidPortABit(tdoBit) || isInvalidPortABit(tdiBit) ||
		 isInvalidPortABit(tmsBit) || isInvalidPortABit(tckBit))
	) {
		errRender(error, "flFlashStandardFirmware(): Only bits 0, 1, 3 & 7 are available for JTAG use on port A");
		FAIL(FL_FX2_ERR);
	}		
		
	bStatus = bufInitialise(&i2cBuf, 0x4000, 0x00, error);
	CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
	if ( xsvfFile ) {
		flStatus = copyFirmwareAndRewriteIDs(
			&eepromWithBootFirmware, newVid, newPid, newDid,
			port, tdoBit, tdiBit, tmsBit, tckBit,
			&i2cBuf, error);
		CHECK_STATUS(flStatus, "flFlashStandardFirmware()", flStatus);
		fwSize = i2cBuf.length;
		flStatus = convertJtagFileToCsvf(&i2cBuf, xsvfFile, error);
		CHECK_STATUS(flStatus, "flFlashStandardFirmware()", flStatus);
		xsvfSize = i2cBuf.length - fwSize;
		if ( handle->writeBuffer.length ) {
			// Write a big-endian uint24 length for the init data, then the data itself
			const uint32 length = handle->writeBuffer.length;
			if ( length > 0x20000 ) {
				errRender(
					error,
					"flFlashStandardFirmware(): Cannot cope with %lu bytes of init data",
					length);
				FAIL(FL_FX2_ERR);
			}
			bStatus = bufAppendByte(&i2cBuf, (uint8)((length>>16) & 0xFF), error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			bStatus = bufAppendByte(&i2cBuf, (uint8)((length>>8) & 0xFF), error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			bStatus = bufAppendByte(&i2cBuf, (uint8)(length & 0xFF), error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			bStatus = bufAppendBlock(
				&i2cBuf, handle->writeBuffer.data, length, error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			initSize = length + 3;
		} else {
			// Write a zero uint24 length so the firmware knows there's no init data to follow
			bStatus = bufAppendByte(&i2cBuf, 0x00, error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			bStatus = bufAppendByte(&i2cBuf, 0x00, error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			bStatus = bufAppendByte(&i2cBuf, 0x00, error);
			CHECK_STATUS(bStatus, "flFlashStandardFirmware()", FL_ALLOC_ERR);
			initSize = 3;
		}
	} else {