PDA

View Full Version : Better Documentation?



Giulio
- 1st January 2007, 10:42
Hi,

I've been having a few problems with implementing USB on a 18F2550 and, judging by the zero replies to my previous posts, it seems that I'm not alone.

Could this be down to the sparse documentation in the pbp manual?

I've finally cracked the problem, and have data going to and from my development board and my PC, but this has been a laborious and time-consuming exercise.

BTW, if anybody is interested, I'm more than happy to share the results of my labours.

Don't get me wrong. I'm more than prepared to R.T.F.M. and have not only bought Jan Axelson's 'bible' but have spent many hours scouring the 'net before resorting to the forums.

Call me lazy, but I don't think it should be necessary for me to become an expert in the field of USB communications when it is such a small part of my overall project.

Overall, I feel that the pbp manual could be improved in this respect. Sure, they have provided the commands, and that has indeed removed the slog of assembler coding from us, but a more detailed explanation of what is going on 'behind the scenes' so to speak, would not go amiss.

Another example would be that way that the relevant underlying resource usage is not explained. Again, I understand the monumental task of providing us with a [it must be said, superb] basic compiler that has to take into account the vast number of different uControllers out there.

But, when my code inexplicably breaks, for example, when I'm using a timer under my own assembler interrupts, and my LCD routines go south, I have to assume that the 'serout2' command is competing with me for the same resource?

I may be wrong - I'm perfectly capable of accepting that it's MY coding skills [or lack of] that are the problem but again, better documentation would save us all hours of frustrating debugging, no?

Just a few thoughts. Whinge over. Any comments?

Giulio

malc-c
- 1st January 2007, 12:09
I think that this could be covered in the book that one of the other posters was looking at writing. I still class myself a s a PBP newbee, and yesterday I used the LCDOUT command to write to a 2 x 16 LCD for the first time. I used a different port, but following the excellent diagram, and using the sample code in the manual it worked 1st time :) But other commands and how they function are very sparce in their description on how they finction, or have no examples on their use.

I've not dabbled with USB, so I can't really comment on your project or the problems you've experienced, but maybe you could post an article in the documentation section for future reference for others. At least this would help others until such time that the manual is re-vamped ;)

Pedro Santos
- 1st January 2007, 13:11
Hi Giulio

Yes, I thing the most of us have probrelms to use the usb with the pic's so
if you will help post your code with comments than we all can learn from that

Regards

Pedro

Giulio
- 1st January 2007, 16:06
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

mister_e
- 1st January 2007, 22:43
At least you're not lazy and you're not afraid to work hard. So, don't give up dude.

Yup the timer interrupt is the way to go with UsbService. Make sure you set the interval each 100uSec or so.... yeah i know it's written 10-20 mSec in the manual.

Yes anything else may screw up the USBservice if it takes to much time to execute. As i don't see your code, i can't comment.

You could remove the external pull-up and enable the internal one, look at the UCFG register.

You MUST change... DEFINE OSC 20 to DEFINE OSC 48 or all your timing will be screwed up.

Mecanique EasyHID always worked a treat for me... too bad...

USB is not as simple as RS232, sure one day i'll have to take my time and read carefully the whole Jan Axelson bible. 'Till now none of my stuff needed the full speed and Timing accuracy, so EasyHid and those 3 PBP command work really well.

It's like everything new stuff, you must learn by trial/error. To me, it's the best way... even if some keyboard, mouse or everything close to my hands, fly here and there :D

In case you didn't already, have a look at the following
http://www.picbasic.co.uk/forum/showthread.php?t=5418

Don't give up!

Giulio
- 2nd January 2007, 18:45
Hey, thanks for the encouraging words!

I FEEL lazy but, when I'm up at 4am for the n_th night in a row, I guess I'm either doing SOME work, or I'm obsessed ! [probably a bit of both].

Like your project - in fact I'm ordering a 18F4550 right now, so I can try it. I could convert parts of it I suppose, but hey, I need an excuse to buy another chip!

My irq code is here - don't be too hard on it ;-), I'm still playing with the numbers to see at what point it falls over.

I haven't yet fired up the calculator or the 'scope to do any formal timing tests...

What it does show is how superb picbasic is at allowing us to mix assembler and basic. I know I could have coded the led toggling with a couple of lines of assembler but I had great fun just dropping in and out of inline code type mixing [if that makes sense].

Onwards and upwards... [or, in my case, sideways!]

Thanks again.

Giulio


;===================================
asm
myint
movwf wsave ;save off relevant registers
swapf STATUS,w
clrf STATUS
movwf ssave
movf PCLATH,w
movwf psave

btfss PIR1,TMR1IF ;test for time1 irq
goto T0_IRQ ;no - go test for timer0
endasm
toggle portc.7 ;yes - flash led [too fast at these settings...]
USBService ;keep connection alive
asm
movlw .250 ;next interrupt
movwf TMR1L ;lo
movlw .210 ;next interrupt
movwf TMR1H ;hi
bcf PIR1,TMR1IF ;acknowledge timer1 interrupt
T0_IRQ
btfss INTCON,TMR0IF ;test for timer0 irq
goto pull ;no - clean up

movlw .0 ;yes set up next irq
movwf TMR0L
movlw .100
movwf TMR0H
bcf INTCON,TMR0IF
endasm
toggle portc.6 ;flash led
asm

pull ;clean up
movf psave,w ;pull registers
movwf PCLATH
swapf ssave,w
movwf STATUS
swapf wsave,f
swapf wsave,w
out
retfie ;done
endasm
;===================================