# Copyright (C) 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Datasheet: https://www.pololu.com/file/0J703/LSM303D.pdf
cyanobyte: 0.1.0
info:
  contact:
    name: Nick Felker
    url: https://github.com/google/cyanobyte
    email: felker@google.com
  package: com.cyanobyte
  title: LSM303D
  description: STMicroelectronics accelerometer and magnetometer
  copyright:
    name: Google Inc.
    date: '2019'
  license:
    name: Apache-2.0
  version: 0.1.0
i2c:
  addressType: 7-bit
  address: 0x1D
  addressMask: 0xFF

registers:
  # Accelerometer registers are 8 bits each, with 16-bit data values
  # Increment each output by 0x80 to enable auto-increment of registers
  AccelerometerX_Low:
    address: 0xA8
    length: 8
    title: Accelerometer X
    description: Raw accelerometer data on X plane
    readWrite: R
  AccelerometerX_High:
    address: 0xA9
    length: 8
    title: Accelerometer X
    description: Raw accelerometer data on X plane
    readWrite: R
  AccelerometerY_Low:
    address: 0xAA
    length: 8
    title: Accelerometer Y
    description: Raw accelerometer data on Y plane
    readWrite: R
  AccelerometerY_High:
    address: 0xAB
    length: 8
    title: Accelerometer Y
    description: Raw accelerometer data on Y plane
    readWrite: R
  AccelerometerZ_Low:
    address: 0xAC
    length: 8
    title: Accelerometer Z
    description: Raw accelerometer data on Z plane
    readWrite: R
  AccelerometerZ_High:
    address: 0xAD
    length: 8
    title: Accelerometer Z
    description: Raw accelerometer data on Z plane
    readWrite: R
  MagnetometerX_Low:
    address: 0x88
    length: 8
    title: Magnetometer X
    description: Raw magnetometer data on X plane
    readWrite: R
  MagnetometerX_High:
    address: 0x89
    length: 8
    title: Magnetometer X
    description: Raw magnetometer data on X plane
    readWrite: R
  MagnetometerY_Low:
    address: 0x8A
    length: 8
    title: Magnetometer Y
    description: Raw magnetometer data on Y plane
    readWrite: R
  MagnetometerY_High:
    address: 0x8B
    length: 8
    title: Magnetometer Y
    description: Raw magnetometer data on Y plane
    readWrite: R
  MagnetometerZ_Low:
    address: 0x8C
    length: 8
    title: Magnetometer Z
    description: Raw magnetometer data on Z plane
    readWrite: R
  MagnetometerZ_High:
    address: 0x8D
    length: 8
    title: Magnetometer Z
    description: Raw magnetometer data on Z plane
    readWrite: R

functions:
  acceleration:
    title: Acceleration as read by sensor
    description: Measures the current acceleration
    readWrite: 'n'
    computed:
      xPlane:
        output: int16
        variables:
          lower: int8
          upper: int8
          datum: int16
        logic:
          - lower: '#/registers/AccelerometerX_Low'
          - upper: '#/registers/AccelerometerX_High'
          - datum:
            - sum:
              - bitShiftLeft:
                var: upper
                bits: 8
              - lower
        return: datum
      yPlane:
        output: int16
        variables:
          lower: int8
          upper: int8
          datum: int16
        logic:
          - lower: '#/registers/AccelerometerY_Low'
          - upper: '#/registers/AccelerometerY_High'
          - datum:
            - sum:
              - bitShiftLeft:
                var: upper
                bits: 8
              - lower
        return: datum
      zPlane:
        output: int16
        variables:
          lower: int8
          upper: int8
          datum: int16
        logic:
          - lower: '#/registers/AccelerometerZ_Low'
          - upper: '#/registers/AccelerometerZ_High'
          - datum:
            - sum:
              - bitShiftLeft:
                var: upper
                bits: 8
              - lower
        return: datum
      asG:
        variables:
          valueX: int16
          valueY: int16
          valueZ: int16
          accelerationScale: int8 # Linear acceleration scale variable
        logic:
          - accelerationScale: = 2 # Default scale level
          - valueX: '#/functions/acceleration/xPlane'
          - valueY: '#/functions/acceleration/yPlane'
          - valueZ: '#/functions/acceleration/zPlane'
          - valueX:
            - product:
              - division:
                - valueX
                - power:
                  - 2
                  - 15
              - accelerationScale
          - valueY:
            - product:
              - division:
                - valueY
                - power:
                  - 2
                  - 15
              - accelerationScale
          - valueZ:
            - product:
              - division:
                - valueZ
                - power:
                  - 2
                  - 15
              - accelerationScale
        return:
          - valueX
          - valueY
          - valueZ
  orientation:
    title: Orientation data as read by sensor
    description: Reads the magnetic orientation
    readWrite: 'n'
    computed:
      xPlane:
        output: int16
        variables:
          lower: int8
          upper: int8
          datum: int16
        logic:
          - lower: '#/registers/MagnetometerX_Low'
          - upper: '#/registers/MagnetometerX_High'
          - datum:
            - sum:
              - bitShiftLeft:
                var: upper
                bits: 8
              - lower
        return: datum
      yPlane:
        output: int16
        variables:
          lower: int8
          upper: int8
          datum: int16
        logic:
          - lower: '#/registers/MagnetometerY_Low'
          - upper: '#/registers/MagnetometerY_High'
          - datum:
            - sum:
              - bitShiftLeft:
                var: upper
                bits: 8
              - lower
        return: datum
      zPlane:
        output: int16
        variables:
          lower: int8
          upper: int8
          datum: int16
        logic:
          - lower: '#/registers/MagnetometerZ_Low'
          - upper: '#/registers/MagnetometerZ_High'
          - datum:
            - sum:
              - bitShiftLeft:
                var: upper
                bits: 8
              - lower
        return: datum
      heading:
        variables:
          valueX: int16
          valueY: int16
          dividend: int16
          heading: int16
        logic:
          - valueX: '#/functions/orientation/xPlane'
          - valueY: '#/functions/orientation/yPlane'
          - dividend:
            - division:
              - valueX
              - valueY
          - heading:
            - arc tangent: dividend
          - heading:
            - modulus:
              - heading
              - product:
                - 2
                - 3.141592653589793 # Pi
          # Convert from radians to degrees
          - heading:
            - product:
              - division:
                - heading
                - 3.141592653589793 # Pi
              - 180
        return: heading