Single LIN master node emulation for FED1.0 DAI MRA2. Emulation of a LIN master node via Serial3 (+ LIN transceiver) with callback function for DAI MRA2 FED1.0. Speed can be controlled and status is printed.
#include "Tasks.h"
#define PRINT_PERIOD 1000 // period for status output
#define LIN_PERIOD 10 // LIN frame every N ms
#define PIN_TOGGLE 30
void printStatus(void);
uint8_t CoolFan_RPM = 0;
uint8_t CoolFan_RPM_Ack = 0;
uint8_t CoolFan_EmAct_Stat = 0;
uint8_t CoolFan_RPM_Avg = 0;
uint8_t CoolFan_OvrVolt_Stat = 0;
uint8_t CoolFan_Voltage_Avg = 0;
uint8_t CoolFan_UnderVolt_Stat = 0;
uint8_t CoolFan_Current_Avg = 0;
uint8_t CoolFan_VoltDerat_Stat = 0;
uint8_t CoolFan_cur_Temp = 0;
uint8_t CoolFan_TempDerat_Stat = 0;
uint8_t CoolFan_Stiff_Stat = 0;
uint8_t CoolFan_Blocking_Stat = 0;
uint8_t CoolFan_Electr_Err = 0;
uint8_t CoolFan_Mech_Err = 0;
uint8_t CoolFan_OvrTemp_Err = 0;
uint8_t CoolFan_Err_Group_ERR_Stat = 0;
uint8_t CoolFan_Err_Group_SNA_Stat = 0;
uint8_t CoolFan_Type = 0;
uint8_t RsErr_CF = 0;
uint8_t WakeupStat_CF = 0;
void setup(void)
{
pinMode(PIN_TOGGLE, OUTPUT);
Serial.begin(115200); while(!Serial);
Tasks_Init();
Tasks_Add((Task) LIN_scheduler, LIN_PERIOD, 0);
Tasks_Add((Task) printStatus, PRINT_PERIOD, PRINT_PERIOD);
Tasks_Start();
}
void loop(void)
{
digitalWrite(PIN_TOGGLE, !digitalRead(PIN_TOGGLE));
if (Serial.available())
{
uint8_t c = Serial.read();
switch(c)
{
case '1':
CoolFan_RPM = (uint8_t) max(0, (int) CoolFan_RPM - 10);
break;
case '2':
CoolFan_RPM = (uint8_t) min(127, (int) CoolFan_RPM + 10);
break;
case '0':
CoolFan_RPM = 0;
break;
}
Serial.print("new speed = ");
Serial.print(CoolFan_RPM*25);
Serial.println("rpm");
}
}
void LIN_scheduler(void)
{
static uint8_t count = 0;
uint8_t id;
uint8_t numData;
uint8_t data[8];
if (count == 0) {
id = 0x3B;
numData = 2;
memset(data, 0, 8);
data[0] = CoolFan_RPM & 0x7f;
count++;
}
else {
id = 0x1B;
numData = 8;
count=0;
}
}
void statusDecode(uint8_t numData, uint8_t *data)
{
CoolFan_RPM_Ack = data[0] & 0x7F;
CoolFan_EmAct_Stat = bitRead(data[0],7);
CoolFan_RPM_Avg = data[1] & 0x7F;
CoolFan_OvrVolt_Stat = bitRead(data[1],7);
CoolFan_Voltage_Avg = data[2] & 0x7F;
CoolFan_UnderVolt_Stat = bitRead(data[2],7);
CoolFan_Current_Avg = data[3] & 0x7F;
CoolFan_VoltDerat_Stat = bitRead(data[3],7);
CoolFan_cur_Temp = data[4];
CoolFan_TempDerat_Stat = bitRead(data[5],0);
CoolFan_Stiff_Stat = bitRead(data[5],1);
CoolFan_Blocking_Stat = bitRead(data[5],2);
CoolFan_Electr_Err = bitRead(data[5],3);
CoolFan_Mech_Err = bitRead(data[5],4);
CoolFan_OvrTemp_Err = bitRead(data[5],5);
CoolFan_Err_Group_ERR_Stat = bitRead(data[5],6);
CoolFan_Err_Group_SNA_Stat = bitRead(data[5],7);
CoolFan_Type = data[6] & 0x0F;
RsErr_CF = bitRead(data[7],5);
WakeupStat_CF = (data[7] & 0xC0) >> 6;
}
void printStatus(void)
{
{
Serial.print("set speed: "); Serial.print(CoolFan_RPM_Ack*25); Serial.println("rpm");
Serial.print("act speed: "); Serial.print(CoolFan_RPM_Avg*25); Serial.println("rpm");
Serial.print("voltage: "); Serial.print(CoolFan_Voltage_Avg*0.2); Serial.println("V");
Serial.print("voltage: "); Serial.print(CoolFan_Current_Avg); Serial.println("A");
Serial.print("voltage: "); Serial.print((int)CoolFan_cur_Temp-0); Serial.println("C");
Serial.print("blocking: "); Serial.print((int)CoolFan_Blocking_Stat-0); Serial.println();
Serial.println();
}
else {
Serial.print("LIN error (0x");
Serial.print("): ");
Serial.print("statemachine ");
Serial.print("echo ");
Serial.print("timeout ");
Serial.print("checksum ");
Serial.print("misc ");
Serial.println();
}
}