summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bma150.h33
-rw-r--r--drivers/gps.cpp40
-rw-r--r--drivers/gps.h60
-rw-r--r--drivers/itg3200.h32
-rw-r--r--drivers/ppmsum.cpp54
-rw-r--r--drivers/ppmsum.h29
-rw-r--r--drivers/xbee.cpp51
-rw-r--r--drivers/xbee.h8
8 files changed, 307 insertions, 0 deletions
diff --git a/drivers/bma150.h b/drivers/bma150.h
new file mode 100644
index 0000000..2e043ff
--- /dev/null
+++ b/drivers/bma150.h
@@ -0,0 +1,33 @@
+#ifndef BMA150_H
+#define BMA150_H
+
+#include "i2c.h"
+
+class BMA150 {
+ private:
+ I2C& i2c;
+
+ public:
+ int16_t x, y, z;
+
+ BMA150(I2C& i2c_bus) : i2c(i2c_bus) {
+
+ }
+
+ void init() {
+ uint8_t temp;
+ i2c.read_reg(0x38, 0x14, 1, &temp);
+ i2c.write_reg(0x38, 0x14, (temp & 0xe0) | 0x00 | 0x00); // 2g range, 25 Hz bandwidth
+ }
+
+ void update() {
+ uint8_t buf[6];
+ i2c.read_reg(0x38, 0x02, 6, buf);
+
+ x = (buf[1] << 8 | buf[0]) - 0;
+ y = (buf[3] << 8 | buf[2]) - 0;
+ z = (buf[5] << 8 | buf[4]) - 0;
+ }
+};
+
+#endif
diff --git a/drivers/gps.cpp b/drivers/gps.cpp
new file mode 100644
index 0000000..1ae3684
--- /dev/null
+++ b/drivers/gps.cpp
@@ -0,0 +1,40 @@
+#include "gps.h"
+
+GPS* GPS::self;
+
+template<>
+void interrupt<Interrupt::USART3>() {
+ GPS::self->irq();
+}
+
+void GPS::irq() {
+
+ uint8_t c = USART3.DR;
+
+ if(!incomplete_msg) {
+ incomplete_msg = msg_pool.create();
+
+ if(!incomplete_msg) {
+ return;
+ }
+ }
+
+ if(incomplete_msg->n == 0 && c != '$') {
+ return;
+ }
+
+ if(incomplete_msg->n >= 128) {
+ incomplete_msg->n = 0;
+ return;
+ }
+
+ incomplete_msg->buf[incomplete_msg->n++] = c;
+
+ if(c == '\n') {
+ GPIOB.ODR ^= 1 << 1;
+
+ const_cast<P<GPSMsg>&>(complete_msg) = incomplete_msg;
+ incomplete_msg.reset();
+ complete = true;
+ }
+}
diff --git a/drivers/gps.h b/drivers/gps.h
new file mode 100644
index 0000000..c37fc8a
--- /dev/null
+++ b/drivers/gps.h
@@ -0,0 +1,60 @@
+#ifndef GPS_H
+#define GPS_H
+
+#include "stm32.h"
+#include "interrupt.h"
+#include "thread.h"
+
+#include "pool.h"
+
+struct GPSMsg {
+ unsigned int n;
+ uint8_t buf[128];
+
+ GPSMsg() : n(0) {}
+};
+
+class GPS {
+ friend void interrupt<Interrupt::USART3>();
+
+ private:
+ static GPS* self;
+
+ void irq();
+
+ Pool<GPSMsg, 4> msg_pool;
+
+ P<GPSMsg> incomplete_msg;
+ volatile P<GPSMsg> complete_msg;
+
+ volatile bool complete;
+
+ public:
+ GPS() {
+ self = this;
+ }
+
+ void enable() {
+ RCC.enable(RCC.USART3);
+ USART3.BRR = 7500; // 4800 baud
+ USART3.CR1 = 0x202c;
+
+ Interrupt::enable(Interrupt::USART3);
+ }
+
+ P<GPSMsg> read() {
+ while(!complete) {
+ Thread::yield();
+ }
+
+ complete = false;
+
+ P<GPSMsg> msg = const_cast<P<GPSMsg>&>(complete_msg);
+
+ const_cast<P<GPSMsg>&>(complete_msg).reset();
+
+ return msg;
+ }
+};
+
+#endif
diff --git a/drivers/itg3200.h b/drivers/itg3200.h
new file mode 100644
index 0000000..2e90f62
--- /dev/null
+++ b/drivers/itg3200.h
@@ -0,0 +1,32 @@
+#ifndef ITG3200_H
+#define ITG3200_H
+
+#include "i2c.h"
+
+class ITG3200 {
+ private:
+ I2C& i2c;
+
+ public:
+ int16_t x, y, z;
+
+ ITG3200(I2C& i2c_bus) : i2c(i2c_bus) {
+
+ }
+
+ void init() {
+ i2c.write_reg(0x68, 0x3e, 0x03); // Select clock reference.
+ i2c.write_reg(0x68, 0x16, 0x18 | 0x02); // 2000 deg/sec range, 98 Hz bandwidth.
+ }
+
+ void update() {
+ uint8_t buf[6];
+ i2c.read_reg(0x68, 0x1d, 6, buf);
+
+ x = (buf[0] << 8 | buf[1]) - 0;
+ y = (buf[2] << 8 | buf[3]) - 0;
+ z = (buf[4] << 8 | buf[5]) - 0;
+ }
+};
+
+#endif
diff --git a/drivers/ppmsum.cpp b/drivers/ppmsum.cpp
new file mode 100644
index 0000000..2beaccb
--- /dev/null
+++ b/drivers/ppmsum.cpp
@@ -0,0 +1,54 @@
+#include "ppmsum.h"
+
+PPMSum* PPMSum::self = 0;
+
+template<>
+void interrupt<Interrupt::TIM1_UP>() {
+ PPMSum::self->irq();
+}
+
+template<>
+void interrupt<Interrupt::TIM1_CC>() {
+ PPMSum::self->irq();
+}
+
+void PPMSum::irq() {
+ int16_t sr = TIM1.SR;
+ TIM1.SR = 0;
+
+ if(sr & 0x01) {
+ // Timeout.
+
+ synced = false;
+
+ } else if(sr & 0x02) {
+ // Period.
+
+ if(TIM1.CCR1 > 5000) {
+ synced = true;
+ index = 0;
+ } else {
+ index++;
+ index &= 0xf;
+ }
+
+ } else if(sr & 0x04) {
+ // Pulsewidth.
+
+ channels[index] = TIM1.CCR2;
+ }
+}
+
+void PPMSum::enable() {
+ RCC.enable(RCC.TIM1);
+ TIM1.PSC = 72;
+ TIM1.CCMR1 = 0x0201;
+ TIM1.SMCR = 0x54;
+ TIM1.CCER = 0x31;
+ TIM1.DIER = 0x07;
+
+ Interrupt::enable(Interrupt::TIM1_UP);
+ Interrupt::enable(Interrupt::TIM1_CC);
+
+ TIM1.CR1 = 0x05;
+}
diff --git a/drivers/ppmsum.h b/drivers/ppmsum.h
new file mode 100644
index 0000000..90bb860
--- /dev/null
+++ b/drivers/ppmsum.h
@@ -0,0 +1,29 @@
+#ifndef PPMSUM_H
+#define PPMSUM_H
+
+#include <stdint.h>
+#include "interrupt.h"
+
+class PPMSum {
+ friend void interrupt<Interrupt::TIM1_UP>();
+ friend void interrupt<Interrupt::TIM1_CC>();
+
+ private:
+ static PPMSum* self;
+
+ uint8_t index;
+
+ void irq();
+
+ public:
+ PPMSum() {
+ self = this;
+ }
+
+ bool synced;
+ uint16_t channels[16];
+
+ void enable();
+};
+
+#endif
diff --git a/drivers/xbee.cpp b/drivers/xbee.cpp
new file mode 100644
index 0000000..efee619
--- /dev/null
+++ b/drivers/xbee.cpp
@@ -0,0 +1,51 @@
+#include "xbee.h"
+
+#include "usart.h"
+#include "mutex.h"
+
+Mutex xbee_mutex;
+
+void xbee_send(uint16_t type, int len, const uint8_t* buf) {
+ xbee_mutex.lock();
+
+ // Start and length.
+ usart_send(0x7e);
+ usart_send(((len + 16) >> 8) & 0xff);
+ usart_send((len + 16) & 0xff);
+
+ // Frame type and ID.
+ usart_send(0x10);
+ usart_send(0x01);
+
+ // Destination address.
+ usart_send(0x00);
+ usart_send(0x13);
+ usart_send(0xa2);
+ usart_send(0x00);
+ usart_send(0x40);
+ usart_send(0x6f);
+ usart_send(0x19);
+ usart_send(0xf1);
+
+ usart_send(0xff);
+ usart_send(0xfe);
+ usart_send(0x00);
+ usart_send(0x00);
+
+ uint8_t chsum = 0x83;
+
+ usart_send(type & 0xff);
+ chsum -= type & 0xff;
+ usart_send(type >> 8);
+ chsum -= type >> 8;
+
+ // Payload
+ for(int i = 0; i < len; i++) {
+ usart_send(buf[i]);
+ chsum -= buf[i];
+ }
+
+ usart_send(chsum);
+
+ xbee_mutex.unlock();
+}
diff --git a/drivers/xbee.h b/drivers/xbee.h
new file mode 100644
index 0000000..59cf0cb
--- /dev/null
+++ b/drivers/xbee.h
@@ -0,0 +1,8 @@
+#ifndef XBEE_H
+#define XBEE_H
+
+#include <stdint.h>
+
+void xbee_send(uint16_t type, int len, const uint8_t* buf);
+
+#endif