• Main Page
  • Modules
  • Index
  • File List
  • Globals

hal/nrf24lu1p/hal_usb.c

Go to the documentation of this file.
00001 /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is confidential property of Nordic 
00004  * Semiconductor ASA.Terms and conditions of usage are described in detail 
00005  * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRENTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *              
00011  * $LastChangedRevision: 2378 $
00012  */
00013 
00017 #include "nrf24lu1p.h"
00018 #include <stdint.h>
00019 #ifdef __ICC8051__
00020 #include <intrinsics.h>
00021 #endif
00022 #ifdef __C51__
00023 #include <intrins.h>
00024 #endif
00025 
00026 #include "nordic_common.h"
00027 #include "hal_usb_desc.h"
00028 #include "usb.h"
00029 #include "hal_delay.h"
00030 
00031 
00032 #define ALLOCATE_USB_MAP
00033 #include "usb_map.h"
00034 
00035 // Define formulas for jumping in the usb registry map based upon the endpoint number
00036 
00037 // Calculate control and status register location in USB-controller
00038 #define CALCULATE_CS_IN_PTR(ep) (uint8_t xdata*)(&in1cs + 2 * ((ep & 0x7f) - 1 ))
00039 #define CALCULATE_CS_OUT_PTR(ep) (uint8_t xdata*)(&out1cs + 2 * ( (ep & 0x7f) - 1 ))
00040 
00041 // Calculate byte count register location in USB-controller
00042 #define CALCULATE_BC_OUT_PTR(ep) (uint8_t xdata *)(&out0bc + (ep * 2 ))
00043 #define CALCULATE_BC_IN_PTR(ep) (uint8_t xdata *)(&in0bc + ((ep & 0x7f ) * 2))
00044 
00045 // Calculate buffer location in USB-controller
00046 #define CALCULATE_BUF_IN_PTR(ep) (uint8_t xdata *)(in0buf - (( ep & 0x7f) * 128))
00047 #define CALCULATE_BUF_OUT_PTR(ep) (uint8_t xdata *)(out0buf - (ep * 128 ))
00048 
00049 static packetizer_t i_packetizer;
00050 static hal_usb_cb_endpoint_t i_endpoint_in_isr[USB_ENDPOINT_IN_COUNT];
00051 static hal_usb_cb_endpoint_t i_endpoint_out_isr[USB_ENDPOINT_OUT_COUNT];
00052 
00053 static hal_usb_device_req req;
00054 hal_usb_t volatile g_hal_usb;
00055 static uint8_t stall_data_size0;
00056 
00057 void hal_usb_init(bool usb_disconnect, hal_usb_cb_device_req_t device_req, hal_usb_cb_reset_t reset, hal_usb_cb_resume_t resume, hal_usb_cb_suspend_t suspend)
00058 {
00059   // Setup descriptors
00060   g_hal_usb.descs.dev = &g_usb_dev_desc;
00061   g_hal_usb.descs.conf = &g_usb_conf_desc;
00062   g_hal_usb.descs.string = &g_usb_string_desc;
00063 
00064   // This is for setting language American English (String descriptor 0 is an array of supported languages)
00065   g_hal_usb.descs.string_zero[0] = 0x04;
00066   g_hal_usb.descs.string_zero[1] = 0x03;
00067   g_hal_usb.descs.string_zero[2] = 0x09;
00068   g_hal_usb.descs.string_zero[3] = 0x04;
00069 
00070   // Setup state information
00071   g_hal_usb.state = DEFAULT;
00072   g_hal_usb.bm_state = 0;
00073   stall_data_size0 = 0;
00074 
00075   // Setconfig configuration information
00076   g_hal_usb.current_config = 0;
00077   g_hal_usb.current_alt_interface = 0;
00078 
00079   // Setup callbacks
00080   g_hal_usb.device_req = device_req;
00081   g_hal_usb.reset = reset;
00082   g_hal_usb.resume = resume;
00083   g_hal_usb.suspend = suspend;
00084 
00085   // Disconnect from USB-bus if we are in this routine from a power on and not a soft reset
00086   if(usb_disconnect)
00087   {
00088     usbcs |= 0x08; // disconnect
00089     delay_ms(50);
00090     usbcs &= ~(0x08); // connect
00091   }
00092 
00093   // Setup interrupts
00094   USBWU = 1; // USBWU is mapped to IEN1.3
00095   USB = 1; // USBIRQ is mapped to IEN1.4
00096 
00097   usbien = 0x1d; // ibnie -5 4 - uresir 3 - suspir, 0 - sudavir
00098 
00099   in_ien = 0x01;
00100   in_irq = 0x1f;
00101   out_ien = 0x01;
00102   out_irq = 0x1f;
00103 
00104   // Setup the USB RAM with some OK default values. Note that isochronos is not set up yet.
00105   bout1addr = 16;
00106   bout2addr = 32;
00107   bout3addr = 48;
00108   bout4addr = 64;
00109   bout5addr = 80;
00110 
00111   binstaddr = 0xc0;
00112   bin1addr = 16;
00113   bin2addr = 32;
00114   bin3addr = 48;
00115   bin4addr = 64;
00116   bin5addr = 80;
00117 
00118   // Set all endpoints to not valid (except EP0IN and EP0OUT)
00119   inbulkval = 0x01;
00120   outbulkval = 0x01;
00121   inisoval = 0x00;
00122   outisoval = 0x00;
00123 }
00124 
00125 void hal_usb_endpoint_stall(uint8_t ep_num, bool stall)
00126 {
00127   uint8_t temp;
00128   uint8_t xdata *cs_ptr;
00129 
00130   temp = 2 * ((ep_num & 0x7f) - 1);
00131 
00132   // Calculate register address
00133   if((ep_num & 0x80 ) == 0x80) // IN endpoints
00134   {
00135     // Calculate control and status register for IN endpoint
00136     cs_ptr = (uint8_t xdata*)(&in1cs + temp);
00137   }
00138   else // OUT endpoints
00139   {
00140     // Calculate control and status register for OUT endpoint
00141     cs_ptr = (uint8_t xdata*)(&out1cs + temp);
00142   }
00143 
00144   if(stall == true)
00145   {
00146     // Set the stall bit
00147     *cs_ptr = 0x01;
00148   }
00149   else
00150   {
00151     // Clear the stall bit
00152     *cs_ptr = 0x00;
00153   }
00154 }
00155 
00156 uint8_t hal_usb_get_address()
00157 {
00158   return fnaddr;
00159 }
00160 
00161 void hal_usb_endpoint_config(uint8_t ep_num, uint8_t ep_size, hal_usb_cb_endpoint_t endpoint_isr)
00162 {
00163   uint8_t xdata *bc_ptr;
00164   uint8_t temp = (ep_num & 0x7f) - 1;
00165   uint8_t stemp = 1 << (ep_num & 0x7f);
00166 
00167   // Dummy use of variable to get rid of warning
00168   ep_size = 0;
00169 
00170   if((ep_num & 0x80 ) == 0x80) // MSB set indicates IN endpoint
00171   {
00172     i_endpoint_in_isr[temp] = endpoint_isr;
00173     if(endpoint_isr != NULL)
00174     {
00175       // Add the callback, enable the interrupt and validate the endpoint
00176       in_ien |= stemp; 
00177       inbulkval |= stemp;
00178     }
00179     else
00180     {
00181       // Remove the callback, disable the interrupt and invalidate the endpoint
00182       in_ien &= ~stemp;
00183       inbulkval &= ~stemp;
00184     }
00185   }
00186   else // OUT endpoint
00187   {
00188     i_endpoint_out_isr[temp] = endpoint_isr;
00189     if(endpoint_isr != NULL)
00190     {
00191       // Add the callback, enable the interrupt and validate the endpoint
00192       out_ien |= stemp;
00193       outbulkval |= stemp;
00194 
00195       // Have to write a dummy value to the OUTxBC register to get interrupts
00196       bc_ptr = CALCULATE_BC_OUT_PTR(ep_num);
00197       *bc_ptr = 0xff;
00198     }
00199     else
00200     {
00201       // Remove the callback, disable the interrupt and invalidate the endpoint
00202       out_ien &= ~stemp;
00203       outbulkval &= ~stemp;
00204     }
00205   }
00206 }
00207 
00208 void hal_usb_wakeup()
00209 {
00210   // We can only issue a wakeup if the host has allowed us to do so
00211   if((g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP)
00212   {
00213     USBCON = 0x40;  // Wakeup the USB controller via remote pin
00214     delay_ms(1);    // Wait until the USB clock starts
00215     USBCON = 0x00;
00216   }
00217 }
00218 
00219 void hal_usb_reset()
00220 {
00221   SWRST = 1;  // Perform a hardware reset of the USB controller
00222 }
00223 
00224 #pragma disable
00225 hal_usb_state_t hal_usb_get_state()
00226 {
00227   return g_hal_usb.state;
00228 }
00229 
00230 void hal_usb_send_data(uint8_t ep_num, uint8_t* array, uint8_t count)
00231 {
00232   uint8_t i;
00233 
00234   uint8_t xdata *buf_ptr;
00235   uint8_t xdata *bc_ptr;
00236 
00237   // Calculate the buffer pointer and byte count pointer
00238   buf_ptr = CALCULATE_BUF_IN_PTR(ep_num);
00239   bc_ptr = CALCULATE_BC_IN_PTR(ep_num);
00240 
00241   // Copy the data into the USB controller
00242   for( i = 0; i < count; i++ )
00243   {
00244     buf_ptr[i] = array[i];
00245   }
00246 
00247   // Set the number of bytes we want to send to USB-host. This also trigger sending of data to USB-host.
00248   *bc_ptr = count;
00249 }
00250 
00251 void hal_usb_bus_disconnect()
00252 {
00253   usbcs |= 0x08; // disconnect
00254 }
00255 
00256 void hal_usb_bus_connect()
00257 {
00258   usbcs &= ~(0x08); // connect
00259 }
00260 
00261 void hal_usb_sleep()
00262 {
00263   USBSLP = 1;
00264 }
00265  
00266 static void packetize(uint8_t *data_ptr, uint8_t data_size)
00267 {
00268   i_packetizer.data_ptr = data_ptr;
00269   i_packetizer.data_size = data_size;
00270   i_packetizer.pkt_size = g_hal_usb.descs.dev->bMaxPacketSize0;
00271 }
00272 
00273 // This routine is called by functions that shall send their first packet and when the EP0IN interrupt is set
00274 static void packetizer_isr_ep0_in(void) 
00275 {
00276   uint8_t size, i;
00277 
00278   // We are getting a ep0in interupt when the host send ACK and do not have any more data to send
00279   if(i_packetizer.data_size == 0)
00280   {        
00281     if (stall_data_size0 == 1)
00282     {
00283         USB_EP0_DSTALL();
00284     }
00285     else
00286     {
00287         stall_data_size0 = 1;
00288         in0bc = 0;
00289         USB_EP0_HSNAK();
00290     }       
00291     return;
00292   }
00293 
00294   size = MIN(i_packetizer.data_size, i_packetizer.pkt_size);
00295 
00296   // Copy data to the USB-controller buffer
00297   for(i = 0; i < size; i++)
00298   {
00299     in0buf[i] = i_packetizer.data_ptr[i];
00300   }
00301 
00302   if (size < i_packetizer.pkt_size)
00303     stall_data_size0 = 1;
00304   // Tell the USB-controller how many bytes to send
00305   // If a IN is received from host after this the USB-controller will send the data
00306   in0bc = size;
00307 
00308   // Update the packetizer data
00309   i_packetizer.data_ptr += size;
00310   i_packetizer.data_size -= size;
00311 
00312   return;
00313 }
00314 
00316 static void usb_process_dev_req_cb_response(void)
00317 {
00318   uint8_t *data_ptr;
00319   uint8_t data_size;
00320   hal_usb_dev_req_resp_t ret = g_hal_usb.device_req(&req, &data_ptr, &data_size);
00321 
00322   switch(ret)
00323   {
00324     case DATA:
00325       packetize((uint8_t *)data_ptr, MIN(req.wLength, data_size));
00326       packetizer_isr_ep0_in();
00327       break;
00328     case NO_RESPONSE:
00329       break;
00330     case EMPTY_RESPONSE:
00331     case NAK:
00332       USB_EP0_HSNAK();
00333       break;
00334     case ACK:
00335       out0bc = 0xff;
00336       break;
00337     case STALL:
00338     default:
00339       USB_EP0_STALL();
00340       break;
00341     }
00342 }
00343 
00344 static void usb_process_get_status(void)
00345 {
00346   uint8_t xdata *ptr;
00347 
00348   if(g_hal_usb.state == ADDRESSED)
00349   {
00350     if(req.wIndex != 0x00)
00351     {
00352         USB_EP0_STALL();
00353     }
00354     else
00355     {
00356       in0buf[0] = in0buf[1] = 
00357         ((g_hal_usb.descs.conf->conf.bmAttributes & 0x40 ) >> 6); // D0 - 0: bus powered, 1: self powered
00358       in0bc = 0x02;
00359     }
00360   }
00361   else if(g_hal_usb.state == CONFIGURED)
00362   {
00363     in0buf[1] = 0x00;
00364     switch(req.bmRequestType)
00365     {
00366       case 0x80: // Device
00367         if((g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP)
00368         {
00369             in0buf[0] = 0x02;
00370         }
00371         else
00372         {
00373             in0buf[0] = 0x00;
00374         }
00375 
00376         in0buf[0] |= ((g_hal_usb.descs.conf->conf.bmAttributes & 0x40 ) >> 6); // D0 - 0: bus powered, 1: self powered
00377         in0bc = 0x02;
00378         break;
00379       case 0x81: // Interface
00380         in0buf[0] = 0x00;
00381         in0bc = 0x02;
00382         break;
00383       case 0x82: // Endpoint
00384         if((req.wIndex & 0x80) == 0x80) // IN endpoints
00385         {
00386           ptr = CALCULATE_CS_IN_PTR(req.wIndex);
00387         }
00388         else
00389         {
00390           ptr = CALCULATE_CS_OUT_PTR(req.wIndex);
00391         }
00392 
00393         in0buf[0] = *ptr & 0x01;
00394         in0bc = 0x02;
00395         break;
00396       default:
00397         USB_EP0_STALL();
00398         break;
00399     } // switch(req.bmRequestType) --end--
00400   }
00401   else
00402   {
00403     // We should not be in this state
00404     USB_EP0_STALL();
00405   }
00406 }
00407 
00408 static void usb_process_get_descriptor(void)
00409 {
00410   // Switch on descriptor type
00411   switch(req.wValueMsb)
00412   {
00413     case USB_DESC_DEVICE:
00414       packetize((uint8_t *)g_hal_usb.descs.dev,
00415       MIN(req.wLength, sizeof(hal_usb_dev_desc_t)));
00416       packetizer_isr_ep0_in();
00417       break;
00418     case USB_DESC_CONFIGURATION:
00419       // For now we just support one configuration. The asked configuration is stored in LSB(wValue).
00420       packetize((uint8_t *)g_hal_usb.descs.conf,
00421       MIN(req.wLength, sizeof(usb_conf_desc_templ_t)));
00422       packetizer_isr_ep0_in();
00423       break;
00424     case USB_DESC_STRING:
00425       // For now we just support english as string descriptor language.
00426       if(req.wValueLsb == 0x00)
00427       {
00428         packetize(g_hal_usb.descs.string_zero, MIN(req.wLength, sizeof(g_hal_usb.descs.string_zero)));
00429         packetizer_isr_ep0_in();
00430       }
00431       else
00432       {
00433         if((req.wValueLsb - 1 ) < USB_STRING_DESC_COUNT)
00434         {
00435           packetize((uint8_t *)(g_hal_usb.descs.string->idx[req.wValueLsb-1]),
00436           MIN(req.wLength, g_hal_usb.descs.string->idx[req.wValueLsb-1][0]));
00437           packetizer_isr_ep0_in();
00438         }
00439         else
00440         {
00441           USB_EP0_STALL();
00442         }
00443       }
00444       break;
00445     case USB_DESC_INTERFACE:
00446     case USB_DESC_ENDPOINT:
00447     case USB_DESC_DEVICE_QUAL:
00448     case USB_DESC_OTHER_SPEED_CONF:
00449     case USB_DESC_INTERFACE_POWER:
00450       USB_EP0_STALL();
00451       break;
00452     default:
00453       usb_process_dev_req_cb_response();
00454       break;
00455   }
00456 }
00457 
00458 static void isr_sudav(void)
00459 {
00460   // Parsing the request into request structure
00461   req.bmRequestType = setupbuf[0];
00462   req.bRequest = setupbuf[1];
00463   req.wValueLsb = setupbuf[2];
00464   req.wValueMsb = setupbuf[3];
00465   req.wIndex = setupbuf[4];
00466   req.wLength = setupbuf[6];
00467   if (setupbuf[7] > 0)
00468   {
00469     req.wLength = 0xff; // We truncate packets requests longer then 255 bytes
00470   }
00471 
00472   // bmRequestType = 0 00 xxxxx : Data transfer direction: Host-to-device Type: Standard
00473   if((req.bmRequestType & 0x60) == 0x00)
00474   {
00475     switch(req.bRequest)
00476     {
00477       case USB_REQ_GET_DESCRIPTOR:
00478         usb_process_get_descriptor();
00479         break;
00480       case USB_REQ_GET_STATUS:
00481         usb_process_get_status();
00482         break;           
00483       case USB_REQ_CLEAR_FEATURE:
00484       case USB_REQ_SET_FEATURE: 
00485         switch(req.bmRequestType)
00486         {
00487           case 0x00: // Device
00488             if(req.wValueLsb == USB_DEVICE_REMOTE_WAKEUP)
00489             {
00490               if (req.bRequest == USB_REQ_CLEAR_FEATURE) 
00491                 g_hal_usb.bm_state &= ~(USB_BM_STATE_ALLOW_REMOTE_WAKEUP);
00492               else
00493                 g_hal_usb.bm_state |= USB_BM_STATE_ALLOW_REMOTE_WAKEUP;
00494               USB_EP0_HSNAK();
00495             }
00496             else
00497             {
00498               USB_EP0_STALL();
00499             }
00500             break;
00501 
00502           case 0x02: // Endpoint
00503             if(req.wValueLsb == USB_ENDPOINT_HALT)
00504             {
00505               if (req.bRequest == USB_REQ_CLEAR_FEATURE) 
00506                 hal_usb_endpoint_stall(req.wIndex, false);
00507               else
00508                 hal_usb_endpoint_stall(req.wIndex, true);
00509               USB_EP0_HSNAK();
00510             }
00511             else 
00512             {
00513                 USB_EP0_STALL();
00514             }
00515             break;
00516           case 0x01: // Interface
00517           default:
00518             USB_EP0_STALL();
00519             break;
00520         }
00521         break;
00522 
00523       case USB_REQ_SET_ADDRESS:
00524         g_hal_usb.state = ADDRESSED;
00525         g_hal_usb.current_config = 0x00;
00526         break;
00527       case USB_REQ_GET_CONFIGURATION:
00528         switch(g_hal_usb.state)
00529         {
00530           case ADDRESSED:
00531             in0buf[0] = 0x00;
00532             in0bc = 0x01;
00533             break;
00534           case CONFIGURED:
00535             in0buf[0] = g_hal_usb.current_config;
00536             in0bc = 0x01;
00537             break;
00538           default:
00539             USB_EP0_STALL();
00540             break;
00541         }
00542         break;
00543       case USB_REQ_SET_CONFIGURATION:
00544         switch(req.wValueLsb)
00545         {
00546           case 0x00:
00547             g_hal_usb.state = ADDRESSED;
00548             g_hal_usb.current_config = 0x00;
00549             USB_EP0_HSNAK();
00550             break;
00551           case 0x01:
00552             g_hal_usb.state = CONFIGURED;
00553             g_hal_usb.bm_state |= USB_BM_STATE_CONFIGURED;
00554             g_hal_usb.current_config = 0x01;
00555             USB_EP0_HSNAK();
00556             break;
00557           default:
00558             USB_EP0_STALL();
00559             break;
00560         }
00561         break;
00562       case USB_REQ_GET_INTERFACE: // GET_INTERFACE
00563         in0buf[0] = g_hal_usb.current_alt_interface;
00564         in0bc = 0x01;
00565         break;
00566       case USB_REQ_SET_DESCRIPTOR:
00567       case USB_REQ_SET_INTERFACE: // SET_INTERFACE (We do not support this)
00568       case USB_REQ_SYNCH_FRAME:   // SYNCH_FRAME (We do not support this)
00569       default:
00570        USB_EP0_STALL();
00571        break;
00572     };
00573   } 
00574   // bmRequestType = 0 01 xxxxx : Data transfer direction: Host-to-device, Type: Class
00575   else if((req.bmRequestType & 0x60 ) == 0x20)  // Class request
00576   {
00577     if(req.wLength != 0 && ((req.bmRequestType & 0x80) == 0x00))
00578     {
00579       // If there is a OUT-transaction associated with the Control-Transfer-Write we call the callback
00580       // when the OUT-transaction is finished. Note that this function do not handle several out transactions.
00581       out0bc = 0xff;
00582     }
00583     else
00584     {
00585       usb_process_dev_req_cb_response();
00586     }
00587     // Call the callback function. Data to be sent back to the host is store by the callback in data_ptr and the size in data_size.
00588   } 
00589   else  // Unknown request type
00590   {
00591     USB_EP0_STALL();
00592   }
00593 }
00594 
00595 static void isr_suspend(void)
00596 {
00597   uint8_t allow_remote_wu = 0;
00598   g_hal_usb.bm_state &= ~(USB_BM_STATE_HOST_WU); // We clear the flag that indicates that the host awoke the MCU via USB here
00599 
00600   if( g_hal_usb.state == CONFIGURED )
00601   {
00602     if( ( g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP )
00603     {
00604       allow_remote_wu = 1;
00605     }
00606   }
00607 
00608   g_hal_usb.state = SUSPENDED;
00609 
00610   if( g_hal_usb.suspend != NULL )
00611   {
00612     g_hal_usb.suspend(allow_remote_wu);
00613   }
00614 }
00615 
00616 static void isr_usbreset(void)
00617 {
00618   g_hal_usb.state = DEFAULT;
00619   g_hal_usb.current_config = 0;
00620   g_hal_usb.current_alt_interface = 0;
00621   g_hal_usb.bm_state = 0;
00622   if( g_hal_usb.reset != NULL ) g_hal_usb.reset();
00623 }
00624 
00625 
00626 USB_WU_ISR() // address: 0x005b
00627 {
00628 #define ICH4
00629   #ifdef ICH4
00630   uint8_t t;
00631   #endif
00632 
00633   // Check if the wakeup source is the pin to the USB controller
00634   // If it is by the pin to the USB controller we want to start
00635   // a remote wakeup
00636   if( ( usbcs & 0x80 ) == 0x80 )
00637   {
00638     // Reset the wakesrc indicator
00639     usbcs = 0x80;
00640 
00641     // If we are allowed to perform a remote wakeup do that
00642     if( ( g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP )
00643     {
00644   #ifdef ICH4
00645       // Force the J state on the USB lines
00646       usbcs |= 0x02;
00647 
00648       // Typical 5.4us delay
00649       _nop_();
00650       _nop_();
00651 
00652       t = usbcs;
00653 
00654       // Stop J state on the USB lines
00655       t &= ~0x02;
00656 
00657       // Signal remote resume
00658       t |= 0x01;
00659 
00660       // We have to set this register in one operation to avoid
00661       // idle state is restored between the forced J and resume state
00662       usbcs = t;
00663 #else
00664       usbcs |= 0x01;  // Turn on the resume signal on the USB bus
00665 #endif
00666       delay_ms(7); //.1.7.7 Resume: The remote wakeup device must hold the resume signaling for at 
00667                     // least 1 ms but for no more than 15ms
00668 
00669       usbcs &= ~0x01; // Turn off the resume signal on the USB bus
00670     }
00671   }
00672   else 
00673   {
00674     // We are awoken by the bus
00675     g_hal_usb.bm_state |= USB_BM_STATE_HOST_WU;
00676   }
00677 
00678   if((g_hal_usb.bm_state & USB_BM_STATE_CONFIGURED ) == USB_BM_STATE_CONFIGURED)
00679   {
00680     g_hal_usb.state = CONFIGURED;
00681   }
00682   else
00683   {
00684     g_hal_usb.state = DEFAULT;
00685   }
00686 
00687   // Call resume callback
00688   g_hal_usb.resume();
00689 }
00690 
00691 // This function processes the response from the EP callback
00692 static void usb_process_ep_response(uint8_t ret, uint8_t xdata* cs_ptr, uint8_t xdata* bc_ptr)
00693 {
00694   if( ret == 0xff ) // Clear the OUTx busy flag enabling reception of the next OUT from USB-host
00695   {
00696     *bc_ptr = 0xff;
00697   }
00698   else if( ( ret & 0x80 ) == 0x80 )  // STALL
00699   {
00700     *cs_ptr = 0x01;
00701   }
00702   else if( ( ret & 0x60 ) == 0x60 ) // NAK
00703   {
00704     *cs_ptr = 0x02;
00705   }
00706   else if( ret == 0 ) // Zero length data
00707   {
00708     *bc_ptr = 0;
00709   }
00710   else
00711   {
00712     *bc_ptr = ret;
00713   }
00714 }
00715 
00716 USB_ISR()
00717 {
00718   uint8_t ep;
00719   uint8_t ret;
00720   uint8_t xdata *cs_ptr;
00721   uint8_t xdata *buf_ptr;
00722   uint8_t xdata *bc_ptr;
00723 
00724   switch(ivec)
00725   {
00726     case INT_SUDAV:
00727       usbirq = 0x01;
00728       isr_sudav();
00729       break;
00730     case INT_SOF:
00731       usbirq = 0x02;
00732       break;
00733     case INT_SUTOK:
00734       usbirq = 0x04;
00735       i_packetizer.data_ptr = NULL;
00736       i_packetizer.data_size = 0;
00737       i_packetizer.pkt_size = 0;
00738       stall_data_size0 = 0;
00739       break;
00740     case INT_SUSPEND:
00741       usbirq = 0x08;
00742       isr_suspend();
00743       break;
00744     case INT_USBRESET:
00745       usbirq = 0x10;
00746       isr_usbreset();
00747       break;
00748     case INT_EP0IN:
00749       in_irq = 0x01;
00750       packetizer_isr_ep0_in();
00751       break;
00752     case INT_EP0OUT:
00753       out_irq = 0x01;
00754       i_packetizer.data_size = 0;
00755       usb_process_dev_req_cb_response();
00756       break;
00757       case INT_EP1IN:
00758       case INT_EP2IN:
00759       case INT_EP3IN:
00760       case INT_EP4IN:
00761       case INT_EP5IN:
00762         // Calculate IN endpoint number
00763         ep = (ivec - INT_EP0IN ) >> 3;// INT_EP2IN - INT_EP1IN == 8 ;   
00764         // Clear interrupt 
00765         in_irq = ( 1 << ep );
00766 
00767         cs_ptr = CALCULATE_CS_IN_PTR(ep);
00768         buf_ptr = CALCULATE_BUF_IN_PTR(ep);
00769         bc_ptr = CALCULATE_BC_IN_PTR(ep);
00770     
00771         // Call registered callback
00772         ret = i_endpoint_in_isr[ep - 1](buf_ptr, bc_ptr);
00773         usb_process_ep_response(ret, cs_ptr, bc_ptr);
00774         break;
00775       case INT_EP1OUT:
00776       case INT_EP2OUT:
00777       case INT_EP3OUT:
00778       case INT_EP4OUT:
00779       case INT_EP5OUT:
00780         // Calculate OUT endpoint number
00781         ep = (ivec - INT_EP0OUT) >> 3;          // INT_EP2OUT - INT_EP1OUT == 8
00782 
00783         // Clear interrupt
00784         out_irq = ( 1 << ep );
00785         
00786         cs_ptr = CALCULATE_CS_OUT_PTR(ep);
00787         buf_ptr = CALCULATE_BUF_OUT_PTR(ep);
00788         bc_ptr = CALCULATE_BC_OUT_PTR(ep);
00789 
00790         // Call registered callback
00791         ret = (i_endpoint_out_isr[ep - 1])(buf_ptr, bc_ptr);
00792         usb_process_ep_response(ret, cs_ptr, bc_ptr);
00793         break;
00794     default:
00795       break;
00796   };
00797 }

Generated on Fri Apr 20 2012 14:11:45 for nRFGo SDK by  doxygen 1.7.2