189 lines
6.6 KiB
C++
189 lines
6.6 KiB
C++
/**
|
|
* @file can.cpp
|
|
*
|
|
* @brief Implementation file for CAN-related functions in the ChainLube application.
|
|
*
|
|
* This file contains the implementation of functions related to CAN (Controller Area Network)
|
|
* communication within the ChainLube application. It includes the initialization of the CAN module,
|
|
* setup of masks and filters, and processing of CAN messages. Additionally, a debug message function
|
|
* is included if CAN debugging is enabled.
|
|
*
|
|
* @author Your Name
|
|
* @date Date
|
|
*/
|
|
|
|
#include "can.h"
|
|
|
|
MCP_CAN CAN0(GPIO_CS_CAN);
|
|
#ifdef CAN_DEBUG_MESSAGE
|
|
#define MAX_DEBUG_RETRIES 100
|
|
void sendCANDebugMessage();
|
|
#endif
|
|
|
|
/**
|
|
* @brief Initializes the CAN module, sets masks, and filters based on the configured CAN source.
|
|
*
|
|
* This function initializes the CAN module, sets masks and filters based on the configured CAN source
|
|
* in the application settings, and sets the CAN module in normal mode for communication.
|
|
*/
|
|
void Init_CAN()
|
|
{
|
|
if (CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ) != CAN_OK)
|
|
MaintainDTC(DTC_CAN_TRANSCEIVER_FAILED, true);
|
|
|
|
CAN0.init_Mask(0, 0, 0x07FF0000); // Init first mask...
|
|
CAN0.init_Mask(1, 0, 0x07FF0000); // Init second mask...
|
|
|
|
switch (LubeConfig.CANSource)
|
|
{
|
|
case KTM_890_ADV_R_2021:
|
|
CAN0.init_Filt(0, 0, 0x012D0000); // Init first filter...
|
|
break;
|
|
case KTM_1290_SD_R_2023:
|
|
CAN0.init_Filt(0, 0, 0x012D0000); // Init first filter...
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
CAN0.setMode(MCP_NORMAL);
|
|
}
|
|
|
|
/**
|
|
* @brief Processes CAN messages and sends a CAN debug message periodically.
|
|
*
|
|
* This function processes CAN messages and sends a CAN debug message periodically based on a time interval.
|
|
*/
|
|
void CAN_Process()
|
|
{
|
|
static uint32_t previousMillis = 0;
|
|
|
|
if (millis() - previousMillis >= 100)
|
|
{
|
|
sendCANDebugMessage();
|
|
previousMillis = millis();
|
|
}
|
|
}
|
|
/**
|
|
* @brief Processes CAN messages to determine the wheel speed based on the configured CAN source.
|
|
*
|
|
* This function reads incoming CAN messages and extracts the rear wheel speed information.
|
|
* The wheel speed is then converted to millimeters per second based on the configured CAN source.
|
|
* The function also monitors the CAN signal for potential issues and triggers diagnostic trouble codes (DTCs).
|
|
*
|
|
* @return The calculated distance traveled in millimeters since the last call.
|
|
*/
|
|
uint32_t Process_CAN_WheelSpeed()
|
|
{
|
|
#define FACTOR_RWP_KMH_890ADV 18 // Divider to convert Raw Data to km/h
|
|
#define FACTOR_RWP_KMH_1290SD 18 // Divider to convert Raw Data to km/h
|
|
can_frame canMsg;
|
|
static uint32_t lastRecTimestamp = 0;
|
|
uint16_t RearWheelSpeed_raw;
|
|
uint32_t milimeters_to_add = 0;
|
|
uint32_t RWP_millimeter_per_second = 0;
|
|
|
|
if (CAN0.readMsgBuf(&canMsg.can_id, &canMsg.can_dlc, canMsg.data) == CAN_OK)
|
|
{
|
|
|
|
switch (LubeConfig.CANSource)
|
|
{
|
|
case KTM_890_ADV_R_2021:
|
|
// raw / FACTOR_RWP_KMH_890ADV -> km/h * 100000 -> cm/h / 3600 -> cm/s
|
|
// raw * 500 -> cm/s
|
|
RearWheelSpeed_raw = (uint16_t)canMsg.data[5] << 8 | canMsg.data[6];
|
|
RWP_millimeter_per_second = (((uint32_t)RearWheelSpeed_raw * 1000000) / FACTOR_RWP_KMH_890ADV) / 3600;
|
|
break;
|
|
case KTM_1290_SD_R_2023:
|
|
// raw / FACTOR_RWP_KMH_1290SD -> km/h * 100000 -> cm/h / 3600 -> cm/s
|
|
// raw * 500 -> cm/s
|
|
RearWheelSpeed_raw = (uint16_t)canMsg.data[5] << 8 | canMsg.data[6];
|
|
RWP_millimeter_per_second = (((uint32_t)RearWheelSpeed_raw * 1000000) / FACTOR_RWP_KMH_1290SD) / 3600;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
uint32_t timesincelast = millis() - lastRecTimestamp;
|
|
lastRecTimestamp = millis();
|
|
|
|
milimeters_to_add = (RWP_millimeter_per_second * timesincelast) / 1000;
|
|
}
|
|
|
|
if (lastRecTimestamp > 1000)
|
|
{
|
|
MaintainDTC(DTC_NO_CAN_SIGNAL, (millis() > lastRecTimestamp + 10000 ? true : false));
|
|
}
|
|
|
|
return milimeters_to_add;
|
|
}
|
|
|
|
#ifdef CAN_DEBUG_MESSAGE
|
|
/**
|
|
* @brief Sends periodic CAN debug messages for monitoring and diagnostics.
|
|
*
|
|
* This function sends periodic CAN debug messages containing various system information for monitoring and diagnostics.
|
|
* The information includes system status, timestamps, tank percentage, DTC flags, and other relevant data.
|
|
* The debug messages are sent with a configurable multiplexer to broadcast different types of information in each cycle.
|
|
*/
|
|
void sendCANDebugMessage()
|
|
{
|
|
#define MAX_DEBUG_MULTIPLEXER 6
|
|
static uint16_t DebugSendFailTimeout = 0;
|
|
static uint8_t debugMultiplexer = 0;
|
|
byte data[8] = {debugMultiplexer, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
uint32_t millisValue = millis();
|
|
|
|
switch (debugMultiplexer)
|
|
{
|
|
case 0:
|
|
memcpy(&data[1], &millisValue, sizeof(millisValue));
|
|
memcpy(&data[5], &globals.purgePulses, sizeof(globals.purgePulses));
|
|
break;
|
|
case 1:
|
|
data[1] = (uint8_t)globals.systemStatus;
|
|
data[2] = (uint8_t)globals.resumeStatus;
|
|
data[3] = (uint8_t)globals.requestEEAction;
|
|
data[4] = globals.TankPercentage;
|
|
data[5] = (0x01 & globals.hasDTC) | ((0x01 & globals.measurementActive) << 1);
|
|
break;
|
|
case 2:
|
|
memcpy(&data[1], &globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
|
|
memcpy(&data[3], &PersistenceData.tankRemain_microL, sizeof(PersistenceData.tankRemain_microL));
|
|
break;
|
|
case 3:
|
|
memcpy(&data[1], &PersistenceData.writeCycleCounter, sizeof(PersistenceData.writeCycleCounter));
|
|
memcpy(&data[3], &PersistenceData.TravelDistance_highRes_mm, sizeof(PersistenceData.TravelDistance_highRes_mm));
|
|
break;
|
|
case 4:
|
|
memcpy(&data[1], &PersistenceData.odometer_mm, sizeof(PersistenceData.odometer_mm));
|
|
break;
|
|
case 5:
|
|
memcpy(&data[1], &PersistenceData.odometer, sizeof(PersistenceData.odometer));
|
|
break;
|
|
case 6:
|
|
memcpy(&data[1], &PersistenceData.checksum, sizeof(PersistenceData.checksum));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
debugMultiplexer++;
|
|
debugMultiplexer = debugMultiplexer > MAX_DEBUG_MULTIPLEXER ? 0 : debugMultiplexer;
|
|
|
|
if (DebugSendFailTimeout < MAX_DEBUG_RETRIES)
|
|
{
|
|
byte sndStat = CAN0.sendMsgBuf(0x7FF, 0, 8, data);
|
|
if (sndStat != CAN_OK)
|
|
{
|
|
Debug_pushMessage("failed sending CAN-DbgMsg: %d, %d\n", sndStat, DebugSendFailTimeout);
|
|
DebugSendFailTimeout++;
|
|
}
|
|
}
|
|
else if (DebugSendFailTimeout == MAX_DEBUG_RETRIES)
|
|
{
|
|
Debug_pushMessage("disable CAN-DbgMsg due to timeout");
|
|
DebugSendFailTimeout++;
|
|
}
|
|
}
|
|
#endif |