Select Git revision
COBSUSBSerial.cpp
COBSUSBSerial.cpp 2.34 KiB
// link !
// TODO: pls use nanocobs, for encode- and decode-in-place, to save big (!) memory
// on new link layer... to fit into D11s...
#include "COBSUSBSerial.h"
#include "cobs.h"
#if defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_RP2040)
COBSUSBSerial::COBSUSBSerial(SerialUSB* _usbcdc){
usbcdc = _usbcdc;
}
#else
COBSUSBSerial::COBSUSBSerial(Serial_* _usbcdc){
usbcdc = _usbcdc;
}
#endif
void COBSUSBSerial::begin(void){
usbcdc->begin(9600);
}
void COBSUSBSerial::loop(void){
// check RX side:
// while data & not-full,
while(usbcdc->available() && rxBufferLen == 0){
rxBuffer[rxBufferWp ++] = usbcdc->read();
if(rxBuffer[rxBufferWp - 1] == 0){
// decoding in place should always work: COBS doesn't revisit bytes
// encoding in place would be a different trick, and would require the use of
// nanocobs from this lad: https://github.com/charlesnicholson/nanocobs
size_t len = cobsDecode(rxBuffer, 255, rxBuffer);
// now we are with-packet, set length and reset write pointer
// len includes the trailing 0, rm that...
rxBufferLen = len - 1;
rxBufferWp = 0;
}
}
// check tx side,
while(txBufferLen && usbcdc->availableForWrite()){
// ship a byte,
usbcdc->write(txBuffer[txBufferRp ++]);
// if done, mark empty
if(txBufferRp >= txBufferLen){
txBufferLen = 0;
txBufferRp = 0;
}
}
}
size_t COBSUSBSerial::getPacket(uint8_t* dest){
if(rxBufferLen > 0){
memcpy(dest, rxBuffer, rxBufferLen);
size_t len = rxBufferLen;
rxBufferLen = 0;
return len;
} else {
return 0;
}
}
boolean COBSUSBSerial::clearToRead(void){
return (rxBufferLen > 0);
}
void COBSUSBSerial::send(uint8_t* packet, size_t len){
// we have a max: we need to stuff into 255,
// and we have a trailing zero and the first key
if(len > 253) len = 253;
// ship that,
size_t encodedLen = cobsEncode(packet, len, txBuffer);
// stuff 0 byte,
txBuffer[encodedLen] = 0;
txBufferLen = encodedLen + 1;
txBufferRp = 0;
}
boolean COBSUSBSerial::clearToSend(void){
// we're CTS if we have nothing in the outbuffer,
return (txBufferLen == 0);
}
// we should do some... work with this, i.e.
// keepalives, to detect if other-end is open or not...
boolean COBSUSBSerial::isOpen(void){
if(usbcdc){
return true;
} else {
return false;
}
}