diff options
| author | Balint Seeber <balint.seeber@ettus.com> | 2015-06-17 11:34:43 -0700 | 
|---|---|---|
| committer | Martin Braun <martin.braun@ettus.com> | 2015-07-14 11:52:21 -0700 | 
| commit | 6d0f1ee6f6a2dffd2ab9480c196f2393d2f67b75 (patch) | |
| tree | 293b32414b58e299600647d2688ec411b32d9c0c | |
| parent | 0afc5d7c646942c668a2dbabf5ba657f00ba9625 (diff) | |
| download | uhd-6d0f1ee6f6a2dffd2ab9480c196f2393d2f67b75.tar.gz uhd-6d0f1ee6f6a2dffd2ab9480c196f2393d2f67b75.tar.bz2 uhd-6d0f1ee6f6a2dffd2ab9480c196f2393d2f67b75.zip | |
fx3: New firmware features: Logging, more configuration
- Logging in conjunction with B200 side-channel utility
  (using UART or directly over USB)
- More and better configurability, e.g. Tx voltage swing
  and DMA configuration
| -rwxr-xr-x[-rw-r--r--] | firmware/fx3/b200/b200_gpifconfig.h | 46 | ||||
| -rw-r--r-- | firmware/fx3/b200/b200_main.c | 974 | ||||
| -rw-r--r-- | firmware/fx3/b200/b200_usb_descriptors.c | 100 | 
3 files changed, 756 insertions, 364 deletions
| diff --git a/firmware/fx3/b200/b200_gpifconfig.h b/firmware/fx3/b200/b200_gpifconfig.h index 58836fac8..a6a24e0c5 100644..100755 --- a/firmware/fx3/b200/b200_gpifconfig.h +++ b/firmware/fx3/b200/b200_gpifconfig.h @@ -1,10 +1,6 @@ -//
 -// Copyright 2013-2014 Ettus Research LLC
 -//
 -
  /*
 - * Project Name: b200_v2.cyfx
 - * Time : 01/17/2013 12:50:08
 + * Project Name: ssf2-edit.cyfx
 + * Time : 11/17/2014 13:01:01
   * Device Type: FX3
   * Project Type: GPIF2
   *
 @@ -13,7 +9,7 @@   *
   * This is a generated file and should not be modified
   * This file need to be included only once in the firmware
 - * This file is generated by Gpif2 designer tool version - 1.0.715.0
 + * This file is generated by Gpif2 designer tool version - 1.0.837.1
   * 
   */
 @@ -25,7 +21,7 @@  /* Summary
     Number of states in the state machine
   */
 -#define CY_NUMBER_OF_STATES 6
 +#define CY_NUMBER_OF_STATES 7
  /* Summary
     Mapping of user defined state names to state indices
 @@ -36,12 +32,13 @@  #define WRITE 3
  #define SHORT_PKT 4
  #define ZLP 5
 +#define DSS_STATE 6
  /* Summary
     Initial value of early outputs from the state machine.
   */
 -#define ALPHA_RESET 0x8
 +#define ALPHA_RESET 0xC
  /* Summary
 @@ -58,26 +55,27 @@ uint16_t CyFxGpifTransition[]  = {     waveform table. 
   */
  CyU3PGpifWaveData CyFxGpifWavedata[]  = {
 -    {{0x1E086001,0x000100C4,0x80000000},{0x00000000,0x00000000,0x00000000}},
 -    {{0x4E080302,0x00000200,0x80000000},{0x00000000,0x00000000,0x00000000}},
 -    {{0x1E086001,0x000100C4,0x80000000},{0x4E040704,0x20000200,0xC0100000}},
 +    {{0x1E086001,0x000302C4,0x80000000},{0x00000000,0x00000000,0x00000000}},
 +    {{0x4E080302,0x00000300,0x80000000},{0x1E086006,0x000302C4,0x80000000}},
 +    {{0x1E086001,0x000302C4,0x80000000},{0x4E040704,0x20000300,0xC0100000}},
 +    {{0x4E080302,0x00000300,0x80000000},{0x1E086001,0x000302C4,0x80000000}},
      {{0x00000000,0x00000000,0x00000000},{0x00000000,0x00000000,0x00000000}},
 -    {{0x00000000,0x00000000,0x00000000},{0x3E738705,0x00000200,0xC0100000}},
 -    {{0x00000000,0x00000000,0x00000000},{0x5E002703,0x2001020C,0x80000000}},
 -    {{0x00000000,0x00000000,0x00000000},{0x4E040704,0x20000200,0xC0100000}}
 +    {{0x00000000,0x00000000,0x00000000},{0x3E738705,0x00000300,0xC0100000}},
 +    {{0x00000000,0x00000000,0x00000000},{0x5E002703,0x2003030C,0x80000000}},
 +    {{0x00000000,0x00000000,0x00000000},{0x4E040704,0x20000300,0xC0100000}}
  };
  /* Summary
     Table that maps state indices to the descriptor table indices.
   */
  uint8_t CyFxGpifWavedataPosition[]  = {
 -    0,1,0,2,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 -    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 -    0,4,0,2,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 -    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 -    0,5,0,2,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 -    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 -    0,6,0,2,0,0
 +    0,1,0,2,0,0,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 +    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 +    0,5,0,2,0,0,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 +    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 +    0,6,0,2,0,0,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 +    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 +    0,7,0,2,0,0,7
  };
  /* Summary
 @@ -154,12 +152,12 @@ uint32_t CyFxGpifRegValue[]  = {      0x00000000,  /*  CY_U3P_PIB_GPIF_LAMBDA_STAT */
      0x00000000,  /*  CY_U3P_PIB_GPIF_ALPHA_STAT */
      0x00000000,  /*  CY_U3P_PIB_GPIF_BETA_STAT */
 -    0x00080000,  /*  CY_U3P_PIB_GPIF_WAVEFORM_CTRL_STAT */
 +    0x000C0000,  /*  CY_U3P_PIB_GPIF_WAVEFORM_CTRL_STAT */
      0x00000000,  /*  CY_U3P_PIB_GPIF_WAVEFORM_SWITCH */
      0x00000000,  /*  CY_U3P_PIB_GPIF_WAVEFORM_SWITCH_TIMEOUT */
      0x00000000,  /*  CY_U3P_PIB_GPIF_CRC_CONFIG */
      0x00000000,  /*  CY_U3P_PIB_GPIF_CRC_DATA */
 -    0xFFFFFFF1  /*  CY_U3P_PIB_GPIF_BETA_DEASSERT */
 +    0xFFFFFFC1  /*  CY_U3P_PIB_GPIF_BETA_DEASSERT */
  };
  /* Summary
 diff --git a/firmware/fx3/b200/b200_main.c b/firmware/fx3/b200/b200_main.c index cb0172af3..e552d3177 100644 --- a/firmware/fx3/b200/b200_main.c +++ b/firmware/fx3/b200/b200_main.c @@ -1,5 +1,5 @@  // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 Ettus Research LLC  //  /* This file defines the application that runs on the Cypress FX3 device, and @@ -34,18 +34,19 @@   *          Indented features must have the parent feature enabled as well.   */ -//#define HAS_HEAP                    // This requires memory to be set aside for the heap (e.g. required for printing floating-point numbers). You can apply the accompanying patch ('fx3_mem_map.patch') to fx3.ld & cyfxtx.c to create one. -//#define ENABLE_MSG                  // This will cause the compiled code to exceed the default text memory area (SYS_MEM). You can apply the accompanying patch ('fx3_mem_map.patch') to fx3.ld & cyfxtx.c to resize the memory map so it will fit. -//#define ENABLE_MANUAL_DMA_XFER -//#define   ENABLE_MANUAL_DMA_XFER_FROM_HOST -//#define   ENABLE_MANUAL_DMA_XFER_TO_HOST +#define HAS_HEAP                    // This requires memory to be set aside for the heap (e.g. required for printing floating-point numbers). You can apply the accompanying patch ('fx3_mem_map.patch') to fx3.ld & cyfxtx.c to create one. +#define ENABLE_MSG                  // This will cause the compiled code to exceed the default text memory area (SYS_MEM). You can apply the accompanying patch ('fx3_mem_map.patch') to fx3.ld & cyfxtx.c to resize the memory map so it will fit. +#define ENABLE_MANUAL_DMA_XFER      // Allows us to set it from the host (using the side channel util), doesn't auto-enable it +//#define   ENABLE_P2U_SUSP_EOP +#define   ENABLE_MANUAL_DMA_XFER_FROM_HOST +#define   ENABLE_MANUAL_DMA_XFER_TO_HOST  //#define   ENABLE_DMA_BUFFER_PACKET_DEBUG -//#define ENABLE_FPGA_SB              // Be careful: this will add an ever-so-slight delay to some operations (e.g. AD3961 tune) +#define ENABLE_FPGA_SB              // Be careful: this will add an ever-so-slight delay to some operations (e.g. AD3961 tune)  #define ENABLE_RE_ENUM_THREAD  #define ENABLE_USB_EVENT_LOGGING  //#define PREVENT_LOW_POWER_MODE -//#define ENABLE_INIT_B_WORKAROUND    // This should only be enabled if you have a board where the FPGA INIT_B line is broken, but the FPGA is known to work -//#define ENABLE_DONE_WORKAROUND      // This should only be enabled if you have a board where the FPGA DONE line is broken, but the FPGA is known to work +/*#define ENABLE_INIT_B_WORKAROUND    // This should only be enabled if you have a board where the FPGA INIT_B line is broken, but the FPGA is known to work*/ +/*#define ENABLE_DONE_WORKAROUND      // This should only be enabled if you have a board where the FPGA DONE line is broken, but the FPGA is known to work*/  #define WATCHDOG_TIMEOUT                1500  #define CHECK_POWER_STATE_SLEEP_TIME    500  // Should be less than WATCHDOG_TIMEOUT @@ -178,7 +179,7 @@ static uint8_t g_usb_event_log_contiguous_buf[USB_EVENT_LOG_SIZE];  #ifdef ENABLE_FPGA_SB  static CyBool_t g_fpga_sb_enabled = CyFalse; -static uint16_t g_fpga_sb_uart_div = 434*2; +//static uint16_t g_fpga_sb_uart_div = 434*2;  static uint16_t g_fpga_sb_last_usb_event_log_index = 0;  static CyU3PThread thread_fpga_sb_poll;  static CyU3PMutex g_suart_lock; @@ -215,7 +216,8 @@ enum ConfigFlags {      CF_DMA_BUFFER_SIZE      = 1 << 5,      CF_DMA_BUFFER_COUNT     = 1 << 6,      CF_MANUAL_DMA           = 1 << 7, -     +    CF_SB_BAUD_DIV          = 1 << 8, +      CF_RE_ENUM              = 1 << 31  }; @@ -236,7 +238,17 @@ typedef struct ConfigMod {      CONFIG config;  } CONFIG_MOD, *PCONFIG_MOD; -static CONFIG g_config; +static CONFIG g_config = { +    65,     // tx_swing +    0x11,   // tx_deemphasis +    0,      // disable_usb2 +    1,      // enable_as_superspeed +    CY_U3P_DS_THREE_QUARTER_STRENGTH,   // pport_drive_strength +    64512,  // dma_buffer_size 2**16-1, then aligned to next page boundary +    1,      // dma_buffer_count +    0,      // manual_dma +    434*2   // sb_baud_div +};  static CONFIG_MOD g_config_mod;  #define REG_LNK_PHY_ERROR_STATUS 0xE0033044 @@ -251,7 +263,7 @@ enum PhyErrors {      PHYERR_PHY_ERROR_EB_UND_EV     = 1 << 2,      PHYERR_PHY_ERROR_EB_OVR_EV     = 1 << 1,      PHYERR_PHY_ERROR_DECODE_EV     = 1 << 0, -     +      PHYERR_MAX                     = PHYERR_PHY_LOCK_EV,      PHYERR_MASK                    = (PHYERR_MAX << 1) - 1  }; @@ -259,7 +271,7 @@ enum PhyErrors {  typedef struct USBErrorCounters {      int phy_error_count;      int link_error_count; -     +      int PHY_LOCK_EV;      int TRAINING_ERROR_EV;      int RX_ERROR_CRC32_EV; @@ -281,35 +293,45 @@ typedef struct DMACounters {      int ERROR;      int PROD_SUSP;      int CONS_SUSP; -     +      int BUFFER_MARKER;      int BUFFER_EOP;      int BUFFER_ERROR;      int BUFFER_OCCUPIED; -     +      int last_count;      int last_size; -     +      int last_sid;      int bad_sid_count;  } DMA_COUNTERS, *PDMA_COUNTERS; +typedef struct PIBCounters +{ +    int socket_inactive;   // CYU3P_PIB_ERR_THR1_SCK_INACTIVE +} PIB_COUNTERS, *PPIB_COUNTERS; +  typedef struct Counters {      int magic; -     +      DMA_COUNTERS dma_to_host;      DMA_COUNTERS dma_from_host; -     +      int log_overrun_count; -     +      int usb_error_update_count; -    USB_ERROR_COUNTERS usb_error_counters;  -     +    USB_ERROR_COUNTERS usb_error_counters; +      int usb_ep_underrun_count; -     +      int heap_size; -     +      int resume_count; + +    int state_transition_count; +    int invalid_gpif_state; + +    PIB_COUNTERS pib_counters[4];  } COUNTERS, *PCOUNTERS;  volatile static COUNTERS g_counters; @@ -333,7 +355,7 @@ caddr_t _sbrk(int incr)      extern char __heap_end;      char *prev_heap_end; -    if (heap_end == 0)  +    if (heap_end == 0)      {          heap_end = (char *)&__heap_start;      } @@ -366,15 +388,15 @@ void msg(const char* str, ...) {      va_list args;      static char buf[LOG_BUFFER_SIZE];      int idx = 0; -     +      msg_CHECK_USE_LOCK          LOCK(g_log_lock); -     +      ++log_count;      log_count %= 10000;      va_start(args, str); -     +      if (1) { // FIXME: Optional          uint32_t time_now = CyU3PGetTime();          idx += sprintf(buf, "%08X %04i ", (uint)time_now, log_count); @@ -382,19 +404,19 @@ void msg(const char* str, ...) {      else          idx += sprintf(buf, "%04i ", log_count);      idx += vsnprintf(buf + idx, LOG_BUFFER_SIZE - idx, str, args); -     +      va_end(args); -     +      if ((LOG_BUFFER_SIZE - log_buffer_len) < (idx + 1 + 1)) {          msg_CHECK_USE_LOCK              LOCK(g_counters_lock);          ++g_counters.log_overrun_count;          msg_CHECK_USE_LOCK              UNLOCK(g_counters_lock); -         +          goto msg_exit;      } -     +      // Circular buffer if we need it later, but currently won't wrap due to above condition      memcpy(log_buffer + log_buffer_len, buf, min(idx + 1, LOG_BUFFER_SIZE - log_buffer_len));      if ((idx + 1) > (LOG_BUFFER_SIZE - log_buffer_len)) @@ -404,7 +426,7 @@ void msg(const char* str, ...) {      }      else          log_buffer[log_buffer_len + idx + 1] = '\0'; -     +      log_buffer_len += (idx + 1);  msg_exit:      msg_CHECK_USE_LOCK @@ -437,42 +459,42 @@ void msg_nl(const char* str, ...)  */  void log_reset(void) {      //LOCK(g_log_lock); -	 +      log_buffer_idx = 0; -	log_buffer_len = 0; +    log_buffer_len = 0;      log_buffer[0] = '\0'; -     +      //UNLOCK(g_log_lock);  }  void counters_auto_reset(void) {      //LOCK(g_counters_lock); -     -	g_counters.log_overrun_count = 0; -     + +    g_counters.log_overrun_count = 0; +      //UNLOCK(g_counters_lock);  }  void counters_dma_reset(void) {      LOCK(g_counters_lock); -     +      LOCK(g_counters_dma_to_host_lock);      memset((void*)&g_counters.dma_to_host, 0x00, sizeof(DMA_COUNTERS));      UNLOCK(g_counters_dma_to_host_lock); -     +      LOCK(g_counters_dma_from_host_lock);      memset((void*)&g_counters.dma_from_host, 0x00, sizeof(DMA_COUNTERS));      UNLOCK(g_counters_dma_from_host_lock); -     +      UNLOCK(g_counters_lock);  }  void counters_reset_usb_errors(void) {      LOCK(g_counters_lock); -     +      g_counters.usb_error_update_count = 0;      memset((void*)&g_counters.usb_error_counters, 0x00, sizeof(g_counters.usb_error_counters)); -     +      UNLOCK(g_counters_lock);  } @@ -485,10 +507,10 @@ void dma_callback (          int from_host)  {      CyU3PReturnStatus_t status = CY_U3P_SUCCESS; -     +      PDMA_COUNTERS cnt = (PDMA_COUNTERS)(from_host ? &g_counters.dma_from_host : &g_counters.dma_to_host);      CyU3PMutex* lock = (from_host ? &g_counters_dma_from_host_lock : &g_counters_dma_to_host_lock); -     +      uint16_t buffer_status = (input->buffer_p.status & CY_U3P_DMA_BUFFER_STATUS_MASK);      if (buffer_status & CY_U3P_DMA_BUFFER_MARKER)      { @@ -513,49 +535,51 @@ void dma_callback (          LOCKP(lock);          int prod_cnt = cnt->PROD_EVENT++;          UNLOCKP(lock); -         -        if (cnt->last_count != input->buffer_p.count) -            msg("[DMA %05d] buffer.count (%d) != last_count (%d)", prod_cnt, input->buffer_p.count, cnt->last_count); + +        //if (cnt->last_count != input->buffer_p.count) +        //    msg("[DMA%d %05d] buffer.count (%05d) != last_count (%05d)", from_host, prod_cnt, input->buffer_p.count, cnt->last_count);          cnt->last_count = input->buffer_p.count; -         +          if (cnt->last_size != input->buffer_p.size) -            msg("[DMA %05d] buffer.size (%d) != last_size (%d)", prod_cnt, input->buffer_p.size, cnt->last_size); +            msg("[DMA%d %05d] buffer.size (%05d) != last_size (%05d)", from_host, prod_cnt, input->buffer_p.size, cnt->last_size);          cnt->last_size = input->buffer_p.size; -         +          uint32_t* p32 = input->buffer_p.buffer;          uint32_t sid = p32[1];          cnt->last_sid = (int)sid; -        if ((sid != 0xa0) && (sid != 0xb0)) +        if (((from_host == 0) && ((sid != 0xa0) && (sid != 0xb0))) || +            ((from_host == 1) && ((sid != 0x50) && (sid != 0x60))))          {              cnt->bad_sid_count++; -            msg("[DMA %05d] Bad SID: 0x%08x", prod_cnt, sid); +            msg("[DMA%d %05d] Bad SID: 0x%08x", from_host, prod_cnt, sid);          } -         +          uint16_t* p16 = input->buffer_p.buffer; -         +          if (p32[0] & (((uint32_t)1) << 31))          { -            msg("[DMA %05d] Error code: 0x%x (packet len: %d)", prod_cnt, p32[4], p16[0]); // Status -             -            //msg("[DMA] 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", p32[0], p32[1], p32[2], p32[3], p32[4], p32[5]); +            msg("[DMA%d %05d] Error code: 0x%x (packet len: %05d, buffer count: %05d, seq: %04d)", from_host, prod_cnt, p32[4], p16[0], input->buffer_p.count, (p16[1] & 0x0fff)); // Status + +            //msg("[DMA%d] 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", from_host, p32[0], p32[1], p32[2], p32[3], p32[4], p32[5]);          }          else -        {             +        {              if (p16[1] & (((uint16_t)1) << 12))              { -                msg("[DMA %05d] EOB", prod_cnt);   // Comes with one sample +                msg("[DMA%d %05d] EOB (packet len: %05d, buffer count: %05d)", from_host, prod_cnt, p16[0], input->buffer_p.count);   // Comes with one sample              } -             +              if ((p16[0] != input->buffer_p.count) && -                ((p16[0] + 4) != input->buffer_p.count)) +               ((p16[0] + 4) != input->buffer_p.count)) // Case of overrun packet length being padded (being rounded up)              { -                msg("[DMA %05d] Packet len (%d) != buffer count (%d)", prod_cnt, p16[0], input->buffer_p.count); +                if (from_host == 0) +                    msg("[DMA%d %05d] Packet len (%05d) != buffer count (%05d), seq: %04d [0x%04x 0x%04x]", from_host, prod_cnt, p16[0], input->buffer_p.count, (p16[1] & 0x0fff), p16[0], p16[1]);              } -             -            //msg("[DMA] 0x%04x 0x%04x 0x%04x 0x%04x", p16[0], p16[1], p16[2], p16[3]); -             + +            //msg("[DMA%d] 0x%04x 0x%04x 0x%04x 0x%04x", from_host, p16[0], p16[1], p16[2], p16[3]); +              if (p16[1] & (((uint16_t)1) << 12)) -                msg("[DMA %05d] 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", prod_cnt, p32[0], p32[1], p32[2], p32[3], p32[4], p32[5]); +                msg("[DMA%d %05d] 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", from_host, prod_cnt, p32[0], p32[1], p32[2], p32[3], p32[4], p32[5]);          }  #endif // ENABLE_DMA_BUFFER_PACKET_DEBUG          status = CyU3PDmaChannelCommitBuffer (chHandle, input->buffer_p.count, 0); @@ -594,7 +618,7 @@ void dma_callback (          LOCKP(lock);          cnt->ABORTED++;          UNLOCKP(lock); -         +          msg("! Aborted %i", from_host);      }      else if (type == CY_U3P_DMA_CB_ERROR) @@ -602,7 +626,7 @@ void dma_callback (          LOCKP(lock);          cnt->ERROR++;          UNLOCKP(lock); -         +          msg("! Error %i", from_host);      }      else if (type == CY_U3P_DMA_CB_PROD_SUSP) @@ -610,7 +634,7 @@ void dma_callback (          LOCKP(lock);          cnt->PROD_SUSP++;          UNLOCKP(lock); -         +          msg("! Prod suspend %i", from_host);      }      else if (type == CY_U3P_DMA_CB_CONS_SUSP) @@ -618,8 +642,10 @@ void dma_callback (          LOCKP(lock);          cnt->CONS_SUSP++;          UNLOCKP(lock); -         -        msg("! Cons suspend %i", from_host); + +        //msg("! Cons suspend %i", from_host); + +        CyU3PDmaChannelResume (chHandle, CyFalse, CyTrue);      }  } @@ -672,7 +698,7 @@ void gpio_interrupt_callback(uint8_t gpio_id) {   * everything will come back up properly. */  void b200_fw_stop(void) {      msg("b200_fw_stop"); -     +      CyU3PEpConfig_t usb_endpoint_config;      /* Update the flag. */ @@ -683,14 +709,14 @@ void b200_fw_stop(void) {      CyU3PUsbFlushEp(DATA_ENDPOINT_CONSUMER);      CyU3PUsbFlushEp(CTRL_ENDPOINT_PRODUCER);      CyU3PUsbFlushEp(CTRL_ENDPOINT_CONSUMER); -     +      /* Reset the DMA channels */      // SDK 1.3 known issue #1 - probably not necessary since Destroy is next, but just in case      CyU3PDmaChannelReset(&data_cons_to_prod_chan_handle);      CyU3PDmaChannelReset(&data_prod_to_cons_chan_handle);      CyU3PDmaChannelReset(&ctrl_cons_to_prod_chan_handle);      CyU3PDmaChannelReset(&ctrl_prod_to_cons_chan_handle); -     +      /* Destroy the DMA channels */      CyU3PDmaChannelDestroy(&data_cons_to_prod_chan_handle);      CyU3PDmaChannelDestroy(&data_prod_to_cons_chan_handle); @@ -716,7 +742,7 @@ void reset_gpif(void) {      CyU3PGpioSetValue(GPIO_FPGA_RESET, CyTrue);      // Bring down GPIF -    CyU3PGpifDisable(CyTrue); +    CyU3PGpifDisable(/*CyTrue*/CyFalse);      /* Reset the DMA channels */      CyU3PDmaChannelReset(&data_cons_to_prod_chan_handle); @@ -725,42 +751,41 @@ void reset_gpif(void) {      CyU3PDmaChannelReset(&ctrl_prod_to_cons_chan_handle);      /* Reset the DMA transfers */ -    CyU3PDmaChannelSetXfer(&data_cons_to_prod_chan_handle, \ -            DMA_SIZE_INFINITE); - -    CyU3PDmaChannelSetXfer(&data_prod_to_cons_chan_handle, \ -            DMA_SIZE_INFINITE); - -    CyU3PDmaChannelSetXfer(&ctrl_cons_to_prod_chan_handle, \ -            DMA_SIZE_INFINITE); - -    CyU3PDmaChannelSetXfer(&ctrl_prod_to_cons_chan_handle, \ -            DMA_SIZE_INFINITE); +    CyU3PDmaChannelSetXfer(&data_cons_to_prod_chan_handle, DMA_SIZE_INFINITE); +    CyU3PDmaChannelSetXfer(&data_prod_to_cons_chan_handle, DMA_SIZE_INFINITE); +    CyU3PDmaChannelSetXfer(&ctrl_cons_to_prod_chan_handle, DMA_SIZE_INFINITE); +    CyU3PDmaChannelSetXfer(&ctrl_prod_to_cons_chan_handle, DMA_SIZE_INFINITE);      /* Flush the USB endpoints */      CyU3PUsbFlushEp(DATA_ENDPOINT_PRODUCER);      CyU3PUsbFlushEp(DATA_ENDPOINT_CONSUMER);      CyU3PUsbFlushEp(CTRL_ENDPOINT_PRODUCER);      CyU3PUsbFlushEp(CTRL_ENDPOINT_CONSUMER); -     +      /* Load the GPIF configuration for Slave FIFO sync mode. */ -    CyU3PGpifLoad(&CyFxGpifConfig); -     +    //CyU3PGpifLoad(&CyFxGpifConfig); +      /* Start the state machine. */ -    CyU3PGpifSMStart(RESET, ALPHA_RESET); -     +    //if (CyU3PGpifSMStart(RESET, ALPHA_RESET) != CY_U3P_SUCCESS) +    //    msg("! CyU3PGpifSMStart"); +      /* Configure the watermarks for the slfifo-write buffers. */ -    CyU3PGpifSocketConfigure(0, DATA_TX_PPORT_SOCKET, 5, CyFalse, 1); -    CyU3PGpifSocketConfigure(1, DATA_RX_PPORT_SOCKET, 6, CyFalse, 1); -    CyU3PGpifSocketConfigure(2, CTRL_COMM_PPORT_SOCKET, 5, CyFalse, 1); -    CyU3PGpifSocketConfigure(3, CTRL_RESP_PPORT_SOCKET, 6, CyFalse, 1); -     +    //CyU3PGpifSocketConfigure(0, DATA_TX_PPORT_SOCKET, 5, CyFalse, 1); +    //CyU3PGpifSocketConfigure(1, DATA_RX_PPORT_SOCKET, 6, CyFalse, 1); +    //CyU3PGpifSocketConfigure(2, CTRL_COMM_PPORT_SOCKET, 5, CyFalse, 1); +    //CyU3PGpifSocketConfigure(3, CTRL_RESP_PPORT_SOCKET, 6, CyFalse, 1); +      CyU3PGpioSetValue(GPIO_FPGA_RESET, CyFalse); -     +      CyU3PThreadSleep(FPGA_RESET_SETTLING_TIME); -     + +    if (CyU3PGpifSMStart(RESET, ALPHA_RESET) != CY_U3P_SUCCESS) +        msg("! CyU3PGpifSMStart"); + +    msg("GPIF reset"); +      b200_start_fpga_sb_gpio(); -     +      g_fx3_state = STATE_RUNNING;  } @@ -792,11 +817,11 @@ CyU3PReturnStatus_t b200_set_io_matrix(CyBool_t fpga_config_mode) {      io_config_matrix.useI2C = CyTrue;      io_config_matrix.useI2S = CyFalse;      io_config_matrix.useSpi = fpga_config_mode; -     +      res = CyU3PDeviceConfigureIOMatrix(&io_config_matrix);      if (res != CY_U3P_SUCCESS)          msg("! ConfigureIOMatrix"); -     +      return res;  } @@ -814,11 +839,11 @@ CyU3PReturnStatus_t b200_gpio_init(CyBool_t set_callback) {      gpio_clock_config.simpleDiv = CY_U3P_GPIO_SIMPLE_DIV_BY_2;      gpio_clock_config.clkSrc = CY_U3P_SYS_CLK;      gpio_clock_config.halfDiv = 0; -     +      res = CyU3PGpioInit(&gpio_clock_config, (set_callback ? gpio_interrupt_callback : NULL));      if (res != CY_U3P_SUCCESS)          msg("! CyU3PGpioInit"); -     +      return res;  } @@ -827,36 +852,36 @@ void sb_write(uint8_t reg, uint32_t val) {  #ifdef ENABLE_FPGA_SB      const int len = 32;      int i; -     +      if (g_fpga_sb_enabled == CyFalse)          return; -     +      reg += FPGA_SB_UART_ADDR_BASE; -     +      //CyU3PBusyWait(1); // Can be used after each SetValue to slow down bit changes -     +      // START      CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 1);   // Should already be 1      CyU3PGpioSetValue(GPIO_FPGA_SB_SDA, 0); -     +      // ADDR[8]      for (i = 7; i >= 0; i--) {          uint8_t bit = ((reg & (0x1 << i)) ? 0x01 : 0x00);          CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 0);          CyU3PGpioSetValue(GPIO_FPGA_SB_SDA, bit); -         +          CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 1); // FPGA reads bit      } -     +      // DATA[32]      for (i = (len-1); i >= 0; i--) {          uint8_t bit = ((val & (0x1 << i)) ? 0x01 : 0x00);          CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 0);          CyU3PGpioSetValue(GPIO_FPGA_SB_SDA, bit); -         +          CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 1); // FPGA reads bit      } -     +      // STOP      CyU3PGpioSetValue(GPIO_FPGA_SB_SDA, 0);      CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 0); @@ -888,10 +913,10 @@ void b200_enable_fpga_sb_gpio(CyBool_t enable) {  #ifdef ENABLE_FPGA_SB      CyU3PGpioSimpleConfig_t gpio_config;      CyU3PReturnStatus_t res; -     +      if (enable == CyFalse) {          g_fpga_sb_enabled = CyFalse; -         +          return;      } @@ -900,7 +925,7 @@ void b200_enable_fpga_sb_gpio(CyBool_t enable) {      gpio_config.driveHighEn = CyTrue;      gpio_config.inputEn     = CyFalse;      gpio_config.intrMode    = CY_U3P_GPIO_NO_INTR; -     +      res = CyU3PGpioSetSimpleConfig(GPIO_FPGA_SB_SCL, &gpio_config);      if (res != CY_U3P_SUCCESS) {          msg("! GpioSetSimpleConfig GPIO_FPGA_SB_SCL"); @@ -912,9 +937,9 @@ void b200_enable_fpga_sb_gpio(CyBool_t enable) {      CyU3PGpioSetValue(GPIO_FPGA_SB_SCL, 1);      CyU3PGpioSetValue(GPIO_FPGA_SB_SDA, 1); -     +      g_fpga_sb_enabled = CyTrue; -     +      msg("Debug SB OK");  #endif // ENABLE_FPGA_SB  } @@ -923,10 +948,10 @@ void b200_enable_fpga_sb_gpio(CyBool_t enable) {  void b200_start_fpga_sb_gpio(void) {  #ifdef ENABLE_FPGA_SB      LOCK(g_suart_lock); -    sb_write(SUART_CLKDIV, g_fpga_sb_uart_div);   // 16-bit reg, master clock = 100 MHz (434*2x = 230400/2) +    sb_write(SUART_CLKDIV, /*g_fpga_sb_uart_div*/g_config.sb_baud_div);   // 16-bit reg, master clock = 100 MHz (434*2x = 230400/2)      _sb_write_string("\r\n B2x0 FPGA reset\r\n");      UNLOCK(g_suart_lock); -     +      msg("Compat:  %d.%d", FX3_COMPAT_MAJOR, FX3_COMPAT_MINOR);      msg("FX3 SDK: %d.%d.%d (build %d)", CYFX_VERSION_MAJOR, CYFX_VERSION_MINOR, CYFX_VERSION_PATCH, CYFX_VERSION_BUILD);  #endif // ENABLE_FPGA_SB @@ -940,15 +965,15 @@ void b200_start_fpga_sb_gpio(void) {   * application thread will re-configure some of the pins. */  void b200_gpios_pre_fpga_config(void) {      CyU3PGpioSimpleConfig_t gpio_config; -     +      //b200_enable_fpga_sb_gpio(CyFalse); -     +      //CyU3PGpioDeInit(); -     +      b200_set_io_matrix(CyTrue); -     +      //b200_gpio_init(CyTrue);   // This now done once during startup -     +      ////////////////////////////////////      /* GPIO[0:32] must be set with the DeviceOverride function, instead of the @@ -989,24 +1014,24 @@ void b200_gpios_pre_fpga_config(void) {      /* Initialize GPIO output values. */      CyU3PGpioSetValue(GPIO_FPGA_RESET, 0);      CyU3PGpioSetValue(GPIO_PROGRAM_B, 1); -     +      b200_enable_fpga_sb_gpio(CyTrue);   // So SCL/SDA are already high when SB state machine activates  }  void b200_slfifo_mode_gpio_config(void) {      CyU3PGpioSimpleConfig_t gpio_config; -     +      //b200_enable_fpga_sb_gpio(CyFalse); -     +      //CyU3PGpioDeInit(); -     +      b200_set_io_matrix(CyFalse);      //b200_gpio_init(CyFalse);  // This now done once during startup -     +      //////////////////////////////////// -     +      /* GPIO[0:32] must be set with the DeviceOverride function, instead of the       * SimpleEn array configuration. */      CyU3PDeviceGpioOverride(GPIO_FPGA_RESET, CyTrue); @@ -1015,7 +1040,7 @@ void b200_slfifo_mode_gpio_config(void) {      CyU3PDeviceGpioOverride(GPIO_FX3_CE, CyTrue);      CyU3PDeviceGpioOverride(GPIO_FX3_MISO, CyTrue);      CyU3PDeviceGpioOverride(GPIO_FX3_MOSI, CyTrue); -     +      /* Configure GPIOs:       *      Outputs:       *          driveLowEn = True @@ -1031,13 +1056,13 @@ void b200_slfifo_mode_gpio_config(void) {      gpio_config.driveHighEn = CyTrue;      gpio_config.inputEn = CyFalse;      gpio_config.intrMode = CY_U3P_GPIO_NO_INTR; -     +      CyU3PGpioSetSimpleConfig(GPIO_FPGA_RESET, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_SHDN_SW, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_FX3_SCLK, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_FX3_CE, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_FX3_MOSI, &gpio_config); -     +      /* Reconfigure the GPIO configure struct for inputs that do NOT require       * interrupts attached to them. */      gpio_config.outValue = CyFalse; @@ -1045,23 +1070,23 @@ void b200_slfifo_mode_gpio_config(void) {      gpio_config.driveLowEn = CyFalse;      gpio_config.driveHighEn = CyFalse;      gpio_config.intrMode = CY_U3P_GPIO_NO_INTR; -     +      CyU3PGpioSetSimpleConfig(GPIO_FX3_MISO, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_AUX_PWR_ON, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_PROGRAM_B, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_INIT_B, &gpio_config);      CyU3PGpioSetSimpleConfig(GPIO_DONE, &gpio_config); -     +      /* Initialize GPIO output values. */      CyU3PGpioSetValue(GPIO_FPGA_RESET, 0);      CyU3PGpioSetValue(GPIO_SHDN_SW, 1);      CyU3PGpioSetValue(GPIO_FX3_SCLK, 0);      CyU3PGpioSetValue(GPIO_FX3_CE, 1);      CyU3PGpioSetValue(GPIO_FX3_MOSI, 0); -     +      // Disabled here as only useful once FPGA has been programmed      //b200_enable_fpga_sb_gpio(CyTrue); -    //b200_start_fpga_sb_gpio();  // Set set up SB USART +    //b200_start_fpga_sb_gpio();  // Set up SB USART  } @@ -1072,7 +1097,7 @@ void b200_slfifo_mode_gpio_config(void) {   * ready to receive data from the host. */  void b200_fw_start(void) {      msg("b200_fw_start"); -     +      CyU3PDmaChannelConfig_t dma_channel_config;      CyU3PEpConfig_t usb_endpoint_config;      CyU3PUSBSpeed_t usb_speed; @@ -1095,9 +1120,9 @@ void b200_fw_start(void) {              data_buffer_size = 512;              g_vendor_req_buff_size = USB2_VREQ_BUF_SIZE;    // Max 64              num_packets_per_burst = USB2_PACKETS_PER_BURST; // 1 -             +              data_buffer_size_to_host = data_buffer_size_from_host = data_buffer_size; -             +              break;          case CY_U3P_SUPER_SPEED: @@ -1110,41 +1135,49 @@ void b200_fw_start(void) {                  msg("LPMDisable OK");  //#endif // PREVENT_LOW_POWER_MODE              max_packet_size = 1024; // Per USB3 spec -             +              // SDK ver: total available buffer memory              // 1.2.3: 204KB              // 1.3.1: 188KB -             +              // These options should be ignored - data_buffer_count *MUST* be 1              // They follow is kept for future testing -             +              // 1K              //data_buffer_count = 64;              //data_buffer_size = 1024; -             +              // 4K              //data_buffer_count = 8;              //data_buffer_size = 4096; -             + +            // 8K +            //data_buffer_count = 4; +            //data_buffer_size = 4096*2; +              // 16K              //data_buffer_count = 2*2;              //data_buffer_size = 16384;    // Default 16K -             +              // 32K              //data_buffer_count = 2;              //data_buffer_size = 16384*2; -             -            data_buffer_count = 1; -            data_buffer_size = ((1 << 16) - 1); -            data_buffer_size -= (data_buffer_size % 1024);  // Align to 1K boundary -             + +            //data_buffer_count = 1; +            //data_buffer_size = ((1 << 16) - 1); +            //data_buffer_size = 16384; +            //data_buffer_size -= (data_buffer_size % 1024);  // Align to 1K boundary + +            data_buffer_count = g_config.dma_buffer_count; +            data_buffer_size = g_config.dma_buffer_size; +              data_buffer_size_to_host = data_buffer_size;              data_buffer_size_from_host = data_buffer_size; -             +              g_vendor_req_buff_size = USB3_VREQ_BUF_SIZE;    // Max 512 -            num_packets_per_burst = USB3_PACKETS_PER_BURST; // 16 +            num_packets_per_burst = USB3_PACKETS_PER_BURST*1+4*0; // 16              break; -             +          case CY_U3P_NOT_CONNECTED:              msg("! CY_U3P_NOT_CONNECTED");              return; @@ -1152,9 +1185,31 @@ void b200_fw_start(void) {          default:              return;      } -     +      msg("[DMA] to host: %d, from host: %d, depth: %d, burst size: %d", data_buffer_size_to_host, data_buffer_size_from_host, data_buffer_count, num_packets_per_burst); +#ifdef ENABLE_MANUAL_DMA_XFER +    msg("[DMA] Callback enabled"); + +#ifdef ENABLE_P2U_SUSP_EOP +    msg("[DMA] P2U_SUSP_EOP enabled"); +#endif // ENABLE_P2U_SUSP_EOP +#ifdef ENABLE_MANUAL_DMA_XFER_FROM_HOST +    msg("[DMA] Manual transfers from host"); +#endif // ENABLE_MANUAL_DMA_XFER_FROM_HOST +#ifdef ENABLE_MANUAL_DMA_XFER_TO_HOST +    msg("[DMA] Manual transfers to host"); +#endif // ENABLE_MANUAL_DMA_XFER_TO_HOST +#ifdef ENABLE_DMA_BUFFER_PACKET_DEBUG +    msg("[DMA] Packet debugging enabled"); +#endif // ENABLE_DMA_BUFFER_PACKET_DEBUG + +#else +    msg("[DMA] AUTO transfer mode"); +#endif // ENABLE_MANUAL_DMA_XFER + +    msg("[DMA] Transfer override: %s", (g_config.manual_dma ? "manual" : "auto")); +      /*************************************************************************       * Slave FIFO Data DMA Channel Configuration       *************************************************************************/ @@ -1205,6 +1260,8 @@ CY_U3P_DMA_CB_PROD_SUSP |  CY_U3P_DMA_CB_CONS_SUSP |  #endif // ENABLE_MANUAL_DMA_XFER      0; +    //if (g_config.manual_dma == 0) +    //    dma_channel_config.notification = 0;    // Force all off is manual is disabled      dma_channel_config.cb =  #if defined(ENABLE_MANUAL_DMA_XFER) && defined(ENABLE_MANUAL_DMA_XFER_FROM_HOST)      from_host_dma_callback; @@ -1218,16 +1275,16 @@ CY_U3P_DMA_CB_CONS_SUSP |      CyU3PDmaChannelCreate (&data_cons_to_prod_chan_handle,  #if defined(ENABLE_MANUAL_DMA_XFER) && defined(ENABLE_MANUAL_DMA_XFER_FROM_HOST) -            /*CY_U3P_DMA_TYPE_AUTO_SIGNAL*/CY_U3P_DMA_TYPE_MANUAL, +            (g_config.manual_dma ? /*CY_U3P_DMA_TYPE_AUTO_SIGNAL*/CY_U3P_DMA_TYPE_MANUAL : CY_U3P_DMA_TYPE_AUTO),  #else              CY_U3P_DMA_TYPE_AUTO,  #endif // ENABLE_MANUAL_DMA_XFER              &dma_channel_config); -     +      // By default these will adopt 'usb_endpoint_config.pcktSize'      //CyU3PSetEpPacketSize(DATA_ENDPOINT_PRODUCER, 16384);      //CyU3PSetEpPacketSize(DATA_ENDPOINT_CONSUMER, 16384); -     +      /* Create a DMA AUTO channel for P2U transfer. */      dma_channel_config.size = data_buffer_size_to_host;      dma_channel_config.prodSckId = DATA_RX_PPORT_SOCKET; @@ -1244,21 +1301,28 @@ CY_U3P_DMA_CB_ERROR |  CY_U3P_DMA_CB_PROD_SUSP |  CY_U3P_DMA_CB_CONS_SUSP |  #endif // ENABLE_MANUAL_DMA_XFER +#if defined(ENABLE_MANUAL_DMA_XFER) && defined(ENABLE_P2U_SUSP_EOP) +CY_U3P_DMA_CB_CONS_SUSP |   // For 'CyU3PDmaChannelSetSuspend' below +#endif // ENABLE_P2U_SUSP_EOP      0; +    //if (g_config.manual_dma == 0) +    //    dma_channel_config.notification = 0;    // Force all off is manual is disabled      dma_channel_config.cb = -#if defined(ENABLE_MANUAL_DMA_XFER) && defined(ENABLE_MANUAL_DMA_XFER_TO_HOST) +#if defined(ENABLE_MANUAL_DMA_XFER) && (defined(ENABLE_MANUAL_DMA_XFER_TO_HOST) || defined(ENABLE_P2U_SUSP_EOP))      to_host_dma_callback;  #else      NULL;  #endif // ENABLE_MANUAL_DMA_XFER      CyU3PDmaChannelCreate (&data_prod_to_cons_chan_handle,  #if defined(ENABLE_MANUAL_DMA_XFER) && defined(ENABLE_MANUAL_DMA_XFER_TO_HOST) -            /*CY_U3P_DMA_TYPE_AUTO_SIGNAL*/CY_U3P_DMA_TYPE_MANUAL, +            (g_config.manual_dma ? /*CY_U3P_DMA_TYPE_AUTO_SIGNAL*/CY_U3P_DMA_TYPE_MANUAL : CY_U3P_DMA_TYPE_AUTO),  #else              CY_U3P_DMA_TYPE_AUTO,  #endif // ENABLE_MANUAL_DMA_XFER              &dma_channel_config); - +#ifdef ENABLE_P2U_SUSP_EOP +    CyU3PDmaChannelSetSuspend(&data_prod_to_cons_chan_handle, CY_U3P_DMA_SCK_SUSP_NONE, CY_U3P_DMA_SCK_SUSP_EOP); +#endif // ENABLE_P2U_SUSP_EOP      /* Flush the Endpoint memory */      CyU3PUsbFlushEp(DATA_ENDPOINT_PRODUCER);      CyU3PUsbFlushEp(DATA_ENDPOINT_CONSUMER); @@ -1328,7 +1392,7 @@ CY_U3P_DMA_CB_CONS_SUSP |      /* Set DMA channel transfer size. */      CyU3PDmaChannelSetXfer(&ctrl_cons_to_prod_chan_handle, DMA_SIZE_INFINITE);      CyU3PDmaChannelSetXfer(&ctrl_prod_to_cons_chan_handle, DMA_SIZE_INFINITE); -     +      //CyU3PUsbEnableEPPrefetch();	// To address USB_EVENT_EP_UNDERRUN on EP 0x86 (didn't fix it though)      /* Update the application status flag. */ @@ -1364,76 +1428,76 @@ void event_usb_callback (CyU3PUsbEventType_t event_type, uint16_t event_data) {                  b200_fw_stop();              }              break; -         +          case CY_U3P_USB_EVENT_CONNECT:              msg("USB_EVENT_CONNECT");              break; -         +          case CY_U3P_USB_EVENT_SUSPEND:              msg("USB_EVENT_SUSPEND");              break; -         +          case CY_U3P_USB_EVENT_RESUME:   // Known issue: this is called repeatedly after a resume              //msg("USB_EVENT_RESUME");              g_counters.resume_count++;  // Not locked              break; -         +          case CY_U3P_USB_EVENT_SPEED:              msg("USB_EVENT_SPEED");              break; -         +          case CY_U3P_USB_EVENT_SETINTF:              msg("USB_EVENT_SETINTF");              break; -         +          case CY_U3P_USB_EVENT_SET_SEL:              msg("USB_EVENT_SET_SEL");              break; -         +          case CY_U3P_USB_EVENT_SOF_ITP:  // CyU3PUsbEnableITPEvent              //msg("USB_EVENT_SOF_ITP");              break; -         +          case CY_U3P_USB_EVENT_EP0_STAT_CPLT:              //msg("USB_EVENT_EP0_STAT_CPLT");   // Occurs each time there's a control transfer              break; -         +          case CY_U3P_USB_EVENT_VBUS_VALID:              msg("USB_EVENT_VBUS_VALID");              break; -         +          case CY_U3P_USB_EVENT_VBUS_REMOVED:              msg("USB_EVENT_VBUS_REMOVED");              break; -             +          case CY_U3P_USB_EVENT_HOST_CONNECT:              msg("USB_EVENT_HOST_CONNECT");              break; -         +          case CY_U3P_USB_EVENT_HOST_DISCONNECT:              msg("USB_EVENT_HOST_DISCONNECT");              break; -         +          case CY_U3P_USB_EVENT_OTG_CHANGE:              msg("USB_EVENT_OTG_CHANGE");              break; -         +          case CY_U3P_USB_EVENT_OTG_VBUS_CHG:              msg("USB_EVENT_OTG_VBUS_CHG");              break; -         +          case CY_U3P_USB_EVENT_OTG_SRP:              msg("USB_EVENT_OTG_SRP");              break; -         +          case CY_U3P_USB_EVENT_EP_UNDERRUN:  // See SDK 1.3 known issues 17 if this happens (can probably ignore first logged occurence)              LOCK(g_counters_lock);              ++g_counters.usb_ep_underrun_count;              UNLOCK(g_counters_lock); -             +              msg("! USB_EVENT_EP_UNDERRUN on EP 0x%02x", event_data);              break; -         +          case CY_U3P_USB_EVENT_LNK_RECOVERY:              msg("USB_EVENT_LNK_RECOVERY");              break; @@ -1441,16 +1505,16 @@ void event_usb_callback (CyU3PUsbEventType_t event_type, uint16_t event_data) {          case CY_U3P_USB_EVENT_USB3_LNKFAIL:              msg("USB_EVENT_USB3_LNKFAIL");              break; -         +          case CY_U3P_USB_EVENT_SS_COMP_ENTRY:              msg("USB_EVENT_SS_COMP_ENTRY");              break; -         +          case CY_U3P_USB_EVENT_SS_COMP_EXIT:              msg("USB_EVENT_SS_COMP_EXIT");              break;  #endif // (CYFX_VERSION_MAJOR >= 1) && (CYFX_VERSION_MINOR >= 3) -         +          default:              msg("! Unhandled USB event");              break; @@ -1510,7 +1574,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {              if(wLength > b200_usb_product_desc[0]) {                  wLength = b200_usb_product_desc[0];              } -             +              //msg("MS string desc");              CyU3PUsbSendEP0Data(wLength, ((uint8_t *) b200_usb_product_desc)); @@ -1540,7 +1604,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                      CyU3PUsbStall(wIndex, CyFalse, CyTrue);                      handled = CyTrue;                      CyU3PUsbAckSetup(); -                     +                      msg("Clear DATA_ENDPOINT_PRODUCER");                  } @@ -1553,7 +1617,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                      CyU3PUsbStall(wIndex, CyFalse, CyTrue);                      handled = CyTrue;                      CyU3PUsbAckSetup(); -                     +                      msg("Clear DATA_ENDPOINT_CONSUMER");                  } @@ -1566,7 +1630,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                      CyU3PUsbStall(wIndex, CyFalse, CyTrue);                      handled = CyTrue;                      CyU3PUsbAckSetup(); -                     +                      msg("Clear CTRL_ENDPOINT_PRODUCER");                  } @@ -1579,7 +1643,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                      CyU3PUsbStall(wIndex, CyFalse, CyTrue);                      handled = CyTrue;                      CyU3PUsbAckSetup(); -                     +                      msg("Clear CTRL_ENDPOINT_CONSUMER");                  }              } @@ -1595,7 +1659,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {          switch(bRequest) {              case B200_VREQ_BITSTREAM_START: {                  CyU3PUsbGetEP0Data(1, g_vendor_req_buffer, &read_count); -                 +                  g_fpga_programming_write_count = 0;                  CyU3PEventSet(&g_event_usb_config, EVENT_BITSTREAM_START, \ @@ -1614,12 +1678,12 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                  }                  break;              } -             +              case B200_VREQ_BITSTREAM_DATA_FILL: {                  CyU3PUsbGetEP0Data(g_vendor_req_buff_size, g_vendor_req_buffer, &g_vendor_req_read_count);                  break;              } -             +              case B200_VREQ_BITSTREAM_DATA_COMMIT: {                  /*CyU3PReturnStatus_t*/int spi_result = -1;                  if (g_fx3_state == STATE_CONFIGURING_FPGA) { @@ -1670,8 +1734,14 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {              case B200_VREQ_GET_LOG: {                  LOCK(g_log_lock); -                 -                if (log_buffer_idx == 0) + +                if (log_buffer_len == 0) { +                    log_buffer[0] = '\0'; +                    CyU3PUsbSendEP0Data(1, (uint8_t*)log_buffer); +                    //CyU3PUsbSendEP0Data(0, NULL); +                    //CyU3PUsbAckSetup(); +                } +                else if (log_buffer_idx == 0)                      CyU3PUsbSendEP0Data(log_buffer_len, (uint8_t*)log_buffer);                  else {                      int len1 = min(LOG_BUFFER_SIZE - log_buffer_idx, log_buffer_len); @@ -1681,39 +1751,39 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                          memcpy(log_contiguous_buffer + len1, log_buffer, log_buffer_len - len1);                      CyU3PUsbSendEP0Data(log_buffer_len, (uint8_t*)log_contiguous_buffer);                  } -                 +                  // FIXME: Necessary? Not used in the other ones                  //CyU3PUsbSendEP0Data(0, NULL);   // Send ZLP since previous send has resulted in an integral # of packets -                 +                  log_reset(); -                 +                  UNLOCK(g_log_lock); -                 +                  //log_reset(); -                 +                  break;              }              case B200_VREQ_GET_COUNTERS: {                  LOCK(g_counters_lock); -                 +                  CyU3PUsbSendEP0Data(sizeof(COUNTERS), (uint8_t*)&g_counters); -                 +                  counters_auto_reset(); -                 +                  UNLOCK(g_counters_lock); -                 +                  //counters_auto_reset(); -                 +                  break;              } -             +              case B200_VREQ_CLEAR_COUNTERS: {                  CyU3PUsbAckSetup();                  //CyU3PUsbGetEP0Data(g_vendor_req_buff_size, g_vendor_req_buffer, &read_count);   // Dummy -                 +                  counters_dma_reset(); -                 +                  break;              } @@ -1750,14 +1820,14 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                          //msg("USB event log [1] %i", (int)len);                      }                  } -                 +                  //if (len > 0)  // Send a ZLP, otherwise it'll timeout                      CyU3PUsbSendEP0Data(len, g_usb_event_log_contiguous_buf); -                 +                  g_last_usb_event_log_index = idx;                  break;              } -             +              case B200_VREQ_SET_CONFIG: {                  CyU3PUsbGetEP0Data(sizeof(CONFIG_MOD), (uint8_t*)g_vendor_req_buffer, &read_count);                  if (read_count == sizeof(CONFIG_MOD)) { @@ -1766,7 +1836,7 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                  }                  break;              } -             +              case B200_VREQ_GET_CONFIG: {                  CyU3PUsbSendEP0Data(sizeof(g_config), (uint8_t*)&g_config);                  break; @@ -1780,64 +1850,77 @@ CyBool_t usb_setup_callback(uint32_t data0, uint32_t data1) {                  for (i = 0; i < read_count; ++i)                      sb_write(SUART_TXCHAR, g_vendor_req_buffer[i]);                  UNLOCK(g_suart_lock); -                 +                  msg("Wrote %d SB chars", read_count);  #else                  msg("SB is disabled");  #endif // ENABLE_FPGA_SB                  break;              } -             +              case B200_VREQ_SET_SB_BAUD_DIV: {                  uint16_t div;                  CyU3PUsbGetEP0Data(sizeof(div), (uint8_t*)&div, &read_count); -                 +                  if (read_count == sizeof(div)) {  #ifdef ENABLE_FPGA_SB                      LOCK(g_suart_lock);                      sb_write(SUART_CLKDIV, div);                      UNLOCK(g_suart_lock);                      msg("SUART_CLKDIV = %d", div); -                    g_fpga_sb_uart_div = div;   // Store for GPIF (FPGA) reset +                    /*g_fpga_sb_uart_div*/g_config.sb_baud_div = div;   // Store for GPIF (FPGA) reset  #else                      msg("SB is disabled");  #endif // ENABLE_FPGA_SB                  }                  else                      msg("! SUART_CLKDIV received %d bytes", read_count); -                 +                  break;              } -             +              case B200_VREQ_FLUSH_DATA_EPS: {                  //msg("Flushing data EPs..."); -                 -                CyU3PUsbAckSetup(); -                 + +                //CyU3PUsbAckSetup(); + +                //CyU3PUsbResetEndpointMemories(); +                  // From host                  //CyU3PDmaChannelReset(&data_cons_to_prod_chan_handle);                  //CyU3PUsbFlushEp(DATA_ENDPOINT_PRODUCER);                  //CyU3PUsbResetEp(DATA_ENDPOINT_PRODUCER);                  //CyU3PDmaChannelSetXfer(&data_cons_to_prod_chan_handle, DMA_SIZE_INFINITE); -                 + +                //CyU3PDmaSocketDisable(DATA_RX_PPORT_SOCKET); +                  //CyU3PDmaChannelReset(&data_cons_to_prod_chan_handle); -                CyU3PDmaChannelReset(&data_prod_to_cons_chan_handle); +                if (CyU3PDmaChannelReset(&data_prod_to_cons_chan_handle) != CY_U3P_SUCCESS) +                { +                    msg("! CyU3PDmaChannelReset"); +                }                  //CyU3PUsbFlushEp(DATA_ENDPOINT_PRODUCER);                  CyU3PUsbFlushEp(DATA_ENDPOINT_CONSUMER);                  //CyU3PUsbResetEp(DATA_ENDPOINT_PRODUCER); -                CyU3PUsbResetEp(DATA_ENDPOINT_CONSUMER); +//                CyU3PUsbResetEp(DATA_ENDPOINT_CONSUMER); +                //CyU3PUsbStall(DATA_ENDPOINT_CONSUMER, CyFalse, CyTrue);                  //CyU3PDmaChannelSetXfer(&data_cons_to_prod_chan_handle, DMA_SIZE_INFINITE); +                //CyU3PDmaSocketEnable(DATA_RX_PPORT_SOCKET);                  CyU3PDmaChannelSetXfer(&data_prod_to_cons_chan_handle, DMA_SIZE_INFINITE); -                 + +                //CyU3PUsbResetEndpointMemories(); +                  // To host                  //CyU3PDmaChannelReset(&data_prod_to_cons_chan_handle);                  //CyU3PUsbFlushEp(DATA_ENDPOINT_CONSUMER);                  //CyU3PUsbResetEp(DATA_ENDPOINT_CONSUMER);                  //CyU3PDmaChannelSetXfer(&data_prod_to_cons_chan_handle, DMA_SIZE_INFINITE); -                 + +                CyU3PUsbAckSetup(); +                  break;              } -             +              case B200_VREQ_EEPROM_WRITE: {                  i2cAddr = 0xA0 | ((wValue & 0x0007) << 1);                  CyU3PUsbGetEP0Data(((wLength + 15) & 0xFFF0), g_vendor_req_buffer, NULL); @@ -1941,6 +2024,97 @@ CyBool_t lpm_request_callback(CyU3PUsbLinkPowerMode link_mode) {  } +/* Callback function to check for PIB ERROR*/ +void gpif_error_cb(CyU3PPibIntrType cbType, uint16_t cbArg) +{ +    if (cbType==CYU3P_PIB_INTR_ERROR) +    { +        switch (CYU3P_GET_PIB_ERROR_TYPE(cbArg)) +        { +            case CYU3P_PIB_ERR_NONE: +                break; +            case CYU3P_PIB_ERR_THR0_WR_OVERRUN: +                msg("CYU3P_PIB_ERR_THR0_WR_OVERRUN"); +                break; +            case CYU3P_PIB_ERR_THR1_WR_OVERRUN: +                msg("CYU3P_PIB_ERR_THR1_WR_OVERRUN"); +                break; +            case CYU3P_PIB_ERR_THR2_WR_OVERRUN: +                msg("CYU3P_PIB_ERR_THR2_WR_OVERRUN"); +                break; +            case CYU3P_PIB_ERR_THR3_WR_OVERRUN: +                msg("CYU3P_PIB_ERR_THR3_WR_OVERRUN"); +                break; +            case CYU3P_PIB_ERR_THR0_RD_UNDERRUN: +                msg("CYU3P_PIB_ERR_THR0_RD_UNDERRUN"); +                break; +            case CYU3P_PIB_ERR_THR1_RD_UNDERRUN: +                msg("CYU3P_PIB_ERR_THR1_RD_UNDERRUN"); +                break; +            case CYU3P_PIB_ERR_THR2_RD_UNDERRUN: +                msg("CYU3P_PIB_ERR_THR2_RD_UNDERRUN"); +                break; +            case CYU3P_PIB_ERR_THR3_RD_UNDERRUN: +                msg("CYU3P_PIB_ERR_THR3_RD_UNDERRUN"); +                break; +            case CYU3P_PIB_ERR_THR0_ADAP_UNDERRUN: +                msg("CYU3P_PIB_ERR_THR0_ADAP_UNDERRUN"); +                break; +            case CYU3P_PIB_ERR_THR1_ADAP_OVERRUN: +                msg("CYU3P_PIB_ERR_THR1_ADAP_OVERRUN"); +                break; +            // FIXME: Other threads +            case CYU3P_PIB_ERR_THR1_SCK_INACTIVE: +                //msg("CYU3P_PIB_ERR_THR1_SCK_INACTIVE"); +                ++g_counters.pib_counters[1].socket_inactive;   // UNSYNC'd +                break; +            default: +                msg("Unknown CYU3P_PIB_ERR %i", CYU3P_GET_PIB_ERROR_TYPE(cbArg)); +                break; +        } + +        switch (CYU3P_GET_GPIF_ERROR_TYPE(cbArg)) +        { +            case CYU3P_GPIF_ERR_NONE:             /**< No GPIF state machine errors. */ +                //msg("CYU3P_GPIF_ERR_NONE"); +                break; +            case CYU3P_GPIF_ERR_INADDR_OVERWRITE: /**< Content of INGRESS_ADDR register is overwritten before read. */ +                msg("CYU3P_GPIF_ERR_INADDR_OVERWRITE"); +                break; +            case CYU3P_GPIF_ERR_EGADDR_INVALID:   /**< Attempt to read EGRESS_ADDR register before it is written to. */ +                msg("CYU3P_GPIF_ERR_EGADDR_INVALID"); +                break; +            case CYU3P_GPIF_ERR_DATA_READ_ERR:    /**< Read from DMA data thread which is not ready. */ +                msg("CYU3P_GPIF_ERR_DATA_READ_ERR"); +                break; +            case CYU3P_GPIF_ERR_DATA_WRITE_ERR:   /**< Write to DMA data thread which is not ready. */ +                msg("CYU3P_GPIF_ERR_DATA_WRITE_ERR"); +                break; +            case CYU3P_GPIF_ERR_ADDR_READ_ERR:    /**< Read from DMA address thread which is not ready. */ +                msg("CYU3P_GPIF_ERR_ADDR_READ_ERR"); +                break; +            case CYU3P_GPIF_ERR_ADDR_WRITE_ERR:   /**< Write to DMA address thread which is not ready. */ +                msg("CYU3P_GPIF_ERR_ADDR_WRITE_ERR"); +                break; +            case CYU3P_GPIF_ERR_INVALID_STATE:    /**< GPIF state machine has reached an invalid state. */ +                //msg("CYU3P_GPIF_ERR_INVALID_STATE"); +                ++g_counters.invalid_gpif_state;    // UNSYNC'd +                break; +            default: +                msg("Unknown CYU3P_GPIF_ERR %i", CYU3P_GET_GPIF_ERROR_TYPE(cbArg)); +                break; +        } +    } +} + + +void GpifStateChangeCb(uint8_t stateId) +{ +    //msg("%d", stateId); +    ++g_counters.state_transition_count; +} + +  /*! Initialize and start the GPIF state machine.   *   * This function starts the GPIF Slave FIFO state machine on the FX3. Because on @@ -1948,7 +2122,7 @@ CyBool_t lpm_request_callback(CyU3PUsbLinkPowerMode link_mode) {   * after FPGA configuration is complete. */  void b200_gpif_init(void) {      msg("b200_gpif_init"); -     +      CyU3PPibClock_t pib_clock_config;      /* Initialize the p-port block; disable DLL for sync GPIF. */ @@ -1956,19 +2130,34 @@ void b200_gpif_init(void) {      pib_clock_config.clkSrc = CY_U3P_SYS_CLK;      pib_clock_config.isHalfDiv = CyFalse;      pib_clock_config.isDllEnable = CyFalse; -    CyU3PPibInit(CyTrue, &pib_clock_config); +    if (CyU3PPibInit(CyTrue, &pib_clock_config) != CY_U3P_SUCCESS) +        msg("! CyU3PPibInit");      /* Load the GPIF configuration for Slave FIFO sync mode. */ -    CyU3PGpifLoad(&CyFxGpifConfig); +    if (CyU3PGpifLoad(&CyFxGpifConfig) != CY_U3P_SUCCESS) +        msg("! CyU3PGpifLoad"); + +    msg("GPIF loaded"); + +    //CyU3PGpifRegisterSMIntrCallback(GpifStateChangeCb);      /* Start the state machine. */ -    CyU3PGpifSMStart(RESET, ALPHA_RESET); +    //CyU3PGpifSMStart(RESET, ALPHA_RESET);      /* Configure the watermarks for the slfifo-write buffers. */ -    CyU3PGpifSocketConfigure(0, DATA_TX_PPORT_SOCKET, 5, CyFalse, 1); -    CyU3PGpifSocketConfigure(1, DATA_RX_PPORT_SOCKET, 6, CyFalse, 1); -    CyU3PGpifSocketConfigure(2, CTRL_COMM_PPORT_SOCKET, 5, CyFalse, 1); -    CyU3PGpifSocketConfigure(3, CTRL_RESP_PPORT_SOCKET, 6, CyFalse, 1); +    if (CyU3PGpifSocketConfigure(0, DATA_TX_PPORT_SOCKET, 5, CyFalse, 1) != CY_U3P_SUCCESS) +        msg("! CyU3PGpifSocketConfigure 0"); +    if (CyU3PGpifSocketConfigure(1, DATA_RX_PPORT_SOCKET, 6, CyFalse, 1) != CY_U3P_SUCCESS) +        msg("! CyU3PGpifSocketConfigure 1"); +    if (CyU3PGpifSocketConfigure(2, CTRL_COMM_PPORT_SOCKET, 5, CyFalse, 1) != CY_U3P_SUCCESS) +        msg("! CyU3PGpifSocketConfigure 2"); +    if (CyU3PGpifSocketConfigure(3, CTRL_RESP_PPORT_SOCKET, 6, CyFalse, 1) != CY_U3P_SUCCESS) +        msg("! CyU3PGpifSocketConfigure 3"); + +    //CyU3PGpifSMStart(RESET, ALPHA_RESET); + +    /* Register a callback for notification of PIB interrupts*/ +    CyU3PPibRegisterCallback(gpif_error_cb, CYU3P_PIB_INTR_ERROR);  } @@ -1979,7 +2168,7 @@ void b200_gpif_init(void) {   * 32-bit mode. */  CyU3PReturnStatus_t b200_spi_init(void) {      msg("b200_spi_init"); -     +      CyU3PSpiConfig_t spiConfig;      /* Start the SPI module and configure the master. */ @@ -2000,10 +2189,10 @@ CyU3PReturnStatus_t b200_spi_init(void) {      spiConfig.wordLen    = 8;      CyU3PReturnStatus_t res = CyU3PSpiSetConfig(&spiConfig, NULL); -     +      if (res != CY_U3P_SUCCESS)          msg("! CyU3PSpiSetConfig"); -     +      return res;  } @@ -2015,7 +2204,7 @@ CyU3PReturnStatus_t b200_spi_init(void) {   */  void b200_usb_init(void) {      //msg("b200_usb_init"); -     +      /* Initialize the I2C interface for the EEPROM of page size 64 bytes. */      CyFxI2cInit(CY_FX_USBI2C_I2C_PAGE_SIZE); @@ -2137,48 +2326,53 @@ void b200_usb_init(void) {      CyU3PUsbSetDesc(CY_U3P_USB_SET_STRING_DESCR, 3,              (uint8_t *) dev_serial); -     +      ////////////////////////////////////////////////////////      // FIXME: CyU3PUsbSetTxDeemphasis(0x11); <0x1F  // Shouldn't need to change this -    uint32_t tx_swing = /*65*/45;   // 65 & 45 are OK, 120 causes much link recovery. <128. 1.2V is USB3 limit. +    const uint32_t tx_swing = g_config.tx_swing/*65*//*45*/;   // 65 & 45 are OK, 120 causes much link recovery. <128. 1.2V is USB3 limit.      if (CyU3PUsbSetTxSwing(tx_swing) == CY_U3P_SUCCESS) -        msg("CyU3PUsbSetTxSwing %d", tx_swing); +        msg("CyU3PUsbSetTxSwing: %d", tx_swing);      else -        msg("! CyU3PUsbSetTxSwing %d", tx_swing); +        msg("! CyU3PUsbSetTxSwing: %d", tx_swing);      ////////////////////////////////////////////////////////      /* Connect the USB pins, and enable SuperSpeed (USB 3.0). */ -    CyU3PConnectState(CyTrue, CyTrue);  // connect, ssEnable +    if (CyU3PConnectState(CyTrue, (g_config.enable_as_superspeed != 0 ? CyTrue : CyFalse)) == CY_U3P_SUCCESS) {  // connect, ssEnable +        CyU3PUSBSpeed_t usb_speed = CyU3PUsbGetSpeed(); +        msg("Link up (speed: USB %d)", (int)usb_speed); // MAGIC: Values happen to map +    } +    else +        msg("! Failed to establish link");  }  void b200_restore_gpio_for_fpga_config(void) {      CyU3PDeviceGpioRestore(GPIO_FPGA_RESET);      CyU3PDeviceGpioRestore(GPIO_DONE); -     +      CyU3PDeviceGpioRestore(GPIO_FX3_SCLK);      CyU3PDeviceGpioRestore(GPIO_FX3_CE);      CyU3PDeviceGpioRestore(GPIO_FX3_MISO);      CyU3PDeviceGpioRestore(GPIO_FX3_MOSI); -     +      //CyU3PGpioDeInit();    // Moved to just before init  }  void thread_fpga_config_entry(uint32_t input) {      uint32_t event_flag; -     +      //msg("thread_fpga_config_entry"); -     +      for(;;) { -         +          // Event is set through VREQ          if(CyU3PEventGet(&g_event_usb_config, \              (EVENT_FPGA_CONFIG), CYU3P_EVENT_AND_CLEAR, \              &event_flag, CYU3P_WAIT_FOREVER) == CY_U3P_SUCCESS) { -             +              //uint8_t old_state = g_fx3_state;              uint32_t old_fpga_programming_write_count = 0; @@ -2200,7 +2394,7 @@ void thread_fpga_config_entry(uint32_t input) {              /* Configure the device GPIOs for FPGA programming. */              b200_gpios_pre_fpga_config(); -             +              CyU3PSysWatchDogClear();              /* Initialize the SPI module that will be used for FPGA programming. */ @@ -2213,7 +2407,7 @@ void thread_fpga_config_entry(uint32_t input) {              /* We can now begin configuring the FPGA. */              g_fx3_state = STATE_FPGA_READY; -             +              msg("Begin FPGA");              // Event is set through VREQ @@ -2232,7 +2426,7 @@ void thread_fpga_config_entry(uint32_t input) {                  CyU3PThreadSleep(FPGA_PROGRAMMING_POLL_SLEEP);                  CyU3PSysWatchDogClear();              } -             +              if (wait_count >= FPGA_PROGRAMMING_BITSTREAM_START_POLL_COUNT)                  continue; @@ -2243,7 +2437,7 @@ void thread_fpga_config_entry(uint32_t input) {              /* Wait for INIT_B to fall and rise. */              wait_count = 0; -             +              msg("Wait FPGA");              while(CyU3PEventGet(&g_event_usb_config, \ @@ -2282,9 +2476,9 @@ void thread_fpga_config_entry(uint32_t input) {              /* We are ready to accept the FPGA bitstream! */              wait_count = 0;              g_fx3_state = STATE_CONFIGURING_FPGA; -             +              msg("Configuring FPGA"); -             +              // g_fpga_programming_write_count is zero'd by VREQ triggering EVENT_BITSTREAM_START              while(CyU3PEventGet(&g_event_usb_config, \ @@ -2308,7 +2502,7 @@ void thread_fpga_config_entry(uint32_t input) {                      wait_count = 0;                      old_fpga_programming_write_count = g_fpga_programming_write_count;                  } -                 +                  CyU3PThreadSleep(FPGA_PROGRAMMING_POLL_SLEEP);                  CyU3PSysWatchDogClear();              } @@ -2329,42 +2523,42 @@ void thread_fpga_config_entry(uint32_t input) {  #endif // ENABLE_DONE_WORKAROUND              if (wait_count >= FPGA_PROGRAMMING_DONE_POLL_COUNT)                  continue; -             +              msg("FPGA done"); -             +              /* Tell the host that we are ignoring it for a while. */              g_fx3_state = STATE_BUSY; -             +              CyU3PSysWatchDogClear(); -             +              /* Now that the FPGA is configured, we need to tear down the current SPI and              * GPIO configs, and re-config for GPIF & bit-banged SPI operation. */              CyU3PSpiDeInit();              b200_restore_gpio_for_fpga_config(); -             +              CyU3PSysWatchDogClear(); -             +              /* Load the GPIO configuration for normal SLFIFO use. */              b200_slfifo_mode_gpio_config(); -             +              /* Tone down the drive strength on the P-port. */              //CyU3PSetPportDriveStrength(CY_U3P_DS_HALF_STRENGTH); -             +              CyU3PSysWatchDogClear(); -             +              /* FPGA configuration is complete! Time to get the GPIF state machine              * running for Slave FIFO. */              b200_gpif_init(); -             +              CyU3PThreadSleep(1);              b200_start_fpga_sb_gpio();  // Moved here to give SB time to init -             +              /* RUN, BABY, RUN! */              g_fx3_state = STATE_RUNNING; -             +              msg("Running");          } -         +          CyU3PThreadRelinquish();      }  } @@ -2403,15 +2597,15 @@ void thread_main_app_entry(uint32_t input) {                  while((current_state >= CyU3PUsbLPM_U1) \                          && (current_state <= CyU3PUsbLPM_U3)) { -                     +                      msg("! LPS = %i", current_state);                      CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);  // This will wake up the host if it's trying to sleep                      CyU3PThreadSleep(1); -                     +                      if (CyU3PUsbGetSpeed () != CY_U3P_SUPER_SPEED)                          break; -                     +                      CyU3PUsbGetLinkPowerState (¤t_state);                  }              } @@ -2426,12 +2620,12 @@ static uint32_t g_poll_last_phy_error_status = 0;  void update_error_counters(void) {      if (CyU3PUsbGetSpeed () != CY_U3P_SUPER_SPEED)          return; -     +      uvint32_t reg = REG_LNK_PHY_ERROR_STATUS;      uint32_t val = 0;      if (CyU3PReadDeviceRegisters((uvint32_t*)reg, 1, &val) == CY_U3P_SUCCESS) {          g_poll_last_phy_error_status |= (val & PHYERR_MASK); -         +          // Reset after read          uint32_t zero = PHYERR_MASK;          if (CyU3PWriteDeviceRegisters((uvint32_t*)reg, 1, &zero) != CY_U3P_SUCCESS) @@ -2441,12 +2635,12 @@ void update_error_counters(void) {          // FIXME: Log once          msg("! Reg read fail");      } -     +      // Equivalent code:      //uint32_t* p = (uint32_t*)REG_LNK_PHY_ERROR_STATUS;      //val = (*p);      //(*p) = PHYERR_MASK; -     +      uint16_t phy_error_count = 0, link_error_count = 0;      if (CyU3PUsbGetErrorCounts(&phy_error_count, &link_error_count) == CY_U3P_SUCCESS) {    // Resets internal counters after call          g_poll_last_phy_error_count += phy_error_count; @@ -2456,7 +2650,7 @@ void update_error_counters(void) {          // FIXME: Log once          msg("! CyU3PUsbGetErrorCounts");      } -     +      LOCK(g_counters_lock);      g_counters.usb_error_update_count++;      g_counters.usb_error_counters.phy_error_count += phy_error_count; @@ -2478,50 +2672,153 @@ void update_error_counters(void) {  void thread_re_enum_entry(uint32_t input) {      uint32_t event_flag; -     +      //msg("thread_re_enum_entry"); -     +      int keep_alive = 0; -     +      while (1) {          if (CyU3PEventGet(&g_event_usb_config, \              (EVENT_RE_ENUM), CYU3P_EVENT_AND_CLEAR, \              &event_flag, RE_ENUM_THREAD_SLEEP_TIME) == CY_U3P_SUCCESS) {                  msg("Re-config"); -                 +                  // FIXME: This section is not finished -                 +                  // Not locking this since we only expect one write in VREQ and read afterward here -                 -                int re_enum = g_config_mod.flags & (CF_RE_ENUM | CF_TX_SWING | CF_TX_DEEMPHASIS); -                 + +                int re_enum = g_config_mod.flags & (CF_RE_ENUM | CF_TX_SWING | CF_TX_DEEMPHASIS | CF_DISABLE_USB2 | CF_ENABLE_AS_SUPERSPEED); +                  CyU3PThreadSleep(100);  // Wait for EP0 xaction to complete -                 +                  //b200_fw_stop(); -                 + +/* +    int tx_swing;               // [90] [65] 45 +    int tx_deemphasis;          // 0x11 +    int disable_usb2;           // 0 +    int enable_as_superspeed;   // 1 +    int pport_drive_strength;   // CY_U3P_DS_THREE_QUARTER_STRENGTH +    int dma_buffer_size;        // [USB3] (max) +    int dma_buffer_count;       // [USB3] 1 +    int manual_dma;             // 0 +    int sb_baud_div;            // 434*2 +*/ +                  if (re_enum) { -                    msg("Link down"); -                    CyU3PConnectState(CyFalse, CyTrue); +                    if (CyU3PConnectState(CyFalse, (g_config.enable_as_superspeed != 0 ? CyTrue : CyFalse)) == CY_U3P_SUCCESS) +                        msg("Link down"); +                    else +                        msg("! Failed to bring link down");                  } -                 +                  if (g_config_mod.flags & CF_TX_DEEMPHASIS) { -                    //g_config_mod.config.tx_deemphasis -                    //CyU3PUsbSetTxDeemphasis(0x11); <0x1F +#if (CYFX_VERSION_MAJOR >= 1) && (CYFX_VERSION_MINOR >= 3) +                    if ((g_config_mod.config.tx_deemphasis < 0x1F) && (CyU3PUsbSetTxDeemphasis(g_config_mod.config.tx_deemphasis) == CY_U3P_SUCCESS)) { +                        msg("TX deemphasis now: %d (was: %d)", g_config_mod.config.tx_deemphasis, g_config.tx_deemphasis); +                        g_config.tx_deemphasis = g_config_mod.config.tx_deemphasis; +                    } +                    else +#endif // #if (CYFX_VERSION_MAJOR >= 1) && (CYFX_VERSION_MINOR >= 3) +                        msg("! Failed to set TX deemphasis: %d (still: %d)", g_config_mod.config.tx_deemphasis, g_config.tx_deemphasis);                  } +                  if (g_config_mod.flags & CF_TX_SWING) { -                    //CyU3PUsbSetTxSwing(90); <128 +                    if ((g_config_mod.config.tx_swing < 128) && (CyU3PUsbSetTxSwing(g_config_mod.config.tx_swing) == CY_U3P_SUCCESS)) { +                        msg("TX swing now: %d (was: %d)", g_config_mod.config.tx_swing, g_config.tx_swing); +                        g_config.tx_swing = g_config_mod.config.tx_swing; +                    } +                    else +                        msg("! Failed to set TX swing: %d (still: %d)", g_config_mod.config.tx_swing, g_config.tx_swing); +                } + +                if (g_config_mod.flags & CF_DISABLE_USB2) { +                    if (CyU3PUsbControlUsb2Support((g_config_mod.config.disable_usb2 != 0 ? CyTrue : CyFalse)) == CY_U3P_SUCCESS) { +                        msg("USB 2 support now: %s (was: %d)", (g_config_mod.config.disable_usb2 ? "disabled" : "enabled"), (g_config.disable_usb2 ? "disabled" : "enabled")); +                        g_config.disable_usb2 = g_config_mod.config.disable_usb2; +                    } +                    else +                        msg("! Failed to change USB 2 support to: %s (still: %s)", (g_config_mod.config.disable_usb2 ? "enabled" : "disabled"), (g_config.disable_usb2 ? "enabled" : "disabled")); +                } + +                if (g_config_mod.flags & CF_PPORT_DRIVE_STRENGTH) { +                    // CY_U3P_DS_QUARTER_STRENGTH,CY_U3P_DS_HALF_STRENGTH,CY_U3P_DS_THREE_QUARTER_STRENGTH,CY_U3P_DS_FULL_STRENGTH +                    if ((g_config_mod.config.pport_drive_strength >= CY_U3P_DS_QUARTER_STRENGTH) && +                        (g_config_mod.config.pport_drive_strength <= CY_U3P_DS_FULL_STRENGTH) && +                        (CyU3PSetPportDriveStrength(g_config_mod.config.pport_drive_strength) == CY_U3P_SUCCESS)) { +                        msg("PPort drive strength now: %d (was: %d)", g_config_mod.config.pport_drive_strength, g_config.pport_drive_strength); +                        g_config.pport_drive_strength = g_config_mod.config.pport_drive_strength; +                    } +                    else +                        msg("! Failed to set PPort drive strength: %d (still: %d)", g_config_mod.config.pport_drive_strength, g_config.pport_drive_strength); +                } + +                int reinit_dma = g_config_mod.flags & (CF_MANUAL_DMA | CF_DMA_BUFFER_COUNT | CF_DMA_BUFFER_SIZE); +                if (re_enum) +                    reinit_dma = 0; // Don't need to if re-enumerating + +                if (g_config_mod.flags & CF_MANUAL_DMA) { +#ifdef ENABLE_MANUAL_DMA_XFER +                    msg("DMA transfers will be: %s (was: %s)", (g_config_mod.config.manual_dma ? "manual" : "auto"), (g_config.manual_dma ? "manual" : "auto")); +                    g_config.manual_dma = g_config_mod.config.manual_dma; +#else +                    msg("! Manual DMA transfers not compiled into FW"); +#endif // ENABLE_MANUAL_DMA_XFER +                } + +                if (g_config_mod.flags & CF_DMA_BUFFER_COUNT) { +                    msg("DMA buffer count will be: %d (was: %d)", g_config_mod.config.dma_buffer_count, g_config.dma_buffer_count); +                    g_config.dma_buffer_count = g_config_mod.config.dma_buffer_count; +                } + +                if (g_config_mod.flags & CF_DMA_BUFFER_SIZE) { +                    msg("DMA buffer size will be: %d (was: %d)", g_config_mod.config.dma_buffer_size, g_config.dma_buffer_size); +                    g_config.dma_buffer_size = g_config_mod.config.dma_buffer_size; +                } + +                if (g_config_mod.flags & CF_SB_BAUD_DIV) { +#ifdef ENABLE_FPGA_SB +                    LOCK(g_suart_lock); +                    sb_write(SUART_CLKDIV, g_config_mod.config.sb_baud_div); +                    UNLOCK(g_suart_lock); +                    msg("SUART_CLKDIV now: %d (was: %d)", g_config_mod.config.sb_baud_div, g_config.sb_baud_div); +                    g_config.sb_baud_div = g_config_mod.config.sb_baud_div; +#else +                    msg("! Failed to set SUART_CLKDIV: SB is disabled (still: %d)", g_config.sb_baud_div); +#endif // ENABLE_FPGA_SB                  } -                //CyU3PUsbControlUsb2Support(); -                                  //b200_fw_start() +                if (g_config_mod.flags & CF_ENABLE_AS_SUPERSPEED) { +                    msg("Enable SuperSpeed: %s (was: %s)", (g_config_mod.config.enable_as_superspeed ? "yes" : "no"), (g_config.enable_as_superspeed ? "yes" : "no")); +                    g_config.enable_as_superspeed = g_config_mod.config.enable_as_superspeed; +                } + +                if (reinit_dma) { +                    if (g_app_running) { +                        msg("Stopping FW..."); + +                        b200_fw_stop(); +                    } + +                    msg("Starting FW..."); + +                    b200_fw_start(); +                } +                else // Shouldn't be re-init'ing AND re-enum'ing                  /* Connect the USB pins, and enable SuperSpeed (USB 3.0). */                  if (re_enum) { -                    msg("Link up"); -                    CyU3PConnectState(CyTrue, CyTrue);  // CHECK: Assuming all other important state will persist +                    msg("Connecting... (as SuperSpeed: %d)", g_config.enable_as_superspeed); + +                    if (CyU3PConnectState(CyTrue, (g_config.enable_as_superspeed != 0 ? CyTrue : CyFalse)) == CY_U3P_SUCCESS) {  // CHECK: Assuming all other important state will persist +                        CyU3PUSBSpeed_t usb_speed = CyU3PUsbGetSpeed(); +                        msg("Link up (speed: USB %d)", (int)usb_speed); // MAGIC: Values happen to map +                    } +                    else +                        msg("! Failed to bring link up");                  } -                 +                  counters_reset_usb_errors();          }          else { @@ -2533,7 +2830,7 @@ void thread_re_enum_entry(uint32_t input) {              update_error_counters();  #endif // !ENABLE_FPGA_SB          } -         +          CyU3PThreadRelinquish();      }  } @@ -2548,26 +2845,26 @@ void base16_encode(uint8_t v, char out[2], char first) {  #ifdef ENABLE_FPGA_SB  void thread_fpga_sb_poll_entry(uint32_t input) {      //msg("thread_fpga_sb_poll_entry"); -     +      while (1) {          uint16_t i;          uint8_t has_change = 0; -         +          update_error_counters(); -         +          /*if (g_poll_last_phy_error_count > 0)              has_change = 1;          if (g_poll_last_link_error_count > 0)              has_change = 1;*/          if (g_poll_last_phy_error_status != 0)              has_change = 1; -         +          uint16_t idx = CyU3PUsbGetEventLogIndex();  // Current *write* pointer          if (idx > (USB_EVENT_LOG_SIZE-1)) {              msg("! USB event log idx = %i", (int)idx);              break;          } -         +          uint8_t has_usb_events = 0;          // Assuming logging won't wrap around between get calls (i.e. buffer should be long enough)          if (g_fpga_sb_last_usb_event_log_index != idx) { @@ -2578,7 +2875,7 @@ void thread_fpga_sb_poll_entry(uint32_t input) {                          break;                      }                  } -                 +                  if (has_usb_events == 0) {                      for (i = 0; i < idx; i++) {                          if (g_usb_event_log[i] != 0x14 && g_usb_event_log[i] != 0x15 && g_usb_event_log[i] != 0x16) { // CTRL, STATUS, ACKSETUP @@ -2597,15 +2894,15 @@ void thread_fpga_sb_poll_entry(uint32_t input) {                  }              }          } -             +          if (has_change || has_usb_events) {              LOCK(g_suart_lock); -             +              sb_write(SUART_TXCHAR, UPT_USB_EVENTS); -             +              char out[3];              out[2] = '\0'; -             +              if (has_usb_events) {                  if (idx < g_fpga_sb_last_usb_event_log_index) {                      for (i = g_fpga_sb_last_usb_event_log_index; i < USB_EVENT_LOG_SIZE; i++) { @@ -2614,7 +2911,7 @@ void thread_fpga_sb_poll_entry(uint32_t input) {                          base16_encode(g_usb_event_log[i], out, 'A');                          _sb_write_string(out);                      } -                 +                      for (i = 0; i < idx; i++) {                          if (g_usb_event_log[i] == 0x14 || g_usb_event_log[i] == 0x15 || g_usb_event_log[i] == 0x16) // CTRL, STATUS, ACKSETUP                              continue; @@ -2631,10 +2928,10 @@ void thread_fpga_sb_poll_entry(uint32_t input) {                      }                  }              } -             +              // USB events: A-P,A-P              // PHY error status: a,a-i -             +              if (g_poll_last_phy_error_status != 0) {                  uint32_t mask;                  size_t offset; @@ -2645,32 +2942,32 @@ void thread_fpga_sb_poll_entry(uint32_t input) {                      }                  }              } -             +              /*char buf[6]; -             +              if (g_poll_last_phy_error_count > 0) {                  sb_write(SUART_TXCHAR, 'b');                  snprintf(buf, sizeof(buf)-1, "%d", g_poll_last_phy_error_count);                  _sb_write_string(buf);              } -             +              if (g_poll_last_link_error_count > 0) {                  sb_write(SUART_TXCHAR, 'c');                  snprintf(buf, sizeof(buf)-1, "%d", g_poll_last_link_error_count);                  _sb_write_string(buf);              }*/ -             +              _sb_write_string("\r\n"); -             +              UNLOCK(g_suart_lock);          } -         +          g_poll_last_phy_error_count = 0;          g_poll_last_link_error_count = 0;          g_poll_last_phy_error_status = 0; -         +          g_fpga_sb_last_usb_event_log_index = idx; -         +          CyU3PThreadRelinquish();      }  } @@ -2692,10 +2989,10 @@ void CyFxApplicationDefine(void) {  #ifdef ENABLE_FPGA_SB      void *fpga_sb_poll_thread_ptr;  #endif // ENABLE_FPGA_SB -     +      g_counters.magic = COUNTER_MAGIC; -    memset(&g_config, 0xFF, sizeof(g_config));  // Initialise to -1 -     +    //memset(&g_config, 0xFF, sizeof(g_config));  // Initialise to -1 +      CyU3PMutexCreate(&g_log_lock, CYU3P_NO_INHERIT);      CyU3PMutexCreate(&g_counters_lock, CYU3P_NO_INHERIT);      CyU3PMutexCreate(&g_counters_dma_from_host_lock, CYU3P_NO_INHERIT); @@ -2706,36 +3003,37 @@ void CyFxApplicationDefine(void) {  #ifdef ENABLE_USB_EVENT_LOGGING      CyU3PUsbInitEventLog(g_usb_event_log, USB_EVENT_LOG_SIZE);  #endif // ENABLE_USB_EVENT_LOGGING -     +      //////////////////////////////////////////////////////// -     +      /* Tell the host that we are ignoring it for a while. */      g_fx3_state = STATE_BUSY; -     +      /* Set the FX3 compatibility number. */      compat_num[0] = FX3_COMPAT_MAJOR;      compat_num[1] = FX3_COMPAT_MINOR; -     +      /* Initialize the USB system. */      b200_usb_init(); -     +      /* Turn on the Watchdog Timer. */      CyU3PSysWatchDogConfigure(CyTrue, WATCHDOG_TIMEOUT); -     +      /* Go do something. Probably not useful, because you aren't configured. */      g_fx3_state = STATE_UNCONFIGURED; -     +      //////////////////////////////////////////////////////// -     +      b200_gpio_init(CyTrue); -     +      b200_enable_fpga_sb_gpio(CyTrue); -     +      msg("Compat:  %d.%d", FX3_COMPAT_MAJOR, FX3_COMPAT_MINOR);      msg("FX3 SDK: %d.%d.%d (build %d)", CYFX_VERSION_MAJOR, CYFX_VERSION_MINOR, CYFX_VERSION_PATCH, CYFX_VERSION_BUILD); -     +    msg("FW built: %s %s", __TIME__, __DATE__); +      //////////////////////////////////////////////////////// -     +      /* Create the USB event group that we will use to track USB events from the       * application thread. */      CyU3PEventCreate(&g_event_usb_config); @@ -2838,14 +3136,14 @@ int main(void) {      status = CyU3PDeviceCacheControl(CyTrue, CyFalse, CyFalse); // Icache, Dcache, DMAcache      if (status != CY_U3P_SUCCESS)          goto handle_fatal_error; -     +      /* Configure the IO peripherals on the FX3. The gpioSimpleEn arrays are       * bitmaps, where each bit represents the GPIO of the matching index - the       * second array is index + 32. */      status = b200_set_io_matrix(CyTrue);      if(status != CY_U3P_SUCCESS)          goto handle_fatal_error; -     +      /* This function calls starts the RTOS kernel.       *       * ABANDON ALL HOPE, YE WHO ENTER HERE */ diff --git a/firmware/fx3/b200/b200_usb_descriptors.c b/firmware/fx3/b200/b200_usb_descriptors.c index 03dbce74a..53979219b 100644 --- a/firmware/fx3/b200/b200_usb_descriptors.c +++ b/firmware/fx3/b200/b200_usb_descriptors.c @@ -1,5 +1,5 @@  // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 Ettus Research LLC  //  /* Define the USB 2.0 and USB 3.0 enumeration descriptions for the USRP B200 @@ -303,7 +303,7 @@ const uint8_t b200_usb_ss_config_desc[] __attribute__ ((aligned (32))) =      0x6A,0x00,                      /* Length of this descriptor and all sub descriptors */      0x05,                           /* Number of interfaces */      0x01,                           /* Configuration number */ -    0x00,                           /* COnfiguration string index */ +    0x00,                           /* Configuration string index */      0x80,                           /* Config characteristics - D6: Self power; D5: Remote wakeup */      0x01,                           /* Lie about the max power consumption (in 8mA unit) : 8mA */ @@ -424,6 +424,102 @@ const uint8_t b200_usb_ss_config_desc[] __attribute__ ((aligned (32))) =  }; +const uint8_t b200_usb_ss_config_desc_new[] __attribute__ ((aligned (32))) = +{ +    /* Configuration descriptor */ +    0x09,                           /* Descriptor size */ +    CY_U3P_USB_CONFIG_DESCR,        /* Configuration descriptor type */ +    0x4F,0x00,                      /* Length of this descriptor and all sub descriptors */ +    0x02,                           /* Number of interfaces */ +    0x01,                           /* Configuration number */ +    0x00,                           /* COnfiguration string index */ +    0x80,                           /* Config characteristics - D6: Self power; D5: Remote wakeup */ +    0x01,                           /* Lie about the max power consumption (in 8mA unit) : 8mA */ + +    /* Interface descriptor */ +    0x09,                           /* Descriptor size */ +    CY_U3P_USB_INTRFC_DESCR,        /* Interface Descriptor type */ +    0x00,                           /* Interface number */ +    0x00,                           /* Alternate setting number */ +    0x00,                           /* Number of end points */ +    0xFF,                           /* Interface class */ +    0x00,                           /* Interface sub class */ +    0x00,                           /* Interface protocol code */ +    0x02,                           /* Interface descriptor string index */ + +    /* Interface descriptor */ +    0x09,                           /* Descriptor size */ +    CY_U3P_USB_INTRFC_DESCR,        /* Interface Descriptor type */ +    0x01,                           /* Interface number */ +    0x00,                           /* Alternate setting number */ +    0x04,                           /* Number of end points */ +    0xFF,                           /* Interface class */ +    0x00,                           /* Interface sub class */ +    0x00,                           /* Interface protocol code */ +    0x02,                           /* Interface descriptor string index */ + +    /* Endpoint descriptor for producer EP */ +    0x07,                           /* Descriptor size */ +    CY_U3P_USB_ENDPNT_DESCR,        /* Endpoint descriptor type */ +    DATA_ENDPOINT_PRODUCER,         /* Endpoint address and description */ +    CY_U3P_USB_EP_BULK,             /* Bulk endpoint type */ +    0x00,0x04,                      /* Max packet size = 1024 bytes */ +    0x00,                           /* Servicing interval for data transfers : 0 for bulk */ + +    /* Super speed endpoint companion descriptor for producer EP */ +    0x06,                           /* Descriptor size */ +    CY_U3P_SS_EP_COMPN_DESCR,       /* SS endpoint companion descriptor type */ +    (USB3_PACKETS_PER_BURST - 1),   /* Max no. of packets in a burst : 0: burst 1 packet at a time */ +    0x00,                           /* Max streams for bulk EP = 0 (No streams) */ +    0x00,0x00,                      /* Service interval for the EP : 0 for bulk */ + +    /* Endpoint descriptor for consumer EP */ +    0x07,                           /* Descriptor size */ +    CY_U3P_USB_ENDPNT_DESCR,        /* Endpoint descriptor type */ +    DATA_ENDPOINT_CONSUMER,         /* Endpoint address and description */ +    CY_U3P_USB_EP_BULK,             /* Bulk endpoint type */ +    0x00,0x04,                      /* Max packet size = 1024 bytes */ +    0x00,                           /* Servicing interval for data transfers : 0 for Bulk */ + +    /* Super speed endpoint companion descriptor for consumer EP */ +    0x06,                           /* Descriptor size */ +    CY_U3P_SS_EP_COMPN_DESCR,       /* SS endpoint companion descriptor type */ +    (USB3_PACKETS_PER_BURST - 1),   /* Max no. of packets in a burst : 0: burst 1 packet at a time */ +    0x00,                           /* Max streams for bulk EP = 0 (No streams) */ +    0x00,0x00,                      /* Service interval for the EP : 0 for bulk */ + +    /* Endpoint descriptor for producer EP */ +    0x07,                           /* Descriptor size */ +    CY_U3P_USB_ENDPNT_DESCR,        /* Endpoint descriptor type */ +    CTRL_ENDPOINT_PRODUCER,         /* Endpoint address and description */ +    CY_U3P_USB_EP_BULK,             /* Bulk endpoint type */ +    0x00,0x04,                      /* Max packet size = 1024 bytes */ +    0x00,                           /* Servicing interval for data transfers : 0 for bulk */ + +    /* Super speed endpoint companion descriptor for producer EP */ +    0x06,                           /* Descriptor size */ +    CY_U3P_SS_EP_COMPN_DESCR,       /* SS endpoint companion descriptor type */ +    (USB3_PACKETS_PER_BURST - 1),   /* Max no. of packets in a burst : 0: burst 1 packet at a time */ +    0x00,                           /* Max streams for bulk EP = 0 (No streams) */ +    0x00,0x00,                      /* Service interval for the EP : 0 for bulk */ + +    /* Endpoint descriptor for consumer EP */ +    0x07,                           /* Descriptor size */ +    CY_U3P_USB_ENDPNT_DESCR,        /* Endpoint descriptor type */ +    CTRL_ENDPOINT_CONSUMER,         /* Endpoint address and description */ +    CY_U3P_USB_EP_BULK,             /* Bulk endpoint type */ +    0x00,0x04,                      /* Max packet size = 1024 bytes */ +    0x00,                           /* Servicing interval for data transfers : 0 for Bulk */ + +    /* Super speed endpoint companion descriptor for consumer EP */ +    0x06,                           /* Descriptor size */ +    CY_U3P_SS_EP_COMPN_DESCR,       /* SS endpoint companion descriptor type */ +    (USB3_PACKETS_PER_BURST - 1),   /* Max no. of packets in a burst : 0: burst 1 packet at a time */ +    0x00,                           /* Max streams for bulk EP = 0 (No streams) */ +    0x00,0x00                       /* Service interval for the EP : 0 for bulk */ +}; + +  /* Standard Language ID String Descriptor */  const uint8_t b200_string_lang_id_desc[] __attribute__ ((aligned (32))) =      { | 
