mbed.org local branch of microbit-dal. The real version lives in git at https://github.com/lancaster-university/microbit-dal

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit Microbit IoTChallenge1 microbit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitI2C.cpp Source File

MicroBitI2C.cpp

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 #include "MicroBitConfig.h"
00027 #include "MicroBitI2C.h"
00028 #include "ErrorNo.h"
00029 #include "twi_master.h"
00030 #include "nrf_delay.h"
00031 
00032 /**
00033   * Constructor.
00034   *
00035   * Create an instance of MicroBitI2C for I2C communication.
00036   *
00037   * @param sda the Pin to be used for SDA
00038   *
00039   * @param scl the Pin to be used for SCL
00040   *
00041   * @code
00042   * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
00043   * @endcode
00044   *
00045   * @note This class presents a wrapped mbed call to capture failed I2C operations caused by a known silicon bug in the nrf51822.
00046   * Attempts to automatically reset and restart the I2C hardware if this case is detected.
00047   * \par
00048   * For reference see PAN56 in:
00049   * \par
00050   * https://www.nordicsemi.com/eng/nordic/Products/nRF51822/PAN-nRF51822/24634
00051   * \par
00052   * v2.0 through to v2.4
00053   */
00054 MicroBitI2C::MicroBitI2C(PinName sda, PinName scl) : I2C(sda,scl)
00055 {
00056     this->retries = 0;
00057 }
00058 
00059 /**
00060   * Performs a complete read transaction. The bottom bit of the address is forced to 1 to indicate a read.
00061   *
00062   * @param address 8-bit I2C slave address [ addr | 1 ]
00063   *
00064   * @param data A pointer to a byte buffer used for storing retrieved data.
00065   *
00066   * @param length Number of bytes to read.
00067   *
00068   * @param repeated if true, stop is not sent at the end. Defaults to false.
00069   *
00070   * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if an unresolved read failure is detected.
00071   */
00072 int MicroBitI2C::read(int address, char *data, int length, bool repeated)
00073 {
00074     int result = I2C::read(address,data,length,repeated);
00075 
00076     //0 indicates a success, presume failure
00077     while(result != 0 && retries < MICROBIT_I2C_MAX_RETRIES)
00078     {
00079         _i2c.i2c->EVENTS_ERROR = 0;
00080         _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
00081         _i2c.i2c->POWER        = 0;
00082         nrf_delay_us(5);
00083         _i2c.i2c->POWER        = 1;
00084         _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
00085         twi_master_init_and_clear();
00086         result = I2C::read(address,data,length,repeated);
00087         retries++;
00088     }
00089 
00090     if(result != 0)
00091         return MICROBIT_I2C_ERROR;
00092 
00093     retries = 0;
00094     return MICROBIT_OK;
00095 }
00096 
00097 /**
00098   * Performs a complete write transaction. The bottom bit of the address is forced to 0 to indicate a write.
00099   *
00100   * @param address 8-bit I2C slave address [ addr | 0 ]
00101   *
00102   * @param data A pointer to a byte buffer containing the data to write.
00103   *
00104   * @param length Number of bytes to write
00105   *
00106   * @param repeated if true, stop is not sent at the end. Defaults to false.
00107   *
00108   * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if an unresolved write failure is detected.
00109   */
00110 int MicroBitI2C::write(int address, const char *data, int length, bool repeated)
00111 {
00112     int result = I2C::write(address,data,length,repeated);
00113 
00114     //0 indicates a success, presume failure
00115     while(result != 0 && retries < MICROBIT_I2C_MAX_RETRIES)
00116     {
00117         _i2c.i2c->EVENTS_ERROR = 0;
00118         _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
00119         _i2c.i2c->POWER        = 0;
00120         nrf_delay_us(5);
00121         _i2c.i2c->POWER        = 1;
00122         _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
00123 
00124         twi_master_init_and_clear();
00125         result = I2C::write(address,data,length,repeated);
00126         retries++;
00127     }
00128 
00129     if(result != 0)
00130         return MICROBIT_I2C_ERROR;
00131 
00132     retries = 0;
00133     return MICROBIT_OK;
00134 }