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 }