/**
*******************************************************************************
* @file modbus.h
* @brief Главный заголовочный файл Modbus библиотеки
*******************************************************************************
@addtogroup MODBUS Modbus tools
@brief Библиотека реализующая протокол Modbus
*******************************************************************************
@addtogroup MODBUS_FUNCTIONS Main API for Modbus Library
@ingroup    MODBUS
@brief Публичные функции библиотеки
@{
*******************************************************************************
* @details
Объединяющий файл для подключения всей функциональности Modbus.
Подключает все необходимые модули:


@section Start Инструкция по подключению
Для корректной работы надо:
- Подключить обработчики RS_UART_Handler(), RS_TIM_Handler(), в соответствубщие 
  низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler вместо HAL'овского обработчика
 
- В modbus_config.h настроить дефайны для нужной работы UART

- Инициализировать хендл мобдас. По умолчанию глобально создается hmodbus1
- После для запуска Modbus:
  @code
  //----------------Слейв модбас----------------//
  #include "modbus.h"

  MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
  MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
  MODBUS_SlaveStart(&hmodbus1, NULL);
  @endcode
  @code
  //----------------Мастер модбас----------------//
  #include "modbus.h"

  MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
  MODBUS_Config(&hmodbus1, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER);
  // Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
  RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
  MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
  
  void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg) 
  {
    // MB_RespGet_... Чтобы достать нужные данные из ответа
    if(hmodbus->RS_STATUS == RS_OK)
    {
      for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
      {
        uint16_t value;
        if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
        {
          read_hold[i] = value;
        }
      }
    }
  }
  @endcode


@section modules Подключаемые модули:
- rs_message.h - работа с uart
- modbus_core.h - базовые определения
- modbus_coils.h - работа с дискретными выходами
- modbus_holdregs.h - работа с регистрами хранения  
- modbus_inputregs.h - работа с входными регистрами
- modbus_devid.h - идентификация устройства
- modbus_diag.h - диагностика modbus


@section data Структура данных Modbus

#### Holding/Input Registers:
- Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.  
Таким образом, сами регистры могут представлять собой как массив так и структуру.

#### Coils:
- Coils — это биты, упакованные в 16-битные слова. Доступ к коилам осуществляется через указатель.  
Таким образом, сами коилы могут представлять собой как массив так и структуру.

******************************************************************************/
#ifndef __MODBUS_H_
#define __MODBUS_H_
 
#include "rs_message.h"
#ifdef MODBUS_ENABLE_MASTER
#include "modbus_master.h"
#endif
#ifdef MODBUS_ENABLE_SLAVE
#include "modbus_slave.h"
#endif
#ifdef MODBUS_ENABLE_COILS
#include "modbus_coils.h"
#endif
#ifdef MODBUS_ENABLE_HOLDINGS
#include "modbus_holdregs.h"
#endif
#ifdef MODBUS_ENABLE_INPUTS
#include "modbus_inputregs.h"
#endif
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
#include "modbus_devid.h"
#endif
#ifdef MODBUS_ENABLE_DIAGNOSTICS
#include "modbus_diag.h"
#endif

  
#ifdef MODBUS_ENABLE_MASTER
#define MODBUS_MODE_MASTER 1  ///< Псевдо-enum: Режим мастер
#endif

#ifdef MODBUS_ENABLE_SLAVE
#define MODBUS_MODE_SLAVE 0   ///< Псевдо-enum: Режим слейв
#endif

/////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---/////////////////////////////

  
//----------------FUNCTIONS FOR USER----------------

/* Инициализация периферии модбас. */
HAL_StatusTypeDef MODBUS_FirstInit(RS_HandleTypeDef *hmodbus, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim);
/* Программная конфигурация модбас. */
HAL_StatusTypeDef MODBUS_Config(RS_HandleTypeDef *hmodbus, uint8_t ID, uint16_t Timeout, uint8_t master);
/* Запуск слейв устройства */
HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg);
/* Реквест мастера модбас */
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*));

  

/////////////////////////---FUNCTIONS---/////////////////////////////

#endif //__MODBUS_H_

/** MODBUS_FUNCTIONS
  * @} 
  */
 