From 8db55736f2fbd856a63683f17cdd28728efab9ea Mon Sep 17 00:00:00 2001 From: Jiri Bilek Date: Mon, 24 Dec 2018 15:13:55 +0100 Subject: [PATCH] Simple I2C example for STM32F0 family --- examples/stm32/f0/other/i2c/Makefile | 24 ++++ examples/stm32/f0/other/i2c/README.md | 14 ++ examples/stm32/f0/other/i2c/i2c.c | 179 ++++++++++++++++++++++++++ examples/stm32/f0/other/stm32f030.ld | 32 +++++ 4 files changed, 249 insertions(+) create mode 100644 examples/stm32/f0/other/i2c/Makefile create mode 100644 examples/stm32/f0/other/i2c/README.md create mode 100644 examples/stm32/f0/other/i2c/i2c.c create mode 100644 examples/stm32/f0/other/stm32f030.ld diff --git a/examples/stm32/f0/other/i2c/Makefile b/examples/stm32/f0/other/i2c/Makefile new file mode 100644 index 00000000..33ee1445 --- /dev/null +++ b/examples/stm32/f0/other/i2c/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BINARY = i2c + +LDSCRIPT = ../stm32f030.ld + +include ../../Makefile.include diff --git a/examples/stm32/f0/other/i2c/README.md b/examples/stm32/f0/other/i2c/README.md new file mode 100644 index 00000000..2ca72c89 --- /dev/null +++ b/examples/stm32/f0/other/i2c/README.md @@ -0,0 +1,14 @@ +# README + +It's intended for naked STM32F030F4 MCU and I2C flash memory Atmel 24C02. The I2C bus is connected to flash memory Atmel 24C02 (but many other memories will do, consult datasheet) - [http://ww1.microchip.com/downloads/en/devicedoc/doc0180.pdf] +The application programs bytes 0x01 and 0x02 with values 0x42 and 0x77 respectively, reads the values back and prints them to the serial port. + +## Board connections + +| Port | Function | Description | +| ------ | ---------- | ---------------------------- | +| `PA2` | `(USART1)` | Serial output (115200,8,N,1) | +| `PA9` | `(SCL)` | I2C connection | +| `PA10` | `(SDA)` | I2C connection | + +The I2C bus requires pullup resistors (e.g. 4k7), this application uses dirty workaround switching on internal pullups. \ No newline at end of file diff --git a/examples/stm32/f0/other/i2c/i2c.c b/examples/stm32/f0/other/i2c/i2c.c new file mode 100644 index 00000000..424268f2 --- /dev/null +++ b/examples/stm32/f0/other/i2c/i2c.c @@ -0,0 +1,179 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Stephen Caudle + * Modified 2018 by Jiri Bilek + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define USART_TX GPIO2 +#define I2C_MEMORY_ADDR 0x50 + +static void systick_setup(int xms); +static void clock_setup(void); +void delay(uint32_t time); +static void usart_setup(void); +static void i2c_setup(void); +static void print(const char *s); + +volatile uint32_t millis = 0L; // millis since start of the program + +/* + * Called when systick fires + */ +void sys_tick_handler(void) +{ + ++millis; +} + +/* + * Set up timer to fire every x milliseconds + */ +static void systick_setup(int xms) +{ + systick_set_clocksource(STK_CSR_CLKSOURCE_EXT); + STK_CVR = 0; + + systick_set_reload((rcc_ahb_frequency / 8 / 1000 * xms) - 1); + systick_counter_enable(); + systick_interrupt_enable(); +} + +/* + * Set STM32 to clock by 48 MHz from HSI oscillator + */ +static void clock_setup(void) +{ + rcc_clock_setup_in_hsi_out_48mhz(); +} + +/* + * Delay in milliseconds + */ +void delay(uint32_t time) +{ + uint32_t old_millis = millis; + + while (millis - old_millis < time) + ; +} + +/* + * Set up USART1: TX on USART_TX(PA2 - alternate pin), RX not used + * 115200 baud, 8N1, no flow control + */ +static void usart_setup(void) +{ + rcc_periph_clock_enable(RCC_USART1); + rcc_periph_clock_enable(RCC_GPIOA); + + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, USART_TX); + gpio_set_af(GPIOA, GPIO_AF1, USART_TX); + + usart_set_baudrate(USART1, 115200); + usart_set_databits(USART1, 8); + usart_set_stopbits(USART1, USART_CR2_STOPBITS_1); + usart_set_mode(USART1, USART_MODE_TX); + usart_set_parity(USART1, USART_PARITY_NONE); + usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); + + usart_enable(USART1); +} + +/* + * Set up I2C1 on PA9, PA10. + * Both pins are internally pulled up, not necessary when external pullup is used. + */ +static void i2c_setup(void) +{ + rcc_periph_clock_enable(RCC_I2C1); + rcc_periph_clock_enable(RCC_GPIOA); + rcc_set_i2c_clock_hsi(I2C1); + + i2c_reset(I2C1); + + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO9 | GPIO10); + gpio_set_af(GPIOA, GPIO_AF4, GPIO9 | GPIO10); + i2c_peripheral_disable(I2C1); + //configure ANFOFF DNF[3:0] in CR1 + i2c_enable_analog_filter(I2C1); + i2c_set_digital_filter(I2C1, 0); + /* HSI is at 8Mhz */ + i2c_set_speed(I2C1, i2c_speed_sm_100k, 8); + //configure No-Stretch CR1 (only relevant in slave mode) + i2c_enable_stretching(I2C1); + //addressing mode + i2c_set_7bit_addr_mode(I2C1); + + i2c_peripheral_enable(I2C1); +} + +static void print(const char *s) +{ + while (*s) + usart_send_blocking(USART1, *s++); +} + +static void printhex(uint8_t h) +{ + h &= 0xf; + if (h > 9) + h += 'A' - '9' - 1; + + usart_send_blocking(USART1, h + '0'); +} + +static void print2hex(uint8_t h) +{ + printhex(h >> 4); + printhex(h & 0xf); +} + +int main(void) +{ + clock_setup(); + usart_setup(); + i2c_setup(); + systick_setup(1); // 1 ms tick + + // write 0x42, 0x75 into address 0x01 + uint8_t cmdWrite[] = { 0x01, 0x42, 0x75 }; + i2c_transfer7(I2C1, I2C_MEMORY_ADDR, cmdWrite, sizeof(cmdWrite), NULL, 0); + + delay(5); // needed for finishing the write (see Datasheet Atmel 24c02) + + // read 2 bytes from address 0x01 + uint8_t cmdRead[] = { 0x01 }; + uint8_t dataOut[2]; + i2c_transfer7(I2C1, I2C_MEMORY_ADDR, cmdRead, sizeof(cmdRead), dataOut, sizeof(dataOut)); + + print("Addr 0x01, value = "); + print2hex(dataOut[0]); + print(" "); + print2hex(dataOut[1]); + print("\n"); + + /* No Main loop */ + return 0; +} diff --git a/examples/stm32/f0/other/stm32f030.ld b/examples/stm32/f0/other/stm32f030.ld new file mode 100644 index 00000000..aa378d8e --- /dev/null +++ b/examples/stm32/f0/other/stm32f030.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F030F4 (16K flash, 4K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE cortex-m-generic.ld +