The solution

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