News:

Let's find out together what makes a PIC Tick!

Main Menu

How can create analog Joystick?

Started by Mapo, Jun 12, 2021, 01:27 PM

Previous topic - Next topic

John Lawton

It seems I've been barking a bit up the wrong tree. The problematic USB event I've noticed with the USB analyser is a buffer overrun, not the (resulting?) reset port event.

A Bulk or Interrupt transfer event occurs detailing a 9 byte buffer. This is then followed by a buffer overrun event.

I don't know why a 9 byte buffer, if this is the main data transfer it should be much larger than that, the HID_INT_OUT_EP_SIZE buffer is 32 bytes...

John


trastikata

Hello John,

I had a 18F46J50 test device with USB port and gave it a try so I can see what's happening. In your descriptor the Buffer size and the EP size is declared as 32 bytes and you are sending only 13 bytes. Change the Buffer and the EP's to 13 and will work:

$define USB_VID   $04D8 ' User VID value
$define USB_PID   $0001 ' User PID value
$define HID_BUFFER_SIZE   13 ' USB Buffer Size
$define USB_BUS_POWER   250 ' Bus power (50 to 250 milliAmps) x2

$define USB_TRANSFER_TYPE   _INTERRUPT

$define USB_SERVICE ' Use the Timer1 low priority interrupt for enumeration and bus servicing
$define USB_USE_HID ' Indicate we require to use a HID interface
$define USB_CONNECT_LED   PORTD.3 ' This pin goes high when the USB is in a connected state
$define USB_SELF_POWER   $80 ' Self powered $C0, $80 bus powered

$define HID_EP_OUT_POLLING_MS 10 ' HID - EP01 - 1ms (EP01Out) ' Changed from 1ms to 10ms
$define HID_EP_IN_POLLING_MS  10 ' HID - EP01 - 1ms (EP01In) ' Changed from 1ms to 10ms

$define HID_INTF_ID   $00
$define HID_EP   1 ' Endpoint number
$define HID_INT_OUT_EP_SIZE   13 ' Increased from 3 to 32
$define HID_INT_IN_EP_SIZE   13 ' Increased from 3 to 32
$define HID_NUM_OF_DSC   1 ' Number of descriptors

$define HID_RPT01_SIZE   SizeOf(HID_Rpt01)   ' Size of "hid_rpt01" table (in bytes)

$define HID_PROTOCOL_JOYSTICK $04
   

Also I think the language code is inverted, should be $0904 thus:
Dim Sd000 As Flash = Byte SizeOf_Table,_ ' Size of this descriptor in bytes
Byte USB_DESCRIPTOR_STRING,_ ' Descriptor Type
Word $0904 ' language ID - (high byte, low byte)

JS.jpg

John Lawton

Bloody Hell, you've done it!!!  ;D

Fantastic work, I'm extremely grateful to you after days of not getting very far, apart from using the USB analyser today which is very interesting. I think this will now allow me to get the joystick unit properly working which is a great relief as it is about to become overdue.

Best regards,

John

top204

#23
Excellent news John, and well done trastikata.

I knew it would be something simple and obvious, but I just could not find out why enumeration worked perfectly but nothing was being received by the PC. It got to the point where I could not see the wood for the trees. :-)

I knew the compiler's HID interface library worked because I tested the keyboard and mouse and a small joystick programs I have and they all worked, and I even tweaked the USB library used for the HID joystick to make it more clearer and more efficient, but as soon as I added extra bits and pieces to the descriptor, the PC stopped receiving them, but still stayed enumerated. I'm even sure I reduced/enlarged the buffer size at one point, but it still refused to receive data from the extra bits and pieces joystick. The HID protocol is dreadful, and typical of most outdated protocols. :-)

The compiler's HID interface library will always keep the connection attached because it uses a low priority Timer1 interrupt to service the USB, so it will not fall off the bus if it is not used for transmit or receive.

John Lawton

Hi Les,

yes, got there in the end. Very many thanks for creating the Joystick Descriptor, which is still mysterious to me in the way it works.

At some point I want to change the X/Y resolution which I assume will mean outputting Words rather than Bytes, and I'd like to move to unsigned variables if possible, but changing almost anything in the descriptor stops it working which is worrying to say the least :)

John

top204

#25
With descriptors, I'm sure the 16-bit values are sent as two sequential 8-bit values, high byte then low byte.

Within the descriptor's Dim As Flash tables, the data entry for the size of the table will need to be altered for the extra bytes, and I think there is a different identifier for larger values that 8-bit.

John Lawton

Thanks, I'll try that shortly. I'm still getting over the thing working :)

John

John Lawton

Finally I'm up and running with the joystick unit now which is great. The customer wants a different USB device serial number on each unit. Presently this is fixed in the USB code as follows:

$ifdef USB_HAVE_SERIAL_STRING
    Dim Sd003 As Flash = {Byte SizeOf_Table,  ' Size of this descriptor (in bytes)
                         Byte USB_DESCRIPTOR_STRING,
                         Word "SERIAL-1001" } ' Serial string - unicode format
$endif

I'm not sure how the above works. I want to be able to modify (i.e. increment) the string "SERIAL-1001" from within my program code, so can I put a pointer to a string array or some other system, in place of the fixed string in the descriptor?

John Lawton


top204

#29
You can change the USB library's code so it looks at RAM instead of flash memory when it is reading the serial number. Then the serial number can be created on the fly, either random of sequentially. If using a device with EEPROM, the current serial number generated can be stored, so it knows what to increment for the next serial number, or what not to use if a random number is used etc...

As long as the HID library I created is in the BASIC program's directory, it will be the code that is used, and the compiler will not look at library files in the any other directory. So any changes in that code will not effect other programs using the library. I am going to add the USB/HID library to the compiler's "PDS/Includes" folder when the compilers are installed, so any program can use them directly, and not need to go into the samples folder.

John Lawton

Quote from: top204 on Sep 17, 2021, 06:00 PM...As long as the HID library I created is in the BASIC program's directory, it will be the code that is used, and the compiler will not look at library files in the any other directory. So any changes in that code will not effect other programs using the library. I am going to add the USB/HID library to the compiler's "PDS/Includes" folder when the compilers are installed, so any program can use them directly, and not need to go into the samples folder.
I <thought> that I was compiling local copies of the USB library code in the same directory as my other source code. So you are saying even if I include these 'local' files in my main .bas file that the compiler won't call them up, but use it's own copies? I though that I had overriden that behaviour.

Not sure I understand how to modify the library code anyway.

John Lawton

In the descriptor.inc file, this code calls up the Flash descriptors, SD001, SD002, SD003 which I would like to change to use RAM data as you suggest so that can be editable in each unit.

Dim Device_Dsc As Flash8 = {SizeOf(Device_Dsc),             ' Size of this descriptor in bytes
                             USB_DESCRIPTOR_DEVICE,          ' Device descriptor type
                             $00, 02,                        ' USB Spec Release Number in BCD format
                             $00,                            ' Class Code
                             $00,                            ' Subclass code
                             $00,                            ' Protocol code
                             USB_EP0_BUFF_SIZE,              ' Max packet size for EP0
                             USB_VID & $FF, USB_VID >> 8,    ' Vendor ID (low byte, high byte)
                             USB_PID & $FF, USB_PID >> 8,    ' Product ID (low byte, high byte)
                             USB_ISS & $FF, USB_ISS >> 8,    ' Device firmware release number in BCD format
                             $01,                            ' Manufacturer String index (SD001)
                             $02,                            ' Product String index (SD002)
                             $03,                            ' Device serial number String index (SD003)
                             $01}                            ' Number of possible configurations

Sorry I'm a bit confused as to what I'm trying to do here, am I right to think that if I change the $01, $02 and $03 on the penultimate lines to variable names then instead of the String Indexes I can use RAM data? If not how should I do this please?

If so, how exactly do I store my customisable data in RAM, which will be strings, of the form "Company Name", "Device Name" and "Serial 0001"

trastikata

John,

I've never put anything in mass production and I don't know how is programming done.

Browsing through the MPLAB IPE's options I've seen before that it had a serialization option with a counter and address pointer for the serial number counter, with optional min and max values etc, however I've never used it.

John Lawton

Hi Trastikata,

this isn't for high volume mass production, we are looking at only 50 off in total, and each device is to be individually customised, serial number etc.

I have adapted your VB.NET HID Framework code (thank you so much for posting it in the wiki) so that a PC Configuration program will be able to view and edit the various USB Descriptor strings in the device, they are then stored in Flash memory (and called up into RAM at startup). I just can't work out how to get these RAM strings into the USB descriptors.

John Lawton

More USB descriptor woes.

The code in my post #31 above is referenced by these bits of code:
' Product string index - unicode format
    Dim Sd002 As Flash = {Byte SizeOf_Table,
                         Byte USB_DESCRIPTOR_STRING,
                         Word "My Custom Product Name" }

and

Dim USB_SD_Address As Flash16 = Sd000, Sd001, sd002  ' Create an address pointer to the descriptor's sd tables (in this case SD002)

But I can't work out how this works nor how to use RAM data instead of the flash table SD002 so the text can be changed.

Any help appreciated!!

John Lawton

Another USB question, probably for Les:

I have extended the Joystick descriptor from 15 bytes to 64 bytes and changed the buffer sizes appropriately in the descriptor file. I've found that my PC application doesn't see any data beyond buffer[31] i.e the 32nd element. Is there a hard coded limit somewhere I haven't found that is stopping this working all the way to 64 bytes?

John

trastikata

Hello John,

I am currently away from home for another week or so and can't test anything, otherwise I would have tried helping with the descriptor serialization thing.
As for the USB HID - the limit is 64 bytes per packet, the problem you see should be an issue with either the descriptor or the PC host program - is that a commercial program?

Regards

John Lawton

#37
It's the USB HID Framework that you put on the wiki using the Mechanique dll. So a black box to me.

John

trastikata

#38
You have to re-dimension as well the BufferInSize in the PC programm to 64 bytes.

John Lawton

#39
Yes I've already done that. I was using a 15 byte buffer and have increased to 64 bytes.