Browse Source

Add i2c eeprom example.

flabbergast 1 year ago
parent
commit
124fe29898
9 changed files with 368 additions and 1 deletions
  1. 1
    0
      .gitignore
  2. 4
    0
      README.md
  3. 38
    0
      i2c_eep/Makefile.f0
  4. 38
    0
      i2c_eep/Makefile.l0
  5. 29
    0
      i2c_eep/Makefile.l0btld
  6. 201
    0
      i2c_eep/i2c_eep.c
  7. 39
    0
      i2c_eep/serial_helper.c
  8. 17
    0
      i2c_eep/serial_helper.h
  9. 1
    1
      libopencm3.rules.mk

+ 1
- 0
.gitignore View File

@@ -4,3 +4,4 @@
4 4
 *.hex
5 5
 *.bin
6 6
 *.map
7
+.gdb_config_bmp

+ 4
- 0
README.md View File

@@ -22,6 +22,10 @@ The board presents itself as a serial port (CDC). It echoes back what it receive
22 22
 
23 23
 L052 only. This is the DFU bootloader that I use on the bat boards with L052. More info about it on [the bat board] main page.
24 24
 
25
+### i2c_eep
26
+
27
+Writes a few bytes, then reads a few bytes, from a standard I2C EEPROM. The bytes read are printed over USART (on PA9/PA10). Connections and address can be seen in the code (different setups for F0 and L0).
28
+
25 29
 ## General setup notes
26 30
 
27 31
 You are expected to a C compiler (for ARM) and some development tools (e.g. make and git) installed and ready to use. You can get a [toolchain from arm.com]; or use one provided by your system package manager (if you're on a normal system like some linux, bsd or mac). For the development tools, use your package manager.

+ 38
- 0
i2c_eep/Makefile.f0 View File

@@ -0,0 +1,38 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+##
6
+## This library is free software: you can redistribute it and/or modify
7
+## it under the terms of the GNU Lesser General Public License as published by
8
+## the Free Software Foundation, either version 3 of the License, or
9
+## (at your option) any later version.
10
+##
11
+## This library is distributed in the hope that it will be useful,
12
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+## GNU Lesser General Public License for more details.
15
+##
16
+## You should have received a copy of the GNU Lesser General Public License
17
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+##
19
+
20
+BINARY = i2c_eep
21
+
22
+OBJS += serial_helper.o
23
+
24
+OPENCM3_DIR=../libopencm3
25
+LDSCRIPT = $(OPENCM3_DIR)/lib/stm32/f0/stm32f07xzb.ld
26
+
27
+include ../common.f0.mk
28
+
29
+BMP_PORT = /dev/cu.usbmodemE0BABAF1
30
+
31
+.gdb_config_bmp:
32
+	echo > .gdb_config_bmp "file $(BINARY).elf\ntarget extended-remote $(BMP_PORT)\nmonitor version\nmonitor swdp_scan\nattach 1\nload\nbreak main\nc\n"
33
+
34
+debug_bmp: .gdb_config_bmp $(BINARY).elf
35
+	cgdb -d $(GDB) -- \
36
+		   --command=.gdb_config_bmp \
37
+		   $(BINARY).elf
38
+

+ 38
- 0
i2c_eep/Makefile.l0 View File

@@ -0,0 +1,38 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+##
6
+## This library is free software: you can redistribute it and/or modify
7
+## it under the terms of the GNU Lesser General Public License as published by
8
+## the Free Software Foundation, either version 3 of the License, or
9
+## (at your option) any later version.
10
+##
11
+## This library is distributed in the hope that it will be useful,
12
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+## GNU Lesser General Public License for more details.
15
+##
16
+## You should have received a copy of the GNU Lesser General Public License
17
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+##
19
+
20
+BINARY = i2c_eep
21
+
22
+OBJS += serial_helper.o
23
+
24
+OPENCM3_DIR=../libopencm3
25
+LDSCRIPT = $(OPENCM3_DIR)/lib/stm32/l0/stm32l0xx8.ld
26
+
27
+include ../common.l0.mk
28
+
29
+BMP_PORT = /dev/cu.usbmodemE0BABAF1
30
+
31
+.gdb_config_bmp:
32
+	echo > .gdb_config_bmp "file $(BINARY).elf\ntarget extended-remote $(BMP_PORT)\nmonitor version\nmonitor swdp_scan\nattach 1\nload\nbreak main\nc\n"
33
+
34
+debug_bmp: .gdb_config_bmp $(BINARY).elf
35
+	cgdb -d $(GDB) -- \
36
+		   --command=.gdb_config_bmp \
37
+		   $(BINARY).elf
38
+

+ 29
- 0
i2c_eep/Makefile.l0btld View File

@@ -0,0 +1,29 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+##
6
+## This library is free software: you can redistribute it and/or modify
7
+## it under the terms of the GNU Lesser General Public License as published by
8
+## the Free Software Foundation, either version 3 of the License, or
9
+## (at your option) any later version.
10
+##
11
+## This library is distributed in the hope that it will be useful,
12
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+## GNU Lesser General Public License for more details.
15
+##
16
+## You should have received a copy of the GNU Lesser General Public License
17
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+##
19
+
20
+BINARY = i2c_eep
21
+
22
+OBJS += serial_helper.o
23
+
24
+OPENCM3_DIR=../libopencm3
25
+LDSCRIPT = ../l052-bldr.ld
26
+DEFS += -DBOOTLOADER8K
27
+
28
+include ../common.l0.mk
29
+

+ 201
- 0
i2c_eep/i2c_eep.c View File

@@ -0,0 +1,201 @@
1
+#include <libopencm3/stm32/rcc.h>
2
+#include <libopencm3/stm32/flash.h>
3
+#include <libopencm3/stm32/gpio.h>
4
+#include <libopencm3/stm32/i2c.h>
5
+
6
+#include <libopencm3/stm32/usart.h>
7
+#include "serial_helper.h"
8
+
9
+
10
+static void usart_setup(void)
11
+{
12
+	/* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */
13
+	rcc_periph_clock_enable(RCC_GPIOA);
14
+	rcc_periph_clock_enable(RCC_USART1);
15
+
16
+#if defined(STM32F0)
17
+	/* USART1 pins: PA9/TX PA10/RX */
18
+	gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9|GPIO10);
19
+	gpio_set_af(GPIOA, GPIO_AF1, GPIO9|GPIO10);
20
+#elif defined(STM32L0)
21
+	/* USART1 pins: PA9/TX PA10/RX */
22
+	gpio_set_af(GPIOA, GPIO_AF4, GPIO9|GPIO10);
23
+	gpio_set_output_options(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_HIGH, GPIO9|GPIO10);
24
+	gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9|GPIO10);
25
+#endif
26
+
27
+	/* Setup UART parameters. */
28
+	usart_set_baudrate(USART1, 115200);
29
+	usart_set_databits(USART1, 8);
30
+	usart_set_parity(USART1, USART_PARITY_NONE);
31
+	usart_set_stopbits(USART1, USART_STOPBITS_1);
32
+	//usart_set_stopbits(USART1, USART_CR2_STOP_1_0BIT);
33
+	usart_set_mode(USART1, USART_MODE_TX_RX);
34
+	usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
35
+
36
+	/* Finally enable the USART. */
37
+	usart_enable(USART1);
38
+}
39
+
40
+static void gpio_setup(void)
41
+{
42
+	rcc_periph_clock_enable(RCC_GPIOA);
43
+
44
+	/* Set PA15 for LED */
45
+	gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO15);
46
+}
47
+
48
+static void i2c_setup(void)
49
+{
50
+	uint32_t i2c;
51
+#if defined(STM32F0)
52
+	/* Enable clocks for I2C2. */
53
+	rcc_periph_clock_enable(RCC_I2C2);
54
+	rcc_periph_clock_enable(RCC_GPIOB);
55
+
56
+	/* Set alternate functions for the SCL and SDA pins of I2C2. */
57
+	gpio_set_af(GPIOB, GPIO_AF1, GPIO10|GPIO11);
58
+	gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO10|GPIO11);
59
+
60
+	i2c = I2C2;
61
+
62
+#elif defined(STM32L0)
63
+	/* Enable clocks for I2C1. */
64
+	rcc_periph_clock_enable(RCC_I2C1);
65
+	rcc_periph_clock_enable(RCC_GPIOB);
66
+
67
+	/* Set alternate functions for the SCL and SDA pins of I2C2. */
68
+	gpio_set_af(GPIOB, GPIO_AF4, GPIO8|GPIO9);
69
+	gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_HIGH, GPIO8|GPIO9);
70
+	gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8|GPIO9);
71
+
72
+	i2c = I2C1;
73
+#endif /* STM32L0 */
74
+	i2c_reset(i2c);
75
+
76
+	/* Disable the I2C before changing any configuration. */
77
+	i2c_peripheral_disable(i2c);
78
+
79
+	/* setup from libopencm3-examples */
80
+	i2c_enable_analog_filter(i2c);
81
+	i2c_set_digital_filter(i2c, I2C_CR1_DNF_DISABLED);
82
+	i2c_set_speed(i2c, i2c_speed_sm_100k, 8);
83
+	i2c_enable_stretching(i2c);
84
+	i2c_set_7bit_addr_mode(i2c);
85
+
86
+	/* If everything is configured -> enable the peripheral. */
87
+	i2c_peripheral_enable(i2c);
88
+}
89
+
90
+
91
+#if defined(STM32L0)
92
+static void clock_setup_l0(void)
93
+{
94
+	/* After a reset, the system uses MSI@2.1MHz. */
95
+	/* end result: 32MHz PLLVCO from HSI16,
96
+	 *	 no system/periph clock divide.
97
+	 */
98
+
99
+	/* increase the latency to 1 wait state (we'll be speeding up) */
100
+	flash_set_ws(1);
101
+
102
+	/* turn on HSI16 */
103
+	rcc_osc_on(RCC_HSI16);
104
+	rcc_wait_for_osc_ready(RCC_HSI16);
105
+
106
+	/* run AHB, APB1, APB2 at full speed */
107
+	rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
108
+	rcc_set_ppre1(RCC_CFGR_PPRE1_NODIV);
109
+	rcc_set_ppre2(RCC_CFGR_PPRE2_NODIV);
110
+
111
+	/* turn off PLL and wait for it to fully stop */
112
+	rcc_osc_off(RCC_PLL);
113
+	while (RCC_CR & RCC_CR_PLLRDY);
114
+
115
+	/* set PLL source to HSI16 */
116
+	RCC_CFGR &= ~(1<<16); // RCC_CFGR_PLLSRC
117
+
118
+	/* set up PLL */
119
+	rcc_set_pll_multiplier(RCC_CFGR_PLLMUL_MUL4);
120
+	rcc_set_pll_divider(RCC_CFGR_PLLDIV_DIV2);
121
+
122
+	/* turn on and switch to PLL */
123
+	rcc_osc_on(RCC_PLL);
124
+	rcc_wait_for_osc_ready(RCC_PLL);
125
+	rcc_set_sysclk_source(RCC_PLL);
126
+
127
+	rcc_ahb_frequency = 32000000;
128
+	rcc_apb1_frequency = 32000000;
129
+	rcc_apb2_frequency = 32000000;
130
+}
131
+#endif /* STM32L0 */
132
+
133
+int main(void)
134
+{
135
+#if defined(BOOTLOADER8K)
136
+#	define SCB_VTOR MMIO32(0xE000ED08)
137
+	SCB_VTOR = (uint32_t) 0x08002000;
138
+#endif /* BOOTLOADER8K */
139
+
140
+#if defined(STM32F0)
141
+	uint32_t i2c = I2C2;
142
+#elif defined(STM32L0)
143
+	uint32_t i2c = I2C1;
144
+#endif /* STM32L0 */
145
+	uint8_t eeprom_addr = 0x50;
146
+
147
+#if defined(STM32F0)
148
+	rcc_clock_setup_in_hsi_out_48mhz();
149
+#elif defined(STM32L0)
150
+	clock_setup_l0();
151
+#endif
152
+	gpio_setup();
153
+	usart_setup();
154
+	i2c_setup();
155
+
156
+	/* Send a message on USART1. */
157
+	pstr("stm\r\n");
158
+
159
+	uint8_t temp[10];
160
+	uint8_t wb[2];
161
+
162
+	// one byte addresses for smaller epproms
163
+	temp[0] = 0;
164
+	// bytes to write
165
+	temp[1] = 0x11;
166
+	temp[2] = 0x22;
167
+	temp[3] = 0x33;
168
+
169
+	// write
170
+	i2c_transfer7(i2c, eeprom_addr, temp, 4, NULL, 0);
171
+
172
+	uint32_t t;
173
+	// the pause needs to be long enough for the eeprom to finish
174
+	// writing the data above; otherwise the 'read' call below
175
+	// hangs
176
+	t = 500000;
177
+	while(t-- > 0)
178
+		__asm__("nop");
179
+
180
+	// two byte addresses for bigger eeproms (change also transfer7 call!)
181
+	//wb[0] = (uint8_t)( 0 >>8);
182
+	//wb[1] = (uint8_t)( 0 &0xFF);
183
+	// one byte addresses for smaller epproms (change also transfer7 call!)
184
+	wb[0] = 0;
185
+
186
+	// read
187
+	i2c_transfer7(i2c, eeprom_addr, wb, 1, temp, 10);
188
+
189
+	gpio_set(GPIOA, GPIO15); /* LED on */
190
+
191
+	uint8_t i;
192
+	for(i=0; i<10; i++)
193
+		phex(temp[i]);
194
+	pent();
195
+
196
+	while (1); /* Halt. */
197
+
198
+	return 0;
199
+}
200
+
201
+// vim: tabstop=4:shiftwidth=4:noexpandtab

+ 39
- 0
i2c_eep/serial_helper.c View File

@@ -0,0 +1,39 @@
1
+#include "serial_helper.h"
2
+
3
+void phex4(uint8_t c) {
4
+	usart_send_blocking(P_USART, (uint8_t)(c + ((c < 10) ? '0' : 'A' - 10)));
5
+}
6
+
7
+void phex(uint8_t c) {
8
+	phex4((c>>4));
9
+	phex4((c&15));
10
+}
11
+
12
+void phex16(uint16_t c) {
13
+	phex((uint8_t)(c>>8));
14
+	phex((uint8_t)c);
15
+}
16
+
17
+void phex24(uint32_t c) {
18
+	phex16((uint16_t)((c>>8)&0xFFFF));
19
+	phex((uint8_t)c);
20
+}
21
+
22
+void phex32(uint32_t c) {
23
+	phex16((uint16_t)(c>>16));
24
+	phex16((uint16_t)(c&0xFFFF));
25
+}
26
+
27
+void pent(void) {
28
+	usart_send_blocking(P_USART, '\r');
29
+	usart_send_blocking(P_USART, '\n');
30
+}
31
+
32
+void pstr(char *s) {
33
+	uint16_t i = 0;
34
+	while(s[i]) {
35
+		usart_send_blocking(P_USART, (uint8_t)(s[i++]));
36
+	}
37
+}
38
+
39
+// vim: tabstop=4:shiftwidth=4:noexpandtab

+ 17
- 0
i2c_eep/serial_helper.h View File

@@ -0,0 +1,17 @@
1
+#ifndef SERIAL_HELPER_H
2
+#define SERIAL_HELPER_H
3
+
4
+#include <libopencm3/stm32/usart.h>
5
+
6
+#define P_USART USART1
7
+
8
+void phex4(uint8_t c);
9
+void phex(uint8_t c);
10
+void phex16(uint16_t c);
11
+void phex24(uint32_t c);
12
+void phex32(uint32_t c);
13
+void pent(void);
14
+
15
+void pstr(char *s);
16
+
17
+#endif /* SERIAL_HELPER_H */

+ 1
- 1
libopencm3.rules.mk View File

@@ -72,7 +72,7 @@ STFLASH		= $(shell which st-flash)
72 72
 STYLECHECK	:= /checkpatch.pl
73 73
 STYLECHECKFLAGS	:= --no-tree -f --terse --mailback
74 74
 STYLECHECKFILES	:= $(shell find . -name '*.[ch]')
75
-OPT		:= -Os
75
+OPT		?= -Os
76 76
 CSTD		?= -std=c99
77 77
 
78 78
 

Loading…
Cancel
Save