Advertisement
Guest User

Untitled

a guest
Jan 2nd, 2013
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.95 KB | None | 0 0
  1. /*
  2.  * usb.c
  3.  *
  4.  * Created: 29.12.2012 17:25:47
  5.  *  Author: Ondra
  6.  */
  7.  
  8. #include "usb.h"
  9. #include "cdc/cdc.h"
  10. //#ifdef DEBUG
  11. #include "../../uart/uart.h"
  12. //#endif
  13.  
  14. volatile USB_RAM_t usb_ram;
  15. byte USB_State;
  16. uint8_t USB_New_Addr;
  17.  
  18. void USB_Init()
  19. {
  20.     uart_println("USB drv: initializing");
  21.     Clock_Set_USB(32); // 32MHz
  22.     PMIC_Enable(PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm);
  23.     USB_Set_Registers();
  24.     USB_Reset();
  25.     uart_println("USB drv: init done");
  26. }
  27.  
  28. void USB_Reset()
  29. {
  30.     USB_Reset_Everything();
  31.     USB_Set_Address(0);
  32.     USB_State = Powered;
  33. }
  34.  
  35. void USB_Reset_Everything()
  36. {  
  37.     USB_Endpoint_Reset(0);
  38.     USB_Endpoint_Reset(1);
  39.     USB_Endpoint_Reset(2);
  40.     USB_Endpoint_Reset(3);
  41.     USB_Endpoint_Reset(4);
  42.     USB_Endpoint_Reset(5);
  43.    
  44.     USB_Endpoint_Set_CTRL(0, USB_EP_TYPE_CONTROL_gc | USB_EP_BUFSIZE_64_gc);
  45.     USB_Endpoint_Set_CTRL(1, USB_EP_TYPE_CONTROL_gc | USB_EP_BUFSIZE_64_gc); // no AZLP nor auxdata -- we are doing it manually due to sillicon errata on A1U chips
  46.     USB_Endpoint_Set_CTRL(2, USB_EP_TYPE_DISABLE_gc);
  47.     USB_Endpoint_Set_CTRL(3, USB_EP_TYPE_BULK_gc | USB_EP_BUFSIZE_64_gc);
  48.     USB_Endpoint_Set_CTRL(4, USB_EP_TYPE_BULK_gc | USB_EP_BUFSIZE_64_gc);
  49.     USB_Endpoint_Set_CTRL(5, USB_EP_TYPE_BULK_gc | USB_EP_BUFSIZE_64_gc); // actually interrupt, but they are the same for XMega
  50.    
  51.     USB_Set_DATA(EP_CTRL_OUT, usb_ram.payload[0]);
  52.     USB_Set_DATA(EP_DATA_OUT, usb_ram.payload[1]);
  53.     USB_Set_DATA(EP_NOTIF_OUT, usb_ram.payload[2]);
  54.    
  55. }
  56.  
  57. void USB_Set_Registers()
  58. {
  59.     USB.EPPTR = (u16)usb_ram.endpoint;
  60.     USB.INTCTRLA = USB_INTLVL_HI_gc | /*USB_SOFIE_bm | */USB_BUSEVIE_bm/* | USB_BUSERRIE_bm | USB_STALLIE_bm*/;
  61.     USB.INTCTRLB = USB_TRNIE_bm | USB_SETUPIE_bm;
  62.    
  63.     USB.CTRLA = USB_ENABLE_bm | USB_SPEED_bm | (XBOOT_ENDPOINTS - 1) | USB_FIFOEN_bm;
  64. }
  65.  
  66. void USB_Attach()
  67. {
  68.     USB.CTRLB |= USB_ATTACH_bm;
  69. }
  70.  
  71. void USB_Detach()
  72. {
  73.     USB.CTRLB &= ~USB_ATTACH_bm;
  74. }
  75.  
  76. void USB_Fetch_Descriptor(USB_DeviceRequest_t* Packet)
  77. {
  78.     switch(Packet->wValue >> 8)
  79.     {
  80.         case USB_Request_Descriptor_DEVICE:
  81.             USB_Send_Data(EP_CTRL_IN, &USB_Descriptor_Device, USB_Descriptor_Device.bLength);
  82.             USB_Ack(EP_CTRL_IN);
  83.             USB_Ack(EP_CTRL_OUT);
  84.             uart_println("Descriptor device");
  85.         break;
  86.         case USB_Request_Descriptor_CONFIGURATION:
  87.             USB_Send_Data(EP_CTRL_IN, &USB_Descriptor_Configuration, USB_Descriptor_Configuration.Configuration.wTotalLength)
  88.             USB_Ack(EP_CTRL_IN);
  89.             USB_Ack(EP_CTRL_OUT);
  90.             uart_println("Descriptor configuration");
  91.         break;
  92.         case USB_Request_Descriptor_STRING:
  93.             switch(Packet->wValue & 0xFF)
  94.             {
  95.                 case USB_STRING_MANUFACTURER:
  96.                     USB_Send_Data(EP_CTRL_IN, &USB_Descriptor_String_Manufacturer, USB_Descriptor_String_Manufacturer.bLength);
  97.                     USB_Ack(EP_CTRL_IN);
  98.                     USB_Ack(EP_CTRL_OUT);
  99.                     uart_println("Descriptor string manufacturer");
  100.                 break;
  101.                 case USB_STRING_PRODUCT:
  102.                     USB_Send_Data(EP_CTRL_IN, &USB_Descriptor_String_Product, USB_Descriptor_String_Product.bLength);
  103.                     USB_Ack(EP_CTRL_IN);
  104.                     USB_Ack(EP_CTRL_OUT);
  105.                     uart_println("Descriptor string product");
  106.                 break;
  107.                 case USB_STRING_LIST:
  108.                     USB_Send_Data(EP_CTRL_IN, &USB_Descriptor_Language, USB_Descriptor_Language.bLength);
  109.                     USB_Ack(EP_CTRL_IN);
  110.                     USB_Ack(EP_CTRL_OUT);
  111.                     uart_println("Descriptor string list");
  112.                 break;
  113.             }
  114.         break;
  115.     }
  116.    
  117.    
  118. }
  119.  
  120. void USB_Process_Setup_Packet()
  121. {
  122.     USB_DeviceRequest_t* Request = (USB_DeviceRequest_t*) ((u8*)usb_ram.endpoint[0].DATAPTR);
  123.    
  124.     USB_Set_AUXDATA(EP_DATA_IN, 0); // clear any pending data
  125.    
  126.     if((Request->bmRequestType & USB_Request_Type_MASK) == USB_Request_Type_CLASS)
  127.     {
  128.         uart_println("CDC Packet");
  129.         USB_CDC_Setup_Packet(Request);
  130.         return;
  131.     }
  132.     else if((Request->bmRequestType & USB_Request_Type_MASK) == USB_Request_Type_VENDOR)
  133.     {
  134.         uart_println("?? vendor packet");
  135.         // error condition
  136.     }
  137.     else if((Request->bmRequestType & USB_Request_Type_STANDARD) == USB_Request_Type_STANDARD)
  138.     { // regular setup packet
  139.         switch(Request->bRequest)
  140.         {
  141.             case USB_Request_GET_DESCRIPTOR:
  142.                 USB_Fetch_Descriptor(Request);
  143.             break;
  144.             case USB_Request_SET_ADDRESS:
  145.                 uart_println("Set address packet");
  146.                 USB_State = AddressPending;
  147.                 USB_New_Addr = Request->wValue & 0x7F;
  148.                 USB_ZLP(EP_CTRL_IN);
  149.                 USB_Ack(EP_CTRL_IN);
  150.                 USB_Ack(EP_CTRL_OUT);
  151.             break;
  152.             case USB_Request_SET_CONFIGURATION:
  153.                 uart_println("Set configuration packet");
  154.                 USB_ZLP(EP_CTRL_IN);
  155.                 USB_Ack(EP_CTRL_OUT);
  156.                 USB_Ack(EP_CTRL_IN);
  157.             break;
  158.         }
  159.     }
  160.    
  161.     //uart_println("This was setup packet. Data: ");
  162.     memdump(Request, sizeof(USB_DeviceRequest_t));
  163.     uart_println("\r\n");
  164. }
  165.  
  166. ISR(USB_TRNCOMPL_vect)
  167. {
  168.     USB_Ack_TRNCOMPL();
  169.    
  170.     if(USB_Is_Setup_Packet())
  171.     {
  172.         USB_Ack_Setup_Packet();
  173.         USB_Process_Setup_Packet();
  174.         return;
  175.     }
  176.    
  177.     u8 EP = (u8)USB_Get_EP_From_FIFO();
  178.     u16 cnt;
  179.     u16 aux;
  180.    
  181.     switch(EP)
  182.     {
  183.         case EP_CTRL_OUT: // PC => device
  184.             // let's hope for now that PC won't send >64 bytes of data on control endpoints
  185.             uart_println("TRNCOMPL on ctrl out FIFO");
  186.             memdump(usb_ram.payload[EP_CTRL_OUT], XBOOT_DATASIZE);
  187.         break;
  188.        
  189.         case EP_CTRL_IN: // device => PC
  190.             uart_println("TRNCOMPL on ctrl in FIFO");
  191.             // manage auxiliary data + ZLP
  192.             cnt = USB_Get_CNT(EP_CTRL_IN);
  193.             aux = USB_Get_AUXDATA(EP_CTRL_IN);
  194.                        
  195.             if(cnt == aux && aux != 0) // aux != 0 for packets with 0 length in the beginning.
  196.             {
  197.                 USB_ZLP(EP_CTRL_IN);
  198.                 USB_Ack(EP_CTRL_IN);
  199.                 uart_println("Sending ZLP");
  200.             }
  201.             else if (cnt < aux)
  202.             {
  203.                 aux -= cnt; //"cnt" sent
  204.                 USB_Set_AUXDATA(EP_CTRL_IN, aux); // set new auxiliary data
  205.                 USB_Set_DATA(EP_CTRL_IN, USB_Get_DATA(EP_CTRL_IN) + cnt); // move ptr by cnt further. Might not have been full XBOOT_DATASIZE (for example only the first 8B of device descriptor for backward compatibility)
  206.                 USB_Set_CNT(EP_CTRL_IN, MIN(aux, cnt)); // now send either aux or cnt - what is smaller. If aux is smaller than max data, then send aux, otherwise max data (cnt)
  207.                 USB_Ack(EP_CTRL_IN);
  208.                 uart_println("Sending another CNT AUX:");
  209.                 //usart_u16(cnt);
  210.                 memdump(&cnt, 2);
  211.                 //usart_u16(aux);
  212.                 memdump(&aux, 2);
  213.                 uart_println("");
  214.             }
  215.             else
  216.             {
  217.                 // error, shouldn't happen?!
  218.                 uart_println("error! cnt > aux!");
  219.             }
  220.            
  221.             if(USB_State == AddressPending)
  222.             {
  223.                 USB_Set_Address(USB_New_Addr);
  224.                 USB_State = Addressed;
  225.                 uart_println("Setting new address");
  226.             }
  227.         break;
  228.        
  229.         /*case EP_DATA_IN: // uart rx
  230.  
  231.         break;
  232.        
  233.         case EP_DATA_OUT: // uart tx
  234.  
  235.         break;
  236.        
  237.         case EP_NOTIF_IN:
  238.        
  239.         break;*/
  240.        
  241.         default: // CDC packet or error condition
  242.             USB_CDC_Data_Packet(EP);
  243.             return;
  244.         break;
  245.     }
  246. }
  247.  
  248. ISR(USB_BUSEVENT_vect)
  249. {
  250.     if(USB.INTFLAGSASET & USB_SOFIF_bm)
  251.     {
  252.         USB.INTFLAGSACLR = USB_SOFIF_bm;
  253.         return;
  254.     }
  255.    
  256.     if(USB.INTFLAGSASET & USB_RSTIF_bm)
  257.     {
  258.         USB.INTFLAGSACLR = USB_RSTIF_bm;
  259.         uart_println("Resetting.");
  260.         USB_Detach();
  261.         USB_Reset();
  262.         USB_Attach();
  263.         return;
  264.     }
  265.  
  266.     USB.INTFLAGSACLR = 0xFF; // clear all the USB A flags
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement