summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--i2c.cpp74
-rw-r--r--i2c.h16
-rw-r--r--main.cpp203
-rw-r--r--ppmsum.cpp53
-rw-r--r--ppmsum.h26
-rw-r--r--usart.h24
-rw-r--r--xbee.h40
7 files changed, 242 insertions, 194 deletions
diff --git a/i2c.cpp b/i2c.cpp
new file mode 100644
index 0000000..90c0ce1
--- /dev/null
+++ b/i2c.cpp
@@ -0,0 +1,74 @@
+#include "i2c.h"
+
+#include "stm32.h"
+
+void I2C::enable() {
+ RCC.enable(RCC.I2C2);
+ asm volatile("nop");
+
+ I2C2.CR1 = 0x8000;
+ I2C2.CR1 = 0;
+
+ I2C2.CR2 = 36;
+ I2C2.TRISE = 37;
+ I2C2.CCR = 180;
+ I2C2.CR1 = 1;
+}
+
+void I2C::write_reg(uint8_t addr, uint8_t reg, uint8_t data) {
+ I2C2.CR1 |= 0x100;
+ while(!(I2C2.SR1 & 0x01));
+
+ I2C2.DR = (addr << 1) | 0;
+ while (!(I2C2.SR1 & 0x02));
+ I2C2.SR2;
+
+ I2C2.DR = reg;
+ while (!(I2C2.SR1 & 0x80));
+
+ I2C2.DR = data;
+ while (!(I2C2.SR1 & 0x04));
+
+ I2C2.CR1 |= 0x200;
+}
+
+void I2C::read_reg(uint8_t addr, uint8_t reg, uint8_t len, uint8_t* buf) {
+ I2C2.CR1 |= 0x100;
+ while(!(I2C2.SR1 & 0x01));
+
+ I2C2.DR = (addr << 1) | 0;
+ while (!(I2C2.SR1 & 0x02));
+ I2C2.SR2;
+
+ I2C2.DR = reg;
+ while (!(I2C2.SR1 & 0x80));
+
+ I2C2.CR1 |= 0x100;
+ while(!(I2C2.SR1 & 0x01));
+
+ I2C2.DR = (addr << 1) | 1;
+ while (!(I2C2.SR1 & 0x02));
+ I2C2.SR2;
+
+ I2C2.CR1 |= 0x400; // Set ACK.
+
+ while(len) {
+ if(len == 3) {
+ while (!(I2C2.SR1 & 0x04)); // Wait for BTF
+
+ I2C2.CR1 &= ~0x400; // Clear ACK.
+ *buf++ = I2C2.DR;
+ len--;
+
+ I2C2.CR1 |= 0x200; // Set STOP.
+ *buf++ = I2C2.DR;
+ len--;
+
+ } else {
+ while (!(I2C2.SR1 & 0x40)); // Wait for RXNE
+
+ *buf++ = I2C2.DR;
+ len--;
+ }
+ }
+}
diff --git a/i2c.h b/i2c.h
new file mode 100644
index 0000000..0681160
--- /dev/null
+++ b/i2c.h
@@ -0,0 +1,16 @@
+#ifndef I2C_H
+#define I2C_H
+
+#include <stdint.h>
+
+class I2C {
+ public:
+ void enable();
+
+ void write_reg(uint8_t addr, uint8_t reg, uint8_t data);
+ void read_reg(uint8_t addr, uint8_t reg, uint8_t len, uint8_t* buf);
+};
+
+
+
+#endif
diff --git a/main.cpp b/main.cpp
index 7af1122..440cad4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,180 +1,10 @@
#include "stm32.h"
#include "interrupt.h"
-volatile unsigned int cnt;
-
-void i2c_write_reg(uint8_t addr, uint8_t reg, uint8_t data) {
- I2C2.CR1 |= 0x100;
- while(!(I2C2.SR1 & 0x01));
-
- I2C2.DR = (addr << 1) | 0;
- while (!(I2C2.SR1 & 0x02));
- I2C2.SR2;
-
- I2C2.DR = reg;
- while (!(I2C2.SR1 & 0x80));
-
- I2C2.DR = data;
- while (!(I2C2.SR1 & 0x04));
-
- I2C2.CR1 |= 0x200;
-}
-
-void i2c_read_reg(uint8_t addr, uint8_t reg, uint8_t len, uint8_t* buf) {
- I2C2.CR1 |= 0x100;
- while(!(I2C2.SR1 & 0x01));
-
- I2C2.DR = (addr << 1) | 0;
- while (!(I2C2.SR1 & 0x02));
- I2C2.SR2;
-
- I2C2.DR = reg;
- while (!(I2C2.SR1 & 0x80));
-
- I2C2.CR1 |= 0x100;
- while(!(I2C2.SR1 & 0x01));
-
- I2C2.DR = (addr << 1) | 1;
- while (!(I2C2.SR1 & 0x02));
- I2C2.SR2;
-
- I2C2.CR1 |= 0x400; // Set ACK.
-
- while(len) {
- if(len == 3) {
- while (!(I2C2.SR1 & 0x04)); // Wait for BTF
-
- I2C2.CR1 &= ~0x400; // Clear ACK.
- *buf++ = I2C2.DR;
- len--;
-
- I2C2.CR1 |= 0x200; // Set STOP.
- *buf++ = I2C2.DR;
- len--;
-
- } else {
- while (!(I2C2.SR1 & 0x40)); // Wait for RXNE
-
- *buf++ = I2C2.DR;
- len--;
- }
- }
-}
+#include "ppmsum.h"
+#include "i2c.h"
-template<>
-void interrupt<Interrupt::USART1>() {
- USART1.DR;
- GPIOA.ODR ^= 1 << 5;
-}
-
-void usart_send(uint8_t data) {
- while(!(USART1.SR & 0x80)); // Wait for TXE.
-
- USART1.DR = data;
-}
-
-void xbee_send(int len, const uint8_t* buf) {
- // Start and length.
- usart_send(0x7e);
- usart_send(((len + 14) >> 8) & 0xff);
- usart_send((len + 14) & 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(0x00);
- usart_send(0x00);
- usart_send(0x00);
- usart_send(0x00);
-
- uint8_t chsum = 0x80;
-
- // Payload
- for(int i = 0; i < len; i++) {
- usart_send(buf[i]);
- chsum -= buf[i];
- }
-
- usart_send(chsum);
-}
-
-class PPMSum {
- friend void interrupt<Interrupt::TIM4>();
-
- private:
- static PPMSum* self;
-
- uint8_t index;
- uint16_t channels[16];
-
- void irq() {
- int16_t sr = TIM4.SR;
- TIM4.SR = 0;
-
- if(sr & 0x06) {
- GPIOA.ODR = 1 << 5;
- } else {
- GPIOA.ODR = 0;
- }
-
-
- if(sr & 0x01) {
- // Timeout.
-
- // TODO: Indicate failsafe.
-
- } else if(sr & 0x02) {
- // Period.
-
- if(TIM4.CCR1 > 5000) {
- index = 0;
- } else {
- index++;
- }
-
- } else if(sr & 0x04) {
- // Pulsewidth.
-
- channels[index] = TIM4.CCR2;
- }
- }
-
- public:
- PPMSum() {
- self = this;
- }
-
- void start() {
- RCC.enable(RCC.TIM4);
- TIM4.PSC = 36;
- TIM4.CCMR1 = 0x0201;
- TIM4.SMCR = 0x54;
- TIM4.CCER = 0x31;
- TIM4.DIER = 0x07;
-
- Interrupt::enable(Interrupt::TIM4);
-
- TIM4.CR1 = 0x05;
- }
-};
-
-PPMSum* PPMSum::self = 0;
-
-template<>
-void interrupt<Interrupt::TIM4>() {
- PPMSum::self->irq();
-}
+volatile unsigned int cnt;
int main() {
RCC.enable(RCC.AFIO);
@@ -188,33 +18,18 @@ int main() {
GPIOB.CRH = 0x4444ff44;
cnt = 0;
- while(cnt++ < (1 << 20));
-
- // 100 kHz.
- RCC.enable(RCC.I2C2);
- while(cnt++ < (1 << 20));
- I2C2.CR1 = 0x8000;
- I2C2.CR1 = 0;
+ I2C i2c;
- I2C2.CR2 = 36;
- I2C2.TRISE = 37;
- I2C2.CCR = 180;
- I2C2.CR1 = 1;
+ i2c.enable();
- i2c_write_reg(0x68, 0x3e, 0x03);
- i2c_write_reg(0x68, 0x16, 0x18 | 0x02);
+ i2c.write_reg(0x68, 0x3e, 0x03);
+ i2c.write_reg(0x68, 0x16, 0x18 | 0x02);
uint8_t buf[6];
- RCC.enable(RCC.USART1);
- USART1.BRR = 7500; // 9600 baud
- USART1.CR1 = 0x202c;
-
- Interrupt::enable(Interrupt::USART1);
-
PPMSum ppmsum;
- ppmsum.start();
+ ppmsum.enable();
while(1) {
cnt++;
@@ -225,7 +40,7 @@ int main() {
}
if(!(cnt & ((1 << 20) - 1))) {
- i2c_read_reg(0x68, 0x1d, 6, buf);
+ i2c.read_reg(0x68, 0x1d, 6, buf);
//xbee_send(6, buf);
}
}
diff --git a/ppmsum.cpp b/ppmsum.cpp
new file mode 100644
index 0000000..7b77036
--- /dev/null
+++ b/ppmsum.cpp
@@ -0,0 +1,53 @@
+#include "ppmsum.h"
+
+PPMSum* PPMSum::self = 0;
+
+template<>
+void interrupt<Interrupt::TIM4>() {
+ PPMSum::self->irq();
+}
+
+void PPMSum::irq() {
+ int16_t sr = TIM4.SR;
+ TIM4.SR = 0;
+
+ if(sr & 0x06) {
+ GPIOA.ODR = 1 << 5;
+ } else {
+ GPIOA.ODR = 0;
+ }
+
+
+ if(sr & 0x01) {
+ // Timeout.
+
+ // TODO: Indicate failsafe.
+
+ } else if(sr & 0x02) {
+ // Period.
+
+ if(TIM4.CCR1 > 5000) {
+ index = 0;
+ } else {
+ index++;
+ }
+
+ } else if(sr & 0x04) {
+ // Pulsewidth.
+
+ channels[index] = TIM4.CCR2;
+ }
+}
+
+void PPMSum::enable() {
+ RCC.enable(RCC.TIM4);
+ TIM4.PSC = 36;
+ TIM4.CCMR1 = 0x0201;
+ TIM4.SMCR = 0x54;
+ TIM4.CCER = 0x31;
+ TIM4.DIER = 0x07;
+
+ Interrupt::enable(Interrupt::TIM4);
+
+ TIM4.CR1 = 0x05;
+}
diff --git a/ppmsum.h b/ppmsum.h
new file mode 100644
index 0000000..3c4ce79
--- /dev/null
+++ b/ppmsum.h
@@ -0,0 +1,26 @@
+#ifndef PPMSUM_H
+#define PPMSUM_H
+
+#include <stdint.h>
+#include "interrupt.h"
+
+class PPMSum {
+ friend void interrupt<Interrupt::TIM4>();
+
+ private:
+ static PPMSum* self;
+
+ uint8_t index;
+ uint16_t channels[16];
+
+ void irq();
+
+ public:
+ PPMSum() {
+ self = this;
+ }
+
+ void enable();
+};
+
+#endif
diff --git a/usart.h b/usart.h
new file mode 100644
index 0000000..6c145c6
--- /dev/null
+++ b/usart.h
@@ -0,0 +1,24 @@
+#ifndef USART_H
+#define USART_H
+
+template<>
+void interrupt<Interrupt::USART1>() {
+ USART1.DR;
+ GPIOA.ODR ^= 1 << 5;
+}
+
+void usart_enable() {
+ RCC.enable(RCC.USART1);
+ USART1.BRR = 7500; // 9600 baud
+ USART1.CR1 = 0x202c;
+
+ Interrupt::enable(Interrupt::USART1);
+}
+
+void usart_send(uint8_t data) {
+ while(!(USART1.SR & 0x80)); // Wait for TXE.
+
+ USART1.DR = data;
+}
+
+#endif
diff --git a/xbee.h b/xbee.h
new file mode 100644
index 0000000..2b577b2
--- /dev/null
+++ b/xbee.h
@@ -0,0 +1,40 @@
+#ifndef XBEE_H
+#define XBEE_H
+
+void xbee_send(int len, const uint8_t* buf) {
+ // Start and length.
+ usart_send(0x7e);
+ usart_send(((len + 14) >> 8) & 0xff);
+ usart_send((len + 14) & 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(0x00);
+ usart_send(0x00);
+ usart_send(0x00);
+ usart_send(0x00);
+
+ uint8_t chsum = 0x80;
+
+ // Payload
+ for(int i = 0; i < len; i++) {
+ usart_send(buf[i]);
+ chsum -= buf[i];
+ }
+
+ usart_send(chsum);
+}
+
+#endif