summaryrefslogtreecommitdiff
path: root/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'i2c')
-rw-r--r--i2c/SConscript21
-rw-r--r--i2c/i2c.cpp131
-rw-r--r--i2c/i2c.h59
-rw-r--r--i2c/stm32_i2c.h35
4 files changed, 56 insertions, 190 deletions
diff --git a/i2c/SConscript b/i2c/SConscript
new file mode 100644
index 0000000..c639898
--- /dev/null
+++ b/i2c/SConscript
@@ -0,0 +1,21 @@
+Import('env')
+
+headers = []
+instances = []
+sources = []
+aliases = {}
+
+periph = env['PLATFORM_SPEC'].get('periph', {})
+
+if 'stm32_i2c' in periph:
+ headers.append('stm32_i2c.h')
+ for name, data in periph['stm32_i2c'].items():
+ instances.append({
+ 'type': 'STM32_I2C_t<STM32_I2C_reg_%s_t>' % data['type'],
+ 'name': name,
+ 'args': [data['offset']],
+ })
+
+env.Jinja2('i2c.h', '../templates/periph_instances.h.j2', headers = headers, instances = instances, aliases = aliases)
+
+Return('sources')
diff --git a/i2c/i2c.cpp b/i2c/i2c.cpp
deleted file mode 100644
index 75aee94..0000000
--- a/i2c/i2c.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#include "i2c.h"
-
-#include <rcc/rcc.h>
-
-#if defined(STM32F1)
-I2C_t I2C1(0x40005400, 36000000);
-I2C_t I2C2(0x40005800, 36000000);
-#elif defined(STM32F4)
-I2C_t I2C1(0x40005400, 42000000);
-I2C_t I2C2(0x40005800, 42000000);
-//I2C_t I2C3(0x40005c00, 42000000);
-#endif
-
-#if defined(STM32F1) || defined(STM32F4)
-void I2C_t::irq_ev() {
- uint32_t sr1 = reg.SR1;
- reg.SR2;
-
- // EV5, SB = 1: Start condition sent.
- if(sr1 & 0x01) {
- // Send address.
- reg.DR = (addr << 1) | (writing ? 0 : 1);
- }
-
- // EV6, ADDR = 1: Address sent.
- if(sr1 & 0x02) {
- if(writing) {
- reg.DR = *write_p++;
- writing--;
- } else {
- if(reading > 1) {
- reg.CR1 |= 0x400; // Set ACK.
- } else {
- reg.CR1 |= 0x200; // Set STOP.
- }
- }
- }
-
- // EV7, RxNE = 1: Receive buffer not empty.
- if(sr1 & 0x40) {
- *read_p++ = reg.DR;
- reading--;
-
- if(reading == 1) {
- // Unset ACK, set STOP.
- reg.CR1 = (reg.CR1 & ~0x400) | 0x200;
- }
-
- if(reading == 0) {
- busy = 0;
- }
- }
-
- //reg.CR1 &= ~0x400;
-
- // EV8, TxE = 1, BTF = 0: Transmit buffer empty, still writing.
- if(sr1 & 0x80 && !(sr1 & 0x04)) {
- if(writing) {
- // Send data.
- reg.DR = *write_p++;
- writing--;
- } else {
- // All data sent.
-
- if(reading) {
- // Send repeat start.
- reg.CR1 |= 0x100;
- } else {
- // Send stop.
- reg.CR1 |= 0x200;
- busy = 0;
- }
- }
- }
-}
-
-void I2C_t::irq_er() {
- handle_error();
-}
-
-void I2C_t::handle_error() {
- reg.SR1;
- reg.SR2;
-
- //while(1);
-
- reg.SR1 = 0;
-
- reg.CR1 |= 0x200;
- busy = 0;
-}
-
-void I2C_t::enable() {
- reg.CR1 = 0x8000;
- reg.CR1 = 0;
-
- reg.CR2 = 0x700 | (clk / 1000000);
- reg.TRISE = clk / 1000000 + 1;
- reg.CCR = clk / 2 / 100000;
-
- reg.CR1 = 1;
-}
-
-void I2C_t::write_reg(uint8_t addr_, uint8_t reg_, uint8_t data) {
- addr = addr_;
- writing = 2;
- reading = 0;
- volatile uint8_t buf[] = {reg_, data};
- write_p = buf;
- busy = 1;
-
- reg.CR1 |= 0x100;
-
- while(busy) {
- }
-}
-
-void I2C_t::read_reg(uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf) {
- addr = addr_;
- writing = 1;
- reading = len;
- write_p = &reg_;
- read_p = buf;
- busy = 1;
-
- reg.CR1 |= 0x100;
-
- while(busy) {
- }
-}
-#endif
diff --git a/i2c/i2c.h b/i2c/i2c.h
deleted file mode 100644
index a2fde32..0000000
--- a/i2c/i2c.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef I2C_H
-#define I2C_H
-
-#include <stdint.h>
-#include <interrupt/interrupt.h>
-
-struct I2C_reg_t {
- volatile uint32_t CR1;
- volatile uint32_t CR2;
- volatile uint32_t OAR1;
- volatile uint32_t OAR2;
- volatile uint32_t DR;
- volatile uint32_t SR1;
- volatile uint32_t SR2;
- volatile uint32_t CCR;
- volatile uint32_t TRISE;
-};
-
-class I2C_t {
- private:
- volatile uint8_t addr;
- volatile uint8_t writing;
- volatile uint8_t reading;
- volatile uint8_t* write_p;
- volatile uint8_t* read_p;
-
- volatile bool busy;
-
- public:
- I2C_reg_t& reg;
- const uint32_t clk;
-
- I2C_t(uint32_t reg_addr, uint32_t bus_clk) : reg(*(I2C_reg_t*)reg_addr), clk(bus_clk) {
- reading = writing = 0;
- }
-
- void irq_ev();
- void irq_er();
-
- void handle_error();
-
- 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);
-};
-
-#if defined(STM32F1)
-extern I2C_t I2C1;
-extern I2C_t I2C2;
-#elif defined(STM32F4)
-extern I2C_t I2C1;
-extern I2C_t I2C2;
-extern I2C_t I2C3;
-#endif
-
-typedef I2C_t I2C;
-
-#endif
diff --git a/i2c/stm32_i2c.h b/i2c/stm32_i2c.h
new file mode 100644
index 0000000..63bda09
--- /dev/null
+++ b/i2c/stm32_i2c.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <mmio/mmio.h>
+
+struct STM32_I2C_reg_v1_t {
+ volatile uint32_t CR1;
+ volatile uint32_t CR2;
+ volatile uint32_t OAR1;
+ volatile uint32_t OAR2;
+ volatile uint32_t DR;
+ volatile uint32_t SR1;
+ volatile uint32_t SR2;
+ volatile uint32_t CCR;
+ volatile uint32_t TRISE;
+};
+
+struct STM32_I2C_reg_v2_t {
+ volatile uint32_t CR1;
+ volatile uint32_t CR2;
+ volatile uint32_t OAR1;
+ volatile uint32_t OAR2;
+ volatile uint32_t TIMINGR;
+ volatile uint32_t TIMEOUTR;
+ volatile uint32_t ISR;
+ volatile uint32_t ICR;
+ volatile uint32_t PECR;
+ volatile uint32_t RXDR;
+ volatile uint32_t TXDR;
+};
+
+template <typename T>
+class STM32_I2C_t : public mmio_ptr<T> {
+ public:
+ using mmio_ptr<T>::ptr;
+};