62f9dafab037cb906bebbcb729edea743f1e1a70
[bertos.git] / bertos / cpu / cortex-m3 / drv / i2c_stm32.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief STM32F103xx I2C driver.
34  *
35  * \author Daniele Basile <asterix@develer.com>
36  */
37
38 #include "cfg/cfg_i2c.h"
39
40 #define LOG_LEVEL  I2C_LOG_LEVEL
41 #define LOG_FORMAT I2C_LOG_FORMAT
42 #include <cfg/log.h>
43
44 #include <cfg/debug.h>
45 #include <cfg/macros.h> // BV()
46 #include <cfg/module.h>
47
48 #include <drv/gpio_stm32.h>
49 #include <drv/irq_cm3.h>
50 #include <drv/clock_stm32.h>
51 #include <drv/i2c.h>
52 #include <drv/timer.h>
53
54 #include <io/stm32.h>
55
56 struct stm32_i2c *i2c = (struct stm32_i2c *)I2C1_BASE;
57
58
59 #define WAIT_BTF(base)        while( !(base->SR1 & BV(SR1_BTF)) )
60 #define WAIT_RXE(base)        while( !(base->SR1 & BV(SR1_RXE)) )
61
62 INLINE uint32_t get_status(struct stm32_i2c *base)
63 {
64         return ((base->SR1 | (base->SR2 << 16)) & 0x00FFFFFF);
65 }
66
67
68 INLINE bool check_i2cStatus(uint32_t event)
69 {
70         while (true)
71         {
72                 uint32_t stat = get_status(i2c);
73
74                 if (stat == event)
75                         break;
76
77                 if (stat & SR1_ERR_MASK)
78                 {
79                         LOG_ERR("[%08lx]\n", stat & SR1_ERR_MASK);
80                         i2c->SR1 &= ~SR1_ERR_MASK;
81
82                         i2c->CR1 |= CR1_START_SET;
83                         return false;
84                 }
85
86         }
87
88         return true;
89 }
90
91 /**
92  * Send START condition on the bus.
93  *
94  * \return true on success, false otherwise.
95  */
96 static bool i2c_builtin_start(void)
97 {
98
99         i2c->CR1 |= (CR1_ACK_SET | BV(CR1_POS) | CR1_PE_SET);
100
101         i2c->CR1 |= CR1_START_SET;
102
103         if(check_i2cStatus(I2C_EVENT_MASTER_MODE_SELECT))
104                 return true;
105
106         return false;
107 }
108
109
110 /**
111  * Send START condition and select slave for write.
112  * \c id is the device id comprehensive of address left shifted by 1.
113  * The LSB of \c id is ignored and reset to 0 for write operation.
114  *
115  * \return true on success, false otherwise.
116  */
117 bool i2c_builtin_start_w(uint8_t id)
118 {
119
120         /*
121          * Loop on the select write sequence: when the eeprom is busy
122          * writing previously sent data it will reply to the SLA_W
123          * control byte with a NACK.  In this case, we must
124          * keep trying until the eeprom responds with an ACK.
125          */
126         ticks_t start = timer_clock();
127         while (i2c_builtin_start())
128         {
129                 i2c->DR = id & OAR1_ADD0_RESET;
130
131                 if(check_i2cStatus(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
132                         return true;
133
134                 if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
135                 {
136                         LOG_ERR("Timeout on I2C_START\n");
137                         break;
138                 }
139         }
140
141         return false;
142 }
143
144
145 /**
146  * Send START condition and select slave for read.
147  * \c id is the device id comprehensive of address left shifted by 1.
148  * The LSB of \c id is ignored and set to 1 for read operation.
149  *
150  * \return true on success, false otherwise.
151  */
152 bool i2c_builtin_start_r(uint8_t id)
153 {
154         i2c_builtin_start();
155
156         i2c->DR = (id | OAR1_ADD0_SET);
157
158         if(check_i2cStatus(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
159                 return true;
160
161         return false;
162 }
163
164
165 /**
166  * Send STOP condition.
167  */
168 void i2c_builtin_stop(void)
169 {
170         i2c->CR1 |= CR1_STOP_SET;
171         i2c->CR1 &= CR1_PE_RESET;
172 }
173
174
175
176 bool i2c_builtin_put(const uint8_t data)
177 {
178         i2c->DR = data;
179         WAIT_BTF(i2c);
180
181         if(check_i2cStatus(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
182                 return true;
183
184         return false;
185 }
186
187 int i2c_builtin_get(bool ack)
188 {
189
190         return 0;
191 }
192
193 /**
194  * In order to read bytes from the i2c we should make some tricks.
195  * This because the silicon manage automatically the NACK on last byte, so to read
196  * one, two or three byte we should manage separately these cases.
197  */
198 bool i2c_recv(void *_buf, size_t count)
199 {
200         uint8_t *buf = (uint8_t *)_buf;
201
202         while (count)
203         {
204                 if (count == 1)
205                 {
206                         i2c->CR1 &= ~BV(CR1_POS);
207
208                         if(!check_i2cStatus(I2C_EVENT_MASTER_BYTE_RECEIVED))
209                                 return false;
210
211                         i2c->CR1 &= CR1_ACK_RESET;
212
213                         *buf++ = i2c->DR;
214                         count = 0;
215                 }
216                 else if (count == 2)
217                 {
218                         i2c->CR1 &= CR1_ACK_RESET;
219
220                         WAIT_BTF(i2c);
221
222                         i2c->CR1 |= CR1_STOP_SET;
223
224                         *buf++ = i2c->DR;
225                         *buf++ = i2c->DR;
226
227                         count = 0;
228
229                         i2c->CR1 &= ~BV(CR1_POS);
230
231                 }
232                 else if (count == 3)
233                 {
234                         i2c->CR1 &= ~BV(CR1_POS);
235
236                         WAIT_BTF(i2c);
237
238                         i2c->CR1 &= CR1_ACK_RESET;
239
240                         *buf++ = i2c->DR;
241
242                         i2c->CR1 |= CR1_STOP_SET;
243
244                         *buf++ = i2c->DR;
245
246                         WAIT_RXE(i2c);
247
248                         *buf++ = i2c->DR;
249
250                         count = 0;
251                 }
252                 else
253                 {
254                         i2c->CR1 &= ~BV(CR1_POS);
255
256                         WAIT_BTF(i2c);
257
258                         *buf++ = i2c->DR;
259
260                         count--;
261                 }
262         }
263
264         return true;
265 }
266
267 MOD_DEFINE(i2c);
268
269 /**
270  * Initialize I2C module.
271  */
272 void i2c_builtin_init(void)
273 {
274         MOD_INIT(i2c);
275
276         RCC->APB2ENR |= RCC_APB2_GPIOB;
277         RCC->APB1ENR |= RCC_APB1_I2C1;
278
279         /* Set gpio to use I2C driver */
280         stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, GPIO_I2C1_SCL_PIN,
281                                 GPIO_MODE_AF_OD, GPIO_SPEED_50MHZ);
282
283         stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, GPIO_I2C1_SDA_PIN,
284                                 GPIO_MODE_AF_OD, GPIO_SPEED_50MHZ);
285
286
287         /* Clear all needed registers */
288         i2c->CR1 = 0;
289         i2c->CR2 = 0;
290         i2c->CCR = 0;
291         i2c->TRISE = 0;
292         i2c->OAR1 = 0;
293
294         /* Set PCLK1 frequency accornding to the master clock settings. See stm32_clock.c */
295         i2c->CR2 |= CR2_FREQ_36MHZ;
296
297         /* Configure spi in standard mode */
298         #if CONFIG_I2C_FREQ <= 100000
299                 i2c->CCR |= (uint16_t)((CR2_FREQ_36MHZ * 1000000) / (CONFIG_I2C_FREQ << 1));
300                 i2c->TRISE |= (CR2_FREQ_36MHZ + 1);
301         #else
302                 #error fast mode not supported
303         #endif
304
305 }