SHOW:
|
|
- or go back to the newest paste.
1 | diff --git a/libmaple/i2c.c b/libmaple/i2c.c | |
2 | - | index 9c93d3f..4902ec3 100644 |
2 | + | index 9c93d3f..b8e622d 100644 |
3 | --- a/libmaple/i2c.c | |
4 | +++ b/libmaple/i2c.c | |
5 | @@ -154,6 +154,7 @@ void i2c_bus_reset(const i2c_dev *dev) { | |
6 | void i2c_init(i2c_dev *dev) { | |
7 | rcc_reset_dev(dev->clk_id); | |
8 | rcc_clk_enable(dev->clk_id); | |
9 | + _i2c_irq_priority_fixup(dev); | |
10 | } | |
11 | ||
12 | /* Hack for deprecated bit of STM32F1 functionality */ | |
13 | @@ -198,12 +199,30 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) { | |
14 | nvic_irq_enable(dev->er_nvic_line); | |
15 | i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR); | |
16 | ||
17 | + /* Configure the slave unit */ | |
18 | + if (flags & I2C_SLAVE_DUAL_ADDRESS) { | |
19 | - | + i2c_slave_dual_address_enable(dev); |
19 | + | + i2c_slave_dual_address_enable(dev); |
20 | - | + } |
20 | + | |
21 | + | |
22 | - | + if (flags & I2C_SLAVE_GENERAL_CALL) { |
22 | + | + if (flags & I2C_SLAVE_GENERAL_CALL) { |
23 | - | + i2c_slave_general_call_enable(dev); |
23 | + | + i2c_slave_general_call_enable(dev); |
24 | - | + } |
24 | + | |
25 | + | |
26 | - | + /* store all of the flags */ |
26 | + | + /* store all of the flags */ |
27 | - | + dev->config_flags = flags; |
27 | + | + dev->config_flags = flags; |
28 | + | |
29 | /* Make it go! */ | |
30 | i2c_peripheral_enable(dev); | |
31 | + i2c_enable_ack(dev); | |
32 | ||
33 | dev->state = I2C_STATE_IDLE; | |
34 | } | |
35 | ||
36 | +void i2c_slave_enable(i2c_dev *dev, uint32 flags) { | |
37 | - | + i2c_disable(dev); |
37 | + | + i2c_disable(dev); |
38 | - | + i2c_master_enable(dev, dev->config_flags | flags); |
38 | + | + i2c_master_enable(dev, dev->config_flags | flags); |
39 | +} | |
40 | + | |
41 | /** | |
42 | * @brief Process an i2c transaction. | |
43 | * | |
44 | - | @@ -303,150 +322,296 @@ void _i2c_irq_handler(i2c_dev *dev) { |
44 | + | @@ -303,6 +322,152 @@ void _i2c_irq_handler(i2c_dev *dev) { |
45 | */ | |
46 | dev->timestamp = systick_uptime(); | |
47 | ||
48 | - | - /* |
48 | + | |
49 | - | - * EV5: Start condition sent |
49 | + | |
50 | + * barry.carter@gmail.com | |
51 | + */ | |
52 | + | |
53 | + /* Check to see if MSL master slave bit is set */ | |
54 | - | - if (sr1 & I2C_SR1_SB) { |
54 | + | |
55 | - | - msg->xferred = 0; |
55 | + | |
56 | - | - i2c_enable_irq(dev, I2C_IRQ_BUFFER); |
56 | + | |
57 | - | - |
57 | + | |
58 | - | - /* |
58 | + | + /* Find out which address was matched */ |
59 | - | - * Master receiver |
59 | + | + /* Check the general call address first */ |
60 | - | - */ |
60 | + | + if (sr2 & I2C_SR2_GENCALL) { |
61 | - | - if (read) { |
61 | + | + dev->i2c_slave_msg->addr = 0; |
62 | - | - i2c_enable_ack(dev); |
62 | + | + } |
63 | + /* We matched the secondary address */ | |
64 | + else if (sr2 & I2C_SR2_DUALF) { | |
65 | + dev->i2c_slave_msg->addr = dev->regs->OAR2 & 0xFE; | |
66 | + } | |
67 | - | + dev->state = I2C_STATE_BUSY; |
67 | + | + /* We matched the primary address */ |
68 | + else if ((sr2 & I2C_SR2_DUALF) != I2C_SR2_DUALF) { | |
69 | + dev->i2c_slave_msg->addr = dev->regs->OAR1 & 0xFE; | |
70 | + } | |
71 | - | + /* Find out which address was matched */ |
71 | + | + /* Shouldn't get here */ |
72 | - | + /* Check the general call address first */ |
72 | + | + else { |
73 | - | + if (sr2 & I2C_SR2_GENCALL) { |
73 | + | + dev->i2c_slave_msg->addr = -1; /* uh oh */ |
74 | - | + dev->i2c_slave_msg->addr = 0; |
74 | + | + } |
75 | - | + } |
75 | + | |
76 | - | + /* We matched the secondary address */ |
76 | + | + /* if we have buffered io */ |
77 | - | + else if (sr2 & I2C_SR2_DUALF) { |
77 | + | |
78 | - | + dev->i2c_slave_msg->addr = dev->regs->OAR2 & 0xFE; |
78 | + | + (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) { |
79 | - | + } |
79 | + | |
80 | - | + /* We matched the primary address */ |
80 | + | + /* if receiving then this would be a repeated start |
81 | - | + else if ((sr2 & I2C_SR2_DUALF) != I2C_SR2_DUALF) { |
81 | + | + * |
82 | - | + dev->i2c_slave_msg->addr = dev->regs->OAR1 & 0xFE; |
82 | + | + *if we have some bytes already |
83 | - | + } |
83 | + | + */ |
84 | - | + /* Shouldn't get here */ |
84 | + | + if ((dev->state == I2C_STATE_SL_RX) && |
85 | - | + else { |
85 | + | + (dev->i2c_slave_msg->xferred > 0) && |
86 | - | + dev->i2c_slave_msg->addr = -1; /* uh oh */ |
86 | + | + (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER)) { |
87 | - | + } |
87 | + | + /* Call the callback with the contents of the data */ |
88 | + if (dev->i2c_slave_recv_callback != NULL) { | |
89 | - | + /* if we have buffered io */ |
89 | + | + (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg); |
90 | - | + if ((dev->config_flags & I2C_SLAVE_USE_RX_BUFFER) || |
90 | + | + } |
91 | - | + (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) { |
91 | + | + } |
92 | + | |
93 | - | + /* if receiving then this would be a repeated start |
93 | + | + /* Reset the message back to defaults. |
94 | - | + * |
94 | + | + * We are starting a new message |
95 | - | + *if we have some bytes already |
95 | + | + */ |
96 | - | + */ |
96 | + | + dev->i2c_slave_msg->flags = 0; |
97 | - | + if (((sr1 & I2C_SR1_TXE) != I2C_SR1_TXE) && |
97 | + | + dev->i2c_slave_msg->length = 0; |
98 | - | + (dev->i2c_slave_msg->xferred > 0) && |
98 | + | + dev->i2c_slave_msg->xferred = 0; |
99 | - | + (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER)) { |
99 | + | + dev->msgs_left = 0; |
100 | - | + /* Call the callback with the contents of the data */ |
100 | + | + dev->timestamp = systick_uptime(); |
101 | - | + if (dev->i2c_slave_recv_callback != NULL) { |
101 | + | |
102 | - | + (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg); |
102 | + | + /* We have been addressed with SLA+R so |
103 | - | + } |
103 | + | + * the master wants us to transmit |
104 | - | + } |
104 | + | + */ |
105 | + if ((sr1 & I2C_SR1_TXE) && | |
106 | - | + /* Reset the message back to defaults. |
106 | + | + (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) { |
107 | - | + * We are starting a new message |
107 | + | + /* Call the transmit callback so it can populate the msg |
108 | - | + */ |
108 | + | + * data with the bytes to go |
109 | - | + dev->i2c_slave_msg->flags = 0; |
109 | + | + */ |
110 | - | + dev->i2c_slave_msg->length = 0; |
110 | + | + if (dev->i2c_slave_transmit_callback != NULL) { |
111 | - | + dev->i2c_slave_msg->xferred = 0; |
111 | + | + (*(dev->i2c_slave_transmit_callback))(dev->i2c_slave_msg); |
112 | - | + dev->msgs_left = 0; |
112 | + | + } |
113 | - | + dev->timestamp = systick_uptime(); |
113 | + | + } |
114 | + dev->state = I2C_STATE_BUSY; | |
115 | - | + /* We have been addressed with SLA+R so |
115 | + | + } |
116 | - | + * the master wants us to transmit |
116 | + | |
117 | - | + */ |
117 | + | |
118 | - | + if ((sr1 & I2C_SR1_TXE) && |
118 | + | |
119 | - | + (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) { |
119 | + | |
120 | - | + /* Call the transmit callback so it can populate the msg |
120 | + | |
121 | - | + * data with the bytes to go |
121 | + | |
122 | - | + */ |
122 | + | + if (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER) { |
123 | - | + if (dev->i2c_slave_transmit_callback != NULL) { |
123 | + | + if (dev->i2c_slave_msg->xferred >= dev->i2c_slave_msg->length) { |
124 | - | + (*(dev->i2c_slave_transmit_callback))(dev->i2c_slave_msg); |
124 | + | + /* End of the transmit buffer? If so we NACK */ |
125 | - | + } |
125 | + | + i2c_disable_ack(dev); |
126 | - | + } |
126 | + | + /* We have to either issue a STOP or write something here. |
127 | - | + } |
127 | + | + * STOP here seems to screw up some masters, |
128 | + * For now padding with 0 | |
129 | + */ | |
130 | + i2c_write(dev, 0); | |
131 | + /*i2c_stop_condition(dev); // This is causing bus lockups way more than it should !? Seems some I2C master devices freak out here*/ | |
132 | + } | |
133 | + else | |
134 | - | + if (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER) { |
134 | + | + { |
135 | - | + if (dev->i2c_slave_msg->xferred >= dev->i2c_slave_msg->length) { |
135 | + | + /* NACk the last byte */ |
136 | - | + /* End of the transmit buffer? If so we NACK */ |
136 | + | + if (dev->i2c_slave_msg->xferred == dev->i2c_slave_msg->length-1) { |
137 | - | + i2c_disable_ack(dev); |
137 | + | + i2c_disable_ack(dev); |
138 | - | + /* We have to either issue a STOP or write something here. |
138 | + | + } |
139 | - | + * STOP here seems to screw up some masters, |
139 | + | + else { |
140 | - | + * For now padding with 0 |
140 | + | + i2c_enable_ack(dev); |
141 | - | + */ |
141 | + | + } |
142 | - | + i2c_write(dev, 0); |
142 | + | + i2c_write(dev, dev->i2c_slave_msg->data[dev->i2c_slave_msg->xferred++]); |
143 | - | + /*i2c_stop_condition(dev); // This is causing bus lockups way more than it should !? Seems some I2C master devices freak out here*/ |
143 | + | + } |
144 | - | + } |
144 | + | + } |
145 | - | + else |
145 | + | + else |
146 | - | + { |
146 | + | + { |
147 | - | + /* NACk the last byte */ |
147 | + | + /* Call the callback to get the data we need. |
148 | - | + if (dev->i2c_slave_msg->xferred == dev->i2c_slave_msg->length-1) { |
148 | + | + * The callback is expected to write using i2c_write(...) |
149 | - | + i2c_disable_ack(dev); |
149 | + | + * If the slave is going to terminate the transfer, this function should |
150 | - | + } |
150 | + | + * also do a NACK on the last byte! |
151 | - | + else { |
151 | + | + */ |
152 | - | + i2c_enable_ack(dev); |
152 | + | + if (dev->i2c_slave_transmit_callback != NULL) (*(dev->i2c_slave_transmit_callback))(dev->i2c_slave_msg); |
153 | - | + } |
153 | + | + } |
154 | - | + i2c_write(dev, dev->i2c_slave_msg->data[dev->i2c_slave_msg->xferred++]); |
154 | + | |
155 | - | + } |
155 | + | + dev->state = I2C_STATE_BUSY; |
156 | - | + } |
156 | + | |
157 | - | + else |
157 | + | |
158 | - | + { |
158 | + | |
159 | - | + /* Call the callback to get the data we need. |
159 | + | |
160 | - | + * The callback is expected to write using i2c_write(...) |
160 | + | |
161 | - | + * If the slave is going to terminate the transfer, this function should |
161 | + | + if (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER) { |
162 | - | + * also do a NACK on the last byte! |
162 | + | + /* Fill the buffer with the contents of the data register */ |
163 | - | + */ |
163 | + | + dev->i2c_slave_msg->data[dev->i2c_slave_msg->xferred++] = dev->regs->DR; |
164 | - | + if (dev->i2c_slave_transmit_callback != NULL) (*(dev->i2c_slave_transmit_callback))(dev->i2c_slave_msg); |
164 | + | + dev->i2c_slave_msg->length++; |
165 | - | + } |
165 | + | + } |
166 | + else { | |
167 | - | + sr1 = sr2 = 0; |
167 | + | + /* Call the callback with the contents of the data */ |
168 | + dev->i2c_slave_msg->data[0] = dev->regs->DR; | |
169 | + if (dev->i2c_slave_recv_callback != NULL) (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg); | |
170 | + } | |
171 | + dev->state = I2C_STATE_SL_RX; | |
172 | - | + if (dev->config_flags & I2C_SLAVE_USE_RX_BUFFER) { |
172 | + | |
173 | - | + /* Fill the buffer with the contents of the data register */ |
173 | + | |
174 | - | + dev->i2c_slave_msg->data[dev->i2c_slave_msg->xferred++] = dev->regs->DR; |
174 | + | |
175 | - | + dev->i2c_slave_msg->length++; |
175 | + | |
176 | - | + } |
176 | + | |
177 | - | + else { |
177 | + | |
178 | - | + /* Call the callback with the contents of the data */ |
178 | + | |
179 | - | + dev->i2c_slave_msg->data[0] = dev->regs->DR; |
179 | + | |
180 | - | + if (dev->i2c_slave_recv_callback != NULL) (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg); |
180 | + | + (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) { |
181 | - | + } |
181 | + | |
182 | + /* The callback with the data will happen on a NACK of the last data byte. | |
183 | + * This is handled in the error IRQ (AF bit) | |
184 | + */ | |
185 | - | - i2c_send_slave_addr(dev, msg->addr, read); |
185 | + | + } |
186 | - | - sr1 = sr2 = 0; |
186 | + | |
187 | - | - } |
187 | + | |
188 | + dev->state = I2C_STATE_IDLE; | |
189 | + } | |
190 | + | |
191 | + return; | |
192 | - | - /* |
192 | + | |
193 | - | - * EV6: Slave address sent |
193 | + | |
194 | - | - */ |
194 | + | /* |
195 | - | - if (sr1 & I2C_SR1_ADDR) { |
195 | + | * EV5: Start condition sent |
196 | - | - /* |
196 | + | |
197 | - | - * Special case event EV6_1 for master receiver. |
197 | + | @@ -447,6 +612,7 @@ void _i2c_irq_handler(i2c_dev *dev) { |
198 | - | - * Generate NACK and restart/stop condition after ADDR |
198 | + | } |
199 | - | - * is cleared. |
199 | + | |
200 | - | - */ |
200 | + | |
201 | - | - if (read) { |
201 | + | |
202 | - | - if (msg->length == 1) { |
202 | + | |
203 | - | - i2c_disable_ack(dev); |
203 | + | |
204 | - | - if (dev->msgs_left > 1) { |
204 | + | |
205 | - | - i2c_start_condition(dev); |
205 | + | @@ -456,10 +622,49 @@ void _i2c_irq_handler(i2c_dev *dev) { |
206 | - | - I2C_CRUMB(RX_ADDR_START, 0, 0); |
206 | + | |
207 | - | - } else { |
207 | + | |
208 | - | - i2c_stop_condition(dev); |
208 | + | |
209 | - | - I2C_CRUMB(RX_ADDR_STOP, 0, 0); |
209 | + | |
210 | - | - } |
210 | + | |
211 | - | - } |
211 | + | |
212 | - | - } else { |
212 | + | |
213 | - | - /* |
213 | + | |
214 | - | - * Master transmitter: write first byte to fill shift |
214 | + | |
215 | - | - * register. We should get another TXE interrupt |
215 | + | |
216 | - | - * immediately to fill DR again. |
216 | + | |
217 | - | - */ |
217 | + | + /* Check to see if the master device did a NAK on the last bit |
218 | - | - if (msg->length != 1) { |
218 | + | + * This is perfectly valid for a master to do this on the bus. |
219 | - | - i2c_write(dev, msg->data[msg->xferred++]); |
219 | + | + * We ignore this. Any further error processing takes us into dead |
220 | - | - } |
220 | + | + * loop waiting for the stop condition that will never arrive |
221 | - | - } |
221 | + | + */ |
222 | - | - sr1 = sr2 = 0; |
222 | + | + if (dev->regs->SR1 & I2C_SR1_AF) { |
223 | - | - } |
223 | + | + /* Clear flags */ |
224 | + dev->regs->SR1 = 0; | |
225 | - | + (dev->config_flags & I2C_SLAVE_USE_TX_BUFFER)) { |
225 | + | + dev->regs->SR2 = 0; |
226 | + /* We need to write something to CR1 to clear the flag. | |
227 | - | - /* |
227 | + | + * This isn't really mentioned but seems important */ |
228 | - | - * EV8: Master transmitter |
228 | + | + i2c_enable_ack(dev); |
229 | - | - * Transmit buffer empty, but we haven't finished transmitting the last |
229 | + | |
230 | - | - * byte written. |
230 | + | + if (dev->state == I2C_STATE_SL_RX && |
231 | - | - */ |
231 | + | + dev->config_flags & I2C_SLAVE_USE_RX_BUFFER && |
232 | - | - if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) { |
232 | + | + dev->i2c_slave_msg->xferred > 0) { |
233 | - | - I2C_CRUMB(TXE_ONLY, 0, 0); |
233 | + | + /* Call the callback with the contents of the data */ |
234 | - | - if (dev->msgs_left) { |
234 | + | + if (dev->i2c_slave_recv_callback != NULL) (*(dev->i2c_slave_recv_callback))(dev->i2c_slave_msg); |
235 | - | - i2c_write(dev, msg->data[msg->xferred++]); |
235 | + | + } |
236 | - | - if (msg->xferred == msg->length) { |
236 | + | |
237 | - | - /* |
237 | + | |
238 | - | - * End of this message. Turn off TXE/RXNE and wait for |
238 | + | + return; |
239 | - | - * BTF to send repeated start or stop condition. |
239 | + | |
240 | - | - */ |
240 | + | + /* Catch any other strange errors while in slave mode. |
241 | - | - i2c_disable_irq(dev, I2C_IRQ_BUFFER); |
241 | + | + * I have seen BERR caused by an over fast master device |
242 | - | - dev->msgs_left--; |
242 | + | + * as well as several overflows and arbitration failures. |
243 | - | - } |
243 | + | + * We are going to reset SR flags and carry on at this point which |
244 | - | - } else { |
244 | + | + * is not the best thing to do, but stops the bus locking up completely |
245 | - | - /* |
245 | + | + * If we carry on below and send the stop bit, the code spins forever */ |
246 | - | - * This should be impossible... |
246 | + | |
247 | - | - */ |
247 | + | |
248 | - | - ASSERT(0); |
248 | + | |
249 | - | - } |
249 | + | |
250 | - | - sr1 = sr2 = 0; |
250 | + | |
251 | - | - } |
251 | + | |
252 | - | + /* The callback with the data will happen on a NACK of the last data byte. |
252 | + | |
253 | - | + * This is handled in the error IRQ (AF bit) |
253 | + | |
254 | - | + */ |
254 | + | |
255 | - | + } |
255 | + | |
256 | @@ -507,3 +712,31 @@ static void set_ccr_trise(i2c_dev *dev, uint32 flags) { | |
257 | - | - /* |
257 | + | |
258 | - | - * EV8_2: Master transmitter |
258 | + | |
259 | - | - * Last byte sent, program repeated start/stop |
259 | + | |
260 | - | - */ |
260 | + | |
261 | - | - if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) { |
261 | + | |
262 | - | - I2C_CRUMB(TXE_BTF, 0, 0); |
262 | + | |
263 | - | - if (dev->msgs_left) { |
263 | + | |
264 | - | - I2C_CRUMB(TEST, 0, 0); |
264 | + | |
265 | - | - /* |
265 | + | |
266 | - | - * Repeated start insanity: We can't disable ITEVTEN or else SB |
266 | + | |
267 | - | - * won't interrupt, but if we don't disable ITEVTEN, BTF will |
267 | + | |
268 | - | - * continually interrupt us. What the fuck ST? |
268 | + | |
269 | - | - */ |
269 | + | |
270 | - | - i2c_start_condition(dev); |
270 | + | |
271 | - | - while (!(dev->regs->SR1 & I2C_SR1_SB)) |
271 | + | |
272 | - | - ; |
272 | + | |
273 | - | - dev->msg++; |
273 | + | |
274 | - | - } else { |
274 | + | |
275 | - | - i2c_stop_condition(dev); |
275 | + | |
276 | - | - |
276 | + | |
277 | - | - /* |
277 | + | |
278 | - | - * Turn off event interrupts to keep BTF from firing until |
278 | + | |
279 | - | - * the end of the stop condition. Why on earth they didn't |
279 | + | |
280 | - | - * have a start/stop condition request clear BTF is beyond |
280 | + | |
281 | - | - * me. |
281 | + | |
282 | - | - */ |
282 | + | |
283 | - | - i2c_disable_irq(dev, I2C_IRQ_EVENT); |
283 | + | |
284 | - | - I2C_CRUMB(STOP_SENT, 0, 0); |
284 | + | + dev->i2c_slave_transmit_callback = func; |
285 | - | - dev->state = I2C_STATE_XFER_DONE; |
285 | + | |
286 | + msg->xferred = 0; | |
287 | +} | |
288 | diff --git a/libmaple/include/libmaple/i2c.h b/libmaple/include/libmaple/i2c.h | |
289 | - | - sr1 = sr2 = 0; |
289 | + | |
290 | - | - } |
290 | + | |
291 | +++ b/libmaple/include/libmaple/i2c.h | |
292 | - | - /* |
292 | + | |
293 | - | - * EV7: Master Receiver |
293 | + | |
294 | - | - */ |
294 | + | |
295 | - | - if (sr1 & I2C_SR1_RXNE) { |
295 | + | |
296 | - | - I2C_CRUMB(RXNE_ONLY, 0, 0); |
296 | + | |
297 | - | - msg->data[msg->xferred++] = dev->regs->DR; |
297 | + | |
298 | - | - |
298 | + | |
299 | - | - /* |
299 | + | |
300 | - | - * EV7_1: Second to last byte in the reception? Set NACK and generate |
300 | + | |
301 | - | - * stop/restart condition in time for the last byte. We'll get one more |
301 | + | |
302 | - | - * RXNE interrupt before shutting things down. |
302 | + | |
303 | - | - */ |
303 | + | |
304 | - | - if (msg->xferred == (msg->length - 1)) { |
304 | + | |
305 | - | - i2c_disable_ack(dev); |
305 | + | |
306 | - | - if (dev->msgs_left > 2) { |
306 | + | |
307 | - | - i2c_start_condition(dev); |
307 | + | |
308 | - | - I2C_CRUMB(RXNE_START_SENT, 0, 0); |
308 | + | |
309 | - | - } else { |
309 | + | |
310 | - | - i2c_stop_condition(dev); |
310 | + | |
311 | - | - I2C_CRUMB(RXNE_STOP_SENT, 0, 0); |
311 | + | |
312 | - | - } |
312 | + | |
313 | - | - } else if (msg->xferred == msg->length) { |
313 | + | |
314 | - | - dev->msgs_left--; |
314 | + | |
315 | - | - if (dev->msgs_left == 0) { |
315 | + | |
316 | - | - /* |
316 | + | |
317 | - | - * We're done. |
317 | + | |
318 | - | - */ |
318 | + | |
319 | - | - I2C_CRUMB(RXNE_DONE, 0, 0); |
319 | + | |
320 | - | - dev->state = I2C_STATE_XFER_DONE; |
320 | + | |
321 | - | - } else { |
321 | + | |
322 | - | - dev->msg++; |
322 | + | |
323 | - | - } |
323 | + | |
324 | - | - } |
324 | + | |
325 | +} | |
326 | + | |
327 | +/** | |
328 | - | + /* |
328 | + | |
329 | - | + * EV5: Start condition sent |
329 | + | |
330 | - | + */ |
330 | + | |
331 | - | + if (sr1 & I2C_SR1_SB) { |
331 | + | |
332 | - | + msg->xferred = 0; |
332 | + | |
333 | - | + i2c_enable_irq(dev, I2C_IRQ_BUFFER); |
333 | + | |
334 | + | |
335 | - | + /* |
335 | + | |
336 | - | + * Master receiver |
336 | + | |
337 | - | + */ |
337 | + | |
338 | - | + if (read) { |
338 | + | |
339 | - | + i2c_enable_ack(dev); |
339 | + | |
340 | - | + } |
340 | + | |
341 | + */ | |
342 | - | + i2c_send_slave_addr(dev, msg->addr, read); |
342 | + | |
343 | - | + sr1 = sr2 = 0; |
343 | + | |
344 | - | + } |
344 | + | |
345 | + * @brief Set the primary I2c slave address | |
346 | - | + /* |
346 | + | |
347 | - | + * EV6: Slave address sent |
347 | + | |
348 | - | + */ |
348 | + | |
349 | - | + if (sr1 & I2C_SR1_ADDR) { |
349 | + | |
350 | - | + /* |
350 | + | |
351 | - | + * Special case event EV6_1 for master receiver. |
351 | + | |
352 | - | + * Generate NACK and restart/stop condition after ADDR |
352 | + | |
353 | - | + * is cleared. |
353 | + | |
354 | - | + */ |
354 | + | |
355 | - | + if (read) { |
355 | + | |
356 | - | + if (msg->length == 1) { |
356 | + | |
357 | - | + i2c_disable_ack(dev); |
357 | + | |
358 | - | + if (dev->msgs_left > 1) { |
358 | + | |
359 | - | + i2c_start_condition(dev); |
359 | + | |
360 | - | + I2C_CRUMB(RX_ADDR_START, 0, 0); |
360 | + | |
361 | - | + } else { |
361 | + | |
362 | - | + i2c_stop_condition(dev); |
362 | + | |
363 | - | + I2C_CRUMB(RX_ADDR_STOP, 0, 0); |
363 | + | |
364 | - | + } |
364 | + | |
365 | - | + } |
365 | + | |
366 | - | + } else { |
366 | + | index 17cabe3..5debcb8 100644 |
367 | - | + /* |
367 | + | |
368 | - | + * Master transmitter: write first byte to fill shift |
368 | + | |
369 | - | + * register. We should get another TXE interrupt |
369 | + | @@ -52,9 +52,12 @@ typedef enum i2c_state { |
370 | - | + * immediately to fill DR again. |
370 | + | I2C_STATE_IDLE = 1, /**< Idle */ |
371 | - | + */ |
371 | + | I2C_STATE_XFER_DONE = 2, /**< Done with transfer */ |
372 | - | + if (msg->length != 1) { |
372 | + | I2C_STATE_BUSY = 3, /**< Busy */ |
373 | - | + i2c_write(dev, msg->data[msg->xferred++]); |
373 | + | + I2C_STATE_SL_RX = 4, /**< Slave receiving */ |
374 | - | + } |
374 | + | |
375 | - | + } |
375 | + | |
376 | - | + sr1 = sr2 = 0; |
376 | + | |
377 | - | + } |
377 | + | |
378 | +typedef void (*i2c_slave_transmit_callback_func)(struct i2c_msg *); | |
379 | - | + /* |
379 | + | |
380 | - | + * EV8: Master transmitter |
380 | + | |
381 | - | + * Transmit buffer empty, but we haven't finished transmitting the last |
381 | + | |
382 | - | + * byte written. |
382 | + | @@ -88,6 +91,17 @@ typedef struct i2c_dev { |
383 | - | + */ |
383 | + | |
384 | - | + if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) { |
384 | + | |
385 | - | + I2C_CRUMB(TXE_ONLY, 0, 0); |
385 | + | |
386 | - | + if (dev->msgs_left) { |
386 | + | |
387 | - | + i2c_write(dev, msg->data[msg->xferred++]); |
387 | + | |
388 | - | + if (msg->xferred == msg->length) { |
388 | + | |
389 | - | + /* |
389 | + | |
390 | - | + * End of this message. Turn off TXE/RXNE and wait for |
390 | + | |
391 | - | + * BTF to send repeated start or stop condition. |
391 | + | |
392 | - | + */ |
392 | + | |
393 | - | + i2c_disable_irq(dev, I2C_IRQ_BUFFER); |
393 | + | |
394 | - | + dev->msgs_left--; |
394 | + | |
395 | - | + } |
395 | + | |
396 | - | + } else { |
396 | + | |
397 | - | + /* |
397 | + | |
398 | - | + * This should be impossible... |
398 | + | |
399 | - | + */ |
399 | + |