This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to recover from UOR condition in UPP Driver

Hi,

I am using UPP peripheral of C6748 running at (300 MHz) to connect to FPGA for High speed data transfer. Presently UPP channel A is connected for (16 bit data width)Transmit and channel B is connected (16 bit data width) for receive. My application is like receiving 4k data at every 2.5 ms and after processing need to transmit through channel B. The number of bytes which we are recieving can go upto 44K. Now after continuosly running for 1-2 minutes I started getting UOR condition on RX channel and afterwards upp peripheral is not able to recover. I followed UPP user guide section 2.6 to give software reset and try to recover from UOR but after few times that also not able to recover. I reduced clock speed from 75 MHZ to 50 MHz (in Rx mode ) and 75 MHz to 37.5 MHz (in Tx Mode) but still this problem persist. Whether I am not able to properly give software reset to UPP peripheral? Can any body give some insight about how to resolve this issue. Also I am using upp_bios_drv IOM driver provided by Joe Coomb. 

 

Regards,

Chandra Shekhar Mishra

  • Chandra,

    You definitely shouldn't be seeing UOR interrupts when operating at or below 75 MHz, so I think we should try to figure out why that is happening.  One issue that can cause UOR errors is when the uPP module clock exceeds 150 MHz.  Are you using the default uPP module clock (i.e. PLL0 SYSCLK2) or an alternate clock?  For more information about this, please refer to the following thread:

    I also want to double check that you are operating in single data rate mode.  In double data rate mode, the maximum allowed speed is 37.5 MHz rather than 75 MHz.

  •  Hi Joe,

    Thanks for quick reply.

    Please find the attached file  I am using for UPP Configuration.

     // start with default settings
      *upp_setup = UPP_USERPARAMS;
    
    /*
     * -----Channel A (Transmitter) Parameters Settings
     */
      upp_setup->params.A.direction = upp_dir_xmit;		// direction of uPP channel
      upp_setup->params.A.clock_div = upp_clock_div;	// clock divider (transmit mode only, 1-16)
      upp_setup->params.A.data_rate = 1;				// data rate (1-2)
      upp_setup->params.A.width 	= 16;				// data width (in bits, 8-16)
      
      upp_setup->params.A.format	 	= upp_format_rjze;      // data format (8 < width < 16 only)
      upp_setup->params.A.xmit_thresh 	= upp_thresh_64; 		// transmit threshold (transmit only)
      upp_setup->params.A.drive_idle	= TRUE;  				// drive value from IVR while idle (else hi-z)
      upp_setup->params.A.idle_value 	= 0xAAAA;				//value for IVR
      
       // signal enable
       upp_setup->params.A.en_start	= TRUE;    		// enable start signal
       upp_setup->params.A.en_enable= TRUE;   		// enable enable signal
       upp_setup->params.A.en_wait  =  TRUE;     	// enable wait signal
      
       // signal polarity
       upp_setup->params.A.inv_start	= FALSE;   	// invert start signal
       upp_setup->params.A.inv_enable	= TRUE;  	// invert enable signal
       upp_setup->params.A.inv_wait		= FALSE;    // invert wait signal
       upp_setup->params.A.inv_clock	= TRUE;//FALSE;   	// invert clock signal
       
       // interrupt generation (async mode only)
       upp_setup->params.A.gen_eow		= TRUE;     // generate end of window (EOW) events
       upp_setup->params.A.gen_eol		= TRUE;     // generate end of line (EOL) events
       upp_setup->params.A.gen_uor		= TRUE;     // generate underflow/overflow (UOR) events
       upp_setup->params.A.gen_err		= TRUE;     // generate internal error (ERR) events
       upp_setup->params.A.gen_dpe		= TRUE;     // generate DMA programming error (DPE) events
       
       // interrupt dispatch (async mode only)
        upp_setup->params.A.fxn_eow	=	NULL;    									// function pointer for EOW user-callback (optional; called if != NULL)
        upp_setup->params.A.fxn_eol	= (upp_CbFxn)LOCAL_upp_complete_EOLTransmit;    // function pointer for EOL user-callback (optional; called if != NULL)
        upp_setup->params.A.fxn_uor	=	(upp_CbFxn)LOCAL_upp_Error_Tx;     // function pointer for UOR user-callback (optional; called if != NULL)
        upp_setup->params.A.fxn_err =	(upp_CbFxn)LOCAL_upp_Error_Tx;     // function pointer for ERR user-callback (optional; called if != NULL)
        upp_setup->params.A.fxn_dpe =	(upp_CbFxn)LOCAL_upp_Error_Tx;     // function pointer for DPE user-callback (optional; called if != NULL)
     
    //////////////////////////////////////////////////////
    
     /*
      * -----Channel B (Receiver) Parameters Settings
      */
      	upp_setup->params.B.direction = upp_dir_rcv;		// direction of uPP channel
      	upp_setup->params.B.clock_div = 0;					// clock divider (transmit mode only, 1-16)
      	upp_setup->params.B.data_rate = 1;					// data rate (1-2)
     	upp_setup->params.B.width 	= 16;					// data width (in bits, 8-16)
     	
    
    
    	// signal enable
       upp_setup->params.B.en_start	= FALSE;    		// enable start signal
       upp_setup->params.B.en_enable= TRUE;   			// enable enable signal
       upp_setup->params.B.en_wait  = TRUE;     		// enable wait signal
      
    	// signal polarity
       upp_setup->params.B.inv_start	= FALSE;   	// invert start signal
       upp_setup->params.B.inv_enable	= FALSE;  	// invert enable signal
       upp_setup->params.B.inv_wait		= FALSE;    // invert wait signal
       upp_setup->params.B.inv_clock	= TRUE;   	// invert clock signal
    
      // interrupt dispatch (async mode only)
        upp_setup->params.B.fxn_eow	= NULL;//(upp_CbFxn)LOCAL_upp_complete_cb;;    // function pointer for EOW user-callback (optional; called if != NULL)
        upp_setup->params.B.fxn_eol	= (upp_CbFxn)LOCAL_upp_complete_EOL;    // function pointer for EOL user-callback (optional; called if != NULL)
        upp_setup->params.B.fxn_uor	=	(upp_CbFxn)LOCAL_upp_Error_Rx;     // function pointer for UOR user-callback (optional; called if != NULL)
        upp_setup->params.B.fxn_err =	(upp_CbFxn)LOCAL_upp_Error_Rx;     // function pointer for ERR user-callback (optional; called if != NULL)
        upp_setup->params.B.fxn_dpe =	(upp_CbFxn)LOCAL_upp_Error_Rx;     // function pointer for DPE user-callback (optional; called if != NULL)         
                
        upp_setup->params.channels = 2;

    Also I find myself in the situation where after sometime Even aftter calling GIO_read() the EOL callback stops.

     

  • Hi Joe,

    Also I forgot to add that in recieve Mode I am getting clock from FPGA on CHB_clock pin that we are providing 75Mhz . And I always got UOR condition while recieving tha data.

     

    Thanks & Regards,

    Chandra Shekhar Mishra

  • Chandra,

    Have you tried temporarily lowering your receive clock to some overly conservative speed, like 10 MHz?  I'm just curious if we can actually pin this problem on the I/O clock (i.e. if there is some "safe" speed well below 75 MHz that eliminates the UOR events).  Also, if your clock is being generated by an FPGA, is it possible that there is an occasional glitch in the generated clock?  The fact that the system runs for a few minutes before failing could make the underlying issue difficult to track down.

    I would still advise you to check the system reference guide and review how you are clocking the uPP peripheral itself.  (That clock comes from one of the PLL modules, depending on how your system is configured.)

  • Hi Joe,

    I verified SYSCFG registers and found that UPP_TX_CLKSRC is set to ASYN3 and ASYNC3_CLKSRC is set to PLL0.  So by looking at upp_user_guide it looks I/O clock for transmit is correct. Also for Rx Mode clock is provided by FPGA.. I changed CHB_clock (Rx Mode ) to different frequencies like 75Mhz,50Mhz, 25 MHz and 10 MHz but result is same. After some time it starts giving UOR error. I called GIO_control to reset upp peripheral as mentioned in following link

    http://wiki.tiprocessors.com/index.php/Using_the_uPP_DSP/BIOS_Driver

    inside UOR callback function to recover from the error condition. But the problem is afterwards I am getting UOR condition continuously and unable to process the  data. Kindly help me to find out the solution.

    Regards,

    Chandra Shekhar Mishra

  • Hi Joe,

    I noticed that after calling upp_sw_reset inside UOR callback instead of UPPQDMA descriptors other registers retained there value. Even though I am trying to write DMA descriptors but unable to set it. Whether I need to follow some sequence?

     

    Regards,

    Chandra Shekhar Mishra

  • Hi Joe,

    Thanks for your replies. I downloaded the fresh upp_bios_drv_v10 and used debug build library in my application after that I never got UOR error condition. But now I am facing strange issue like occasionally UPP RX peripheral goes into wait state and I am unable to acquire data on UPP RX peripheral. Could you please guide me where I need to debug?

    Regards,

    Chandra Shekhar Mishra

  • Chandra,

    Did you previously modify or rebuild the driver library, or is the difference that you are using the debug profile driver instead of the release profile driver?  I want to understand how this re-downloaded driver is different from the version you were using before.

    When a uPP channel is configured in receive mode, the WAIT signal should never assert during normal operation.  The only time you should see WAIT asserted is when the peripheral is reset or when the emulator halts DSP execution.  If you're seeing WAIT assert at other times, you may want to double check that nothing else on your board is inadvertently pulling the WAIT signal high.

  • Hi Joe,

    I was getting the UOR condition with Release build of UPP driver. Once again I cross checked today and got UOR condition with release build of driver. I am getting these error condition while increasing the payload on UPP TX channel. Actually I need to send continuous data on Tx channel,If payload is less, there is no problem but as soon as I increase the payload it generates error. In Debug build, it is not generating UOR condition but peripheral generates wait signal. As you suggested i checked the UPP registers after that condition and found that UPP peripheral got RESET. Can you suggest how to get resolve this issue?

    Thanks & Regards

    Chandra Shekhar Mishra

  • Hi Joe,

    Still I am struggling to make UPP peripheral running consistently. If I configured Rx channel to recieve 4k data bytes every 2.5 ms and send 16K data bytes every 10ms at TX channel than it is working fine but If I increase Tx channel data payload to 32K onwards than problem starts. some time it runs for 1 minute or sometime it stops after 5 minutes. I checked UPP registers after that and found sometime SWRST and EN bit of UPPCR register got disabled and if these bits are ok than RTEMU got enabled. I am wondering how come RTEMU got enabled. After this UPP Rx channel is not ready to work even though I followed software reset proceedure mentioned in UPP user guide. It will be really a great help if you can share your knowledge to troubleshoot my problem.

     

    Thanks & Regards,

    Chandra Shekhar Mishra

  • Chandra,

    I have not been able to reproduce the issues you describe regarding SWRST, EN, and RTEMU.  It is particularly strange that you report seeing RTEMU enabled sometimes during operation, since the driver never touches that register field.  Does this seem to happen randomly in your application, or is there some point at which it happens?  Also, are you relying entirely on the uPP driver to control the peripheral, or are you also modifying the registers directly with your own code?

    The throughput values that you describe should fall well within the range of normal uPP operation.  I wonder if this could be a symptom of some other hardware or software issue in your system that is interfering with the uPP peripheral.

  • Dear Joe,

    I am not modifying any of the registers directly from the code. The only difference between your Test software and my application is that I am continuoously reading Data on UPP_Rx  channel inside Hardware Interrupt ISR (using GIO_read) and sending data on UPP_Tx channel (using GIO_write) inside task while your test application do it sequencially inside a task. I doubt while transmitting data on Tx channel, if Interrupt comes, this condition is creating Problem.

    For the testing purpose I masked the RX Interrupt while sending the data on Tx channel than I am not able to get the error condition. Can you please suggest How I need to properly Synchronise this read and write. Is it required to move UPP read operation  inside a task of same priority of UPP write operation ?

    Thanks a lot for your time.

    Regards,

    Chandra Shekhar Mishra 

  • Chandra,

    Generally speaking, it's better to make calls to GIO_read and GIO_write from a TSK context.  I recommend modifying your application to move these calls outside of your ISRs.  For example, you can call SEM_post from inside your ISR, then use SEM_pend to make the TSK wait until the uPP transfer is complete.  (You can also use SEM_count to check whether or not the transfer is complete without blocking to wait until it is.)

    It's also a good idea to call to GIO_read and GIO_write from a TSK or TSKs with the same priority so that they can't pre-empt each other.

    Making the ISR more light-weight should help things run more smoothly.