Patrick222122
Posts: 80
Joined: Sun Dec 02, 2012 5:51 pm

uart and propellor

Fri Jan 11, 2013 3:42 pm

If you have seen my previous posts, you know I am trying to get a propellor development board to communicate with my pi. Well I think almost got it by using the in built UART port. Unfortuantly the communications is not working. I belive I got it wired correctly, gnd to gnd, robot rx to pi tx and vise versa and 5v to 5v. I think it may be a bug in the code for when I tried this code a member gave me in another post, the output was simply speed 11.
#include <stdio.h> /* Standard input/output definitions */
#include <stdlib.h> /* exit */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <ctype.h> /* isxxx() */

/* ------------------------------------------------------------------------

cc -o 433 433.c

Usage ./433 [option] ...

-r, receiver (default)

-t, transmitter

-s BPS, bits per second, default 2400
(300, 600, 1200, 1800, 2400, 4800, 9600, 19200)

-m COUNT, test messages, default 1000

./433 -t -s4800 -m500 run as transmitter send 500 messages at 4800 bps
./433 -r -s4800 run as receiver (default), receive at 4800 bps

-------------------------------------------------------------------------- */

#define PREAMBLE 0x21
#define SYNC 0xAA

int rx = 1; /* defaults to receiver end */
int messages = 1000; /* default send 1000 test messages */
speed_t speed = B2400; /* default to 2400 bps */

struct termios orig;
int filedesc;

/* prototypes */

int openSerialPort (char * device, int bps);
void tx_message (int fd, int mlen, char * dat);
int rx_message (int fd, char * dat);
int initOpts (int argc, char *argv[]);
void tidyup(void);

int main(int argc, char *argv[])
{
int i, c;
char buf[512];

initOpts(argc, argv);

filedesc = openSerialPort("/dev/ttyAMA0", speed);

if (filedesc == -1) exit(1);

atexit(tidyup);

if (rx)
{
while(1)
{
usleep(100);
c = rx_message(filedesc, buf);
if (c > 0)
{
buf[c]=0;
printf(buf);
}
}
}
else
{
for (i=1; i<=messages; i++)
{
sprintf(buf, "message #%d\n", i);
tx_message(filedesc, strlen(buf), buf);
usleep(500); /* delay between messages */
}
}
return 0;
}

void tidyup(void)
{
fflush(NULL); /* flush output */

/* important to use TCSAFLUSH, otherwise buffered messages will be lost */
tcsetattr(filedesc, TCSAFLUSH, &orig); /* restore original serial settings */
}

int openSerialPort(char * device, int bps)
{
int fd;
struct termios new;
char buf[128];

fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);

if (fd == -1)
{
sprintf(buf, "openSerialPort %s error", device);
perror(buf);
}
else
{
tcgetattr(fd, &orig); /* save current serial settings */
tcgetattr(fd, &new);
cfmakeraw(&new);
fprintf(stderr, "speed=%d\n", bps);
cfsetispeed(&new, bps);
cfsetospeed(&new, bps);
tcsetattr(fd, TCSANOW, &new); /* set new serial settings */
fcntl (fd, F_SETFL, O_RDWR);
}
return fd;
}

int checksum(int len, char * dat)
{
int cksm;
int i;

cksm = 0;
for (i=0; i<len; i++) cksm ^= dat;

return cksm;
}

void tx_message(int fd, int mlen, char * dat)
{
char buf[300];
char cksm;
int wrote;

buf[0] = SYNC; /* gives time for the receiving uart to sync */
buf[1] = SYNC; /* gives time for the receiving uart to sync */
buf[2] = PREAMBLE;
buf[3] = mlen;

memcpy(buf+4, dat, mlen);

cksm = checksum(mlen+2, buf+2);
buf[mlen+4] = cksm;

wrote = write(fd, buf, mlen+5);
if (wrote != (mlen+5)) printf("short write %d\n", wrote);
}

void printBuf(char * buf, int bufLen)
{
int i;

for (i=0; i<bufLen; i++)
{
if (isprint(buf)) printf("%c ", buf);
else printf("%02X ", buf);
}

printf("\n");
}

int rx_message(int fd, char * dat)
{
static int posBuf=0;
static char msgBuf[512];

int i, scanning, mlen, validMessage;
char cksm;
char * ptr;

validMessage = 0;

i = read(fd, msgBuf+posBuf, sizeof(msgBuf)-posBuf);

if (i>0)
{
posBuf += i;

scanning = 1;

while (scanning)
{
if (msgBuf[0] != PREAMBLE)
{
/* find message start */

ptr = memchr(msgBuf, PREAMBLE, posBuf);

if (ptr != NULL)
{
/* preamble found, discard previous junk */

i = ptr - msgBuf;
posBuf -= i;
memmove(msgBuf, ptr, posBuf);
}
else
{
/* no preamble found, discard junk */

posBuf = 0;
scanning = 0;
}
}

if (posBuf > 2)
{
/* we have enough to calculate size */

mlen = msgBuf[1];

if (posBuf > (mlen+2))
{
/* we have enough for a message */

cksm = checksum(mlen+2, msgBuf);

if (msgBuf[mlen+2] == cksm)
{
/* valid message received */
validMessage = 1;

/* copy message to callers buffer */
memmove(dat, msgBuf+2, mlen);

/* remove from receive buffer */
posBuf -= (mlen+3);
if (posBuf) memmove(msgBuf, msgBuf+mlen+3, posBuf);
scanning = 0;
}
else
{
/* corrupt message or invalid preamble.
Delete preamble and search for another
*/
msgBuf[0] = 0;
}
}
else scanning = 0;
}
else scanning = 0;
}
}

if (validMessage) return mlen; else return 0;

}

int initOpts(int argc, char *argv[])
{
int opt;

while ((opt = getopt(argc, argv, "m:rs:t")) != -1)
{
switch (opt)
{
case 'm':
opt = atoi(optarg);
if (opt>0) messages = opt;
break;

case 'r':
rx = 1;
break;

case 's':
opt = atoi(optarg);

if (opt == 300) speed = B300;
else if (opt == 600) speed = B600;
else if (opt == 1200) speed = B1200;
else if (opt == 1800) speed = B1800;
else if (opt == 2400) speed = B2400;
else if (opt == 4800) speed = B4800;
else if (opt == 9600) speed = B9600;
else if (opt == 19200) speed = B19200;

break;

case 't':
rx = 0;
break;
}
}
return 0;
}
I am pretty sure that the problem is something mind numblingly stupid that I did notice it. My next post will containe the companion spin code. Also is it possible for the pi to use flash memory sticks to transfer data to my home computer. I hate it when I have to post code like above

Patrick222122
Posts: 80
Joined: Sun Dec 02, 2012 5:51 pm

Re: uart and propellor

Fri Jan 11, 2013 3:51 pm

here is the spin code I use. If you are not familiar with spin go to Parallax's website. They two really good books on their website for free

Code: Select all

con
_CLKMODE=XTAL1+PLL2X
_XINFREQ =5_000_00

obj
Ser       : "FullDuplexSerial"      
pub start
send:=6
outout:=22
Ser.start(31, 30, 0, 38400)
send:=20
repeat 
 ser.tx(send)
 buffer:=ser.rx
 if buffer=="a"
  ser.tx(outout)
ser.tx(100)
dat
send byte "Hello world",0
buffer byte " ",0
outout byte "it works",0

Return to “Automation, sensing and robotics”