exp/sensor: enable magnetometer on darwin{arm,arm64}

Change-Id: Ib188121501ac96cb8743e57f907b23d0fdfc37a0
Reviewed-on: https://go-review.googlesource.com/14292
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/exp/sensor/darwin_armx.go b/exp/sensor/darwin_armx.go
index 612882e..94c3f89 100644
--- a/exp/sensor/darwin_armx.go
+++ b/exp/sensor/darwin_armx.go
@@ -23,6 +23,10 @@
 void GoIOS_stopGyro();
 void GoIOS_readGyro(int64_t* timestamp, float* vector);
 
+void GoIOS_startMagneto(float interval);
+void GoIOS_stopMagneto();
+void GoIOS_readMagneto(int64_t* timestamp, float* vector);
+
 void GoIOS_destroyManager();
 */
 import "C"
@@ -71,17 +75,16 @@
 	if delay < minDelay {
 		delay = minDelay
 	}
-	interval := float64(delay) / float64(time.Second)
+	interval := C.float(float64(delay) / float64(time.Second))
 
 	switch t {
 	case Accelerometer:
-		C.GoIOS_startAccelerometer(C.float(interval))
+		C.GoIOS_startAccelerometer(interval)
 	case Gyroscope:
-		C.GoIOS_startGyro(C.float(interval))
+		C.GoIOS_startGyro(interval)
 	case Magnetometer:
-		return fmt.Errorf("sensor: %v is not supported yet", t)
+		C.GoIOS_startMagneto(interval)
 	}
-
 	go m.pollSensor(s, t, delay, channels.done[t])
 	return nil
 }
@@ -102,8 +105,7 @@
 	case Gyroscope:
 		C.GoIOS_stopGyro()
 	case Magnetometer:
-	default:
-		return fmt.Errorf("sensor: unknown sensor type: %v", t)
+		C.GoIOS_stopMagneto()
 	}
 	return nil
 }
@@ -119,11 +121,16 @@
 		case <-done:
 			return
 		default:
+			tp := (*C.int64_t)(unsafe.Pointer(&timestamp))
+			vp := (*C.float)(unsafe.Pointer(&ev[0]))
+
 			switch t {
 			case Accelerometer:
-				C.GoIOS_readAccelerometer((*C.int64_t)(unsafe.Pointer(&timestamp)), (*C.float)(unsafe.Pointer(&ev[0])))
+				C.GoIOS_readAccelerometer(tp, vp)
 			case Gyroscope:
-				C.GoIOS_readGyro((*C.int64_t)(unsafe.Pointer(&timestamp)), (*C.float)(unsafe.Pointer(&ev[0])))
+				C.GoIOS_readGyro(tp, vp)
+			case Magnetometer:
+				C.GoIOS_readMagneto(tp, vp)
 			}
 			ts := int64(timestamp)
 			if ts > lastTimestamp {
diff --git a/exp/sensor/darwin_armx.m b/exp/sensor/darwin_armx.m
index a775a46..d67f812 100644
--- a/exp/sensor/darwin_armx.m
+++ b/exp/sensor/darwin_armx.m
@@ -47,6 +47,23 @@
   v[2] = data.rotationRate.z;
 }
 
+void GoIOS_startMagneto(float interval) {
+  manager.magnetometerUpdateInterval = interval;
+  [manager startMagnetometerUpdates];
+}
+
+void GoIOS_stopMagneto() {
+  [manager stopMagnetometerUpdates];
+}
+
+void GoIOS_readMagneto(int64_t* timestamp, float* v) {
+  CMMagnetometerData* data = manager.magnetometerData;
+  *timestamp = (int64_t)(data.timestamp * 1000 * 1000);
+  v[0] = data.magneticField.x;
+  v[1] = data.magneticField.y;
+  v[2] = data.magneticField.z;
+}
+
 void GoIOS_destroyManager() {
   [manager release];
   manager = nil;