Start of a microbit mpr121 library
Dependents: microbitmpr121-example
Diff: MicroBitMpr121.cpp
- Revision:
- 4:f63476855239
- Parent:
- 3:a91b1bb396ca
- Child:
- 5:4a8384331ca7
--- a/MicroBitMpr121.cpp Mon Jan 16 14:31:36 2017 +0000 +++ b/MicroBitMpr121.cpp Mon Jan 16 19:19:50 2017 +0000 @@ -1,128 +1,218 @@ -#include "MicroBit.h" -#include "MicroBitI2C.h" -#include "MicroBitMpr121.h" +/* +The MIT License (MIT) + +Copyright (c) 2016 British Broadcasting Corporation. +This software is provided by Lancaster University by arrangement with the BBC. -#define DEBUG 1 +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. +*/ -//MicroBitMpr121::MicroBitMpr121(PinName sda, PinName scl, PinName irq, MPR121_ADDR addr) -MicroBitMpr121::MicroBitMpr121() +/** + * Class definition for MicroBit Mpr121. + * + * Represents an implementation of the Mpr121. + * Also includes ... + */ +#include "MicroBitConfig.h" +#include "MicroBitPin.h" +#include "MicroBitMpr121.h" +#include "MicroBitFiber.h" +#include "ErrorNo.h" + +/** + * An initialisation member function. + * + * @param id the unique identifier for this instance. + * + * @param address the base address on the i2c bus. + */ +void MicroBitMpr121::init(uint16_t id, uint16_t address) { - MicroBitI2C::I2C _i2c(I2C_SDA0, I2C_SCL0); - uint8_t addr = ADDR_SDA; -// PinName _irq = irq; //TODO :: use - uint8_t _i2c_addr = (addr << 1); // To get 8bit address ...? - return; + this->id = id; + this->address = address; + + // Indicate that we're up and running. + status |= MICROBIT_COMPONENT_RUNNING; } -void MicroBitMpr121::init(void) +/** + * Constructor. + * Create a software representation. + * + * @param _i2c an instance of i2c + * + * @param address the address register on the i2c bus. Defaults to MPR121_DEFAULT_ADDR. + * + * @param id the ID of the new object. Defaults to MPR121_DEFAULT_ADDR. + * + * @code + * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); + * + * MicroBitMpr121 mpr121(i2c); + * @endcode + */ +MicroBitMpr121::MicroBitMpr121(MicroBitI2C& _i2c, uint16_t address, uint16_t id) : + int1(MICROBIT_PIN_P16), + i2c(_i2c) + { - // P16.setPull(PullUp); //TODO use _irq and not hard code - MicroBitMpr121::write(SRST, 0x63); - MicroBitMpr121::write(MHDR, 0x1); - MicroBitMpr121::write(NHDR, 0x1); - MicroBitMpr121::write(NCLR, 0x0); - MicroBitMpr121::write(FDLR, 0x0); - MicroBitMpr121::write(MHDF, 0x1); - MicroBitMpr121::write(NHDF, 0x1); - MicroBitMpr121::write(NCLF, 0xFF); - MicroBitMpr121::write(FDLF, 0x2); - for(int i=0; i<(12*2); i+=2) { - MicroBitMpr121::write(static_cast<MPR121_REGISTER>(E0TTH+i), 0x20); - } - for(int i=0; i<(12*2); i+=2) { - MicroBitMpr121::write(static_cast<MPR121_REGISTER>(E0RTH+i), 0x10); - } - MicroBitMpr121::write(DT_DR, 0x11); - MicroBitMpr121::write(CDC_CONFIG, 0x10); - MicroBitMpr121::write(CDT_CONFIG, 0x20); - MicroBitMpr121::write(AUTO_CFG0, 0x33); - MicroBitMpr121::write(AUTO_CFG1, 0x07); - MicroBitMpr121::write(USL, 0xc9); - MicroBitMpr121::write(LSL, 0x83); - MicroBitMpr121::write(TL, 0xb5); - MicroBitMpr121::write(ECR, 0x8f); - return; + init(id, address); } -void MicroBitMpr121::enable(void) +/** + * Issues a standard, 2 byte I2C command write. + * + * Blocks the calling thread until complete. + * + * @param reg The address of the register to write to. + * + * @param value The value to write. + * + * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed. + */ +int MicroBitMpr121::writeCommand(uint8_t reg, uint8_t value) { - _button = 0; - _button_has_changed = 0; - MicroBitMpr121::write(ECR, 0x8f); - //TODO _irq->fall(this, &MicroBitMpr121::handler); - return; + uint8_t command[2]; + command[0] = reg; + command[1] = value; + + return i2c.write(address, (const char *)command, 2); } -void MicroBitMpr121::disable(void) +/** + * Issues a read command, copying data into the specified buffer. + * + * Blocks the calling thread until complete. + * + * @param reg The address of the register to access. + * + * @param buffer Memory area to read the data into. + * + * @param length The number of bytes to read. + * + * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed. + */ +int MicroBitMpr121::readCommand(uint8_t reg, uint8_t* buffer, int length) { - //TODO _irq->fall(NULL); - _button = 0; - _button_has_changed = 0; - MicroBitMpr121::write(ECR, 0x0); - MicroBitMpr121::write(AUTO_CFG0, 0x0); - MicroBitMpr121::write(AUTO_CFG1, 0x0); - return; -} + int result; + + if (buffer == NULL || length <= 0) + return MICROBIT_INVALID_PARAMETER; -uint32_t MicroBitMpr121::isPressed(void) -{ - return _button_has_changed; + result = i2c.write(address, (const char *)®, 1, true); + if (result !=0) + return MICROBIT_I2C_ERROR; + + result = i2c.read(address, (char *)buffer, length); + if (result !=0) + return MICROBIT_I2C_ERROR; + + return MICROBIT_OK; } -uint16_t MicroBitMpr121::buttonPressed(void) -{ - _button_has_changed = 0; - return _button; -} - -void MicroBitMpr121::registerDump() const +/** + * Issues a read of a given address, and returns the value. + * + * Blocks the calling thread until complete. + * + * @param reg The address of the 16 bit register to access. + * + * @return The register value, interpreted as a 16 but signed value, or MICROBIT_I2C_ERROR if the read request failed. + */ +int MicroBitMpr121::read16(uint8_t reg) { - uint8_t reg_val = 0; + uint8_t cmd[2]; + int result; + + cmd[0] = reg; + result = i2c.write(address, (const char *)cmd, 1); + if (result !=0) + return MICROBIT_I2C_ERROR; - for(int i=0; i<0x80; i++) { - reg_val = MicroBitMpr121::read(static_cast<MPR121_REGISTER>(i)); - printf("Reg 0x%02x: 0x%02x \n", i, reg_val); - } + cmd[0] = 0x00; + cmd[1] = 0x00; - return; + result = i2c.read(address, (char *)cmd, 2); + if (result !=0) + return MICROBIT_I2C_ERROR; + + return (int16_t) ((cmd[1] | (cmd[0] << 8))); //concatenate the MSB and LSB } -void MicroBitMpr121::handler(void) +/** + * Issues a read of a given address, and returns the value. + * + * Blocks the calling thread until complete. + * + * @param reg The address of the 16 bit register to access. + * + * @return The register value, interpreted as a 8 bit unsigned value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed. + */ +int MicroBitMpr121::read8(uint8_t reg) { - uint16_t reg_val = 0, oor_val = 0; - reg_val = MicroBitMpr121::read(ELE0_7_STAT); - reg_val |= MicroBitMpr121::read(ELE8_11_STAT) << 8; - oor_val = MicroBitMpr121::read(ELE0_7_OOR_STAT); - oor_val |= MicroBitMpr121::read(ELE8_11_OOR_STAT) << 8; - if((0 != oor_val) && DEBUG) { - printf("MPR121 OOR failure - 0x%04x\n", oor_val); - wait(0.1f); - NVIC_SystemReset(); - } - _button = reg_val; - _button_has_changed = 1; - return; + uint8_t data; + int result; + + data = 0; + result = readCommand(reg, (uint8_t*) &data, 1); + if (result != MICROBIT_OK) + return MICROBIT_I2C_ERROR; + + return data; } -void MicroBitMpr121::write(MPR121_REGISTER const reg, uint8_t const data) const +/** + * Periodic callback from MicroBit idle thread. + * + * Calls ... + */ +void MicroBitMpr121::idleTick() { - char buf[2] = {reg, data}; - uint8_t result = 0; - result = _i2c.write(_i2c_addr, buf, 2); - if(result && DEBUG) { - printf("I2c write failed\n"); - } - return; + } -uint8_t MicroBitMpr121::read(MPR121_REGISTER const reg) const +/** + * Attempts to read the 8 bit ID from the mpr121, this can be used for + * validation purposes. TODO? + * + * @return the 8 bit ID returned by the mpr121, or MICROBIT_I2C_ERROR if the request fails. + * + * @code + * compass.whoAmI(); + * @endcode + */ +int MicroBitMpr121::whoAmI() { - char buf[1] = {reg}, data = 0; - uint8_t result = 1; - result &= _i2c.write(_i2c_addr, buf, 1, true); //TODO: Correct with true? - result &= _i2c.read(_i2c_addr, &data, 1); - if(result && DEBUG) { - printf("I2c read failed\n"); - } - return data; + uint8_t data; + int result; + + // result = readCommand(MAG_WHOAMI, &data, 1); + if (result != MICROBIT_OK) + return MICROBIT_I2C_ERROR; + + return (int)data; } + +/** + * Destructor, where we deregister this instance from the array of fiber components. + */ +MicroBitMpr121::~MicroBitMpr121() +{ + fiber_remove_idle_component(this); +}