add files
This commit is contained in:
1 parent
3eaff3a647
commit
e76a9c1e9b
9 files changed
+752
No files matched your search
@@ -0,0 +1,133 @@
|
||||
// =====================================================================
|
||||
// LD2453Parser.cpp
|
||||
//
|
||||
// See the big comment at the top of LD2453Parser.h before touching
|
||||
// this file. The acquisition/debug layer below is fully functional;
|
||||
// tryParseFrame() is intentionally stubbed pending the official
|
||||
// HLK-LD2453 protocol.
|
||||
// =====================================================================
|
||||
#include "LD2453Parser.h"
|
||||
|
||||
#if !defined(ARDUINO_ARCH_ESP32)
|
||||
#warning "LD2453Parser was written/tested against the ESP32 Arduino core. Verify HardwareSerial pin-remap behavior on other cores."
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// PLACEHOLDER PROTOCOL CONSTANTS
|
||||
//
|
||||
// None of the values below are confirmed. They exist only so the
|
||||
// state machine in tryParseFrame() has something concrete to compare
|
||||
// against once you fill them in from the real manual or from a
|
||||
// DEBUG_RADAR_RAW capture. Do not rely on these for real parsing.
|
||||
// ---------------------------------------------------------------
|
||||
// static const uint8_t FRAME_HEADER[] = { 0x00, 0x00, 0x00, 0x00 }; // TODO: confirm
|
||||
// static const uint8_t FRAME_TAIL[] = { 0x00, 0x00 }; // TODO: confirm
|
||||
// static const size_t TARGET_RECORD_SIZE = 0; // bytes per target, TODO: confirm
|
||||
// static const size_t MAX_TARGETS = 3;
|
||||
|
||||
void LD2453Parser::begin(HardwareSerial &serial, int rxPin, int txPin, uint32_t baud,
|
||||
const char *nodeId, bool rawDebug) {
|
||||
_serial = &serial;
|
||||
_rawDebug = rawDebug;
|
||||
_nodeId = nodeId;
|
||||
_bufferLen = 0;
|
||||
_sequenceCounter = 0;
|
||||
_stats = LD2453Stats{};
|
||||
_ppsWindowStart = millis();
|
||||
_ppsWindowCount = 0;
|
||||
|
||||
// HardwareSerial::begin(baud, config, rxPin, txPin) — ESP32 Arduino
|
||||
// core supports remapping RX/TX to any capable GPIO. 8N1 assumed;
|
||||
// confirm against the official manual.
|
||||
_serial->begin(baud, SERIAL_8N1, rxPin, txPin);
|
||||
}
|
||||
|
||||
void LD2453Parser::dumpRawHex(const uint8_t *data, size_t len) {
|
||||
Serial.print(F("[RAW] "));
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (data[i] < 0x10) Serial.print('0');
|
||||
Serial.print(data[i], HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.print(F(" (len="));
|
||||
Serial.print(len);
|
||||
Serial.println(')');
|
||||
}
|
||||
|
||||
void LD2453Parser::feedByte(uint8_t b) {
|
||||
if (_bufferLen >= RING_BUFFER_SIZE) {
|
||||
// Buffer overrun with no recognized frame boundary — drop the
|
||||
// oldest half so we can keep tolerating a stuck/garbage stream
|
||||
// without ever blocking or allocating.
|
||||
memmove(_ringBuffer, _ringBuffer + RING_BUFFER_SIZE / 2, RING_BUFFER_SIZE / 2);
|
||||
_bufferLen = RING_BUFFER_SIZE / 2;
|
||||
_stats.parseErrors++;
|
||||
}
|
||||
_ringBuffer[_bufferLen++] = b;
|
||||
}
|
||||
|
||||
bool LD2453Parser::update() {
|
||||
if (!_serial) return false;
|
||||
|
||||
bool gotFrame = false;
|
||||
|
||||
// Drain whatever is available right now — non-blocking, no delay().
|
||||
// While rawDebug is on, dump exactly the newly-arrived bytes as
|
||||
// hex so you can capture real traffic to reverse-engineer the
|
||||
// frame format, independent of whether tryParseFrame() (still a
|
||||
// stub) recognizes anything.
|
||||
size_t newBytesStart = _bufferLen;
|
||||
while (_serial->available() > 0) {
|
||||
uint8_t b = (uint8_t)_serial->read();
|
||||
feedByte(b);
|
||||
_stats.bytesReceived++;
|
||||
}
|
||||
if (_rawDebug && _bufferLen > newBytesStart) {
|
||||
dumpRawHex(_ringBuffer + newBytesStart, _bufferLen - newBytesStart);
|
||||
}
|
||||
|
||||
// Try to pull as many complete frames out of the buffer as
|
||||
// possible in this call (in case several arrived since the last
|
||||
// loop() iteration).
|
||||
while (tryParseFrame()) {
|
||||
gotFrame = true;
|
||||
_stats.framesParsed++;
|
||||
_ppsWindowCount++;
|
||||
}
|
||||
|
||||
// Update packets-per-second once a second, non-blocking.
|
||||
uint32_t now = millis();
|
||||
if (now - _ppsWindowStart >= 1000) {
|
||||
_stats.packetsPerSecond = _ppsWindowCount * 1000.0f / (now - _ppsWindowStart);
|
||||
_ppsWindowStart = now;
|
||||
_ppsWindowCount = 0;
|
||||
}
|
||||
|
||||
return gotFrame;
|
||||
}
|
||||
|
||||
bool LD2453Parser::tryParseFrame() {
|
||||
// -----------------------------------------------------------
|
||||
// STUB: real frame sync/parse goes here once the official
|
||||
// HLK-LD2453 protocol is confirmed. Suggested shape, mirroring
|
||||
// the LD2410/LD2450 family's approach (adapt once verified):
|
||||
//
|
||||
// 1. Scan _ringBuffer for FRAME_HEADER.
|
||||
// 2. If found but fewer than (header + declared length + tail)
|
||||
// bytes are available yet, return false and wait for more
|
||||
// bytes next call (do NOT block).
|
||||
// 3. Verify FRAME_TAIL at the expected offset.
|
||||
// 4. If rawDebug, dumpRawHex() the whole candidate frame.
|
||||
// 5. Decode each target record into RadarTarget (x_mm, y_mm,
|
||||
// speed, and distance/angle only if the protocol actually
|
||||
// carries them).
|
||||
// 6. Fill _lastFrame (timestamp_ms = millis(), sequence_number
|
||||
// = ++_sequenceCounter, node_id = _nodeId, targetCount).
|
||||
// 7. memmove() the consumed bytes out of _ringBuffer.
|
||||
// 8. Return true.
|
||||
//
|
||||
// Until then, this always returns false so callers never receive
|
||||
// fabricated coordinates.
|
||||
// -----------------------------------------------------------
|
||||
return false;
|
||||
}
|
||||
Reference in new issue
Block a user