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.

Can uPP work with DSPF_sp_fftSPxSP()?

Dear TI experts,

I'm working on C6748. I use uPP read data from ADC, and process it with DSPF_sp_fftSPxSP() function. If I run uPP independently, the uPP works good. If I run DSPF_sp_fftSPxSP() independently, the FFT function is good.

However, if I run them together, the uPP interruption will never come out. I know the DSPF_sp_fftSPxSP() is optimized by hand, so it's very fast. I want to know what's the interaction between hand-optimized function with the uPP.

What I did: (In debug mode)

1,  initialize the uPP,

2, the main() is waiting the data from uPP.

3, uPP gets enough data through DMA, generates interruption, set a volatile flag that the data are ready, and restart the uPP for next block of data.

4, The main() loop find that the volatile flag is set, call DSPF_sp_fftSPxSP() to process the data. Clear the flag.

5, goto step 2.

What I observed:

The loop can go to step 4, but after step 5, it will fly away

----------

I think the system is going to call the uPP interruption at step 3; but the CPU lost the correct entrance of the uPP interruption function, or the DSPF_sp_fftSPxSP() destroyed the uPP interrupt function.

----------

Then,

A: I removed the DSPF_sp_fftSPxSP() function from step 4, and run the project again, the project runs smoothly.

B: I replaced the DSPF_sp_fftSPxSP() with DSPF_sp_fftSPxSP_cn(), the project runs no problem -- but the speed of FFT is unacceptable.

---------

Then, I wrote another project as:

1, Run the DSPF_sp_fftSPxSP() at the very beginning of the main() function for one time;

2, initialize the uPP,

3, the main() is waiting the data from uPP (waiting the uPP interruption happen).

What I observed this time:

The uPP interruption never come out.

Any solution about this?

The dsplib version: dsplib_c674x_3_2_0_1. I put everything(data, functions, variables) in the DSPL2RAM  (only the uPP read data from ADC to DDR2).

Thanks for your reading,

King

void Init_uPP()
{

	SetUpuPPInt();


	flag_buf_using = BUFF_A;
	flag_buf_full_a = FALSE;
	flag_buf_full_b = FALSE;


	int i;
//////////// block 1, copied from TI's code. ////////////////
	// LOCAL_kick_unlock allows register access at run time.
    // enables register access at run time
    KICK0R = 0x83e70b13;  // Kick0 register + data (unlock)
    KICK1R = 0x95a4f1e0;  // Kick1 register + data (unlock)

    //Using system default clock, the syspll0.
    // powers on one LPSC.	// turn on uPP LPSC
    *(unsigned int*) (PSC1_MDCTL + 4 * 19) =
        (*(unsigned int*) (PSC1_MDCTL + 4 * 19) & 0xFFFFFFE0) | 0x0003;
    PSC1_PTCMD = 0x1 << 0;
    // Wait for power state transition to finish
    while( (PSC1_PTSTAT & (0x1 << 0)) != 0) asm(" nop");
    while( (*(unsigned int*)(PSC1_MDSTAT + 4 * 19) & 0x1F) !=0x3) asm(" nop");

    // enables all uPP pin functions.
    // all pins (channel A, channel B, DATA, and XDATA) as UPP
    PINMUX13 = (PINMUX13 & 0x0000FFFF) | 0x44440000;
    PINMUX14 = (PINMUX14 & 0x000000FF) | 0x44444400;
    PINMUX15 = (PINMUX15 & 0x00000000) | 0x44444444;
    PINMUX16 = (PINMUX16 & 0x00000000) | 0x44444444;
    PINMUX17 = (PINMUX17 & 0x00000000) | 0x44444444;
    PINMUX18 = (PINMUX18 & 0xFF000000) | 0x00444444;

/////////// block 2, create by Kevin, referent to uPP Manual //////////////////////
// uPP soft reset
//	1. Write the EN bit in the uPP peripheral control register (UPPCR) to 0 (disables the uPP).
    UPPCR = 0x00000006;	// clear EN bit = 0.
//  2. Poll the DB bit in UPPCR for activity; wait until DMA controller is inactive/idle.
    while (UPPCR & 0x00000080);	// waiting until DB bit = 0.
//  3. Write the SWRST bit UPPCR to 1 (places uPP in software reset).
    UPPCR = (UPPCR | 0x00000010);	// set SWRST bit = 1.

    for(i=200;i>0;i--);	// delay 200 cpu clock.

    UPPCR = (UPPCR & 0xFFFFFFEF);	// set SWRST bit = 0, out of reset
// 	set parameters.
    UPDLB = 0x00000000;	// Disable loopback.

	UPICR = 0x2D002D00;	// Both are receiving data ata down edge.

	UPIVR = 0x00000000;	// Interface Idle Value Register, output value while idle. no sense.

	UPTCR = 0x00000303;		// 00-trB 00-trA 00-rdB 00rdA	// 256bytes
//	UPTCR = 0x00000000;	// Threshold Configuration Register. Lease than 64byte, do not set.
						// but a safe value for this field is setting RDSIZEI/Q = 3h. (256byte)
//	UPCTL = 0x02020006; // A for receive 16bit, B for transmit 8bit. Single rate.
	UPCTL = 0x00000004;	// Dual channels are active. independent DMA channels.
						// A -- I;  B -- Q.

	UPIEC = 0xFFFFFFFF;	// Interrupt Enable Clear Register.	To disable an interrupt, set it.
						// Disable all interrupts.

	// uPP_A interrupt End of Window
	UPIES = (unsigned int)(1<<3);	// Interrupt Enable Set Register. To enable an interrupt, set it.


 // this part is belong to void Restart_uPP(unsigned short line)
	UPID0 = (unsigned int)(adc_buf_A);	// DMA channel I Descriptor 0 Register. The starting address of
											//   receiving buffer. The lowest 3 bits must be 000.

	// only uPP_A is used.
	// 1 line, 4096*8*2 bytes (byte count can up to 65536).
	UPID1 = (unsigned int)(0x01000100);		// Line count(31-16) and Byte count(15-1, 0=0.
													// So it must be even). Total is L*B.
	UPID2 = 0x00000000;		// Line Offset Address. The offset from 2nd line(B1) to 1st line(B1).
	UPIS0 = 0x00000000;
	UPIS1 = 0x00000000;		// useless
	UPIS2 = 0x00000000;		// useless
	UPIER = 0xffffffff;	// clear all interrupts of uPPDMA

//	4. Write the SWRST bit UPPCR to 0 to (brings uPP out of software reset).
//	UPPCR = 0x00000009;	// Free run mode, and enable uPP.
	UPPCR = 0x0000000E;	// debug mode, and enable uPP.
}

void SetUpuPPInt(void)
{
	// Setup the ARM or DSP interrupt controller

#ifdef _TMS320C6X
	// Initialize the DSP interrupt controller
	IntDSPINTCInit();

	// Register the ISR in the vector table
	IntRegister(C674X_MASK_INT4, uPP_isr);

	// Map system interrupt to the DSP maskable interrupt
	IntEventMap(C674X_MASK_INT4, SYS_INT_UPP_INT);

	// Enable the DSP maskable interrupt
	IntEnable(C674X_MASK_INT4);

	// Enable DSP interrupts globally
	IntGlobalEnable();
#else
    /* Initialize the ARM Interrupt Controller.*/
    IntAINTCInit();

    /* Register the ISR in the Interrupt Vector Table.*/
    IntRegister(SYS_INT_SPINT1, SPIIsr);

    /* Set the channnel number 2 of AINTC for system interrupt 56.
     * Channel 2 is mapped to IRQ interrupt of ARM9.
    */
    IntChannelSet(SYS_INT_SPINT1, 2);

    /* Enable the System Interrupts for AINTC.*/
    IntSystemEnable(SYS_INT_SPINT1);

    /* Enable IRQ in CPSR.*/
    IntMasterIRQEnable();

    /* Enable the interrupts in GER of AINTC.*/
    IntGlobalEnable();

    /* Enable the interrupts in HIER of AINTC.*/
    IntIRQEnable();
#endif
}

  • Can you try disabling/restoring interrupts around the call to the DSPF_sp_fftSPxSP function?  I've run into a lot of past issues where the hand-assembly functions can crash if an interrupt occurs in a certain window.  This one may not necessarily have the issue, but the symptoms fit.

  • Good morning Brad,

    I tested the project as what you suggested, and the same thing happened. "No source available for "0x712120" "

    I put a breakpoint between FFT and IntEnable(); Step by Step, whenever the program pointer quit the IntEnable() function, it will fly away; then I pause the debugger, it will come to "No source available for "0x712120" ". --  It should jump into the uPP interrupt response function.

    ---- now I believe the DSP system manages the L1/L2 memory automatically, and when the hand-assembly function is called, it will crash the the interruption function(the interrupt table or the function itself).
     Going to use other memory with L1/L2 untouched; the performance will at least three slower, but maybe it's the only solution.

    Thanks for your reply,

    With best regard,

    King

  • You need to debug what happens before/after re-enabling interrupts.  It sounds like perhaps the function is trashing some memory (that might be a result of some constraint not being met?).  Perhaps another quick and easy test might be to put some "padding" buffers before and after your real data.  You could initialize them to zero with your code and then view them after the function to see if anything is written there.

  • Thank you Brad.

    I don't know how the DSP manages the L1/L2; how and where it caches the program/data. I believe I am unable to solve the problem even I can find out where the memory inside is modified by FFT. To me, I think only the uPP or hand-assembly-function group can test and find out the solution.

    Regards,

    King

  • The problem was caused by the cache function in the DSP. The DSP enabled the cache(L1/L2) as default.

    To use L2 memory, just disable the cache of L2.

    The example code can be found in quickStartOMAPL1x_rCSL.