#include "canWorking.h"

CANEmu_HandleTypeDef hcanemu;
uint32_t mbox;

int disable_poll_timeout = 1000;
int flag_manual = 0;
int transmit_prev = 0;

void CAN_Init(CANEmu_HandleTypeDef *canemu)
{
#ifdef CAN_ONLY_EMULATING
  if(canemu->EmuFlag == 0)
  {
    CANEmu_Init(canemu, canemu->bitrate_bps);
  }
#else
  if(canemu->errors.all && (canemu->EmuFlag == 0))
  {
    CANEmu_Init(canemu, canemu->bitrate_bps);
  }
  else if ((canemu->errors.all == 0) && canemu->EmuFlag)
  {    
    canemu->EmuFlag = 0;
    HAL_CAN_MspInit(&hcan);
  }
#endif
}

void CAN_SendFrame(CANEmu_HandleTypeDef *canemu)
{
#ifdef CAN_ONLY_EMULATING
  CANEmu_SendFrame(canemu);
#else
  if(canemu->EmuFlag)
    CANEmu_SendFrame(canemu);
  else
    HAL_CAN_AddTxMessage(&hcan, &canemu->header, canemu->data, &mbox);
#endif
}

void CANEmu_Working(CANEmu_HandleTypeDef *canemu)
{
  uint32_t tick_now = HAL_GetTick();
  
  if(flag_manual == 0)
  {
    if(tick_now - hmodbus1.lastRxTick > disable_poll_timeout)
      MB_DATA.Coils.START_POLLING = 0;
    canemu->start_poll          = MB_DATA.Coils.START_POLLING;
    
    canemu->transmit            = MB_DATA.Coils.START_SINGLE_FRAME;
    canemu->period_ms           = MB_DATA.HoldRegs.CAN_PERIOD;
    if(canemu->period_ms < CAN_MIN_PERIOD)
    {
      canemu->period_ms = CAN_MIN_PERIOD;
    }
    // can message
    canemu->header.IDE    = MB_DATA.Coils.HEADER_IDE;
    canemu->header.RTR    = MB_DATA.Coils.HEADER_RTR;      
    canemu->bitrate_bps   = (uint32_t)MB_DATA.HoldRegs.CAN_BITRATE_KBPS*1000;
    canemu->header.ExtId  = ((uint32_t)MB_DATA.HoldRegs.CAN_ID_HI << 16) | MB_DATA.HoldRegs.CAN_ID_LO;
    canemu->header.StdId  = canemu->header.ExtId;
    canemu->header.DLC    = (uint8_t)MB_DATA.HoldRegs.CAN_DLC & 0xF;
    canemu->data[0]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_0;
    canemu->data[1]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_1;
    canemu->data[2]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_2;
    canemu->data[3]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_3;
    canemu->data[4]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_4;
    canemu->data[5]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_5;
    canemu->data[6]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_6;
    canemu->data[7]       = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_7;
    
    // errors
    canemu->errors.bit.FF_SRS       = MB_DATA.Coils.FLIP_SRS;
    canemu->errors.bit.FF_IDE       = MB_DATA.Coils.FLIP_IDE;
    canemu->errors.bit.FF_RTR       = MB_DATA.Coils.FLIP_RTR;
    canemu->errors.bit.FF_R1        = MB_DATA.Coils.FLIP_R1;
    canemu->errors.bit.FF_R0        = MB_DATA.Coils.FLIP_R0;
    canemu->errors.bit.MSGID        = MB_DATA.Coils.FLIP_MSGID_BIT;
    canemu->errors.bit.DATA         = MB_DATA.Coils.FLIP_DATA_BIT;
    canemu->errors.bit.CRC_ERR      = MB_DATA.Coils.FLIP_CRC_BIT;
    canemu->errors.bit.STUFF_BITS   = MB_DATA.Coils.DISABLE_STUFF_BITS;
    
  }
    
    
  CAN_Init(canemu);
  if(canemu->start_poll)
  {
    canemu->transmit = 0;
    HAL_Delay(canemu->period_ms);
    CAN_SendFrame(canemu);
  }
  else if((canemu->transmit == 1) && (transmit_prev == 0))
  {
    CAN_SendFrame(canemu);
  }
  transmit_prev = canemu->transmit;
}
