/*
 * Modbus_RTU.h
 *
 *  Created on: 8. 3. 2020
 *      Author: Ondrej Vitoslavsky
 */

#ifndef MODBUS_RTU_H_
#define MODBUS_RTU_H_


//sizes and offsets in ADU (application data layer) - address,PDU,CRC
#define MODBUS_ADU_SIZE_MAX     256     //Maximum size of ADU.
#define MODBUS_ADU_SIZE_CRC     2       //Size of CRC field in ADU.
#define MODBUS_ADU_ADDR_OFF     0       //Slave address offset in ADU.
#define MODBUS_ADU_PDU_OFF      1       //PDU offset in ADU.

//sizes and offsets in PDU (application data layer) - function code + data
#define MODBUS_PDU_SIZE_MAX     253 //Maximum size of a PDU.
#define MODBUS_PDU_FUNC_OFF     0   //Offset of function code in PDU.
#define MODBUS_PDU_DATA_OFF     1   //Offset for data in PDU.


typedef enum
{
    STATE_INIT,
    STATE_IDLE,
    STATE_RECEIVE,
    STATE_ERROR,
    STATE_TRANSMIT
} ModbusState;


/**
  * @brief  Starts Modbus RTU protocol.
  * @note   Initializes timers,USART and sets State of FSM to STATE_INIT.
  * @param  none.
  * @retval none
  */
void Modbus_RTU_Start(void);

/**
  * @brief  Sends data using RTU.
  * @note   Sets sending buffer and appends CRC to it.
  * @param  Frame pointer to buffer where modbus PDU starts.
  * @param  Length length of PDU frame, function code + data to send.
  * @retval none
  */
void Modbus_RTU_Send(uint8_t * Frame, uint16_t Length );

/**
  * @brief  Modbus RTU Finite state machine.
  * @note   Should be called from USART_IRQ handler.
  * 		Takes care of receiving and sending bytes using USART.
  * 		Is automatically called by USART TXE and RXNE interrupts.
  * @param  none
  * @retval none
  */
void Modbus_RTU_FSM(void);

/**
  * @brief  Timer 3.5.
  * @note   Should be called from TIM_IRQ handler.
  * 		Function is setting new states in FSM
  * 		depending in which state it expired.
  * @param  none
  * @retval none
  */
void Modbus_RTU_Timer35_Expired(void);

/**
  * @brief  Timer 1.5.
  * @note   Should be called from TIM_IRQ handler.
  * 		Function is setting new states in FSM
  * 		depending in which state it expired.
  * @param  none
  * @retval none
  */
void Modbus_RTU_Timer15_Expired(void);

#endif /* MODBUS_RTU_H_ */
