
/*
 * serial.h
 *
 *  Created on: 4 Jan 2016
 *      Author: Mike
 */

#pragma once 

#include "main.h"


typedef struct
{
	/// @brief UART handle
	UART_HandleTypeDef *Handle;
	/// @brief Locally maintained transmit buffer
	volatile uint8_t tx_usart_buff[TX_USART_BUFF_SIZ];
	volatile unsigned int tx_usart_in_Ptr;
	volatile unsigned int tx_usart_out_Ptr;
	volatile unsigned int tx_usart_overruns; 
	/// @brief Set when the usart is transmitting
	volatile uint8_t tx_usart_running;
	
	/// @brief Locally maintained receive buffer
	volatile uint8_t rx_usart_buff[RX_USART_BUFF_SIZ];
	volatile unsigned int rx_usart_in_Ptr;
	volatile unsigned int rx_usart_out_Ptr;
	/// @brief Set when the receiver buffer is full
	volatile uint8_t rx_usart_buffer_full;
} usart_ctl;

 

#if defined SERIAL_UART1
extern usart_ctl uc1;
#endif
#if defined SERIAL_UART2
extern usart_ctl uc2;
#endif
#if defined SERIAL_UART3
extern usart_ctl uc3;
#endif
#if defined SERIAL_UART4
extern usart_ctl uc4;
#endif
#if defined SERIAL_UART5
extern usart_ctl uc5;
#endif

///@brief  returns the number of characters in the recieve buffer
///@param instance Pointer to usart_ctl structure
///@return Number of characters
extern uint16_t SerialCharsReceived(usart_ctl *instance);

///@brief Get the amount of free space in the transmit buffer.
///@param instance Pointer to usart_ctl structure
///@return Free space at time of checking 
extern uint16_t SerialTransmitSpace(usart_ctl *instance);

/// @brief Return 1 if there are any characters in the receive buffer
/// @param instance Pointer to usart_ctl structure
/// @return 1 if any characters 
extern uint8_t PollSerial(usart_ctl *instance);

/// @brief return the next character in the Serial input buffer
/// This function will wait until a character arrives.
/// Use PollSerial() or SerialCharsReceived() if you want
/// to ensure you do not block here.
/// @param instance Pointer to usart_ctl structure 
/// @return next character 
extern uint8_t GetCharSerial(usart_ctl *instance);

/// @brief Enable the receive interrupt 
/// @param instance 
extern void EnableSerialRxInterrupt(usart_ctl *instance);

/// @brief Send a character
/// @param instance Pointer to usart_ctl structure
/// @param c character to send
extern void PutCharSerial(usart_ctl *instance, uint8_t c);

/// @brief Reset transmit buffer
/// @param instance Pointer to usart_ctl structure
extern void ResetTxBuffer(usart_ctl *instance);

/// @brief Reset receive buffer
/// @param instance Pointer to usart_ctl structure
extern void ResetRxBuffer(usart_ctl *instance);

/// @brief Reset both transmit and receive buffers
/// @param instance Pointer to usart_ctl structure
extern void FlushSerial(usart_ctl *instance);

/// @brief Check if the transmitter buffer is empty
/// @param instance Pointer to usart_ctl structure
/// @return 1 if the buffer is empty
extern uint8_t TxBufferEmpty(usart_ctl *instance);

///@brief  wait until the USART buffer is empty and all characters are sent
/// @param instance Pointer to usart_ctl structure
extern void TxWaitEmpty(usart_ctl *instance);

/// @brief Establish this instance as being in control of a USART
/// @param instance  Pointer to usart_ctl structure
/// @param usart Handle to usart maintained by HAL
extern void init_usart_ctl(usart_ctl *instance,
						   UART_HandleTypeDef *usart);

/// @brief Set the baud rate on this instance
/// @param instance  Pointer to usart_ctl structure
/// @param baud Baud rate in bits per second
extern void setBaud(usart_ctl *instance, uint32_t baud);


/// @brief Interrupt handler generic wrapper 
/// @param instance Pointer to usart_ctl structure
extern void UART_IRQHandler(usart_ctl *instance);
