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

