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 CCS Technical Support

USB Transfer stops suddenly

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



Joined: 10 Mar 2011
Posts: 11

View user's profile Send private message

USB Transfer stops suddenly
PostPosted: Wed Apr 06, 2011 5:11 am     Reply with quote

Hi, I'm doing a project using PIC18F2550 to get analog values, then transfer data to PC via USB cable. PC send a 1byte command valued 0x04 so that PIC can start it's job each time. Now the rate is 1 transfer/sec.
The problem is the transfer is stopped just after several hundreds transfers. Here is what I did and what i've checked:

Firmware: I'm using timer1 with overflow = 10ms to check usb rx pipe periodically (using usb_kbhit(1)), if there is a package which values 0x04, then a variable names MeasureNow will be set to 1. main() consists of a while loop which checks MeasureNow, if it is 1, then main() will take adc value and transfer data to PC. Here is the code:
Code:

//Timer1 Interrupt Service Routine
#int_timer1
void interrupt_timer1()
{
  set_timer1(Timer1StartValue_10ms);
  //check if a packet has been received over USB
  if(usb_kbhit(1))
  {
    int8 Command = 0;
    usb_get_packet(1, &Command, USB_DTS_TOGGLE);
    if(Command == GET_DATA_CMD) //host request device to transfer measure data
      MeasureNow = 1;
   }
}


main()
Code:

if(MeasureNow == 1)
//Get ADC value
...
...
//Finish getting ADC value
//Transmit data over USB cable
usb_puts(1, Data2Send, 32, 10);



On PC: I'm using Visual C++ 2005 together with driver and dll from Microchip. Here is the code
Code:


//Send command to device to get dataDWORD ActualLength;
byte Command = GET_DATA_CMD;
DWORD ActualLength;
while(!MPUSBWrite(EP1OUTHandle, &Command, 1, &ActualLength, 1000))
{
}

System::Threading::Thread::Sleep(500); //wait for PIC to get ADC value

//get data
byte Buffer[32];
MPUSBRead(EP1INHandle, Buffer, 32, &ActualLength, 1000);   //Receive the answer from the device firmware through USB


I'm using SnoopyPro to capture USB packet. This is the image of where I think the problem happens:

As you can see, normally, after PIC receives 0x04 command from PC, it replies 0x00000000 after just 2-3msec (late due to timer1). But in the first blue line, PIC replies after 43 msec (I don't know why it is so late), the reply is 0x00000005 (I think means a failure). Then PC keeps sending command over and over (it is the MPUSBWrite loop). I notice a packet names RESET_PIPE is sent then but have know idea what it does (I do not find this packet in USB2.0 Spec).
I've also checked PIC state in time of problem, MeasureNow is kept to be 1 all the time, Timer1 still works (it's register values still changes).
I don't know where the problem come from, it is quite a long post, sorry for that!
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Apr 06, 2011 7:51 am     Reply with quote

Welcome to the wonderful world of the USB aka Useless Serial Bus. Since it is not interrupt driven and running under the Windows GUI I'm not surprised at what you see.

Have you cut any PC code to invoke a simple 'loopback' test to properly test the mess that USB has to do to send/rcv a single character ?

Divide and conquer, eliminate the PIC from the problem first, get the PC side up and running flawlessly...
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Wed Apr 06, 2011 9:24 am     Reply with quote

For RESET_PIPE, do a search for 'reset_pipe URB'. Chapter 10 of the current USB spec. They are not USB packets, but a software requests to reset the host controller to it's initial state. Normally triggered by a timeout. Now a USB device, is meant to reply within a certain period to a packet addressed to it. this is why you must not have interrupts disabled in the PIC for more than about 10mSec when using USB.
Things that might cause this:
1) Having some code in the PIC that results in interrupts being disabled for a long time.
2) Bad electrical layout at the USB connector.
3) Not enough smoothing on the Vusb connection.
4) Supply problem at the PIC itself. Brownout or noise.
5) Just a faulty cable.
Plus any number of other similar problems.

Best Wishes
hawking1122



Joined: 10 Mar 2011
Posts: 11

View user's profile Send private message

PostPosted: Thu Apr 07, 2011 2:40 am     Reply with quote

temtronic wrote:
Since it is not interrupt driven and running under the Windows GUI I'm not surprised at what you see.

Have you cut any PC code to invoke a simple 'loopback' test to properly test the mess that USB has to do to send/rcv a single character ?

Divide and conquer, eliminate the PIC from the problem first,gte the PC side up and running flawlessly...

Thanks for suggestion, I see that all example codes from CCS are not interrupt driven, so I'm not sure how to start that way, do you know any code does that? Also, how to test "the mess" as you said? SnoopyPro does not provide such deep level of info. I'm reading Spec, hope it help.

Ttelmah wrote:
Things that might cause this:
1) Having some code in the PIC that results in interrupts being disabled for a long time.
2) Bad electrical layout at the USB connector.
3) Not enough smoothing on the Vusb connection.
4) Supply problem at the PIC itself. Brownout or noise.
5) Just a faulty cable.
Plus any number of other similar problems.

3) I'm using 470n cap at Vusb pin, is it smooth enough or I have to check with oscilloscope?
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Thu Apr 07, 2011 4:46 am     Reply with quote

What about the actual PIC supply?.
All the CCS USB examples, _are_ interrupt driven. Why do you think they are not?. Only turned 'off', if you define USB_ISR_POLLING, in which case the interrupt bit is polled, rather than directly used, and the polling routines must be called very frequently. USB_TASK enables the interrupt.
Look in the text header of pic18_usb.h 'NOTE ABOUT INTERRUPTS'.

Best Wishes
hawking1122



Joined: 10 Mar 2011
Posts: 11

View user's profile Send private message

PostPosted: Thu Apr 07, 2011 6:22 pm     Reply with quote

Thanks, Ttelmah, you always give me detail and useful answers!
Now I know I'm mistaken, I'm reading Spec to know how to handle when software send RESET_PIPE or ABORT_PIPE URB, I'll feedback soon.
hawking1122



Joined: 10 Mar 2011
Posts: 11

View user's profile Send private message

PostPosted: Thu Apr 07, 2011 6:24 pm     Reply with quote

One more thing, PIC is powered from usb port. I'm thinking the problem may not come from hardware, so I'm checking the code.
hawking1122



Joined: 10 Mar 2011
Posts: 11

View user's profile Send private message

PostPosted: Wed Apr 13, 2011 4:24 am     Reply with quote

I've spent a couple of days reading both USB2.0 Spec and PIC Datasheet but they didn't help much. I've used USBlyzer to check the communication and see that normally, software send packets to a driver names ACPI, then ACPI sends packets to another driver names usbhub, then I guess the packet is sent to device. At time of trouble, command packet is sent correctly to usbhub (then I guess it will be sent to device, am I correct?), but then usbhub receives packets USBD_STATUS_CANCELED. After 3 more transfers, usbhub receives USBD_STATUS_DEV_NOT_RESPONDING URB. Then software sends URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL urb to ACPI.


I do not know how to restart the communication after that, the Spec says (page 290): Resetting a Pipe: The pipe’s IRPs are aborted. The host state is moved to Active. If the reflected endpoint state needs to be changed, that must be commanded explicitly by the USBD client. But it seems that there is no way to restart using Microchip dll?
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