API serial eagain error

Hi all,

Somebody please help me.

I am trying to get API mode works on a local module by following the instructions on XBee/XBee Pro RF Manual for v1.xEx (page 59, printed 2009.9.23). However the read() fails and the error message is EAGAIN ERROR .

The module firmware version is correct, it is attached to a FoxBoard-LX832, which runs on Linux platform. I have no problem in running AT commands at transparent mode.

I wrote the code that describes the AT command frame as:


static char API1[] = {0x7E, 0x00, 0x04, 0x08, 0x52, 0x44, 0x4C, 0x15};

int wi = write(fd, &API1, 8);

Could it be the frame format is wrong?

Many thanks.

Andrew[img]

The packet is correct: here’s what the packet-check program (see pinned posts) has to say about it:

[john@eccles ~]$ packet-check
API Packet analyzer version 1.1 for Series 1 XBee (802.15.4)
Note: if it prompts for more bytes and you’re done, hit return
Enter packet: 7e 00 04 08 52 44 4c 15

Packet: 7E 00 04 08 52 44 4C 15
7E // Correct packet header byte
00 04 // payload length (decimal 4)
08 // Packet type: local AT command with immediate action
52 // frame id: non-zero so response packet expected
44 4C // AT command “DL”
15 // checksum - correct

So you’re asking for the value of the DL register, which is a perfectly reasonable thing to do.

The EAGAIN error suggests that you’ve opened the port for reading in non-blocking mode and that at the point where you try to read it there’s no data available yet because the XBee hasn’t responded. Try it with a short delay before the read, and if that works you’ll need to modify the code to react when data is available (or use blocking mode, but non-blocking is a much better idea overall).

You might also want to think about using unsigned char as the data type. Char won’t hurt in your example, but people have in the past been bitten by finding negative values when converting to int from the array (see FAQ Q4).

Hope that helps

Hi johnf,

Thank you for the reply.

I tried a delay of read() for up to 10 seconds but no luck — same error message.

I tried unblocking mode and the program waits for reply forever, i.e. still no luck.

In both occasions I tried signed and unsigned char.

Here is my code:

/******************************************/

#include /* Standard input/output definitions /
#include /
String function definitions /
#include /
UNIX standard function definitions /
#include /
File control definitions /
#include /
Error number definitions /
#include /
POSIX terminal control definitions */

int fd;

int readport(int fd, char *result) {
int iIn = read(fd, result, 254);
result[iIn-1] = 0x00;
if (iIn < 0) {
if (errno == EAGAIN) {
printf("SERIAL EAGAIN ERROR
");
return 0;
} else {
printf("SERIAL read error %d %s
", errno, strerror(errno));
return 0;
}
}
return 1;
}

int initport(int fd) {
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);

options.c_cflag |= (CLOCAL | CREAD);

options.c_cflag &amp;= ~PARENB;
options.c_cflag &amp;= ~CSTOPB;
options.c_cflag &amp;= ~CSIZE;
options.c_cflag |= CS8;

tcsetattr(fd, TCSANOW, &amp;options);
return 1;

}

int main(int argc, char **argv) {

fd = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
	perror("open_port: Unable to open /dev/ttyS2 - ");
	return 1;
} else {
	fcntl(fd, F_SETFL, 0);
}

initport(fd);

// static char API1[] = {0x7E00040852444C15};
static unsigned char API1[] = {0x7E, 0x00, 0x04, 0x08, 0x52, 0x44, 0x4C, 0x15};

printf("written:%x

", API1);
int wi = write(fd, &API1, 8);
usleep(2000000);
fcntl(fd, F_SETFL, FNDELAY); // don’t block serial read

char sResult[254];
if (!readport(fd,sResult)) {
	printf("read failed

");
close(fd);
return 1;
}

printf("readport=%s

", sResult);

close(fd);
return 0;

}

/*******************************************/

DoI need to change the format of the byte expression so that the XBee module could understand and response? I tried ‘\x7E’, ‘0x7E’ but no luck so far.

Thanks.

Andrew

Hi johnf,

problem solved by changing the port setting to:

int initport(int fd) {
struct termios oldtio, newtio;

tcgetattr(fd, &amp;oldtio);
bzero(&amp;newtio, sizeof(newtio));
newtio.c_cflag = B9600 | CS8 |CREAD | CLOCAL;
newtio.c_iflag = IGNPAR;
newtio.c_lflag = 0;   
newtio.c_oflag = 0;    
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &amp;newtio);

}

Thanks.

Andrew[b]Hi johnf,

problem solved by changing the port setting to:

int initport(int fd) {
struct termios oldtio, newtio;

tcgetattr(fd, &amp;oldtio);
bzero(&amp;newtio, sizeof(newtio));
newtio.c_cflag = B9600 | CS8 |CREAD | CLOCAL;
newtio.c_iflag = IGNPAR;
newtio.c_lflag = 0;   
newtio.c_oflag = 0;    
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &amp;newtio);

}

Thanks.

Andrew[/b]Hi johnf,

problem solved by changing the port setting to:

int initport(int fd) {
struct termios oldtio, newtio;

tcgetattr(fd, &amp;oldtio);
bzero(&amp;newtio, sizeof(newtio));
newtio.c_cflag = B9600 | CS8 |CREAD | CLOCAL;
newtio.c_iflag = IGNPAR;
newtio.c_lflag = 0;   
newtio.c_oflag = 0;    
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &amp;newtio);

}

Thanks.

Andrew

Glad you got it working!