PDA

View Full Version : USBSERVICE + serout2 problem



EToscano
- 4th June 2010, 23:54
Good afternoon everybody, I need some asistance with a problem with a USB/Serial program.
I'm posting this in both the USB and SERIAL groups.

This is running on a 18f4550@48mhz using DT's "usb_asm_service".


the thing is if in my main loop I put:

baud485 con $4006

mainloop:


high en485
serout2 tx485,baud485,["!",s485(0),s485(1),s485(2),s485(3),s485(4),s485(5), _
s485(6),s485(7),s485(8),s485(9),s485(10),s485(11), _
s485(12),s485(13),s485(14)]
low en485

pause 1000
goto mainloop


end



if the usb cable is not connected, I get the sent bytes on my 485 bus, but as soon as I plug the usb cable, I start loosing some bytes(at least 1) of every cycle.

this is not the actual code, but it does the same thing basically.

It seems to me as if during the serout2 instruction the usbservice happens it kills the byte being transmited at the time.
Do I make any sense?

What I need is to be able to process serial comm using serout2 to other devices even when the device is connected to the usb host.

Hopefully this is clear enough so someone can share some tips.


Best regards

Eduardo Toscano
Seneca Sistemas

mackrackit
- 5th June 2010, 02:24
I deleted your other post as there is no need to double post.

You may need to post your complete code also.

Darrel Taylor
- 5th June 2010, 05:29
Anytime you are using interrupts (other than ON INTERRUPT), it interrupts things.
USB_ASM_Service uses USB interrupts that happen quite frequently.

Software timed routines like SEROUT2, PAUSE, PULSIN/OUT etc. Will lose time that they don't know about.

When using interrupts, Hardware devices should be use instead of software commands.
Instead of SEROUT2, use HSEROUT with the USART.

PAUSE ... use a timer.
PULSIN ... use a CCP module.
COUNT ... use a Timer

There are still many PBP commands you can use without problems.
But, if if they require specific timing thru software, that timing will be disturbed.

aberco
- 24th August 2010, 07:15
Hi Darrel,
I'm actually back on USB development, there is quite a bit of new stuffs! your USB_ASM_Service routine is very exciting.

If I understand correctly the timing issue will also "kill" I2CRead/Write, Shiftin/Shiftout, LCDout... There's hardware modules for SPI and I2C, even if they are not used by these instructions. However there's not much solution for driving the LCD.

Is the delay introduced by the interrupt that long? I mean, some processes does not require an extreme regularity of clocking/data signals, an intelligent LCD display should probably cope with this.

However I haven't been able to experiment with it yet... I have managed to compile and run successfully the DCD demo on a PIC18F13K50. Adding the USB_ASM_Service routine and commenting the USBService/USBInit in the demo makes the board unable to declare itself anymore.

I've also tried running both the interrupt and polled USB servicing to display the status of "PLUGGED" on a LED but nothing happens. The rest of the demo works fine though.

Any lead for this issue?
Thanks in advance for your time

mackrackit
- 24th August 2010, 10:06
However I haven't been able to experiment with it yet... I have managed to compile and run successfully the DCD demo on a PIC18F13K50. Adding the USB_ASM_Service routine and commenting the USBService/USBInit in the demo makes the board unable to declare itself anymore.
Can you post the non-working code?

aberco
- 24th August 2010, 15:35
Yep sure!




ASM
CONFIG CPUDIV=NOCLKDIV ; CPU runing at full speed
CONFIG USBDIV=OFF ; Low speed USB clock diviser disabled, not used here
CONFIG FOSC=HS ; Use of High Speed crystal oscillator
CONFIG PLLEN=ON ; Enable PLL multiplier, 12Mhz oscilator x 4
CONFIG PCLKEN=ON ; Primary clock source is enabled
CONFIG FCMEN=OFF ; Failsafe clock off
CONFIG IESO=OFF ; Oscillator switchover mode disabled
CONFIG WDTEN=ON ; Watchdog timer on
CONFIG WDTPS=512 ; Watchdog divider is 512
CONFIG MCLRE=OFF ; Disable MCLR pin, enable RC3
CONFIG STVREN=ON ; Stack full/underflow will cause reset
CONFIG LVP=OFF ; Low voltage programming disabled
CONFIG BBSIZ=OFF ; 512kW block boot size
CONFIG XINST=OFF ; Extended instruction mode disabled
ENDASM

Include "cdc_desc.bas" ' Include the CDC descriptors
INCLUDE "USB_ASM_Service.pbp" ' USB Init and Service interrupt routines

'Define pin function
TRISA = %00000000 'PortA all digital output
TRISB = %00000000 'PortB all digital output
TRISC = %00000000 'PortC all digital output

ANSEL = %00000000 'Disable analog input on other pins
ANSELH = %00000000 'Disable analog input on other pins

'Define weak pullups
WPUA = %00000000 'No weak pullup on portA
WPUB = %00000000 'No weak pullup on portB

Define OSC 48

buffer VAR BYTE[16]
cnt VAR BYTE Byte
i VAR BYTE

'Pin function declaration

GreenLED VAR PORTC.6
RedLED VAR PORTC.3
BlueLED VAR PORTC.4

pwmvalue VAR BYTE

'Program start

pwmvalue = 130
HPWM 1,pwmvalue,32767

LOW REDLED
LOW BLUELED
LOW GREENLED

Pause 10

USBInit ' Get USB going

' Wait for USB input
idleloop:
USBService ' Must service USB regularly
cnt = 16 ' Specify input buffer size
USBIn 3, buffer, cnt, idleloop

i = 0

SELECT CASE buffer
CASE "R"
HIGH REDLED
LOW GREENLED
LOW BLUELED
CASE "G"
LOW REDLED
HIGH GREENLED
LOW BLUELED
CASE "B"
LOW REDLED
LOW GREENLED
HIGH BLUELED
CASE "C"
LOW REDLED
HIGH GREENLED
HIGH BLUELED
CASE "M"
HIGH REDLED
LOW GREENLED
HIGH BLUELED
CASE "Y"
HIGH REDLED
HIGH GREENLED
LOW BLUELED
CASE "W"
HIGH REDLED
HIGH GREENLED
HIGH BLUELED
CASE "K"
LOW REDLED
LOW GREENLED
LOW BLUELED
CASE ELSE
i = 1
END SELECT

' Message received

IF i = 0 THEN
buffer[0] = buffer
buffer[1] = "-"
buffer[2] = "O"
buffer[3] = "k"
buffer[4] = 13
buffer[5] = 10
buffer[6] = 0
ELSE
buffer[0] = "E"
buffer[1] = "r"
buffer[2] = "r"
buffer[3] = "."
buffer[4] = 13
buffer[5] = 10
buffer[6] = 0
ENDIF


outloop:
USBService ' Must service USB regularly
USBOut 3, buffer, 7, outloop
Goto idleloop ' Wait for next buffer

It is a quick and dirty modification of the CDC demo. A RGB LED takes the color code sent on the USB port as a letter. The code works, but commenting USBInit, and both USBService kill it.

mackrackit
- 24th August 2010, 15:54
LOW REDLED
LOW BLUELED
LOW GREENLED

Pause 10

USBInit * *' Get USB going
When using Darrel's includes do not add any USBInit.

rsocor01
- 24th August 2010, 21:53
If I understand correctly the timing issue will also "kill" I2CRead/Write, Shiftin/Shiftout, LCDout... There's hardware modules for SPI and I2C, even if they are not used by these instructions. However there's not much solution for driving the LCD.

I use I2CRead/Write and LCDout with a USB connection at the same time with no problems. However, I haven't tried using Shiftin/Shiftout and USB at the same time.

I got the LCDout command working together with the USB connection thanks to the great help from DT. You can see the details in the next link

http://www.picbasic.co.uk/forum/showthread.php?t=12014&daysprune=-1

Robert

aberco
- 25th August 2010, 03:44
Hi mackrackit and thanks for your attention,

"When using Darrel's includes do not add any USBInit"

Yes I know that, however if I comment USBInit and USBService it kill the program. It still run but it is not seen by the computer anymore. The include seems to be effective as I can use the PLUGGED, RX_READY and TX_READY variables inside my program without declaring them. They all read 0 whatever is happening though...

Was it tested on a 13/14K50 before? With CDC profile? or am I doing something wrong? The usage seems pretty straightforward though...

rsocor01, it is nice to know that all these can be used. Darrel's code for handling the USB is a nice time saver over handling USBService manually. It's just a nightmare when the program gets complicated.

Thanks to both of you,
Antoine.

mackrackit
- 25th August 2010, 05:32
Was it tested on a 13/14K50 before? With CDC profile? or am I doing something wrong? The usage seems pretty straightforward though...

I never have but I am sure Darrel did...


buffer[0] = buffer
That will not work.

aberco
- 25th August 2010, 06:47
Ok, let's just go back to the original demo without any alteration:


' USB sample program for PIC18F4550 CDC serial port emulation
' Requires PBP 2.60 or later

' Compilation of this program requires that specific support files be
' available in the source directory. For detailed information, see
' the file PBP\USB18\USB.TXT.

ASM
CONFIG CPUDIV=NOCLKDIV ; CPU runing at full speed
CONFIG USBDIV=OFF ; Low speed USB clock diviser disabled, not used here
CONFIG FOSC=HS ; Use of High Speed crystal oscillator
CONFIG PLLEN=ON ; Enable PLL multiplier, 12Mhz oscilator x 4
CONFIG PCLKEN=ON ; Primary clock source is enabled
CONFIG FCMEN=OFF ; Failsafe clock off
CONFIG IESO=OFF ; Oscillator switchover mode disabled
CONFIG WDTEN=ON ; Watchdog timer on
CONFIG WDTPS=512 ; Watchdog divider is 512
CONFIG MCLRE=OFF ; Disable MCLR pin, enable RC3
CONFIG STVREN=ON ; Stack full/underflow will cause reset
CONFIG LVP=OFF ; Low voltage programming disabled
CONFIG BBSIZ=OFF ; 512kW block boot size
CONFIG XINST=OFF ; Extended instruction mode disabled
ENDASM

Include "cdc_desc.bas" ' Include the CDC descriptors
INCLUDE "USB_ASM_Service.pbp" ' USB Init and Service interrupt routines

'Define pin function
TRISA = %00000000 'PortA all digital output
TRISB = %00000000 'PortB all digital output
TRISC = %00000000 'PortC all digital output

ANSEL = %00000000 'Disable analog input on other pins
ANSELH = %00000000 'Disable analog input on other pins

'Define weak pullups
WPUA = %00000000 'No weak pullup on portA
WPUB = %00000000 'No weak pullup on portB

Define OSC 48

buffer Var Byte[16]
cnt Var Byte

'Pin function declaration

Pause 10

' USBInit ' Get USB going

' Wait for USB input
idleloop:
' USBService ' Must service USB regularly
cnt = 16 ' Specify input buffer size
USBIn 3, buffer, cnt, idleloop

' Message received
buffer[0] = "H"
buffer[1] = "e"
buffer[2] = "l"
buffer[3] = "l"
buffer[4] = "o"
buffer[5] = " "
buffer[6] = "W"
buffer[7] = "o"
buffer[8] = "r"
buffer[9] = "l"
buffer[10] = "d"
buffer[11] = 13
buffer[12] = 10
buffer[13] = 0

outloop:
' USBService ' Must service USB regularly
USBOut 3, buffer, 14, outloop

Goto idleloop ' Wait for next buffer


... does not work.

I must say that after 2 days of digging the forum and the internet I am starting to get clueless about what to do to solve it. Is there a timer or an interrupt register to set up manually in order to run it properly? I could try to run it on a 18F4550 board I have but that won't solve the problem for my 13K50 project.

Also, I found out that USB_ASM_Service.pbp does not work in conjunction with INDT_INTS-18.bas and SPWM_INT.bas from Darell. I will need at least the latter, so maybe I should find another solution than actually trying to use USB_ASM_Service.pbp.

Any idea for troubleshooting this? or pointing to an interrupt solution that I could use? I'm starting to get clueless. Any help greatly appreciated!

BTW, I'm running PBP 2.60 in MCS 4.0.0.0, in conjunction with MPLAB 8.53.

mackrackit
- 25th August 2010, 16:42
Looks like we will have to wait till Darrel gets back to help with his includes, I do not see where the problem is.

If you do not use USB_ASM_Service.pbp the USB works?

aberco
- 25th August 2010, 17:02
Yes, it does not matters if I comment USB_ASM_Service.pbp or not. The demo does work perfectly with USBINIT and USBService, but as soon as I comment these I loose USB enumeration.

I also wish to use USB_ASM_Service.pbp in conjunction with Darrel's SPWM_INT.bas which does not seems possible right now (it gives an INTHAND symbol cannot be refefined error, which is normal because it appears twice). I could do the USBService interrupt with the SPWM interrupt at the same time... I do not have tight frequency requirements for the PWM signal (about 100Hz or more), what I'm interested in is the duty cycle. The main idea of my project is based on controlling the brightness of 3 LEDs by sending serial commands through USB CDC. I have to use the 13K50 for this application, but there's only one ECCP module.

But first things first, making USB_ASM_Service.pbp work with the demo! Hopefully Darrel can spare a little time to check what is going wrong here.

mackrackit
- 25th August 2010, 22:02
I am not at a place to test this to see if it makes a difference or not...

I (for no good reason) have this after all DEFINES and Variable declarations.

Include "cdc_desc.bas" ' Include the CDC descriptors
INCLUDE "USB_ASM_Service.pbp" ' USB Init and Service interrupt routines
Which is where your first USBInt is...

And maybe for the other ISR.
From USB_ASM_SERVICE.pbp

To use other high priority interrupts you can add the define *
'* DEFINE INT_HOOK handlers *
'* handlers will be called on each high priority interrupt *
'* The handlers must be ASM Interrupt compatible

aberco
- 26th August 2010, 01:52
I can easily do the test, moved the includes just before the start of the main program with the same result, does not enumerate :(. Still work like a charm the old way though.

Tomorrow I will get my 18F4550 board out and try.

aberco
- 16th September 2010, 16:52
I could not get the CDC demo to run on my 18F4550 board, (though, 3 years ago it was running fine... but since then I changed PBP, MCS and PMLAB versions...). I however did no progress regarding the 13K50 issue in three weeks, I just can't figure what's wrong, what to modify, or where to look for. Is there a need to enable an hardware timer to run the interrupt?

Unfortunately the same apply for running more than one interrupt-based routine from Darrel, using the DEFINE INT_HOOK handlers. I have not been able to find any example for it, and I don't really understand how to makes it work.

Any help would be greatly appreciated :)

mackrackit
- 16th September 2010, 17:20
Which version of PBP are you currently using?

aberco
- 16th September 2010, 17:27
I'm running PBP 2.60 in MCS 4.0.0.0, in conjunction with MPLAB 8.53.

mackrackit
- 16th September 2010, 17:36
Some things have changed with PBP 2.6. Maybe that is the problem?
Have you seen this?
http://www.picbasic.co.uk/forum/showthread.php?t=5806&p=80301#post80301

aberco
- 16th September 2010, 17:45
Yes I know this post was my starting point.


Copy the PBP\USB18 folder to a new location.
You do not want any files left over from previous versions of PBP, so don't try to copy it into an existing project folder.

Open and compile cdc_demo.bas with the proper chip selected.
Program the chip and test. Done deal.

That is exactly what I did, and it does work.

It is when I add Darrel USB_ASM_Service.pbp and remove the original USBINIT/USBSERVICE that the PIC does not enumerate anymore...

A last resort idea would be to USBSERVICE using a Timer0 interrupt, but Darrel solution adds more fancy controls such as the ability to know if the link is established, or if Tx/Rx operations are available/possible. This would be a nice addition to prevent any USB buffer fill and lock-up of the PIC.

(PS. I tried to send a private message to Darrel about 3 weeks ago but had no reply).

mackrackit
- 16th September 2010, 18:00
Darrel has been out of town. He is sorta back now so maybe he will be able to help now.

aberco
- 16th September 2010, 22:34
Ok, I tried some debug attempt with some LED blink, which show me that the interrupt handler "DoUSBSERVICE" within Darrel's routine is not called.

This is what should do the USBSERVICE. Is there something to do to link this handler to an interrupt? should I configure a timer for this? I have deactivated the watchdog timer if that could explain why the handler is not working...
I do not understand what triggers this interrupt. I've tried to call it manually within the USBIN loop using a GOSUB, but that does not help getting the PIC to enumerate...

Darrel Taylor
- 17th September 2010, 02:07
Aberco,

Sorry, I deleted your modification because it was silly to use Timer0 for USB interrupts, and it won't detect Plugged, RX, or TX, that way.
Plus I don't want that code floating around.
Some Patience is required until I get settled. I don't have any computers or internet access at night right now.

I believe that all you need to do is change the USBIE and USBIF bits because Microchip moved them in the 13K50/14K50.
They used to be PIE2.5 and PIR2.5 in the 4550 family. Now they are PIE2.2 and PIR2.2 in those chips.

Please download the file again to start from scratch, then change to ...


USBIE VAR PIE2.2 ; USB funnel Interrupt Enable
USBIF VAR PIR2.2 ; USB Interrupt Flag

aberco
- 17th September 2010, 09:23
Simple enough, and worked great!

May I ask what drives the USBSERVICE interrupt?
Also I would like to use DT_INTS-18.bas in the program as well but I don't understand how to use the interrupt hook handler, and could not find any example of it.

Take your time, there's no hurry, I can now spend some time to play with USB data transmission :D

Thanks a lot for the great help.

aberco
- 17th September 2010, 17:02
Or... is there a way to turn DT_HID260 into a DT_CDC260? is there something I could use in the cdc_desc.bas file (contained in the USB demo folder) to do such thing or is it more complicated than transferring a series of values?

Darrel Taylor
- 20th September 2010, 00:36
> May I ask what drives the USBSERVICE interrupt?
The USB module itself generates many different interrupts.

> Also I would like to use DT_INTS-18.bas in the program as well
> but I don't understand how to use the interrupt hook handler,
> and could not find any example of it.
That is not possible with USB_ASM_Service.pbp.
All interrupts used with the "Hook" can only be ASM (assembly language) type interrupts.

> Or... is there a way to turn DT_HID260 into a DT_CDC260?
No, but I could write a DT_CDC program. If I ever get my computers and internet access at home. :rolleyes:

aberco
- 20th September 2010, 14:23
Ok, that was my understanding of the interrupt hook handler. Hmmm that will make things more difficult. A DT_CDC would be extremely helpful in my case, but that is a lot to ask...

I will think about it, currently I have two different application, both that need to use the CDC profile (HID could work, but that would make programming more difficult on the computer side... also it is nice to use a terminal to drive the device without any dedicated software).
One application needs Timer1 to do precise timing sampling, the second needs your multiple software PWM routine to drive 3 LEDs.

Darrel Taylor
- 22nd September 2010, 18:09
aberco,

Here's a little ditty that should get you going with servicing CDC and DT-INTS-18.
Hope it helps.

DEFINE OSC 48

INCLUDE "cdc_desc.bas"

;--- Setup Interrupts ------------------------------------------------------
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler USB_INT, _DoUSBSERVICE, ASM, yes
INT_Handler INT_INT, _Handle_INT, PBP, yes
endm
INT_CREATE ; Creates the Low Priority interrupt processor

INT_ENABLE USB_INT
INT_ENABLE INT_INT
ENDASM


;----[Initialise USB and Interrupts]----------------------------------------
PAUSE 100 ; Allow VUSB to stabilize
USBINIT ; initialize the USB driver
USBSERVICE ; service it once
UIE = $7F ; enable USB interrupts
UEIE = $9F ; enable USB Error interrupts

;----[Main program loop]----------------------------------------------------
Main:
; some code here
GOTO Main

;----[Interrupt handler -- Service USB]-------------------------------------
DoUSBSERVICE:
USBSERVICE ; Run the SERVICE routines
@ INT_RETURN

;----[Interrupt handler -- INT]
Handle_INT:
; something here
@ INT_RETURN

aberco
- 22nd September 2010, 18:57
Thanks Darrel, I will play with this in a couple of days, it looks like this would do the trick.

What I really like in your DT_HID260 is that all USB dependent declaration are clearly listed within the program. I feel it is better and self-contained than digging cdc_desc.bas to modify the values, but maybe it works just the same at the end. I am now planning to use a bootloader as well, so I will have to check if two independent USB setup can be used one after the other without creating conflict.

aberco
- 7th October 2010, 00:28
Well I must say that I'm still banging my head against USB CDC... I've tried this, the led does blink for 1 1/2 cycles and everything hangs and the pic does not enumerate.
Now, is it because USB is serviced before the device is attached?

I changed the interrupt from "ASM" to "PBP" (USBSERVICE is a PBP instruction).


'************************************************* ******
'Config fuses for PIC18LF14K50
'************************************************* ******

ASM
CONFIG CPUDIV=NOCLKDIV ; CPU runing at full speed
CONFIG USBDIV=OFF ; Low speed USB clock diviser disabled, not used here
CONFIG FOSC=HS ; Use of High Speed crystal oscillator
CONFIG PLLEN=ON ; Enable PLL multiplier, 12Mhz oscilator x 4
CONFIG PCLKEN=ON ; Primary clock source is enabled
CONFIG FCMEN=OFF ; Failsafe clock off
CONFIG IESO=OFF ; Oscillator switchover mode disabled
CONFIG WDTEN=ON ; Watchdog timer on
CONFIG WDTPS=512 ; Watchdog divider is 512
CONFIG MCLRE=OFF ; Disable MCLR pin, enable RC3
CONFIG STVREN=ON ; Stack full/underflow will cause reset
CONFIG LVP=OFF ; Low voltage programming disabled
CONFIG BBSIZ=OFF ; 512kW block boot size
CONFIG XINST=OFF ; Extended instruction mode disabled
ENDASM


DEFINE OSC 48
DEFINE LOADER_USED 1

'************************************************* ******
'Init for PIC18LF14K50
'************************************************* ******

'Set ADC pins to digital operation
ADCON0 = %00000000 'turn ADC OFF
CM1CON0 = %00000000 'disabling comparator module 1
CM2CON0 = %00000000 'disabling comparator module 2

'Define pin function
TRISA = %00000000 'PortA all digital output
TRISB = %00000000 'PortB all digital output
TRISC = %00000000 'PortC all digital output

ANSEL = %00000000 'Disable analog input all pins
ANSELH = %00000000 'Disable analog input all pins

RedLED VAR PORTC.3

INCLUDE "cdc_desc.bas"

;--- Setup Interrupts ------------------------------------------------------
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler USB_INT, _DoUSBSERVICE, PBP, yes
endm
INT_CREATE ; Creates the Low Priority interrupt processor

INT_ENABLE USB_INT
ENDASM

;----[Initialise USB and Interrupts]----------------------------------------
PAUSE 100 ; Allow VUSB to stabilize
USBINIT ; initialize the USB driver
USBSERVICE ; service it once
UIE = $7F ; enable USB interrupts
UEIE = $9F ; enable USB Error interrupts

;----[Main program loop]----------------------------------------------------
Main:
HIGH RedLED
PAUSE 200
LOW REDLED
PAUSE 200
GOTO MAIN

;----[Interrupt handler -- Service USB]-------------------------------------
DoUSBSERVICE:
USBSERVICE ; Run the SERVICE routines
@ INT_RETURN

END

Darrel Taylor
- 7th October 2010, 01:13
Try moving the USB enable to after the initialization.


; INT_ENABLE USB_INT
ENDASM

;----[Initialise USB and Interrupts]----------------------------------------
PAUSE 100 ; Allow VUSB to stabilize
USBINIT ; initialize the USB driver
USBSERVICE ; service it once
UIE = $7F ; enable USB interrupts
UEIE = $9F ; enable USB Error interrupts
@ INT_ENABLE USB_INT

Enabling before USBINIT probably wasn't a good idea on my part.

And while USBSERVICE is a PBP statement, the code is all ASM and does not use any of PBP's system variables. So change it back to ASM "type".

aberco
- 7th October 2010, 01:46
Hmm that make sense... I made the changes but that doesn't work any better though.

A little troubleshooting, if I plug the USB connector halfway (just Power) the LED blink, however it stops a couple 100's ms after D+/D- get connected.

Darrel Taylor
- 7th October 2010, 02:17
I may have asked you this in another thread, sorry if I did ... but ...

What size capacitor do you have on VUSB.
0.22 - 0.47uF?

aberco
- 7th October 2010, 10:17
Hardware is fine, USB does work with DT_HID260. I have two prototype boards with 220nF, both are ok. Config fuses are OK too, should be software-related.

Darrel Taylor
- 8th October 2010, 02:08
Well, I've got a 14K50 here now, and it enumerates and holds the USB just fine.
So far I haven't got a single blink out of RC3 yet though.

Not sure what's going on there, but I'll play with it some more tomorrow.

I'll add some USBIN/USBOUT statements too and make sure CDC is really working.

What operating system are you using?
Win7-64 here.

aberco
- 8th October 2010, 12:40
Well yeah, you're right! it does enumerates!!! and it even blink on my application.

What's happening, this is due to my programming setup and the specific hardwiring of the 18F1xK50. The USB lines D+/D- are shared with PGD and PGC, and it seems that in order for USB to work, the programmer has to be disconnected. For this purpose, I have purchased microchip special module for the 18F1xK50, that adapt the programming levels of the programmer to something that the PIC can accept, but at the same time allows to leave plugged the USB cable of the host computer by protecting the D+/D- lines from programming voltages.

Well I realized early on that it did not work, and I had to disconnect PGD and PGC in order to have USB working, so I added a set of switches on my programming cable.

Now I've been able to verify different behavior on USB programs, especially DT_HID260 which is the only one "powerful" enough to enumerate even with PGD/PGC connected to the programmer. All others required those lines disconnected to enumerate.

http://aberco.free.fr/imagesdivers/loggerprogram.jpg

Now, about your little CDC routine, it does work well with PGD/PGC disconnected. But when I connect them back the USB connexion drops and the PIC crashes. No big deal, but I'll have to make sure that communication is established when servicing, and especially turn it of before unplugging USB.

Now I'll try to add USBIN/USBOUT statements and play a bit with communication before building the full program around it. Thanks for your great help!

aberco
- 8th October 2010, 18:56
Well, more progress, and so far so good!
In understood that your program proposal is actually a stripped off version of your USB_ASM_Service routine. I have been able to use it within my program now, but calling the DoUSBSERVICE routine using the USB interrupt triggered by your interrupt routine.

So far so good, it does enumerate, and more importantly I have all the control options given by the connected state, Tx/Rx ready. The LED always blink regardless of what the USB is doing.

The only thing that seems to break the code is "DEFINE RESET_ORG 2048 ' Start code at $0800", I added this at the very top to be ready for the bootloader implementation (leaving 1 kWords available). Probably a problem of memory bank and interrupt...

Seems to work very well so far... I am not posting the code until it is ok with you.

aberco
- 9th October 2010, 00:21
Trying to implement a "console like" behavior but cannot get it to work.

I'm using RX_Ready to read USB and then entering the desired reaction regarding the received command. However it seems that after doing an USBIn command, RX_Ready does not stay = 0 for very long, even if absolutely no data is received.

Is RX_Ready indicating a capacity to receive data (buffer not full), just like TX_Ready? In that case I cannot use this to trigger an event upon packet receive...

To better explain it here is some very dirty code.


MainLoop:

ARRAYWRITE USBBuffer, [">"]
GOSUB DoUSBOut

GOSUB DoUSBIn

SELECT CASE USBBuffer [0]
CASE "A", "a"
GOSUB EchoData
ARRAYWRITE USBBuffer, ["OK", 10, 13]
Gosub DoUSBOut
CASE ELSE
GosuB EchoData
ARRAYWRITE USBBuffer, ["Error", 10, 13]
GOSUB DoUSBOut
END SELECT

PAUSE 1000

GOTO MainLoop

'************************************************* ******
'Echo sent frame back
'************************************************* ******
EchoData:

GOSUB DoUSBOut
ARRAYWRITE USBBuffer, [10, 13]
GOSUB DoUSBOut

RETURN


I'm confused yet about very simple things, like how to clear the buffer between requests. Also here it is polled every seconds, because I do not know how to trigger the event upon packet received... Tried to look for helpful examples without any luck.

Darrel Taylor
- 9th October 2010, 19:54
If you are trying to tie together USB_ASM_Service and the routine I gave in this thread, it won't work as is.

CDC uses a different endpoint than HID.

aberco
- 9th October 2010, 21:15
Well, I managed to make it all work... possibly partially but so far so good!

I can send and receive 32 bytes packets. However as you said I may have not modofied everything which makes TX_Ready and RX_Ready non functional. However they are tied to USB registers and should not be dependent to endpoints if my understanding of the datasheet was correct...

http://aberco.free.fr/imagesdivers/serialterm.png

I'm pasting here part of the main code that I used:


INCLUDE "cdc_desc.bas"
INCLUDE "EEPROM_detect.pbp"

'************************************************* ******
'Init the interrupt handling system
'************************************************* ******
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler USB_INT, _DoUSBSERVICE, PBP, yes
INT_Handler TMR1_INT, _TempCheck, PBP, Yes
INT_Handler INT0_INT, _USBAttached, PBP, Yes
endm
INT_CREATE ; Creates the Low Priority interrupt processor
ENDASM

INCLUDE "USB_ASM_Service.pbp"

aberco
- 12th October 2010, 12:06
Last edited by Darrel Taylor; - 10th October 2010 at 16:56. Reason: Incorrect Mod

Well ok, but what does makes it incorrect?

aberco
- 12th October 2010, 18:18
Ok, there's indeed something that relates to endpoint. I understand that you use two bytes located within the USB RAM space to get the TX and RX reports.


BD1STATOUT = _USBMEMORYADDRESS + 8 ; 408h or 208h
BD1STATIN = _USBMEMORYADDRESS + 0Ch ; 40Ch or 20Ch

Now I'm clueless about what this refers to... tried to look at the hid_desc.pbp/asm code and compare it with cdc_desc.pbp/asm, and also to look on the net for RAM endpoint allocation at these two address but no luck so far

aberco
- 13th October 2010, 23:20
Follow up on the monologue, and after a day of digging through literature, I now have a slightly deeper understanding of the USB protocol. The more helpful was Microchip datasheet, within the USB section related to BDT RAM.

http://aberco.free.fr/imagesdivers/bdtram.jpg

200h is start of USB RAM for PIC18F1xK50, 400h for 18Fx550/x455/x450.

I moved the allocations to Endpoint 3 for CDC usage:


RXOWNED VAR BD3STATOUT.7 ; Out report Owned (OUT is PC to PIC)
TXOWNED VAR BD3STATIN.7 ; IN report Owned (IN is PIC to PC)
-------------------------------------------------------------------------------------------------------
BD3STATOUT = _USBMEMORYADDRESS + 18h ; 418h or 218h
BD3STATIN = _USBMEMORYADDRESS + 1Ch ; 41Ch or 21Ch


Bit 7 of BDxSTAT states which device (SIE or CPU) owns the right to write or read into the dual ported USB RAM space, so this is what is used for the TX and RX ready flag.

For some reason the compiler doesn't like the 3 in "BD3STATOUT and BD3STATIN" (Bad data type error). CONFIGURED_STATE should not differs between HID or CDC as it is not endpoint dependent.

Darrel Taylor
- 13th October 2010, 23:38
I moved the allocations to Endpoint 3 for CDC usage:
...
For some reason the compiler doesn't like the 3 in "BD3STATOUT and BD3STATIN"
You missed the EXT vars ...


BD3STATOUT VAR BYTE EXT ; OUT report status byte
BD3STATIN VAR BYTE EXT ; IN report status byte

aberco
- 14th October 2010, 00:12
Ah thanks! that was just above, an easy fix.

RX_Ready seems to work! but TX_Ready is always true... maybe because the time when the OUT endpoint is owned by the SIE is so short that I can't see it? However if I do a loop that sends data as soon as the SIE is ready I have huge data loss.
Right now I have to add a 200ms delay between each 32Bytes packets I send in order to avoid data transmission loss. It is rather slow... reading a 24LC512 at this speed would take a bit less than 4h.

Am I missing something here?

Darrel Taylor
- 14th October 2010, 17:14
My shipping container just arrived yesterday with all my stuff from California, still unloading it.
Hopefully I can get some computers setup soon to be able to work on this stuff again.

Can't sit in the forum at work, just too busy during the day.

If you haven't figured it out by next week, I'll be back on it.
Sorry, I haven't been much help.

aberco
- 14th October 2010, 17:27
No Darrel, you have been very helpful so far, at least to set me on the right course to fix issues.

I'm much more of an hardware person, getting better and better at programming but some time simple software tricks are not obvious to me... However when it comes to reading datasheets and understanding hardware peripherals, registers and configuration bits I feel at home.

I will carry on progress one step at a time :)

aberco
- 15th October 2010, 17:02
I think that most of my USB problems are solved now!

I rewrote the USB Out routine as such:


'************************************************* ******
'Writing data to USB port
'************************************************* ******
DoUSBOut:

USBBufferSizeTX = 0
FOR Counter = 1 TO USBBufferSizeMax 'Calculate number of valid bytes within the string
IF USBBuffer [Counter - 1] > 0 THEN USBBufferSizeTX = USBBufferSizeTX + 1
NEXT Counter

IF TX_READY THEN 'USB data can be transmitted
TX_READY = 0 'Clear USB data send flag
USBOUT 3, USBBuffer, USBBufferSizeTX, DoUSBOut
ENDIF

FOR Counter = 1 TO USBBufferSizeMax 'Clear the USB buffer after data has been sent
USBBuffer [Counter - 1] = 0
NEXT Counter

RETURN

- Fist step is to calculate how many bytes are used in the string (not = 0)
- Second, sending data
- third, blanking the data buffer for next operation

I have no more garbage data in my strings, and I was able to remove the Pause without any data loss. Transmission is very fast now, with over 10kB/s (I have large conversion routines between my DoUSBOut, could even be faster without these).

Now onto other problems, especially getting all the interrupts to work together,and implementing ADC and ultra-low power routine.

What about publishing the generic code for CDC? I'll let you decide since it is actually minor modification to code you have written.

aberco
- 10th December 2011, 18:40
And everything collapsed!

The CDC USB routine was working well until now. It is working very well on my early prototypes, I made 3 more identical one and the PIC just stop running randomly after a few seconds up to several minutes. USB communication stops and LEDs turns off. It still respond to the INT0 interrupt though, and resume normal operation after reset... until it crashes again randomly.

I am puzzled as the hardware is strictly identical, the only difference I could spot is in the silicon revision of the PIC18LF14K50, says 0000006 on the working batch and 0000005 on the batch that crashes. I have inserted a simple blinking LED loop routine at the very beginning of my code, and it still crashes and stop blinking. Removing part of the program related to USB solve the crashing problem so I would think that there is something wrong in the USB CDC code I have modified.

Problem is that in the revision errata there is nothing linked to the USB SIE, and I am totally clueless about where to start to debug this issue. What could be wrong to have the PIC crash at a random time interval? some kind of buffer overflow?

aberco
- 10th December 2011, 21:06
A bit more debugging, it seems that only the USBIN side does crash.


'************************************************* ******
'Reading incoming data from USB port
'************************************************* ******
DoUSBIn:

FOR counter = 1 TO USBBufferSizeMax 'Clear the USB buffer before data is received
USBBuffer [counter - 1] = 0
NEXT COUNTER

WHILE !RX_READY
GOSUB UpdateLEDStatus
WEND

IF RX_READY THEN
RX_READY = 0 'Clear USB data received flag
USBBufferCount = USBBufferSizeRX
USBIn 3, USBBuffer, USBBufferCount, DoUSBIn
ENDIF

RETURN

At random the UpdateLEDStatus subroutine stop to be serviced, and the USBIN does not receive anymore data. When it crashes, RX_READY = 0, then if I send data RX_READY = 1 and just stay there, without being cleared. the USBOUT side toes work well though, even when the IN side has crashed.

Might have something to do with USB_ASM_Service.pbp not working properly?

-> A bit more debug introducing some LED blink to see if the USB_ASM_Service is being called: it stops being called when it crashes...

aberco
- 10th December 2011, 22:10
Well.. finally was able to track the problem down to a conflict between the use of SPWM_INT.bas and USB_ASM_Service.pbp. If I disable the Timer1 interrupt used for sPWM then the USB works well. Strange thing is that the code works well on 3 prototypes with the older PIC silicon revision, and does not work with 3 prototypes with the newer silicon revision...

Anyway, here is the debug program I have that run the sPWM and at the same time read a string from USB and send it back (using CDC serial port emulation).


INCLUDE "cdc_desc.bas"


INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts


INCLUDE "SPWM_INT.bas"


INCLUDE "USB_ASM_Service.pbp"


' USB status variable handled by USBASMService
' "PLUGGED" indicates when the device is fully connected to the PC
' "RX_READY" indicates when a report has been received
' "TX_READY" indicates when it's OK to Send. The device is Plugged and the SIE is ready to accept data


'************************************************* ******
'Init the software multi_PWM system
'************************************************* ******


DEFINE SPWM_FREQ 200 'SPWM Frequency
DEFINE SPWM_RES 256 'SPWM Resolution


DutyCycles VAR BYTE [3] 'DutyCycle Variables
RedDutyCycle VAR DutyCycles [0]
GreenDutyCycle VAR DutyCycles [1]
BlueDutyCycle VAR DutyCycles [2]


ASM
SPWM_LIST macro ;Define Pin's to use for SPWM and the associated DutyCycle variables
SPWM_PIN PORTC, 3, _RedDutyCycle
SPWM_PIN PORTC, 6, _GreenDutyCycle
SPWM_PIN PORTC, 4, _BlueDutyCycle
endm
SPWM_INIT SPWM_LIST ;Initialize the Pins
ENDASM


'************************************************* ******
'Init the interrupt handling system
'************************************************* ******


ASM
;----[High Priority Interrupts]-------------------------
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler USB_INT, _DoUSBSERVICE, ASM, yes
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the High Priority interrupt processor
ENDASM


'************************************************* ******
'BlueTooth module initialisation
'************************************************* ******


@ INT_ENABLE USB_INT ; Enable USB Servicing interrupt
@ INT_ENABLE TMR1_INT ; Enable PWM interrupt


'************************************************* ******
'Main program loop
'************************************************* ******
MainLoop:


GOSUB DoUSBIn


GOTO MainLoop


'************************************************* ******
'Reading incoming data from USB port
'************************************************* ******
DoUSBIn:


FOR counter = 1 TO USBBufferSizeMax 'Clear the USB buffer before data is received
USBBuffer [counter - 1] = 0
NEXT COUNTER


WHILE !RX_READY
PAUSEUS 5
WEND


IF RX_READY THEN
RX_READY = 0 'Clear USB data received flag
USBBufferCount = USBBufferSizeRX
USBIn 3, USBBuffer, USBBufferCount, DoUSBIn
ENDIF


GOSUB DoUSBOUT


RETURN


'************************************************* ******
'Writing data to USB port
'************************************************* ******
DoUSBOut:


USBBufferSizeTX = 0
FOR counter = 1 TO USBBufferSizeMax 'Calculate number of valid bytes within the string
IF USBBuffer [counter - 1] > 0 THEN USBBufferSizeTX = USBBufferSizeTX + 1
NEXT COUNTER


IF TX_READY THEN 'USB data can be transmitted
TX_READY = 0 'Clear USB data send flag
USBOUT 3, USBBuffer, USBBufferSizeTX, DoUSBOut
ENDIF


HSEROUT [STR USBBuffer \USBBufferSizeTX]


ClearUSBBuffer:


FOR counter = 1 TO USBBufferSizeMax 'Clear the USB buffer after data has been sent
USBBuffer [counter - 1] = 0
NEXT COUNTER


RETURN


END

aberco
- 22nd December 2011, 16:35
After debugging everything pinpoint an issue coming from the different revision of the PIC. The CDC routine works with silicon revision 0000006 of the PIC18LF14K50, but not 0000005.
Really getting stuck there as I have no clue of how to solve the problem, and I cannot rely on ordering a specific revision of the microcontroller...