0 Replies Latest reply on Jan 1, 2018 5:46 AM by mrpgolab_2370711

    FX3 FPGA Fimware load problem - only once

    mrpgolab_2370711

      Hi, all!

       

      I'm trying to implement FX3 SLFIFO app with FPGA Firmware loading, based on ConfigFpgaSlaveFifoSync example. As in the example, the FX3 works in cycle-switching between SLFIFO App and ConfigFPGA App. The problem is, I can do FPGA Firmware loading only once. The next one just doesn't do the DMA transfer between USB endpoint and GPIF.

      I have zeroed in on the problem by effectively removing the SLFIFO App and just repeating the reinitialization and termination of ConfigApp. It looks, that the source of the problem is disabling the USB Endpoint on termination of ConfigFPGA App(CyU3PSetEpConfig) and than reeanabling it on restart. If, after first time initialization of EP I leave it active, I can do multiple FPGA reconfiguration. All other resources (DMA Channel, GPIF State machine, GPIF Socket) are being released and reinitiated without problem.

       

      Do you have an idea, what can be the cause of the problem?

       

      Below are crucial functions forming the reintialization - termination cycle. 'fcattempt' is 0 at FX3 firmware init and changes to 1 after first successful FPGA firmware load. Without 'if (!fcattempt)' condition the repeated FPGA FW loading fails. I have removed all the status checks, to make code citation shorter.

       

      void startConfigFpgaApp(void)
      {
          uint16_t size = 0;
          CyU3PEpConfig_t epCfg;
          CyU3PDmaChannelConfig_t dmaCfg;
          CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
          uint8_t burstLength =0;
      
      
          initConfigFpgaApp(); //effectively calling gpifConfigure function (included below)
      apiRetStatus = usbTransferParams(&size, &burstLength);
      
      
          CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
          epCfg.enable = CyTrue;
          epCfg.epType = CY_U3P_USB_EP_BULK;
          epCfg.burstLen = burstLength;
          epCfg.streams = 0;
          epCfg.pcktSize = size;
      
      
          if (!fcattempt)  //without that condition here and int stopConfigFpgaApp, the repeated loading fails
      {
      apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_PRODUCER, &epCfg);
      }
      
      
          apiRetStatus = CyU3PUsbSetEpSeqNum(CY_FX_EP_PRODUCER, seqnum_slfifo);
      
      
          dmaCfg.size  = size * BURST_LEN;
          dmaCfg.count = DMA_BUFFER_COUNT;
          dmaCfg.prodSckId = FPGA_CONFIG_PRODUCER_SOCKET;
          dmaCfg.consSckId = FPGA_CONFIG_CONSUMER_SOCKET;
          dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
          dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
          dmaCfg.cb = FpgaUtoPDmaCallback;
          dmaCfg.prodHeader = 0;
          dmaCfg.prodFooter = 0;
          dmaCfg.consHeader = 0;
          dmaCfg.prodAvailCount = 0;
          apiRetStatus = CyU3PDmaChannelCreate (&dmahndFpgaLoadUSB2CPU,CY_U3P_DMA_TYPE_MANUAL, &dmaCfg);
          CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);
          apiRetStatus = CyU3PDmaChannelSetXfer(&dmahndFpgaLoadUSB2CPU, 0);
          glIsApplicationActive = CyTrue;
      }
      
      
      void stopConfigFpgaApp(void)
      {
          CyU3PEpConfig_t epCfg;
          CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
          glIsApplicationActive = CyFalse;
          CyU3PUsbGetEpSeqNum(CY_FX_EP_PRODUCER, &seqnum_slfifo);
          apiRetStatus = CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);
          apiRetStatus = CyU3PDmaChannelReset(&dmahndFpgaLoadUSB2CPU);
          apiRetStatus = CyU3PDmaChannelDestroy (&dmahndFpgaLoadUSB2CPU);
          if (!fcattempt)
          {
      CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
      epCfg.enable = CyFalse;
      apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_PRODUCER, &epCfg);
          }
      }
      
      
      void initConfigFpgaApp(void)
      {
      CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
      apiRetStatus = gpifConfigure(GPIF_CONFIG_FPGA_FW_LOAD);
      }
      
      
      
      
      CyU3PReturnStatus_t gpifConfigure(Fx3_Gpif_Config Gpif_Config)
      {
          CyU3PReturnStatus_t status;
          CyU3PPibClock_t pibClock;
          const CyU3PGpifConfig_t *gpif_config;
          uint8_t gpif_state_index;
          uint8_t gpif_initial_alpha;
      
      
          static CyBool_t gpif_active = CyFalse;
          static CyBool_t pib_active = CyFalse;
      
      
          if (gpif_active)
          {
              CyU3PGpifDisable(CyTrue);
              gpif_active = CyFalse;
          }
      
      
          if (pib_active)
          {
          status = CyU3PPibDeInit();
          pib_active = CyFalse;
          }
      
      
          switch (Gpif_Config) {
              case GPIF_CONFIG_SLFIFO:
          //... irrelevant
                  break;
              case GPIF_CONFIG_FPGA_FW_LOAD:
                  gpif_config = &loadFPGAGpifConfig;
                  gpif_state_index = FPGA_FW_LOAD_START;
                  gpif_initial_alpha = FPGA_FW_LOAD_ALPHA_START;
                  Dbg (4, "GPIF = FPGA Fw Load\n");
                  break;
      
      
      case GPIF_CONFIG_DISABLED:
                  return CY_U3P_SUCCESS;
      
      
              default:
                  return CY_U3P_ERROR_BAD_ARGUMENT;
          }
      
      
      pibClock.clkDiv = 2;
      pibClock.clkSrc = CY_U3P_SYS_CLK;
      pibClock.isHalfDiv = CyFalse;
      pibClock.isDllEnable = CyFalse;
      status = CyU3PPibInit(CyTrue, &pibClock);
          pib_active = CyTrue;
      
      
          status = CyU3PGpifLoad(gpif_config);
          if(Gpif_Config == GPIF_CONFIG_SLFIFO)
          {
      // ... irrelevant
          }
          else
          if(Gpif_Config == GPIF_CONFIG_FPGA_FW_LOAD)
          {
          status = CyU3PGpifSocketConfigure (3,FPGA_CONFIG_CONSUMER_SOCKET,7,CyFalse,1);
          }
          gpif_active = CyTrue;
      
      
          status = CyU3PGpifSMStart (gpif_state_index,gpif_initial_alpha);
          return CY_U3P_SUCCESS;
      }