blob: cebe127c25beb8c5e7e1a68b3b8aa767f996b88b [file] [log] [blame]
Brian Silvermanf6b68842013-12-20 12:34:58 -08001#include "bbb/uart_reader.h"
Brian Silverman1662a0e2013-12-19 17:50:01 -08002
Daniel Pettia4fe7bc2013-12-22 12:57:50 -08003#include <errno.h>
Daniel Pettib36f5b82013-12-15 08:55:04 -08004#include <fcntl.h>
5#include <linux/serial.h>
Daniel Pettib36f5b82013-12-15 08:55:04 -08006#include <unistd.h>
Daniel Petti059be422013-12-14 19:47:42 -08007
Brian Silverman1662a0e2013-12-19 17:50:01 -08008#include "aos/common/logging/logging.h"
Brian Silverman53f29182013-12-21 15:16:27 -08009
Daniel Petti059be422013-12-14 19:47:42 -080010// This is the code for receiving data from the cape via UART.
Brian Silverman1662a0e2013-12-19 17:50:01 -080011// NOTE: In order for this to work, you MUST HAVE
12// "capemgr.enable_partno=BB_UART1"
Daniel Petti059be422013-12-14 19:47:42 -080013// in your BBB's /media/BEAGLEBONE/uEnv.txt file!
Brian Silverman0b6d9f42013-12-23 22:03:57 -080014// `su -c "echo BB-UART1 > /sys/devices/bone_capemgr.*/slots"` works too, but
15// you have to do it every time.
Daniel Pettib36f5b82013-12-15 08:55:04 -080016
Daniel Petti059be422013-12-14 19:47:42 -080017namespace bbb {
Brian Silverman1662a0e2013-12-19 17:50:01 -080018namespace {
19// TODO(brians): Determine this in some way that allows easy switching for
20// testing with /dev/ttyUSB0 for example.
Brian Silverman0b6d9f42013-12-23 22:03:57 -080021const char *device = "/dev/ttyO1";
Brian Silverman1662a0e2013-12-19 17:50:01 -080022} // namespace
Daniel Petti059be422013-12-14 19:47:42 -080023
Brian Silverman0b6d9f42013-12-23 22:03:57 -080024extern "C" {
25
26// Sets all of the weird, annoying TTY flags on fd. In a separate file because
27// the structure it uses is so weird and annoying and carries so much baggage it
28// messes up all the #includes in whatever file it's used in.
Brian Silvermanc82c5122013-12-25 15:53:44 -080029// Defined in uart_reader_termios2.c.
Brian Silverman0b6d9f42013-12-23 22:03:57 -080030extern int aos_uart_reader_set_tty_options(int fd, int baud_rate);
31
32} // extern "C"
33
Brian Silvermanf6b68842013-12-20 12:34:58 -080034UartReader::UartReader(int32_t baud_rate)
Brian Silvermanff1218b2014-01-03 14:47:39 -080035 : fd_(open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) {
Daniel Pettia4fe7bc2013-12-22 12:57:50 -080036
Brian Silverman1662a0e2013-12-19 17:50:01 -080037 if (fd_ < 0) {
Brian Silvermanff1218b2014-01-03 14:47:39 -080038 LOG(FATAL, "open(%s, O_RDWR | O_NOCTTY | O_NOBLOCK) failed with %d: %s."
Brian Silvermanf6b68842013-12-20 12:34:58 -080039 " Did you read my note in bbb/uart_reader.cc?\n",
Brian Silverman1662a0e2013-12-19 17:50:01 -080040 device, errno, strerror(errno));
Daniel Petti059be422013-12-14 19:47:42 -080041 }
Brian Silvermaned030062013-12-20 21:03:47 -080042
Brian Silverman0b6d9f42013-12-23 22:03:57 -080043 if (aos_uart_reader_set_tty_options(fd_, baud_rate) != 0) {
44 LOG(FATAL, "aos_uart_reader_set_tty_options(%d) failed with %d: %s\n",
Brian Silverman1662a0e2013-12-19 17:50:01 -080045 fd_, errno, strerror(errno));
46 }
Brian Silvermanff1218b2014-01-03 14:47:39 -080047
48 FD_ZERO(&fd_set_);
49 FD_SET(fd_, &fd_set_);
Daniel Petti059be422013-12-14 19:47:42 -080050}
51
Brian Silvermanf6b68842013-12-20 12:34:58 -080052UartReader::~UartReader() {
Brian Silverman1662a0e2013-12-19 17:50:01 -080053 if (fd_ > 0) close(fd_);
54}
Daniel Petti059be422013-12-14 19:47:42 -080055
Brian Silvermanff1218b2014-01-03 14:47:39 -080056ssize_t UartReader::ReadBytes(AlignedChar *dest, size_t max_bytes,
Brian Silverman7d16c572014-01-03 20:27:57 -080057 const ::aos::time::Time &timeout_time) {
Brian Silverman803b7a52014-01-01 13:21:18 -080058 do {
Brian Silverman7d16c572014-01-03 20:27:57 -080059 ::aos::time::Time timeout = timeout_time - ::aos::time::Time::Now();
60 if (timeout < ::aos::time::Time(0, 0)) return -2;
Brian Silvermanff1218b2014-01-03 14:47:39 -080061 struct timeval timeout_timeval = timeout.ToTimeval();
62 switch (select(fd_ + 1, &fd_set_, NULL, NULL, &timeout_timeval)) {
63 case 0:
64 return -2;
65 case -1:
66 continue;
67 case 1:
68 break;
69 default:
70 LOG(WARNING, "unknown select return value\n");
71 return -1;
72 }
Brian Silverman803b7a52014-01-01 13:21:18 -080073 ssize_t r = read(fd_, dest, max_bytes);
74 if (r != -1) return r;
75 } while (errno == EINTR);
76 return -1;
Brian Silverman1662a0e2013-12-19 17:50:01 -080077}
Daniel Petti059be422013-12-14 19:47:42 -080078
Brian Silvermanffeef3f2013-12-22 14:06:23 -080079} // namespace bbb