Part Number: TMS320C6748
Hello,
I'm having trouble to get uPP peripheral works on C6748.
I configured everything so that the DSP receive a full 1024 bytes buffer over uPP. Interruptions works great and there's no overrun or underflow error.
Currently, the buffer is filled only once, at the first interruption. When the DSP receive another 1024 bytes over uPP, an interruption is raised but the buffer stay the same.
I tried to increase the line count and to 2, set line offset = byte count and increase the size of buffer to 2048. I correctly get different data twice.
What I want to do is overwriting the same buffer everytime an interruption is raised.
Could you help me with that ?
Here's my code for uPP operations :
#include "BIFE_upp.h"
CSL_UppRegsOvly uppRegs = (CSL_UppRegsOvly)CSL_UPP_0_REGS;
#define UPP_BUF_SIZE 512
#define UPP_CH_DESCR1 (0x00010400) // DMA Line + Byte count (1024 bytes)
#define UPP_CH_DESCR2 (0x00000000) // DMA Line offset (0 = overwrite to the same address)
/*______________ Buffers ____________ */
#pragma DATA_ALIGN(recv_buffer,64)
volatile uint16_t recv_buffer[UPP_BUF_SIZE] = {0};
void upp_setParam()
{
/*
* Set Channel Control Register
*/
uppRegs->UPCTL = CSL_UPP_UPCTL_RESETVAL; // Reset register
// Channel A
CSL_FINST(uppRegs->UPCTL, UPP_UPCTL_IWA, 16BIT); // 16-bit interface width
CSL_FINST(uppRegs->UPCTL, UPP_UPCTL_DPWA, FULL); // No data packing
CSL_FINST(uppRegs->UPCTL, UPP_UPCTL_DRA, SINGLE); // Single data rate
CSL_FINST(uppRegs->UPCTL, UPP_UPCTL_CHN, ONE); // Channel A only
CSL_FINST(uppRegs->UPCTL, UPP_UPCTL_MODE, RECEIVE); // All receive mode
/*
* Set Interface Configuration Register (need to do a single 32 bit write)
*/
uppRegs->UPICR = CSL_UPP_UPICR_RESETVAL;
uppRegs->UPICR = CSL_FMKT(UPP_UPICR_STARTA, ENABLE) // Start signal is enabled for channel A
| CSL_FMKT(UPP_UPICR_ENAA, ENABLE); // Enable signal is enabled for channel A
/*
* Set Threshold Configuration Register
*/
uppRegs->UPTCR = CSL_UPP_UPTCR_RESETVAL;
/*
* Set Peripheral Control Register
*/
CSL_FINST(uppRegs->UPPCR, UPP_UPPCR_FREE, ENABLE);
CSL_FINST(uppRegs->UPPCR, UPP_UPPCR_SOFT, ENABLE);
CSL_FINST(uppRegs->UPPCR, UPP_UPPCR_RTEMU, ENABLE); // ONLY ENABLE WHILE DEBUG
/*
* Set Interrupt Enable Set Register
*/
CSL_FINST(uppRegs->UPIES, UPP_UPIES_DPEI, SET); // Interrupt for Channel I Programming error
CSL_FINST(uppRegs->UPIES, UPP_UPIES_EOLI, SET); // End of Line
// CSL_FINST(uppRegs->UPIES, UPP_UPIES_EOWI, SET); // End of Word
CSL_FINST(uppRegs->UPIES, UPP_UPIES_ERRI, SET); // Internal Bus Error
CSL_FINST(uppRegs->UPIES, UPP_UPIES_UORI, SET); // Underrun or Overflow error
}
void upp_init()
{
int i = 0;
upp_reset();
uppRegs->UPPCR = CSL_UPP_UPPCR_RESETVAL; // Reset control register
CSL_FINST(uppRegs->UPPCR, UPP_UPPCR_SWRST, RESET); // Set uPP on reset
for (i = 0; i < 300; i++){}; // Wait for at least 200 clock cycles
CSL_FINST(uppRegs->UPPCR, UPP_UPPCR_SWRST, RUNNING); // Set uPP back on running
upp_setParam(); // Configure parameters
CSL_FINST(uppRegs->UPPCR, UPP_UPPCR_EN, ENABLE); // Enable uPP peripheral
// Initialize DMA with buffer
upp_reloadDMA();
}
void upp_reloadDMA()
{
uppRegs->UPID0 = (uint32_t)&recv_buffer;
uppRegs->UPID1 = UPP_CH_DESCR1; // Line + Byte count
uppRegs->UPID2 = UPP_CH_DESCR2; // Line offset
while(uppRegs->UPIS2 & 0x02){};
}
uint16_t* upp_readBufferAddress()
{
return (uint16_t*)&recv_buffer;
}
void upp_ISR()
{
uint32_t interrupt_status = uppRegs->UPIER;
while(interrupt_status != 0){
if (CSL_FEXT(interrupt_status, UPP_UPIER_DPEI)){
CSL_FINS(uppRegs->UPIER, UPP_UPIER_DPEI, 1);
System_printf("uPP programming error !\n");
}
if (CSL_FEXT(interrupt_status, UPP_UPIER_EOLI)){
CSL_FINS(uppRegs->UPIER, UPP_UPIER_EOLI, 1);
upp_reloadDMA();
Swi_post(uPPProcessing_SWI);
}
if (CSL_FEXT(interrupt_status, UPP_UPIER_EOWI)){
CSL_FINS(uppRegs->UPIER, UPP_UPIER_EOWI, 1);
// upp_reloadDMA();
Swi_post(uPPProcessing_SWI);
}
if (CSL_FEXT(interrupt_status, UPP_UPIER_UORI)){
CSL_FINS(uppRegs->UPIER, UPP_UPIER_UORI, 1);
System_printf("uPP underrun or overflow\n");
}
if (CSL_FEXT(interrupt_status, UPP_UPIER_ERRI)){
CSL_FINS(uppRegs->UPIER, UPP_UPIER_ERRI, 1);
System_printf("uPP internal bus error, need reset...\n");
upp_init();
}
interrupt_status = uppRegs->UPIER;
}
uppRegs->UPEOI = 0;
}
void upp_reset()
{
uppRegs->UPPCR = CSL_UPP_UPPCR_RESETVAL;
uppRegs->UPDLB = CSL_UPP_UPDLB_RESETVAL;
uppRegs->UPCTL = CSL_UPP_UPCTL_RESETVAL;
uppRegs->UPICR = CSL_UPP_UPICR_RESETVAL;
uppRegs->UPIVR = CSL_UPP_UPIVR_RESETVAL;
uppRegs->UPTCR = CSL_UPP_UPTCR_RESETVAL;
uppRegs->UPIEC = 0xFFFFFFFF;
uppRegs->UPID0 = CSL_UPP_UPID0_RESETVAL;
uppRegs->UPID1 = CSL_UPP_UPID1_RESETVAL;
uppRegs->UPID2 = CSL_UPP_UPID2_RESETVAL;
uppRegs->UPQD0 = CSL_UPP_UPQD0_RESETVAL;
uppRegs->UPQD1 = CSL_UPP_UPQD1_RESETVAL;
uppRegs->UPQD2 = CSL_UPP_UPQD2_RESETVAL;
/* Reset receive buffer */
int i;
for (i = 0; i < UPP_BUF_SIZE; i++)
recv_buffer[i] = 0;
}
Best regards,
GChapman