Extension of original I2CSlave library to support multiple slave addresses and interrupts.

Committer:
jaerts
Date:
Sat Jul 12 15:26:34 2014 +0000
Revision:
1:b7e586fffbf2
Parent:
0:f94c714b3b4d
Update example code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jaerts 0:f94c714b3b4d 1 #ifndef MBED_I2CSLAVEX_H
jaerts 0:f94c714b3b4d 2 #define MBED_I2CSLAVEX_H
jaerts 0:f94c714b3b4d 3
jaerts 0:f94c714b3b4d 4 #include "mbed.h"
jaerts 0:f94c714b3b4d 5
jaerts 0:f94c714b3b4d 6 namespace mbed {
jaerts 0:f94c714b3b4d 7
jaerts 0:f94c714b3b4d 8 /** An I2C Slave, used for communicating with an I2C Master device with support for Interrupts and multiple slave addresses
jaerts 0:f94c714b3b4d 9 *
jaerts 1:b7e586fffbf2 10 * Warning: Currently only somewhat tested with LPC1347. This should be concidered a proof of concept. Ideally this would
jaerts 1:b7e586fffbf2 11 * be merged into the original I2CSlave library.
jaerts 1:b7e586fffbf2 12 *
jaerts 0:f94c714b3b4d 13 * Example:
jaerts 0:f94c714b3b4d 14 * @code
jaerts 1:b7e586fffbf2 15 * // Simple Simulated I2C Read-Only EEPROM
jaerts 1:b7e586fffbf2 16 * #include <mbed.h>
jaerts 1:b7e586fffbf2 17 * #include "I2CSlaveX.h"
jaerts 1:b7e586fffbf2 18 *
jaerts 1:b7e586fffbf2 19 * I2CSlaveX slave(p9, p10);
jaerts 1:b7e586fffbf2 20 *
jaerts 1:b7e586fffbf2 21 * uint8_t eeprom_data[16] = {0);
jaerts 1:b7e586fffbf2 22 * uint8_t eeprom_addr = 0;
jaerts 1:b7e586fffbf2 23 *
jaerts 1:b7e586fffbf2 24 * void receive_handler() {
jaerts 1:b7e586fffbf2 25 * char addr;
jaerts 1:b7e586fffbf2 26 * int i = slave.receive(&addr);
jaerts 1:b7e586fffbf2 27 * switch (i) {
jaerts 1:b7e586fffbf2 28 * case I2CSlave::ReadAddressed:
jaerts 1:b7e586fffbf2 29 * slave.write(&eeprom_data[eeprom_addr], 1);
jaerts 1:b7e586fffbf2 30 * printf("Write @ %02X [%02X] : %02X\n", addr, eeprom_addr, eeprom_data[eeprom_addr]);
jaerts 1:b7e586fffbf2 31 * break;
jaerts 1:b7e586fffbf2 32 * case I2CSlave::WriteAddressed:
jaerts 1:b7e586fffbf2 33 * slave.read(&eeprom_addr, 1);
jaerts 1:b7e586fffbf2 34 * printf("Read @ %02X [%02X]\n", addr, eeprom_addr);
jaerts 1:b7e586fffbf2 35 * break;
jaerts 1:b7e586fffbf2 36 * }
jaerts 1:b7e586fffbf2 37 * }
jaerts 1:b7e586fffbf2 38 *
jaerts 1:b7e586fffbf2 39 * int main() {
jaerts 1:b7e586fffbf2 40 * slave.address(0xA0, 0);
jaerts 1:b7e586fffbf2 41 * slave.address(0x30, 1);
jaerts 1:b7e586fffbf2 42 * slave.attach(&receive_handler);
jaerts 1:b7e586fffbf2 43 *
jaerts 1:b7e586fffbf2 44 * while(1) {
jaerts 1:b7e586fffbf2 45 * printf("Nothing to do really...");
jaerts 1:b7e586fffbf2 46 * eeprom_data[0]++;
jaerts 1:b7e586fffbf2 47 * wait(1);
jaerts 1:b7e586fffbf2 48 * }
jaerts 1:b7e586fffbf2 49 * }
jaerts 0:f94c714b3b4d 50 * @endcode
jaerts 0:f94c714b3b4d 51 */
jaerts 0:f94c714b3b4d 52 class I2CSlaveX : public I2CSlave
jaerts 0:f94c714b3b4d 53 {
jaerts 0:f94c714b3b4d 54 public:
jaerts 0:f94c714b3b4d 55 /** Create an I2C Slave interface, connected to the specified pins.
jaerts 0:f94c714b3b4d 56 *
jaerts 0:f94c714b3b4d 57 * @param sda I2C data line pin
jaerts 0:f94c714b3b4d 58 * @param scl I2C clock line pin
jaerts 0:f94c714b3b4d 59 */
jaerts 0:f94c714b3b4d 60 I2CSlaveX(PinName sda, PinName scl);
jaerts 0:f94c714b3b4d 61
jaerts 0:f94c714b3b4d 62 /** Checks to see if this I2C Slave has been addressed.
jaerts 0:f94c714b3b4d 63 *
jaerts 0:f94c714b3b4d 64 * @returns
jaerts 0:f94c714b3b4d 65 * A status indicating if the device has been addressed, and how
jaerts 0:f94c714b3b4d 66 * - NoData - the slave has not been addressed
jaerts 0:f94c714b3b4d 67 * - ReadAddressed - the master has requested a read from this slave
jaerts 0:f94c714b3b4d 68 * - WriteAddressed - the master is writing to this slave
jaerts 0:f94c714b3b4d 69 * - WriteGeneral - the master is writing to all slave
jaerts 0:f94c714b3b4d 70 */
jaerts 0:f94c714b3b4d 71 int receive(char *data = NULL);
jaerts 0:f94c714b3b4d 72
jaerts 0:f94c714b3b4d 73 /** Read from an I2C master.
jaerts 0:f94c714b3b4d 74 *
jaerts 0:f94c714b3b4d 75 * @param data pointer to the byte array to read data in to
jaerts 0:f94c714b3b4d 76 * @param length maximum number of bytes to read
jaerts 0:f94c714b3b4d 77 *
jaerts 0:f94c714b3b4d 78 * @returns
jaerts 0:f94c714b3b4d 79 * 0 on success,
jaerts 0:f94c714b3b4d 80 * non-0 otherwise
jaerts 0:f94c714b3b4d 81 */
jaerts 0:f94c714b3b4d 82 int read(char *data, int length);
jaerts 0:f94c714b3b4d 83
jaerts 0:f94c714b3b4d 84 /** Write to an I2C master.
jaerts 0:f94c714b3b4d 85 *
jaerts 0:f94c714b3b4d 86 * @param data pointer to the byte array to be transmitted
jaerts 0:f94c714b3b4d 87 * @param length the number of bytes to transmite
jaerts 0:f94c714b3b4d 88 *
jaerts 0:f94c714b3b4d 89 * @returns
jaerts 0:f94c714b3b4d 90 * 0 on success,
jaerts 0:f94c714b3b4d 91 * non-0 otherwise
jaerts 0:f94c714b3b4d 92 */
jaerts 0:f94c714b3b4d 93 int write(const char *data, int length);
jaerts 0:f94c714b3b4d 94
jaerts 0:f94c714b3b4d 95 /** Sets the I2C slave address.
jaerts 0:f94c714b3b4d 96 *
jaerts 0:f94c714b3b4d 97 * @param address The address to set for the slave (ignoring the least
jaerts 0:f94c714b3b4d 98 * signifcant bit). If set to 0, the slave will only respond to the
jaerts 0:f94c714b3b4d 99 * general call address.
jaerts 0:f94c714b3b4d 100 */
jaerts 0:f94c714b3b4d 101 void address(int address, int idx = 0);
jaerts 0:f94c714b3b4d 102
jaerts 0:f94c714b3b4d 103 /** Attach a function to call when state changed event occured on the I2C peripheral
jaerts 0:f94c714b3b4d 104 *
jaerts 0:f94c714b3b4d 105 * @param fptr A pointer to a void function, or 0 to set as none
jaerts 0:f94c714b3b4d 106 */
jaerts 0:f94c714b3b4d 107 void attach(void (*fptr)(void));
jaerts 0:f94c714b3b4d 108
jaerts 0:f94c714b3b4d 109 /** Attach a member function to call when state changed event occured on the I2C peripheral
jaerts 0:f94c714b3b4d 110 *
jaerts 0:f94c714b3b4d 111 * @param tptr pointer to the object to call the member function on
jaerts 0:f94c714b3b4d 112 * @param mptr pointer to the member function to be called
jaerts 0:f94c714b3b4d 113 */
jaerts 0:f94c714b3b4d 114 template<typename T>
jaerts 0:f94c714b3b4d 115 void attach(T* tptr, void (T::*mptr)(void)) {
jaerts 0:f94c714b3b4d 116 _receive.attach(tptr, mptr);
jaerts 0:f94c714b3b4d 117 enable_irq();
jaerts 0:f94c714b3b4d 118 }
jaerts 0:f94c714b3b4d 119
jaerts 0:f94c714b3b4d 120 /** Enable IRQ. This method depends on hw implementation, might enable one
jaerts 0:f94c714b3b4d 121 * port interrupts. For further information, check gpio_irq_enable().
jaerts 0:f94c714b3b4d 122 */
jaerts 0:f94c714b3b4d 123 void enable_irq();
jaerts 0:f94c714b3b4d 124
jaerts 0:f94c714b3b4d 125 /** Disable IRQ. This method depends on hw implementation, might disable one
jaerts 0:f94c714b3b4d 126 * port interrupts. For further information, check gpio_irq_disable().
jaerts 0:f94c714b3b4d 127 */
jaerts 0:f94c714b3b4d 128 void disable_irq();
jaerts 0:f94c714b3b4d 129
jaerts 0:f94c714b3b4d 130 static void _irq_handler(uint32_t id, uint8_t addr, uint8_t state);
jaerts 0:f94c714b3b4d 131
jaerts 0:f94c714b3b4d 132 protected:
jaerts 0:f94c714b3b4d 133 FunctionPointer _receive;
jaerts 0:f94c714b3b4d 134
jaerts 0:f94c714b3b4d 135 };
jaerts 0:f94c714b3b4d 136
jaerts 0:f94c714b3b4d 137 }
jaerts 0:f94c714b3b4d 138
jaerts 0:f94c714b3b4d 139 #endif