summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2022-04-16 20:44:24 +0200
committerVegard Storheil Eriksen <zyp@jvnv.net>2022-04-16 21:01:57 +0200
commit4ba824dab86433bb5295878f2380a9bd9536d67e (patch)
tree0b8a25c8c65b350f2e2266c9992a385c0ec9c681
parent32df2ae55601f1ad135247ad79a913514d018032 (diff)
i2c: stm32: Add v2 support.
-rw-r--r--.gitignore1
-rw-r--r--SConscript2
-rw-r--r--i2c/SConscript21
-rw-r--r--i2c/i2c.cpp131
-rw-r--r--i2c/i2c.h59
-rw-r--r--i2c/stm32_i2c.h35
-rw-r--r--platforms/stm32/f7.yaml14
7 files changed, 72 insertions, 191 deletions
diff --git a/.gitignore b/.gitignore
index 46bc223..f349eb7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,5 +22,6 @@ syscfg/syscfg.h
timer/timer.h
usb/usb.h
uart/uart.h
+i2c/i2c.h
wpan/hsem.h
wpan/ipcc.h
diff --git a/SConscript b/SConscript
index 01679d9..8b41b09 100644
--- a/SConscript
+++ b/SConscript
@@ -17,10 +17,10 @@ env.Append(
env.SConscript('syscfg/SConscript'),
env.SConscript('timer/SConscript'),
env.SConscript('uart/SConscript'),
+ env.SConscript('i2c/SConscript'),
env.SConscript('usb/SConscript'),
env.SConscript('wpan/SConscript'),
Glob('startup/*.cpp'),
- Glob('i2c/*.cpp'),
Glob('os/*.cpp'),
],
)
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;
+};
diff --git a/platforms/stm32/f7.yaml b/platforms/stm32/f7.yaml
index abf821a..b6b158a 100644
--- a/platforms/stm32/f7.yaml
+++ b/platforms/stm32/f7.yaml
@@ -26,6 +26,20 @@
offset: 0x40004400
type: v2
+ stm32_i2c:
+ I2C1:
+ offset: 0x40005400
+ type: v2
+ I2C2:
+ offset: 0x40005800
+ type: v2
+ I2C3:
+ offset: 0x40005c00
+ type: v2
+ I2C4:
+ offset: 0x40006000
+ type: v2
+
rcc:
RCC:
offset: 0x40023800