Arm Mbed OS support forum

How to determine if TX is complete in RawSerial/UnbufferedSerial?

Hi,

I am trying to interface with a RS485 transceiver in half duplex mode, and need to disable driver right after TX is complete then enable receiver.

Is there anyway to determine in mbed if TX is done? We can try to directly access the MCU registers or add some arbitrary delay to deal with this, but both ways seem defy the purpose of Mbed.

Please advise. Thanks.

Hello Li,

In addition to the public write funtion the UnbufferedSerial has also two private write functions inherited from it’s base class - SerialBase.

    /** Begin asynchronous write using 8bit buffer.
     *
     *  The write operation ends with any of the enabled events and invokes
     *  registered callback function (which can be empty to not receive callback at all).
     *  Events that are not enabled by event argument are simply ignored.
     *  Operation has to be ended explicitly by calling abort_write() when
     *  no events are enabled.
     *  This function locks the deep sleep until any event has occurred.
     *
     *  @param buffer   The buffer where received data will be stored
     *  @param length   The buffer length in bytes
     *  @param callback The event callback function
     *  @param event    The logical OR of TX events that should end operation
     *  @return Zero if new transaction was started, -1 if transaction is already on-going
     */
    int write(const uint8_t *buffer, int length, const event_callback_t &callback, int event = SERIAL_EVENT_TX_COMPLETE);

    /** Begin asynchronous write using 16bit buffer.
     *
     *  The write operation ends with any of the enabled events and invokes
     *  registered callback function (which can be empty to not receive callback at all).
     *  Events that are not enabled by event argument are simply ignored.
     *  Operation has to be ended explicitly by calling abort_write() when
     *  no events are enabled.
     *  This function locks the deep sleep until any event has occurred.
     *
     *  @param buffer   The buffer where received data will be stored
     *  @param length   The buffer length in bytes
     *  @param callback The event callback function
     *  @param event    The logical OR of TX events that should end operation
     *  @return Zero if new transaction was started, -1 if transaction is already on-going
     */
    int write(const uint16_t *buffer, int length, const event_callback_t &callback, int event = SERIAL_EVENT_TX_COMPLETE);

As you can see these functions call a callback function you can use to determine when TX is complete.

So my suggestion is:

  • Define a MyUnbufferedSerial class by copy&pasting the UnbufferedSerial and change inheritance from private to public:
class UnbufferedSerial:
    private SerialBase,
    public FileHandle,
    private NonCopyable<UnbufferedSerial> {
public:
...

to

class MyUnbufferedSerial:
    public SerialBase,
    public FileHandle,
    private NonCopyable<UnbufferedSerial> {
public:
...

This should make the SerialBase class write functions available in the MyUnbufferedSerial class.

  • Another option is to use a SerialBase object in your application program rather then an UnbufferedSerial one.

Best regards, Zoltan