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

How to use USB interrupts

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



Joined: 24 Sep 2012
Posts: 4

View user's profile Send private message

How to use USB interrupts
PostPosted: Mon Sep 24, 2012 10:21 am     Reply with quote

Hi to all, this is my first post; please don't tell to check in other posts because I've just looked for my problem without results.
I want to read data with USB interrupt. The function void USB_isr() is defined in pic18_usb.c in this way:
Code:


/*****************************************************************************
/* usb_handle_interrupt()
/*
/* Summary: Checks the interrupt, and acts upon event.  Processing finished
/*          tokens is the majority of this code, and is handled by usb.c
/*
/* NOTE: If you wish to change to a polling method (and not an interrupt
/*       method), then you must call this function rapidly.  If there is more
/*       than 10ms latency the PC may think the USB device is stalled and
/*       disable it.
/*       To switch to a polling method, remove the #int_usb line above this
/*       fuction.  Also, goto usb_init() and remove the code that enables the
/*       USB interrupt.
/******************************************************************************/
#if !defined(USB_ISR_POLLING) && !defined(USB_NO_ISR_PREPROCESSOR)
#int_usb NOCLEAR
#endif
void usb_isr(void)
{
   unsigned int8 TRNAttempts;
   
   clear_interrupt(INT_USB);
   
   if (usb_state == USB_STATE_DETACHED) return;   //should never happen, though
   if (UIR)
   {
      debug_usb(debug_putc,"\r\n\n[%X] ",UIR);

      //activity detected.  (only enable after sleep)
      if (UIR_ACTV && UIE_ACTV) {usb_isr_activity();}

      if (UCON_SUSPND) return;

      if (UIR_STALL && UIE_STALL) {usb_isr_stall();}        //a stall handshake was sent

      if (UIR_UERR && UIE_UERR) {usb_isr_uerr();}          //error has been detected

      if (UIR_URST && UIE_URST) {usb_isr_rst();}        //usb reset has been detected

      if (UIR_IDLE && UIE_IDLE) {usb_isr_uidle();}        //idle time, we can go to sleep
     
      if (UIR_SOF && UIE_SOF) {usb_isr_sof();}

      TRNAttempts = 0;
      do
      {
         if (UIR_TRN && UIE_TRN)
         {
            USTATCopy = U1STAT;
            usb_clear_trn();
            usb_isr_tok_dne();
         }
         else
            break;
      } while (TRNAttempts++ < 4);
   }
}


Now I want to understand where to write my code for reading from USB interrupt.
For debug for example I could read a printf("hello world") when the interrupt fires.
monyno



Joined: 24 Sep 2012
Posts: 4

View user's profile Send private message

PostPosted: Mon Sep 24, 2012 1:51 pm     Reply with quote

none?? I need to know it for my degree.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Sep 24, 2012 2:49 pm     Reply with quote

You are looking at too low a level.

USB interrupts occur for dozens of reasons (not just data transfers). Every one of these low level events needs to be handled.

The interrupt code handles about a dozen separate events, and then has a state machine that handles transmitting or receiving data when it is available. USB requires all of these to be there and working.

You need to be looking only for the out token done interrupt on the endpoint being used for receiving data. usb_isr_tok_out_dne (in and out are confusing, referring to the host, not the PIC, so 'out token done' is triggered when the PIC has received data on a particular endpoint). Test the endpoint number to match what is used for your data transfer, and this then 'marks' that a data packet has arrived and is ready to be read.

Best Wishes
monyno



Joined: 24 Sep 2012
Posts: 4

View user's profile Send private message

PostPosted: Tue Sep 25, 2012 7:55 am     Reply with quote

I use endpoint 1. So for example if i want to do something( like printf hello world ) when date are on this endpoint, I have to write : printf("hello world") in the function that you've mentioned.
Can you make an example?
THANK YOU
monyno



Joined: 24 Sep 2012
Posts: 4

View user's profile Send private message

PostPosted: Tue Sep 25, 2012 7:58 am     Reply with quote

This is the function:
Code:

void usb_isr_tok_dne(void)
{
   unsigned int8 en;

   en = USTATCopy>>3;

   debug_usb(debug_putc, "T ");
   debug_usb(debug_putc, "%X ", USTATCopy);

   if (USTATCopy == USTAT_OUT_SETUP_E0)
   {
      //new out or setup token in the buffer
      int8 pidKey;
     
      debug_usb(debug_putc,"%X ", EP_BDxST_O(0));
     
      pidKey = EP_BDxST_O(0) & 0x3C;  //save PID
     
      EP_BDxST_O(0) &= 0x43;  //clear pid, prevent bdstal/pid confusion
     
      if (pidKey == USB_PIC_PID_SETUP)
      {
         if ((EP_BDxST_I(0) & 0x80) != 0x00)
            EP_BDxST_I(0)=0;   // return the in buffer to us (dequeue any pending requests)

         debug_usb(debug_putc,"(%U) ", EP_BDxCNT_O(0));
         debug_display_ram(EP_BDxCNT_O(0), usb_ep0_rx_buffer);

         usb_isr_tok_setup_dne();

         UCON_PKTDIS=0;       // UCON,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit

         //if setup_0_tx_size==0xFF - stall ep0 (unhandled request) (see usb_request_stall())
         //if setup_0_tx_size==0xFE - get EP0OUT ready for a data packet, leave EP0IN alone (see usb_request_get_data())
         //else setup_0_tx_size=size of response, get EP0OUT ready for a setup packet, mark EPOIN ready for transmit (see usb_request_send_response())
         if (__setup_0_tx_size == 0xFF)
            usb_flush_out(0, USB_DTS_STALL);
         else
         {
            usb_flush_out(0, USB_DTS_TOGGLE);
            if (__setup_0_tx_size != 0xFE)
               usb_flush_in(0 ,__setup_0_tx_size, USB_DTS_USERX);
         }
         //why was this here?
         //UCON_PKTDIS=0;       // UCON,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit
      }
      else if (pidKey == USB_PIC_PID_OUT)
      {
         usb_isr_tok_out_dne(0);
         usb_flush_out(0, USB_DTS_TOGGLE);
         if ((__setup_0_tx_size!=0xFE) && (__setup_0_tx_size!=0xFF))
         {
            usb_flush_in(0,__setup_0_tx_size,USB_DTS_DATA1);   //send response (usually a 0len)
         }
      }
      else
      {
         debug_usb(debug_putc, "!!! ");
      }
   }
   else if (USTATCopy == USTAT_IN_E0)
   {   
      //pic -> host transfer completed
      EP_BDxST_I(0) = EP_BDxST_I(0) & 0x43;   //clear up any BDSTAL confusion
      __setup_0_tx_size = 0xFF;
      usb_isr_tok_in_dne(0);
      if (__setup_0_tx_size!=0xFF)
         usb_flush_in(0, __setup_0_tx_size, USB_DTS_TOGGLE);
      else
      {
         //usb_init_ep0_setup(); //REMOVED JUN/9/2009
      } 
   }
   else
   {
      if (!bit_test(USTATCopy, 2))
      {
         EP_BDxST_O(en) = EP_BDxST_O(en) & 0x43;   //clear up any BDSTAL confusion
         usb_isr_tok_out_dne(en);
      }
      else
      {
         EP_BDxST_I(en) = EP_BDxST_I(en) & 0x43;   //clear up any BDSTAL confusion
         usb_isr_tok_in_dne(en);
      }
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Sep 25, 2012 8:09 am     Reply with quote

No.
You have things the wrong way round.

Printf, is to send data from the PIC to the PC. Either use the cdc code/driver, and printf to usb_cdc_putc, or sprintf to a buffer, and use usb_puts. Interrupts are not involved as far as you are concerned in this direction. The existing driver will transfer the packet, when it receives a request from the PC. Understand that there is nothing you can do to trigger a transfer, it _has_ to wait for the PC to ask for the data. Fiddling around in the interrupt driver will gain you nothing.

The 'usb_isr_tok_out_dne' function is called from the interrupt handler, when a packet has been _received_ by the PIC. It is called with the endpoint number that the packet has come from, so you can check the number, and if the packet is for your endpoint, call code that you want to handle the packet (but with the big restriction that as always you _must_ get out of the ISR ASAP). This is what is done by the CDC code, setting the flag used by kbhit, when this happens.

Best Wishes
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