CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

USB CDC corrupt RAM data - Only one byte

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
E_Blue



Joined: 13 Apr 2011
Posts: 417

View user's profile Send private message

USB CDC corrupt RAM data - Only one byte
PostPosted: Fri Jul 18, 2014 2:04 pm     Reply with quote

Hi, I'm having an issue with USB CDC Driver, PIC side

CCS v5.025
PIC18F67J50

I have the variable ID defined as

Code:
char ID[5];


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

View user's profile Send private message

PostPosted: Fri Jul 18, 2014 2:36 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 18, 2014 7:36 pm     Reply with quote

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: 19470

View user's profile Send private message

PostPosted: Sat Jul 19, 2014 3:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 21, 2014 7:35 am     Reply with quote

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. Confused
_________________
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

View user's profile Send private message

PostPosted: Mon Jul 21, 2014 9:31 am     Reply with quote

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. Sad

I think some interrupt is mishandling the BSR.
_________________
Electric Blue
Ttelmah



Joined: 11 Mar 2010
Posts: 19470

View user's profile Send private message

PostPosted: Mon Jul 21, 2014 2:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 21, 2014 2:53 pm     Reply with quote

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: 19470

View user's profile Send private message

PostPosted: Mon Jul 21, 2014 11:44 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jul 22, 2014 7:12 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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