|
|
View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
USB CDC corrupt RAM data - Only one byte |
Posted: Fri Jul 18, 2014 2:04 pm |
|
|
Hi, I'm having an issue with USB CDC Driver, PIC side
CCS v5.025
PIC18F67J50
I have the variable ID defined as
When I have an ASCII character 7 on ID[0], ID[2] start to go up
I.E.: If ID[2] = '3' the next corrupt value will be ID[2]='4', next ID[2]='5' and so on.
ID[0] is located at 0x3A4 so I search on disassembling list the value 0xA6 and found this
Code: | 659: char usb_cdc_getc(void)
660: {
661: char c;
662:
663: while (!usb_cdc_kbhit())
11742 0101 MOVLB 0x1
11744 B1A4 BTFSC 0xa4, 0, BANKED //<--- Here 1
11746 D001 BRA 0x1174a
664: {
665: #if defined(USB_ISR_POLLING)
11748 D7FD BRA 0x11744
666: usb_task();
667: #endif
668: }
669:
670: c=usb_cdc_get_buffer_status_buffer[usb_cdc_get_buffer_status.index++];
1174A 51A6 MOVF 0xa6, W, BANKED
1174C 2BA6 INCF 0xa6, F, BANKED //<--- Here 2
1174E 0FA3 ADDLW 0xa3
11750 6EE9 MOVWF FSR0L, ACCESS
11752 0E04 MOVLW 0x4
11754 6EEA MOVWF FSR0H, ACCESS
11756 B0D8 BTFSC STATUS, 0, ACCESS
11758 2AEA INCF FSR0H, F, ACCESS
1175A CFEF MOVFF INDF0, 0x966
|
As you can see if bit 0 of 0xA4 = true then increments 0xA6
If I have ID[0]='F' Nothing happen, all works OK; I think because the bit zero is set.
In my Main() routine I have an infinite while running and have a call to the usb_task() routine, now I disable it not calling that routine when USB_CON_SENSE_PIN is zero.
Result, the ID variable is not being corrupted until I connect the USB plug.
This, shouldn't be happening because the USB variable is in 0x1A6 and my variable (ID) is in 0x3A4.
So I think something in the handle of BSR pointer of USB Driver is wrong.
I read this thread too and seems to be similar
http://www.ccsinfo.com/forum/viewtopic.php?t=49764&view=previous
But, in my case, the corrupted data is not in the USB buffer.
Any ideas?
Thanks
Pd.: Should I call the usb_task() routine periodically from my Main() or not? Because as you can see in the code above there's a call to that routine too. _________________ Electric Blue |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Jul 18, 2014 2:36 pm |
|
|
Hi,
All my USB projects have started with the CCS examples. They work, and are a good starting point. I use the USB CDC example in a couple of projects, and I'm reliably sending data back and forth between a PC application, and the PIC. I'd recommend that you fallback to one of the working examples, and modify it from there.
BTW, the comments in the CCS USB examples note that 'USB_Task()' must be called frequently on PIC18 systems.
John |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Fri Jul 18, 2014 7:36 pm |
|
|
I can't, I been working four years in this project and now have a lot of code, plus, the USB is working OK, the problem is that specific byte in the RAM.
I'm thinking into just move the variable to another RAM position. _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sat Jul 19, 2014 3:32 am |
|
|
Try declaring ID, as static.
There was a problem a few compiler versions ago, with the BSR occasionally getting corrupted. Things that could trigger it were:
Maths in an ISR. At a certain degree of complexity, a scratch variable got overwritten.
Global variables behaved differently if declared as 'static' (aside from the initialisation differences).
I must admit I thought this was fixed a couple of versions ago, but it may still be occurring with your code.
It appears from your code, that you are using USB without interrupts (you have ISR_POLLING defined). Why?. Makes things much more likely to fail. You talk about polling usb_task, but can you _guarantee_ that this is polled fast enough all the time?. If you take even a few uSec too long, it _will_ cause failures. You can only do this, if you are using a very simple device, and can ensure that nothing in the polling loop can ever result in an interval exceeding 8msec.
There is one other thing. This is the sort of error I have seen occurring, if I use 'mid code' variable declarations, instead of sticking to the C standard of putting these at the start of a code section. If you have used such declarations, move them. |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Mon Jul 21, 2014 7:35 am |
|
|
Thanks for your answer, this is good info.
Ttelmah wrote: | Try declaring ID, as static.
There is one other thing. This is the sort of error I have seen occurring, if I use 'mid code' variable declarations, instead of sticking to the C standard of putting these at the start of a code section. If you have used such declarations, move them. |
Ok, I understand the part of declaring variables at mid code, but What about the variables outside the code?
I have a lot of them and some are Struct, in the upper section outside the code where the #defines and #includes are defined.
I will check and modify my code and post the results.
Quote: | It appears from your code, that you are using USB without interrupts (you have ISR_POLLING defined). Why? |
I tested toggling a pin in every loop cycle and seems to run a 115KHz plus doing it by pooling I can disable the USB, that's the way I found the reason of the corrupted byte; when I stop calling the usb_task() routine I get no corrupted byte
Edit:
I check my code and can't found any part of the code where USB_POLLING were defined. _________________ Electric Blue
Last edited by E_Blue on Mon Jul 21, 2014 11:40 am; edited 1 time in total |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Mon Jul 21, 2014 9:31 am |
|
|
I add some assembler code to catch the BSR error and get this.
This happen even when ID was declared as STATIC
So, as I was supposing it's a bug in the BSR handling.
I think some interrupt is mishandling the BSR. _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jul 21, 2014 2:07 pm |
|
|
You can't 'disable the USB' by using polling.
Once USB is enumerated, you as the 'slave' device, _must_ keep the USB running at all times, unless you request the host to disconnect. Otherwise you will cause problems. As such, try your code with the USB in an ISR instead of using polling. Nobody polls USB!... (I know the option is there, but it is pretty much never used). I suspect there is a problem with the code when 'polled' which has never been seen, because nobody would use this option!... |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Mon Jul 21, 2014 2:53 pm |
|
|
I check my code and the only poll is to usb_task() routine and I do it as its explained in the help.
usb_task()
If you use connection sense, and the usb_init_cs() for initialization, then you must periodically call this function to keep an eye on the connection sense pin. When the PIC is connected to the BUS, this function will then perpare the USB peripheral. When the PIC is disconnected from the BUS, it will reset the USB stack and peripheral. Will enable and use the USB interrupt _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jul 21, 2014 11:44 pm |
|
|
In which case, turn _off_ the ISR polling option.
Let the USB use interrupts.
The point is, your compiled code, shows that you have ISR_POLLING enabled. This is only wanted, if you are polling the USB peripheral, rather than letting it use interrupts.
You still poll usb_task, to handle disconnect, but this can be done at a much longer interval.
As I said before: "I suspect there is a problem with the code when 'polled'".
Having the interrupt routines 'polled', changes the way that this part of the code works.
You can still 'poll' the USB for disconnect/reconnect, but when ISR_POLLING is enabled, this same polling routine, then calls the actual USB peripheral code, which is normally sitting 'isolated' in the interrupt handler.... |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Tue Jul 22, 2014 7:12 am |
|
|
Quote: | The point is, your compiled code, shows that you have ISR_POLLING enabled. |
No, that's not like that.
If you see under the line 665 have a branch to 11744 to make the while loop, but there's not assembler code under line 666.
So, the code is there but has no effect on the assembler code generated. _________________ Electric Blue |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|