fxload fx2lp dev board
[fx2fw-sdcc] / fx2 / usb_common.c
index 8805e45..4fc3492 100644 (file)
 /* -*- c++ -*- */\r
-\r
 /*-----------------------------------------------------------------------------\r
-\r
  * Common USB code for FX2\r
-\r
  *-----------------------------------------------------------------------------\r
-\r
  * Code taken from USRP2 firmware (GNU Radio Project), version 3.0.2,\r
-\r
  * Copyright 2003 Free Software Foundation, Inc.\r
-\r
  *-----------------------------------------------------------------------------\r
-\r
  * This code is part of usbjtag. usbjtag is free software; you can redistribute\r
-\r
  * it and/or modify it under the terms of the GNU General Public License as\r
-\r
  * published by the Free Software Foundation; either version 2 of the License,\r
-\r
  * or (at your option) any later version. usbjtag is distributed in the hope\r
-\r
  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\r
-\r
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-\r
  * GNU General Public License for more details.  You should have received a\r
-\r
  * copy of the GNU General Public License along with this program in the file\r
-\r
  * COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin\r
-\r
  * St, Fifth Floor, Boston, MA  02110-1301  USA\r
-\r
  *-----------------------------------------------------------------------------\r
-\r
  */\r
 \r
-\r
-\r
 #include "usb_common.h"\r
-\r
 #include "fx2regs.h"\r
-\r
 #include "syncdelay.h"\r
-\r
 #include "fx2utils.h"\r
-\r
 #include "isr.h"\r
-\r
 #include "usb_descriptors.h"\r
-\r
 #include "usb_requests.h"\r
 \r
-\r
-\r
 extern xdata char str0[];\r
-\r
 extern xdata char str1[];\r
-\r
 extern xdata char str2[];\r
-\r
 extern xdata char str3[];\r
-\r
 extern xdata char str4[];\r
-\r
 extern xdata char str5[];\r
 \r
-\r
-\r
 volatile bit _usb_got_SUDAV;\r
 \r
-\r
-\r
 unsigned char  _usb_config = 0;\r
-\r
 unsigned char  _usb_alt_setting = 0;   // FIXME really 1/interface\r
 \r
-\r
-\r
 xdata unsigned char *current_device_descr;\r
-\r
 xdata unsigned char *current_devqual_descr;\r
-\r
 xdata unsigned char *current_config_descr;\r
-\r
 xdata unsigned char *other_config_descr;\r
 \r
-\r
-\r
 static void\r
-\r
 setup_descriptors (void)\r
-\r
 {\r
-\r
   if (USBCS & bmHSM){          // high speed mode\r
-\r
     current_device_descr  = high_speed_device_descr;\r
-\r
     current_devqual_descr = high_speed_devqual_descr;\r
-\r
     current_config_descr  = high_speed_config_descr;\r
-\r
     other_config_descr    = full_speed_config_descr;\r
-\r
        EP8AUTOINLENH = 0x02; SYNCDELAY;                                // Size in bytes of the IN data automatically commited (512 bytes here)\r
-\r
        EP8AUTOINLENL = 0x00; SYNCDELAY;                                // Can use signal PKTEND if you want to commit a shorter packet\r
-\r
   }\r
-\r
   else {\r
-\r
     current_device_descr  = full_speed_device_descr;\r
-\r
     current_devqual_descr = full_speed_devqual_descr;\r
-\r
     current_config_descr  = full_speed_config_descr;\r
-\r
     other_config_descr    = high_speed_config_descr;\r
-\r
        EP8AUTOINLENH = 0x00; SYNCDELAY;                                // Size in bytes of the IN data automatically commited (64 bytes here)\r
-\r
        EP8AUTOINLENL = 0x40; SYNCDELAY;                                // Can use signal PKTEND if you want to commit a shorter packet\r
-\r
   }\r
 \r
-\r
-\r
   // whack the type fields\r
-\r
   // FIXME, may not be required.\r
-\r
   // current_config_descr[1] = DT_CONFIG;\r
-\r
   // other_config_descr[1]   = DT_OTHER_SPEED;\r
-\r
 }\r
 \r
-\r
-\r
 static void\r
-\r
 isr_SUDAV (void) interrupt\r
-\r
 {\r
-\r
   clear_usb_irq ();\r
-\r
   _usb_got_SUDAV = 1;\r
-\r
 }\r
 \r
-\r
-\r
 static void\r
-\r
 isr_USBRESET (void) interrupt\r
-\r
 {\r
-\r
   clear_usb_irq ();\r
-\r
   setup_descriptors ();\r
-\r
 }\r
 \r
-\r
-\r
 static void\r
-\r
 isr_HIGHSPEED (void) interrupt\r
-\r
 {\r
-\r
   clear_usb_irq ();\r
-\r
   setup_descriptors ();\r
-\r
 }\r
 \r
-\r
-\r
 void\r
-\r
 usb_install_handlers (void)\r
-\r
 {\r
-\r
   setup_descriptors ();            // ensure that they're set before use\r
 \r
-\r
-\r
   hook_uv (UV_SUDAV,     (unsigned short) isr_SUDAV);\r
-\r
   hook_uv (UV_USBRESET,  (unsigned short) isr_USBRESET);\r
-\r
   hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);\r
 \r
-\r
-\r
   USBIE = bmSUDAV | bmURES | bmHSGRANT;\r
-\r
 }\r
 \r
-\r
-\r
 // On the FX2 the only plausible endpoints are 0, 1, 2, 4, 6, 8\r
-\r
 // This doesn't check to see that they're enabled\r
 \r
-\r
-\r
 unsigned char\r
-\r
 plausible_endpoint (unsigned char ep)\r
-\r
 {\r
-\r
   ep &= ~0x80; // ignore direction bit\r
 \r
-\r
-\r
   if (ep > 8)\r
-\r
     return 0;\r
 \r
-\r
-\r
   if (ep == 1)\r
-\r
     return 1;\r
 \r
-\r
-\r
   return (ep & 0x1) == 0;      // must be even\r
-\r
 }\r
 \r
-\r
-\r
 // return pointer to control and status register for endpoint.\r
-\r
 // only called with plausible_endpoints\r
 \r
-\r
-\r
 xdata volatile unsigned char *\r
-\r
 epcs (unsigned char ep)\r
-\r
 {\r
-\r
   if (ep == 0x01)              // ep1 has different in and out CS regs\r
-\r
     return EP1OUTCS;\r
 \r
-\r
-\r
   if (ep == 0x81)\r
-\r
     return EP1INCS;\r
 \r
-\r
-\r
   ep &= ~0x80;                 // ignore direction bit\r
 \r
-\r
-\r
   if (ep == 0x00)              // ep0\r
-\r
     return EP0CS;\r
 \r
-\r
-\r
   return EP2CS + (ep >> 1);    // 2, 4, 6, 8 are consecutive\r
-\r
 }\r
 \r
-\r
-\r
 void\r
-\r
 usb_handle_setup_packet (void)\r
-\r
 {\r
-\r
   _usb_got_SUDAV = 0;\r
 \r
-\r
-\r
   // handle the standard requests...\r
 \r
-\r
-\r
   switch (bRequestType & bmRT_TYPE_MASK){\r
 \r
-\r
-\r
   case bmRT_TYPE_CLASS:\r
-\r
   case bmRT_TYPE_RESERVED:\r
-\r
     fx2_stall_ep0 ();          // we don't handle these.  indicate error\r
-\r
     break;\r
-\r
     \r
-\r
   case bmRT_TYPE_VENDOR:\r
-\r
     // call the application code.\r
-\r
     // If it handles the command it returns non-zero\r
 \r
-\r
-\r
     if (!app_vendor_cmd ())    \r
-\r
       fx2_stall_ep0 ();\r
-\r
     break;\r
 \r
-\r
-\r
   case bmRT_TYPE_STD:\r
-\r
     // these are the standard requests...\r
 \r
-\r
-\r
     if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){\r
 \r
-\r
-\r
       ////////////////////////////////////\r
-\r
       //    handle the IN requests\r
-\r
       ////////////////////////////////////\r
 \r
-\r
-\r
       switch (bRequest){\r
 \r
-\r
-\r
       case RQ_GET_CONFIG:\r
-\r
        EP0BUF[0] = _usb_config;        // FIXME app should handle\r
-\r
        EP0BCH = 0;\r
-\r
        EP0BCL = 1;\r
-\r
        break;\r
-\r
        \r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_GET_INTERFACE:\r
-\r
        EP0BUF[0] = _usb_alt_setting;   // FIXME app should handle\r
-\r
        EP0BCH = 0;\r
-\r
        EP0BCL = 1;\r
-\r
        break;\r
 \r
-\r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_GET_DESCR:\r
-\r
        switch (wValueH){\r
 \r
-\r
-\r
        case DT_DEVICE:\r
-\r
          SUDPTRH = MSB (current_device_descr);\r
-\r
          SUDPTRL = LSB (current_device_descr);\r
-\r
          break;\r
-\r
          \r
-\r
        case DT_DEVQUAL:\r
-\r
          SUDPTRH = MSB (current_devqual_descr);\r
-\r
          SUDPTRL = LSB (current_devqual_descr);\r
-\r
          break;\r
 \r
-\r
-\r
        case DT_CONFIG:\r
-\r
          if (0 && wValueL != 1)        // FIXME only a single configuration\r
-\r
            fx2_stall_ep0 ();\r
-\r
          else {\r
-\r
            SUDPTRH = MSB (current_config_descr);\r
-\r
            SUDPTRL = LSB (current_config_descr);\r
-\r
          }\r
-\r
          break;\r
 \r
-\r
-\r
        case DT_OTHER_SPEED:\r
-\r
          if (0 && wValueL != 1)        // FIXME only a single configuration\r
-\r
            fx2_stall_ep0 ();\r
-\r
          else {\r
-\r
            SUDPTRH = MSB (other_config_descr);\r
-\r
            SUDPTRL = LSB (other_config_descr);\r
-\r
          }\r
-\r
          break;\r
 \r
-\r
-\r
        case DT_STRING:\r
-\r
          if (wValueL >= nstring_descriptors)\r
-\r
            fx2_stall_ep0 ();\r
-\r
          else {\r
-\r
            xdata char *p = string_descriptors[wValueL];\r
-\r
            SUDPTRH = MSB (p);\r
-\r
            SUDPTRL = LSB (p);\r
-\r
          }\r
-\r
          break;\r
 \r
-\r
-\r
        default:\r
-\r
          fx2_stall_ep0 ();     // invalid request\r
-\r
          break;\r
-\r
        }\r
-\r
        break;\r
-\r
        \r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_GET_STATUS:\r
-\r
        switch (bRequestType & bmRT_RECIP_MASK){\r
-\r
        case bmRT_RECIP_DEVICE:\r
-\r
          EP0BUF[0] = 0;\r
-\r
          EP0BUF[1] = 0;\r
-\r
          EP0BCH = 0;\r
-\r
          EP0BCL = 2;\r
-\r
          break;\r
 \r
-\r
-\r
        case bmRT_RECIP_INTERFACE:\r
-\r
          EP0BUF[0] = 0;\r
-\r
          EP0BUF[1] = 0;\r
-\r
          EP0BCH = 0;\r
-\r
          EP0BCL = 2;\r
-\r
          break;\r
 \r
-\r
-\r
        case bmRT_RECIP_ENDPOINT:\r
-\r
          if (plausible_endpoint (wIndexL)){\r
-\r
            EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL;\r
-\r
            EP0BUF[1] = 0;\r
-\r
            EP0BCH = 0;\r
-\r
            EP0BCL = 2;\r
-\r
          }\r
-\r
          else\r
-\r
            fx2_stall_ep0 ();\r
-\r
          break;\r
 \r
-\r
-\r
        default:\r
-\r
          fx2_stall_ep0 ();\r
-\r
          break;\r
-\r
        }\r
-\r
         break;\r
 \r
-\r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_SYNCH_FRAME:     // not implemented\r
-\r
       default:\r
-\r
        fx2_stall_ep0 ();\r
-\r
        break;\r
-\r
       }\r
-\r
     }\r
 \r
-\r
-\r
     else {\r
 \r
-\r
-\r
       ////////////////////////////////////\r
-\r
       //    handle the OUT requests\r
-\r
       ////////////////////////////////////\r
 \r
-\r
-\r
       switch (bRequest){\r
 \r
-\r
-\r
       case RQ_SET_CONFIG:\r
-\r
        IOE &= ~(1 << 6);\r
-\r
        _usb_config = wValueL;          // FIXME app should handle\r
-\r
        break;\r
 \r
-\r
-\r
       case RQ_SET_INTERFACE:\r
-\r
        _usb_alt_setting = wValueL;     // FIXME app should handle\r
-\r
        break;\r
 \r
-\r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_CLEAR_FEATURE:\r
-\r
        switch (bRequestType & bmRT_RECIP_MASK){\r
 \r
-\r
-\r
        case bmRT_RECIP_DEVICE:\r
-\r
          switch (wValueL){\r
-\r
          case FS_DEV_REMOTE_WAKEUP:\r
-\r
          default:\r
-\r
            fx2_stall_ep0 ();\r
-\r
          }\r
-\r
          break;\r
 \r
-\r
-\r
        case bmRT_RECIP_ENDPOINT:\r
-\r
          if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){\r
-\r
            *epcs (wIndexL) &= ~bmEPSTALL;\r
-\r
            fx2_reset_data_toggle (wIndexL);\r
-\r
          }\r
-\r
          else\r
-\r
            fx2_stall_ep0 ();\r
-\r
          break;\r
 \r
-\r
-\r
        default:\r
-\r
          fx2_stall_ep0 ();\r
-\r
          break;\r
-\r
        }\r
-\r
        break;\r
 \r
-\r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_SET_FEATURE:\r
-\r
        switch (bRequestType & bmRT_RECIP_MASK){\r
 \r
-\r
-\r
        case bmRT_RECIP_DEVICE:\r
-\r
          switch (wValueL){\r
-\r
          case FS_TEST_MODE:\r
-\r
            // hardware handles this after we complete SETUP phase handshake\r
-\r
            break;\r
 \r
-\r
-\r
          case FS_DEV_REMOTE_WAKEUP:\r
-\r
          default:\r
-\r
            fx2_stall_ep0 ();\r
-\r
            break;\r
-\r
          }\r
-\r
        }\r
-\r
        break;\r
 \r
-\r
-\r
       case bmRT_RECIP_ENDPOINT:\r
-\r
        switch (wValueL){\r
-\r
        case FS_ENDPOINT_HALT:\r
-\r
          if (plausible_endpoint (wIndexL))\r
-\r
            *epcs (wIndexL) |= bmEPSTALL;\r
-\r
          else\r
-\r
            fx2_stall_ep0 ();\r
-\r
          break;\r
 \r
-\r
-\r
        default:\r
-\r
          fx2_stall_ep0 ();\r
-\r
          break;\r
-\r
        }\r
-\r
        break;\r
 \r
-\r
-\r
       // --------------------------------\r
 \r
-\r
-\r
       case RQ_SET_ADDRESS:     // handled by fx2 hardware\r
-\r
       case RQ_SET_DESCR:       // not implemented\r
-\r
       default:\r
-\r
        fx2_stall_ep0 ();\r
-\r
       }\r
 \r
-\r
-\r
     }\r
-\r
     break;\r
 \r
-\r
-\r
   }    // bmRT_TYPE_MASK\r
 \r
-\r
-\r
   // ack handshake phase of device request\r
-\r
   EP0CS |= bmHSNAK;\r
-\r
 }\r
-\r