Extension of original I2CSlave library to support multiple slave addresses and interrupts.
Revision 0:f94c714b3b4d, committed 2014-07-12
- Comitter:
- jaerts
- Date:
- Sat Jul 12 15:09:06 2014 +0000
- Child:
- 1:b7e586fffbf2
- Commit message:
- Initial version
Changed in this revision
I2CSlaveX.cpp | Show annotated file Show diff for this revision Revisions of this file |
I2CSlaveX.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2CSlaveX.cpp Sat Jul 12 15:09:06 2014 +0000 @@ -0,0 +1,63 @@ +#include "I2CSlaveX.h" + +#if DEVICE_I2CSLAVE + +namespace mbed { + +I2CSlaveX* instance; + +I2CSlaveX::I2CSlaveX(PinName sda, PinName scl) : I2CSlave(sda, scl) { + +} + +// Add optional index argument for slaves that accept multiple addresses +void I2CSlaveX::address(int address, int idx) { + int addr = (address & 0xFF) | 1; + i2c_slave_address(&_i2c, idx, addr, 0); +} + +// Add optional argument that will be set with the received data value (usually slave address) +int I2CSlaveX::receive(char *data) { + if(data) { + *data = _i2c.i2c->DAT; + } + return i2c_slave_receive(&_i2c); +} + +// Return read length rather than match/no match +int I2CSlaveX::read(char *data, int length) { + return i2c_slave_read(&_i2c, data, length); +} + +// Return write length rather than match/no match +int I2CSlaveX::write(const char *data, int length) { + return i2c_slave_write(&_i2c, data, length); +} + +void I2CSlaveX::attach(void (*fptr)(void)) { + if (fptr) { + _receive.attach(fptr); + enable_irq(); + } else { + disable_irq(); + } +} + +void I2CSlaveX::_irq_handler(uint32_t id, uint8_t addr, uint8_t state) { + instance->_receive.call(); +} + +void I2CSlaveX::enable_irq() { + // Hacky way to call this instance + instance = this; + NVIC_SetVector(I2C_IRQn, (uint32_t)(&I2CSlaveX::_irq_handler)); + NVIC_EnableIRQ(I2C_IRQn); +} + +void I2CSlaveX::disable_irq() { + NVIC_DisableIRQ(I2C_IRQn); +} + +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2CSlaveX.h Sat Jul 12 15:09:06 2014 +0000 @@ -0,0 +1,102 @@ +#ifndef MBED_I2CSLAVEX_H +#define MBED_I2CSLAVEX_H + +#include "mbed.h" + +namespace mbed { + +/** An I2C Slave, used for communicating with an I2C Master device with support for Interrupts and multiple slave addresses + * + * Example: + * @code + * TBD EXAMPLE + * @endcode + */ +class I2CSlaveX : public I2CSlave +{ +public: + /** Create an I2C Slave interface, connected to the specified pins. + * + * @param sda I2C data line pin + * @param scl I2C clock line pin + */ + I2CSlaveX(PinName sda, PinName scl); + + /** Checks to see if this I2C Slave has been addressed. + * + * @returns + * A status indicating if the device has been addressed, and how + * - NoData - the slave has not been addressed + * - ReadAddressed - the master has requested a read from this slave + * - WriteAddressed - the master is writing to this slave + * - WriteGeneral - the master is writing to all slave + */ + int receive(char *data = NULL); + + /** Read from an I2C master. + * + * @param data pointer to the byte array to read data in to + * @param length maximum number of bytes to read + * + * @returns + * 0 on success, + * non-0 otherwise + */ + int read(char *data, int length); + + /** Write to an I2C master. + * + * @param data pointer to the byte array to be transmitted + * @param length the number of bytes to transmite + * + * @returns + * 0 on success, + * non-0 otherwise + */ + int write(const char *data, int length); + + /** Sets the I2C slave address. + * + * @param address The address to set for the slave (ignoring the least + * signifcant bit). If set to 0, the slave will only respond to the + * general call address. + */ + void address(int address, int idx = 0); + + /** Attach a function to call when state changed event occured on the I2C peripheral + * + * @param fptr A pointer to a void function, or 0 to set as none + */ + void attach(void (*fptr)(void)); + + /** Attach a member function to call when state changed event occured on the I2C peripheral + * + * @param tptr pointer to the object to call the member function on + * @param mptr pointer to the member function to be called + */ + template<typename T> + void attach(T* tptr, void (T::*mptr)(void)) { + _receive.attach(tptr, mptr); + enable_irq(); + } + + /** Enable IRQ. This method depends on hw implementation, might enable one + * port interrupts. For further information, check gpio_irq_enable(). + */ + void enable_irq(); + + /** Disable IRQ. This method depends on hw implementation, might disable one + * port interrupts. For further information, check gpio_irq_disable(). + */ + void disable_irq(); + + static void _irq_handler(uint32_t id, uint8_t addr, uint8_t state); + +protected: + FunctionPointer _receive; + +}; + +} + +#endif