USB VID & PID

Designing hardware and software for systems that use the VS1010 MP3 Audio DSP Microcontroller.
Arek
Senior User
Posts: 111
Joined: Thu 2016-09-01 10:58

Re: USB VID & PID

Post by Arek »

Pictures, mentioned earlier:
Image
Image
Image
Image
User avatar
Panu
VSDSP Expert
Posts: 2829
Joined: Tue 2010-06-22 13:43

Re: USB VID & PID

Post by Panu »

Hi!

It looks like to me that this is the SCSI disk drive vendor and product name, not the USB vendor and product name. It's a lot harder to change, it would need to reimplement the scsi part in RAM...

Code: Select all

// ------- SCSI replies -------
const __y u_int16 inquiry1[18] = { //-----this must be first SCSI packet-----
	128, 1, 31<<8, 0, ('V'<<8)|'L',('S'<<8)|'I', 0, 0,
	('V'<<8)|'S',('1'<<8)|'0',('1'<<8)|'0',('C'<<8), 0, 0, 0, 0,
	('1'<<8)|'.',('4'<<8)|' '};
const __y u_int16 sense[9] = {0x7000, 0}; //no_sense
const __y u_int16 capacity1[4] = {0, 31, 0x0000, 512}; //Read Capacity
const __y u_int16 atapiCapacities[6] = {0, 8, 0, 31, 0x0200, 512}; //ATAPI read format capacities
const __y u_int16 diskData[1] = {0};
const __y u_int16 csw1[7] = {0x5553, 0x4253, 0, 0, 0, 0, 0}; //-----this must be after all SCSI packets-----

const __y void* const scsi[] = {
	0, //NOT_CHAPTER_9 //do not limit reply length
// recordLenght, matchWords, {data}*, replyEndpoint, replyLength, SideEffectFn, replyPacketPtr 
	7, 1, 0x0612, 2, 36, DoNothing, inquiry1, //inquiry
	7, 1, 0x0c12, 2, 36, DoNothing, inquiry1, //inquiry
	7, 1, 0x0c03, 2, 18, DoNothing, sense, //request sense
	7, 1, 0x0a25, 2, 8, DoNothing, capacity, //read capacity
	7, 1, 0x0a28, 2, -1, HandleDiskLba, diskData, //read 10
	7, 1, 0x0a2a, 2, -2, HandleDiskLba, csw, //write 10
	7, 1, 0x0a23, 2, 12, DoNothing, atapiCapacities, //ATAPI read format capacities
	7, 1, 0x061a, 2, 4, DoNothing, tenzeros,
	7, 1, 0x0a5a, 2, 4, DoNothing, tenzeros,
	6, 0, 2, 13, DoNothing, csw, //send csw ok to all unknown commands - don't worry, be happy.
	0 
};
-Panu
Arek
Senior User
Posts: 111
Joined: Thu 2016-09-01 10:58

Re: USB VID & PID

Post by Arek »

Hi Panu,

many thanks.
It looks for me much difficult.
The "scsi" isn't variable and as constante can not take new value (i.e. my_scsi).

Any idea how to change the USB answer?

am
Arek
Senior User
Posts: 111
Joined: Thu 2016-09-01 10:58

Re: USB VID & PID

Post by Arek »

Hi Panu,

case closed?
User avatar
Panu
VSDSP Expert
Posts: 2829
Joined: Tue 2010-06-22 13:43

Re: USB VID & PID

Post by Panu »

No... but difficult to say how to proceed... everything can be implemented in RAM but not everything can be configured with single pointers such as *chapter9

Can you confirm that the USB vendor name is changed, but the disk drive (SCSI) vendor name is not changed?

-Panu
Arek
Senior User
Posts: 111
Joined: Thu 2016-09-01 10:58

Re: USB VID & PID

Post by Arek »

Hi Panu,

thanks.

I use following code (taken from "arch-ums-2019-04-30-17-33-32mA", modified):
Changed:
- PID
- VID
- vendor name
- product name
- serial number

Code: Select all

/// \file main.c VS1010D VSOS Executable main file
/// This is a starting point for developing VS1010D DLX libraries and executables

#include <vo_stdio.h>
#include <volink.h>     // Linker directives like DLLENTRY
#include <apploader.h>  // RunLibraryFunction etc
#include <vs1010dRom.h>
#include <vo_gpio.h>
#include <vs1010c.h>
#include <playerinfo.h>
#include <string.h>
#include <protocol.h>
#include <devSdSd.h>
#include <usblowlib.h>
#include <usbmachine.h>

void UsbBootLoopNoReturn(void) ;


//#define VENDOR_NAME_LENGTH 13
//#define MODEL_NAME_LENGTH 7


#define MY_VENDOR_NAME_LENGTH 13
const __y u_int16 myvendorStringDescriptor[] = {
  ((MY_VENDOR_NAME_LENGTH * 2 + 2)<<8) | 0x03,
  'A' <<8, 'A' <<8, 'B' <<8, 'B' <<8, ' ' <<8, 'S' <<8, 'o' <<8, 'l' <<8, 'u' <<8, 't' <<8, 'i' <<8, 'o' <<8, 'n' <<8};

#define MY_MODEL_NAME_LENGTH 7
const __y u_int16 myproductStringDescriptor[] = {
  ((MY_MODEL_NAME_LENGTH * 2 + 2)<<8) | 0x03,
  'C'<<8, 'C' <<8, 'D' <<8, 'D' <<8, '1' <<8, '0' <<8, 'C' <<8};

#define SERIAL_NUMBER_LENGTH 12
const __y u_int16 myserialNumberDescriptorDefault[] = {
  ((SERIAL_NUMBER_LENGTH * 2 + 2)<<8) | 0x03,
  '0'<<8, // You should put your own serial number here
  '0'<<8,'0'<<8,'0'<<8,'0'<<8,'0'<<8,
  '0'<<8,'0'<<8,'0'<<8,'0'<<8,'0'<<8,
  '1'<<8, // Serial number should be unique for each unit
};





const __y u_int16 mydeviceDescriptor[] = { 
  //Device Descriptor	
  0x1201,   // bLength | bDescriptorType
  0x1001,   // bcd USB Version (01.10) Low | high
  0x0000,   // bDeviceClass:    Defined in Interface Descriptor
  0x0040,   // bDeviceProtocol: -''-, Endpoint 0 size 64
  0xFFEE,   // idVendorL VLSI 0x19fb
  0xAACC,   // idProductL VS1000: 0x00.0x02 (0x02=MassStorage)
  0x0000,   // bcdDeviceL
  0x0102,   // iManufacturerString
  0x0301    // SerialNumber
};

const __y u_int16 myconfigurationDescriptor[] = {
  // Prime Configuration Descriptor        
  0x0902,   //Length
  0x2000,   //Lo(Total length of configuration descriptor (32))
  0x0101,   //Number of interfaces supported (at least bulk only)
  0x0080,   //String index to this configuration
  0x1009,   //Power usage: 32 milliamperes | Length  
  // Interface Descriptor 1 of 1                 
  0x0400,   //Type: Interface Descriptor
  0x0002,   //This is Alternate Setting 0
  0x0806,   //Device Class: Mass Storage (Class 8)
  0x5000,   //Interface Protocol: Bulk Only Transport (0x50)  
  // Endpoint Descriptor 1 of 2, data IN to PC from our device    
  0x0705,   //Length, Endpoint descriptor
  0x8202,   //EP 2 IN, Bulk
  0x4000,   //Lo(Maximum packet size (64 bytes))
  0x0007,   //Polling Interval (0=Not Applicable for bulk endpoints)                  
  // Endpoint Descriptor 2 of 2, data OUT from PC to our device  
  0x0503,   //Endpoint descriptor, EP 3 OUT
  0x0240,   //This is a bulk endpoint
  0x0000,   //Hi(-''-)  
};


const __y void* const mychapter9MSC[] = { //USB chapter 9 protocol
	1, //IS_CHAPTER_9 // limit reply lenght to that requested by chapter 9 request
// recordLenght, matchWords, {data}*, replyEndpoint, replyLength, SideEffectFn, replyPacketPtr 
	7, 1, 0x0005, 0, 0, DoSetAddress, NULL, //Set address (zero reply, special)
	8, 2, 0x8006, 0x0001,  0, 18, DoNothing, mydeviceDescriptor, //Get device descriptor
	8, 2, 0x8006, 0x0002,  0, 32, DoNothing, myconfigurationDescriptor, //Get configuration descriptor
	8, 2, 0x8006, 0x0003,  0, 4, DoNothing, languageDescriptor,
	8, 2, 0x8006, 0x0103,  0, (MY_VENDOR_NAME_LENGTH * 2 + 2), DoNothing, myvendorStringDescriptor,
	8, 2, 0x8006, 0x0203,  0, (MY_MODEL_NAME_LENGTH * 2 + 2), DoNothing, myproductStringDescriptor,
	8, 2, 0x8006, 0x0303,  0, (SERIAL_NUMBER_LENGTH * 2 + 2), DoNothing, serialNumberDescriptor,
	7, 1, 0x0009, 0, 0, DoResetDataToggles, NULL, //Set any configuration (zero reply)
	8, 2, 0x0201, 0x0000, 0, 0, DoResetDataToggles, NULL, //Clear endpoint halt (zero reply)
	7, 1, 0xa1fe, 0, 1, DoNothing, tenzeros, //get max lun
	0
};






// ------- SCSI replies -------
const __y u_int16 inquiry1[18] = { //-----this must be first SCSI packet-----
	128, 1, 31<<8, 0, ('W'<<8)|'W',('W'<<8)|'W', 0, 0,
	('A'<<8)|'A',('A'<<8)|'A',('1'<<8)|'0',('C'<<8), 0, 0, 0, 0,
	('1'<<8)|'.',('4'<<8)|' '};
const __y u_int16 sense[9] = {0x7000, 0}; //no_sense
const __y u_int16 capacity1[4] = {0, 31, 0x0000, 512}; //Read Capacity
const __y u_int16 atapiCapacities[6] = {0, 8, 0, 31, 0x0200, 512}; //ATAPI read format capacities
const __y u_int16 diskData[1] = {0};
const __y u_int16 csw1[7] = {0x5553, 0x4253, 0, 0, 0, 0, 0}; //-----this must be after all SCSI packets-----

const __y void* const scsi[] = {
	0, //NOT_CHAPTER_9 //do not limit reply length
// recordLenght, matchWords, {data}*, replyEndpoint, replyLength, SideEffectFn, replyPacketPtr 
	7, 1, 0x0612, 2, 36, DoNothing, inquiry1, //inquiry
	7, 1, 0x0c12, 2, 36, DoNothing, inquiry1, //inquiry
	7, 1, 0x0c03, 2, 18, DoNothing, sense, //request sense
	7, 1, 0x0a25, 2, 8, DoNothing, capacity, //read capacity
	7, 1, 0x0a28, 2, -1, HandleDiskLba, diskData, //read 10
	7, 1, 0x0a2a, 2, -2, HandleDiskLba, csw, //write 10
	7, 1, 0x0a23, 2, 12, DoNothing, atapiCapacities, //ATAPI read format capacities
	7, 1, 0x061a, 2, 4, DoNothing, tenzeros,
	7, 1, 0x0a5a, 2, 4, DoNothing, tenzeros,
	6, 0, 2, 13, DoNothing, csw, //send csw ok to all unknown commands - don't worry, be happy.
	0 
};



__y u_int16 serialNumberDescriptor[sizeof(myserialNumberDescriptorDefault)];


void myUsbSetSerialNumber(u_int32 n) {
	__y char *p = (__y char*)&serialNumberDescriptor[12];
	memcpyYY(serialNumberDescriptor, myserialNumberDescriptorDefault, sizeof(serialNumberDescriptor));
	while(p>serialNumberDescriptor) {
		*p-- = ((n&0x7)+'0') << 8;
		n >>= 3;
	}
}





void FlushStorage() {
	if (currentBlockLoaded) { //Unsaved SPI flash block in memory
		printf ("SPI Flush\n");
		SaveBlock(&spiBus);
	}
	if (sdcard.hardwareInfo[0] & SDSD_F_MULTIPLE_BLOCK_WRITE) { //SD write in progress
		printf("SD Flush\n");
		VODEV('U')->BlockRead(VODEV('U'),0,0,NULL);
	}
}

s_int32 frameLength = -10000;
int MyUsbHandler (int i) {
	static u_int32 flushCounter = 0;
	static u_int16 lastSdBlockLSW = 0;
	static u_int16 thisFrame = 0;
	static u_int16 lastFrame = 0;
	static u_int16 ejected = 0;

	
	PERIP(ANA_CF3) |= ANA_CF3_UTM_ENA | ANA_CF3_480_ENA | ANA_CF3_UTMBIAS;
	
	
	// Frame length tracking for detection of non-activity
	if ((usp[1] == 3) && (usp[3] == 0x5553) && (usp[3+7] == 0x061b) && (usp[3+9]==2)) ejected = 1; // SCSI eject detected
	if (!ejected && (PERIP(USB_STATUS) & (1 << USB_ST_SOF_B))) { //Start Of Frame detected
		thisFrame++; //increase frame number
		frameLength = 0;
		PERIP(USB_STATUS) = (1 << USB_ST_SOF_B); //Clear SOF flag
	}
	frameLength++;

	// Fall-back for dropping out of High Speed if the connection is not working properly
	if ((usbResetCounter) && (PERIP(USB_ST) & USB_ST_BRST)) usbResetCounter++; //USB reset detected
	if ((usbResetCounter > 8) || (runlevel < 12)) { // Don't use high speed after too many resets and not for non-highspeed runlevels
		PERIP(USB_CF) |= USB_CF_NOHIGHSPEED; // disable high speed after 8th bus reset
	}
	
	
	// Track disk activity for flushing writes left hanging		
	if ((VODEV('U') == &spiFlash) && (currentBlockLoaded == 0)) flushCounter = 0; //activity in SPI flash	
	if (sdcard.hardwareInfo[4] != lastSdBlockLSW) { //activity in SD card
		lastSdBlockLSW = sdcard.hardwareInfo[4];
		flushCounter = 0;
	}	
	if (flushCounter++ > 100000) { //So many iterations since last write activity
		FlushStorage();
		flushCounter = 0;
	}	
	 
	// Exit conditions
	if (lastReceivedCharUart0 == 27) {
		printf("ESC");
		appFlags |= APP_FLAG_QUIT;
	}				
	if (lastReceivedCharUart0 == 's') {
		printf("Shell");
		appFlags |= APP_FLAG_QUIT;
	}				
	if (frameLength > 200000) {
		printf("USB inactive");
		appFlags |= APP_FLAG_QUIT;
	}

	return 0;
}



ioresult main (char *params) {
u_int32 usbHandlerSave = ReadFromProgramRam(109);
u_int32 serialNr;

/*
FILE *f;

	f = fopen("s:serial.srl", "rb");
	fread(&serialNr, 1, 2, f);
	fclose(f);
*/	
	if (sbs[2].f) return SysError("Too many files open");
	PERIP(ANA_CF1) |= ANA_CF1_BTNDIS;		
	PERIP(USB_CF) = (USB_CF_USBENA | USB_CF_DTOGERR);
	SetJmpiHookFunction((void*)109,MyUsbHandler);
	VODEV('U') = vo_pdevices[(params[0]|32)-'a'];
	if (!sdSize) {
		sdSize=1;
		VODEV('U') = &spiFlash;
	}
	appFlags = 0;

	serialNr = 0x29c; // oct. 1234, test only
	UsbSetSerialNumber(serialNr);
	memcpyYY (deviceDescriptor, mydeviceDescriptor, sizeof(deviceDescriptor));
	
	chapter9 = mychapter9MSC;

	UsbBootLoopNoReturn(); // Call USB MSC handler in ROM. In VS1010D it will return if APP_FLAG_QUIT flag is high.
	FlushStorage();
	WriteToProgramRam(109, usbHandlerSave); //Restore original USB handler
	PERIP(USB_CF) = 0; //Disable USB
	if (lastReceivedCharUart0 == 's') {
		SimpleShell();
	}
	return S_OK;
}



then start via Termite:
VS1010>s:ums.dlx d
s:ums.dlx d
Relocked (3008)


and check with windows explorer:
first, I get: "VLSI VS1010C USB Device" (???)
with following properties:
- PID changed to CCAA - ok
- VID changed to EEFF - ok
- vendor name: VLSI - not changed
- product name: VS1010C - not changed
- serial number changed, ok


see pictures:
Arek
Senior User
Posts: 111
Joined: Thu 2016-09-01 10:58

Re: USB VID & PID

Post by Arek »

Pictures:

Image


Image


Image
User avatar
Panu
VSDSP Expert
Posts: 2829
Joined: Tue 2010-06-22 13:43

Re: USB VID & PID

Post by Panu »

Yeah.. it's like this USB Device, made by vendor "USBDeviceMakerCompanyName" (your company) contains a SCSI Disk Controller made by "ChipsetVendorName" (our company). And Windows just wants to show the ChipsetVendorName instead of the USBDeviceMakerCompanyName.

It's like if you purchase a USB Hard Disk from, say, LaCie, those used to be common, it will say "LaCie" when you plug in the USB install the device, but when you look at the disk drive, it will show the Western Digital hard disk, which the LaCie USB device contains.

As I said, everything can be rewritten in RAM, but not with equal difficulty.

-Panu
Arek
Senior User
Posts: 111
Joined: Thu 2016-09-01 10:58

Re: USB VID & PID

Post by Arek »

Many thanks, Panu!
Everything is clear to me.
Post Reply