/****************************************************************************/
/* Copyright 2009 - 2015 MBARI                                              */
/****************************************************************************/
/* Summary  : Definitions for Serial Port module for OASIS5 Expander Board  */
/* Filename : serial.h                                                      */
/* Author   : Mike Risi (mrisi), Robert Herlien (rah)                       */
/* Project  : OASIS Mooring Replacement (OASIS5)                            */
/* Revision: 1.0                                                            */
/* Created  : 2009 by Mike Risi, Adapted for Oasis5 10/29/2015 by Bob Herlien*/
/*                                                                          */
/* MBARI provides this documentation and code "as is", with no warranty,    */
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium  */
/* Research Institute to assist in its use, correction, modification, or    */
/* enhancement. This information should not be published or distributed to  */
/* third parties without specific written permission from MBARI.            */
/*                                                                          */
/****************************************************************************/
/* Modification History:                                                    */
/* 29oct2015 rah - adapted from Respirometer chamber controller             */
/****************************************************************************/

#ifndef SERIAL_H
#define SERIAL_H

#include <Generic.h>
#include "sys_timer.h"

#define NumberOf(arr)       ((sizeof(arr) / sizeof(arr[0])))

#define RX_BUFF_SIZE    2048
#ifdef O5_DB
#define TX_BUFF_SIZE   256
#else
#define TX_BUFF_SIZE   512
#endif

#if defined(O5_DB) && !defined(O5_DB_DBG)
#define SER_PORT_TOTAL 6
#else
#define SER_PORT_TOTAL 5
#endif

#define SER_PORT_0     0
#define SER_PORT_1     1
#define SER_PORT_2     2
#define SER_PORT_3     3
#define SER_PORT_4     4

#if SER_PORT_TOTAL > 5
#define SER_PORT_5     5
#endif

#define CFG_SERPORT    0

#define FastBRG(baud)   ((PBCLK/(4*baud)) - 1)
#define StdBRG(baud)    ((PBCLK/(16*baud)) - 1)

#define STD_BAUD        9600L
#define UxMODE          0x8800
#define UxSTA           0x1400


/* data/parity settings */
#define D8_NONE         0
#define D8_EVEN         1
#define D8_ODD          2
#define D9_NONE         3

/* stop bits */
#define S_1             1
#define S_2             2

/* Error flag defines */
#define OVERFLOW_ERR    0x01

#define OVERRUN_ERR     0x02
#define FRAMING_ERR     0x04
#define PARITY_ERR      0x08
/* note: ERR_FLAG_MASK is for overrun, framing, and partiy 
only, it is used to mask off those bits in UxSTA register */
#define ERR_FLAG_MASK   0x0E


/********************************/
/*    Macros                    */
/********************************/

#define isSerPortValid(port)  ((port >= SER_PORT_0) && (port < SER_PORT_TOTAL))


/********************************/
/*  Function Prototypes         */
/********************************/

void serInit(); 

void serSetBaud(int port, unsigned long baud);
unsigned long serGetBaud(int port);
void serSetConfig(int port, int data_par, int stop);
void serGetConfig(int port, int* data_par, int* stop);

int serGetByte(int port, BYTE* b);
int serPutByte(int port, BYTE b);
int serPutString(int port, char* buff);
int serPutStringBool(int port, char* buff, int onoff);

void serRxFlush(int port);
void serTxFlush(int port);

void serSetBreak(int port, int state);
int serGetBreak(int port);

int serIsRxFull(int port);
int serIsTxFull(int port);
int serIsTxEmpty(int port);
int serRxAvailable(int port);

#define	SER_RX_IDLE_TICKS	(TICKS_PER_SEC/10)
int serRxIsIdle(void);

int serGetErrFlag(int port);

void serClrXERR(int port);
int serGetXERR(int port);

void serClrOERR(int port);
int serGetOERR(int port);

void serClrFERR(int port);
int serGetFERR(int port);

void serClrPERR(int port);
int serGetPERR(int port);

/* serial port xcvr */
void serXcvrSet(int port, int state);
int serXcvrGet(int port);

/* Separated out Modbus stack critical section (port/portserial.c:EnterCriticalSection) */
/* which only sets CPU priority to 4 to mask interrupt levels 0-4, from application-level*/
/* critical section which turns off all interrupts                                      */
void EnterAppCriticalSection(void);
void ExitAppCriticalSection(void);

#endif

