/**
************************************************************************************************
* @文件    : can.c
* @作者    : 樊春春
* @版本    : V1.0
* @时间    : 2022/05/30 22:47:14
* @邮箱    : fanchcho@gmail.com
* @说明    : CAN初始化
************************************************************************************************
**/

#include "can.h"
#include "fly_param.h"
#include <string.h>

CanRxMsg can1_recv_msg;
CanRxMsg can2_recv_msg;

CanData_TypeDef CanDataCan1; // CAN1数据
CanData_TypeDef CanDataCan2; // CAN2数据

void can_network_init(void)
{
    CAN_InitTypeDef       can_parameter;
    CAN_FilterInitTypeDef can_filter;

    CAN_StructInit(&can_parameter);
    CAN_FilterInit(&can_filter);

    /* initialize CAN register */
    CAN_DeInit(CAN1);
    CAN_DeInit(CAN2);

    /* initialize CAN parameters */
    can_parameter.CAN_TTCM = DISABLE;
    can_parameter.CAN_ABOM = DISABLE;
    can_parameter.CAN_AWUM = DISABLE;
    can_parameter.CAN_NART = DISABLE;
    can_parameter.CAN_RFLM = DISABLE;
    can_parameter.CAN_TXFP = DISABLE;
    can_parameter.CAN_Mode = CAN_Mode_Normal;
    can_parameter.CAN_SJW  = CAN_SJW_1tq;
    can_parameter.CAN_BS1  = CAN_BS1_10tq; // CAN_BT_BS1_6TQ;
    can_parameter.CAN_BS2  = CAN_BS2_3tq;  // CAN_BT_BS2_4TQ;

    /* 1MBps */
#if CAN_BAUDRATE == 1000
    can_parameter.prescaler = 5;
    /* 500KBps */
#elif CAN_BAUDRATE == 500
    can_parameter.prescaler = 10;
    /* 250KBps */
#elif CAN_BAUDRATE == 250
    can_parameter.CAN_Prescaler = 12; // 24;//20;
                                      /* 125KBps */
#elif CAN_BAUDRATE == 125
    can_parameter.prescaler = 40;
    /* 100KBps */
#elif CAN_BAUDRATE == 100
    can_parameter.prescaler = 50;
    /* 50KBps */
#elif CAN_BAUDRATE == 50
    can_parameter.prescaler = 100;
    /* 20KBps */
#elif CAN_BAUDRATE == 20
    can_parameter.prescaler = 250;
#else
#error "please select list can baudrate in private defines in main.c "
#endif
    /* initialize CAN */
    CAN_Init(CAN1, &can_parameter);
    CAN_Init(CAN2, &can_parameter);

    /* initialize filter */
    can_filter.CAN_FilterNumber         = 0;
    can_filter.CAN_FilterMode           = CAN_FilterMode_IdMask;
    can_filter.CAN_FilterScale          = CAN_FilterScale_32bit;
    can_filter.CAN_FilterIdHigh         = 0x0000;
    can_filter.CAN_FilterIdLow          = 0x0000;
    can_filter.CAN_FilterMaskIdHigh     = 0x0000;
    can_filter.CAN_FilterMaskIdLow      = 0x0000;
    can_filter.CAN_FilterFIFOAssignment = CAN_FIFO0;
    can_filter.CAN_FilterActivation     = ENABLE;

    CAN_FilterInit(&can_filter);

    /* CAN1 filter number */
    can_filter.CAN_FilterNumber         = 15;
    can_filter.CAN_FilterMode           = CAN_FilterMode_IdMask;
    can_filter.CAN_FilterScale          = CAN_FilterScale_32bit;
    can_filter.CAN_FilterIdHigh         = 0x0000;
    can_filter.CAN_FilterIdLow          = 0x0000;
    can_filter.CAN_FilterMaskIdHigh     = 0x0000;
    can_filter.CAN_FilterMaskIdLow      = 0x0000;
    can_filter.CAN_FilterFIFOAssignment = CAN_FIFO0;
    can_filter.CAN_FilterActivation     = ENABLE;

    CAN_FilterInit(&can_filter);

    can_nvic_config();
    /* CAN FIFO0 消息接收中断使能 */
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

    /* CAN FIFO0 消息接收中断使能 */
    CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
}

void can_nvic_config(void)
{
    /* configure CAN0 NVIC */
    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* configure CAN1 NVIC */
    NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_Init(&NVIC_InitStructure);
}

/*!
    \brief      this function handles CAN0 RX0 exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void CAN1_RX0_IRQHandler(void)
{
    /* check the receive message */
    CAN_Receive(CAN1, CAN_FIFO0, &can1_recv_msg);
    if ((can1_recv_msg.IDE == CAN_Id_Extended) && (CAN_MSG_LEN == can1_recv_msg.DLC))
    {
        memcpy(CanDataCan1.buf, can1_recv_msg.Data, CAN_MSG_LEN);
        CanDataCan1.can_id = can1_recv_msg.ExtId;
        InsertQueue(&CanQueueCan1, CanDataCan1);
    }
    OSSemPost(can1_sem);
}

/*!
    \brief      this function handles CAN1 RX0 exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void CAN2_RX0_IRQHandler(void)
{
    /* check the receive message */
    CAN_Receive(CAN1, CAN_FIFO0, &can2_recv_msg);
    if (CAN_MSG_LEN == can2_recv_msg.DLC)
    {
        memcpy(CanDataCan2.buf, can2_recv_msg.Data, CAN_MSG_LEN);
        if (can2_recv_msg.IDE == CAN_Id_Extended)
        {
            CanDataCan2.can_id = can2_recv_msg.ExtId;
        }
        else
        {
            CanDataCan2.can_id = can2_recv_msg.StdId;
        }
        InsertQueue(&CanQueueCan2, CanDataCan2);
    }
    OSSemPost(can2_sem);
}