Ejemplo n.º 1
0
static void
statemachine(enum state_event ev)
{
        static enum {
                st_off,
                st_power,
                st_ezport_running,
                st_erasing,
                st_programming,
                st_app_running,
        } state = st_off;
        static size_t program_address;
        static struct timeout_ctx t;

        if (state == st_off && ev == ev_button) {
                state = st_power;

                signal_leds(RESULT_UNKNOWN);
                enable_power();
                timeout_add(&t, 10, timeout, NULL);
        } else if (state == st_power && ev == ev_reset) {
                state = st_ezport_running;

                timeout_cancel(&t);
                enable_spi();
                check_status();
        } else if (state == st_ezport_running && ev == ev_cmd_done) {
                /* Is chip bricked? */
                if (ezport_status.fs && ezport_status.bedis)
                        goto error;
                state = st_erasing;

                bulk_erase();
                /* Datasheet 6.4.1.2 */
                timeout_add(&t, 300, timeout, NULL);
        } else if (state == st_erasing && ev == ev_cmd_done) {
                /* if still running, check again */
                if (ezport_status.wip) {
                        check_status();
                        return;
                }

                timeout_cancel(&t);
                program_address = 0;
                state = st_programming;
                goto program;
        } else if (state == st_programming && ev == ev_cmd_done) {
                /* if still running, check again */
                if (ezport_status.wip) {
                        check_status();
                        return;
                }

                timeout_cancel(&t);
                /* repeat if not done */
                if (program_address < (size_t)&_binary_payload_bin_size) {
program:
                        program_address = program_sector(program_address);
                        /* Datasheet 6.4.1.2 */
                        timeout_add(&t, 200, timeout, NULL);
                        return;
                }

                state = st_app_running;
                reset_target();
                timeout_add(&t, 1000, timeout, NULL);
        } else if (state == st_app_running && ev == ev_led) {
                /**
                 * We reset the target here, but because there is a
                 * cap on the reset line, we never see that reset
                 * "edge" (actually an exponential slope).
                 *
                 * Instead, we wait for the LED to blink.
                 */
                state = st_off;

                timeout_cancel(&t);
                signal_leds(RESULT_SUCCESS);
                disable_power();
        } else {
error:
                /* invalid transition */
                state = st_off;
                timeout_cancel(&t);
                signal_leds(RESULT_FAIL);
                disable_power();
        }
}
Ejemplo n.º 2
0
/*******************************************************************************
* Pull EP1 data
*******************************************************************************/
void ep1_pool(void){
	BYTE i;
	WORD adr;
	BYTE new_data = 0;
	
	// Test data for internal test
	if(FPGA_INT0 && FPGA_DONE && !prev_done && !cmd_cnt){
		EP8FIFOCFG = 0x00;  SYNCDELAY;
		FIFORESET = 0x08; SYNCDELAY;
		FIFORESET = 0x00; SYNCDELAY;
		EP8FIFOBUF[0] = 0x12;
		EP8FIFOBUF[1] = 0x34;
		EP8FIFOBUF[2] = 0x56;
		EP8FIFOBUF[3] = 0x78;
		EP8FIFOBUF[4] = 0x90;
		EP8FIFOBUF[5] = 0xAB;
		EP8FIFOBUF[6] = 0xCD;
		EP8FIFOBUF[7] = 0xEF;
		EP8BCH = 0;
		EP8BCL = 8;
		EP8FIFOCFG = 0x10;  SYNCDELAY;
		prev_done = 1;
	}

	if( !( EP1OUTCS & 0x02) ){ 			// Got something
		cmd_cnt++;
		for (i = 0; i < 0x40; i++) 
			EP1INBUF[i] = 0xFF;			// fill output buffer
			
		switch(EP1OUTBUF[0]){			// Decode command
			//-----------------------------------------------------------------
			default:
			case	CMD_READ_VERSION:
				EP1INBUF[0] = fx2_ver_maj_;
				EP1INBUF[1] = fx2_ver_min_;
				EP1INBUF[2] = fx2_tip_maj_;
				EP1INBUF[3] = fx2_tip_min_;
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case	CMD_SET_AUTORESPONSE:
				sts_int_auto_configured = 1;
				iar_adress = EP1OUTBUF[1];
				iar_count = EP1OUTBUF[2];
				iar_int_idx = 0;
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case	CMD_GET_AUTORESPONSE:
				EP1INBUF[0] = iar_int_idx;
				for(i = 0; i < 32; i++)
					EP1INBUF[i+1] = auto_response_data[i];
				iar_int_idx = 0;
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case	CMD_SWITCH_MODE:
				sts_current_mode = 1;
				new_data = 1;
				EP1INBUF[0] = EP1OUTBUF[1];
				break;
			//-----------------------------------------------------------------
			case	CMD_READ_STATUS:
				sts_flash_busy = get_flash_busy();
				sts_booting = FPGA_DONE;
				sts_fpga_prog = 0xaa;
				sts_high_speed_mode = (USBCS & bmHSM) ? 1 : 255;
				new_data = 1;					
				EP1INBUF[0] = sts_fifo_error;
				EP1INBUF[1] = sts_current_mode;
				EP1INBUF[2] = sts_flash_busy;
				EP1INBUF[3] = sts_fpga_prog;
				EP1INBUF[4] = sts_booting;
				EP1INBUF[5] = sts_i2c_new_data;
				EP1INBUF[6] = sts_int_auto_configured;
				EP1INBUF[7] = sts_high_speed_mode;
				sts_i2c_new_data = 0;
				break;
			//-----------------------------------------------------------------
			case CMD_RESET_FIFO_STATUS:
				sts_fifo_error = 0;
				FIFORESET = 0x80;  SYNCDELAY;  // NAK all requests from host.
				switch(EP1OUTBUF[1]){
					case 2:
						EP2FIFOCFG = 0x48;  SYNCDELAY;
						FIFORESET = 0x02;  SYNCDELAY;
						break;
					case 4:
						EP4FIFOCFG = 0x48;  SYNCDELAY;
						FIFORESET = 0x04;  SYNCDELAY;
						break;
					case 6:
						EP6FIFOCFG = 0x48;  SYNCDELAY;
						FIFORESET = 0x06;  SYNCDELAY;
						break;
					default:	// 0
						EP2FIFOCFG = 0x48;  SYNCDELAY;
						EP4FIFOCFG = 0x48;  SYNCDELAY;
						EP6FIFOCFG = 0x48;  SYNCDELAY;
						EP8FIFOCFG = 0x10;  SYNCDELAY;
						FIFORESET = 0x02;  SYNCDELAY;
						FIFORESET = 0x04;  SYNCDELAY;
						FIFORESET = 0x06;  SYNCDELAY;
				}
				FIFORESET = 0x00;  SYNCDELAY;	// Resume normal operation.
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_FLASH_WRITE:
				if (EP1OUTBUF[4] > 59) EP1OUTBUF[4] = 59;
				page_write(EP1OUTBUF[1], EP1OUTBUF[2], EP1OUTBUF[3], &EP1OUTBUF[5], EP1OUTBUF[4]);	//highest, high, low adr, read_ptr, size
			//-----------------------------------------------------------------
			case CMD_FLASH_READ:					
				if (EP1OUTBUF[4] > 64) EP1OUTBUF[4] = 64;
				page_read(EP1OUTBUF[1], EP1OUTBUF[2], EP1OUTBUF[3], &EP1INBUF[0], EP1OUTBUF[4]);		//highest, high, low adr, read_ptr, size
				new_data = 1;
				break;			
			//-----------------------------------------------------------------
			case CMD_FLASH_ERASE:
				// busy_polling();	
				// On some modules it cause API error - better to do it from software side
				bulk_erase();
				new_data = 1;
				sts_flash_busy = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_SECTOR_ERASE:
				sector_erase(EP1OUTBUF[1]);
				new_data = 1;
				sts_flash_busy = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_FLASH_WRITE_COMMAND:
				EP1INBUF[0] = 0x55;
				spi_command(EP1OUTBUF[1], &EP1OUTBUF[3], EP1OUTBUF[2], &EP1INBUF[1]);
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_EEPROM_WRITE:					
				adr = EP1OUTBUF[1];
				adr = (adr << 8) + EP1OUTBUF[2];
				if (EP1OUTBUF[3] > 32) EP1OUTBUF[3] = 32;				
				EEPROMWrite(adr, EP1OUTBUF[3], &EP1OUTBUF[4]);	// adress, size, data
			//-----------------------------------------------------------------
			case CMD_EEPROM_READ:
				adr = EP1OUTBUF[1];
				adr = (adr << 8) + EP1OUTBUF[2];
				EEPROMRead(adr, EP1OUTBUF[3], &EP1INBUF[0]);	// adress, size, data
				new_data = 1;
				break;			
			//-----------------------------------------------------------------
			case CMD_GET_FIFO_STATUS:
				EP1INBUF[0] = EP2CS;
				EP1INBUF[1] = EP4CS;
				EP1INBUF[2] = EP6CS;
				EP1INBUF[3] = EP8CS;
				EP1INBUF[4] = EP2FIFOBCH;
				EP1INBUF[5] = EP4FIFOBCH;
				EP1INBUF[6] = EP6FIFOBCH;
				EP1INBUF[7] = EP8FIFOBCH;
				EP1INBUF[8] = EP2FIFOBCL;
				EP1INBUF[9] = EP4FIFOBCL;
				EP1INBUF[10] = EP6FIFOBCL;
				EP1INBUF[11] = EP8FIFOBCL;
				EP1INBUF[12] = EP2FIFOFLGS;
				EP1INBUF[13] = EP4FIFOFLGS;
				EP1INBUF[14] = EP6FIFOFLGS;
				EP1INBUF[15] = EP8FIFOFLGS;
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_I2C_WRITE:
				I2CWrite(EP1OUTBUF[1], EP1OUTBUF[2], &EP1OUTBUF[3]);	// adress, size, data
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_I2C_READ:
				I2CRead(EP1OUTBUF[1], EP1OUTBUF[2], &EP1INBUF[0]);	// adress, size, data
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			/*
			case CMD_I2C_WRITE_READ:
				i = EP1OUTBUF[1];
				I2CWrite(i, EP1OUTBUF[2], &EP1OUTBUF[4]);	// adress, size, data
				delaycnt = 0;
				while (INT0_PIN == 0){
					EZUSB_Delay1ms();
					delaycnt++;
					if (delaycnt > 800)
						break;
					continue;
				}
				I2CRead(i, EP1OUTBUF[3], &EP1INBUF[0]);	// adress, size, data					
				new_data = 1;
				break;
			*/
			//-----------------------------------------------------------------
			case CMD_FPGA_POWER:
				if (EP1OUTBUF[1] == 0){
					FPGA_POWER = 0;
					sts_int_auto_configured = 0;
				}
				else{
					IOD = 0x03;	// Enable Power and disable Reset
					OED = 0x03;	// PROG_B and POWER
					FPGA_POWER = 1;
				}
				EP1INBUF[0] = (FPGA_POWER) ? 1 : 0;
				EP1INBUF[1] = 0xAA;
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_FPGA_RESET:
				FPGA_INT1 = (EP1OUTBUF[1]) ? 1 : 0;
				EP1INBUF[0] = FPGA_INT1;
				EP1INBUF[1] = 0xAA;
				new_data = 1;
				break;
			//-----------------------------------------------------------------
			case CMD_DEV_LOCK:
				if(EP1OUTBUF[1] == 0x01){	// Driver trying to lock device
					if(lock == 0){		// Device is free
						EP1INBUF[0] = 0x22;	// Sucessfull lock
						lock = 1;
					}
					else				// Device is locked
						EP1INBUF[0] = 0x00;	// Already locked
				}
				else{						// Driver trying to unlock device
					if(lock == 1){		// Device is locked
						EP1INBUF[0] = 0x33;	// Sucessfull unlock
						lock = 0;
					}
					else				// Device is unlocked
						EP1INBUF[0] = 0x00;	// Got problem
				}
				new_data = 1;
				break;		
			//-----------------------------------------------------------------
		}
		EP1OUTBC = EP1DATA_COUNT;		// Free input buffer
	}

	if(new_data){						// Have something to send
		if ( !(EP1INCS & 0x02)){		// Can send ?
			EP1INBC = EP1DATA_COUNT;	// Send
			new_data = 0;
		}
	}
}
Ejemplo n.º 3
0
void ProcessIO(void)
{
	char oldPGDtris;
	char PIN;
	static byte counter=0;
	int nBytes;
	unsigned long address;
	unsigned char i;
	
	input_buffer[0]=UART1RX(); //USBGenRead((byte*)input_buffer,64);
//	if(nBytes>0)
//	{
		switch(input_buffer[0])
		{
			case CMD_ERASE:
				setLeds(LEDS_ON | LEDS_WR);
				getBytes(1,1);//get more data, #bytes, where to insert in input buffer array
				output_buffer[0]=bulk_erase(picfamily,pictype,input_buffer[1]);
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_READ_ID:
				setLeds(LEDS_ON | LEDS_RD);
				switch(picfamily)
				{
					case DSPIC30:
						read_code(picfamily,pictype,0xFF0000,(unsigned char*)output_buffer,2,3);
						break;
					case PIC18:
						read_code(picfamily,pictype,0x3FFFFE,(unsigned char*)output_buffer,2,3);  //devid is at location 0x3ffffe   for PIC18 devices
						break;
					case PIC16:
						set_vdd_vpp(picfamily, pictype, 0);
						read_code(picfamily,pictype,0x2006,(unsigned char*)output_buffer,2,3);  //devid is at location 0x2006  for PIC16 devices
						break;
				}
				counter=2;
				setLeds(LEDS_ON);
				break;
			case CMD_WRITE_CODE:
				setLeds(LEDS_ON | LEDS_WR);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				output_buffer[0]=write_code(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]);
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_READ_CODE:
				setLeds(LEDS_ON | LEDS_RD);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				read_code(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]);
				counter=input_buffer[1];
				setLeds(LEDS_ON);
				break;
			case CMD_WRITE_DATA:
				setLeds(LEDS_ON | LEDS_WR);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				output_buffer[0]=write_data(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); 
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_READ_DATA:
				setLeds(LEDS_ON | LEDS_RD);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				read_data(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]); 
				counter=input_buffer[1];
				setLeds(LEDS_ON);
				break;
			case CMD_WRITE_CONFIG:
				setLeds(LEDS_ON | LEDS_WR);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				output_buffer[0]=write_config_bits(picfamily, pictype, address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]);
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_SET_PICTYPE:
				output_buffer[0]=set_pictype(input_buffer+1);
				//output_buffer[0]=1; //Ok
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_FIRMWARE_VERSION:
				for(counter=0; counter<18; counter++)output_buffer[counter]=upp_version[counter];
				counter=18;
				setLeds(LEDS_ON);
				break;
			case CMD_DEBUG:
				setLeds(LEDS_ON | LEDS_WR | LEDS_RD);
				switch(input_buffer[1])
				{
					case 0:
						set_vdd_vpp(dsP30F, DSPIC30, 1);
						output_buffer[0]=1;
						counter=1;	
						break;
					case 1:
						set_vdd_vpp(dsP30F, DSPIC30, 0);
						output_buffer[0]=1;
						counter=1;	
						break;
					case 2:
						dspic_send_24_bits(((unsigned long)input_buffer[2])|
								((unsigned long)input_buffer[3])<<8|
								((unsigned long)input_buffer[4])<<16);
						output_buffer[0]=1;
						counter=1;
						break;
					case 3:
						nBytes =  dspic_read_16_bits();
						output_buffer[0]=(unsigned char)nBytes;
						output_buffer[1]=(unsigned char)(nBytes>>8);
						counter=2;
						break;
						
				}
				break;
			case CMD_GET_PIN_STATUS:
				switch(input_buffer[1])
				{
					case SUBCMD_PIN_PGC:
						if((!TRISPGC_LOW)&&(!PGC_LOW)) //3.3V levels
						{
							if(PGC) output_buffer[0] = PIN_STATE_3_3V;
							else output_buffer[0] = PIN_STATE_0V;
						}
						else	//5V levels
						{
							if(PGC) output_buffer[0] = PIN_STATE_5V;
							else output_buffer[0] = PIN_STATE_0V;
						}
						counter=1;
						break;
					case SUBCMD_PIN_PGD:
						if(TRISPGD)//PGD is input
						{
							if(PGD_READ) output_buffer[0] = PIN_STATE_5V;
							else output_buffer[0] = PIN_STATE_0V;
						}
						else
						{							
							if((!TRISPGD_LOW)&&(!PGD_LOW)) //3.3V levels
							{
								if(PGD) output_buffer[0] = PIN_STATE_3_3V;
								else output_buffer[0] = PIN_STATE_0V;
							}
							else	//5V levels
							{
								if(PGD) output_buffer[0] = PIN_STATE_5V;
								else output_buffer[0] = PIN_STATE_0V;
							}
						}
						counter=1;
						break;
					case SUBCMD_PIN_VDD:
						//if(VDD) output_buffer[0] = PIN_STATE_FLOAT;
						//else output_buffer[0] = PIN_STATE_5V;
						output_buffer[0] = PIN_STATE_5V;
						counter = 1;
						break;
					case SUBCMD_PIN_VPP:
						counter=1;
						if(!VPP){output_buffer[0] = PIN_STATE_12V;break;}
						if(VPP_RST){output_buffer[0] = PIN_STATE_0V;break;}
						if(VPP_RUN){output_buffer[0] = PIN_STATE_5V;break;}
						output_buffer[0] = PIN_STATE_FLOAT;
						break;
					case SUBCMD_PIN_VPP_VOLTAGE:
						ReadAdc(output_buffer);
						counter=2;
						break;
					default:
						output_buffer[0]=3;
						counter=1;
						break;
				}
				break;
			case CMD_SET_PIN_STATUS:
				switch(input_buffer[1])
				{
					case SUBCMD_PIN_PGC:
						switch(input_buffer[2])
						{
							case PIN_STATE_0V:
								TRISPGC = 0;
								PGC = 0;
								TRISPGC_LOW = 1;
								PGC_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_3_3V:
								TRISPGC = 0;
								PGC = 1;
								TRISPGC_LOW = 0;
								PGC_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_5V:
								TRISPGC = 0;
								PGC = 1;
								TRISPGC_LOW = 1;
								PGC_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					case SUBCMD_PIN_PGD:
						switch(input_buffer[2])
						{
							case PIN_STATE_0V:
								TRISPGD = 0;
								PGD = 0;
								TRISPGD_LOW = 1;
								PGD_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_3_3V:
								TRISPGD = 0;
								PGD = 1;
								TRISPGD_LOW = 0;
								PGD_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_5V:
								TRISPGD = 0;
								PGD = 1;
								TRISPGD_LOW = 1;
								PGD_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_INPUT:
								TRISPGD_LOW = 1;
								TRISPGD = 1;
								output_buffer[0]=1;//ok
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					case SUBCMD_PIN_VDD:
						switch(input_buffer[2])
						{
							case PIN_STATE_5V:
								//VDD = 0;
								output_buffer[0]=1;
								break;
							case PIN_STATE_FLOAT:
								//VDD = 1;
								output_buffer[0]=1;
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					case SUBCMD_PIN_VPP:
						switch(input_buffer[2])
						{
							case PIN_STATE_0V:
								VPP = 1;
								VPP_RST = 1;
								VPP_RUN = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_5V:
								VPP = 1;
								VPP_RST = 0;
								VPP_RUN = 1;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_12V:
								VPP = 0;
								VPP_RST = 0;
								VPP_RUN = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_FLOAT:
								VPP = 1;
								VPP_RST = 0;
								VPP_RUN = 0;
								output_buffer[0]=1;//ok
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					default:
						output_buffer[0]=3;
				}
				counter=1;
				break;
		}
	//} //if nBytes>0
	if(counter != 0)
	{
		//if(!mUSBGenTxIsBusy())
		//USBGenWrite((byte*)&output_buffer,counter);
		for(i=0; i<counter; i++) UART1TX(output_buffer[i]);
		counter=0;
	}
}//end ProcessIO
Ejemplo n.º 4
0
void ProcessIO(void)
{
	char oldPGDtris;
	char PIN;
	static byte counter=0;
	int nBytes;
	unsigned long address;
	
	// When the device is plugged in, the leds give the numbers 1, 2, 3, 4, 5. 
	//After configured state, the leds are controlled by the next lines in this function
	if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1))
	{
		BlinkUSBStatus();
		return;
	}
	

	nBytes=USBGenRead((byte*)input_buffer,64);
	if(nBytes>0)
	{
		switch(input_buffer[0])
		{
			case CMD_ERASE:
				setLeds(LEDS_ON | LEDS_WR);
				output_buffer[0]=bulk_erase(picfamily,pictype,input_buffer[1]);
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_READ_ID:
				setLeds(LEDS_ON | LEDS_RD);
				switch(picfamily)
				{
					case PIC24:
					case dsPIC30:
						read_code(picfamily,pictype,0xFF0000,(unsigned char*)output_buffer,2,3);
						break;
					case PIC18:
					case PIC18J:
					case PIC18K:
						read_code(picfamily,pictype,0x3FFFFE,(unsigned char*)output_buffer,2,3);  //devid is at location 0x3ffffe   for PIC18 devices
						break;
					case PIC16:
						set_vdd_vpp(picfamily, pictype, 0);
						read_code(picfamily,pictype,0x2006,(unsigned char*)output_buffer,2,3);  //devid is at location 0x2006  for PIC16 devices
						break;
				}
				counter=2;
				setLeds(LEDS_ON);
				break;
			case CMD_WRITE_CODE:
				setLeds(LEDS_ON | LEDS_WR);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				output_buffer[0]=write_code(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]);
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_READ_CODE:
				setLeds(LEDS_ON | LEDS_RD);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				PIN=read_code(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]);
				if(PIN==3)output_buffer[0]=0x3;
				counter=input_buffer[1];
				setLeds(LEDS_ON);
				break;
			case CMD_WRITE_DATA:
				setLeds(LEDS_ON | LEDS_WR);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				output_buffer[0]=write_data(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); 
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_READ_DATA:
				setLeds(LEDS_ON | LEDS_RD);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				read_data(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]); 
				counter=input_buffer[1];
				setLeds(LEDS_ON);
				break;
			case CMD_WRITE_CONFIG:
				setLeds(LEDS_ON | LEDS_WR);
				address=((unsigned long)input_buffer[2])<<16|
						((unsigned long)input_buffer[3])<<8|
						((unsigned long)input_buffer[4]);
				output_buffer[0]=write_config_bits(picfamily, pictype, address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]);
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_SET_PICTYPE:
				output_buffer[0]=set_pictype(input_buffer+1);
				//output_buffer[0]=1; //Ok
				counter=1;
				setLeds(LEDS_ON);
				break;
			case CMD_FIRMWARE_VERSION:
				strcpypgm2ram((char*)output_buffer,(const far rom char*)upp_version);
				counter=18;
				setLeds(LEDS_ON);

				break;
			case CMD_DEBUG:
				setLeds(LEDS_ON | LEDS_WR | LEDS_RD);
				switch(input_buffer[1])
				{
					case 0:
						set_vdd_vpp(dsP30F, dsPIC30, 1);
						output_buffer[0]=1;
						counter=1;	
						break;
					case 1:
						set_vdd_vpp(dsP30F, dsPIC30, 0);
						output_buffer[0]=1;
						counter=1;	
						break;
					case 2:
						dspic_send_24_bits(((unsigned long)input_buffer[2])|
								((unsigned long)input_buffer[3])<<8|
								((unsigned long)input_buffer[4])<<16);
						output_buffer[0]=1;
						counter=1;
						break;
					case 3:
						nBytes =  dspic_read_16_bits(1);
						output_buffer[0]=(unsigned char)nBytes;
						output_buffer[1]=(unsigned char)(nBytes>>8);
						counter=2;
						break;
						
				}
				break;
			case CMD_GET_PIN_STATUS:
				switch(input_buffer[1])
				{
					case SUBCMD_PIN_PGC:
						if((!TRISPGC_LOW)&&(!PGC_LOW)) //3.3V levels
						{
							if(PGC) output_buffer[0] = PIN_STATE_3_3V;
							else output_buffer[0] = PIN_STATE_0V;
						}
						else	//5V levels
						{
							if(PGC) output_buffer[0] = PIN_STATE_5V;
							else output_buffer[0] = PIN_STATE_0V;
						}
						counter=1;
						break;
					case SUBCMD_PIN_PGD:
						if(TRISPGD)//PGD is input
						{
							if(PGD_READ) output_buffer[0] = PIN_STATE_5V;
							else output_buffer[0] = PIN_STATE_0V;
						}
						else
						{							
							if((!TRISPGD_LOW)&&(!PGD_LOW)) //3.3V levels
							{
								if(PGD) output_buffer[0] = PIN_STATE_3_3V;
								else output_buffer[0] = PIN_STATE_0V;
							}
							else	//5V levels
							{
								if(PGD) output_buffer[0] = PIN_STATE_5V;
								else output_buffer[0] = PIN_STATE_0V;
							}
						}
						counter=1;
						break;
					case SUBCMD_PIN_VDD:
						if(VDD) output_buffer[0] = PIN_STATE_FLOAT;
						else output_buffer[0] = PIN_STATE_5V;
						counter = 1;
						break;
					case SUBCMD_PIN_VPP:
						counter=1;
						if(!VPP){output_buffer[0] = PIN_STATE_12V;break;}
						if(VPP_RST){output_buffer[0] = PIN_STATE_0V;break;}
						if(VPP_RUN){output_buffer[0] = PIN_STATE_5V;break;}
						output_buffer[0] = PIN_STATE_FLOAT;
						break;
					case SUBCMD_PIN_VPP_VOLTAGE:
						ReadAdc(output_buffer);
						counter=2;
						break;
					default:
						output_buffer[0]=3;
						counter=1;
						break;
				}
				break;
			case CMD_SET_PIN_STATUS:
				switch(input_buffer[1])
				{
					case SUBCMD_PIN_PGC:
						switch(input_buffer[2])
						{
							case PIN_STATE_0V:
								TRISPGC = 0;
								PGC = 0;
								TRISPGC_LOW = 1;
								PGC_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_3_3V:
								TRISPGC = 0;
								PGC = 1;
								TRISPGC_LOW = 0;
								PGC_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_5V:
								TRISPGC = 0;
								PGC = 1;
								TRISPGC_LOW = 1;
								PGC_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					case SUBCMD_PIN_PGD:
						switch(input_buffer[2])
						{
							case PIN_STATE_0V:
								TRISPGD = 0;
								PGD = 0;
								TRISPGD_LOW = 1;
								PGD_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_3_3V:
								TRISPGD = 0;
								PGD = 1;
								TRISPGD_LOW = 0;
								PGD_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_5V:
								TRISPGD = 0;
								PGD = 1;
								TRISPGD_LOW = 1;
								PGD_LOW = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_INPUT:
								TRISPGD_LOW = 1;
								TRISPGD = 1;
								output_buffer[0]=1;//ok
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					case SUBCMD_PIN_VDD:
						switch(input_buffer[2])
						{
							case PIN_STATE_5V:
								VDD = 0;
								output_buffer[0]=1;
								break;
							case PIN_STATE_FLOAT:
								VDD = 1;
								output_buffer[0]=1;
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					case SUBCMD_PIN_VPP:
						switch(input_buffer[2])
						{
							case PIN_STATE_0V:
								VPP = 1;
								VPP_RST = 1;
								VPP_RUN = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_5V:
								VPP = 1;
								VPP_RST = 0;
								VPP_RUN = 1;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_12V:
								VPP = 0;
								VPP_RST = 0;
								VPP_RUN = 0;
								output_buffer[0]=1;//ok
								break;
							case PIN_STATE_FLOAT:
								VPP = 1;
								VPP_RST = 0;
								VPP_RUN = 0;
								output_buffer[0]=1;//ok
								break;
							default:
								output_buffer[0]=3;
								break;
						}
						break;
					default:
						output_buffer[0]=3;
				}
				counter=1;
				break;
		}
	}
	if(counter != 0)
	{
		if(!mUSBGenTxIsBusy())
		USBGenWrite((byte*)&output_buffer,counter);
		counter=0;
	}
}//end ProcessIO