/*---------------------------------------------------------------------------*
 * Routine:  ISerialGeneric_TimerCallbackTransmitEmpty
 *---------------------------------------------------------------------------*
 * Description:
 *      The transmission buffer is empty (or needs more characters).  Pull
 *      a byte out of the waiting buffer and put into the serial hardware
 *      output by calling SerialDevice->OutputByte.
 * Inputs:
 *      void *aCallbackWorkspace    -- Pointer to T_RS485_Generic_Timer_Workspace
 *---------------------------------------------------------------------------*/
static void ISerialGeneric_TimerCallbackTransmitEmpty(
    void *aCallbackWorkspace,
    TUInt32 aNumBytesAvailable)
{
    T_RS485_Generic_Timer_Workspace *p =
        (T_RS485_Generic_Timer_Workspace *)aCallbackWorkspace;
    TUInt8 c;
    PARAM_NOT_USED(aNumBytesAvailable);

    // Only send one byte at a time because we have greater control
    // over the timing (the LPC2478 takes 1 character minus 1 stop bit to process
    // this many characters
    // Output a byte to the buffer
    if (_isr_UEZQueueReceive(p->iQueueSend, &c) == UEZ_ERROR_NONE) {
        // Got data, send it
        (*p->iSerial)->OutputByte((T_halWorkspace *)p->iSerial, c);
    } else {
        // No more data to send
        p->iTxBusy = EFalse;

        // Set the time it takes until we get a match
        (*p->iTimer)->SetMatchRegister(p->iTimer, 0,
            p->iReleaseTimeCPUCycles, ETrue, EFalse, EFalse);

        // Reset and start the counter
        (*p->iTimer)->Reset(p->iTimer);
        (*p->iTimer)->Enable(p->iTimer);
    }
}
/*---------------------------------------------------------------------------*
 * Routine:  ISerialGenericHalfDuplexCallbackTransmitEmpty
 *---------------------------------------------------------------------------*
 * Description:
 *      The transmission buffer is empty (or needs more characters).  Pull
 *      a byte out of the waiting buffer and put into the serial hardware
 *      output by calling SerialDevice->OutputByte.
 * Inputs:
 *      void *aCallbackWorkspace    -- Pointer to T_Serial_GenericHalfDuplex_Workspace
 *---------------------------------------------------------------------------*/
void ISerialGenericHalfDuplexCallbackTransmitEmpty(
                void *aCallbackWorkspace,
                TUInt32 aNumBytesAvailable)
{
    T_Serial_GenericHalfDuplex_Workspace *p = (T_Serial_GenericHalfDuplex_Workspace *)aCallbackWorkspace;
    TUInt8 c;

    while (aNumBytesAvailable--)  {
        // Output a byte to the buffer
        if (_isr_UEZQueueReceive(p->iQueueSend, &c) == UEZ_ERROR_NONE)  {
            // Got data, send it
            (*p->iSerial)->OutputByte((T_halWorkspace *)p->iSerial, c);
        } else {
            // No more data to send
            p->iTxBusy = EFalse;
            // Start a countdown until we release
            _isr_UEZSemaphoreRelease(p->iDESem);
            _isr_UEZSemaphoreRelease(p->iSemEmpty);
            break;
        }
    }
}