The solution
1. #![deny(unsafe_code)]
2. #![no_main]
3. #![no_std]
5. #[allow(unused_imports)]
6. use aux14::{entry, iprint, iprintln, prelude::*};
8. // Slave address
9. const MAGNETOMETER: u8 = 0b001_1110;
11. // Addresses of the magnetometer's registers
12. const OUT_X_H_M: u8 = 0x03;
13. const IRA_REG_M: u8 = 0x0A;
15. #[entry]
16. fn main() -> ! {
17. let (i2c1, _delay, mut itm) = aux14::init();
19. // Stage 1: Send the address of the register we want to read to the
20. // magnetometer
21. {
22. // Broadcast START
23. // Broadcast the MAGNETOMETER address with the R/W bit set to Write
24. i2c1.cr2.write(|w| {
25. w.start().set_bit();
26. w.sadd1().bits(MAGNETOMETER);
27. w.rd_wrn().clear_bit();
28. w.nbytes().bits(1);
29. w.autoend().clear_bit()
30. });
32. // Wait until we can send more data
33. while i2c1.isr.read().txis().bit_is_clear() {}
35. // Send the address of the register that we want to read: IRA_REG_M
36. i2c1.txdr.write(|w| w.txdata().bits(IRA_REG_M));
38. // Wait until the previous byte has been transmitted
39. while i2c1.isr.read().tc().bit_is_clear() {}
40. }
42. // Stage 2: Receive the contents of the register we asked for
43. let byte = {
44. // Broadcast RESTART
45. // Broadcast the MAGNETOMETER address with the R/W bit set to Read
46. i2c1.cr2.modify(|_, w| {
47. w.start().set_bit();
48. w.nbytes().bits(1);
49. w.rd_wrn().set_bit();
50. w.autoend().set_bit()
51. });
53. // Wait until we have received the contents of the register
54. while i2c1.isr.read().rxne().bit_is_clear() {}
56. // Broadcast STOP (automatic because of `AUTOEND = 1`)
58. i2c1.rxdr.read().rxdata().bits()
59. };
61. // Expected output: 0x0A - 0b01001000
62. iprintln!(&mut itm.stim[0], "0x{:02X} - 0b{:08b}", IRA_REG_M, byte);
64. loop {}
65. }