From 3fffef85de0b780eb26beef5625242355053e872 Mon Sep 17 00:00:00 2001 From: Birte Kristina Friesel Date: Sun, 11 Feb 2024 21:21:28 +0100 Subject: stm32f446re: Add I²C driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- include/arch/stm32f446re-nucleo/driver/i2c.h | 23 +++++++++++++++++ src/arch/stm32f446re-nucleo/Kconfig | 14 +++++++++- src/arch/stm32f446re-nucleo/Makefile.inc | 4 +++ src/arch/stm32f446re-nucleo/driver/i2c.cc | 38 ++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 include/arch/stm32f446re-nucleo/driver/i2c.h create mode 100644 src/arch/stm32f446re-nucleo/driver/i2c.cc 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 ©); + + 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 +#include +#include + +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; -- cgit v1.2.3