UART Console Between PIC24 and BeagleBoneBlack

by kacang bawang


So, I’m working on a project which is based on the PIC24 microcontroller and I needed a console. A regular, plain-jane text output (and less-so input) to somewhere where I can read it. While this shouldn’t be much of a problem, for this particular combination there were a few little things that had to be just so, or the whole thing broke. I would like to describe the conditions that I found necessary for getting it up and running.

Wait, why are you using BeagleBoneBlack for this? Well, you see, BeagleBoneBlack (or any of its competitors such as RaspberryPi for that matter) conveniently have UART pins that are at 3.3V and can be connected directly to the PIC to do my bidding via one of /dev/tty file descriptors. This is very convenient – all you do is echo to one of the /dev/tty and it goes to the PIC. To read data back, just cat < /dev/tty. No drivers, no terminal programs.

1. Enabling and Testing UART on BeagleBoneBlack RevC

There are a number of different procedures for enabling UART on the BeagleBone’s depending on which version you have. What I say here applies to RevC.

#edit /boot/uboot/uEnv.txt
#make sure optargs includes the following:

This enables UART4, aka, /dev/ttyO4, aka, pins P9.11(Rx) and P9.13(Tx). I chose UART4 simply because the pins for it were easiest to find. There is some confilicting info out there with regard to whether UART4 pins share functionality with HDMI. On RevC there is no conflict between UART4 and HDMI, as confirmed by testing with and without disabling HDMI.

Ok, now that it is enabled, let’s test it. How do we do that?

1. Short the Rx and Tx pins (ie, stick a paper clip into both of the those pin holes).
2. Connect via two ssh sessions to the Bone.

1 or 2> stty -F /dev/ttyO4 raw ispeed 115200 ospeed 115200 cs8 -ignpar -cstopb -echo
1> cat -v < /dev/ttyO4
2> echo "testes, testes, 1,2,3" > /dev/ttyO4

You should see whatever you echo’ed into window 2 be printed in window 1. The ssty step is key to getting this to go, without it, the echo command will hang while writing to /dev/ttyO4 and you won’t see anything being printed in the cat window. What it does is sets tty parameters such as baud-rate, parity, etc for that device. NOTE: YOU HAVE TO DO THIS EVERY TIME AFTER RESTARTING THE BEAGLEBONE. I naively assumed that, by default, they would be set to something useful, at least, useful enough to do a loopback test as described above, but it isn’t so. Set your params or spend precious time googling about why isn’t it working.

2. Configure your pins on the PIC

1. Configure your UART pins to output and input, for example:
PORTG = 0;
TRISG = 0; //all port g to output
TRISGbits.TRISG7 = 1; //except the RX pin

2. Turn off analog functions on UART pins, for example:
ANSG = 0;
3. Set up peripheral select, initialize UART, etc, as described in the manual or this guide.

It is very important to turn off the analog functionality, else you get a system that is able to UART transmit characters out, but cannot read characters in. It will simply block on UART receive. This was not obvious to me at all.

Test by connecting:

On the Bone, create two ssh windows as before, and on the PIC create an echo “server” that read from RX and writes it to the TX without modification (the guide above goes into all this). You should see the same behavior on the Bone as before (type into one ssh prompt, echo out of the other), but now the data flows through the PIC.

3. Don’t forget to clear errors

This is covered in the PIC manual, but I will mention it here for the sake of completeness.

If you send data to the PIC too fast such that its UART RX buffer (4 chars) overflows (say, you type really really fast, or are really slow about processing because you’re blinking LEDs with loop-based delays), you will find that no matter what you send to the PIC, it will always send back the same symbol. This is because when RX buffer overflows it gets stuck in such a way that it will always return the overflowing character (the 5th one), until you clear the error flag and manually read out the 4 chars that are in there already. If you just clear the flag, like this, for example:

UxSTAbits.OERR = 0;

You will lose the 4 chars in the buffer.

In closing.

Hopefully these tips will save you some searching as well as some frustration when staring a PIC project.