#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "can.h"
#include "log.h"
#include "can_node.h"

CAN_RxHeaderTypeDef can1RxHeader; // FDCAN1 接收头
uint8_t can1RxData[8];            // FDCAN1 接收数据
int canTransmitErrorCount = 0;

void can_node_init(void)
{
    CAN_FilterTypeDef filter;
    // 设置接收过滤器
    filter.FilterBank = 0;
    filter.FilterMode = CAN_FILTERMODE_IDMASK;
    filter.FilterScale = CAN_FILTERSCALE_32BIT;

    // 全部接收
    filter.FilterIdHigh = 0x0000;
    filter.FilterIdLow = 0x0000;
    filter.FilterMaskIdHigh = 0x0000;
    filter.FilterMaskIdLow = 0x0000;

    filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    filter.FilterActivation = ENABLE;
    if (HAL_CAN_ConfigFilter(&hcan1, &filter) != HAL_OK)
    {
        Error_Handler();
    }

    // 启动 CAN1
    if (HAL_CAN_Start(&hcan1) != HAL_OK)
    {
        Error_Handler();
    }
    // 启动接收
    if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_Delay(5);
    _dbg_printf("CAN1 initialized successfully\r\n");
}

int can_node_transmit(uint32_t canID, uint8_t *TxData)
{
    CAN_TxHeaderTypeDef txHeader;
    uint32_t txMailbox;

    txHeader.StdId = canID;
    txHeader.ExtId = 0;
    txHeader.IDE = CAN_ID_STD;
    txHeader.RTR = CAN_RTR_DATA;
    txHeader.DLC = 8;
    txHeader.TransmitGlobalTime = DISABLE;

    // 等待邮箱空闲
    while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0)
    {
        canTransmitErrorCount ++;
        if(canTransmitErrorCount > 1000)
        {
            _dbg_printf("CAN transmit timeout\r\n");
            canTransmitErrorCount = 0;
            return -1;
        }
    };
    HAL_CAN_AddTxMessage(&hcan1, &txHeader, TxData, &txMailbox);
    return 0;
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1RxHeader, can1RxData);

    if (can1RxHeader.IDE == CAN_ID_STD)
    {
        // 示例：收到 ID = 0x123
        if (can1RxHeader.StdId == 0x123)
        {
            // 处理数据
            // can1RxData[0..can1RxHeader.DLC-1]
        }
    }
}
