cleaned up issues with Daniel's code
There were a lot of style things and a misunderstanding of the protocol
between the cape and the BBB.
diff --git a/bbb_cape/src/bbb/bbb.gyp b/bbb_cape/src/bbb/bbb.gyp
index ec617cc..ddbf388 100644
--- a/bbb_cape/src/bbb/bbb.gyp
+++ b/bbb_cape/src/bbb/bbb.gyp
@@ -1,4 +1,9 @@
{
+ 'target_defaults': {
+ 'include_dirs': [
+ '..',
+ ],
+ },
'targets': [
{
'target_name': 'crc',
@@ -16,8 +21,12 @@
'dependencies': [
'crc',
'<(DEPTH)/bbb_cape/src/cape/cape.gyp:cows',
+ '<(DEPTH)/bbb_cape/src/cape/cape.gyp:data_struct',
'<(AOS)/build/aos.gyp:logging',
],
+ 'export_dependent_settings': [
+ '<(DEPTH)/bbb_cape/src/cape/cape.gyp:data_struct',
+ ],
'sources': [
'uart_receiver.cc',
],
diff --git a/bbb_cape/src/bbb/crc.cc b/bbb_cape/src/bbb/crc.cc
index 60e665a..214f86f 100644
--- a/bbb_cape/src/bbb/crc.cc
+++ b/bbb_cape/src/bbb/crc.cc
@@ -1,4 +1,4 @@
-#include "crc.h"
+#include "bbb/crc.h"
#include "aos/common/once.h"
diff --git a/bbb_cape/src/bbb/crc.h b/bbb_cape/src/bbb/crc.h
index cb0bf63..7a8eb95 100644
--- a/bbb_cape/src/bbb/crc.h
+++ b/bbb_cape/src/bbb/crc.h
@@ -1,7 +1,7 @@
#ifndef BBB_CRC_H_
#define BBB_CRC_H_
-#include <cstring>
+#include <string.h>
#include <stdint.h>
namespace cape {
diff --git a/bbb_cape/src/bbb/gpios.cc b/bbb_cape/src/bbb/gpios.cc
index e2ab654..5a9c76e 100644
--- a/bbb_cape/src/bbb/gpios.cc
+++ b/bbb_cape/src/bbb/gpios.cc
@@ -1,146 +1,153 @@
-#include <cstdio>
-#include <cstdlib>
+#include "bbb/gpios.h"
+
+#include <stdio.h>
+#include <stdlib.h>
#include "aos/common/logging/logging_impl.h"
-#include "gpios.h"
namespace bbb {
- Pin::Pin(int bank, int pin) : handle_(NULL), direction_(0),
- kernel_pin_(bank * 32 + pin), exported_(false) {}
+Pin::Pin(int bank, int pin)
+ : handle_(NULL),
+ direction_(0),
+ kernel_pin_(bank * 32 + pin),
+ exported_(false) {}
- Pin::~Pin() {
- // Unexport the pin.
- if ((handle_ = fopen("/sys/class/gpio/unexport", "ab")) == NULL) {
- LOG(WARNING, "Could not unexport gpio pin.\n");
- // There's nothing intelligent we can really do here.
- return;
- }
-
- char gpio_num[2];
- snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
- fwrite(gpio_num, sizeof(char), 2, handle_);
- fclose(handle_);
+Pin::~Pin() {
+ // Unexport the pin.
+ if ((handle_ = fopen("/sys/class/gpio/unexport", "ab")) == NULL) {
+ LOG(WARNING, "Could not unexport gpio pin.\n");
+ // There's nothing intelligent we can really do here.
+ return;
}
- int Pin::DoExport() {
- char gpio_num[2];
- snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
-
- // Export the pin.
- if ((handle_ = fopen("/sys/class/gpio/export", "ab")) == NULL) {
- LOG(ERROR, "Could not export GPIO pin.\n");
- return -1;
- }
+ char gpio_num[2];
+ snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
+ fwrite(gpio_num, sizeof(char), 2, handle_);
+ fclose(handle_);
+}
- fwrite(gpio_num, sizeof(char), 2, handle_);
- fclose(handle_);
+int Pin::DoExport() {
+ char gpio_num[2];
+ snprintf(gpio_num, sizeof(gpio_num), "%d", kernel_pin_);
- exported_ = true;
- return 0;
+ // Export the pin.
+ if ((handle_ = fopen("/sys/class/gpio/export", "ab")) == NULL) {
+ LOG(ERROR, "Could not export GPIO pin.\n");
+ return -1;
}
- int Pin::DoPinDirSet(int direction) {
- char buf[4], type_path[64];
- snprintf(type_path, sizeof(type_path), "/sys/class/gpio/gpio%d/direction", kernel_pin_);
-
- if ((handle_ = fopen(type_path, "rb+")) == NULL) {
- LOG(ERROR, "Unable to set pin direction.\n");
- return -1;
- }
+ fwrite(gpio_num, sizeof(char), 2, handle_);
+ fclose(handle_);
- direction_ = direction;
- switch (direction) {
- case 1:
- strcpy(buf, "in");
- break;
- case 2:
- strcpy(buf, "low");
- break;
- case 0:
- return 0;
- default:
- LOG(ERROR, "Invalid direction identifier %d.\n", direction);
- direction_ = 0;
- return -1;
- }
- fwrite(buf, sizeof(char), 3, handle_);
- fclose(handle_);
+ exported_ = true;
+ return 0;
+}
- return 0;
+int Pin::DoPinDirSet(int direction) {
+ char buf[4], type_path[64];
+ snprintf(type_path, sizeof(type_path), "/sys/class/gpio/gpio%d/direction",
+ kernel_pin_);
+
+ if ((handle_ = fopen(type_path, "rb+")) == NULL) {
+ LOG(ERROR, "Unable to set pin direction.\n");
+ return -1;
}
- int Pin::MakeInput() {
- if (!exported_) {
- if (DoExport()) {
- return -1;
- }
- }
+ direction_ = direction;
+ switch (direction) {
+ case 1:
+ strcpy(buf, "in");
+ break;
+ case 2:
+ strcpy(buf, "low");
+ break;
+ case 0:
+ return 0;
+ default:
+ LOG(ERROR, "Invalid direction identifier %d.\n", direction);
+ direction_ = 0;
+ return -1;
+ }
+ fwrite(buf, sizeof(char), 3, handle_);
+ fclose(handle_);
- return DoPinDirSet(1);
+ return 0;
+}
+
+int Pin::MakeInput() {
+ if (!exported_) {
+ if (DoExport()) {
+ return -1;
+ }
}
- int Pin::MakeOutput() {
- if (!exported_) {
- if (DoExport()) {
- return -1;
- }
- }
+ return DoPinDirSet(1);
+}
- return DoPinDirSet(2);
+int Pin::MakeOutput() {
+ if (!exported_) {
+ if (DoExport()) {
+ return -1;
+ }
}
- int Pin::Write(uint8_t value) {
- if (direction_ != 2) {
- LOG(ERROR, "Only pins set as output can be written to.\n");
- return -1;
- }
+ return DoPinDirSet(2);
+}
- char buf, val_path [64];
- snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value", kernel_pin_);
- if (value != 0) {
- value = 1;
- }
-
- if ((handle_ = fopen(val_path, "rb+")) == NULL) {
- LOG(ERROR, "Unable to set pin value.\n");
- return -1;
- }
-
- snprintf(&buf, sizeof(buf), "%d", value);
- fwrite(&buf, sizeof(char), 1, handle_);
- fclose(handle_);
-
- return 0;
+int Pin::Write(uint8_t value) {
+ if (direction_ != 2) {
+ LOG(ERROR, "Only pins set as output can be written to.\n");
+ return -1;
}
- int Pin::Read() {
- // NOTE: I can't find any docs confirming that one can indeed
- // poll a pin's value using this method, but it seems that it
- // should work. Really, the "right" (interrupt driven) way to
- // do this is to set an event, but that involves messing with
- // dev tree crap, which I'm not willing to do unless we need
- // this functionality.
-
- if (direction_ != 1) {
- LOG(ERROR, "Only pins set as input can be read from.\n");
- return -1;
- }
-
- char buf, val_path [64];
- snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value", kernel_pin_);
-
- if ((handle_ = fopen(val_path, "rb")) == NULL) {
- LOG(ERROR, "Unable to read pin value.\n");
- return -1;
- }
-
- if (fread(&buf, sizeof(char), 1, handle_) <= 0) {
- LOG(ERROR, "Failed to read pin value from file.\n");
- return -1;
- }
- fclose(handle_);
- return atoi(&buf);
+ char buf, val_path[64];
+ snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value",
+ kernel_pin_);
+ if (value != 0) {
+ value = 1;
}
-} // bbb
+ if ((handle_ = fopen(val_path, "rb+")) == NULL) {
+ LOG(ERROR, "Unable to set pin value.\n");
+ return -1;
+ }
+
+ snprintf(&buf, sizeof(buf), "%d", value);
+ fwrite(&buf, sizeof(char), 1, handle_);
+ fclose(handle_);
+
+ return 0;
+}
+
+int Pin::Read() {
+ // NOTE: I can't find any docs confirming that one can indeed
+ // poll a pin's value using this method, but it seems that it
+ // should work. Really, the "right" (interrupt driven) way to
+ // do this is to set an event, but that involves messing with
+ // dev tree crap, which I'm not willing to do unless we need
+ // this functionality.
+
+ if (direction_ != 1) {
+ LOG(ERROR, "Only pins set as input can be read from.\n");
+ return -1;
+ }
+
+ char buf, val_path[64];
+ snprintf(val_path, sizeof(val_path), "/sys/class/gpio/gpio%d/value",
+ kernel_pin_);
+
+ if ((handle_ = fopen(val_path, "rb")) == NULL) {
+ LOG(ERROR, "Unable to read pin value.\n");
+ return -1;
+ }
+
+ if (fread(&buf, sizeof(char), 1, handle_) <= 0) {
+ LOG(ERROR, "Failed to read pin value from file.\n");
+ return -1;
+ }
+ fclose(handle_);
+ return atoi(&buf);
+}
+
+} // namespace bbb
diff --git a/bbb_cape/src/bbb/gpios.h b/bbb_cape/src/bbb/gpios.h
index 1494da2..a377d68 100644
--- a/bbb_cape/src/bbb/gpios.h
+++ b/bbb_cape/src/bbb/gpios.h
@@ -1,8 +1,8 @@
#ifndef BBB_CAPE_SRC_BBB_CAPE_CONTROL_H_
#define BBB_CAPE_SRC_BBB_CAPE_CONTROL_H_
-#include <cstdint>
-#include <cstring>
+#include <stdint.h>
+#include <stdio.h>
// As it turns out, controlling the BBB's GPIO pins
// from C++ is kind of a pain. The purpose of this
@@ -35,6 +35,6 @@
int Read();
};
-} // bbb
+} // namespace bbb
#endif
diff --git a/bbb_cape/src/bbb/uart_receiver.cc b/bbb_cape/src/bbb/uart_receiver.cc
index aabedd3..b29723e 100644
--- a/bbb_cape/src/bbb/uart_receiver.cc
+++ b/bbb_cape/src/bbb/uart_receiver.cc
@@ -1,78 +1,90 @@
+#include "bbb/uart_receiver.h"
+
#include <fcntl.h>
#include <linux/serial.h>
#include <termio.h>
#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
-#include <cmath>
-#include <cstring>
+#include <algorithm>
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/logging.h"
#include "bbb_cape/src/cape/cows.h"
-#include "crc.h"
-#include "uart_receiver.h"
+#include "bbb/crc.h"
// This is the code for receiving data from the cape via UART.
-// NOTE: In order for this to work, you MUST HAVE "capemgr.enable_partno=BB_UART1"
+// NOTE: In order for this to work, you MUST HAVE
+// "capemgr.enable_partno=BB_UART1"
// in your BBB's /media/BEAGLEBONE/uEnv.txt file!
// Implementation for setting custom serial baud rates based on this code:
// <http://jim.sh/ftx/files/linux-custom-baudrate.c>
namespace bbb {
+namespace {
+// TODO(brians): Determine this in some way that allows easy switching for
+// testing with /dev/ttyUSB0 for example.
+const char *device = "/dev/ttyO1";
+} // namespace
-UartReceiver::UartReceiver(uint32_t baud_rate) :
- baud_rate_(baud_rate) {
- packet_size_ = DATA_STRUCT_SEND_SIZE;
- //packet_size_ should be a multiple of four.
- int toadd = packet_size_ % 4;
- LOG(DEBUG, "Increasing packet size by %d bytes.\n", toadd);
- packet_size_ += toadd;
-
- // See cows.h for where this comes from.
- stuffed_size_ = ((packet_size_ - 1) / (pow(2, 32) - 1) + 1) * 4 + packet_size_;
-
- buf_ = static_cast<char *>(malloc(stuffed_size_));
-}
+UartReceiver::UartReceiver(int32_t baud_rate)
+ : baud_rate_(baud_rate),
+ buf_(new AlignedChar[DATA_STRUCT_SEND_SIZE]),
+ fd_(open(device, O_RDWR | O_NOCTTY)) {
+ static_assert((DATA_STRUCT_SEND_SIZE % 4) == 0,
+ "We can't do checksums of lengths that aren't multiples of 4.");
-UartReceiver::~UartReceiver() {
- free(buf_);
-}
-
-int UartReceiver::SetUp() {
- termios options;
- serial_struct serinfo;
-
- if ((fd_ = open("/dev/ttyO1", O_RDWR | O_NOCTTY)) < 0) {
- LOG(FATAL, "Open() failed with error %d.\
- (Did you read my note in uart_receiver.cc?)\n", fd_);
+ if (fd_ < 0) {
+ LOG(FATAL, "open(%s, O_RDWR | O_NOCTTY) failed with %d: %s."
+ " Did you read my note in bbb/uart_receiver.cc?\n",
+ device, errno, strerror(errno));
}
+ serial_struct serinfo;
// Must implement an ugly custom divisor.
serinfo.reserved_char[0] = 0;
- if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0)
- return -1;
+ if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0) {
+ LOG(FATAL, "ioctl(%d, TIOCGSERIAL, %p) failed with %d: %s\n",
+ fd_, &serinfo, errno, strerror(errno));
+ }
serinfo.flags &= ~ASYNC_SPD_MASK;
serinfo.flags |= ASYNC_SPD_CUST;
serinfo.custom_divisor = (serinfo.baud_base + (baud_rate_ / 2)) / baud_rate_;
- if (serinfo.custom_divisor < 1)
- serinfo.custom_divisor = 1;
- if (ioctl(fd_, TIOCSSERIAL, &serinfo) < 0)
- LOG(ERROR, "First ioctl failed.\n");
- return -1;
- if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0)
- LOG(ERROR, "Second ioctl failed.\n");
- return -1;
- if (serinfo.custom_divisor * static_cast<int>(baud_rate_)
- != serinfo.baud_base) {
- LOG(WARNING, "actual baudrate is %d / %d = %f",
- serinfo.baud_base, serinfo.custom_divisor,
- (float)serinfo.baud_base / serinfo.custom_divisor);
+ if (serinfo.custom_divisor < 1) serinfo.custom_divisor = 1;
+ if (ioctl(fd_, TIOCSSERIAL, &serinfo) < 0) {
+ LOG(FATAL, "ioctl(%d, TIOCSSERIAL, %p) failed with %d: %s\n",
+ fd_, &serinfo, errno, strerror(errno));
+ }
+ if (ioctl(fd_, TIOCGSERIAL, &serinfo) < 0) {
+ LOG(FATAL, "ioctl(%d, TIOCGSERIAL, %p) failed with %d: %s\n",
+ fd_, &serinfo, errno, strerror(errno));
+ }
+ if (serinfo.custom_divisor * baud_rate_ != serinfo.baud_base) {
+ LOG(WARNING, "actual baudrate is %d / %d = %f\n",
+ serinfo.baud_base, serinfo.custom_divisor,
+ static_cast<double>(serinfo.baud_base) / serinfo.custom_divisor);
}
- fcntl(fd_, F_SETFL, 0);
- tcgetattr(fd_, &options);
- cfsetispeed(&options, B38400);
- cfsetospeed(&options, B38400);
+ if (fcntl(fd_, F_SETFL, 0) != 0) {
+ LOG(FATAL, "fcntl(%d, F_SETFL, 0) failed with %d: %s\n",
+ fd_, errno, strerror(errno));
+ }
+
+ termios options;
+ if (tcgetattr(fd_, &options) != 0) {
+ LOG(FATAL, "tcgetattr(%d, %p) failed with %d: %s\n",
+ fd_, &options, errno, strerror(errno));
+ }
+ if (cfsetispeed(&options, B38400) != 0) {
+ LOG(FATAL, "cfsetispeed(%p, B38400) failed with %d: %s\n",
+ &options, errno, strerror(errno));
+ }
+ if (cfsetospeed(&options, B38400) != 0) {
+ LOG(FATAL, "cfsetospeed(%p, B38400) failed with %d: %s\n",
+ &options, errno, strerror(errno));
+ }
cfmakeraw(&options);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CRTSCTS;
@@ -81,98 +93,86 @@
options.c_lflag = 0;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 1;
- if (tcsetattr(fd_, TCSANOW, &options) != 0)
- LOG(ERROR, "Tcsetattr failed.\n");
- return -1;
-
- return 0;
+ if (tcsetattr(fd_, TCSANOW, &options) != 0) {
+ LOG(FATAL, "tcsetattr(%d, TCSANOW, %p) failed with %d: %s\n",
+ fd_, &options, errno, strerror(errno));
+ }
}
-int UartReceiver::GetPacket(DataStruct *packet) {
- int pstarti = 0, bread, cons_zeros = 0;
- uint32_t readi = 0;
- bool done = false, has_packet = false;
- uint32_t ptemp [(stuffed_size_ - 1) / 4 + 1];
+UartReceiver::~UartReceiver() {
+ delete buf_;
+ if (fd_ > 0) close(fd_);
+}
- while (!done && buf_used_ < stuffed_size_) {
- if ((bread = read(fd_, buf_ + buf_used_, stuffed_size_ - buf_used_)) < 0) {
- LOG(WARNING, "Read() failed with error %d.\n", bread);
- return -1;
+bool UartReceiver::FindPacket() {
+ // How many 0 bytes we've found at the front so far.
+ int zeros_found = 0;
+ // How many bytes of the packet we've read in (or -1 if we don't know where
+ // the packet is).
+ int packet_bytes = -1;
+ while (true) {
+ size_t already_read = ::std::max(packet_bytes, 0);
+ ssize_t new_bytes =
+ read(fd_, buf_ + already_read, DATA_STRUCT_SEND_SIZE - already_read);
+ if (new_bytes < 0) {
+ if (errno == EINTR) continue;
+ LOG(WARNING, "read(%d, %p, %zd) failed with %d: %s\n",
+ fd_, buf_ + already_read, DATA_STRUCT_SEND_SIZE - already_read,
+ errno, strerror(errno));
+ return false;
}
- buf_used_ += bread;
- // Find the beginning of the packet.
- // Look for four bytes of zeros.
- while (readi < buf_used_) {
- if (buf_[readi] == 0) {
- if (cons_zeros == 4) {
- if (has_packet) {
- // We got to the end of a packet.
- done = true;
+ if (packet_bytes == -1) {
+ // Find the beginning of the packet (aka look for four zero bytes).
+ for (ssize_t checked = 0; checked < new_bytes; ++checked) {
+ if (buf_[checked] == 0) {
+ ++zeros_found;
+ if (zeros_found == 4) {
+ packet_bytes = new_bytes - checked - 1;
+ memmove(buf_, buf_ + checked + 1, packet_bytes);
break;
- } else {
- // We got to the start of a packet.
- has_packet = true;
- pstarti = readi - 3;
}
} else {
- ++cons_zeros;
+ zeros_found = 0;
}
- } else {
- cons_zeros = 0;
}
- readi++
+ } else { // we think there's a packet at the beginning of our buffer
+ for (int to_check = packet_bytes; packet_bytes + new_bytes; ++to_check) {
+ // We shouldn't find any 0s in the middle of what should be a packet.
+ if (buf_[to_check] == 0) {
+ packet_bytes = -1;
+ break;
+ }
+ }
+ packet_bytes += new_bytes;
+ if (packet_bytes == DATA_STRUCT_SEND_SIZE) return true;
}
}
+}
- // Copy packet data to output.
- int filled = 0;
- readi -= 3; // We read a little into the next packet.
- for (uint32_t i = pstarti; i < readi - 3; ++i) {
- ptemp[i] = buf_[i];
- ++filled;
- }
- // Move everything we didn't use to the beginning of the buffer for next time.
- uint32_t puti = 0;
- for (uint32_t i = readi; i < stuffed_size_; ++i) {
- buf_[puti++] = buf_[i];
- }
- buf_used_ = stuffed_size_ - readi;
- readi = 0;
+bool UartReceiver::GetPacket(DataStruct *packet) {
+ if (!FindPacket()) return false;
- // Cows algorithm always outputs something 4-byte aligned.
- if (filled % 4) {
- LOG(WARNING, "Rejecting packet due to it not being possible\
- for cows to have created it.\n");
- return -1;
- }
-
- // Unstuff our packet.
- uint32_t ptemp_unstuffed [packet_size_];
- uint32_t bunstuffed;
- if ((bunstuffed = cows_unstuff(ptemp, sizeof(ptemp), ptemp_unstuffed)) == 0) {
- LOG(WARNING, "Rejecting packet due to failure to unstuff it.\n");
- return -1;
- }
- if (bunstuffed != packet_size_) {
- LOG(WARNING, "Rejecting packet of wrong size.\
- Expected packet of size %d, got packet of size %d.\n",
- packet_size_, bunstuffed);
- return -1;
+ uint32_t unstuffed = cows_unstuff(reinterpret_cast<uint32_t *>(buf_),
+ DATA_STRUCT_SEND_SIZE / 4,
+ reinterpret_cast<uint32_t *>(packet));
+ if (unstuffed == 0) {
+ LOG(WARNING, "invalid packet\n");
+ } else if (unstuffed != sizeof(packet)) {
+ LOG(WARNING, "packet is %" PRIu32 " words instead of %" PRIu32 "\n",
+ unstuffed, DATA_STRUCT_SEND_SIZE / 4);
}
// Make sure the checksum checks out.
- uint32_t checksum = static_cast<uint32_t>(ptemp_unstuffed[packet_size_ - 4]);
- // Checksum only gets done on the actual datastruct part of the packet,
- // so we'll discard everything after it.
- memcpy(packet, ptemp_unstuffed, sizeof(DataStruct));
- if (cape::CalculateChecksum((uint8_t *)packet, sizeof(DataStruct)) != checksum) {
+ uint32_t checksum;
+ memcpy(&checksum, buf_ + DATA_STRUCT_SEND_SIZE - 4, 4);
+ if (cape::CalculateChecksum(reinterpret_cast<uint8_t *>(packet),
+ sizeof(DataStruct)) != checksum) {
LOG(WARNING, "Rejecting packet due to checksum failure.\n");
- return -1;
+ return false;
}
- return 0;
+ return true;
}
-} // bbb
-
+} // namespace bbb
diff --git a/bbb_cape/src/bbb/uart_receiver.h b/bbb_cape/src/bbb/uart_receiver.h
index 36bb170..73ba781 100644
--- a/bbb_cape/src/bbb/uart_receiver.h
+++ b/bbb_cape/src/bbb/uart_receiver.h
@@ -1,30 +1,36 @@
#ifndef FCR971_INPUT_UART_RECEIVER_H_
#define FRC971_INPUT_UART_RECEIVER_H_
-#include <cstdint>
+#include <stdint.h>
#define DATA_STRUCT_NAME DataStruct
-#include <bbb_cape/src/cape/data_struct.h>
+#include "cape/data_struct.h"
#undef DATA_STRUCT_NAME
namespace bbb {
-
- class UartReceiver {
- uint32_t baud_rate_;
- size_t packet_size_, stuffed_size_;
- int fd_;
- uint32_t buf_used_;
- char *buf_;
-
- public:
- UartReceiver(uint32_t baud_rate);
- ~UartReceiver();
- // Opens file descriptor, etc.
- int SetUp();
- int GetPacket(DataStruct *packet);
-
- };
-} //bbb
+class UartReceiver {
+ public:
+ UartReceiver(int32_t baud_rate);
+ ~UartReceiver();
+
+ // Returns true if it finds one or false if it gets an I/O error first.
+ // packet must be aligned to 4 bytes.
+ bool GetPacket(DataStruct *packet);
+
+ private:
+ // Reads bytes until there are 4 zeros and then fills up buf_.
+ // Returns true if it finds one or false if it gets an I/O error first or the
+ // packet is invalid in some way.
+ bool FindPacket();
+
+ typedef char __attribute__((aligned(8))) AlignedChar;
+
+ const int32_t baud_rate_;
+ AlignedChar *const buf_;
+ const int fd_;
+};
+
+} // namespace bbb
#endif
diff --git a/bbb_cape/src/bbb/uart_receiver_main.cc b/bbb_cape/src/bbb/uart_receiver_main.cc
index 272d454..3e31624 100644
--- a/bbb_cape/src/bbb/uart_receiver_main.cc
+++ b/bbb_cape/src/bbb/uart_receiver_main.cc
@@ -1,10 +1,10 @@
-#include <cstdint>
+#include <stdint.h>
#include "aos/atom_code/init.h"
#include "aos/common/logging/logging_impl.h"
#include "aos/common/time.h"
-#include "gpios.h"
-#include "uart_receiver.h"
+#include "bbb/gpios.h"
+#include "bbb/uart_receiver.h"
using ::aos::time::Time;
@@ -16,7 +16,6 @@
Time kPacketTimeout = Time::InSeconds(1);
bbb::UartReceiver receiver = bbb::UartReceiver(3000000);
- receiver.SetUp();
bbb::Pin reset_pin = bbb::Pin(1, 6);
reset_pin.MakeOutput();
diff --git a/bbb_cape/src/bbb/uart_receiver_test.cc b/bbb_cape/src/bbb/uart_receiver_test.cc
index 601dbf6..0552b20 100644
--- a/bbb_cape/src/bbb/uart_receiver_test.cc
+++ b/bbb_cape/src/bbb/uart_receiver_test.cc
@@ -1,7 +1,8 @@
+#include "bbb/uart_receiver.h"
+
#include <termios.h>
#include "gtest/gtest.h"
-#include "uart_receiver.h"
namespace bbb {
namespace {
@@ -14,10 +15,12 @@
UartReceiverTest () : test_instance_(UartReceiver(3000000)) {}
};
+#if 0
TEST_F(UartReceiverTest, SetUpTest) {
// Test its ability to open a file descriptor and set a baud rate.
ASSERT_EQ(test_instance_.SetUp(), 0);
}
+#endif
-} //namespace
-} //bbb
+} // namespace
+} // namespace bbb
diff --git a/bbb_cape/src/cape/cape.gyp b/bbb_cape/src/cape/cape.gyp
index e9d34ef..91ec298 100644
--- a/bbb_cape/src/cape/cape.gyp
+++ b/bbb_cape/src/cape/cape.gyp
@@ -1,4 +1,9 @@
{
+ 'target_defaults': {
+ 'include_dirs': [
+ '..',
+ ],
+ },
'targets': [
{
'target_name': 'cows',
@@ -7,5 +12,9 @@
'cows.c',
],
},
+ {
+ 'target_name': 'data_struct',
+ 'type': 'static_library',
+ },
],
}
diff --git a/bbb_cape/src/cape/cows.c b/bbb_cape/src/cape/cows.c
index 396889c..16ed1fc 100644
--- a/bbb_cape/src/cape/cows.c
+++ b/bbb_cape/src/cape/cows.c
@@ -1,4 +1,4 @@
-#include "cows.h"
+#include "cape/cows.h"
#include <limits.h>
diff --git a/bbb_cape/src/cape/data_struct.h b/bbb_cape/src/cape/data_struct.h
index 95992b9..797648f 100644
--- a/bbb_cape/src/cape/data_struct.h
+++ b/bbb_cape/src/cape/data_struct.h
@@ -60,6 +60,7 @@
// The number of bytes that we actually send (so it stays consistent) (including
// the byte-stuffing overhead and the CRC on the end).
+// This will always be a multiple of 4.
#define DATA_STRUCT_SEND_SIZE 200
#ifdef __cplusplus
diff --git a/bbb_cape/src/flasher/build.sh b/bbb_cape/src/flasher/build.sh
index 7e3ddd5..cb50569 100755
--- a/bbb_cape/src/flasher/build.sh
+++ b/bbb_cape/src/flasher/build.sh
@@ -2,6 +2,8 @@
set -e
+cd $(dirname $0)
+
[[ -d stm32flash ]] || ( git clone https://git.gitorious.org/stm32flash/stm32flash.git stm32flash &&
cd stm32flash && git checkout 16fbfe6e5854dc36f41712f60b2282cde7571afd && patch -p1 < ../0001-actually-calculate-and-send-a-checksum-for-individua.patch )
diff --git a/frc971/atom_code/build.sh b/frc971/atom_code/build.sh
index b8129ab..172b2d4 100755
--- a/frc971/atom_code/build.sh
+++ b/frc971/atom_code/build.sh
@@ -1,3 +1,5 @@
#!/bin/bash
+cd $(dirname $0)
+
../../aos/build/build.sh atom atom_code.gyp no "$@"
diff --git a/frc971/crio/build.sh b/frc971/crio/build.sh
index b3fc031..9e77e89 100755
--- a/frc971/crio/build.sh
+++ b/frc971/crio/build.sh
@@ -1,3 +1,5 @@
#!/bin/bash
+cd $(dirname $0)
+
../../aos/build/build.sh crio crio.gyp no "$@"