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.

TMS320F28386S: SCI_writeCharNonBlocking not working on 2nd write

Part Number: TMS320F28386S

I have a bit of code running in CCS that is responding to the serial flash programmer running in Visual Studio C++. The first write works but the 2nd does not.

    byteData0 = SCI_readCharBlockingNonFIFO(SCIA_BASE);
    SCI_writeCharNonBlocking(SCIA_BASE, byteData0);
    byteData1 = SCI_readCharBlockingNonFIFO(SCIA_BASE);
    SCI_writeCharNonBlocking(SCIA_BASE, byteData1);
    byteData0 |= byteData1 << 8;

I would post the VS C++ code but it seems only one <insert> is allowed, at least at this time.

I tried switching the 2nd write to blocking but that did not help.

The top line is what the 28386 is reading and the bottom is what it is sending. The reads are catching the data properly.

  • Hi John,

    Thanks for your question and the scope shot.

    So the scope shot helps a lot here, because it shows where the issue likely is.

    The top line in yellow in your scopeshot looks like the voltage level is not returning to high between bytes. Voltage is hovering some voltage between 0 and high between bytes in that scope shot. This is not acceptable for UART data reception, and so you will get unreliable data because of this. Basically, since it looks like it is beyond the VIL level, it will look like a long break detect, but may be borderline enough to only happen some of the time.

    The voltage should be high between bytes. If this is fixed, likely the second byte will not have issues.

    NOTE: Remember that C2000 devices are only capable of 3.3V logic. If the VS C++ device is outputting 5V logic, then this could have also damaged the C2000 device. Also, transceiver data is not acceptable, it must be converted back to UART from any transceiver protocol like "RS-485", using another transceiver.

    Regards,

    Vince

  • Hi Vince,

    Sorry for the trouble and misleading info but I was really tired when I posted as it was late and I had been fighting with it all day. (That is my best excuse.)

    I failed to mention that what was on the scope had been through an RS-485 converter. Then it goes to a RS-485/USB adapter which the serial flash programmer running on VS C++ is monitoring. When the data is there it is perfect on both ends. The serial flash programmer code verifies the tx and rx bytes match. I added some debug prints to the serial programmer code to verify.

    The main purpose of the scope image was to show timing.

    So maybe the scope image wasn't a good idea. But at least it will help me justify it on my taxes. ;>)

  • I think the problem was possibly a breakpoint being hit before the peripheral had finished its work. Is this controllable?

  • Hi John,

    Scope images are always welcome Slight smileSlight smile

    Thanks for the follow up too, that helps quite a bit. I was initially guessing it's was either a parity error or framing error (or both) that's preventing the reception of the second byte to be complete. You can sanity check whether it's getting past the first read by checking where the code is stopped.

    But if you were able to pin it down to the breakpoint interrupting the peripheral, then one simple solution is to put a delay (DEVICE_DELAY_US) before the given breakpoint. But to avoid changing the original code, you could also move the breakpoint till it is the instruction after a blocking write.

    Otherwise, when the breakpoint is hit, the transmission is not initiated if it hasn't started yet.

    Regards,

    Vince

  • Thanks for getting back to me. Breakpoint after a block write sounds good. Next time I will add a superfluous blocking write to SCIB as SCIA is sending data and the original TI code uses a non blocking write on SCIA. However, I wonder if that will work because the blocking write waits until there is room in the TX buffer. Once there will the hardware send it out or is it stopped by the breakpoint like timers are stopped when a breakpoint is hit?

  • Hi John,

    So if we're talking debugger set to stop all clocks, then this will even pause the output mid-transmission.

    But if the debugger is not set to stop clocks (if you want to go this route, I'll need to double check with a debugger expert to see what's needed to make that possible) then you can theoretically just load it to the shift register and at that point it will continue to transmit the data (even with the debugger paused).

    So to answer your question directly: if the data has reached the shift register by the time the break point occurs, then it will transmit. If it doesn't reach the shift register before the breakpoint (and it's still in the TX buffer), then it will not transmit until the breakpoint continues.

    So to ensure it always sending the data, you can wait until after the whole blocking write funciton occurs, or within the blocking right function right after the bytes are written to the buffer (with maybe a few clock cycle delay to allow time to reach the shift register).

      

    There's also a bit related to this in the SCI registers that really isn't used too often (mainly because I think the same effect is done by having the debugger continue clocks to LSPCLK):

    Regards,

    Vince

  • Could you tell me how to have the debugger continue clocks to LSPCLK?

  • Hi John,

    I will double check with the debugger expert, but I believe my original assumption that there is a separate control for free run was incorrect.

    Please use the SCIPRI.FREESOFT bits in the meantime, as this should allow for free-run of the SCI module during breakpoints (so that anything that is queued or in the buffer will full flush out even during the breakpoint). Any statements after the breakpoint will not execute though (because they were not put in the SCI's domain yet).

    Regards,

    Vince

  • OK, thanks.

    Is there a set of macros for register manipulation?

    JH

  • Hi John,

      

    Yes! We have the following register and field definitions (located in driverlib\f2838x\driverlib\inc\hw_sci.h):

    #define SCI_O_PRI     0xFU   // SCI priority control

      

    //*************************************************************************************************
    //
    // The following are defines for the bit fields in the SCIPRI register
    //
    //*************************************************************************************************
    #define SCI_PRI_FREESOFT_S   3U
    #define SCI_PRI_FREESOFT_M   0x18U   // Emulation modes

      

    Let me know if any questions on this.

      

    Regards,

    Vince