Complete PCF8574 and PCF74A library with interrupt handling
Dependents: Nucleo_PCF8574_led_iic Dawson_Controller
PCF8574.h@0:6d75da25c179, 2012-07-14 (annotated)
- Committer:
- bborredon
- Date:
- Sat Jul 14 08:20:07 2012 +0000
- Revision:
- 0:6d75da25c179
[mbed] converted /I2c/PCF8574
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bborredon | 0:6d75da25c179 | 1 | #ifndef PCF8574__H_ |
bborredon | 0:6d75da25c179 | 2 | #define PCF8574__H_ |
bborredon | 0:6d75da25c179 | 3 | |
bborredon | 0:6d75da25c179 | 4 | // Includes |
bborredon | 0:6d75da25c179 | 5 | #include <string> |
bborredon | 0:6d75da25c179 | 6 | #include <bitset> |
bborredon | 0:6d75da25c179 | 7 | |
bborredon | 0:6d75da25c179 | 8 | #include "mbed.h" |
bborredon | 0:6d75da25c179 | 9 | |
bborredon | 0:6d75da25c179 | 10 | // Example |
bborredon | 0:6d75da25c179 | 11 | /* |
bborredon | 0:6d75da25c179 | 12 | #include <string> |
bborredon | 0:6d75da25c179 | 13 | |
bborredon | 0:6d75da25c179 | 14 | #include "mbed.h" |
bborredon | 0:6d75da25c179 | 15 | #include "PCF8574.h" |
bborredon | 0:6d75da25c179 | 16 | |
bborredon | 0:6d75da25c179 | 17 | #define PCF8574_ADDR 0 // I2c PCF8574 address is 0x00 |
bborredon | 0:6d75da25c179 | 18 | |
bborredon | 0:6d75da25c179 | 19 | static void myerror(std::string msg) |
bborredon | 0:6d75da25c179 | 20 | { |
bborredon | 0:6d75da25c179 | 21 | printf("Error %s\n",msg.c_str()); |
bborredon | 0:6d75da25c179 | 22 | exit(1); |
bborredon | 0:6d75da25c179 | 23 | } |
bborredon | 0:6d75da25c179 | 24 | |
bborredon | 0:6d75da25c179 | 25 | void pcf8574_it(uint8_t data, PCF8574 *o) |
bborredon | 0:6d75da25c179 | 26 | { |
bborredon | 0:6d75da25c179 | 27 | printf("PCF8574 interrupt data = %02x\n",data); |
bborredon | 0:6d75da25c179 | 28 | } |
bborredon | 0:6d75da25c179 | 29 | |
bborredon | 0:6d75da25c179 | 30 | DigitalOut led2(LED2); |
bborredon | 0:6d75da25c179 | 31 | |
bborredon | 0:6d75da25c179 | 32 | int main() |
bborredon | 0:6d75da25c179 | 33 | { |
bborredon | 0:6d75da25c179 | 34 | PCF8574 pcf(p9,p10,PCF8574_ADDR,true); // Declare PCF8574A i2c with sda = p9 and scl = p10 |
bborredon | 0:6d75da25c179 | 35 | uint8_t data; |
bborredon | 0:6d75da25c179 | 36 | |
bborredon | 0:6d75da25c179 | 37 | led2 = 0; |
bborredon | 0:6d75da25c179 | 38 | |
bborredon | 0:6d75da25c179 | 39 | // Set all IO port bits to 1 to enable inputs and test error |
bborredon | 0:6d75da25c179 | 40 | data = 0xFF; |
bborredon | 0:6d75da25c179 | 41 | pcf = data; |
bborredon | 0:6d75da25c179 | 42 | if(pcf.getError() != 0) |
bborredon | 0:6d75da25c179 | 43 | myerror(pcf.getErrorMessage()); |
bborredon | 0:6d75da25c179 | 44 | |
bborredon | 0:6d75da25c179 | 45 | // Assign interrupt function to pin 17 |
bborredon | 0:6d75da25c179 | 46 | pcf.interrupt(p17,&pcf8574_it); |
bborredon | 0:6d75da25c179 | 47 | |
bborredon | 0:6d75da25c179 | 48 | if(pcf.getError() != 0) |
bborredon | 0:6d75da25c179 | 49 | myerror(pcf.getErrorMessage()); |
bborredon | 0:6d75da25c179 | 50 | |
bborredon | 0:6d75da25c179 | 51 | // Get IO port (switch is used to flip bit 1) |
bborredon | 0:6d75da25c179 | 52 | while(1) { |
bborredon | 0:6d75da25c179 | 53 | wait(2.0); |
bborredon | 0:6d75da25c179 | 54 | data = pcf; |
bborredon | 0:6d75da25c179 | 55 | if(pcf.getError() != 0) |
bborredon | 0:6d75da25c179 | 56 | myerror(pcf.getErrorMessage()); |
bborredon | 0:6d75da25c179 | 57 | led2 = !led2; |
bborredon | 0:6d75da25c179 | 58 | } |
bborredon | 0:6d75da25c179 | 59 | |
bborredon | 0:6d75da25c179 | 60 | return(0); |
bborredon | 0:6d75da25c179 | 61 | } |
bborredon | 0:6d75da25c179 | 62 | */ |
bborredon | 0:6d75da25c179 | 63 | |
bborredon | 0:6d75da25c179 | 64 | // Defines |
bborredon | 0:6d75da25c179 | 65 | #define PCF8574_NoError 0x00 |
bborredon | 0:6d75da25c179 | 66 | #define PCF8574_BadAddress 0x01 |
bborredon | 0:6d75da25c179 | 67 | #define PCF8574_I2cError 0x02 |
bborredon | 0:6d75da25c179 | 68 | #define PCF8574_IntrError 0x03 |
bborredon | 0:6d75da25c179 | 69 | |
bborredon | 0:6d75da25c179 | 70 | #define PCF8574_MaxError 4 |
bborredon | 0:6d75da25c179 | 71 | |
bborredon | 0:6d75da25c179 | 72 | #ifndef BIT_SET |
bborredon | 0:6d75da25c179 | 73 | #define BIT_SET(x,n) (x=x | (0x01<<n)) |
bborredon | 0:6d75da25c179 | 74 | #endif |
bborredon | 0:6d75da25c179 | 75 | #ifndef BIT_TEST |
bborredon | 0:6d75da25c179 | 76 | #define BIT_TEST(x,n) (x & (0x01<<n)) |
bborredon | 0:6d75da25c179 | 77 | #endif |
bborredon | 0:6d75da25c179 | 78 | #ifndef BIT_CLEAR |
bborredon | 0:6d75da25c179 | 79 | #define BIT_CLEAR(x,n) (x=x & ~(0x01<<n)) |
bborredon | 0:6d75da25c179 | 80 | #endif |
bborredon | 0:6d75da25c179 | 81 | #ifndef BIT_GET |
bborredon | 0:6d75da25c179 | 82 | #define BIT_GET(x,n) ((x >>n) & 0x1) |
bborredon | 0:6d75da25c179 | 83 | #endif |
bborredon | 0:6d75da25c179 | 84 | |
bborredon | 0:6d75da25c179 | 85 | static std::string _ErrorMessagePCF8574[PCF8574_MaxError] = { |
bborredon | 0:6d75da25c179 | 86 | "", |
bborredon | 0:6d75da25c179 | 87 | "Bad chip address", |
bborredon | 0:6d75da25c179 | 88 | "I2C error (nack)", |
bborredon | 0:6d75da25c179 | 89 | "Unable to create InterruptIn instance" |
bborredon | 0:6d75da25c179 | 90 | }; |
bborredon | 0:6d75da25c179 | 91 | |
bborredon | 0:6d75da25c179 | 92 | // Class |
bborredon | 0:6d75da25c179 | 93 | class PCF8574 { |
bborredon | 0:6d75da25c179 | 94 | public: |
bborredon | 0:6d75da25c179 | 95 | /* |
bborredon | 0:6d75da25c179 | 96 | * Constructor, initialize the PCF8574 on i2c interface. |
bborredon | 0:6d75da25c179 | 97 | * @param sda : sda i2c pin (PinName) |
bborredon | 0:6d75da25c179 | 98 | * @param scl : scl i2c pin (PinName) |
bborredon | 0:6d75da25c179 | 99 | * @param address : PCF8574 address between 0 and 7 (uint8_t) |
bborredon | 0:6d75da25c179 | 100 | * @param typeA : PCF8574A if true, default false (bool) |
bborredon | 0:6d75da25c179 | 101 | * @return none |
bborredon | 0:6d75da25c179 | 102 | */ |
bborredon | 0:6d75da25c179 | 103 | PCF8574(PinName sda, PinName scl, uint8_t address, bool typeA = false); |
bborredon | 0:6d75da25c179 | 104 | |
bborredon | 0:6d75da25c179 | 105 | /* |
bborredon | 0:6d75da25c179 | 106 | * Read the IO pins level |
bborredon | 0:6d75da25c179 | 107 | * @param : none |
bborredon | 0:6d75da25c179 | 108 | * @return port value (uint8_t) |
bborredon | 0:6d75da25c179 | 109 | */ |
bborredon | 0:6d75da25c179 | 110 | uint8_t read(void); |
bborredon | 0:6d75da25c179 | 111 | |
bborredon | 0:6d75da25c179 | 112 | /* |
bborredon | 0:6d75da25c179 | 113 | * Write to the IO pins |
bborredon | 0:6d75da25c179 | 114 | * @param data : The 8 bits to write to the IO port (uint8_t) |
bborredon | 0:6d75da25c179 | 115 | * @return none |
bborredon | 0:6d75da25c179 | 116 | */ |
bborredon | 0:6d75da25c179 | 117 | void write(uint8_t data); |
bborredon | 0:6d75da25c179 | 118 | |
bborredon | 0:6d75da25c179 | 119 | /* |
bborredon | 0:6d75da25c179 | 120 | * Write to individual IO pin |
bborredon | 0:6d75da25c179 | 121 | * @param pin : The pin number between 0 and 7 (uint8_t) |
bborredon | 0:6d75da25c179 | 122 | * @param value : The pin value (uint8_t) |
bborredon | 0:6d75da25c179 | 123 | * @return none |
bborredon | 0:6d75da25c179 | 124 | */ |
bborredon | 0:6d75da25c179 | 125 | void write(uint8_t pin, uint8_t value); |
bborredon | 0:6d75da25c179 | 126 | |
bborredon | 0:6d75da25c179 | 127 | /* |
bborredon | 0:6d75da25c179 | 128 | * Write to IO pins with a bitset and a bitset mask (only bits set in mask are written) |
bborredon | 0:6d75da25c179 | 129 | * @param data : The biset to write to the IO port (bitset<8>) |
bborredon | 0:6d75da25c179 | 130 | * @param mask : The biset to write mask (bitset<8>) |
bborredon | 0:6d75da25c179 | 131 | * @return none |
bborredon | 0:6d75da25c179 | 132 | */ |
bborredon | 0:6d75da25c179 | 133 | void write(bitset<8> data, bitset<8> mask); |
bborredon | 0:6d75da25c179 | 134 | |
bborredon | 0:6d75da25c179 | 135 | /* |
bborredon | 0:6d75da25c179 | 136 | * Interrupt IO callback called when PCF8574 IO pins changed (falling edge) |
bborredon | 0:6d75da25c179 | 137 | * @param intr : pin name connected to PCF8574 int pin (PinName) |
bborredon | 0:6d75da25c179 | 138 | * @param ftpr : user callback function (void ftpr(unit8_t data, PCF8574 *o)). |
bborredon | 0:6d75da25c179 | 139 | * data : PCF8574 IO port value |
bborredon | 0:6d75da25c179 | 140 | * o : object instance address |
bborredon | 0:6d75da25c179 | 141 | * @return none |
bborredon | 0:6d75da25c179 | 142 | */ |
bborredon | 0:6d75da25c179 | 143 | void interrupt(PinName intr,void (*ftpr)(uint8_t data, PCF8574 *o)); |
bborredon | 0:6d75da25c179 | 144 | |
bborredon | 0:6d75da25c179 | 145 | /* |
bborredon | 0:6d75da25c179 | 146 | * Get current error message |
bborredon | 0:6d75da25c179 | 147 | * @param : none |
bborredon | 0:6d75da25c179 | 148 | * @return current error message(std::string) |
bborredon | 0:6d75da25c179 | 149 | */ |
bborredon | 0:6d75da25c179 | 150 | std::string getErrorMessage(void) |
bborredon | 0:6d75da25c179 | 151 | { |
bborredon | 0:6d75da25c179 | 152 | if(_errnum < PCF8574_MaxError) |
bborredon | 0:6d75da25c179 | 153 | return(_ErrorMessagePCF8574[_errnum]); |
bborredon | 0:6d75da25c179 | 154 | else |
bborredon | 0:6d75da25c179 | 155 | return("errnum out of range"); |
bborredon | 0:6d75da25c179 | 156 | } |
bborredon | 0:6d75da25c179 | 157 | |
bborredon | 0:6d75da25c179 | 158 | /* |
bborredon | 0:6d75da25c179 | 159 | * Get the current error number (PCF8574_NoError if no error) |
bborredon | 0:6d75da25c179 | 160 | * @param : none |
bborredon | 0:6d75da25c179 | 161 | * @return current error number (uint8_t) |
bborredon | 0:6d75da25c179 | 162 | */ |
bborredon | 0:6d75da25c179 | 163 | uint8_t getError(void); |
bborredon | 0:6d75da25c179 | 164 | |
bborredon | 0:6d75da25c179 | 165 | /* |
bborredon | 0:6d75da25c179 | 166 | * Memorize data IO port value and bits that have changed when interrupt |
bborredon | 0:6d75da25c179 | 167 | * @param data : data IO port value when interrupt (bitset<8>) |
bborredon | 0:6d75da25c179 | 168 | * @param changed : bits that have changed (bitset<8>) |
bborredon | 0:6d75da25c179 | 169 | * @return none |
bborredon | 0:6d75da25c179 | 170 | */ |
bborredon | 0:6d75da25c179 | 171 | void setIntrData(bitset<8> data, bitset<8> changed); |
bborredon | 0:6d75da25c179 | 172 | |
bborredon | 0:6d75da25c179 | 173 | /* |
bborredon | 0:6d75da25c179 | 174 | * Get data IO port value when and bits that have changed when interrupt |
bborredon | 0:6d75da25c179 | 175 | * @param data : data IO port value when interrupt (bitset<8>&) |
bborredon | 0:6d75da25c179 | 176 | * @param changed : bits that have changed (bitset<8>&) |
bborredon | 0:6d75da25c179 | 177 | * @return none |
bborredon | 0:6d75da25c179 | 178 | */ |
bborredon | 0:6d75da25c179 | 179 | void getIntrData(bitset<8>& data, bitset<8>& changed); |
bborredon | 0:6d75da25c179 | 180 | |
bborredon | 0:6d75da25c179 | 181 | /* |
bborredon | 0:6d75da25c179 | 182 | *Operator () (read) |
bborredon | 0:6d75da25c179 | 183 | */ |
bborredon | 0:6d75da25c179 | 184 | operator uint8_t(); |
bborredon | 0:6d75da25c179 | 185 | |
bborredon | 0:6d75da25c179 | 186 | /* |
bborredon | 0:6d75da25c179 | 187 | *Operator = (write) |
bborredon | 0:6d75da25c179 | 188 | */ |
bborredon | 0:6d75da25c179 | 189 | PCF8574 &operator=(uint8_t data); |
bborredon | 0:6d75da25c179 | 190 | |
bborredon | 0:6d75da25c179 | 191 | private: |
bborredon | 0:6d75da25c179 | 192 | I2C _i2c; // Local i2c communication interface instance |
bborredon | 0:6d75da25c179 | 193 | int _address; // Local pcf8574 i2c address |
bborredon | 0:6d75da25c179 | 194 | int _PCF8574_address; // PCF8574 address |
bborredon | 0:6d75da25c179 | 195 | uint8_t _errnum; // Error number |
bborredon | 0:6d75da25c179 | 196 | bitset<8> _intr_data; // IO port value when interrupt |
bborredon | 0:6d75da25c179 | 197 | bitset<8> _intr_bits_changed; // Bits that have changed on interrupt |
bborredon | 0:6d75da25c179 | 198 | InterruptIn *_intr; // Internal InterruptIn object address |
bborredon | 0:6d75da25c179 | 199 | uint8_t _intr_flag; // interrupt function has been called |
bborredon | 0:6d75da25c179 | 200 | }; |
bborredon | 0:6d75da25c179 | 201 | |
bborredon | 0:6d75da25c179 | 202 | #endif |