// 2010.6.2 RealSYS KCO
// can.c
#include "common.h"
#include "can.h"

u8 can_rx_flag=0,can_rx_cnt=0;
CanTxMsg TxMessage;
CanRxMsg RxMessage;

void init_can(void){
GPIO_InitTypeDef  GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef  NVIC_InitStructure;
   
    /* GPIOA clocks enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
    
    /* CAN1 Periph clocks enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); 
    
    /* Configure CAN1 RX pin */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    /* Configure CAN1 TX pin */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* CAN register init */
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);
    /* CAN1 cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
    CAN_InitStructure.CAN_Prescaler = 4;
    CAN_Init(CAN1, &CAN_InitStructure);
    /* CAN1 filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
    /* IT Configuration for CAN1 */  
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void can_tx_data_s(u16 id, u8 *data){
u8 i;  
  /* Transmit */
  TxMessage.StdId = id;  // between 0 to 0x7FF
  TxMessage.RTR = CAN_RTR_DATA; // CAN_RTR_DATA or CAN_RTR_REMOTE
  TxMessage.IDE = CAN_ID_STD;   // CAN_ID_EXT or CAN_ID_EXT;
  TxMessage.DLC = 8;
  for(i=0;i<8;i++) TxMessage.Data[i] = data[i];
  CAN_Transmit(CAN1, &TxMessage);
}

void can_tx_data_e(u32 id, u8 *data){
u8 i;  
  /* Transmit */
  TxMessage.ExtId = id; // between 0 to 0x1FFFFFFF
  TxMessage.RTR = CAN_RTR_DATA; // CAN_RTR_DATA or CAN_RTR_REMOTE
  TxMessage.IDE = CAN_ID_EXT;   // CAN_ID_EXT or CAN_ID_EXT;
  TxMessage.DLC = 8;
  for(i=0;i<8;i++) TxMessage.Data[i] = data[i];
  CAN_Transmit(CAN1, &TxMessage);
}

void clear_can_rx_message(CanRxMsg *RxMessage){
u8 i = 0;
  RxMessage->StdId = 0x00;
  RxMessage->ExtId = 0x00;
  RxMessage->IDE = CAN_ID_STD;
  RxMessage->DLC = 0;
  RxMessage->FMI = 0;
  for (i = 0; i < 8; i++){
    RxMessage->Data[i] = 0x00;
  }
}

void USB_LP_CAN1_RX0_IRQHandler(void){
    can_rx_cnt++;
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
    can_rx_flag = 1;
}