Author Topic: GZLL interrupts and serial read issue  (Read 1389 times)

vincc

  • RFduino Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
GZLL interrupts and serial read issue
« on: September 14, 2015, 04:37:40 AM »
Hello gentlemen,

I'm experiencing some issues when serial communication and GZLL co-exist in my code. The communication protocol I'm trying to implement is very simple: I have 2 RFduino (1 HOST and 1 DEVICE) and they have to work as a serial pass-through communication with 32 bytes packet exchange. For example, the DEVICE waits on its serial port until 32 bytes are received, then it send the whole 32 bytes packet on radio using RFduinoGZLL.sendToHost() call. At this point, if the HOST is present, it will ack on the DEVICE triggering the interrupt RFduinoGZLL_onReceive().
It happens that when the HOST is turned on(i.e. when ack interrupt is sent), readings on serial port aren't anymore stable because occasionally I start loosing bytes and getting other bytes wrong.


After some time spent trying to understand what was going on, I understood that:

1) serial communication alone works properly; I implemented a loopback write on the serial port every time 32 bytes are received on the same port; it worked properly for several minutes @115200 bps (T=20ms);

2) bluetooth exchange works properly; the receiver gets always the same data the sender is trasmitting;

so I discovered serial reading is affected by some issue when there are interrupts in the system.

Does anyone of you have experieced the same kind of problem?
Any advice would be greatly appreciated. If it can be useful, I can share my code.

Vincenzo



« Last Edit: September 14, 2015, 11:10:40 PM by vincc »

vincc

  • RFduino Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: GZLL interrupts and serial read issue
« Reply #1 on: September 14, 2015, 11:07:52 AM »
Device code:

Code: [Select]
#include <RFduinoGZLL.h>

#define HOST_POLLING_INTERVAL         50   // ms
#define PACKET_SIZE                   32
#define SERIAL_BAUDRATE           115200


// Global variables
device_t  role;

bool      send2serial;
bool      send2bluetooth;
bool      polling_enabled;
unsigned long last_bluetoothtx_timestamp;
unsigned int serial_rx_counter;

char      BluetoothRxSerialTx_buffer[PACKET_SIZE];
char      SerialRxBluetoothTx_buffer[PACKET_SIZE];


/* Setup function ----------------------------------------------------------------*/
void setup()
{
  int dummy;
 
  role             = DEVICE0;
  send2serial      = false;
  send2bluetooth   = false;
  polling_enabled  = false;
  last_bluetoothtx_timestamp = millis();
  serial_rx_counter = 0;

  if(RFduinoGZLL.begin(role) != 0)          // start the GZLL stack
    RFduino_systemReset();
 
  //Serial.begin(SERIAL_BAUDRATE, 2, 3);
  Serial.begin(SERIAL_BAUDRATE);            // Serial initialization
 
  while (Serial.available())                // Clean the serial buffer
    dummy =  (unsigned char) Serial.read();
}
/**********************************************************************************/


/* Loop function -----------------------------------------------------------------*/
void loop()
{

  // Send to serial
  if (send2serial == true)  {        // if I've received a packet from bluetooth
    for(int i=0; i<32; i++)
      Serial.write(BluetoothRxSerialTx_buffer[i]);  // send it out the serial port             
    send2serial = false;                                     // clear the flag
  }
 
  // Send to bluetooth
  if (send2bluetooth == true)  {
    //Serial.write((uint8_t *)SerialRxBluetoothTx_buffer, 32);  // DEBUG POURPOSE
    polling_enabled = false;
    RFduinoGZLL.sendToHost(SerialRxBluetoothTx_buffer, 32);
    last_bluetoothtx_timestamp = millis();
    polling_enabled = true;
    send2bluetooth = false;
  }
 
  // Polling to host
  if (millis() - last_bluetoothtx_timestamp > HOST_POLLING_INTERVAL && polling_enabled == true)  {
    RFduinoGZLL.sendToHost(NULL, 0);
    last_bluetoothtx_timestamp = millis();
  }

}
/**********************************************************************************/


void serialEvent()  {
  SerialRxBluetoothTx_buffer[serial_rx_counter] = (char) Serial.read();
  serial_rx_counter++;
  if( serial_rx_counter == 32 ) {
    serial_rx_counter = 0;
    send2bluetooth = true;
    }
}


/* RFduinoGZLL_onReceive ISR -----------------------------------------------------*/
void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
  if (len == 32 && send2serial == false)  {                    // if a packet came from bluetooth and there isn't a serial tx ongoing
    for(int i = 0; i < 32; i++)                              // store the packet in BluetoothRxSerialTx
      BluetoothRxSerialTx_buffer[i] = data[i];
    send2serial = true;                                      // set the send2serial to start com on loop function
  }
}
/**********************************************************************************/


Host code:

Code: [Select]

#include <RFduinoGZLL.h>

#define PACKET_SIZE           32
#define SERIAL_BAUDRATE   115200


// Global variables
device_t  role;
bool      send2serial;
bool      send2bluetooth;
uint8_t   BluetoothRxSerialTx_buffer[PACKET_SIZE];
char      SerialRxBluetoothTx_buffer[PACKET_SIZE];


/* Setup function ----------------------------------------------------------------*/
void setup()
{
  int dummy;
 
  role           = HOST;
  send2serial    = false;
  send2bluetooth = false;
 
 
  if(RFduinoGZLL.begin(role) != 0)       // start the GZLL stack
    RFduino_systemReset();

  Serial.begin(SERIAL_BAUDRATE);         // start serial com
 
  NVIC_SetPriority(UART0_IRQn, 3);
 
  while(Serial.available())              // clear the serial buffer
    dummy = Serial.read();
 

}
/**********************************************************************************/


/* Loop function -----------------------------------------------------------------*/
void loop() {
 
   if(Serial.available() >= 32 && send2bluetooth == false) {
      for(int i = 0; i<32 ; i++)  {
        SerialRxBluetoothTx_buffer[i] = (char) Serial.read();
      }
      // Serial.write((uint8_t*)SerialRxBluetoothTx_buffer, 32);  //Debug purpose
      send2bluetooth = true;
   }
 
  if (send2serial == true)  {
      Serial.write(BluetoothRxSerialTx_buffer, 32);
      send2serial = false;
   }

}
/**********************************************************************************/


/* RFduinoGZLL_onReceive ISR -----------------------------------------------------*/
void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
 
  if (len == 32 && send2serial == false)  {
    for (int i=0;i<32;i++)
      BluetoothRxSerialTx_buffer[i] = data[i];
    send2serial = true;
  }
 
  if (send2bluetooth == true)  {
    RFduinoGZLL.sendToDevice(device, SerialRxBluetoothTx_buffer, 32);
    send2bluetooth = false;
  }
}
/**********************************************************************************/


« Last Edit: September 14, 2015, 11:10:05 PM by vincc »