summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBirte Kristina Friesel <derf@finalrewind.org>2024-02-11 21:21:28 +0100
committerBirte Kristina Friesel <derf@finalrewind.org>2024-02-11 21:21:28 +0100
commit3fffef85de0b780eb26beef5625242355053e872 (patch)
tree516fb36dbbd5b84475fd5b2c852aef18f16e8214
parentae68513e744e2a7d99ee085c02de227b135b5a7d (diff)
stm32f446re: Add I²C driver
-rw-r--r--README.md3
-rw-r--r--include/arch/stm32f446re-nucleo/driver/i2c.h23
-rw-r--r--src/arch/stm32f446re-nucleo/Kconfig14
-rw-r--r--src/arch/stm32f446re-nucleo/Makefile.inc4
-rw-r--r--src/arch/stm32f446re-nucleo/driver/i2c.cc38
5 files changed, 80 insertions, 2 deletions
diff --git a/README.md b/README.md
index c9dcc8c..4cba957 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ features; the remainder of this README covers details.
| MSP430FR5969 | 16 MHz | 48 (64) KiB FRAM | 2 KiB SRAM | I²C, SPI, UART, DMX, ADC |
| MSP430FR5994 | 16 MHz | 48 (256) KiB FRAM | 4 (8) KiB SRAM | I²C, SPI, UART, DMX, ADC |
| RM46L852 (Cortex-R4F) | 160 MHz | 1.25 MiB Flash | 192 KiB SRAM | |
-| STM32F446RE (Cortex-M4) | 168 MHz | 512 KiB Flash | 128 KiB SRAM | |
+| STM32F446RE (Cortex-M4) | 168 MHz | 512 KiB Flash | 128 KiB SRAM | I²C |
| STM32F746ZG (Cortex-M7) | 216 MHz | 1 MiB Flash | 320 KiB SRAM | |
| POSIX | – | – | – | I²C |
@@ -131,6 +131,7 @@ Peripheral communication:
Peripheral communication:
* UART output on USART2
+* I²C on I2C1 muxed to PB8 / PB9
### STM32F746ZG (NUCLEO-F746ZG)
diff --git a/include/arch/stm32f446re-nucleo/driver/i2c.h b/include/arch/stm32f446re-nucleo/driver/i2c.h
new file mode 100644
index 0000000..384827e
--- /dev/null
+++ b/include/arch/stm32f446re-nucleo/driver/i2c.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2024 Birte Kristina Friesel
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#ifndef I2C_H
+#define I2C_H
+
+class I2C {
+ private:
+ I2C(const I2C &copy);
+
+ public:
+ I2C () {}
+ signed char setup();
+ signed char xmit(unsigned char address,
+ unsigned char tx_len, unsigned char *tx_buf,
+ unsigned char rx_len, unsigned char *rx_buf);
+};
+
+extern I2C i2c;
+
+#endif
diff --git a/src/arch/stm32f446re-nucleo/Kconfig b/src/arch/stm32f446re-nucleo/Kconfig
index a97d8b2..0fa6b15 100644
--- a/src/arch/stm32f446re-nucleo/Kconfig
+++ b/src/arch/stm32f446re-nucleo/Kconfig
@@ -1,10 +1,22 @@
-# Copyright 2020 Birte Kristina Friesel
+# Copyright 2024 Birte Kristina Friesel
#
# SPDX-License-Identifier: CC0-1.0
config arch_stm32f446re_nucleo_driver_counter
bool "Cycle Counter"
select meta_driver_counter
+config arch_stm32f446re_nucleo_driver_i2c
+bool "I²C on PB[89]"
+help
+ SDA: PB9 (CN5 D14)
+ SCL: PB8 (CN5 D15)
+select meta_driver_hardware_i2c
+select meta_driver_i2c
+
+config arch_stm32f446re_nucleo_driver_i2c_fast_mode
+bool "Fast Mode (400 kHz)"
+depends on arch_stm32f446re_nucleo_driver_i2c
+
#config arch_stm32f446re_nucleo_driver_timer
#bool "Timer with Interrupts"
#select meta_driver_timer
diff --git a/src/arch/stm32f446re-nucleo/Makefile.inc b/src/arch/stm32f446re-nucleo/Makefile.inc
index 8ff7063..3a7670c 100644
--- a/src/arch/stm32f446re-nucleo/Makefile.inc
+++ b/src/arch/stm32f446re-nucleo/Makefile.inc
@@ -55,6 +55,10 @@ ifdef CONFIG_arch_stm32f446re_nucleo_driver_counter
CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/counter.cc
endif
+ifdef CONFIG_arch_stm32f446re_nucleo_driver_i2c
+ CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/i2c.cc
+endif
+
#ifdef CONFIG_arch_stm32f446re_nucleo_driver_timer
# CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/timer.cc
#endif
diff --git a/src/arch/stm32f446re-nucleo/driver/i2c.cc b/src/arch/stm32f446re-nucleo/driver/i2c.cc
new file mode 100644
index 0000000..01b2623
--- /dev/null
+++ b/src/arch/stm32f446re-nucleo/driver/i2c.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2024 Birte Kristina Friesel
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include "driver/i2c.h"
+#include "arch.h"
+#include <libopencm3/stm32/rcc.h>
+#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/stm32/i2c.h>
+
+signed char I2C::setup()
+{
+ rcc_periph_clock_enable(RCC_I2C1);
+ gpio_set_af(GPIOB, GPIO_AF4, GPIO8 | GPIO9);
+ gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO8|GPIO9);
+ gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9);
+ i2c_peripheral_disable(I2C1);
+#ifdef CONFIG_arch_stm32f446re_nucleo_driver_i2c_fast_mode
+ i2c_set_speed(I2C1, i2c_speed_fm_400k, rcc_apb1_frequency / 1000000);
+#else
+ i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency / 1000000);
+#endif
+ i2c_set_standard_mode(I2C1);
+ i2c_peripheral_enable(I2C1);
+
+ return 0;
+}
+
+signed char I2C::xmit(unsigned char address,
+ unsigned char tx_len, unsigned char *tx_buf,
+ unsigned char rx_len, unsigned char *rx_buf)
+{
+ i2c_transfer7(I2C1, address, tx_buf, tx_len, rx_buf, rx_len);
+ return 0;
+}
+
+I2C i2c;