bafang-esp32/src/bafang_MotorMaster.cpp

116 lines
2.4 KiB
C++

#include <Arduino.h>
#include "utils.h"
#include "main.h"
#include "bafang.h"
namespace Bafang {
namespace MotorMaster {
typedef void (*CommandCallback)(void *pUser, uint8_t *pData, int dataLen, bool crcError);
struct MotorCommand {
uint8_t *pSend;
uint8_t len;
bool crc;
CommandCallback pfnCallback;
void *pUser;
};
enum eMotorState {
STATE_IDLE = 0,
STATE_AWAITING = 1,
STATE_SUPERFLUOUS = 2
};
eMotorState g_State;
uint8_t g_RxBuffer[255];
uint8_t g_RxBufferLen = 0;
unsigned long g_LastRx = 0;
const sPacketDesc *g_pPacketDesc = NULL;
void OnData(uint8_t c)
{
if(!g_RxBufferLen)
g_LastRx = millis();
if(millis() - g_LastRx > 2 * BYTE_TIME)
{
g_State = STATE_IDLE;
g_RxBufferLen = 0;
g_pPacketDesc = NULL;
}
if(g_State == STATE_IDLE)
g_State = STATE_SUPERFLUOUS;
if(g_RxBufferLen >= sizeof(g_RxBuffer))
return;
g_RxBuffer[g_RxBufferLen++] = c;
if(g_pPacketDesc)
{
const sPacketDesc::sInfo &info = g_pPacketDesc->res;
if(info.len < 0)
{
g_State = STATE_IDLE;
return;
}
int readLen = info.len;
if(info.crc)
readLen++;
if(g_RxBufferLen < readLen)
return;
if(info.crc)
{
uint8_t crc = 0;
for(int i = 0; i < g_RxBufferLen - 1; i++)
crc += g_RxBuffer[i];
if(c != crc)
{
char bla[16];
bytes2hex(g_RxBuffer, g_RxBufferLen, bla, sizeof(bla));
Serial.printf("!!! CRC ERROR %X != %X -> %s\n", c, crc, bla);
g_State = STATE_IDLE;
return;
}
}
OnMotorResponse(g_pPacketDesc, g_RxBuffer, g_RxBufferLen);
g_State = STATE_IDLE;
g_RxBufferLen = 0;
g_pPacketDesc = NULL;
}
g_LastRx = millis();
}
void tick()
{
if((g_State == STATE_SUPERFLUOUS || g_State == STATE_AWAITING) && g_RxBufferLen && millis() - g_LastRx > 2 * BYTE_TIME)
{
OnMotorResponse(g_pPacketDesc, g_RxBuffer, g_RxBufferLen);
g_State = STATE_IDLE;
g_RxBufferLen = 0;
g_pPacketDesc = NULL;
}
}
void SendRawPacket(const sPacketDesc *packet, uint8_t *data, uint8_t dataLen)
{
g_State = STATE_AWAITING;
g_RxBufferLen = 0;
g_pPacketDesc = packet;
MotorSerial.write(data, dataLen);
}
}
}