Since my previous YX5300 post I have received a number of questions related to how the serial messages between a host and the MP3 module work. Understanding this message flow is important when writing code that uses the MP3 player in an interactive application.
My previous post provided bare bones details of the communications protocol:
- Asynchronous serial RS232 at 9600 bps, 8 data bits, No parity, 1 stop bit, no hardware flow control.
- Data packet flow control follows request/response protocol. The data packet format is in the previous post.
- Unsolicited messages are sent when certain events occur (eg, TF card removed or inserted).
Message Sequence Basics
There are 2 basic type of message flows between the Host and YX5300.
The first type is a simple message to set a parameter or cause an action. In this case the messages are exchanged as one request/response pair, shown in the sequence chart below. The request contains the command or setting, the response acknowledges the command.
The second type is a message that is requesting information from the YX5300. In this case the same simple message flow (requesting the data, acknowledging the request) is followed a short time later by another message from the device containing the requested data, which is the in turn acknowledged by the Host. This is shown in the sequence chart below. The second message can effectively be treated as an unsolicited message containing information about the device.
Managing the Serial Message Sequence
The MD_YX5300 library manages the serial interface to the YX5300 by taking care of the request/response pairs. The MP3 Player responds to command requests but it also sends unsolicited messages when certain events occur, so the user application needs to understand how to handle unsolicited messages, including the response to a data request.
How message are processed by the application using the library is flexible and depends on the setSynchronous() setting and whether a callback function is defined using setCallback().
Synchronous or Asynchronous?
The first choice in processing messages is whether to process them inline with the application sequence (synchronous) or separately (asynchronous).
Synchronous: The command message is sent and the code waits for the acknowledgement before returning to the calling application. This is relatively inefficient of CPU time as it involves a busy wait, but is easy to implement in code flow and works well enough for most applications.
Asynchronous: The command message is sent and the library immediately returns. The response message is processed as it returns and the calling application can continue to run while this happens. Once the response is received, the application can be notified through a callback or polled status (see below). This method gives the calling application priority to use the CPU between messages but requires the application to become “message flow” aware.
Polled or Callback?
Independently of the sync/async mode, the application can choose to be informed when received messages are ready to process either by polling completion status or using a callback. The relevant notification data is placed in a return data structure (cbData) for the application to process.
How the message is processed also depends on the synchronous setting, as shown in the two variants for the message sequence diagrams in each section below.
Polled: The return status of the check() method is used as the signal that an unsolicited message has been received. In polled mode a true returned value from check() is followed by a getStatus() call to retrieve the relevant cbData structure.
Callback: If a callback function is defined (see setCallback()), every unsolicited message received will be processed through the callback mechanism.
In callback mode, the call to check() triggers a callback with the relevant cbData structure passed to the callback function. Additionally, in synchronous mode the callback and the return from check() will signal receipt of the same message, so the application code should guard against trying to process the message twice.