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.

How to write a 16-bit value on McBSP

Other Parts Discussed in Thread: TMS320C6416

Hi everyone,

      I've wrote a McBSP uart program on TMS320C6416, I transmit data between memory and McBSP by EDMA, it's ok.

Now I want to write 16-bit value directly to McBSP, but CSL api just one function "MCBSP_write()" that need Uint32 parameter,

so how can I  write a 16-bit value on McBSP?

 

Another question, can anybody tell me how to trigger EDMA to work again after once transfering bytes completely?

 

 Thanks.

 

  • Hello,

    Bolt Dog said:
    I've wrote a McBSP uart program on TMS320C6416, I transmit data between memory and McBSP by EDMA, it's ok.

    Now I want to write 16-bit value directly to McBSP, but CSL api just one function "MCBSP_write()" that need Uint32 parameter,

    so how can I  write a 16-bit value on McBSP?

    I believe you just need to cast the 16-bit value as a 32-bit value (MCBSP_write(&handle, (Uint32)value);) and the McBSP will ignore the upper 16 bits as long as it is configured to output a 16-bit value. The copy from the transmit buffer to the transmit shift register will only take however many bits it requires and the others should be ignored.

    Bolt Dog said:
    Another question, can anybody tell me how to trigger EDMA to work again after once transfering bytes completely?
    Are you asking how to get the EDMA to "reset" itself after it completes a transfer of ELECNT * FRMCNT words? If so, you can use the LINK field to link to another set of Parameter RAM (PaRAM) which contains a "fresh" set of values for your EDMA channel. This will essentially re-arm the EDMA channel after it completes its transfer.

    For more information on linking see sections 1.11 and 4.8.6 of the EDMA User Guide.

  • Thanks,Tim Harron.

    I 've changed my code according to your suggestions, use "MCBSP_write((Uint32)val)" to write 16-bit value directly, but

    my computer received the wrong bytes, that's not correct, maybe there is something I should setup?

  • Hi,Tim Harron,

         Maybe I know why I got a incorrect bytes, I used this code below and my computer got correct bytes.


        dxr = (volatile Uint16 *)hMcbsp0->dxrAddr; // hMcbsp0 is the McBSP Handle
        for( i = 0; i< BUFFER_SIZE * 11; i++ )
        {
            while (!MCBSP_xrdy(hMcbsp0));
            *dxr = 0x0;
            dxr ++;
            *dxr = xmitbufptr[i];  // xmibufptr is unsigned short array
        }

  • I am not sure why you need to output the data in this manner, but in any case I am glad it seems to be working for you. One thing I am curious about, though, is whether or not you are outputting an extra word of 0x0000 in between each "real" value? Or does it only output the contents of the xmitbufptr[i]?

  • Hi,TimHarron, that's the reality I come to, my computer will receive the wrong bytes if I output data using "MCBSP_write((Uint32)xmitbufptr[i])" directly, 

    I've read SPRU580 about McBSP. The register DXR is 32-bit, if I want  output 16-bit, I think only the lower 16-bit is value will be transfered.

  • Two important details that are missing from your code snippet: what is the declaration for your variable dxr, and are you using Little Endian or Big Endian?

    The DXR register is indeed 32-bits, and the Config Bus requires 32-bit operations at all times. Depending on Endianess incorrect data can result when a DSP write of less than 32-bits is used.

    However, you are not writing to the DXR register directly. The value in the struct member "dxrAddr" is the address of the McBSP's memory-mapped buffer area which is outside of the Config Bus space. This space also expects a 32-bit write at all times.

    If you have configured the McBSP to send 16 bits per serial "word", then a 32-bit write to DXR or to dxrAddr will result in only the lower 16 bits being shifted out.

    I have always been accused of using too many parentheses in my C code, but I prefer to make certain that all operations and all castings are done exactly the way I want them to be done. I do not know the exact order that things like casting and operators like [] get applied, so this gives me confidence that my intentions get implemented. And I say this because I have concerns about a couple of your implementations in the code you have mentioned:

    Bolt Dog said:

    my computer will receive the wrong bytes if I output data using "MCBSP_write((Uint32)xmitbufptr[i])" directly, 

    This may be okay, but I would feel more comfortable if it were written unambiguously as MCBSP_write((Uint32)(xmitbufptr[i])). Depending on what wrong data you are receiving, this might explain the problem.

    Bolt Dog said:

        dxr = (volatile Uint16 *)hMcbsp0->dxrAddr; // hMcbsp0 is the McBSP Handle
        for( i = 0; i< BUFFER_SIZE * 11; i++ )
        {
            while (!MCBSP_xrdy(hMcbsp0));
            *dxr = 0x0;
            dxr ++;
            *dxr = xmitbufptr[i];  // xmibufptr is unsigned short array
        }

    The variable dxr should be declared as "volatile Uint32 *". And I would be more comfortable with extra parens on the first line, "(volatile Uint16 *)(hMcbsp0->dxrAddr)".

    You should not have the *dxr = 0; and dxr++; lines. It should not be working right this way, but I cannot predict what is happening without knowing the answers to the declaration and endianess questions.

     

    Do you have a scope or logic analyzer to let you see exactly what is being transmitted from one data word to the next?
    Do you have the serial word size set to 16 (XCR.XWDLEN1 = 2)?
    How is your computer interpreting the serial bus?