tm4c_hal/i2c.rs
1//! Common I2C code for TM4C123 and TM4C129
2
3/// I2C error
4#[derive(Debug)]
5#[non_exhaustive]
6pub enum Error {
7 /// Bus Busy
8 BusBusy,
9
10 /// Arbitration loss
11 Arbitration,
12
13 /// Missing Data ACK
14 DataAck,
15
16 /// Missing Address ACK
17 AdrAck,
18
19 /// I2C Timeout
20 Timeout,
21}
22
23#[macro_export]
24/// Implements the traits for an I2C peripheral
25macro_rules! i2c_pins {
26 ($I2Cn:ident,
27 scl: [$(($($sclgpio: ident)::*, $sclaf: ident)),*],
28 sda: [$(($($sdagpio: ident)::*, $sdaaf: ident)),*],
29 ) => {
30 $(
31 impl<T> SclPin<$I2Cn> for $($sclgpio)::*<AlternateFunction<$sclaf, T>>
32 where
33 T: OutputMode,
34 {}
35 )*
36
37 $(
38 impl<T> SdaPin<$I2Cn> for $($sdagpio)::*<AlternateFunction<$sdaaf, T>>
39 where
40 T: OutputMode,
41 {}
42 )*
43 }
44}
45
46#[macro_export]
47/// Spins until the controler is ready (mcs.busy is clear) and optionally on
48/// another field of the mcs register until it is clear or set (depending on op
49/// parameter).
50macro_rules! i2c_busy_wait {
51 ($i2c:expr $(, $field:ident, $op:ident)? ) => {{
52 // in 'release' builds, the time between setting the `run` bit and checking the `busy`
53 // bit is too short and the `busy` bit is not reliably set by the time you get there,
54 // it can take up to 8 clock cycles for the `run` to begin so this delay allows time
55 // for that hardware synchronization
56 delay(8);
57
58 // Allow 1,000 clock cycles before we timeout. At 100 kHz, this is 10 ms.
59 $i2c.mclkocnt
60 .write(|w| unsafe { w.cntl().bits((1_000 >> 4) as u8) });
61
62 let mcs = loop {
63 let mcs = $i2c.mcs.read();
64
65 if mcs.busy().bit_is_clear() {
66 break mcs;
67 }
68 };
69
70
71 if mcs.clkto().bit_is_set() {
72 return Err(Error::Timeout)
73 } else if mcs.arblst().bit_is_set() {
74 return Err(Error::Arbitration)
75 } else if mcs.error().bit_is_set() {
76 if mcs.adrack().bit_is_set() {
77 return Err(Error::AdrAck);
78 } else { // if mcs.datack().bit_is_set() {
79 return Err(Error::DataAck);
80 }
81 }
82
83 $( loop {
84 if mcs.clkto().bit_is_set() {
85 return Err(Error::Timeout)
86 } else if mcs.arblst().bit_is_set() {
87 return Err(Error::Arbitration)
88 } else if mcs.error().bit_is_set() {
89 if mcs.adrack().bit_is_set() {
90 return Err(Error::AdrAck);
91 } else { // if mcs.datack().bit_is_set() {
92 return Err(Error::DataAck);
93 }
94 } else if mcs.$field().$op() {
95 break;
96 } else {
97 // try again
98 }
99 };)?
100
101 Ok(())
102 }};
103}
104
105#[macro_export]
106/// Implements embedded-hal for an TM4C I2C peripheral
107macro_rules! i2c_hal {
108 ($($I2CX:ident: ($powerDomain:ident, $i2cX:ident),)+) => {
109 $(
110 impl<SCL, SDA> I2c<$I2CX, (SCL, SDA)> {
111 /// Configures the I2C peripheral to work in master mode
112 pub fn $i2cX<F>(
113 i2c: $I2CX,
114 pins: (SCL, SDA),
115 freq: F,
116 clocks: &Clocks,
117 pc: &sysctl::PowerControl,
118 ) -> Self where
119 F: Into<Hertz>,
120 SCL: SclPin<$I2CX>,
121 SDA: SdaPin<$I2CX>,
122 {
123 sysctl::control_power(
124 pc, sysctl::Domain::$powerDomain,
125 sysctl::RunMode::Run, sysctl::PowerState::On);
126 sysctl::reset(pc, sysctl::Domain::$powerDomain);
127
128 // set Master Function Enable, and clear other bits.
129 i2c.mcr.write(|w| w.mfe().set_bit());
130
131 // Write TimerPeriod configuration and clear other bits.
132 let freq = freq.into().0;
133 let tpr = ((clocks.sysclk.0/(2*10*freq))-1) as u8;
134
135 i2c.mtpr.write(|w| unsafe {w.tpr().bits(tpr)});
136
137 I2c { i2c, pins }
138 }
139
140 /// Releases the I2C peripheral and associated pins
141 pub fn free(self) -> ($I2CX, (SCL, SDA)) {
142 (self.i2c, self.pins)
143 }
144 }
145
146 impl<PINS> Write for I2c<$I2CX, PINS> {
147 type Error = Error;
148
149 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
150 // Write Slave address and clear Receive bit
151 self.i2c.msa.write(|w| unsafe {
152 w.sa().bits(addr)
153 });
154
155 // Put first byte in data register
156 self.i2c.mdr.write(|w| unsafe {
157 w.data().bits(bytes[0])
158 });
159
160 let sz = bytes.len();
161
162 i2c_busy_wait!(self.i2c, busbsy, bit_is_clear)?;
163
164 // Send START + RUN
165 // If single byte transfer, set STOP
166 self.i2c.mcs.write(|w| {
167 if sz == 1 {
168 w.stop().set_bit();
169 }
170 w.start().set_bit()
171 .run().set_bit()
172 });
173
174 for (i,byte) in (&bytes[1..]).iter().enumerate() {
175 i2c_busy_wait!(self.i2c)?;
176
177 // Put next byte in data register
178 self.i2c.mdr.write(|w| unsafe {
179 w.data().bits(*byte)
180 });
181
182 // Send RUN command (Burst continue)
183 // Set STOP on last byte
184 self.i2c.mcs.write(|w| {
185 if (i+1) == (sz-1) {
186 w.stop().set_bit();
187 }
188 w.run().set_bit()
189 });
190 }
191
192 i2c_busy_wait!(self.i2c)?;
193
194 Ok(())
195 }
196 }
197
198 impl<PINS> Read for I2c<$I2CX, PINS> {
199 type Error = Error;
200
201 fn read(
202 &mut self,
203 addr: u8,
204 buffer: &mut [u8],
205 ) -> Result<(), Error> {
206
207 // Write Slave address and set Receive bit
208 self.i2c.msa.write(|w| unsafe {
209 w.sa().bits(addr)
210 .rs().set_bit()
211 });
212
213 i2c_busy_wait!(self.i2c, busbsy, bit_is_clear)?;
214
215 let recv_sz = buffer.len();
216
217 if recv_sz == 1 {
218 // Single receive
219 self.i2c.mcs.write(|w| {
220 w.run().set_bit()
221 .start().set_bit()
222 .stop().set_bit()
223 });
224
225 i2c_busy_wait!(self.i2c)?;
226 buffer[0] = self.i2c.mdr.read().data().bits();
227 } else {
228 self.i2c.mcs.write(|w| {
229 w.start().set_bit()
230 .run().set_bit()
231 .ack().set_bit()
232 });
233
234 i2c_busy_wait!(self.i2c)?;
235 buffer[0] = self.i2c.mdr.read().data().bits();
236
237 for byte in &mut buffer[1..recv_sz-1] {
238 self.i2c.mcs.write(|w| {
239 w.run().set_bit()
240 .ack().set_bit()
241 });
242 i2c_busy_wait!(self.i2c)?;
243 *byte = self.i2c.mdr.read().data().bits();
244 }
245 self.i2c.mcs.write(|w| {
246 w.run().set_bit()
247 .stop().set_bit()
248 });
249
250 i2c_busy_wait!(self.i2c)?;
251 buffer[recv_sz-1] = self.i2c.mdr.read().data().bits();
252 }
253
254 Ok(())
255 }
256 }
257
258 impl<PINS> WriteRead for I2c<$I2CX, PINS> {
259 type Error = Error;
260
261 fn write_read(
262 &mut self,
263 addr: u8,
264 bytes: &[u8],
265 buffer: &mut [u8],
266 ) -> Result<(), Error> {
267
268 let write_len = bytes.len();
269
270 if buffer.len() == 0 {
271 return self.write(addr, bytes);
272 }
273
274 if bytes.len() == 0 {
275 return self.read(addr, buffer);
276 }
277
278 // Write Slave address and clear Receive bit
279 self.i2c.msa.write(|w| unsafe {
280 w.sa().bits(addr)
281 });
282
283 // send first byte
284 self.i2c.mdr.write(|w| unsafe {
285 w.data().bits(bytes[0])
286 });
287
288 i2c_busy_wait!(self.i2c, busbsy, bit_is_clear)?;
289 self.i2c.mcs.write(|w| {
290 w.start().set_bit()
291 .run().set_bit()
292 });
293
294 i2c_busy_wait!(self.i2c)?;
295 for byte in (&bytes[1..write_len]).iter() {
296 self.i2c.mdr.write(|w| unsafe {
297 w.data().bits(*byte)
298 });
299
300 self.i2c.mcs.write(|w| {
301 w.run().set_bit()
302 });
303
304 i2c_busy_wait!(self.i2c)?;
305 }
306
307 // Write Slave address and set Receive bit
308 self.i2c.msa.write(|w| unsafe {
309 w.sa().bits(addr)
310 .rs().set_bit()
311 });
312
313 let recv_sz = buffer.len();
314
315 if recv_sz == 1 {
316 // emit Repeated START and STOP for single receive
317 self.i2c.mcs.write(|w| {
318 w.run().set_bit()
319 .start().set_bit()
320 .stop().set_bit()
321 });
322
323 i2c_busy_wait!(self.i2c)?;
324 buffer[0] = self.i2c.mdr.read().data().bits();
325 } else {
326 // emit Repeated START
327 self.i2c.mcs.write(|w| {
328 w.run().set_bit()
329 .start().set_bit()
330 .ack().set_bit()
331 });
332
333 i2c_busy_wait!(self.i2c)?;
334 buffer[0] = self.i2c.mdr.read().data().bits();
335
336 for byte in &mut buffer[1..recv_sz-1] {
337 self.i2c.mcs.write(|w| {
338 w.run().set_bit()
339 .ack().set_bit()
340 });
341 i2c_busy_wait!(self.i2c)?;
342 *byte = self.i2c.mdr.read().data().bits();
343 }
344
345 self.i2c.mcs.write(|w| {
346 w.run().set_bit()
347 .stop().set_bit()
348 });
349
350 i2c_busy_wait!(self.i2c)?;
351 buffer[recv_sz-1] = self.i2c.mdr.read().data().bits();
352 }
353
354 Ok(())
355 }
356 }
357 )+
358 }
359}