/*******************************************************************************
* the includes
******************************************************************************/
#include "CanDrv.h"
#include <stdio.h>
#include "Uart2CanDiagApp.h"
#include <string.h>
#include "CherryRB/chry_ringbuffer.h"

/*******************************************************************************
* the defines
******************************************************************************/
#define TEST_ID 0x222


/*******************************************************************************
* the typedefs
******************************************************************************/


/*******************************************************************************
* the globals
******************************************************************************/
extern CAN_HandleTypeDef hcan1;
static CAN_TxHeaderTypeDef txhead;
static uint32_t TxMailbox = CAN_TX_MAILBOX0;
static uint16_t respID = 0,phyID = 0;

static chry_ringbuffer_t rb;
static uint8_t mempool[64];
static uint8_t FlagRbErr,FlagGetFC;
/*******************************************************************************
* the const
******************************************************************************/



/*******************************************************************************
* the functions
******************************************************************************/



uint8_t CanDrv_Init(void)
{
    txhead.StdId = TEST_ID;
    txhead.IDE = CAN_ID_STD;
    txhead.RTR = CAN_RTR_DATA;
    txhead.TransmitGlobalTime = DISABLE;
    txhead.DLC = 8;
    HAL_CAN_Start(&hcan1);
    CanDrv_SetFilter(0x777,0);//for test
    HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

    if(0 != chry_ringbuffer_init(&rb, mempool, 64))
    {
        printf("err:can rb init\n");
    }
    return 0;
}

uint8_t CanDrv_Txmsg(uint16_t id,uint8_t * data)
{
    txhead.StdId = id;
    HAL_StatusTypeDef ret = HAL_CAN_AddTxMessage(&hcan1,&txhead,data,&TxMailbox);
    //printf("ret=%d",ret);
    return ret;
}

uint8_t txtestdata[8] = {1,2,3,4,5,6,7,8};
void CanDrv_Test()
{
    CanDrv_Txmsg(TEST_ID,txtestdata);
}

uint8_t CanDrv_GetCANTxEmpty(void)
{
    uint32_t ret = HAL_CAN_IsTxMessagePending(&hcan1,CAN_TX_MAILBOX0|CAN_TX_MAILBOX1|CAN_TX_MAILBOX2);
    if (ret == 0)
    {   //空闲
        return 1;
    }
    return 0;
}

//中断函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef rxmsg;
    uint8_t data[8];
    HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&rxmsg,data);
    if (rxmsg.StdId >= 0x600)
    {
        //printf("get id:0x%03x",rxmsg.StdId);
        if (respID == rxmsg.StdId)
        {
            uint32_t len = chry_ringbuffer_write(&rb, data, 8);
            if (len != 8)
            {
                FlagRbErr = 1;
                printf("err:ring buf write\n");
            }
            
        }
        
    }
    
    
}

uint8_t CanDrv_SetFilter(uint16_t id,uint8_t bank)
{
    CAN_FilterTypeDef filter;
    filter.FilterMode = CAN_FILTERMODE_IDMASK;
    filter.FilterIdHigh = id << 5;         // 注意：标准 ID 要左移 5 位
    filter.FilterMaskIdHigh = 0x7FF << 5;
    filter.FilterFIFOAssignment = CAN_RX_FIFO0;
    filter.FilterBank = bank;

    filter.FilterScale = CAN_FILTERSCALE_32BIT;
    filter.FilterActivation = CAN_FILTER_ENABLE;


    HAL_CAN_ConfigFilter(&hcan1,&filter);
    return 0;
}

void CanDrv_SetDiagID(uint16_t pid,uint16_t rid)
{
    CanDrv_SetFilter(rid,1);
    respID = rid;
    phyID = pid;
}



uint8_t CanDrv_isGetFC(void)
{
    uint8_t ret = 0;
    ret = FlagGetFC;
    FlagGetFC = 0;
    return ret;
}

void CanDrv_MsgRecvTask(void)
{
    uint8_t data[8];
    uint32_t len = chry_ringbuffer_read(&rb, data, 8);
    if (len)
    {
        if (len == 8)
        {
            //缓冲区中有数据
            U2CD_PackDiagMsg(data);
        }
        else
        {
            FlagRbErr = 1;
        }
    }
    
}