#ifndef _aplmt_devices_serial_stream_uartaapi_h_
#define _aplmt_devices_serial_stream_uartaapi_h_
/*----------------------------------------------------------------------------
** SUMMARY: APLMT Low-Level Stream based UART-A Device Interface (DEVSUARTA)
**
** DESCRIPTION:
**  This file provides an interrupt driven, stream oriented, blocking IO,
**  with ring buffers interface for the primary Serial port.  The mapping of
**  of primary UART to a physical port is dependent on your platform's 
**  implementation. The driver can be configured as Receive Only, Transmit 
**  Only, or Receive and Transmit (see compile switches below).
**
**  UART INITIALIZATION
**  -------------------
**  There is NO "uart-initialize" method(s) defined.  This is intentional
**  since UART initialization is very CPU/micro/peripheral specific.  See the
**  aplmt/hardware/<vendor>/<family>/<target>/uart/... directory tree for the 
**  appropriate initialize method(s).  THE APPLICATION MUST INITIALIZE THE
**  THE PLATFORM'S UART BEFORE STARTING THE DRIVER.
**
**  THREAD SAFETY
**  -------------
**  While this interface provides blocking semantics for the read/write calls
**  there are threading related restrictions when using the interface. This 
**  interface ASSUMES that access to the UART is single-thread-access in that 
**  ONE AND ONLY ONE thread "owns" a the UART stream at any given time (aka 
**  non-reentrant).  TX and RX streams are considered independent streams. For 
**  example: if Thread-X is calling Aplmt_devUartATransmitByte(), no other 
**  thread may call any of the transmit methods for UART-A until 
**  Aplmt_devUartATransmitByte() finishes executing in Thread-X.  However, since
**  the TX stream is independent of the RX stream, Thread-Y can be using
**  the 'read' methods at the same time Thread-X is using the 'write' methods.
**  Individual UARTs and/or streams may be "owned" by different threads. It is 
**  the RESPONSIBILITY of the application to enforce/follow this paradigm.
**
**  RX BUFFER
**  ---------
**  Receive buffer OVERRUNS are handled silently.  If the receive buffer is 
**  full and a new byte of data is received, the last byte in the receive is 
**  overwritten with the new data just received.
**  
**  
** CONFIGURATION 
** -------------
**  COMPILE:     USE_APLMT_DEVICE_UARTA_TX
**               USE_APLMT_DEVICE_UARTA_RX
**
**  APPLICATION: The application can override the following types/defintions
**                  AplmtDevUartABufSize
**                  OPTION_APLMT_DEVICE_UARTA_TX_RBUFIZE 
**                  OPTION_APLMT_DEVICE_UARTA_RX_RBUFIZE
**
**  PLATFORM:    none.
**
**
**  NOTES:
**  1. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called from interrupt service routines.
**  2. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called before the platform's kernel is running.
**  3. Unless explicitly stated otherwise, all of the following methods assume
**     that interrupts are enabled at the time of the call.
**  4. All of the methods are true functions (as opposed to macros) to 
**     facilitate building look-up tables of the driver functions.
----------------------------------------------------------------------------*/


#include "aplcfg.h"                 /* For: Application configuration */
#include "apl/types/types.h"        /* For: basic types */


#ifdef __cplusplus
extern "C" {
#endif

/*-------------- CONSTANTS -------------------------------------------------*/
/** Default Transmit buffer size.  Holds at most 15 elements */
#ifndef OPTION_APLMT_DEVICE_UARTA_TX_RBUFIZE
#define OPTION_APLMT_DEVICE_UARTA_TX_RBUFIZE    16
#endif

/** Default Receive buffer size.  Holds at most 15 elements */
#ifndef OPTION_APLMT_DEVICE_UARTA_RX_RBUFIZE
#define OPTION_APLMT_DEVICE_UARTA_RX_RBUFIZE    16
#endif


/*-------------- TYPES -----------------------------------------------------*/
/** Data type for the size/index pointers used for the internal Ring buffers.
    Default limits the buffer to a max raw size of 256 and at most 255
    elements.
*/
#ifndef AplmtDevUartABufSize
#define AplmtDevUartABufSize                    Apl8u
#endif 


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method is used to initialize the stream driver and begin receiving
    data.  It does NOT intialize the UART itself, this must be done seperately 
    by the application.  This method must be called before using any of the 
    following methods.
 */
void Aplmt_devUartAStartDriver(void);

/** This method is used to disable and/or turn-off the driver (i.e. stop 
    receiving/transmitting data). When the driver is stop there is no 
    guaranty on what happens to the data currently stored in the Rx and 
    Tx buffers.  The driver can be restarted.
 */
void Aplmt_devUartAStopDriver(void);

/** This method transmits the specified byte.  The call will block if the 
    transmit buffer is full.  Once the character has been inserted in the 
    TX buffer the call returns.  This method returns the byte transmitted
    if successful, else -1 if there is a device error.
    NOTES:  
        o Just because the method returns does NOT mean that the data
          has been physically transmitted, just that it is in the Tx 
          outbound queue.
        o This method returns a signed int in an attempt to be compatible
          with the C stdlib function: putchar().
 */
Apl16 Aplmt_devUartATransmitByte( AplByte data );

/** This method transmits 'numBytes' pointed to by 'buffer'.  The call will
    block until all bytes have been inserted in to the transmit buffer.
    This method returns true on if successful, else false if there is device 
    error.
    NOTES:  
        o Just because the method returns does NOT mean that the data
          has been physically transmitted, just that it is in the Tx 
          outbound queue.
 */
AplBool Aplmt_devUartATransmitBuffer( void* buffer, AplmtDevUartABufSize numBytes );
                                                  
/** This method blocks until there is a byte available in the UART receive
    buffer.  The methods returns the received character or -1 if there 
    is a device error.
    NOTES:  
        o This method does NO translation on the incoming data.
        o This method returns a signed int in an attempt to be compatible
          with the C stdlib function: getchar().
 */
Apl16 Aplmt_devUartAGetByte(void);

/** This method blocks until there is one or more bytes of data available.
    The receive data is copied into 'buffer' for at most 'maxBytes'.  The
    method returns the number of bytes copied (non-zero) or 0 if there 
    is device error.
    NOTES:  
        o The number of bytes copied into the buffer can be less than
          specified 'maxBytes'.  However, there will always be at least
          one byte copied (assuming no errors).
        o If 'maxBytes' is zero, then the method will return 0 BUT no
          error occurred.
 */
AplmtDevUartABufSize Aplmt_devUartAGetBuffer( void* destBuffer, AplmtDevUartABufSize maxBytes );

/** This method is a NON-blocking call that returns the number of bytes 
    currently in the the receive buffer.  If the buffer is empty, zero is 
    returned. If an error occurred then -1 is returned.
    NOTES:
        o Error Return code: The data type AplmtDevUartABufSize is
          typically unsigned. So when an error occurs, the max possible
          value for the AplmtDevUartABufSize is returned (aka -1).  Since
          the max number of elements is always OPTION_APLMT_DEVICE_UARTA_RX_RBUFIZE -1,
          there is NO CONFLICT with the error return code and the range of
          possible number of bytes available.
 */
AplmtDevUartABufSize Aplmt_devUartADataAvailable(void);
  

#ifdef __cplusplus
}
#endif
/*--------------------------------------------------------------------------*/
#endif  /* end _aplmt_devices_serial_stream_uartaapi_h_ */

