1 /*
2 * Copyright (c) 2017 The Fuchsia Authors
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <arch/arm/cm.h>
9 #include <dev/i2c.h>
10 #include <lk/err.h>
11 #include <kernel/event.h>
12 #include <kernel/mutex.h>
13 #include <platform/rcc.h>
14 #include <stm32f0xx.h>
15
16 typedef I2C_TypeDef stm32_i2c_regs_t;
17
18 // Some supplemental defines.
19 #define I2C_CR2_NBYTES_SHIFT 16
20
21
22 typedef enum {
23 STM32_I2C_STATE_IDLE = 0,
24 STM32_I2C_STATE_REG,
25 STM32_I2C_STATE_TX,
26 STM32_I2C_STATE_RX,
27
28 // Error states have bit 0x100 set.
29 STM32_I2C_STATE_ERROR = 0x100,
30 STM32_I2C_STATE_ERROR_TIMEOUT = 0x101,
31 STM32_I2C_STATE_ERROR_ARBITRATION_LOST = 0x102,
32 STM32_I2C_STATE_ERROR_BUS_ERROR = 0x103,
33 STM32_I2C_STATE_ERROR_NACK = 0x104,
34 } stm32_i2c_state_t;
35
36 typedef enum {
37 STM32_I2C_DIR_R = I2C_CR2_RD_WRN,
38 STM32_I2C_DIR_W = 0,
39 } stm32_i2c_dir_t;
40
41 typedef struct {
42 uint8_t *data;
43 uint16_t len;
44 uint16_t pos;
45 } stm32_i2c_buf_t;
46
47 typedef struct {
48 stm32_rcc_clk_t clock;
49 stm32_i2c_regs_t *regs;
50
51 stm32_i2c_state_t state;
52
53 uint8_t reg;
54 stm32_i2c_buf_t tx_buf;
55 stm32_i2c_buf_t rx_buf;
56
57 mutex_t lock; // Used to ensure that only one transaction is active.
58 event_t txn_complete;
59 } stm32_i2c_dev_t;
60
61 #ifdef ENABLE_I2C1
62 static stm32_i2c_dev_t i2c1 = {
63 .clock = STM32_RCC_CLK_I2C1,
64 .regs = I2C1,
65 };
66 #endif
67
68 #ifdef ENABLE_I2C2
69 static stm32_i2c_dev_t i2c2 = {
70 .clock = STM32_RCC_CLK_I2C2,
71 .regs = I2C2,
72 };
73 #endif
74
stm32_i2c_get_dev(int bus)75 stm32_i2c_dev_t *stm32_i2c_get_dev(int bus) {
76
77 switch (bus) {
78 #ifdef ENABLE_I2C1
79 case 1:
80 return &i2c1;
81 #endif
82 #ifdef ENABLE_I2C2
83 case 2:
84 return &i2c2;
85 #endif
86 default:
87 return NULL;
88 }
89 }
90
stm32_i2c_early_init(stm32_i2c_dev_t * i2c)91 static void stm32_i2c_early_init(stm32_i2c_dev_t *i2c) {
92 stm32_rcc_set_enable(i2c->clock, true);
93
94 // Clear PE.
95 i2c->regs->CR1 &= ~I2C_CR1_PE;
96
97 // Leave the default analog filter enabled.
98
99 // Magic timing value for I2C. Calculated by STM32CubeMX.
100 //
101 // 8Mhz clock:
102 // Standard Mode (100 KHz): 0x2000090e
103 // Fast Mode (400 KHz): 0x0000020b
104 // Fast Mode Plus: 0x00000001
105
106 // 48Mhz clock:
107 // Standard Mode (100 KHz): 0x20303e5d
108 // Fast Mode (400 KHz): 0x2010091a
109 // Fast Mode Plus: 0x20000209
110 #ifdef STM32_I2C_TIMINGR
111 i2c->regs->TIMINGR = STM32_I2C_TIMINGR;
112 #else
113 # ifdef USE_USB_CLKSOURCE_CRSHSI48
114 i2c->regs->TIMINGR = 0x2010091a;
115 # else
116 i2c->regs->TIMINGR = 0x0000020b;
117 # endif
118 #endif
119
120 // Configure NOSTRETCH in CR1.
121 // Must be kept cleared in master mode.
122
123 // Set PE
124 i2c->regs->CR1 |= I2C_CR1_PE | I2C_CR1_TXIE | I2C_CR1_RXIE | I2C_CR1_NACKIE | I2C_CR1_ERRIE
125 | I2C_CR1_TCIE;
126
127 i2c->state = STM32_I2C_STATE_IDLE;
128 mutex_init(&i2c->lock);
129 event_init(&i2c->txn_complete, false, 0);
130 }
131
i2c_init(void)132 void i2c_init(void) {
133
134 }
135
i2c_init_early(void)136 void i2c_init_early(void) {
137 #ifdef ENABLE_I2C1
138 stm32_i2c_early_init(&i2c1);
139 NVIC_EnableIRQ(I2C1_IRQn);
140 #endif
141 #ifdef ENABLE_I2C2
142 stm32_i2c_early_init(&i2c2);
143 NVIC_EnableIRQ(I2C2_IRQn);
144 #endif
145 }
146
stm32_i2c_buf_is_done(stm32_i2c_buf_t * buf)147 static bool stm32_i2c_buf_is_done(stm32_i2c_buf_t *buf) {
148 return buf->pos >= buf->len;
149 }
150
stm32_i2c_buf_pop(stm32_i2c_buf_t * buf)151 static uint8_t stm32_i2c_buf_pop(stm32_i2c_buf_t *buf) {
152 return buf->data[buf->pos++];
153 }
154
stm32_i2c_buf_push(stm32_i2c_buf_t * buf,uint8_t data)155 static void stm32_i2c_buf_push(stm32_i2c_buf_t *buf, uint8_t data) {
156 buf->data[buf->pos++] = data;
157 }
158
stm32_i2c_check_error(stm32_i2c_dev_t * i2c,uint32_t isr,uint32_t flag,stm32_i2c_state_t error_state)159 static bool stm32_i2c_check_error(stm32_i2c_dev_t *i2c,
160 uint32_t isr,
161 uint32_t flag,
162 stm32_i2c_state_t error_state) {
163 if (isr & flag) {
164 i2c->state = error_state;
165 return true;
166 } else {
167 return false;
168 }
169 }
170
stm32_i2c_is_error_state(stm32_i2c_state_t state)171 static bool stm32_i2c_is_error_state(stm32_i2c_state_t state) {
172 return state & STM32_I2C_STATE_ERROR;
173 }
174
stm32_i2c_is_terminal_state(stm32_i2c_state_t state)175 static bool stm32_i2c_is_terminal_state(stm32_i2c_state_t state) {
176 return state == STM32_I2C_STATE_IDLE || stm32_i2c_is_error_state(state);
177 }
178
stm32_i2c_do_repeated_start(stm32_i2c_dev_t * i2c)179 static void stm32_i2c_do_repeated_start(stm32_i2c_dev_t *i2c) {
180 uint32_t cr2 = i2c->regs->CR2;
181 cr2 &= ~(I2C_CR2_NBYTES | I2C_CR2_START);
182 cr2 |= i2c->rx_buf.len << I2C_CR2_NBYTES_SHIFT | I2C_CR2_RD_WRN;
183 i2c->regs->CR2 = cr2;
184 i2c->regs->CR2 = cr2 | I2C_CR2_START;
185 }
186
stm32_i2c_do_stop(stm32_i2c_dev_t * i2c)187 static void stm32_i2c_do_stop(stm32_i2c_dev_t *i2c) {
188 i2c->regs->CR2 |= I2C_CR2_STOP;
189 }
190
stm32_i2c_irq(stm32_i2c_dev_t * i2c)191 static void stm32_i2c_irq(stm32_i2c_dev_t *i2c) {
192 arm_cm_irq_entry();
193 uint32_t isr = i2c->regs->ISR;
194
195 bool error = false;
196 error |= stm32_i2c_check_error(i2c, isr, I2C_ISR_NACKF, STM32_I2C_STATE_ERROR_NACK);
197 error |= stm32_i2c_check_error(i2c, isr, I2C_ISR_BERR, STM32_I2C_STATE_ERROR_BUS_ERROR);
198 error |= stm32_i2c_check_error(i2c, isr, I2C_ISR_ARLO, STM32_I2C_STATE_ERROR_ARBITRATION_LOST);
199 error |= stm32_i2c_check_error(i2c, isr, I2C_ISR_TIMEOUT, STM32_I2C_STATE_ERROR_TIMEOUT);
200 if (error) {
201 goto out;
202 }
203
204 switch (i2c->state) {
205 case STM32_I2C_STATE_REG:
206 if (isr & I2C_ISR_TXIS) {
207 i2c->regs->TXDR = i2c->reg;
208 i2c->state = STM32_I2C_STATE_TX;
209 }
210 break;
211
212 case STM32_I2C_STATE_TX:
213 if (isr & I2C_ISR_TXIS) {
214 if (!stm32_i2c_buf_is_done(&i2c->tx_buf)) {
215 i2c->regs->TXDR = stm32_i2c_buf_pop(&i2c->tx_buf);
216 }
217 }
218 if (isr & I2C_ISR_TC) {
219 if (!stm32_i2c_buf_is_done(&i2c->rx_buf)) {
220 i2c->state = STM32_I2C_STATE_RX;
221 stm32_i2c_do_repeated_start(i2c);
222 } else {
223 i2c->state = STM32_I2C_STATE_IDLE;
224 stm32_i2c_do_stop(i2c);
225 }
226 }
227 break;
228
229 case STM32_I2C_STATE_RX:
230 if (isr & I2C_ISR_RXNE) {
231 stm32_i2c_buf_push(&i2c->rx_buf, i2c->regs->RXDR);
232 }
233 if (isr & I2C_ISR_TC) {
234 if (stm32_i2c_buf_is_done(&i2c->rx_buf)) {
235 i2c->state = STM32_I2C_STATE_IDLE;
236 stm32_i2c_do_stop(i2c);
237 }
238 }
239 break;
240
241 default:
242 break;
243 }
244
245 out:
246 i2c->regs->ICR = isr;
247 if (stm32_i2c_is_terminal_state(i2c->state)) {
248 event_signal(&i2c->txn_complete, false);
249 arm_cm_irq_exit(true);
250 } else {
251 arm_cm_irq_exit(false);
252 }
253 }
254
255 #ifdef ENABLE_I2C1
stm32_I2C1_IRQ(void)256 void stm32_I2C1_IRQ(void) {
257 stm32_i2c_irq(&i2c1);
258 }
259 #endif
260
261 #ifdef ENABLE_I2C2
stm32_I2C2_IRQ(void)262 void stm32_I2C2_IRQ(void) {
263 stm32_i2c_irq(&i2c2);
264 }
265 #endif
266
stm32_i2c_setup_buf(stm32_i2c_buf_t * buf,uint8_t * data,size_t count)267 static void stm32_i2c_setup_buf(stm32_i2c_buf_t *buf, uint8_t *data, size_t count) {
268 buf->data = data;
269 buf->len = count;
270 buf->pos = 0;
271 }
272
273 // 10 bit addressing not supported.
274 // Transfers > 255 bytes not supported.
stm32_i2c_txn(stm32_i2c_dev_t * i2c,uint8_t address,uint8_t * reg_addr,uint8_t * tx_data,size_t tx_count,uint8_t * rx_data,size_t rx_count)275 static status_t stm32_i2c_txn(stm32_i2c_dev_t *i2c, uint8_t address,
276 uint8_t *reg_addr,
277 uint8_t *tx_data, size_t tx_count,
278 uint8_t *rx_data, size_t rx_count) {
279 mutex_acquire(&i2c->lock);
280 stm32_i2c_setup_buf(&i2c->tx_buf, tx_data, tx_count);
281 stm32_i2c_setup_buf(&i2c->rx_buf, rx_data, rx_count);
282
283 if (reg_addr != NULL) {
284 tx_count++;
285 i2c->reg = *reg_addr;
286 }
287
288 stm32_i2c_dir_t dir;
289 size_t count;
290 if (tx_count > 0) {
291 count = tx_count;
292 dir = STM32_I2C_DIR_W;
293 i2c->state = reg_addr ? STM32_I2C_STATE_REG : STM32_I2C_STATE_TX;
294 } else {
295 count = rx_count;
296 dir = STM32_I2C_DIR_R;
297 i2c->state = STM32_I2C_STATE_RX;
298 }
299
300
301 event_unsignal(&i2c->txn_complete);
302 i2c->regs->CR2 = (address & 0x7f) << 1 | dir | (count & 0xff) << I2C_CR2_NBYTES_SHIFT
303 | I2C_CR2_START;
304 event_wait(&i2c->txn_complete);
305
306 stm32_i2c_state_t state = i2c->state;
307
308 mutex_release(&i2c->lock);
309
310 switch (state) {
311 case STM32_I2C_STATE_IDLE:
312 return NO_ERROR;
313
314 case STM32_I2C_STATE_ERROR_TIMEOUT:
315 return ERR_TIMED_OUT;
316
317 case STM32_I2C_STATE_ERROR_ARBITRATION_LOST:
318 return ERR_BUSY;
319
320 case STM32_I2C_STATE_ERROR_BUS_ERROR:
321 return ERR_IO;
322
323 case STM32_I2C_STATE_ERROR_NACK:
324 return ERR_I2C_NACK;
325
326 default:
327 return ERR_BAD_STATE;
328 }
329 }
330
331
i2c_transmit(int bus,uint8_t address,const void * buf,size_t count)332 status_t i2c_transmit(int bus, uint8_t address, const void *buf, size_t count) {
333 stm32_i2c_dev_t *i2c = stm32_i2c_get_dev(bus);
334 if (i2c == NULL) {
335 return ERR_BAD_HANDLE;
336 }
337
338 // We discard const here in service of keeping the rx and tx buffer handling code common.
339 return stm32_i2c_txn(i2c, address, NULL, (uint8_t *)buf, count, NULL, 0);
340 }
341
i2c_receive(int bus,uint8_t address,void * buf,size_t count)342 status_t i2c_receive(int bus, uint8_t address, void *buf, size_t count) {
343 stm32_i2c_dev_t *i2c = stm32_i2c_get_dev(bus);
344 if (i2c == NULL) {
345 return ERR_BAD_HANDLE;
346 }
347
348 return stm32_i2c_txn(i2c, address, NULL, NULL, 0, buf, count);
349 }
350
i2c_write_reg_bytes(int bus,uint8_t address,uint8_t reg,const uint8_t * buf,size_t count)351 status_t i2c_write_reg_bytes(int bus, uint8_t address, uint8_t reg, const uint8_t *buf, size_t count) {
352 stm32_i2c_dev_t *i2c = stm32_i2c_get_dev(bus);
353 if (i2c == NULL) {
354 return ERR_BAD_HANDLE;
355 }
356
357 // We discard const here in service of keeping the rx and tx buffer handling code common.
358 return stm32_i2c_txn(i2c, address, ®, (uint8_t *)buf, count, NULL, 0);
359 }
360
i2c_read_reg_bytes(int bus,uint8_t address,uint8_t reg,uint8_t * buf,size_t count)361 status_t i2c_read_reg_bytes(int bus, uint8_t address, uint8_t reg, uint8_t *buf, size_t count) {
362 stm32_i2c_dev_t *i2c = stm32_i2c_get_dev(bus);
363
364 return stm32_i2c_txn(i2c, address, ®, NULL, 0, buf, count);
365 }
366