Ok, here's what I have learned [it's by no means authoritative but it works]...
I haven't drawn a circuit diagram yet, as it's still on the breadboard.
The 18F2550 has a 20mhz oscillator. The config bits are shown in the attached screenshot. I use the crystal for the main oscillator[HS: USB-HS].
Watchdog timer is off in this screenshot, as I've been using the debug mode in MPLAB.
Initially, it wouldn't enumerate, even though the PC knew it was there. I read the documentation again and again for the correct oscillator settings. Turned out you need to enable the USB voltage regulator AND [IMPORTANT], place a pull-up resistor [1k works fine] from Vusb to D+
Windows rewarded me with the distinctive 'ding-dong' sound and the device enumerated.
Codewise, I started out by using Easyhid and the default templates [I have VB6]. Nothing doing. The pic was stuck in the DoUSBIn and DoUSBOut routines and no data was passing. Changing the label at the end of the USBIn and USBOut commands had no effect, even though I could then exit the routines and proceed with the main program loop.
Windows was giving me an 'access is denied' message, so I figured that it was not the pic side of things that was the problem.
Re-read the docs in my PBP folder [usb.txt] and edited USBDESC.ASM to allow MOUSDESC.ASM to be the compiled file. Ran the USBMOUSE.BAS demo included with PBP and Voila! - my mouse was moving of its own accord.
Ok - re-edited USBDESC.ASM to compile JADESC.ASM and ran USBJADEM.BAS [also included with PBP] - the code couldn't be simpler. It worked - sending two bytes back to the PC.
The only changes made to the VB side of Easyhid were to change the Vid and Pid to match Jan Axelson's [&H0925 and &1234] and the following [after adding a text box named Text1 to the form]...
'************************************************* ****************
' on read event...
'************************************************* ****************
Public Sub OnRead(ByVal pHandle As Long)
' read the data (don't forget, pass the whole array)...
If hidRead(pHandle, BufferIn(0)) Then
' ** YOUR CODE HERE **
Text1.Text = Val(BufferIn(1)) & " " & Val(BufferIn(2))
' first byte is the report ID, e.g. BufferIn(0)
' the other bytes are the data from the microcontrolller...
End If
End Sub
;----------------------
The pic code [slightly modified from the included example] is simplicity.
;==============================
buffer Var Byte[8]
cnt Var Byte
Define OSC 20
USBInit
idleloop:
buffer[0] = buffer[0] + 1
buffer[1] = buffer[1] + 1
outloop:
USBService ' Must service USB regularly
USBOut 1, buffer, 2, outloop ' Send the bytes back
Goto idleloop ' Wait for next buffer
;==============================
I then changed the number of bytes I wanted to send, from 2 to 8. Failed!
Sooo... It was back the reading the docs. Eventually, I figured out that you have to change the 'report descriptor' in [in my case] JADESC.ASM in order to send or receive more data REGARDLESS of the size of your buffer declarations, although if you try and send 16 bytes when your buffer size is 8 then it ain't gonna work anyway ;-)
Here are the lines to change [found in JADESC.ASM in the PBP folder, at the 'ReportDescriptor' label]...
;=================================
retlw 0x08
retlw 0x95 ; report count (2) (fields)
retlw 0x02 ; CHANGE THIS VALUE TO YOUR BUFFER SIZE
retlw 0x81 ; input (Data, Variable, Absolute)
retlw 0x02 ; AND THIS
retlw 0x09 ; usage (Vendor Defined)
retlw 0x05
retlw 0x09 ; useage (Vendor Defined)
retlw 0x06
retlw 0x15 ; logical minimum (-128)
retlw 0x80
retlw 0x25 ; logical maximum (127)
retlw 0x7F
retlw 0x35 ; Physical Minimum (0)
retlw 0x00
retlw 0x45 ; Physical Maximum (255)
retlw 0xFF
retlw 0x75 ; report size (8) (bits)
retlw 0x08
retlw 0x95 ; report Count (2) (fields)
retlw 0x02 ; AND THIS
retlw 0x91 ; Output (Data, Variable, Absolute)
retlw 0x02 ; AND THIS
retlw 0xC0 ; end collection
retlw 0xC0 ; end collection
;=================================
Once I had changed the occurences of 0x02 to 0x08, I could then send 8 bytes at a time to and from. Beware that the array indexing pic-side is different to the PC side, i.e. pic buffer[0] = BufferIn(1) at the PC.
Here is a slightly revised version. As I said the, code could not be simpler [in the end]. I've stripped it back to the absolute minimum. It has progressed from here, but hopefully this should allow you to get up and running and not have to plough through the documentation just to send a couple of bytes to and fro.
;==================================
picbasic code
;==================================
buffer Var Byte[8]
Define OSC 20
USBInit
main:
loop:
buffer[0] = "I"
buffer[1] = "t"
buffer[2] = " "
buffer[3] = "L"
buffer[4] = "i"
buffer[5] = "v"
buffer[6] = "e"
buffer[7] = "s"
outloop:
USBService ' Must service USB regularly
USBOut 1, buffer, 8, outloop ' Send the bytes back
Goto loop
;==================================
Yup - that's ALL you need
;==================================
VB code as Easyhid, but with text box named Text1 added to form, Vid and Pid changed accordingly, and these lines added...
'************************************************* ****************
' on read event...
'************************************************* ****************
Public Sub OnRead(ByVal pHandle As Long)
' read the data (don't forget, pass the whole array)...
If hidRead(pHandle, BufferIn(0)) Then
' ** YOUR CODE HERE **
For stuff = 1 To 8
Message = Message & Chr$(BufferIn(stuff))
Next
Text1.Text = Message
' first byte is the report ID, e.g. BufferIn(0)
' the other bytes are the data from the microcontrolller...
End If
End Sub
;==================================
I've since coded my own Timer0 interrupt routine, and call USBService from there, which takes away the headache of keeping the connection alive in the main loop.
I'd be more than happy to share anything I come up with, but be aware that I'm far from the greatest coder :-(
Giulio
Bookmarks