Hi everyone! And welcome to episode ten of my Bluetooth in Action series. Today, we are going to look into more advanced debugging, by using the serial port to view data.
Up until now, we haven’t really needed to visualize data; we’ve been blinking LEDs, turning on and off GPIOs, and mainly using visual references. For the next part of this series, we’ll be looking into more advanced features, and ones that will require some level of data output. This is also a question I get frequently, so today, we’re going to be quickly looking at serial output.
The BGM111 module is connected to a computer using a CMSIS device, one that allows us to flash the device, but also to use it as a serial port, simultaneously. For serial output, BGScript isn’t quite as easy to use as C, but with a few helper procedures, we can print a lot of data.
The command that we are going to be using is endpoint_send, which in the API reference is in the Endpoint section. Note that the API talks about the endpoint; UART1, UART0, or DROP. We’ll be using UART1, since that is what is connected to the CMSIS module, and to make thing easier, we will go ahead and create a const, called uart_ep for end point, and give it the value two, for UART1. It will make things easier later on.
Back to the documentation. The function we are interested in is an endpoint command, called “endpoint_send”. It takes three parameters; the endpoint is the UART port, data_len is the length of the data to send, and data_data is the buffer to send. So let’s say we want to send a “Hello, world!” to our computer. So, we copy and paste the system boot event from a file I prepared earlier, and we add the endpoint_send command. The first parameter is the UART port, which we called uart_ep. The second parameter is the length; we’ll get back to that. The third is the buffer, “Hello, world!”, for a total length of 13. Let’s add that number to the length parameter. Okay, we should be good.
In order to see the text, we need a serial console. There are a lot to choose from; I’m using Tera Term, because I’m used to it, but others exist. They all share the same principle; select a COM port, set up the connection parameters, and wait for data. I’ll be using 115200 baud, 8 bits of data, no parity, and one stop bit, shortened to 115200, 8N1. I’ll show you why in just a second.
So let’s compile that, and flash it. And… nothing happens. Why? Here’s the catch. We are using the right command, but remember that unless we set up the hardware, nothing is actually configured, so the UART port hasn’t actually been set up, it is up to us to correctly configure the I/O pins.
We will need two things to get us up and running. We will need to configure the serial port; by default, these devices are in 8N1, we’ll just specify the baud rate for easy viewing. This is done in the hardware file. The documentation file at Silicon Labs is UG119. All documentation files are available on the Silicon Labs website, or directly by installing Simplicity Studio, version 4 has just come out.
So, in UG119, section three point four, UART. This show us what parameters are needed. Index, baudrate and flowcontrol make sense, only bgapi needs explaining; “When an external host us used to control the Bluetooth module over UART, the BGAPI serial protocol must be enabled.” Well, we don’t need that, so we will leave it at false. Secondly, and this is sometimes the tricky part, the two GPIO pins need to be set correctly. A5 is Tx, A3 is Rx.
Let’s try to compile that again, and see what happens. This time, things change, we can see some serial output. If you get any corrupted text, or no text at all, make sure that you are using the right settings, as very few devices are able to automatically detect the baud rate.
This is a great way of printing text, but there are times when you will need to print something else; decimal, hexadecimal or even binary are frequently used types. There is no direct way to print out this kind of data, but with some simple helper procedures, you can print out just about anything. I didn’t create these procedures, they were actually available in some example programs, just hidden away. So for example, for debugging purposes, it is always interesting to know what hardware build we are using. To do this, we’ll use an endpoint send to print out some text, and then call the print int32 procedure, before calling endpoint send again, using a carriage return sequence.