Finished initial uart code, it compiles.
The next task is writting unit tests for it.
Also fixed some minor issues in Brian's code.
Finally, fixed a minor problem in download_externals.sh
that was causing things not to build properly.
diff --git a/.gitignore b/.gitignore
index 0d20b64..5bfc69f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
*.pyc
+output/
diff --git a/aos/build/download_externals.sh b/aos/build/download_externals.sh
index f33eced..9d8a9f5 100755
--- a/aos/build/download_externals.sh
+++ b/aos/build/download_externals.sh
@@ -153,7 +153,7 @@
GMP_DIR=${COMPILED}/gmp-${GMP_VERSION}
GMP_PREFIX=${GMP_DIR}-prefix
GMP_LIB=${GMP_PREFIX}/lib/libgmp.a
-GMP_URL=http://ftp.gmplib.org/gmp/gmp-${GMP_VERSION}.tar.lz
+GMP_URL=ftp://ftp.gmplib.org/pub/gmp/gmp-${GMP_VERSION}.tar.lz
[ -f ${GMP_TAR} ] || wget ${GMP_URL} -O ${GMP_TAR}
[ -d ${GMP_DIR} ] || ( mkdir ${GMP_DIR} && tar \
--strip-components=1 -C ${GMP_DIR} -xf ${GMP_TAR} )
diff --git a/bbb_cape/src/bbb/bbb.gyp b/bbb_cape/src/bbb/bbb.gyp
index a2d62ea..9040140 100644
--- a/bbb_cape/src/bbb/bbb.gyp
+++ b/bbb_cape/src/bbb/bbb.gyp
@@ -10,5 +10,17 @@
'crc.cc',
],
},
+ {
+ 'target_name': 'uart_receiver',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'crc',
+ '<(DEPTH)/bbb_cape/src/cape/cape.gyp:cows',
+ '<(AOS)/build/aos.gyp:logging',
+ ],
+ 'sources': [
+ 'uart_receiver.cc',
+ ],
+ },
],
}
diff --git a/bbb_cape/src/bbb/crc.cc b/bbb_cape/src/bbb/crc.cc
index b770f37..60e665a 100644
--- a/bbb_cape/src/bbb/crc.cc
+++ b/bbb_cape/src/bbb/crc.cc
@@ -1,4 +1,4 @@
-#include "bbb/crc.h"
+#include "crc.h"
#include "aos/common/once.h"
@@ -27,7 +27,7 @@
} // namespace
uint32_t CalculateChecksum(uint8_t *data, size_t length) {
- static ::aos::once<const uint32_t> table_once(GenerateTable);
+ static ::aos::Once<const uint32_t> table_once(GenerateTable);
const uint32_t *const table = table_once.Get();
uint32_t r = 0xFFFFFFFF;
diff --git a/bbb_cape/src/bbb/crc.h b/bbb_cape/src/bbb/crc.h
index b353efc..cb0bf63 100644
--- a/bbb_cape/src/bbb/crc.h
+++ b/bbb_cape/src/bbb/crc.h
@@ -1,6 +1,7 @@
#ifndef BBB_CRC_H_
#define BBB_CRC_H_
+#include <cstring>
#include <stdint.h>
namespace cape {
diff --git a/bbb_cape/src/bbb/uart_receiver.cc b/bbb_cape/src/bbb/uart_receiver.cc
new file mode 100644
index 0000000..1150c55
--- /dev/null
+++ b/bbb_cape/src/bbb/uart_receiver.cc
@@ -0,0 +1,146 @@
+#include <cmath>
+#include <cstring>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "aos/common/logging/logging_impl.h"
+#include "bbb_cape/src/cape/cows.h"
+#include "crc.h"
+#include "uart_receiver.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"
+// in your BBB's /media/BEAGLEBONE/uEnv.txt file!
+
+namespace bbb {
+
+UartReceiver::UartReceiver(speed_t baud_rate, size_t packet_size) :
+ baud_rate_(baud_rate), packet_size_(packet_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() {
+ free(buf_);
+}
+
+int UartReceiver::SetUp() {
+ termios cape;
+
+ 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 (int ret = tcgetattr(fd_, &cape)) {
+ LOG(ERROR, "Tcgetattr() failed with error %d.\n", ret);
+ return -1;
+ }
+ if (int ret = cfsetispeed(&cape, baud_rate_) < 0) {
+ LOG(ERROR, "Cfsetispeed() failed with error %d.\n", ret);
+ return -1;
+ }
+
+ cape.c_iflag = 0;
+ cape.c_oflag = 0;
+ cape.c_lflag = 0;
+ cape.c_cc[VMIN] = 0;
+ cape.c_cc[VTIME] = 0;
+
+ tcsetattr(fd_, TCSANOW, &cape);
+
+ return 0;
+}
+
+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];
+
+ 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;
+ }
+ 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;
+ break;
+ } else {
+ // We got to the start of a packet.
+ has_packet = true;
+ pstarti = readi - 3;
+ }
+ } else {
+ ++cons_zeros;
+ }
+ } else {
+ cons_zeros = 0;
+ }
+ }
+ ++readi;
+ }
+
+ // Copy packet data to output.
+ int filled = 0;
+ readi -= 3;
+ 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;
+
+ // 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;
+ }
+
+ // Make sure the checksum checks out.
+ uint32_t checksum = static_cast<uint32_t>(ptemp_unstuffed[packet_size_ - 4]);
+ memcpy(packet, ptemp_unstuffed, sizeof(DataStruct));
+ if (cape::CalculateChecksum((uint8_t *)packet, sizeof(DataStruct)) != checksum) {
+ LOG(WARNING, "Rejecting packet due to checksum failure.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+} //bbb
+
diff --git a/bbb_cape/src/bbb/uart_receiver.h b/bbb_cape/src/bbb/uart_receiver.h
new file mode 100644
index 0000000..1a29dab
--- /dev/null
+++ b/bbb_cape/src/bbb/uart_receiver.h
@@ -0,0 +1,31 @@
+#ifndef FCR971_INPUT_UART_RECEIVER_H_
+#define FRC971_INPUT_UART_RECEIVER_H_
+
+#include <cstdint>
+#include <termios.h>
+
+#define DATA_STRUCT_NAME DataStruct
+#include <bbb_cape/src/cape/data_struct.h>
+#undef DATA_STRUCT_NAME
+
+namespace bbb {
+
+ class UartReceiver {
+ speed_t baud_rate_;
+ size_t packet_size_, stuffed_size_;
+ int fd_;
+ uint32_t buf_used_;
+ char *buf_;
+
+ public:
+ UartReceiver(speed_t baud_rate, size_t packet_size);
+ ~UartReceiver();
+ // Opens file descriptor, etc.
+ int SetUp();
+ int GetPacket(DataStruct *packet);
+
+ };
+
+} //bbb
+
+#endif
diff --git a/bbb_cape/src/cape/cape.gyp b/bbb_cape/src/cape/cape.gyp
new file mode 100644
index 0000000..e9d34ef
--- /dev/null
+++ b/bbb_cape/src/cape/cape.gyp
@@ -0,0 +1,11 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'cows',
+ 'type': 'static_library',
+ 'sources': [
+ 'cows.c',
+ ],
+ },
+ ],
+}
diff --git a/bbb_cape/src/cape/cows.c b/bbb_cape/src/cape/cows.c
index b0d168e..22bd056 100644
--- a/bbb_cape/src/cape/cows.c
+++ b/bbb_cape/src/cape/cows.c
@@ -1,4 +1,4 @@
-#include "cape/cows.h"
+#include "cows.h"
#include <limits.h>
diff --git a/bbb_cape/src/cape/cows.h b/bbb_cape/src/cape/cows.h
index a589fca..27cb556 100644
--- a/bbb_cape/src/cape/cows.h
+++ b/bbb_cape/src/cape/cows.h
@@ -18,8 +18,8 @@
// source and destination both have to be 4-byte aligned.
// Returns the total number of words written (not necessarily the maximum given
// in the above description of destination).
-uint32_t cows_stuff(const void *restrict source, size_t source_length,
- void *restrict destination);
+uint32_t cows_stuff(const void *__restrict__ source, size_t source_length,
+ void *__restrict__ destination);
// source_length will be rounded up a multiple of 4. That many bytes of source
// will be read.
@@ -27,7 +27,7 @@
// cows_stuff for the exact size it might be).
// source and destination both have to be 4-byte aligned.
// Returns the total number of words written to destination or 0 for error.
-uint32_t cows_unstuff(const uint32_t *restrict source, size_t source_length,
- uint32_t *restrict destination);
+uint32_t cows_unstuff(const uint32_t *__restrict__ source, size_t source_length,
+ uint32_t *__restrict__ destination);
#endif // CAPE_COWS_H_
diff --git a/frc971/atom_code/atom_code.gyp b/frc971/atom_code/atom_code.gyp
index 780ca23..a004c4d 100644
--- a/frc971/atom_code/atom_code.gyp
+++ b/frc971/atom_code/atom_code.gyp
@@ -25,6 +25,7 @@
#'camera/camera.gyp:frc971',
'../../gyro_board/src/libusb-driver/libusb-driver.gyp:get',
'../input/input.gyp:gyro_sensor_receiver',
+ '<(DEPTH)/bbb_cape/src/bbb/bbb.gyp:uart_receiver',
],
'copies': [
{
diff --git a/frc971/input/uart_receiver.cc b/frc971/input/uart_receiver.cc
deleted file mode 100644
index 29aba81..0000000
--- a/frc971/input/uart_receiver.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <fcntl.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "bbb_cape/src/cape/cows.h"
-#include "uart_receiver.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"
-// in your BBB's /media/BEAGLEBONE/uEnv.txt file!
-
-int UartReceiver::ReadUart(size_t packet_size) {
- termios cape;
- char byte_in[packet_size];
- int fd, bread;
-
- 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 ((ret = tcgetattr(fd, &cape)) != 0) {
- LOG(ERROR, "Tcgetattr() failed with error %d.\n", ret);
- return -1;
- }
-}
diff --git a/frc971/input/uart_receiver.h b/frc971/input/uart_receiver.h
deleted file mode 100644
index 171c54c..0000000
--- a/frc971/input/uart_receiver.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef FCR971_INPUT_UART_RECEIVER_H_
-#define FRC971_INPUT_UART_RECEIVER_H_
-
-namespace frc971 {
-
- class UartReceiver {
- int ReadUart();
-
- };
-
-} //frc971
-
-#endif