/** * @file CAN_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2026 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief functions of can process for C platform * * @version * - 1_00_260116 > ATY * -# Preliminary version ******************************************************************************** */ #ifndef __CAN_ATY_C #define __CAN_ATY_C #include "CAN_ATY.h" #include "string.h" /******************************* For user *************************************/ /******************************************************************************/ void CAN_RegRW(struct CAN_ATY_Dev* dev, uint32_t frameId, uint8_t cmd, uint8_t regAddr, float value){ uint8_t txData[8] = {0}; txData[0] = cmd; txData[1] = regAddr; memcpy(&txData[2], &value, 4); txData[6] = 0; txData[7] = 0; dev->addTxMessage(frameId, txData, 8); } void CAN_Response(struct CAN_ATY_Dev* dev, uint8_t cmd, uint8_t regAddr, float value, uint8_t error){ uint8_t txData[8] = {0}; txData[0] = cmd; txData[1] = regAddr; memcpy(&txData[2], &value, 4); txData[6] = 0; txData[7] = error; dev->addTxMessage(CAN_STD_ID_RESPONSE + dev->addr, txData, 8); } void CAN_FaultReport(struct CAN_ATY_Dev* dev, uint8_t faultCode, uint8_t severity, float faultValue){ uint8_t txData[8] = {0}; txData[0] = faultCode; txData[1] = severity; memcpy(&txData[2], &faultValue, 4); txData[6] = 0; txData[7] = 0; dev->addTxMessage(CAN_STD_ID_FAULT + dev->addr, txData, 8); } void CAN_RX_Callback(struct CAN_ATY_Dev* dev, uint32_t stdId, float* data, uint8_t* rxData){ uint8_t cmd = rxData[0]; uint8_t regAddr = rxData[1]; if(stdId == CAN_STD_ID_BROADCAST || stdId == (CAN_STD_ID_MULTICAST + dev->groupId)){ memcpy(&data[regAddr], &rxData[2], 4); } else if(stdId == (CAN_STD_ID_P2P + dev->addr)){ switch(cmd){ case CAN_CMD_READ: CAN_Response(dev, cmd, regAddr, data[regAddr], CAN_ERR_NONE); break; case CAN_CMD_WRITE: memcpy(&data[regAddr], &rxData[2], 4); CAN_Response(dev, cmd, regAddr, data[regAddr], CAN_ERR_NONE); break; default: CAN_Response(dev, cmd, regAddr, data[regAddr], CAN_ERR_CMD); break; } } else if(stdId == (CAN_STD_ID_RESPONSE + dev->addr)){ } else if(stdId == CAN_STD_ID_FAULT + dev->addr){ } } #endif /* __CAN_ATY_C */ /************************************ etc *************************************/ /* init // CAN ------------------------------------------------------------------------- #include "CAN_ATY.h" uint8_t CAN1_FilterConfig(uint8_t bankId){ CAN_FilterTypeDef sFilterConfig; if(bankId > 14){ sFilterConfig.FilterBank = CAN_FILTER_BROADCAST; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 0; if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) return 9; } if(bankId == 0 || bankId == CAN_FILTER_BROADCAST){ sFilterConfig.FilterBank = CAN_FILTER_BROADCAST; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = ((CAN_STD_ID_BROADCAST << 21) >> 16); sFilterConfig.FilterIdLow = (CAN_STD_ID_BROADCAST << 21) & 0xFFFF; sFilterConfig.FilterMaskIdHigh = 0xFFFF; sFilterConfig.FilterMaskIdLow = 0xFFFF; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 0; if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) return 1; } if(bankId == 0 || bankId == CAN_FILTER_MULTICAST){ sFilterConfig.FilterBank = CAN_FILTER_MULTICAST; sFilterConfig.FilterIdHigh = (((CAN_STD_ID_MULTICAST + (uint8_t)RGF_SYS_GROUP_ID) << 21) >> 16); sFilterConfig.FilterIdLow = ((CAN_STD_ID_MULTICAST + (uint8_t)RGF_SYS_GROUP_ID) << 21) & 0xFFFF; sFilterConfig.FilterMaskIdHigh = 0xFFFF; sFilterConfig.FilterMaskIdLow = 0xFFFF; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1; sFilterConfig.FilterActivation = ENABLE; if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) return 2; } if(bankId == 0 || bankId == CAN_FILTER_P2P){ sFilterConfig.FilterBank = CAN_FILTER_P2P; sFilterConfig.FilterIdHigh = (((CAN_STD_ID_P2P + (uint8_t)RGF_SYS_ADDR) << 21) >> 16); sFilterConfig.FilterIdLow = ((CAN_STD_ID_P2P + (uint8_t)RGF_SYS_ADDR) << 21) & 0xFFFF; sFilterConfig.FilterMaskIdHigh = 0xFFFF; sFilterConfig.FilterMaskIdLow = 0xFFFF; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1; sFilterConfig.FilterActivation = ENABLE; if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) return 3; } return 0; } uint8_t CAN1_InitConfigStart(void){ uint8_t err = 0; err = CAN1_FilterConfig(0); if(err != 0) return err; if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) err = 10; if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK) err = 11; if(HAL_CAN_Start(&hcan) != HAL_OK) err = 12; return err; } uint8_t CAN1_AddTxMessage(uint32_t stdId, uint8_t* data, uint8_t len){ CAN_TxHeaderTypeDef txHeader; uint32_t mailBox; txHeader.StdId = stdId; txHeader.IDE = CAN_ID_STD; txHeader.RTR = CAN_RTR_DATA; txHeader.DLC = len; txHeader.TransmitGlobalTime = DISABLE; HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &mailBox); return 0; } struct CAN_ATY_Dev CAN_ATY_Dev_1 = { .addTxMessage = CAN1_AddTxMessage, .addr = 0, .groupId = 0, .lock = __ATY_UNLOCKED }; void CAN1_UpdateFilter(uint8_t addr, uint8_t groupId){ if(CAN_ATY_Dev_1.addr != addr){ CAN_ATY_Dev_1.addr = addr; CAN1_FilterConfig(0); } if(CAN_ATY_Dev_1.groupId != groupId){ CAN_ATY_Dev_1.groupId = groupId; CAN1_FilterConfig(CAN_FILTER_MULTICAST); } } void CAN1_RxProcess(CAN_HandleTypeDef* hcan_t, uint32_t RxFifo){ CAN_RxHeaderTypeDef rxHeader; uint8_t rxData[8] = {0}; if(HAL_CAN_GetRxMessage(hcan_t, RxFifo, &rxHeader, rxData) != HAL_OK){ return; } if(rxHeader.IDE != CAN_ID_STD || rxHeader.DLC < 2 || rxHeader.DLC < 6){ return; } CAN_RX_Callback(&CAN_ATY_Dev_1, rxHeader.StdId, rgf, rxData); } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* hcan_t){ if(hcan_t == &hcan){ CAN1_RxProcess(hcan_t, CAN_RX_FIFO0); } } void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* hcan_t){ if(hcan_t == &hcan){ CAN1_RxProcess(hcan_t, CAN_RX_FIFO1); } } */ /* use // init CAN1_InitConfigStart(); // cycles CAN1_UpdateFilter((uint8_t)RGF_SYS_ADDR, (uint8_t)RGF_SYS_GROUP_ID); */ /******************************************************************************/ /******************************** End Of File *********************************/