База для Monjaro и Atlas2024
All checks were successful
Push Branch / Build Test (push) Successful in 1m53s
All checks were successful
Push Branch / Build Test (push) Successful in 1m53s
This commit is contained in:
36
src/CAN_FW.h
36
src/CAN_FW.h
@@ -6,12 +6,44 @@
|
|||||||
#include "Periodic.h"
|
#include "Periodic.h"
|
||||||
#include "Can.h"
|
#include "Can.h"
|
||||||
|
|
||||||
#define CAN_FW_DESCRIPTION "Test"
|
enum TPeriodicTasks
|
||||||
|
{
|
||||||
|
PELightButton, // Задача управления триггерной кнопкой.
|
||||||
|
PeriodicCount, // количество задач
|
||||||
|
};
|
||||||
|
|
||||||
// структура с пользовательскими переменными
|
// структура с пользовательскими переменными
|
||||||
struct TCanFwMem {
|
struct TCanFwMem {
|
||||||
CSettings::TSettings Settings; // структура с настройками - должна быть всегда в начале
|
CSettings::TSettings Settings; // структура с настройками - должна быть всегда в начале
|
||||||
|
CPeriodic<PeriodicCount> PeriodicTask;
|
||||||
|
|
||||||
|
bool ign; // флаг зажигания
|
||||||
|
bool arm;
|
||||||
|
bool prearm; // предыдущий статус охраны автомобиля
|
||||||
|
bool cmf; // флаг "комфорт"
|
||||||
|
bool mirror; // флаг "сложить зеркала"
|
||||||
|
|
||||||
|
struct{
|
||||||
|
bool hazlamp; // состояние аварийки (любой)
|
||||||
|
bool seized; // Флаг захвата кнопки аварийки
|
||||||
|
uint8_t step; // Шаги функции Emergency Light Button
|
||||||
|
TimerMs tmr; // Таймер сбрасывается в момент фронта/спада автомобильной (не нашей!) аварийки
|
||||||
|
uint8_t cnt;
|
||||||
|
} ELight;
|
||||||
|
|
||||||
|
struct{
|
||||||
|
bool multipkt;
|
||||||
|
uint8_t mode;
|
||||||
|
uint8_t pid;
|
||||||
|
char vin[17];
|
||||||
|
} Diag;
|
||||||
};
|
};
|
||||||
|
void Wake_CAN (TCanFwMem * vars);
|
||||||
|
void ELight_Button2 (TCanFwMem * vars);
|
||||||
|
|
||||||
|
// OBDII
|
||||||
|
void DiagRcv (TCanFwMem * vars, TCanPkt * pkt, TCanChannel channel);
|
||||||
|
void DiagReq (TCanFwMem * vars, uint8_t mode, uint8_t pid, TCanChannel channel);
|
||||||
|
|
||||||
|
|
||||||
#endif /* CAN_FW_H_ */
|
#endif /* CAN_FW_H_ */
|
||||||
|
|||||||
189
src/CAN_Inputs.h
189
src/CAN_Inputs.h
@@ -2,21 +2,186 @@
|
|||||||
#include "Can.h"
|
#include "Can.h"
|
||||||
#include "IO.h"
|
#include "IO.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
#include "myfunc/VinReq.h"
|
||||||
|
#include "myfunc/_MFM3.h"
|
||||||
|
|
||||||
void Init (TCanFwMem * vars)
|
void Init (TCanFwMem * vars)
|
||||||
{
|
{
|
||||||
CoreFunc->DebugConsole("CAN_FW version: %s\n", (const char*)(gCanFwInfo.TextInfo));
|
static const TCanInit can1_init =
|
||||||
|
{
|
||||||
|
CCan::CanBaudrate500,
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
CCan::Filter::List11 (0x010, 0x020),
|
||||||
|
CCan::Filter::List11 (0x040, 0x0E0),
|
||||||
|
CCan::Filter::List11 (0x095, 0x100),
|
||||||
|
CCan::Filter::List11 (0x300, 0x310),
|
||||||
|
CCan::Filter::List11 (0x334, 0x355),
|
||||||
|
|
||||||
static const TCanInit can1_init =
|
CCan::Filter::List11 (0x380),
|
||||||
{
|
|
||||||
CCan::CanBaudrate500,
|
CCan::Filter::List11 (0x0C3, 0x210),
|
||||||
1,
|
}
|
||||||
{
|
};
|
||||||
CCan::Filter::List11 (0x660),
|
CoreFunc->CanInit (CANch1, &can1_init);
|
||||||
CCan::Filter::Mask11 (0x7E0, 0x7F0), // 0x7E0..0x7EF
|
//---------------------------------------------------------
|
||||||
}
|
static const TCanInit can2_init =
|
||||||
};
|
{
|
||||||
CoreFunc->CanInit (CANch1, &can1_init);
|
CCan::CanBaudrate500,
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
CCan::Filter::List11 (0x04B, 0x050),
|
||||||
|
CCan::Filter::List11 (0x111, 0x138),
|
||||||
|
CCan::Filter::Mask11 (0x7E0, 0x7F0),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CoreFunc->CanInit (CANch2, &can2_init);
|
||||||
|
//---------------------------------------------------------
|
||||||
|
vars->PeriodicTask.AddTask (PELightButton, ELight_Button2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Can1Received (TCanFwMem * vars, TCanPkt *apPkt)
|
||||||
|
{
|
||||||
|
// int32_t temp; // знаковое!
|
||||||
|
// int16_t tmp; // знаковое!
|
||||||
|
uint8_t * buf = apPkt->data;
|
||||||
|
TCanPkt pkt;
|
||||||
|
TCanPkt pktm;
|
||||||
|
|
||||||
|
switch (apPkt->id)
|
||||||
|
{
|
||||||
|
case 0x010:
|
||||||
|
CoreFunc->InputState (CIO::iLock, (Rx_D & 0x0C)==0x08);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x040:
|
||||||
|
CoreFunc->InputState (CIO::iDoorDrv, (Rx_G & 0xC0)==0x40);
|
||||||
|
CoreFunc->InputState (CIO::iDoorRL, (Rx_F & 0x0C)==0x04);
|
||||||
|
|
||||||
|
if (vars->cmf)
|
||||||
|
{
|
||||||
|
pkt = *apPkt;
|
||||||
|
pkt.data[4] |= 0x0A;
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 7);
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 17);
|
||||||
|
vars->cmf = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0E0:
|
||||||
|
CoreFunc->InputState (CIO::iDoorFP, (Rx_D & 0xC0)==0x40);
|
||||||
|
CoreFunc->InputState (CIO::iDoorRR, (Rx_B & 0x30)==0x10);
|
||||||
|
CoreFunc->InputState (CIO::iTrunk, (Rx_F & 0xC0)==0x40);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x095:
|
||||||
|
if (Rx_A == 0x52) CoreFunc->Command (CoreCmdTrunkOpened, 0x04); // Br-Hf
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x100:
|
||||||
|
|
||||||
|
if (Rx_B == 0x1F || Rx_B == 0x2F || Rx_B == 0x9F) CoreFunc->Command (CoreCmdArm, 0x04); // Br, HF-L,R
|
||||||
|
else if (Rx_B == 0x17 || Rx_B == 0x27 || Rx_B == 0x97) CoreFunc->Command (CoreCmdDisarm, 0x04); // Br, HF-L,R
|
||||||
|
/*
|
||||||
|
if (vars->mirror) не закрывается и зеркала зависают
|
||||||
|
{
|
||||||
|
pktm = *apPkt;
|
||||||
|
pktm.data[1] == 0x1F;
|
||||||
|
// попробовать это !!! pktm.data[7] |= 0x08;
|
||||||
|
for (int i=0; i<30; i++) CoreFunc->CanSend (CANch1, &pktm, 30);
|
||||||
|
vars->mirror = false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case 0x210:
|
||||||
|
CoreFunc->DataValue (CanData_CoolantTemp, Rx_C - 10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//case 0x270: XC90
|
||||||
|
//CoreFunc->DataValue (CanData_FuelLevel, buf[6]*100/256);//
|
||||||
|
// break;
|
||||||
|
|
||||||
|
case 0x300:
|
||||||
|
CoreFunc->DataValue (CanData_RPM, (Rx_C << 8 | Rx_D) >> 1);
|
||||||
|
break;
|
||||||
|
case 0x310:
|
||||||
|
CoreFunc->DataValue (CanData_Odometer, ((Rx_A & 0x0F) <<16 | buf[1]<<8 | buf[2]) * 10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x334:
|
||||||
|
CoreFunc->InputState (CIO::iLeftTurnLight, Rx_H & BIT(4));
|
||||||
|
CoreFunc->InputState (CIO::iRightTurnLight, Rx_H & BIT(2));
|
||||||
|
CoreFunc->InputState (CIO::iEmergency, (Rx_H & 0x14) == 0x14);
|
||||||
|
break;
|
||||||
|
case 0x355:
|
||||||
|
CoreFunc->InputState (CIO::iLauncher, Rx_F & 0x03);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x000:
|
||||||
|
// CoreFunc->InputState (CIO::iLamp, Rx_B & BIT(2)); // от XC90 не подходит ID0C3
|
||||||
|
// CoreFunc->DataValue (CanData_Speed, (Rx_B << 8 | Rx_C)>>4);
|
||||||
|
// CoreFunc->DataValue (CanData_FuelLevel, Rx_H); // от XC90 не подходит ID310
|
||||||
|
// CoreFunc->DataValue (CanData_FuelConsumption, Rx_C);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Can2Received (TCanFwMem * vars, TCanPkt *apPkt)
|
||||||
|
{
|
||||||
|
// int32_t temp; // знаковое!
|
||||||
|
// int16_t tmp; // знаковое!
|
||||||
|
uint8_t * buf = apPkt->data;
|
||||||
|
|
||||||
|
switch (apPkt->id)
|
||||||
|
{
|
||||||
|
|
||||||
|
case 0x04B:
|
||||||
|
CoreFunc->InputState (CIO::iPark, (Rx_D & 0x0E) == 0x00);
|
||||||
|
break;
|
||||||
|
case 0x050:
|
||||||
|
Rx_C = Rx_C/2;
|
||||||
|
if (Rx_C > 100) Rx_C = 100;
|
||||||
|
CoreFunc->DataValue (CanData_Accelerator, Rx_C);
|
||||||
|
break;
|
||||||
|
case 0x111:
|
||||||
|
CoreFunc->InputState (CIO::iIgn, Rx_C & BIT(7));
|
||||||
|
break;
|
||||||
|
case 0x138:
|
||||||
|
//CoreFunc->InputState (CIO::iHBrake, (Rx_A & 0x0C)==0x04); // ID144
|
||||||
|
CoreFunc->DataValue (CanData_BrakeForce,(Rx_E << 8 | Rx_F)/20);
|
||||||
|
CoreFunc->InputState (CIO::iBrake, Rx_E );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x2B0:
|
||||||
|
//tmp = Rx_D << 8 | Rx_E ;
|
||||||
|
//CoreFunc->DataValue (CanData_WheelAngle, tmp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputChanged (TCanFwMem * vars, uint32_t aInputNum, bool aSwitchedOn)
|
||||||
|
{
|
||||||
|
// TCanPkt pkt;
|
||||||
|
|
||||||
|
if ((aInputNum == CIO::iIgn) && ! aSwitchedOn)
|
||||||
|
{
|
||||||
|
CoreFunc->InputState (CIO::iBrake, false);
|
||||||
|
CoreFunc->DataValue (CanData_Invalid | CanData_RPM, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aInputNum == CIO::iIgn) vars->ign = aSwitchedOn;
|
||||||
|
|
||||||
|
if (aInputNum == CIO::iEmergency)
|
||||||
|
{
|
||||||
|
vars->ELight.hazlamp = aSwitchedOn;
|
||||||
|
|
||||||
|
if (!vars->ELight.seized) vars->ELight.tmr.Restart (); // при собственных моргках таймер не перезапускаем
|
||||||
|
//tt(aSwitchedOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuardEvent (TCanFwMem * vars, TGuardEvents aEvent)
|
||||||
|
{
|
||||||
|
if (aEvent == geARM) vars->arm = true;
|
||||||
|
if (aEvent == geDISARM) vars->arm = false;
|
||||||
|
}
|
||||||
@@ -3,3 +3,129 @@
|
|||||||
#include "IO.h"
|
#include "IO.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
void OutputChanged (TCanFwMem * vars, uint32_t aOutputNum, bool aSwitchedOn)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
|
||||||
|
switch (aOutputNum)
|
||||||
|
{
|
||||||
|
case CIO::oLights:
|
||||||
|
if(aSwitchedOn)
|
||||||
|
{
|
||||||
|
if (vars->ELight.tmr.Value() > 800 && vars->ELight.step == 0)
|
||||||
|
{
|
||||||
|
CoreFunc->RunSequence(SEQ(oEmergency, seqProg8)); // Выход на кнопку аварийки импульс 250 ms
|
||||||
|
vars->PeriodicTask.SetTimeout (PELightButton, 260);
|
||||||
|
vars->ELight.step++;
|
||||||
|
vars->ELight.cnt = 0;
|
||||||
|
vars->ELight.seized = true;
|
||||||
|
//tt(0x10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CIO::oCloseWindows:
|
||||||
|
if (aSwitchedOn) vars->cmf = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case CIO::oFoldMirrors:
|
||||||
|
if (aSwitchedOn) vars->mirror = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ELight_Button2(TCanFwMem * vars) // Нажатия на триггерную кнопку аварийки с ожиданием вспышки
|
||||||
|
{
|
||||||
|
switch (vars->ELight.step)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (!vars->ELight.hazlamp)
|
||||||
|
{
|
||||||
|
if (vars->ELight.cnt < 8) // ожидаем когда лампа загориться
|
||||||
|
{
|
||||||
|
vars->PeriodicTask.SetTimeout (PELightButton, 50); // подождем еще
|
||||||
|
vars->ELight.cnt++;
|
||||||
|
//tt(0x15);
|
||||||
|
}
|
||||||
|
else {vars->ELight.step = 0; /*tt(3);*/} // не удалось зажечь
|
||||||
|
}
|
||||||
|
else // если лампа загорелась (~440mS для Monjaro)
|
||||||
|
{
|
||||||
|
vars->PeriodicTask.SetTimeout (PELightButton, 150); // пусть погорит хотя бы 150mS
|
||||||
|
vars->ELight.step++;
|
||||||
|
//tt(0x20);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // лампа горит уже 150m
|
||||||
|
CoreFunc->RunSequence(SEQ(oEmergency, seqProg9)); // гасим ее импульсом не менее 150 мс ( 100mS для Monjaro мало)
|
||||||
|
vars->PeriodicTask.SetTimeout (PELightButton, 160);
|
||||||
|
vars->ELight.step++;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (!vars->ELight.hazlamp) // ожидаем когда лампа погаснет
|
||||||
|
{
|
||||||
|
|
||||||
|
vars->ELight.step = 0;
|
||||||
|
vars->ELight.seized = false;
|
||||||
|
//tt(0x0F);
|
||||||
|
}
|
||||||
|
else vars->PeriodicTask.SetTimeout (PELightButton, 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// события arm, disarm, alarm, ...
|
||||||
|
void Command (TCanFwMem * vars, TCanFwCommands aCmd, uint32_t aCmdParam)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
switch (aCmd)
|
||||||
|
{
|
||||||
|
|
||||||
|
case ccLockDoors:
|
||||||
|
Wake_CAN(vars);
|
||||||
|
pkt.id = 0x020;
|
||||||
|
pkt.data_len = 8;
|
||||||
|
pkt.SetData("\x28\x12\x28\x2B\xAA\x00\x00\x68"); // FL=0x2X RL=0xX2 FR=0x2X RR=0x2X
|
||||||
|
for (i=0; i<4; i++) CoreFunc->CanSend (CANch1, &pkt, 18);
|
||||||
|
break;
|
||||||
|
case ccUnLockDoors: // можно сделать mccPriority
|
||||||
|
Wake_CAN(vars);
|
||||||
|
pkt.id = 0x020;
|
||||||
|
pkt.data_len = 8;
|
||||||
|
pkt.SetData("\x18\x11\x18\x1B\xAA\x00\x00\x68");
|
||||||
|
for (i=0; i<4; i++) CoreFunc->CanSend (CANch1, &pkt, 18);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ccSendObdReq:
|
||||||
|
pkt.id = 0x7DF;
|
||||||
|
pkt.data_len = 8;
|
||||||
|
pkt.data[0] = 0x01;
|
||||||
|
pkt.data[1] = aCmdParam;
|
||||||
|
CoreFunc->CanSend (CANch2, &pkt, 1);
|
||||||
|
break;
|
||||||
|
case ccUpdateVin: // отправить запрос VIN-кода
|
||||||
|
DiagReq (vars, 0x09, 0x02, CANch2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============== Пробуждение ==================================================
|
||||||
|
void Wake_CAN(TCanFwMem * vars)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
// uint8_t i;
|
||||||
|
|
||||||
|
if (CoreFunc->CanGetRxTimeout (CANch1) < 1000) return; // Если шина не спит то не будим!
|
||||||
|
|
||||||
|
pkt.id = 0x501;
|
||||||
|
pkt.data_len = 8;
|
||||||
|
pkt.SetData("\x01\x40\x26\x00\x01");
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 2);
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 20);
|
||||||
|
}
|
||||||
@@ -1,10 +1,24 @@
|
|||||||
//=====================================================================================
|
#define iWireLock iDevice6
|
||||||
|
#define iWireUnlock iDevice7
|
||||||
|
#define iEmergency iDevice8
|
||||||
|
#define oWireLock oDevice6
|
||||||
|
#define oWireUnlock oDevice7
|
||||||
|
#define oEmergency oDevice8
|
||||||
|
|
||||||
// SETTING_RSRV позволяет сделать "дырки" в номерах настроек
|
/** Новая классификация прошивок **
|
||||||
// если не определена, значит, она не используется
|
|
||||||
#ifndef SETTING_RSRV
|
(A) - Обычный обходчик
|
||||||
#define SETTING_RSRV(name)
|
(B) - Baypass
|
||||||
#endif
|
(С) - Запуск через штатную CAN команду
|
||||||
|
(E) - Электрический автомобиль
|
||||||
|
|
||||||
|
Правила нумерации версий:
|
||||||
|
release - меняется только при появлении существенно новой версии приложения. Обратная совместимость может не обеспечиваться.
|
||||||
|
version - меняется при появлении новых возможостей.
|
||||||
|
update - меняется при исправлении ошибок в текущей версии.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CAN_FW_DESCRIPTION "Geely_Atlas2024_[C]"
|
||||||
|
|
||||||
//************************** Динамические параметры ***********************************************//
|
//************************** Динамические параметры ***********************************************//
|
||||||
|
|
||||||
|
|||||||
79
src/myfunc/VinReq.h
Normal file
79
src/myfunc/VinReq.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include "CAN_FW.h"
|
||||||
|
#include "Can.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void DiagReq (TCanFwMem * vars, uint8_t mode, uint8_t pid, TCanChannel channel)
|
||||||
|
{
|
||||||
|
TCanPkt req;
|
||||||
|
req.id = 0x7DF;
|
||||||
|
req.SetData ("\x02\x00\x00");
|
||||||
|
req.data_len = 8;
|
||||||
|
req.data[1] = mode;
|
||||||
|
req.data[2] = pid;
|
||||||
|
CoreFunc->CanSend (channel, &req, 0);
|
||||||
|
|
||||||
|
vars->Diag.mode = mode;
|
||||||
|
vars->Diag.pid = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DiagRcv (TCanFwMem * vars, TCanPkt * pkt, TCanChannel channel)
|
||||||
|
{
|
||||||
|
uint8_t * buf = pkt->data;
|
||||||
|
|
||||||
|
// заголовок мультипакета
|
||||||
|
if (buf[0] == 0x10)
|
||||||
|
{
|
||||||
|
uint8_t mode = buf[2] & (~0x40);
|
||||||
|
uint8_t pid = buf[3];
|
||||||
|
|
||||||
|
// отправить flow control
|
||||||
|
if (mode == vars->Diag.mode &&
|
||||||
|
pid == vars->Diag.pid)
|
||||||
|
{
|
||||||
|
TCanPkt fc;
|
||||||
|
fc.id = 0x7E0;
|
||||||
|
fc.SetData ("\x30\x00\x00");
|
||||||
|
fc.data_len = 8;
|
||||||
|
CoreFunc->CanSend (channel, &fc, 0);
|
||||||
|
|
||||||
|
vars->Diag.multipkt = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// сбросить автомат
|
||||||
|
vars->Diag.mode = vars->Diag.pid = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// заголовок мультипакета с VIN-кодом
|
||||||
|
if (mode == 9 && pid == 2)
|
||||||
|
memcpy (vars->Diag.vin, &buf[5], 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
// тело мультипакета
|
||||||
|
else
|
||||||
|
if (((buf[0] & 0xF0) == 0x20) && vars->Diag.multipkt)
|
||||||
|
{
|
||||||
|
uint8_t cnt = buf[0] & 0x0F;
|
||||||
|
|
||||||
|
// мультипакет с VIN-кодом
|
||||||
|
if (vars->Diag.mode == 9 && vars->Diag.pid == 2)
|
||||||
|
{
|
||||||
|
if (cnt == 1)
|
||||||
|
memcpy (&vars->Diag.vin[3], &buf[1], 7);
|
||||||
|
if (cnt == 2)
|
||||||
|
{
|
||||||
|
memcpy (&vars->Diag.vin[10], &buf[1], 7);
|
||||||
|
|
||||||
|
// сообщить в ядро о приёме пакета
|
||||||
|
CoreFunc->DataValueArr (CanData_VIN, vars->Diag.vin);
|
||||||
|
|
||||||
|
// сбросить автомат
|
||||||
|
vars->Diag.mode = vars->Diag.pid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vars->Diag.multipkt = false;
|
||||||
|
}
|
||||||
119
src/myfunc/_MFM3.h
Normal file
119
src/myfunc/_MFM3.h
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "CAN_FW.h"
|
||||||
|
#include "Can.h"
|
||||||
|
|
||||||
|
#define Rx_DLC apPkt->data_len
|
||||||
|
#define Rx_A buf[0]
|
||||||
|
#define Rx_B buf[1]
|
||||||
|
#define Rx_C buf[2]
|
||||||
|
#define Rx_D buf[3]
|
||||||
|
#define Rx_E buf[4]
|
||||||
|
#define Rx_F buf[5]
|
||||||
|
#define Rx_G buf[6]
|
||||||
|
#define Rx_H buf[7]
|
||||||
|
|
||||||
|
uint16_t bcd (uint16_t hexdata)
|
||||||
|
{
|
||||||
|
uint16_t x;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
if ( hexdata > 9999) return 0xFFFF;
|
||||||
|
|
||||||
|
x = hexdata >> (14-3);
|
||||||
|
hexdata <<= (2+3);
|
||||||
|
|
||||||
|
for (i=0; i<11; i++)
|
||||||
|
{
|
||||||
|
if ((x >> 0 & 0x0F) > 4) x+=0x0003;
|
||||||
|
if ((x >> 4 & 0x0F) > 4) x+=0x0030;
|
||||||
|
if ((x >> 8 & 0x0F) > 4) x+=0x0300;
|
||||||
|
if ((x >>12 & 0x0F) > 4) x+=0x3000;
|
||||||
|
x <<= 1;
|
||||||
|
if (hexdata & 0x8000) x++;
|
||||||
|
hexdata <<= 1;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
#if defined ISiSLAVE
|
||||||
|
void iSlaveTune (TCanFwMem * vars, bool isStep)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
uint16_t bcdTime;
|
||||||
|
|
||||||
|
if (isStep)
|
||||||
|
{
|
||||||
|
pkt.data[0] = vars->iSlave.prestep;
|
||||||
|
pkt.data[1] = vars->iSlave.step;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pkt.data[0] = 0xFF;
|
||||||
|
pkt.data[1] = vars->iSlave.step;
|
||||||
|
}
|
||||||
|
|
||||||
|
bcdTime = bcd (vars->iSlave.tmrHaz.Value());
|
||||||
|
pkt.data[2] = bcdTime >> 8; // время вспышки в двоично-десятичном формате
|
||||||
|
pkt.data[3] = bcdTime >> 0;
|
||||||
|
|
||||||
|
// pkt.data[2] = (vars->iSlave.tmrHaz.Value()) >> 8;
|
||||||
|
// pkt.data[3] = vars->iSlave.tmrHaz.Value();
|
||||||
|
|
||||||
|
pkt.id = 0x7dd;
|
||||||
|
pkt.data_len = 4;
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 0);
|
||||||
|
}
|
||||||
|
void TestSteps (TCanFwMem * vars)
|
||||||
|
{
|
||||||
|
if (vars->iSlave.step != vars->iSlave.prestep)
|
||||||
|
iSlaveTune (vars, true);
|
||||||
|
vars->iSlave.prestep = vars->iSlave.step;
|
||||||
|
}
|
||||||
|
void TestTimeFlash (TCanFwMem * vars)
|
||||||
|
{
|
||||||
|
if (vars->iSlave.prehazlamp != vars->iSlave.hazlamp)
|
||||||
|
iSlaveTune (vars, false);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
//=================================================================
|
||||||
|
|
||||||
|
void tt (uint8_t t)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
pkt.id = 0x7dd;
|
||||||
|
pkt.data_len = 1;
|
||||||
|
pkt.data[0] = t;
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 0);
|
||||||
|
}
|
||||||
|
void tt2 (uint8_t t)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
pkt.id = 0x7dd;
|
||||||
|
pkt.data_len = 1;
|
||||||
|
pkt.data[0] = t;
|
||||||
|
CoreFunc->CanSend (CANch2, &pkt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ttBcd (uint8_t t)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
uint16_t T;
|
||||||
|
|
||||||
|
T = bcd (t);
|
||||||
|
pkt.id = 0x7dd;
|
||||||
|
pkt.data_len = 2;
|
||||||
|
pkt.data[0] = T >> 8;
|
||||||
|
pkt.data[1] = T >> 0;
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ttuint (uint32_t t)
|
||||||
|
{
|
||||||
|
TCanPkt pkt;
|
||||||
|
pkt.id = 0x7dd;
|
||||||
|
pkt.data_len = 4;
|
||||||
|
pkt.data[0] = t >> 24;
|
||||||
|
pkt.data[1] = t >> 16;
|
||||||
|
pkt.data[2] = t >> 8;
|
||||||
|
pkt.data[3] = t >> 0;
|
||||||
|
CoreFunc->CanSend (CANch1, &pkt, 0);
|
||||||
|
}
|
||||||
|
//=================================================================
|
||||||
Reference in New Issue
Block a user