From 4ba824dab86433bb5295878f2380a9bd9536d67e Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Sat, 16 Apr 2022 20:44:24 +0200 Subject: i2c: stm32: Add v2 support. --- .gitignore | 1 + SConscript | 2 +- i2c/SConscript | 21 ++++++++ i2c/i2c.cpp | 131 ------------------------------------------------ i2c/i2c.h | 59 ---------------------- i2c/stm32_i2c.h | 35 +++++++++++++ platforms/stm32/f7.yaml | 14 ++++++ 7 files changed, 72 insertions(+), 191 deletions(-) create mode 100644 i2c/SConscript delete mode 100644 i2c/i2c.cpp delete mode 100644 i2c/i2c.h create mode 100644 i2c/stm32_i2c.h 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' % 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 - -#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 = ®_; - 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 -#include - -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 + +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 +class STM32_I2C_t : public mmio_ptr { + public: + using mmio_ptr::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 -- cgit v1.2.3