Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Custom app stops when recieving radio data


#1

Hey folks,
I’m making a custom app to communicate between up to 8 devices, at 100hz.
I’m using the radio_mac library, because the queue and link libraries are limited to two devices, although at this time I only have two to test with.

Right now I set it up as a tty repeater, to try to isolate the issue. (I open two terminal emulators and attach them to the appropriate ports, and when I type in one, it should appear in the other)

The app seems to stop when a packet is recieved, but not every time. I’ve tried to remove every opportunity to seg-fault, but I’m wondering if the issue is the DMA writing to an address at the same time as the CPU is reading from it. I’m not sure, though, because disabling the non-interrupt recieving code doesn’t seem to solve the issue.

Any suggestions are appreciated.
radio8_source.tar.gz (1.57 KB)


#2

Hello.

I am sorry you are having trouble with programming the Wixel.

The radio_queue library is not limited to just communicating with one other device.

I noticed that in one of the places where you call usbComTxSendByte, you are not calling usbComTxAvailable first to ensure there is space in the USB buffers. That could cause problems.

One way to debug your app would be to add temporary lines of code in certain places to blink the LEDs. If you see activity on those LEDs, then you know that those parts of your app are being run. You said the app seems to stop, so one of the first things I would try is to blink an LED in the main loop and see if the LED keeps blinking after the app seems to stop. That would tell you whether the main loop is running or not. If you have an oscilloscope, you can use these kinds of debugging signals to get a lot of insight into what your app is doing.

Another approach would be to rewrite your app to use radio_queue and see if that works for you. Once you have something that basically works, you could slowly modify the radio_queue library and the app to suit your needs, while testing your app frequently to make sure your modifications have not broken anything.

I don’t think this is an issue with DMA. The radio_mac library should take care of the DMA issues for you.

If you would like more help, please try to simplify your program further. You should move everything from radio8.h into radio8.c so that your entire program is just in one file, and post that file here using [code ] and [/code ] tags (without the spaces). You can reduce the switch statement in main() to a simple if statement, and get rid of things like #if 1. You should remove unused variables like rx_buffer_index and tx_buffer_index. Also, please give a specific explanation of what goes wrong: instead of just saying “the app seems to stop”, you should say exactly what you were doing to the Wixel, what behavior you observed, and what behavior you expected. You should say exactly what inputs you provided to all the Wixels in your system starting from when they were first powered on.

–David


#3

EDIT: I just changed the reciever to toggle red LED instead of yellow, and now it doesn’t crash. What’s going on?

I’ve included what I was going to post below:

[quote]David, thanks for the tips. I think I’ve followed most of them.

First, I’ve made two apps, to isolate the issue. One only sends, and one only recieves. The sender works fine - I’ve tested it with the radio sniffer. However, the receiver crashes after a few messages have been recieved - maybe 5, or 3, or 13, or somewhere in between. It’s not the same every time I run it. Here’s how I know it crashes:
(1) The yellow LED is solid, and the green one does a double-blink every second.
(2) The “wixelconfig” program says that the app is stopped.

First, the sender code:

[code]/** Dependencies **************************************************************/

#include <radio_mac.h>
#include <board.h> // for LEDs
#include <cc2511_map.h>
#include <dma.h>
#include <radio_registers.h>

#include <usb.h>
#include <usb_com.h>

#include <stdio.h>
#include <string.h>

/** Global Variables *********************************/

#define RADIO_COUNT 2
#define MAX_TIMEOUT 50
#define MAX_PACKET_LEN 5

int32 CODE param_radio_channel = 128; // 0 - 255. Seperate by 2 channels to avoid crosstalk

uint8 XDATA rx_packet[MAX_PACKET_LEN + 4]; // room to store CRC
uint8 XDATA tx_packet[MAX_PACKET_LEN];
volatile uint8 PDATA radio_tx_available = 0;
volatile uint8 DATA respond_state = 0;
#define MESSAGE_RCV 1
#define BAD_CRC 2
#define RADIO_ID_ERROR 3
#define RADIO_TIMEOUT 4

/** Functions *****************************************************************/

void radioInitAddendum() {
CHANNR = param_radio_channel;
PKTLEN = MAX_PACKET_LEN;
}

void radioMacEventHandler( uint8 event) {
if(radio_tx_available){
radioMacTx( tx_packet );
LED_RED(1);
radio_tx_available = 0;
} else {
LED_RED(0);
}
}

void main( void ) {
uint8 PDATA i = 1; // counter
char DATA letter = ‘z’;

systemInit();
usbInit();
radioMacInit();
radioInitAddendum();

while(1){
	boardService();
	usbComService();
	
	
	if( --i == 0 ) {
		i = 100;
		if( !radio_tx_available ){
			if( usbComTxAvailable() > 1){
				usbComTxSendByte( letter );
			}
			tx_packet[1] = letter;
			tx_packet[0] = 1; // lenght of packet, excluding this byte
			radio_tx_available = 1;
			radioMacStrobe();
		}
	}
	
	if( usbComRxAvailable() ) {
		letter = usbComRxReceiveByte();
		i = 1; //send the new character right away
	} else {
		delayMs(5);
	}

}

}[/code]

And now the reciever code, which is crashing:

[code]/** Dependencies **************************************************************/

#include <radio_mac.h>
#include <board.h>
#include <cc2511_map.h>
#include <dma.h>
#include <radio_registers.h>
#include <usb.h>
#include <usb_com.h>

/** Global Variables *********************************/

#define MAX_TIMEOUT 50
#define MAX_PACKET_LEN 5

int32 CODE param_radio_channel = 128; // 0 - 255. Seperate by 2 channels to avoid crosstalk

uint8 XDATA rx_packet[MAX_PACKET_LEN + 4]; // room to store CRC
volatile uint8 DATA message_available = 0;

/** Functions *****************************************************************/

/* This function is declared in radio_mac.h, but needs to be defined here */
void radioMacEventHandler( uint8 event) {

if( event == RADIO_MAC_EVENT_RX){ //Packet recieved
	message_available = 1;
	LED_YELLOW_TOGGLE();
}
radioMacRx( rx_packet, MAX_TIMEOUT );

}

void main( void ) {

CHANNR = param_radio_channel;
PKTLEN = MAX_PACKET_LEN;
systemInit();
usbInit();
radioMacInit();
radioMacStrobe();

while(1){
	boardService();
	usbComService();
	
	if( message_available && usbComTxAvailable() ){
		usbComTxSendByte(rx_packet[1]);
		message_available = 0;
	}
}

}[/code]

Here’s my testing procedure:
I plug in the wixel with the reciever code, and wait two seconds. Then I plug in the wixel with the sender code. Then I count the toggles of the yellow LED on the reciever, to see how many messages it recieves before it crashes.

[/quote]


#4

It sounds like your Wixel is going into bootloader mode by accident. I think that this code in libraries/src/wixel/board.c is causing the problem:

void boardStartBootloaderIfNeeded()
{
    if (!(P2DIR & (1<<2)))       // If the yellow LED is off...
    {
        delayMicroseconds(10);
        if (P2_2)
        {
            boardStartBootloader();
        }
    }
}

Unfortunately, that code assumes that if the yellow LED is off then it will remain off for 10 microseconds before we check the voltage on P2_2. That assumption is not true if you are toggling the yellow LED from an interrupt.

That function is called by boardService. If you want to toggle the yellow LED in an interrupt, you should probably stop calling boardService in your app. However, you would then lose the ability to start the bootloader by shorting P2_2 to 3V3 while the app is running. There are other ways to start the bootloader, so that is probably fine.

–David