Exemplo n.º 1
0
/**
    Open a power meter probe by a given serial number

    \param pm a pointer to a pm_context
    \param serial the serial number

    \retval  0 - all fine
    \retval -1 - open failed (wrong serial number?)
    \retval -2 - setting baudrate failed
    \retval -3 - setting data characteristics failed
    \retval -4 - setting flow control failed
    \retval -5 - setting timeouts failed
    \retval -6 - purging buffers failed
    \retval -7 - resetting device failed
*/
PM600X_EXPORT int pm_open(struct pm_context *pm, unsigned long serial)
{
	FT_STATUS ftstat;

	// convert the serial into a 8 digit string with leading zeroes
	char serial_string[12];
	snprintf(serial_string, 12, "%06lu", serial);

	// open the device by a given serial number
	ftstat = FT_OpenEx((void *)serial_string, FT_OPEN_BY_SERIAL_NUMBER, &pm->handle);
	if (ftstat != FT_OK)
		pm_error_return(-1, "open failed (wrong serial number?)");

	// get the device info to obtain the power meter type
	unsigned long id;
	ftstat = FT_GetDeviceInfo(pm->handle, NULL, &id, NULL, NULL, NULL);
	if (ftstat != FT_OK)
		pm_error_return(-8, "can not retrieve device info!");

	pm->type = id;

	// set baud rate to 115200
	ftstat = FT_SetBaudRate(pm->handle, FT_BAUD_115200);
	if (ftstat != FT_OK)
		pm_error_return(-2, "setting baudrate failed");

	// set data characteristics to 8n1
	ftstat = FT_SetDataCharacteristics(pm->handle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
	if (ftstat != FT_OK)
		pm_error_return(-3, "setting data characteristics failed");

	// set flow control to NONE
	ftstat = FT_SetFlowControl(pm->handle, FT_FLOW_NONE, 0, 0);
	if (ftstat != FT_OK)
		pm_error_return(-4, "setting flow control failed");

	// set timeouts to 1 second for writes and 3.5 seconds for reads. This should be enough when measuring with averaging == 10000
	ftstat = FT_SetTimeouts(pm->handle, 3500, 1000);
	if (ftstat != FT_OK)
		pm_error_return(-5, "setting timeouts failed");

	// purge bufffers just in case
	ftstat = FT_Purge(pm->handle, FT_PURGE_RX | FT_PURGE_TX);
	if (ftstat != FT_OK)
		pm_error_return(-6, "purging buffers failed");

	// reset the device via *RST
	return pm_reset(pm);
}
Exemplo n.º 2
0
bool CKMotionIO::RequestedDeviceAvail(char *Reason)
{
	FT_STATUS ftStatus;
	FT_DEVICE ftDevice;
	DWORD deviceID;
	int i, numDevs, list[MAX_BOARDS];
	char SerialNumber[16]; 
	char Description[64]; 

	Mutex->Lock();
	
	// fill the list with -1 because driver
	// leaves the entries for open drivers unchanged

	for (i=0; i<16; i++) list[i]=-1;

	numDevs=-1;

	ftStatus = FT_ListDevices(list,&numDevs,FT_LIST_ALL|FT_OPEN_BY_LOCATION);
	
	if (numDevs==0)
	{
		Mutex->Unlock();
		if (Reason) strcpy(Reason,"No KMotion devices available");
		return false;
	}

	if (numDevs < 1 || numDevs >= MAX_BOARDS) 
	{
		Mutex->Unlock();
		if (Reason) strcpy(Reason,"No KMotion devices available");
		return false;
	}

	// go through the list and remove any non-dynomotion boards
	for (i=0; i<numDevs; i++)
	{
		if (list[i] != -1)
		{
			ftStatus = FT_OpenEx((void *)list[i], FT_OPEN_BY_LOCATION, &ftHandle); 

			if(ftStatus != FT_OK)
			{ 
			   // FT_Open failed 
			   list[i] = -1;  // mark as unusable 
			} 
			else
			{
				ftStatus = FT_GetDeviceInfo( 
					  ftHandle, 
					  &ftDevice, 
					  &deviceID, 
					  SerialNumber, 
					  Description, 
					  NULL 
					  ); 

				if (ftStatus == FT_OK) 
				{
					FT_Close(ftHandle);

					if (strstr(Description,"KFLOP")== NULL &&
						strstr(Description,"KMotion")== NULL &&
						strstr(Description,"Dynomotion")== NULL)
					{
						// remove it from the list
						for (int k=i+1; k<numDevs; k++)
							list[k-1] = list[k];  // shift up
						
						numDevs--;
						i--; // redo this slot since it was deleted and things shifted up
					}
				}
			}
		}
	}


	// if USB Location is undefined select the first from
	// the list that is not already taken

	if (!BoardIDAssigned)
	{
		for (i=0; i<numDevs && !BoardIDAssigned; i++)
		{
			if (list[i] != -1)
			{
				int k;
				// make sure nobody is already using this one
				for (k=0; k<MAX_BOARDS; k++)
				{
					if (list[i]==KMotionLocal.KMotionIO[k].USB_Loc_ID)
						break;
				}
				if (k==MAX_BOARDS)
				{
					BoardIDAssigned=true;
					USB_Loc_ID=list[i];  // assign it
				}
			}
		}
		if (!BoardIDAssigned)
		{
			Mutex->Unlock();
			if (Reason) strcpy(Reason,"No KMotion devices available");
			return false;
		}
	}

	// user wants a specific usb location
	// so see if it is available

	for (i=0; i<numDevs; i++)
	{
		if (list[i]==USB_Loc_ID)
			break;
	}

	if (i==numDevs)
	{
		Mutex->Unlock();
		if (Reason) sprintf(Reason,"KMotion not found on USB Location %08X\r\r"
								   "Unable to open device",USB_Loc_ID);
		return false;
	}

	Mutex->Unlock();
	return true;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
	FT_STATUS	ftStatus;
	FT_HANDLE	ftHandle0;
	int iport;
	FT_PROGRAM_DATA Data;
	FT_DEVICE	ftDevice; 
	
	if(argc > 1) {
		sscanf(argv[1], "%d", &iport);
	}
	else {
		iport = 0;
	}
	printf("opening port %d\n", iport);
	FT_SetVIDPID(0x0403, 0x6017);
	ftStatus = FT_Open(iport, &ftHandle0);
	
	if(ftStatus != FT_OK) {
		/* 
			This can fail if the ftdi_sio driver is loaded
		 	use lsmod to check this and rmmod ftdi_sio to remove
			also rmmod usbserial
		 */
		printf("FT_Open(%d) failed\n", iport);
		return 1;
	}

	printf("ftHandle0 = %p\n", ftHandle0);

		ftStatus = FT_GetDeviceInfo( 
				ftHandle0, 
				&ftDevice, 
				NULL, 
				NULL, 
				NULL, 
				NULL 
				); 

	if (ftStatus != FT_OK) { 
		printf("FT_GetDeviceType FAILED!\n");
		return 1;
	}  

	if (ftDevice == FT_DEVICE_BM) {

		Data.Signature1 = 0x00000000;
		Data.Signature2 = 0xffffffff;
		Data.VendorId = 0x0403;				
		Data.ProductId = 0x6001;
		Data.Manufacturer =  "FTDI";
		Data.ManufacturerId = "FT";
		Data.Description = "USB <-> Srial";
		Data.SerialNumber = "FT000001";		// if fixed, or NULL
		
		Data.MaxPower = 44;
		Data.PnP = 1;
		Data.SelfPowered = 0;
		Data.RemoteWakeup = 1;
		Data.Rev4 = 1;
		Data.IsoIn = 0;
		Data.IsoOut = 0;
		Data.PullDownEnable = 1;
		Data.SerNumEnable = 1;
		Data.USBVersionEnable = 0;
		Data.USBVersion = 0x110;

	}
	else if (ftDevice == FT_DEVICE_232R) {

		Data.Signature1 = 0x00000000;
		Data.Signature2 = 0xffffffff;
		Data.Version = 2;
		Data.VendorId = 0x0403;				
		Data.ProductId = 0x6001 ;
		Data.Manufacturer =  "FTDI";
		Data.ManufacturerId = "FT";
		Data.Description = "USB <-> Serial";
		Data.SerialNumber = "FT000008";		// if fixed, or NULL
		
		Data.MaxPower = 100;
		Data.PnP = 1;
		Data.SelfPowered = 0;
		Data.RemoteWakeup = 1;
			
		Data.UseExtOsc = 0x00;			// Use External Oscillator
		Data.HighDriveIOs = 0x00;			// High Drive I/Os
		Data.EndpointSize = 0x40;			// Endpoint size

		Data.PullDownEnableR = 0x00;		// non-zero if pull down enabled
		Data.SerNumEnableR = 0x01;		// non-zero if serial number to be used

		Data.InvertTXD = 0x00;			// non-zero if invert TXD
		Data.InvertRXD = 0x00;			// non-zero if invert RXD
		Data.InvertRTS = 0x00;			// non-zero if invert RTS
		Data.InvertCTS = 0x00;			// non-zero if invert CTS
		Data.InvertDTR = 0x00;			// non-zero if invert DTR
		Data.InvertDSR = 0x00;			// non-zero if invert DSR
		Data.InvertDCD = 0x00;			// non-zero if invert DCD
		Data.InvertRI = 0x00;				// non-zero if invert RI

		Data.Cbus0 = 0x02;				// Cbus Mux control
		Data.Cbus1 = 0x03;				// Cbus Mux control
		Data.Cbus2 = 0x01;				// Cbus Mux control
		Data.Cbus3 = 0x01;				// Cbus Mux control
		Data.Cbus4 = 0x05;				// Cbus Mux control

		Data.RIsD2XX = 0;				// non-zero if using VCP drivers

	}
	else if (ftDevice == FT_DEVICE_2232C) {

		Data.Signature1 = 0x00000000;
		Data.Signature2 = 0xffffffff;
		Data.VendorId = 0x0403;				
		Data.ProductId = 0x6010;
		Data.Manufacturer =  "FTDI";
		Data.ManufacturerId = "FT";
		Data.Description = "USB <-> Serial";
		Data.SerialNumber = "FT123442";		// if fixed, or NULL
		
		Data.MaxPower = 200;
		Data.PnP = 1;
		Data.SelfPowered = 0;
		Data.RemoteWakeup = 0;

		Data.Rev5 = 1;					// non-zero if Rev5 chip, zero otherwise
		Data.IsoInA = 0;				// non-zero if in endpoint is isochronous
		Data.IsoInB = 0;				// non-zero if in endpoint is isochronous
		Data.IsoOutA = 0;				// non-zero if out endpoint is isochronous
		Data.IsoOutB = 0;				// non-zero if out endpoint is isochronous
		Data.PullDownEnable5 = 0;		// non-zero if pull down enabled
		Data.SerNumEnable5 = 1;			// non-zero if serial number to be used
		Data.USBVersionEnable5 = 0;		// non-zero if chip uses USBVersion
		Data.USBVersion5 = 0x0200;		// BCD (0x0200 => USB2)
		Data.AIsHighCurrent = 0;		// non-zero if interface is high current
		Data.BIsHighCurrent = 0;		// non-zero if interface is high current
		Data.IFAIsFifo = 0;				// non-zero if interface is 245 FIFO
		Data.IFAIsFifoTar = 0;			// non-zero if interface is 245 FIFO CPU target
		Data.IFAIsFastSer = 0;			// non-zero if interface is Fast serial
		Data.AIsVCP = 0;				// non-zero if interface is to use VCP drivers
		Data.IFBIsFifo = 0;				// non-zero if interface is 245 FIFO
		Data.IFBIsFifoTar = 0;			// non-zero if interface is 245 FIFO CPU target
		Data.IFBIsFastSer = 0;			// non-zero if interface is Fast serial
		Data.BIsVCP = 0;				// non-zero if interface is to use VCP drivers

	}								

	ftStatus = FT_EE_Program(ftHandle0, &Data);
	if(ftStatus != FT_OK) {
		printf("FT_EE_Program failed (%d)\n", ftStatus);
	}
	FT_Close(ftHandle0);
	return 0;
}
Exemplo n.º 4
0
static int presto_open_ftd2xx(char *req_serial)
{
	uint32_t i;
	DWORD numdevs;
	DWORD vidpid;
	char devname[FT_DEVICE_NAME_LEN];
	FT_DEVICE device;

	BYTE presto_data;
	DWORD ftbytes;

	presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;

#if IS_WIN32 == 0
	/* Add non-standard Vid/Pid to the linux driver */
	presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID);
	if (presto->status != FT_OK) {
		LOG_ERROR("couldn't add PRESTO VID/PID");
		exit(-1);
	}
#endif

	presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY);
	if (presto->status != FT_OK) {
		LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto->status));
		return ERROR_JTAG_DEVICE_ERROR;
	}

	LOG_DEBUG("FTDI devices available: %" PRIu32, (uint32_t)numdevs);
	for (i = 0; i < numdevs; i++) {
		presto->status = FT_Open(i, &(presto->handle));
		if (presto->status != FT_OK) {
			/* this is not fatal, the device may be legitimately open by other process,
			 *hence debug message only */
			LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto->status));
			continue;
		}
		LOG_DEBUG("FTDI device %i open", (int)i);

		presto->status = FT_GetDeviceInfo(presto->handle, &device,
				&vidpid, presto->serial, devname, NULL);
		if (presto->status == FT_OK) {
			if (vidpid == PRESTO_VID_PID && (req_serial == NULL ||
					!strcmp(presto->serial, req_serial)))
				break;
		} else
			LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(
					presto->status));

		LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
		FT_Close(presto->handle);
		presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
	}

	if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
		return ERROR_JTAG_DEVICE_ERROR;	/* presto not open, return */

	presto->status = FT_SetLatencyTimer(presto->handle, 1);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto->status = FT_SetTimeouts(presto->handle, 100, 0);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto_data = 0xD0;
	presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	/* delay between first write/read turnaround (after purge?) necessary
	 * under Linux for unknown reason,
	 * probably a bug in library threading */
	usleep(100000);
	presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	if (ftbytes != 1) {
		LOG_DEBUG("PRESTO reset");

		presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;
		presto->status = FT_SetBitMode(presto->handle, 0x80, 1);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;
		presto->status = FT_SetBaudRate(presto->handle, 9600);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		presto_data = 0;
		for (i = 0; i < 4 * 62; i++) {
			presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
			if (presto->status != FT_OK)
				return ERROR_JTAG_DEVICE_ERROR;
		}
		usleep(100000);

		presto->status = FT_SetBitMode(presto->handle, 0x00, 0);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		presto_data = 0xD0;
		presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		/* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
		   probably a bug in library threading */
		usleep(100000);
		presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		if (ftbytes != 1) {
			LOG_DEBUG("PRESTO not responding");
			return ERROR_JTAG_DEVICE_ERROR;
		}
	}

	presto->status = FT_SetTimeouts(presto->handle, 0, 0);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto->status = FT_Write(presto->handle, &presto_init_seq,
			sizeof(presto_init_seq), &ftbytes);

	if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
		return ERROR_JTAG_DEVICE_ERROR;

	return ERROR_OK;
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
	FT_STATUS	ftStatus;
	FT_HANDLE	ftHandle0;
	int iport;
	FT_PROGRAM_DATA Data;
	FT_DEVICE	ftDevice; 

	if(argc > 1) {
		sscanf(argv[1], "%d", &iport);
	}
	else {
		iport = 0;
	}
	printf("opening port %d\n", iport);
	
	ftStatus = FT_Open(iport, &ftHandle0);
	if(ftStatus != FT_OK) {
		/* 
			This can fail if the ftdi_sio driver is loaded
		 	use lsmod to check this and rmmod ftdi_sio to remove
			also rmmod usbserial
		 */
		printf("FT_Open(%d) failed\n", iport);
		return 1;
	}
	
	printf("ftHandle0 = %p\n", ftHandle0);

	ftStatus = FT_GetDeviceInfo( 
				ftHandle0, 
				&ftDevice, 
				NULL, 
				NULL, 
				NULL, 
				NULL 
				); 

	if (ftStatus != FT_OK) { 
		printf("FT_GetDeviceType FAILED!\n");
		return 1;
	}  

	Data.Signature1 = 0x00000000;
	Data.Signature2 = 0xffffffff;
	Data.Manufacturer = (char *)malloc(4);			// "FTDI"
	Data.ManufacturerId = (char *)malloc(4);		// "FT"
	Data.Description = (char *)malloc(23);			// "USB HS Serial Converter"
	Data.SerialNumber = (char *)malloc(9);			// "FT000001" if fixed, or NULL
	ftStatus = FT_EE_Read(ftHandle0, &Data);
	if(ftStatus != FT_OK) {
		printf("FT_EE_Read failed\n");
		FT_Close(ftHandle0);
		return 1;
	}
		
	FT_Close(ftHandle0);

	printf("Signature1 = %d\n", Data.Signature1);			
	printf("Signature2 = %d\n", Data.Signature2);			
	printf("Version = %d\n", Data.Version);				
								
	printf("VendorId = 0x%04X\n", Data.VendorId);				
	printf("ProductId = 0x%04X\n", Data.ProductId);
	printf("Manufacturer = %s\n", Data.Manufacturer);			
	printf("ManufacturerId = %s\n", Data.ManufacturerId);		
	printf("Description = %s\n", Data.Description);			
	printf("SerialNumber = %s\n", Data.SerialNumber);			
	printf("MaxPower = %d\n", Data.MaxPower);				
	printf("PnP = %d\n", Data.PnP) ;					
	printf("SelfPowered = %d\n", Data.SelfPowered);			
	printf("RemoteWakeup = %d\n", Data.RemoteWakeup);
	
	if (ftDevice == FT_DEVICE_BM) {

		//
		// Rev4 extensions
		//
		printf("Rev4 = 0x%X\n", Data.Rev4);					
		printf("IsoIn = 0x%X\n", Data.IsoIn);				
		printf("IsoOut = 0x%X\n", Data.IsoOut);				
		printf("PullDownEnable = 0x%X\n", Data.PullDownEnable);		
		printf("SerNumEnable = 0x%X\n", Data.SerNumEnable);			
		printf("USBVersionEnable = 0x%X\n", Data.USBVersionEnable);		
		printf("USBVersion = 0x%X\n", Data.USBVersion);
	}

	if (ftDevice == FT_DEVICE_2232C) {

		//
		// FT2232C extensions
		//
		printf("Rev5 = 0x%X\n", Data.Rev5);					
		printf("IsoInA = 0x%X\n", Data.IsoInA);				
		printf("IsoInB = 0x%X\n", Data.IsoInB);				
		printf("IsoOutA = 0x%X\n", Data.IsoOutA);				
		printf("IsoOutB = 0x%X\n", Data.IsoOutB);				
		printf("PullDownEnable5 = 0x%X\n", Data.PullDownEnable5);		
		printf("SerNumEnable5 = 0x%X\n", Data.SerNumEnable5);		
		printf("USBVersionEnable5 = 0x%X\n", Data.USBVersionEnable5);	
		printf("USBVersion5 = 0x%X\n", Data.USBVersion5);			
		printf("AIsHighCurrent = 0x%X\n", Data.AIsHighCurrent);		
		printf("BIsHighCurrent = 0x%X\n", Data.BIsHighCurrent);		
		printf("IFAIsFifo = 0x%X\n", Data.IFAIsFifo);			
		printf("IFAIsFifoTar = 0x%X\n", Data.IFAIsFifoTar);			
		printf("IFAIsFastSer = 0x%X\n", Data.IFAIsFastSer);			
		printf("AIsVCP = 0x%X\n", Data.AIsVCP);				
		printf("IFBIsFifo = 0x%X\n", Data.IFBIsFifo);			
		printf("IFBIsFifoTar = 0x%X\n", Data.IFBIsFifoTar);			
		printf("IFBIsFastSer = 0x%X\n", Data.IFBIsFastSer);			
		printf("BIsVCP = 0x%X\n", Data.BIsVCP);
	}

	if (ftDevice == FT_DEVICE_232R) {

		//
		// FT232R extensions
		//
		printf("UseExtOsc = 0x%X\n", Data.UseExtOsc);			// Use External Oscillator
		printf("HighDriveIOs = 0x%X\n", Data.HighDriveIOs);			// High Drive I/Os
		printf("EndpointSize = 0x%X\n", Data.EndpointSize);			// Endpoint size

		printf("PullDownEnableR = 0x%X\n", Data.PullDownEnableR);		// non-zero if pull down enabled
		printf("SerNumEnableR = 0x%X\n", Data.SerNumEnableR);		// non-zero if serial number to be used

		printf("InvertTXD = 0x%X\n", Data.InvertTXD);			// non-zero if invert TXD
		printf("InvertRXD = 0x%X\n", Data.InvertRXD);			// non-zero if invert RXD
		printf("InvertRTS = 0x%X\n", Data.InvertRTS);			// non-zero if invert RTS
		printf("InvertCTS = 0x%X\n", Data.InvertCTS);			// non-zero if invert CTS
		printf("InvertDTR = 0x%X\n", Data.InvertDTR);			// non-zero if invert DTR
		printf("InvertDSR = 0x%X\n", Data.InvertDSR);			// non-zero if invert DSR
		printf("InvertDCD = 0x%X\n", Data.InvertDCD);			// non-zero if invert DCD
		printf("InvertRI = 0x%X\n", Data.InvertRI);				// non-zero if invert RI

		printf("Cbus0 = 0x%X\n", Data.Cbus0);				// Cbus Mux control
		printf("Cbus1 = 0x%X\n", Data.Cbus1);				// Cbus Mux control
		printf("Cbus2 = 0x%X\n", Data.Cbus2);				// Cbus Mux control
		printf("Cbus3 = 0x%X\n", Data.Cbus3);				// Cbus Mux control
		printf("Cbus4 = 0x%X\n", Data.Cbus4);				// Cbus Mux control

		printf("RIsVCP = 0x%X\n", Data.RIsD2XX);				// non-zero if using VCP drivers
	}	
	
	free(Data.Manufacturer);
	free(Data.ManufacturerId);
	free(Data.Description);
	free(Data.SerialNumber);
	
	return 0;
}