Beispiel #1
0
//*****************************************************
// Puts the address on the address bus
// And gets the value from the data bus
// Then returns this value
//*****************************************************
u16 readCommand(struct FLContext *handle, u32 address){
	u8 buffer[4];
	
	buffer[0] = READ;
	buffer[1] = address & 0xFF;
	buffer[2] = (address & 0xFF00) >> 8;
	buffer[3] = (address & 0xFF0000) >> 16;
	// Ask the flash to send the data at the specified address
	flWriteChannel(handle, 1000, 0, 4, buffer, NULL);
	flReadChannel(handle, 1000, 0, 2, buffer, NULL); 
	u16 ret = buffer[0] | (buffer[1] << 8);
	return ret;
}
Beispiel #2
0
//*****************************************************
// Puts the address on the address bus to the flash
// and puts data on the data bus
//*****************************************************
void writeCommand(struct FLContext *handle, u32 address, u16 data){
	u8 buffer[6];
	
	buffer[0] = WRITE;
	buffer[1] = address;
	buffer[2] = (address & 0xFF00) >> 8;
	buffer[3] = (address & 0xFF0000) >> 16;
        buffer[4] = data & 0xFF;
	buffer[5] = (data & 0xFF00) >> 8;

	//printf("Address %x-%x\n", (u8)buffer[2], (u8)buffer[1]);
        flWriteChannel(handle, 1000, 0, 6, buffer, NULL); 
}
Beispiel #3
0
// Tell the monitor to continue execution with the (possibly new) register/memory context, until
// a breakpoint is hit. If there is no breakpoint in the execution-path, this function will wait
// forever.
//
int umdkContWait(
	struct FLContext *handle, bool debug, struct Registers *regs, const char **error)
{
	int retVal = 0, status, i;
	uint8 tmpData[65536];
	size_t scrapSize;
	uint32 vbAddr, actualLength;
	uint16 oldOp;
	union RegUnion {
		struct Registers reg;
		uint32 longs[18];
		uint8 bytes[18*4];
	} *const u = (union RegUnion *)regs;
	const uint8 *recvData;
	FILE *file = NULL;

	if ( debug ) {
		// Read RAM
		status = umdkReadBytes(handle, 0xFF0000, 65536, tmpData, error);
		CHECK_STATUS(status, status, cleanup);
		
		// Save it
		file = fopen("ramBefore.bin", "wb");
		CHECK_STATUS(!file, 13, cleanup, "umdkContWait(): Unable to open ramBefore.bin for writing!");
		fwrite(tmpData, 1, 65536, file);
		fclose(file);
		file = NULL;
		
		// Open trace log
		file = fopen("trace.log", "wb");
		CHECK_STATUS(!file, 13, cleanup, "umdkContWait(): Unable to open trace.log for writing!");
	}

	// Get address of VDP vertical interrupt routine and its first opcode
	status = umdkDirectReadLong(handle, VB_VEC, &vbAddr, error);
	CHECK_STATUS(status, status, cleanup);
	status = umdkDirectReadWord(handle, vbAddr, &oldOp, error);
	CHECK_STATUS(status, status, cleanup);

	// Write monitor address to illegal instruction vector
	status = umdkDirectWriteLong(handle, IL_VEC, MONITOR, error);
	CHECK_STATUS(status, status, cleanup);

	if ( debug ) {
		// Disable tracing (if any) & clear junk from trace FIFO
		tmpData[0] = 0x00;
		status = flWriteChannel(handle, 0x01, 1, tmpData, error);
		CHECK_STATUS(status, 25, cleanup);
		status = flReadChannel(handle, 0x03, 1, tmpData, error);
		CHECK_STATUS(status, 20, cleanup);
		scrapSize = tmpData[0] << 8;
		status = flReadChannel(handle, 0x04, 1, tmpData, error);
		CHECK_STATUS(status, 20, cleanup);
		scrapSize |= tmpData[0];
		while ( scrapSize ) {
			// Clear junk from FIFO
			status = flReadChannel(handle, 0x02, scrapSize, tmpData, error);
			CHECK_STATUS(status, 20, cleanup);
			
			// Verify no junk remaining
			status = flReadChannel(handle, 0x03, 1, tmpData, error);
			CHECK_STATUS(status, 20, cleanup);
			scrapSize = tmpData[0] << 8;
			status = flReadChannel(handle, 0x04, 1, tmpData, error);
			CHECK_STATUS(status, 20, cleanup);
			scrapSize |= tmpData[0];
		}
		
		// Enable tracing
		tmpData[0] = 0x02;
		status = flWriteChannelAsync(handle, 0x01, 1, tmpData, error);
		CHECK_STATUS(status, 25, cleanup);
	}

	// Set up the continue command and execute it
	status = umdkDirectWriteWord(handle, CB_INDEX, CMD_CONT, error);
	CHECK_STATUS(status, status, cleanup);
	status = umdkDirectWriteWord(handle, CB_FLAG, CF_CMD, error);
	CHECK_STATUS(status, status, cleanup);

	if ( debug ) {
		// Submit 1st read for some trace data
		status = flReadChannelAsyncSubmit(handle, 2, 22528, NULL, error);
		CHECK_STATUS(status, 28, cleanup);
	}

	// Submit 1st read for the command status flag
	status = umdkDirectReadBytesAsync(handle, CB_FLAG, 2, error);
	CHECK_STATUS(status, status, cleanup);
	do {
		// If interrupted (escape or ctrl-c in gdb), induce a suspend at the next vblank
		if ( isInterrupted() ) {
			status = umdkDirectWriteWord(handle, vbAddr, ILLEGAL, error);
			CHECK_STATUS(status, status, cleanup);
		}

		if ( debug ) {
			// Submit a read for some trace data
			status = flReadChannelAsyncSubmit(handle, 2, 22528, NULL, error);
			CHECK_STATUS(status, 28, cleanup);
		}

		// Submit a read for the command status flag
		status = umdkDirectReadBytesAsync(handle, CB_FLAG, 2, error);
		CHECK_STATUS(status, status, cleanup);

		if ( debug ) {
			// Await the requested trace data
			status = flReadChannelAsyncAwait(handle, &recvData, &actualLength, &actualLength, error);
			CHECK_STATUS(status, status, cleanup);

			// Write it to the trace-log
			fwrite(recvData, 1, actualLength, file);
		}

		// Await the requested command status flag
		status = flReadChannelAsyncAwait(handle, &recvData, &actualLength, &actualLength, error);
		CHECK_STATUS(status, status, cleanup);
	} while ( recvData[0] != 0x00 || recvData[1] != CF_READY );

	if ( debug ) {
		// Await the final block of trace-data
		status = flReadChannelAsyncAwait(handle, &recvData, &actualLength, &actualLength, error);
		CHECK_STATUS(status, status, cleanup);
		
		// Write it to the trace-log
		fwrite(recvData, 1, actualLength, file);
		fclose(file);
		file = NULL;
	}
	
	// Await the final command-flag
	status = flReadChannelAsyncAwait(handle, &recvData, &actualLength, &actualLength, error);
	CHECK_STATUS(status, status, cleanup);

	// Restore old opcode to vbAddr
	status = umdkDirectWriteWord(handle, vbAddr, oldOp, error);
	CHECK_STATUS(status, status, cleanup);

	// Read saved registers, if necessary
	if ( regs ) {
		status = umdkDirectReadBytes(handle, CB_REGS, 18*4, u->bytes, error);
		CHECK_STATUS(status, status, cleanup);
		for ( i = 0; i < 18; i++ ) {
			u->longs[i] = bigEndian32(u->longs[i]);
		}
	}

	if ( debug ) {
		// Read RAM
		status = umdkReadBytes(handle, 0xFF0000, 65536, tmpData, error);
		CHECK_STATUS(status, status, cleanup);
		
		// Save it
		file = fopen("ramAfter.bin", "wb");
		CHECK_STATUS(!file, 13, cleanup, "umdkContWait(): Unable to open ramAfter.bin for writing!");
		fwrite(tmpData, 1, 65536, file);
		fclose(file);
		file = NULL;
	}
cleanup:
	if ( file ) {
		fclose(file);
	}
	return retVal;
}
Beispiel #4
0
int main(int argc, const char *argv[]) {
	int returnCode;
	struct FLContext *handle = NULL;
	FLStatus status;
	const char *error = NULL;
	uint8 byte = 0x10;
	uint8 buf[256];
	bool flag;
	bool isNeroCapable, isCommCapable;
	uint32 fileLen;
	uint8 *buffer = NULL;
	uint32 numDevices, scanChain[16], i;
	const char *vp = NULL, *ivp = NULL, *queryPort = NULL, *portConfig = NULL, *progConfig = NULL, *dataFile = NULL;
	const char *const prog = argv[0];

	printf("FPGALink \"C\" Example Copyright (C) 2011-2013 Chris McClelland\n\n");
	argv++;
	argc--;
	while ( argc ) {
		if ( argv[0][0] != '-' ) {
			unexpected(prog, *argv);
			FAIL(1);
		}
		switch ( argv[0][1] ) {
		case 'h':
			usage(prog);
			FAIL(0);
			break;
		case 'q':
			GET_ARG("q", queryPort, 2);
			break;
		case 'd':
			GET_ARG("d", portConfig, 3);
			break;
		case 'v':
			GET_ARG("v", vp, 4);
			break;
		case 'i':
			GET_ARG("i", ivp, 5);
			break;
		case 'p':
			GET_ARG("p", progConfig, 6);
			break;
		case 'f':
			GET_ARG("f", dataFile, 7);
			break;
		default:
			invalid(prog, argv[0][1]);
			FAIL(8);
		}
		argv++;
		argc--;
	}
	if ( !vp ) {
		missing(prog, "v <VID:PID>");
		FAIL(9);
	}

	status = flInitialise(0, &error);
	CHECK(10);
	
	printf("Attempting to open connection to FPGALink device %s...\n", vp);
	status = flOpen(vp, &handle, NULL);
	if ( status ) {
		if ( ivp ) {
			int count = 60;
			printf("Loading firmware into %s...\n", ivp);
			status = flLoadStandardFirmware(ivp, vp, &error);
			CHECK(11);
			
			printf("Awaiting renumeration");
			flSleep(1000);
			do {
				printf(".");
				fflush(stdout);
				flSleep(100);
				status = flIsDeviceAvailable(vp, &flag, &error);
				CHECK(12);
				count--;
			} while ( !flag && count );
			printf("\n");
			if ( !flag ) {
				fprintf(stderr, "FPGALink device did not renumerate properly as %s\n", vp);
				FAIL(13);
			}
			
			printf("Attempting to open connection to FPGLink device %s again...\n", vp);
			status = flOpen(vp, &handle, &error);
			CHECK(14);
		} else {
			fprintf(stderr, "Could not open FPGALink device at %s and no initial VID:PID was supplied\n", vp);
			FAIL(15);
		}
	}
	
	if ( portConfig ) {
		printf("Configuring ports...\n");
		status = flPortConfig(handle, portConfig, &error);
		CHECK(16);
		flSleep(100);
	}

	isNeroCapable = flIsNeroCapable(handle);
	isCommCapable = flIsCommCapable(handle);
	if ( queryPort ) {
		if ( isNeroCapable ) {
			status = jtagScanChain(handle, queryPort, &numDevices, scanChain, 16, &error);
			CHECK(17);
			if ( numDevices ) {
				printf("The FPGALink device at %s scanned its JTAG chain, yielding:\n", vp);
				for ( i = 0; i < numDevices; i++ ) {
					printf("  0x%08X\n", scanChain[i]);
				}
			} else {
				printf("The FPGALink device at %s scanned its JTAG chain but did not find any attached devices\n", vp);
			}
		} else {
			fprintf(stderr, "JTAG chain scan requested but FPGALink device at %s does not support NeroJTAG\n", vp);
			FAIL(18);
		}
	}

	if ( progConfig ) {
		printf("Executing programming configuration \"%s\" on FPGALink device %s...\n", progConfig, vp);
		if ( isNeroCapable ) {
			status = flProgram(handle, progConfig, NULL, &error);
			CHECK(19);
		} else {
			fprintf(stderr, "Program operation requested but device at %s does not support NeroProg\n", vp);
			FAIL(20);
		}
	}
	
	if ( dataFile ) {
		if ( isCommCapable ) {
			printf("Enabling FIFO mode...\n");
			status = flFifoMode(handle, true, &error);
			CHECK(21);
			printf("Zeroing registers 1 & 2...\n");
			byte = 0x00;
			status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error);
			CHECK(22);
			status = flWriteChannel(handle, 1000, 0x02, 1, &byte, &error);
			CHECK(23);
			
			buffer = flLoadFile(dataFile, &fileLen);
			if ( buffer ) {
				uint16 checksum = 0x0000;
				uint32 i;
				for ( i = 0; i < fileLen; i++ ) {
					checksum += buffer[i];
				}
				printf(
					"Writing %0.2f MiB (checksum 0x%04X) from %s to FPGALink device %s...\n",
					(double)fileLen/(1024*1024), checksum, dataFile, vp);
				status = flWriteChannel(handle, 30000, 0x00, fileLen, buffer, &error);
				CHECK(24);
			} else {
				fprintf(stderr, "Unable to load file %s!\n", dataFile);
				FAIL(25);
			}
			printf("Reading channel 0...");
			status = flReadChannel(handle, 1000, 0x00, 1, buf, &error);
			CHECK(26);
			printf("got 0x%02X\n", buf[0]);
			printf("Reading channel 1...");
			status = flReadChannel(handle, 1000, 0x01, 1, buf, &error);
			CHECK(27);
			printf("got 0x%02X\n", buf[0]);
			printf("Reading channel 2...");
			status = flReadChannel(handle, 1000, 0x02, 1, buf, &error);
			CHECK(28);
			printf("got 0x%02X\n", buf[0]);
		} else {
			fprintf(stderr, "Data file load requested but device at %s does not support CommFPGA\n", vp);
			FAIL(29);
		}
	}
	returnCode = 0;

cleanup:
	if ( error ) {
		fprintf(stderr, "%s\n", error);
		flFreeError(error);
	}
	flFreeFile(buffer);
	flClose(handle);
	return returnCode;
}