This tutorial will teach you how to setup and use a serial port in BeRTOS.
Struct serial
Serial ports are accesses through the Serial interface. You need to declare a struct Serial for each serial port you want to use, then you access it by using the KFile interface.
#include <drv/ser.h> int main(void) { Serial ser_port; IRQ_ENABLE; ser_init(&ser_port, SER_UART0); ser_setbaudrate(&ser_port, 115200); //...
First, initialize the structure with a call to ser_init(), in which you specify the port you want to use. You should use the values SER_UARTn because they are CPU independent. You then set the baudrate with a call to ser_setbaudrate(). These are the only methods you need to start using the serial port.
Remember:
if you're using the same struct Serial from two or more processes, you must protect access with a semaphore to avoid race conditions.
When you have initialized a serial port, you can use the KFile interface to read and write from it. However, read the full serial documentation for other serial-specific functions.
SPI master protocol
You can use the SPI master protocol through the Serial interface. All you need to do is to call a different initialization function:
int main(void) { Serial spi_port; IRQ_ENABLE; spimaster_init(&spi_port, SER_SPI0); ser_setbaudrate(&spi_port, 500000L); // use spi_port with kfile interface uint8_t buf[50]; kfile_read(&spi_port.fd, buf, sizeof(buf)); }
Error handling
As you may have noticed, the serial driver has a timeout parameter both in transmission and reception; you can change it by hand in your project's configuration file cfg/cfg_ser.h, or by using the wizard.
By default, timeout is disabled so each call to kfile_read doesn't return until all characters are read (the same applies to kfile_write). Such behaviour is called blocking, since code execution effectively 'blocks' at the function call; note that if you're using the cooperative kernel there will be a context switch when the serial driver is waiting for characters.
When you enable the timeout, a call to kfile_read may return before having read all the characters you requested; in these case the driver will enter the error state and won't read or write any more until you explicitly reset (or acknowledge) the error.
Here is a code snippet that shows how to handle timeout errors:
// configure RX timeout with CONFIG_SER_RXTIMEOUT != -1
#define INPUT_CHARS 4
//...
ser_temp = kfile_read(&ser_port.fd, ser_buffer, INPUT_CHARS);
if (kfile_error(&ser_port.fd)) {
//handle error
//.....
//clear error
kfile_clearerr(&ser_port.fd);
}
if (ser_temp < INPUT_CHARS)
// ... handle this case
Note that after you've cleared the error on the serial driver, you may also need to handle the error in your application, since the number of received characters will be less than what you expect.
