Skip to content
Snippets Groups Projects
Select Git revision
  • 53e7f831b7349e607fe76d0de9bda6f6d41e1035
  • main default protected
2 results

COBSUSBSerial.cpp

Blame
  • 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; 
      }
    }