Code kills USB interface

Hi, All:

I started working on a spectrum analyzer, beginning with the test_radio_signal_rx app, and have been having inexplicable problems with the USB interface. The test_radio_signal_rx app was working well, and I made some changes to see if I understood everything before starting the new app.

In particular, the test_radio_signal code skipped output unless USB TX buffer space was available, but I want to have the code wait until buffer space become available, then output some data. I thought a while loop might accomplish that (see following), with the red LED lit to indicate waiting. The red LED does not light and the code kills the USB interface such that after a few moments, the PC reports that an unrecognized USB device is connected. A manual reset into bootloader mode is required to restore the wixel.

The code that follows, with the suspect section being “report_results”, is currently intended just to get some output on the USB serial connection, and should print the value of loop variable “i” twice. However, the wixel dies shortly after the app is downloaded. Note: the extra set of braces around the actual output loop seems to be required by the compiler. Variable declarations are evidently not recognized within “for” loops.

To make matters worse, the output code within the brackets in “report_results” can be transplanted to the test_radio_signal_rx app, and it works! So, something else must be wrong. I suspect the “while” and will try something else, but for the moment I’m stuck. If anyone has any insight, I would appreciate all comments.

Update: if I remove the “while” and put in a delayMs, sometimes the USB connection does not fail. However,
nothing appears on a correctly configured Hyperterm window connected to the wixel serial port.

Thanks, Jim


/* spectrum analyzer:
 * The receivers(s) (the Wixel(s) loaded with spectrum_analyzer) will
 * report the signal strength on all 256 channels.
 *
 * Reports channel # and  average signal strength (RSSI) in dBm+110.  This will be a number
 * typically between 10 and 100.
 *
 */

#include <wixel.h>
#include <radio_registers.h>
#include <stdio.h>
#include <usb.h>
#include <usb_com.h>

static volatile int16 DATA i,channel;
static volatile int32 DATA rssiSum;

static volatile int16 XDATA rssi[256];

void updateLeds()
{
    usbShowStatusWithGreenLed();
    LED_YELLOW(0) ;
    LED_RED(0);
}

void perTestRxInit()
{
    radioRegistersInit();


    MCSM0 = 0x14;    // Auto-calibrate  when going from idle to RX or TX.
    MCSM1 = 0x00;    // Disable CCA.  After RX, go to IDLE.  After TX, go to IDLE.
    // We leave MCSM2 at its default value = 0x07
	MDMCFG2 = 0x70;	//disable sync word detection
	RFST = 4; //idle radio
}

void CheckRadioChannels()
{
	LED_YELLOW(1);
	for(channel=0; channel<256; channel++)
		 {
		 CHANNR = channel;
		 RFST = 2;  // radio in RX mode and autocal
		 delayMs(1); //wait for RSSI to stabilize
		 rssiSum = 0;
		 for (i=0; i<100; i++)
		 	 {
			 rssiSum += radioRssi();
			 delayMicroseconds(10); //sample every 10 microseconds
		 	 }
		 RFST = 4; //idle radio
		 rssi[channel] = 110 + rssiSum/100;  //make it positive
		 }
	LED_YELLOW(0);
}

void reportResults()
{
		for (i=0; i<256; i++)
    	 {
     			while (usbComTxAvailable() < 20) LED_RED(1) ;    //wait for usb TX buffer space
     		   LED_RED(0) ;
     			{
     			   uint8 XDATA report[20];
     			   uint8 reportLength = sprintf(report, "%4d %5d \r\n", i, i);
     			   usbComTxSend(report, reportLength);
     			}
    	 }
}

void main()
{
    systemInit();
    usbInit();
    perTestRxInit();
    usbInit();
    while(1)
    {
    	boardService();
        usbComService();
        updateLeds();
//        CheckRadioChannels();
        reportResults();
     }
}

Hello.

If you don’t call usbComService(); in too long, the computer assumes the Wixel went away. Can you try add that to your while loop?

- Ryan

Hi, Ryan

Thanks very much, your suggestion worked. The code for the new output function follows. What is the maximum delay between calls to usbComService? It is mysterious that placing the call to usbComService just before the while loop does not work, so there must be some interaction with usbComTxAvailable.

Edit: Now I understand! The usb interface is (at least partially) polled, rather than interrupt driven, so the while loop would just hang in the previous non-working example. Now to get the radio working – the previously posted attempt does not work: the reported RSSI is a constant for all channels.

void reportResults()
{
		for (i=0; i<256; i++)
    	 {
			while (usbComTxAvailable() < 20) usbComService() ;    //wait for usb TX buffer space
      			   reportLength = sprintf(report, "%4d %5d \r\n", i, rssi[i]);
     			   usbComTxSend(report, reportLength);
     	 }
}

Hello, Jim.

In this post it sounds like you solved the problem you were having with RSSI. Is that right?

–David

Yes, the RSSI problem is solved. The value reported is evidently 0x7F if the radio is not in RX mode.

If sync word detection is disabled, the radio interprets noise as data bytes. Unless those are read, rx_overflow occurs, which in turn kicks the radio out of RX mode. This happens very quickly! For the purpose of the spectrum_analyzer, the trick is to keep reading the receive data register. In that case the radio will stay in RX as long as you want – except that you need to call usbComService to keep the USB interface alive! So, there is a conflict.

From the SDK documentation:

-Ryan