lexus2k / tinyproto

Tiny Software Protocol for communication over UART, SPI, etc
GNU General Public License v3.0
225 stars 51 forks source link

proto.run_rx hangs indefinitely in Arduino #22

Closed redemption95 closed 2 years ago

redemption95 commented 2 years ago

Hi @lexus2k, The communication with Rpi, and Arduino could happen over the TinyLight protocol.

However, I want to use HDLC in Arduino as I am using from Pi side. Now, I have spent some hours now, debugging but it seems like there is some issue with the method

tinyproto::Hldc->run_rx()

I have no debugging environment set up so it was hard for me to debug further inside the library. But I have done some preliminary analysis. See sample code.

FD Example

#include "TinyProtocol.h"
tinyproto::Fd<64>  proto;

void onReceive(void *udata, tinyproto::IPacket &pkt) {
    // Process message here, you can do with the message, what you need
    // Let's send it back to the sender ;)
    Serial.println("Callback");
    if ( proto.write(pkt) == TINY_ERR_TIMEOUT ) {
        // Do what you need to do if looping back failed on timeout.
        // But never use blocking operations inside callback
    }
}

void setup() {
    Serial.begin(9600);
    Serial.println("Full duplex example");
    // ...
    // Here we say FD protocol object, which callback to call once new msg is received
    proto.setReceiveCallback( onReceive );
    proto.begin();
}

void loop() {
    if (Serial.available()) {
      Serial.println(Serial.available());
        uint8_t byte = Serial.read();
        // proto.run_rx( &byte, 1 ); // run FD protocol parser to process data received from the channel 

**The run_rx doesn't return and hangs indefinitely. I can see the buffer available() when this line is commented out. 
Also, the callback method onRecieve is never called even if valid packets are sent.**

    }
    // uint8_t byte;
    // if ( proto.run_tx( &byte, 1 ) == 1 ) // FD protocol fills buffer with data, we need to send to the channel
    // {
    //     while ( Serial.write( byte ) == 0 ); // Just send the data
    // }
}

HDLC Example :

#include <TinyProtocol.h>
#include <SoftwareSerial.h>
/* Creating protocol object is simple */
//tinyproto::Light  proto;
//tinyproto::Packet<16> hdlc_packet;

int buff[16];
tinyproto::Hdlc proto_hdlc(buff, 16);

SoftwareSerial mySerial(A3, A2);

void hdlcRecieveCallback(tinyproto::IPacket &pkt)
{
    //Recive and process packets
    Serial.println("HDLC Recieve callback");
    // Serial.println(pkt.data());
    Serial.println("=========================");
}
void setup() {
    /* No timeout, since we want non-blocking UART operations. */
    Serial.setTimeout(0);
    mySerial.setTimeout(0);
    /* Initialize serial protocol for test purposes */
    Serial.begin(9600);
    mySerial.begin(57600);
    proto_hdlc.setReceiveCallback(hdlcRecieveCallback);
    proto_hdlc.begin();
    // proto_hdlc.begin([](void *p, const void *b, int s) -> int { return mySerial.write((const uint8_t *)b, s); },
    //           [](void *p, void *b, int s) -> int { return mySerial.readBytes((uint8_t *)b, s); });
    proto_hdlc.disableCrc();
}

void loop()
{

    if (mySerial.available()) {
        Serial.println(String(mySerial.available()));
        uint8_t byte = mySerial.read();
        //Serial.println(proto_hdlc.run_rx( &byte, 1 )); // run FD protocol parser to process data received from the channel

      **[ HERE ] : Blocks indefinitely and the call back is never called.** 
    }
    // uint8_t byte;
    // if ( proto_hdlc.run_tx( &byte, 1 ) == 1 ) //FD protocol fills buffer with data, we need to send to the channel
    // {
    //     while ( mySerial.write( byte ) == 0 ); // Just send the data
    // }
}

Please correct me I am doing something wrong. Or is there something that needs correction. Thank you. Sasank Panda

redemption95 commented 2 years ago

Increasing the buffer solved the issue. The buffer was always overflowing.