
/// Copyright 2009 MBARI.                                                    
/// MBARI Proprietary Information. All rights reserved.                      

/// @file serial.h
/// @brief read, write, and control UARTs, also contains ISRs

#ifndef SERIAL_H
#define SERIAL_H
#include "pic24.h"
#include "cwgsys.h"

/// Length of Msg_Buff
// printing strings longer than this can cause 
// undefined behavior 
#define SER_PRINTF_BUFFER_BYTES 512 //128
/// set true if characters arrive

#define SER_RX(mask) ( (g_rx_flag&mask) ? true :false )
#define SER_RX_CLR(mask) CLR_FLAGS(g_rx_flag,mask)
#define SER_RX_CONS  0x01
#define SER_RX_HOST  0x02
#define SER_RX_LICOR 0x04
#define SER_RX_ANY   0x07

typedef serial_port_t SerPort;

/// Buffer used for serprintf() and CLI output
extern char *g_msg_buffer;
extern volatile uint16_t g_rx_flag;

/// @brief Set up UARTS

void serInit();

/// @brief Set a port baud rate
/// @param port Serial port to change
/// @param baud New baud rate
/// @return ERROR_OK if it worked

int serSetBaud(SerPort port, UINT32 baud);
/// @brief Get one byte from port
/// @param port serial port to get from
/// @return byte or '\0'
byte serGetChar(serial_port_t port);

/// @brief Get one byte from port
/// @param port serial port to get from
/// @param [out] b pointer to char to fill
/// @return true if byte found, else false and @p *b = '\0'

int serGetByte(SerPort port, unsigned char* b);

/// @brief See next byte from port's software buffer, leaves it there
/// @param port port to read from
/// @return  next byte in buffer or 0 if empty (ambiguous with real '\0')

unsigned char serPeek(SerPort port, unsigned char *b);

/// @brief get bytes from a port for some interval
/// @param port Port to read from
/// @param [out] buffer Buffer to place string
/// @param buflen Maximum number of bytes to read
/// @param period Number of milliseconds to keep looking for bytes
/// @return Number of bytes read.

int serGetSTO(SerPort port, char* buffer, int buflen, UINT32 period);

/// @brief get bytes from a port until string is matched
/// @param port Port to read from
/// @param ends String to match
/// @param [out] buffer Buffer to place string
/// @param buflen Maximum number of bytes to read
/// @return Number of bytes read.

int serGetUntil(SerPort port, const char* ends, char* buffer, int buflen);
/// @brief get bytes from a port until string is matched
/// @param port Port to read from
/// @param ends String to match
/// @param [out] buffer Buffer to place string
/// @param buflen Maximum number of bytes to read
/// @param tmout_ms timeout, msec
/// @return Number of bytes read.

int serGetUntilTO(SerPort port, const char* ends, char* buffer, int buflen, UINT32 tmout_ms, bool keep);

/// @brief throw out bytes until target or terminator
/// @param port Port to look at
/// @param targ Target string to match
/// @param term Terminating String
/// @return TRUE if target is found, else FALSE

int serScanUntil(SerPort port, char* targ, const char* term);

/// @brief throw out bytes until target or timeout
/// @param port Port to look at
/// @param targ Target string to match
/// @param period Timeout interval
/// @return TRUE if target is found, else FALSE

int serScanTO(SerPort port, char* targ, UINT32 period);

/// @brief put a byte in SW buffer and begin transmission
/// @param port Port to use
/// @param b Byte to write
/// @return TRUE if successful, else FALSE

int serPutChar(SerPort port, char b);

/// @brief output a formated string 
/// @param port Port to use
/// @param format printf() style string 
/// @return Number of bytes written

int serPrintf(SerPort port, const char* format, ...);

/// @brief output a string to serial port
/// @param port Port to use
/// @param buff String to send
/// @return Number of bytes written

int serPutString(SerPort port, char* buff);
int serPutPrettyString(SerPort port, char* buff, byte *flag);

/// @brief output to console if TERSE is not set
/// @param buff String to output
/// @return ERR_SUCCESS or TERSE value

int serDebugS(char* buff);

/// @brief output formated string if TERSE is not set
/// @param format printf() style string
/// @return number of bytes written (0 if TERSE)

int serDebugf(const char* format, ...);

/// @brief Put a byte in TX hardware buffer
/// @param port Port use
/// @param b byte to write
/// @return TRUE if successful, FALSE if buffer full

int serSetByte(SerPort port, BYTE b);

/// @brief are bytes available to be read in Rx SW buffer
/// @param port Port to look at
/// @return number of bytes in buffer

int serIsAvail(SerPort port);

/// @brief check if Rx software buffer is full
/// @param port Port to look at
/// @return TRUE if buffer is full

int serIsRxFull(SerPort port);

/// @brief check if Tx hardware buffer is full
/// @param port Port to look at
/// @return TRUE if buffer is full

int serIsTxFull(SerPort port);

/// @brief check if Rx overflow flag was set
/// @param port Port to look at
/// @return TRUE if buffer filled up

int serGetRxOverFlow(SerPort port);

/// @brief clear Rx overflow flag
/// @param port Port to use

void serClrRxOverFlow(SerPort port);

/// @brief clear out Rx SW buffer
/// @param port Port to use

void serRxFlush(SerPort port);

/// @brief clear out Tx buffer
/// @param port Port to use

void serTxFlush(SerPort port);

/// @brief wait until port's transmission is finished
/// @param port Port to wait on

void serTxWait(SerPort port);
#endif