#ifndef CANFORM_H
#define CANFORM_H

#include "main.h"
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "canConfig.h"


typedef union {
  uint16_t all;
  struct
  {
    unsigned FF_SRS       : 1;  // Ошибка SRS бит (extended frame)
    unsigned FF_IDE       : 1;  // Ошибка IDE бит
    unsigned FF_RTR       : 1;  // Ошибка RTR бит
    unsigned FF_R1        : 1;  // Ошибка r1 бит (reserved)
    unsigned FF_R0        : 1;  // Ошибка r0 бит (reserved)
    unsigned MSGID        : 1;  // Ошибка битов ID
    unsigned DATA         : 1;  // Ошибка битов данных
    unsigned CRC_ERR      : 1;  // Ошибка битов CRC
    unsigned STUFF_BITS   : 1;  // Ошибка бит-стаффинга (пропуск вставки stuff bits)
    unsigned reserved     : 7;  // Зарезервировано
  }bit;
} CAN_ErrorFlags_t;

#ifndef IS_FUNCTIONAL_STATE
typedef enum 
{
  DISABLE = 0, 
  ENABLE = !DISABLE
} FunctionalState;
#endif
#ifndef HAL_CAN_MODULE_ENABLED
/**
  * @brief  CAN Tx message header structure definition
  */
typedef struct
{
  uint32_t StdId;    /*!< Specifies the standard identifier.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */

  uint32_t ExtId;    /*!< Specifies the extended identifier.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */

  uint32_t IDE;      /*!< Specifies the type of identifier for the message that will be transmitted.
                          This parameter can be a value of @ref CAN_identifier_type */

  uint32_t RTR;      /*!< Specifies the type of frame for the message that will be transmitted.
                          This parameter can be a value of @ref CAN_remote_transmission_request */

  uint32_t DLC;      /*!< Specifies the length of the frame that will be transmitted.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 8. */

  FunctionalState TransmitGlobalTime; /*!< Specifies whether the timestamp counter value captured on start
                          of frame transmission, is sent in DATA6 and DATA7 replacing pData[6] and pData[7].
                          @note: Time Triggered Communication Mode must be enabled.
                          @note: DLC must be programmed as 8 bytes, in order these 2 bytes are sent.
                          This parameter can be set to ENABLE or DISABLE. */

} CAN_TxHeaderTypeDef;
#endif


#define MAX_BITS 256
extern uint8_t can_bits[MAX_BITS]; // После стаффинга
extern uint32_t can_bits_len;

uint16_t compute_crc15(const uint8_t *bits, uint32_t len);
void form_CAN_bitstream_full(const CAN_TxHeaderTypeDef *header, const uint8_t *data, CAN_ErrorFlags_t errors);

#endif //CANFORM_H