/**
* @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 *********************************/