Initial commit

This commit is contained in:
2025-10-22 20:40:25 +03:00
commit 63d038ee63
57 changed files with 104378 additions and 0 deletions

212
libs/LinBus.h Normal file
View File

@@ -0,0 +1,212 @@
/*
* LinBus.h
*
* Created on: 17 дек. 2015 г.
* Author: esaulenko
*/
#ifndef DRIVERS_LINBUS_H_
#define DRIVERS_LINBUS_H_
#ifndef CAN_FIRMWARE
#include "KLineDrv.h"
#include "ImoDrv.h"
#include "Buffer.h"
#include "SysTimer.h"
#include "scmRTOS/scmRTOS.h"
extern CLin LinBus1;
extern CLin LinBus2;
extern CLin LinBus3;
union TLinInit;
#endif // CAN_FIRMWARE
#include "LinFrame.h"
class CLin
{
public:
enum TLinMode {
Mode_RawNoParity, // без стандарта, принимает-передаёт любые пакеты (без чётности)
Mode_Master, // LIN-мастер
Mode_Slave, // LIN-слейв
Mode_RawEvenParity, // без стандарта, байты с проверкой на чётность
Mode_RawOddParity, // без стандарта, байты с проверкой на нечётность
Mode_Raw9bit, // без стандарта, в байте 9 бит данных без чётности
Mode_RawIgnoreError, // без стандарта, принимаются байты без чётности, стоп-бита и т.д.
Mode_RawStop2bit, // без стандарта, 2 стоп-бита
Mode_ImoImi, // протокол Toyota (старый), 48.8 бит/сек, 16 бит данных
Mode_ImoRenault, // протокол Renault, 81,4 бит/с
Mode_ImoImi2, // протокол Toyota (новый), 195.3 бит/сек, 32 бита данных
Mode_FordDstTx, // протокол Ford DST80 (ШИМ, 1 бит = 1 мс / 0,5 мс)
Mode_FordUartRx, // протокол Ford (UART 15625 бит/с, 384 мкс между байтами)
Mode_Haval, // протокол с импульсами подтверждения (фильтрация/генерация)
Mode_FordDstInversion, // протокол Ford DST80 (ШИМ, 1 бит = 1 мс / 0,5 мс, ИНВЕРСНЫЙ сигнал)
};
#ifndef CAN_FIRMWARE
CLin(const KLineHw & cfg) : _drv(cfg, this), _imoDrv(this, cfg)
{}
uint32_t Init(const TLinInit & init);
// Для режима Haval
void InitEXTI(void);
void DeinitEXTI(void);
void EdgeRcv(const bool newVal);
void CheckTimeout(void);
int32_t GetFrame(TLinFrame & aFrame);
uint32_t SendFrame(const TLinFrame & aFrame);
void Sleep(const bool sleepEnable);
// вызывается из обработчиков прерываний:
// приём/передача UART
void IrqUart(void)
{ _drv.IrqProcess(); }
// передача UART по таймеру
uint32_t IrqTimerSend(void)
{ return _drv.IrqTimerSend(); }
// фронт в режиме IMO/IMI
void IrqImoEdge(const bool val)
{
Sleep(false);
if (_mode == Mode_Haval)
EdgeRcv(val);
else
_imoDrv.rx.EdgeRcv(val);
}
// таймер передачи в режиме IMO/IMI (только для LIN1)
void IrqImoSend(void)
{ _imoDrv.tx.IrqSetNextBit(); }
// управление выходом напрямую, как GPIO
void SetOutput(const bool setZero);
private:
CKLineDrv _drv;
CImoDrv _imoDrv;
// вызывается из прерывания по приёму
void DataRcvd(uint16_t data);
void BreakRcvd(void);
void ErrorRcvd(void);
// вызывается из прерываний IMO/IMI
void DataImiRcvd(const uint8_t * data, uint32_t data_len);
// вызывается из прерывания по передаче
bool IsTxData(void)
{ return _tx_buf.Avail() > 0; }
uint16_t GetTxData(void)
{ return _tx_buf.Get(); }
void TxComplete(void);
friend CKLineDrv;
friend CImoDrv;
TLinMode _mode;
union {
bool _mode9bit = false;
bool _InverseSignal; // инверсия входного сигнала
};
// не-UART протоколы на таймере
bool isCustomMode(void) const
{
return _mode == Mode_ImoImi ||
_mode == Mode_ImoImi2 ||
_mode == Mode_ImoRenault ||
_mode == Mode_FordDstTx ||
_mode == Mode_FordDstInversion;
}
enum {
State_NoInit,
State_BusOff,
State_Idle,
State_WaitSync,
State_WaitId,
State_WaitData,
State_SlaveTxData,
} _state = State_NoInit;
TLinFrame _rx_frame;
TimerMs _rx_tmr;
uint32_t _rx_timeout;
TimerMs _sleep_tmr;
uint32_t _sleep_timeout;
uint8_t _bytecnt; // счетчик байт для Mode_Haval
uint8_t _bytes_noack; // кол-во байт без подтверждения для Mode_Haval
uint8_t _bytes_ack; // кол-во байт c подтверждением для Mode_Haval
// TimerUs _ack_tmr; // таймер для генерации импульов Mode_Haval
uint8_t _bit_length_us;
uint16_t _ack_pause_us;
bool FrameToRxQueue(void);
CircularBuffer<TLinFrame, 8> _rx_queue;
CircularBuffer<uint16_t, 16> _tx_buf; // буфер на передачу
TLinFrame _tx_fr_buf[16]; // кадры для передачи slave'ом
TLinFrame*_tx_fr_cur = _tx_fr_buf; // текущий передающийся кадр
bool StartSlaveTx(uint8_t id); // функция отправки этого кадра
TLinFrame * getTxFrame(void) // забрать фрейм из буфера (для imo_drv)
{
for (auto & it: _tx_fr_buf)
if (it.data_len > 0)
return &it;
return nullptr;
}
// возвращает номер канала
inline TLinChannel Instance(void) const
{
#ifdef MOBICAR_3
if (this == &LinBus3)
return LINch3;
#endif
if (this == &LinBus2)
return LINch2;
return LINch1;
}
#endif // not CAN_FIRMWARE
};
union TLinInit
{
struct TLin
{
uint16_t baudrate;
CLin::TLinMode mode;
uint32_t rxTimeout;
uint32_t sleepTimeout;
}Lin;
struct THaval
{
uint16_t baudrate;
CLin::TLinMode mode;
uint16_t rxTimeout;
uint32_t sleepTimeout;
uint8_t bytes_noack; // кол-во байт без подтверждения
uint8_t bytes_ack; // кол-во байт c подтверждением
uint16_t ack_pause_us; // пауза в us перед ack в режиме генерации (0-режим фильтрации)
}Haval;
};
#endif /* DRIVERS_LINBUS_H_ */