+ ao_hmc5883_addr = 0xff;
+}
+
+static uint8_t ao_hmc5883_done;
+
+static void
+ao_hmc5883_isr(void)
+{
+ ao_exti_disable(AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN);
+ ao_hmc5883_done = 1;
+ ao_wakeup(&ao_hmc5883_done);
+}
+
+static uint32_t ao_hmc5883_missed_irq;
+
+void
+ao_hmc5883_sample(struct ao_hmc5883_sample *sample)
+{
+ uint16_t *d = (uint16_t *) sample;
+ int i = sizeof (*sample) / 2;
+ uint8_t single = HMC5883_MODE_SINGLE;
+
+ ao_hmc5883_done = 0;
+ ao_exti_enable(AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN);
+ ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE);
+
+ ao_alarm(AO_MS_TO_TICKS(10));
+ cli();
+ while (!ao_hmc5883_done)
+ if (ao_sleep(&ao_hmc5883_done))
+ ++ao_hmc5883_missed_irq;
+ sei();
+ ao_clear_alarm();
+
+ ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample));
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* byte swap */
+ while (i--) {
+ uint16_t t = *d;
+ *d++ = (t >> 8) | (t << 8);
+ }
+#endif