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.

OMAP-L138/TMS320C674x McBSP Companding Internal Data

Other Parts Discussed in Thread: OMAP-L138

Hello!

I'm trying to use one of McBSP1 for companding internal data using non-DLB mode. Here is what I did:

- woke up the McBSP1 logic

- set the RRST and XRST to 0 in SPCR

- set the XCOMPAND to 0x3

- set the RCOMPAND to 0x0

- wrote some value to DXR

- waited for 4 clock cycles asm("nop")

- read DRR

The problem is I always read back 0 from DRR. When I read other registers that I have set, they get read back OK, so I think that McBSP1 is up and running.

Are there any other registers I need to set?

  • Szymon,

    Are you using OMAP-L138?  If so, is the ARM connected or halted?

    -Tommy

  • Yes, I'm using OMAP-L138.

    ARM is running, but it's doing nothing in u-boot I guess.

    I write&compile a simple McBSP configuration program in CCS 3.3 and load it on the DSP. During establishing the connection to the board the approprieate GEL code wakes up McBSP (I'm using the OMAP-L138 eXperimenter board from Logic).

  • Szymon,

    I assume that you tried waiting for more clock cycles to make sure that there are no synchronization issues between CPU and McBSP clock domains.  Can you try setting the FREE bit in the SPCR register during McBSP configuration to see if it makes a difference?

    -Tommy

  • Szymon,

    Can you also verify that the McBSP RCR and XCR are programmed to operate in 8-bit mode?

    -Tommy

  • I set FREE, RCR and XCR are programmed for 8 bits.

    Here is the program and its output:

     

    #define MCBSP1_DRR                        0x01D11000
    #define MCBSP1_DXR                        0x01D11004
    #define MCBSP1_SPCR                        0x01D11008
    #define MCBSP1_RCR                        0x01D1100C
    #define MCBSP1_XCR                         0x01D11010

    int main() {
        int toCompress = 0x88888888;
        int afterCompress;
        *(volatile int *)MCBSP1_SPCR = (1 << 25);
        *(volatile int *)MCBSP1_XCR = (3 << 19);
        *(volatile int *)MCBSP1_RCR = 0;

        printf("To compress: %x\n", toCompress);
        printf("MCBSP1_SPCR: %x\n", *(volatile int *)MCBSP1_SPCR);
        printf("MCBSP1_XCR: %x\n", *(volatile int *)MCBSP1_XCR);
        printf("MCBSP1_RCR: %x\n", *(volatile int *)MCBSP1_RCR);
        *(volatile int *)MCBSP1_DXR = toCompress;       
        asm(" NOP");
        asm(" NOP");
        asm(" NOP");
        asm(" NOP");
        afterCompress=*(volatile int *)MCBSP1_DRR;
        printf("After compress: %x\n", afterCompress);
    }

     

    Output:

    To compress: 88888888
    MCBSP1_SPCR: 2000000
    MCBSP1_XCR: 180000
    MCBSP1_RCR: 0
    After compress: 0

  • Szymon,

    Thanks for the code snippet.  Someone here is looking into it and will report back.

    -Tommy

  • You need to poll the RRDY bit to know the appropriate moment to read from DRR.  4 cycles is definitely not going to be enough time.  The McBSP is a serial interface, so if you're transferring 8-bit data you will need 8 bit clocks for that data to transfer.  Furthermore the CPU clock is going to be a multiple of that bit-clock so it will be some multiple of 8 cycles that you would wait, though again you'll simply poll RRDY.

  • I'm trying to use Non-DLB mode and the documentation (sprugj6b) states:

    "Non-DLB: When both the transmit and receive sections of the serial port are reset, DRR and DXR are internally connected through the companding logic. Values from DXR are compressed as determined by the XCOMPAND bits and then expanded as determined by the RCOMPAND bits. RRDY and XRDY bits are not set. However, data is available in DRR four internal McBSP clocks after being written to DXR. The advantage of this method is its speed. The disadvantage is that there is no synchronization available to the CPU and the EDMA controller to control the flow of data."

    According to this, RRDY and XRDY will not be set. I imagined that there is a dedicated circuitry in McBSP that always compands the data on DXR and after 4 clock cycles it is available on DRR in case the transmit and receive sections are off.

    Adding like a 100 NOPs to my program doesn't help.

  • I will try to check if running the application through DSPLink not CCS gives some other results...

  • Szymon,

    Thank you for bringing this up. Unfortunately the documentation for this part is incorrect, and it does not support the companding internal data in non-DLB mode. We will update the user guide to reflect this error.

    Instead you will have to use DLB mode to enable the companding. I modified your code to perform this:


    #define MCBSP1_DRR                        0x01D11000
    #define MCBSP1_DXR                        0x01D11004
    #define MCBSP1_SPCR                      0x01D11008
    #define MCBSP1_RCR                        0x01D1100C
    #define MCBSP1_XCR                         0x01D11010
    #define MCBSP1_PCR                         0x01D11024
    #define MCBSP1_RCERE0                  0x01D1101C
    #define MCBSP1_XCERE0                  0x01D11020
    #define MCBSP1_SRGR                       0x01D11014

    #include <stdio.h>

    int main() {
        int toCompress = 0xef;
        int afterCompress, i;

        *(volatile int *)MCBSP1_SRGR =     0x30070002;
        *(volatile int *)MCBSP1_PCR =     0x00000F00;
        *(volatile int *)MCBSP1_XCR =     0x180000;   // Companding on tx side
        *(volatile int *)MCBSP1_RCR =      0x0;
        *(volatile int *)MCBSP1_RCERE0 = 0x0000FFFF;
        *(volatile int *)MCBSP1_XCERE0 = 0x0000FFFF;


        printf("To compress: %x\n", toCompress);
        printf("MCBSP1_SPCR: %x\n", *(volatile int *)MCBSP1_SPCR);
        printf("MCBSP1_XCR: %x\n", *(volatile int *)MCBSP1_XCR);
        printf("MCBSP1_RCR: %x\n", *(volatile int *)MCBSP1_RCR);

        *(volatile int *)MCBSP1_DXR = toCompress;       

        *(volatile int *)MCBSP1_SPCR =     0x02C18007;


    /*The DRR register must  be read 3 times in order to flush out old data in the receive buffer */

    for(i=0; i<4; i++) {
        afterCompress=*(volatile int *)MCBSP1_DRR;
    }

    printf("After compress: %x\n\n", afterCompress);
      
    while (1);
    }

     

  • How do I perform expansion? Changing MCBSP1_XCR to 0 and MCBSP1_RCR to 0x180000 as would be the case in Non-DLB mode doesnt do anything...

  • You need to reset the transmit and receiver if you change the type of companding, by adding this line at the start of the code

       *(volatile int *)MCBSP1_SPCR =     0x0;

    Jeff