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.

TMS320C6748: uPP overwrite to the same buffer issues

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