Hi,
I'm just trying to use uPP DLB on C6657 EVM.
I briefly created the code to transfer data from g_txBuffer to g_rxBuffer with uPP DLB mode.
Please note I'm using CSL (C:\ti\pdk_C6657_1_1_2_6\packages\ti\csl) to build the code.
#include <ti/csl/csl_chip.h> #include <ti/csl/csl_psc.h> #include <ti/csl/csl_pscAux.h> #include <ti/csl/cslr_bootcfg.h> #include <ti/csl/cslr_upp.h> #define REG_UPP_BASE 0x02580000 #define REG_DEVCTRL_BASE 0x02620000 #define PACKET_SIZE 64 #pragma DATA_SECTION (g_txBuffer, ".upp_buffer"); #pragma DATA_ALIGN (g_txBuffer, 64); Int g_txBuffer[PACKET_SIZE]; #pragma DATA_SECTION (g_rxBuffer, ".upp_buffer"); #pragma DATA_ALIGN (g_rxBuffer, 64); Int g_rxBuffer[PACKET_SIZE]; static UInt l2_global_address (UInt addr) { UInt corenum; /* Get the core number. */ corenum = CSL_chipReadReg(CSL_CHIP_DNUM); /* Compute the global address. */ return (addr + (0x10000000 + (corenum*0x1000000))); } Void taskFxn(UArg a0, UArg a1) { Int i; CSL_UppRegs *uppRegs = (CSL_UppRegs *)REG_UPP_BASE; CSL_BootcfgRegs *bootRegs = (CSL_BootcfgRegs *)REG_DEVCTRL_BASE; // Initialize rx/tx buffer for (i = 0; i < PACKET_SIZE; i++) { g_txBuffer[i] = i; g_rxBuffer[i] = 0xFFFFFFFF; } // 1 Apply the appropriate pin multiplexing settings. See the device-specific data manual, and/or //pin multiplexing utility for more information. bootRegs->CHIP_PIN_CONTROL_1 = CSL_BOOTCFG_CHIP_PIN_CONTROL_1_UPP_EMIF16_MASK; // 2 Enable the power and clocks to the uPP peripheral. See the device-specific data manual for more //information. //...Nothing... // 3 Set the SWRST bit in the uPP peripheral control register (UPPCR) to 1 to place uPP in software //reset. uppRegs->UPPCR = (CSL_UPP_UPPCR_SWRST_RESET << CSL_UPP_UPPCR_SWRST_SHIFT) | (CSL_UPP_UPPCR_FREE_ENABLE << CSL_UPP_UPPCR_FREE_SHIFT); // 4 Wait at least 200 device clock cycles, then clear the SWRST bit to 0 to bring the module out of //reset. for (i = 0; i < 200; i++) { asm (" nop"); } uppRegs->UPPCR &= ~CSL_UPP_UPPCR_SWRST_MASK; // 5 Program the uPP configuration registers: UPCTL, UPICR, UPIVR, UPTCR, and UPDLB. uppRegs->UPCTL = (CSL_UPP_UPCTL_MODE_DUPLEX0 << CSL_UPP_UPCTL_MODE_SHIFT) | //Using Duplex mode 0 (CSL_UPP_UPCTL_CHN_TWO << CSL_UPP_UPCTL_CHN_SHIFT) | //2 channels - A and B (CSL_UPP_UPCTL_SDRTXIL_DISABLE << CSL_UPP_UPCTL_SDRTXIL_SHIFT) | (CSL_UPP_UPCTL_DPWA_FULL << CSL_UPP_UPCTL_DPWA_SHIFT) | (CSL_UPP_UPCTL_DPWB_FULL << CSL_UPP_UPCTL_DPWB_SHIFT) | (CSL_UPP_UPCTL_IWA_8BIT << CSL_UPP_UPCTL_IWA_SHIFT) | (CSL_UPP_UPCTL_IWB_8BIT << CSL_UPP_UPCTL_IWB_SHIFT) | (CSL_UPP_UPCTL_DRA_SINGLE << CSL_UPP_UPCTL_DRA_SHIFT) | (CSL_UPP_UPCTL_DRB_SINGLE << CSL_UPP_UPCTL_DRB_SHIFT) | (CSL_UPP_UPCTL_DDRDEMUX_DISABLE << CSL_UPP_UPCTL_DDRDEMUX_SHIFT) ; uppRegs->UPICR = //Transmit -- B channel //START is an output signal and is always driven. //ENABLE is an output signal and is always driven. //WAIT is an input signal and may be disabled using the WAITx bit in UPICR. //CLOCK is an output signal. (15 << CSL_UPP_UPICR_CLKDIVB_SHIFT) | // very slow clocking... (CSL_UPP_UPICR_WAITPOLB_NORMAL << CSL_UPP_UPICR_WAITPOLB_SHIFT) | //WAIT is active-high // (CSL_UPP_UPICR_CLKINVB_INVERT << CSL_UPP_UPICR_CLKINVB_SHIFT) | //Falling edge to send data (CSL_UPP_UPICR_WAITB_ENABLE << CSL_UPP_UPICR_WAITB_SHIFT) | //Using wait signal with default polality //Receive -- A channel //START is an input signal and may be disabled using the STARTx bit in UPICR. //ENABLE is an input signal and may be disabled using the ENAx bit in UPICR. //WAIT is an output signal. //CLOCK is an input signal. (CSL_UPP_UPICR_STARTA_ENABLE << CSL_UPP_UPICR_STARTA_SHIFT) | //Using START signal (CSL_UPP_UPICR_ENAA_ENABLE << CSL_UPP_UPICR_ENAA_SHIFT) | //Using ENA signal (CSL_UPP_UPICR_CLKINVA_NORMAL << CSL_UPP_UPICR_CLKINVA_SHIFT) //Rising edge to get data ; uppRegs->UPIVR = CSL_UPP_UPIVR_VALB_RESETVAL; uppRegs->UPTCR = 0; // 64byte transaction to DMAs uppRegs->UPDLB = CSL_UPP_UPDLB_BA_ENABLE << CSL_UPP_UPDLB_BA_SHIFT; //B to A loopback //6 Program the uPP interrupt enable set register (UPIES) to interrupt generation for the desired //events. Register an interrupt service routine (ISR) if desired; otherwise, polling is required. uppRegs->UPIEC = (0x1F << 8) | (0x1F); // Disable all interrupts //7 Set the EN bit in the uPP peripheral control register (UPPCR) to 1 to turn on the uPP peripheral. uppRegs->UPPCR |= CSL_UPP_UPPCR_EN_ENABLE << CSL_UPP_UPPCR_EN_SHIFT; //Start UPP Rx Part uppRegs->UPID0 = l2_global_address((UInt)g_rxBuffer); uppRegs->UPID1 = (1 << 16) | sizeof (g_rxBuffer); uppRegs->UPID2 = 0; //Start UPP Tx Part uppRegs->UPQD0 = l2_global_address((UInt)g_txBuffer); uppRegs->UPQD1 = (1 << 16) | sizeof (g_txBuffer); uppRegs->UPQD2 = 0; while (1) { asm(" nop"); } }
When the control reaches to "nop", I think the transfer should happen, but actually,no transfer.
Do you have any suggestions ? Please note tx/rx buffer has been allocated in L2RAM. So, I don't implement cache related code to tx/rx buffer.
What I want to check with this code is to evaluate the latency in uPP. So,I'm doing only minimal configurations to uPP.
Please check the following link about the background.
http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/390898
Best Regards,
Kawada