got all of the basic cape code working
diff --git a/bbb_cape/src/bbb/packet_finder.cc b/bbb_cape/src/bbb/packet_finder.cc
index 298edc7..a6b108c 100644
--- a/bbb_cape/src/bbb/packet_finder.cc
+++ b/bbb_cape/src/bbb/packet_finder.cc
@@ -2,7 +2,6 @@
#include <errno.h>
#include <inttypes.h>
-#include <assert.h>
#include <algorithm>
@@ -17,7 +16,7 @@
packet_size_(packet_size),
buf_(new AlignedChar[packet_size_]),
unstuffed_data_(new AlignedChar[packet_size_ - 4]) {
- assert((packet_size_ % 4) == 0);
+ CHECK((packet_size_ % 4) == 0);
}
PacketFinder::~PacketFinder() {
diff --git a/bbb_cape/src/bbb/uart_reader_main.cc b/bbb_cape/src/bbb/uart_reader_main.cc
index 5bda02c..94db8fc 100644
--- a/bbb_cape/src/bbb/uart_reader_main.cc
+++ b/bbb_cape/src/bbb/uart_reader_main.cc
@@ -7,24 +7,15 @@
#include "aos/common/time.h"
#include "bbb/gpios.h"
#include "bbb/uart_reader.h"
+#include "bbb/packet_finder.h"
using ::aos::time::Time;
-#define DO_RESET 0
-
int main() {
::aos::Init();
-#if DO_RESET
- // time since last good packet before we reset
- // the board.
- static const Time kPacketTimeout = Time::InSeconds(1);
-
- ::bbb::Pin reset_pin = bbb::Pin(1, 6);
- reset_pin.MakeOutput();
-#endif
-
- ::bbb::UartReader receiver(1500000);
+ ::bbb::UartReader reader(750000);
+ ::bbb::PacketFinder receiver(&reader, DATA_STRUCT_SEND_SIZE - 4);
receiver.ReadPacket();
// TODO(brians): Do this cleanly.
int chrt_result = system(
@@ -38,17 +29,6 @@
Time last_packet_time = Time::Now();
while (true) {
-#if DO_RESET
- if (!last_packet_time.IsWithin(Time::Now(), kPacketTimeout.ToNSec())) {
- LOG(ERROR, "No good packets for too long. Resetting cape.\n");
- reset_pin.Write(1);
- ::aos::time::SleepFor(Time::InSeconds(1));
- reset_pin.Write(0);
-
- last_packet_time = Time::Now();
- }
-#endif
-
if (!receiver.ReadPacket()) {
LOG(WARNING, "Could not read a packet.\n");
continue;
@@ -66,6 +46,10 @@
LOG(DEBUG, "adc[%d]=%f (%" PRIx16 ")\n", i,
3.3 * packet->test.analogs[i] / 0x3FF, packet->test.analogs[i]);
}
+ LOG(DEBUG, "digitals=%x\n", packet->test.digitals);
+ LOG(DEBUG, "+=%" PRId32 "/%" PRIu8 " and -=%" PRId32 "/%" PRIu8 "\n",
+ packet->test.posedge_value, packet->test.posedge_count,
+ packet->test.negedge_value, packet->test.negedge_count);
}
::aos::Cleanup();
diff --git a/bbb_cape/src/cape/data_struct.h b/bbb_cape/src/cape/data_struct.h
index 367c359..e4f0d78 100644
--- a/bbb_cape/src/cape/data_struct.h
+++ b/bbb_cape/src/cape/data_struct.h
@@ -44,16 +44,18 @@
// We are 64-bit aligned at this point.
union {
+ // This is for the test code that basically just sends all of the values
+ // over to make sure that everything is working.
struct {
int32_t encoders[8];
uint16_t analogs[8];
uint32_t digitals;
+
+ int32_t posedge_value, negedge_value;
+ uint8_t posedge_count, negedge_count;
} test;
-
- struct {
- } bot3;
};
} __attribute__((aligned(8)));
#pragma pack(pop)
diff --git a/bbb_cape/src/cape/digital.c b/bbb_cape/src/cape/digital.c
index a15b00b..70fce99 100644
--- a/bbb_cape/src/cape/digital.c
+++ b/bbb_cape/src/cape/digital.c
@@ -33,8 +33,6 @@
void digital_capture_12P(void) ALIAS_WEAK(digital_capture_default);
void digital_capture_12N(void) ALIAS_WEAK(digital_capture_default);
-typedef void (*EXTIHandler)(uint32_t);
-
void EXTI2_IRQHandler(void) {
uint32_t inputs = GPIOB->IDR;
EXTI->PR = EXTI_PR_PR2;
@@ -72,7 +70,7 @@
}
static void EXTI8_Handler(uint32_t inputs) {
- if (inputs & (1 << 7)) {
+ if (inputs & (1 << 8)) {
digital_capture_7N();
} else {
digital_capture_7P();
@@ -88,21 +86,21 @@
}
void EXTI9_5_IRQHandler(void) {
- uint32_t inputs = GPIOC->IDR;
+ uint32_t a_inputs = GPIOA->IDR, b_inputs = GPIOB->IDR, c_inputs = GPIOC->IDR;
uint32_t exti = __clz(EXTI->PR);
EXTI->PR = (1 << 31) >> exti;
switch (exti) {
case 31 - 5:
- EXTI5_Handler(inputs);
+ EXTI5_Handler(c_inputs);
break;
case 31 - 7:
- EXTI7_Handler(inputs);
+ EXTI7_Handler(a_inputs);
break;
case 31 - 8:
- EXTI8_Handler(inputs);
+ EXTI8_Handler(b_inputs);
break;
case 31 - 9:
- EXTI9_Handler(inputs);
+ EXTI9_Handler(b_inputs);
break;
}
}
@@ -156,27 +154,27 @@
}
void EXTI15_10_IRQHandler(void) {
- uint32_t inputs = GPIOC->IDR;
+ uint32_t a_inputs = GPIOA->IDR, b_inputs = GPIOB->IDR, c_inputs = GPIOC->IDR;
uint32_t exti = __clz(EXTI->PR);
EXTI->PR = (1 << 31) >> exti;
switch (exti) {
case 31 - 10:
- EXTI10_Handler(inputs);
+ EXTI10_Handler(b_inputs);
break;
case 31 - 11:
- EXTI11_Handler(inputs);
+ EXTI11_Handler(a_inputs);
break;
case 31 - 12:
- EXTI12_Handler(inputs);
+ EXTI12_Handler(a_inputs);
break;
case 31 - 13:
- EXTI13_Handler(inputs);
+ EXTI13_Handler(c_inputs);
break;
case 31 - 14:
- EXTI14_Handler(inputs);
+ EXTI14_Handler(c_inputs);
break;
case 31 - 15:
- EXTI15_Handler(inputs);
+ EXTI15_Handler(c_inputs);
break;
}
}
diff --git a/bbb_cape/src/cape/digital.h b/bbb_cape/src/cape/digital.h
index 4905c23..9743c3f 100644
--- a/bbb_cape/src/cape/digital.h
+++ b/bbb_cape/src/cape/digital.h
@@ -5,37 +5,80 @@
void digital_init(void);
+// For all of the digital functions, a high voltage level on the input reads as
+// 1 (and a low to high transition is a positive edge).
+
static inline int digital_read(int num) {
switch (num) {
case 0:
- return GPIOC->IDR & (1 << 4);
+ return !(GPIOC->IDR & (1 << 4));
case 1:
- return GPIOC->IDR & (1 << 5);
+ return !(GPIOC->IDR & (1 << 5));
case 2:
- return GPIOC->IDR & (1 << 13);
+ return !(GPIOC->IDR & (1 << 13));
case 3:
- return GPIOC->IDR & (1 << 14);
+ return !(GPIOC->IDR & (1 << 14));
case 4:
- return GPIOC->IDR & (1 << 15);
+ return !(GPIOC->IDR & (1 << 15));
case 5:
- return GPIOB->IDR & (1 << 10);
+ return !(GPIOB->IDR & (1 << 10));
case 6:
- return GPIOB->IDR & (1 << 9);
+ return !(GPIOB->IDR & (1 << 9));
case 7:
- return GPIOB->IDR & (1 << 8);
+ return !(GPIOB->IDR & (1 << 8));
case 8:
- return GPIOA->IDR & (1 << 12);
+ return !(GPIOA->IDR & (1 << 12));
case 9:
- return GPIOA->IDR & (1 << 11);
+ return !(GPIOA->IDR & (1 << 11));
case 10:
- return GPIOA->IDR & (1 << 7);
+ return !(GPIOA->IDR & (1 << 7));
case 11:
- return GPIOB->IDR & (1 << 2);
+ return !(GPIOB->IDR & (1 << 2));
default:
return 0;
}
}
+// A helper function for implementing digital_capture_{disable,enable}.
+static inline enum IRQn digital_capture_getirqn(int num) {
+ switch (num) {
+ case 0:
+ return EXTI4_IRQn;
+ case 1:
+ return EXTI9_5_IRQn;
+ case 2:
+ return EXTI15_10_IRQn;
+ case 3:
+ return EXTI15_10_IRQn;
+ case 4:
+ return EXTI15_10_IRQn;
+ case 5:
+ return EXTI15_10_IRQn;
+ case 6:
+ return EXTI9_5_IRQn;
+ case 7:
+ return EXTI9_5_IRQn;
+ case 8:
+ return EXTI15_10_IRQn;
+ case 9:
+ return EXTI15_10_IRQn;
+ case 10:
+ return EXTI9_5_IRQn;
+ case 11:
+ return EXTI2_IRQn;
+ default:
+ __builtin_trap();
+ }
+}
+
+static inline void digital_capture_disable(int num) {
+ NVIC_DisableIRQ(digital_capture_getirqn(num));
+}
+
+static inline void digital_capture_enable(int num) {
+ NVIC_EnableIRQ(digital_capture_getirqn(num));
+}
+
// These are the functions for handling edges on the inputs. They have
// default (weak symbol) implementations that do nothing.
//void digital_capture_0P(void);
diff --git a/bbb_cape/src/cape/fill_packet.c b/bbb_cape/src/cape/fill_packet.c
index d2dc01e..012b7e3 100644
--- a/bbb_cape/src/cape/fill_packet.c
+++ b/bbb_cape/src/cape/fill_packet.c
@@ -55,7 +55,7 @@
struct DataStruct packet;
uint8_t padding[DATA_STRUCT_SEND_SIZE - sizeof(struct DataStruct) - 12];
uint32_t checksum;
- } data __attribute__((aligned(4)));
+ } __attribute__((packed)) data __attribute__((aligned(4)));
STATIC_ASSERT(sizeof(data) == DATA_STRUCT_SEND_SIZE - 8,
The_size_of_the_data_is_wrong);
struct DataStruct *packet = &data.packet;
@@ -89,6 +89,6 @@
led_set(LED_ERR, 0);
gyro_init();
- uart_common_configure(1500000);
+ uart_common_configure(750000);
uart_dma_configure(DATA_STRUCT_SEND_SIZE, buffer1, buffer2);
}
diff --git a/bbb_cape/src/cape/robot_test.c b/bbb_cape/src/cape/robot_test.c
index 85074c3..f329790 100644
--- a/bbb_cape/src/cape/robot_test.c
+++ b/bbb_cape/src/cape/robot_test.c
@@ -4,6 +4,25 @@
#include "cape/analog.h"
#include "cape/digital.h"
+#define CAPTURE_NUM 11
+
+#define CAPTURE(num, np) digital_capture_ ## num ## np
+#define CAPTURE2(num, np) CAPTURE(num, np)
+#define CAPTURE_P CAPTURE2(CAPTURE_NUM, P)
+#define CAPTURE_N CAPTURE2(CAPTURE_NUM, N)
+
+static int32_t posedge_value, negedge_value;
+static uint8_t posedge_count = 0, negedge_count = 0;
+
+void CAPTURE_P(void) {
+ ++posedge_count;
+ posedge_value = encoder_read(1);
+}
+void CAPTURE_N(void) {
+ ++negedge_count;
+ negedge_value = encoder_read(1);
+}
+
void robot_fill_packet(struct DataStruct *packet) {
packet->test.encoders[0] = encoder_read(0);
packet->test.encoders[1] = encoder_read(1);
@@ -20,8 +39,13 @@
packet->test.digitals = 0;
for (int i = 0; i < 12; ++i) {
- SET_BITS(packet->test.digitals, 1, !!digital_read(i), i);
+ SET_BITS(packet->test.digitals, 1, digital_read(i), i);
}
- // TODO(brians): digitals
+ digital_capture_disable(CAPTURE_NUM);
+ packet->test.posedge_count = posedge_count;
+ packet->test.posedge_value = posedge_value;
+ packet->test.negedge_count = negedge_count;
+ packet->test.negedge_value = negedge_value;
+ digital_capture_enable(CAPTURE_NUM);
}