Skip to content

Commit

Permalink
Working Version 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Matschke committed Jan 27, 2019
1 parent 9b0672d commit 11ae6a4
Showing 1 changed file with 81 additions and 82 deletions.
163 changes: 81 additions & 82 deletions Sources/LSM303/LSM303.swift
Original file line number Diff line number Diff line change
@@ -1,76 +1,75 @@
import Foundation
import SwiftyGPIO

let LSM303_ADDRESS_ACCEL = (0x32 >> 1) // 0011001x
let LSM303_ADDRESS_MAG = (0x3C >> 1) // 0011110x
let LSM303_ID = (0b11010100)
let Address_Acc = (0x32 >> 1)
let Address_Mag = (0x3C >> 1)

public enum AccelRegisters:UInt8 {
case CTRL_REG1_A = 0x20 // 00000111 rw
case CTRL_REG2_A = 0x21 // 00000000 rw
case CTRL_REG3_A = 0x22 // 00000000 rw
case CTRL_REG4_A = 0x23 // 00000000 rw
case CTRL_REG5_A = 0x24 // 00000000 rw
case CTRL_REG6_A = 0x25 // 00000000 rw
case REFERENCE_A = 0x26 // 00000000 r
case STATUS_REG_A = 0x27 // 00000000 r
case OUT_X_L_A = 0x28
case OUT_X_H_A = 0x29
case OUT_Y_L_A = 0x2A
case OUT_Y_H_A = 0x2B
case OUT_Z_L_A = 0x2C
case OUT_Z_H_A = 0x2D
case FIFO_CTRL_REG_A = 0x2E
case FIFO_SRC_REG_A = 0x2F
case INT1_CFG_A = 0x30
case INT1_SOURCE_A = 0x31
case INT1_THS_A = 0x32
case INT1_DURATION_A = 0x33
case INT2_CFG_A = 0x34
case INT2_SOURCE_A = 0x35
case INT2_THS_A = 0x36
case INT2_DURATION_A = 0x37
case CLICK_CFG_A = 0x38
case CLICK_SRC_A = 0x39
case CLICK_THS_A = 0x3A
case TIME_LIMIT_A = 0x3B
case TIME_LATENCY_A = 0x3C
case TIME_WINDOW_A = 0x3D
case Ctrl_Reg1_A = 0x20
case Ctrl_Reg2_A = 0x21
case Ctrl_Reg3_A = 0x22
case Ctrl_Reg4_A = 0x23
case Ctrl_Reg5_A = 0x24
case Ctrl_Reg6_A = 0x25
case Reference_A = 0x26
case Status_Reg_A = 0x27
case Out_X_L_A = 0x28
case Out_X_H_A = 0x29
case Out_Y_L_A = 0x2A
case Out_Y_H_A = 0x2B
case Out_Z_L_A = 0x2C
case Out_Z_H_A = 0x2D
case Fifo_Ctrl_Reg_A = 0x2E
case Fifo_Src_Reg_A = 0x2F
case Int1_CFG_A = 0x30
case Int1_Source_A = 0x31
case Int1_THS_A = 0x32
case Int1_Duration_A = 0x33
case Int2_CFG_A = 0x34
case Int2_Source_A = 0x35
case Int2_THS_A = 0x36
case Int2_Duration_A = 0x37
case Click_CFG_A = 0x38
case Click_Src_A = 0x39
case Click_THS_A = 0x3A
case Time_Limit_A = 0x3B
case Time_Latency_A = 0x3C
case Time_Window_A = 0x3D
}

public enum AccelScale:UInt8 {
// The accelertions is only set in two bits, so this code actually sets other flags alongside. Consult data sheet for more information
case G2 = 0b00000000 // Max is 2G
case G4 = 0b00010000 // .. 4G
case G8 = 0b00100000 // .. 8G
case G16 = 0b00110000 // .. 16G
}

public enum MagRegisters : UInt8 {
case CRA_REG_M = 0x00
case CRB_REG_M = 0x01
case MR_REG_M = 0x02
case OUT_X_H_M = 0x03
case OUT_X_L_M = 0x04
case OUT_Z_H_M = 0x05
case OUT_Z_L_M = 0x06
case OUT_Y_H_M = 0x07
case OUT_Y_L_M = 0x08
case SR_REG_Mg = 0x09
case IRA_REG_M = 0x0A
case IRB_REG_M = 0x0B
case IRC_REG_M = 0x0C
case TEMP_OUT_H_M = 0x31
case TEMP_OUT_L_M = 0x32
case CRA_Reg_M = 0x00
case CRB_Reg_M = 0x01
case MR_Reg_M = 0x02
case Out_X_H_M = 0x03
case Out_X_L_M = 0x04
case Out_Z_H_M = 0x05
case Out_Z_L_M = 0x06
case Out_Y_H_M = 0x07
case Out_Y_L_M = 0x08
case SR_Reg_Mg = 0x09
case IRA_Reg_M = 0x0A
case IRB_Reg_M = 0x0B
case IRC_Reg_M = 0x0C
case Temp_Out_H_M = 0x31
case Temp_Out_L_M = 0x32
}

public enum MagGain : UInt8 {
case GAIN_1_3 = 0x20 // +/- 1.3
case GAIN_1_9 = 0x40 // +/- 1.9
case GAIN_2_5 = 0x60 // +/- 2.5
case GAIN_4_0 = 0x80 // +/- 4.0
case GAIN_4_7 = 0xA0 // +/- 4.7
case GAIN_5_6 = 0xC0 // +/- 5.6
case GAIN_8_1 = 0xE0 // +/- 8.1
case Gain_1_3 = 0x20 // +/- 1.3
case Gain_1_9 = 0x40 // +/- 1.9
case Gain_2_5 = 0x60 // +/- 2.5
case Gain_4_0 = 0x80 // +/- 4.0
case Gain_4_7 = 0xA0 // +/- 4.7
case Gain_5_6 = 0xC0 // +/- 5.6
case Gain_8_1 = 0xE0 // +/- 8.1
}

public struct AccelData {
Expand All @@ -85,34 +84,34 @@ public class LSM303 {
var i2c : I2CInterface
public var accel : AccelData = AccelData(x: 0, y: 0, z: 0)
public var mag : MagData = MagData(x: 0, y: 0, z: 0)
var magGain : MagGain = MagGain.GAIN_1_3
var magGain : MagGain = MagGain.Gain_1_3
var accScale : AccelScale = AccelScale.G2

public convenience init() {self.init(for:.RaspberryPi3)}
public init(for board: SupportedBoard) {
let i2cs = SwiftyGPIO.hardwareI2Cs(for:board)!
self.i2c = i2cs[1] // not sure what i2cs[0] is ...
// Enable the accelerometer
i2c.writeByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.CTRL_REG1_A.rawValue, value: 0x27);
i2c.writeByte(Address_Acc, command: AccelRegisters.Ctrl_Reg1_A.rawValue, value: 0x27);
// Enable the magnetometer
i2c.writeByte(LSM303_ADDRESS_MAG, command: MagRegisters.MR_REG_M.rawValue, value: 0x00);
i2c.writeByte(Address_Mag, command: MagRegisters.MR_Reg_M.rawValue, value: 0x00);

accel = AccelData(x: 0, y: 0, z: 0)
mag = MagData(x: 0, y: 0, z: 0)
}

public func read() {
// Read acceleration
let xlo : UInt8 = i2c.readByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.OUT_X_L_A.rawValue); // Wire.read();
let xhi : UInt8 = i2c.readByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.OUT_X_H_A.rawValue); // Wire.read();
let ylo : UInt8 = i2c.readByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.OUT_Y_L_A.rawValue); // Wire.read();
let yhi : UInt8 = i2c.readByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.OUT_Y_H_A.rawValue); // Wire.read();
let zlo : UInt8 = i2c.readByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.OUT_Z_L_A.rawValue); // Wire.read();
let zhi : UInt8 = i2c.readByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.OUT_Z_H_A.rawValue); // Wire.read();
let xlo : UInt8 = i2c.readByte(Address_Acc, command: AccelRegisters.Out_X_L_A.rawValue); // Wire.read();
let xhi : UInt8 = i2c.readByte(Address_Acc, command: AccelRegisters.Out_X_H_A.rawValue); // Wire.read();
let ylo : UInt8 = i2c.readByte(Address_Acc, command: AccelRegisters.Out_Y_L_A.rawValue); // Wire.read();
let yhi : UInt8 = i2c.readByte(Address_Acc, command: AccelRegisters.Out_Y_H_A.rawValue); // Wire.read();
let zlo : UInt8 = i2c.readByte(Address_Acc, command: AccelRegisters.Out_Z_L_A.rawValue); // Wire.read();
let zhi : UInt8 = i2c.readByte(Address_Acc, command: AccelRegisters.Out_Z_H_A.rawValue); // Wire.read();

var g : Float = 1000.0
switch (self.accScale) {
case .G2 : g = 1000.0
case .G2 : g = 1000.0 // LSB/g from the data sheet
case .G4 : g = 2000.0
case .G8 : g = 4000.0
case .G16 : g = 12000.0
Expand All @@ -122,24 +121,24 @@ public class LSM303 {
accel.z = Float(((Int16(zhi) << 8) | Int16(zlo)) >> 4) / g

// Read magnetometer
i2c.writeByte(LSM303_ADDRESS_MAG, value: MagRegisters.OUT_X_H_M.rawValue)
let axlo : UInt8 = i2c.readByte(LSM303_ADDRESS_MAG, command: MagRegisters.OUT_X_L_M.rawValue); // Wire.read();
let axhi : UInt8 = i2c.readByte(LSM303_ADDRESS_MAG, command: MagRegisters.OUT_X_H_M.rawValue); // Wire.read();
let aylo : UInt8 = i2c.readByte(LSM303_ADDRESS_MAG, command: MagRegisters.OUT_Y_L_M.rawValue); // Wire.read();
let ayhi : UInt8 = i2c.readByte(LSM303_ADDRESS_MAG, command: MagRegisters.OUT_Y_H_M.rawValue); // Wire.read();
let azlo : UInt8 = i2c.readByte(LSM303_ADDRESS_MAG, command: MagRegisters.OUT_Z_L_M.rawValue); // Wire.read();
let azhi : UInt8 = i2c.readByte(LSM303_ADDRESS_MAG, command: MagRegisters.OUT_Z_H_M.rawValue); // Wire.read();
i2c.writeByte(Address_Mag, value: MagRegisters.Out_X_H_M.rawValue)
let axlo : UInt8 = i2c.readByte(Address_Mag, command: MagRegisters.Out_X_L_M.rawValue); // Wire.read();
let axhi : UInt8 = i2c.readByte(Address_Mag, command: MagRegisters.Out_X_H_M.rawValue); // Wire.read();
let aylo : UInt8 = i2c.readByte(Address_Mag, command: MagRegisters.Out_Y_L_M.rawValue); // Wire.read();
let ayhi : UInt8 = i2c.readByte(Address_Mag, command: MagRegisters.Out_Y_H_M.rawValue); // Wire.read();
let azlo : UInt8 = i2c.readByte(Address_Mag, command: MagRegisters.Out_Z_L_M.rawValue); // Wire.read();
let azhi : UInt8 = i2c.readByte(Address_Mag, command: MagRegisters.Out_Z_H_M.rawValue); // Wire.read();

var mxy : Float = 1.0
var mz : Float = 1.0
switch (self.magGain) {
case .GAIN_1_3 : mxy = 1100.0; mz = 980.0
case .GAIN_1_9 : mxy = 855.0; mz = 760.0
case .GAIN_2_5 : mxy = 670.0; mz = 600.0
case .GAIN_4_0 : mxy = 450.0; mz = 400.0
case .GAIN_4_7 : mxy = 400.0; mz = 355.0
case .GAIN_5_6 : mxy = 330.0; mz = 295.0
case .GAIN_8_1 : mxy = 230.0; mz = 105.0
case .Gain_1_3 : mxy = 1100.0; mz = 980.0 // LSB/gauss
case .Gain_1_9 : mxy = 855.0; mz = 760.0
case .Gain_2_5 : mxy = 670.0; mz = 600.0
case .Gain_4_0 : mxy = 450.0; mz = 400.0
case .Gain_4_7 : mxy = 400.0; mz = 355.0
case .Gain_5_6 : mxy = 330.0; mz = 295.0
case .Gain_8_1 : mxy = 230.0; mz = 205.0
}
mag.x = Float((Int16(axhi) << 8) | Int16(axlo)) / mxy
mag.y = Float((Int16(ayhi) << 8) | Int16(aylo)) / mxy
Expand All @@ -148,11 +147,11 @@ public class LSM303 {

public func setMagGain(gain: MagGain) {
self.magGain = gain
i2c.writeByte(LSM303_ADDRESS_MAG, command: MagRegisters.CRB_REG_M.rawValue, value: gain.rawValue)
i2c.writeByte(Address_Mag, command: MagRegisters.CRB_Reg_M.rawValue, value: gain.rawValue)
}

public func setAccScale(scale: AccelScale) {
self.accScale = scale
i2c.writeByte(LSM303_ADDRESS_ACCEL, command: AccelRegisters.CTRL_REG4_A.rawValue, value: scale.rawValue)
i2c.writeByte(Address_Acc, command: AccelRegisters.Ctrl_Reg4_A.rawValue, value: scale.rawValue)
}
}

0 comments on commit 11ae6a4

Please sign in to comment.