initial code for i2c communication with accelerometers
Dependencies: BLE_API mbed-dev nRF51822
Fork of capstone_i2c by
Diff: main.cpp
- Revision:
- 0:6a249a5be3a4
- Child:
- 1:e2ba28405dd5
diff -r 000000000000 -r 6a249a5be3a4 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Apr 04 03:17:10 2017 +0000 @@ -0,0 +1,221 @@ +/* + +Copyright (c) 2012-2014 RedBearLab + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include "mbed.h" +#include "wire.h" + +#define BLE_Nano +//#define nRF_51822 + + +#ifdef nRF_51822 +#define SCL 28 +#define SDA 29 +#endif + +#ifdef BLE_Nano +#define SCL 7 +#define SDA 6 +#endif + +#define DEV_ADDR 0xA0 +#define ADDR_ONE 0x19 +#define ADDR_TWO 0x18 +#define AXIS_X 0x00 +#define AXIS_Y 0x01 +#define AXIS_Z 0x02 +#define REG_OUT_X_L 0x28 +#define REG_CTRL1 0x20 +#define REG_CTRL4 0x23 +#define RANGE_2G 0x00 + + +#define DATARATE_400HZ 0b0111 // 400Hz +#define DATARATE_200HZ 0b0110 // 200Hz +#define DATARATE_100HZ 0b0101 // 100Hz +#define DATARATE_50HZ 0b0100 // 50Hz +#define DATARATE_25HZ 0b0011 // 25Hz +#define DATARATE_10HZ 0b0010 // 10Hz +#define DATARATE_1HZ 0b0001 // 1Hz +#define DATARATE_POWERDOWN 0 // Power down +#define DATARATE_LOWPOWER_1K6HZ 0b1000 // Low power mode (1.6KHz) +#define DATARATE_LOWPOWER_5KHZ 0b1001 // Low power mode (5KHz) / Normal power mode (1.25KHz) + +Serial pc(USBTX, USBRX); +TwoWire Wire = TwoWire(NRF_TWI0); + +void AT24C512_WriteBytes(uint16_t addr, uint8_t *pbuf, uint16_t length, uint16_t i2cAddr) +{ + Wire.beginTransmission(i2cAddr); + Wire.write( (uint8_t)addr>>8 ); + Wire.write( (uint8_t)addr ); + Wire.write(pbuf, length); + Wire.endTransmission(); +} + +void AT24C512_ReadBytes(uint16_t addr, uint8_t *pbuf, uint16_t length, uint16_t i2cAddr) +{ + Wire.beginTransmission(i2cAddr); + Wire.write( (uint8_t)addr>>8 ); + Wire.write( (uint8_t)addr ); + Wire.endTransmission(); + + Wire.requestFrom(i2cAddr+1, length); + while( Wire.available() > 0 ) + { + *pbuf = Wire.read(); + pbuf++; + } +} + +//Set the bit at index 'bit' to 'value' on 'input' and return +uint8_t setBit(uint8_t input, uint8_t bit, uint8_t value) { + uint8_t mask = 1 << bit; + input &= ~mask; + if (value == 1) { + input |= mask; + } + return input; +} + +uint16_t getAxis(uint16_t axis, uint16_t i2cAddr) +{ + uint8_t base = REG_OUT_X_L + (2 * axis); + uint8_t* low = new uint8_t[1]; + uint8_t* high = new uint8_t[1]; + AT24C512_ReadBytes(base, low, 1, i2cAddr); + AT24C512_ReadBytes(base + 1, high, 1, i2cAddr); + uint16_t res = low[0] | (high[0] << 8); + return res; +} + +void setRange(uint8_t range, uint16_t i2cAddr) { + uint8_t* val = new uint8_t[1]; + AT24C512_ReadBytes(REG_CTRL4, val, 1, i2cAddr);//get value from the register + val[0] &= ~(0b110000); //zero out lowest 4 bits + val[0] |= (range << 4); // write in our new range + AT24C512_WriteBytes(REG_CTRL4, val, 1, i2cAddr); +} + +//Set whether we want to use high resolution or not +void setHighResolution(bool highRes, uint16_t i2cAddr) { + uint8_t* val = new uint8_t[1]; + AT24C512_ReadBytes(REG_CTRL4, val, 1, i2cAddr);//get value from the register + uint8_t final; + if (highRes) { + final = setBit(val[0], 3, 1); + } else { + final = setBit(val[0], 3, 1); + } + val[0] = final; + AT24C512_WriteBytes(REG_CTRL4, val, 1, i2cAddr); +} + +void setAxisStatus(uint8_t axis, bool enable, uint16_t i2cAddr) { + uint8_t* current = new uint8_t[1]; + AT24C512_ReadBytes(REG_CTRL1, current, 1, i2cAddr);//get value from the register + uint8_t final; + if (enable == 1) { + final = setBit(current[0], axis, 1); + } else { + final = setBit(current[0], axis, 0); + } + current[0] = final; + AT24C512_WriteBytes(REG_CTRL1, current, 1, i2cAddr); +} + +void setDataRate(uint8_t dataRate, uint16_t i2cAddr) { + uint8_t* val = new uint8_t[1]; + AT24C512_ReadBytes(REG_CTRL1, val, 1, i2cAddr); + val[0] &= 0b1111; //mask off lower bits + val[0] |= (dataRate << 4); + AT24C512_WriteBytes(REG_CTRL1, val, 1, i2cAddr); +} + +void setBDU(bool bdu, uint16_t i2cAddr) +{ + uint8_t* val = new uint8_t[1]; + AT24C512_ReadBytes(REG_CTRL4, val, 1, i2cAddr);//get value from the register + uint8_t final; + if (bdu == true) { + final = setBit(val[0], 7, 1); + } else { + final = setBit(val[0], 7, 1); + } + val[0] = final; + AT24C512_WriteBytes(REG_CTRL4, val, 1, i2cAddr); +} + +uint16_t getX(uint16_t i2cAddr) +{ + return getAxis(AXIS_X, i2cAddr); +} + +uint16_t getY(uint16_t i2cAddr) +{ + return getAxis(AXIS_Y, i2cAddr); +} + +uint16_t getZ(uint16_t i2cAddr) +{ + return getAxis(AXIS_Z, i2cAddr); +} + +int main(void) +{ + pc.baud(9600); + wait(5); + //Wire.begin(); + Wire.begin(SCL, SDA, TWI_FREQUENCY_100K); + pc.printf("IIC Demo Start \r\n"); + + setAxisStatus(AXIS_X, true, ADDR_ONE); + setAxisStatus(AXIS_Y, true, ADDR_ONE); + setAxisStatus(AXIS_Z, true, ADDR_ONE); + setDataRate(DATARATE_400HZ, ADDR_ONE); + setHighResolution(true, ADDR_ONE); + setBDU(true, ADDR_ONE); + setRange(RANGE_2G, ADDR_ONE); + + setAxisStatus(AXIS_X, true, ADDR_TWO); + setAxisStatus(AXIS_Y, true, ADDR_TWO); + setAxisStatus(AXIS_Z, true, ADDR_TWO); + setDataRate(DATARATE_400HZ, ADDR_ONE); + setHighResolution(true, ADDR_TWO); + setBDU(true, ADDR_TWO); + setRange(RANGE_2G, ADDR_TWO); + + wait(0.1); + + while(1) + { + pc.printf("Read data from AT24C512 \r\n"); + uint16_t x1 = getX(ADDR_ONE); + uint16_t y1 = getY(ADDR_ONE); + uint16_t z1 = getZ(ADDR_ONE); + + uint16_t x2 = getX(ADDR_TWO); + uint16_t y2 = getY(ADDR_TWO); + uint16_t z2 = getZ(ADDR_TWO); + pc.printf("Accel one: x %d y %d z %d\r\n", x1, y1, z1); + pc.printf("Accel two: x %d y %d z %d\r\n", x2, y2, z2); + pc.printf("\r\n"); + wait(1); + } +}