/**
 * @file        commserial.h
 * @brief       Diagnose serial line communication driver
 */

/* Define to prevent recursive inclusion **************************************/
#ifndef COMMSERIAL_H_
#define COMMSERIAL_H_

#ifdef __cplusplus
extern "C" {
#endif

/* Includes *******************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "main.h"
#include "stm32f4xx_hal.h"
extern UART_HandleTypeDef huart2;

/* Defines ********************************************************************/
#define COMMSERIAL_UART             (&huart2)
#define COMMSERIAL_DMA              (&hdma_usart2_rx)
#define COMMSERIAL_FLAG_RX          1
#define COMMSERIAL_FLAG_ERR         4

#define COMMSERIAL_STX              0x02
#define COMMSERIAL_LEN_MAX          256
#define COMMSERIAL_LEN_FRAME_OFFSET 2   /* Offset between length of the full frame and value of the length byte */
#define COMMSERIAL_LEN_HEADER       3   /* Header length */
#define COMMSERIAL_LEN_CHECKSUM     1   /* Length of header bytes included in length */
#define COMMSERIAL_LEN_NONDATA      (COMMSERIAL_LEN_HEADER + COMMSERIAL_LEN_CHECKSUM)   /* HEADER_OVERLAP + cs length */

/* Types **********************************************************************/
/**
 * @brief   Structure of the message.
 */
#pragma pack(1)
typedef struct{
    uint8_t Command;        /*!< Ccommand */
    uint8_t DataLength;     /*!< Length of the data */
    uint8_t Valid;          /*!< Validity */
    uint8_t Data[COMMSERIAL_LEN_MAX];
}commserial_msg_t;
#pragma pack()

/* Public functions ***********************************************************/
/**
 * @brief   COMMSeriald_Init()
 *          Initializes the comm serial line driver.
 *
 * @return  None
 */
void COMMSeriald_Init(void);

/**
 * @brief   COMMSeriald_Read()
 *          This function must be called from the DMA transfer complete callback
 *          when new communication data arrives.
 *
 * @return  None
 */
void COMMSeriald_Read(void);

/**
 * @brief   COMMSeriald_Error()
 *          This function must be called from the DMA error callback. It cleans
 *          the buffers and restarts the DMA reading from the UART line.
 *
 * @return  None
 */
void COMMSeriald_Error(void);

/**
 * @brief   COMMSeriald_LoadMsg()
 *          Function loads the incoming message to the provided parameter.
 *
 * @param   [out]   msg     Pointer to message structure.
 *
 * @retval  1 - new message loaded
 * @retval  0 - no new message loaded
 * @return  Validity of the message.
 */
uint8_t COMMSeriald_LoadMsg(commserial_msg_t* msg);

/**
 * @brief   COMMSeriald_SendMsg()
 *          This function should be called after commnostics are done to send
 *          response to PC.
 *
 * @param   [in]    msg     Pointer to message structure.
 *
 * @return  None
 */
void COMMSeriald_SendMsg(commserial_msg_t* msg);

/**
 * @brief   COMMSerial_RaiseFlag()
 *          This function switches on selected flag when specified event
 *          occurs. See COMMSERIAL_FLAG_RX and COMMSERIAL_FLAG_ERR. This function must
 *          be called in the UsartRX callback with COMMSERIAL_FLAG_RX argument. The
 *          main communication logic is done in COMMSeriald_GetStatus function.
 *
 * @param   [in]    flag    Flag definition to raise.
 *
 * @return  None
 */
void COMMSeriald_RaiseFlag(uint16_t flag);

#ifdef __cplusplus
}
#endif

#endif /* COMMSERIAL_H_ */
