Complete PCF8574 and PCF74A library with interrupt handling

Dependents:   Nucleo_PCF8574_led_iic Dawson_Controller

Committer:
bborredon
Date:
Sat Jul 14 08:20:07 2012 +0000
Revision:
0:6d75da25c179
[mbed] converted /I2c/PCF8574

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bborredon 0:6d75da25c179 1 /***********************************************************
bborredon 0:6d75da25c179 2 Author: Bernard Borredon
bborredon 0:6d75da25c179 3 Date: 27 december 2011
bborredon 0:6d75da25c179 4 Version: 1.0
bborredon 0:6d75da25c179 5 ************************************************************/
bborredon 0:6d75da25c179 6 #include "PCF8574.h"
bborredon 0:6d75da25c179 7
bborredon 0:6d75da25c179 8 // Local object address
bborredon 0:6d75da25c179 9 static PCF8574 *pt_pcf8574;
bborredon 0:6d75da25c179 10
bborredon 0:6d75da25c179 11 // User callback function address
bborredon 0:6d75da25c179 12 static void (*_ptf)(uint8_t data,PCF8574 *o)= NULL;
bborredon 0:6d75da25c179 13
bborredon 0:6d75da25c179 14 // Callback
bborredon 0:6d75da25c179 15 static void _InterruptCB(void)
bborredon 0:6d75da25c179 16 {
bborredon 0:6d75da25c179 17 uint8_t data = 0;
bborredon 0:6d75da25c179 18 bitset<8> data_p,val;
bborredon 0:6d75da25c179 19 bitset<8> changed;
bborredon 0:6d75da25c179 20 uint8_t i;
bborredon 0:6d75da25c179 21
bborredon 0:6d75da25c179 22 // Read PCF8574 port (to acknowledge interrupt)
bborredon 0:6d75da25c179 23 data = pt_pcf8574->read();
bborredon 0:6d75da25c179 24
bborredon 0:6d75da25c179 25 // Set bits that have changed
bborredon 0:6d75da25c179 26 pt_pcf8574->getIntrData(data_p,changed);
bborredon 0:6d75da25c179 27 changed = 0;
bborredon 0:6d75da25c179 28 val = data;
bborredon 0:6d75da25c179 29 for(i = 0;i < 8;i++) {
bborredon 0:6d75da25c179 30 if(val[i] != data_p[i])
bborredon 0:6d75da25c179 31 changed[i] = 1;
bborredon 0:6d75da25c179 32 }
bborredon 0:6d75da25c179 33 pt_pcf8574->setIntrData(val,changed);
bborredon 0:6d75da25c179 34
bborredon 0:6d75da25c179 35 // Call user callback, if any with port value
bborredon 0:6d75da25c179 36 if(_ptf != NULL)
bborredon 0:6d75da25c179 37 _ptf(data,pt_pcf8574);
bborredon 0:6d75da25c179 38 }
bborredon 0:6d75da25c179 39
bborredon 0:6d75da25c179 40 // Constructor
bborredon 0:6d75da25c179 41 PCF8574::PCF8574(PinName sda,PinName scl,uint8_t address, bool typeA) : _i2c(sda, scl)
bborredon 0:6d75da25c179 42 {
bborredon 0:6d75da25c179 43 _errnum = PCF8574_NoError;
bborredon 0:6d75da25c179 44 _intr = NULL;
bborredon 0:6d75da25c179 45 pt_pcf8574 = NULL;
bborredon 0:6d75da25c179 46 _intr_data = 0xFF;
bborredon 0:6d75da25c179 47 _intr_bits_changed = 0;
bborredon 0:6d75da25c179 48 _intr_flag = 0;
bborredon 0:6d75da25c179 49
bborredon 0:6d75da25c179 50 // Set the address
bborredon 0:6d75da25c179 51 if(typeA) { // PCF8574A
bborredon 0:6d75da25c179 52 _PCF8574_address = 0x70;
bborredon 0:6d75da25c179 53 }
bborredon 0:6d75da25c179 54 else { // PCF8574
bborredon 0:6d75da25c179 55 _PCF8574_address = 0x40;
bborredon 0:6d75da25c179 56 }
bborredon 0:6d75da25c179 57
bborredon 0:6d75da25c179 58 _address = address;
bborredon 0:6d75da25c179 59
bborredon 0:6d75da25c179 60 // Check address validity (between 0 and 7)
bborredon 0:6d75da25c179 61 if(address > 7) {
bborredon 0:6d75da25c179 62 _errnum = PCF8574_BadAddress;
bborredon 0:6d75da25c179 63 }
bborredon 0:6d75da25c179 64
bborredon 0:6d75da25c179 65 // Shift address
bborredon 0:6d75da25c179 66 _address = _address << 1;
bborredon 0:6d75da25c179 67
bborredon 0:6d75da25c179 68 // Set I2C frequency (100 MHz)
bborredon 0:6d75da25c179 69 _i2c.frequency(100000);
bborredon 0:6d75da25c179 70 }
bborredon 0:6d75da25c179 71
bborredon 0:6d75da25c179 72 // Read IO port
bborredon 0:6d75da25c179 73 uint8_t PCF8574::read(void)
bborredon 0:6d75da25c179 74 {
bborredon 0:6d75da25c179 75 uint8_t data;
bborredon 0:6d75da25c179 76 int ack;
bborredon 0:6d75da25c179 77
bborredon 0:6d75da25c179 78 // Check error
bborredon 0:6d75da25c179 79 if(_errnum)
bborredon 0:6d75da25c179 80 return(0);
bborredon 0:6d75da25c179 81
bborredon 0:6d75da25c179 82 // No error
bborredon 0:6d75da25c179 83 _errnum = PCF8574_NoError;
bborredon 0:6d75da25c179 84
bborredon 0:6d75da25c179 85 // Read port
bborredon 0:6d75da25c179 86 ack = _i2c.read(_PCF8574_address | _address,(char *)&data,sizeof(data));
bborredon 0:6d75da25c179 87
bborredon 0:6d75da25c179 88 // Check error
bborredon 0:6d75da25c179 89 if(ack != 0) {
bborredon 0:6d75da25c179 90 _errnum = PCF8574_I2cError;
bborredon 0:6d75da25c179 91 }
bborredon 0:6d75da25c179 92
bborredon 0:6d75da25c179 93 return(data);
bborredon 0:6d75da25c179 94 }
bborredon 0:6d75da25c179 95
bborredon 0:6d75da25c179 96 // Write IO port
bborredon 0:6d75da25c179 97 void PCF8574::write(uint8_t data)
bborredon 0:6d75da25c179 98 {
bborredon 0:6d75da25c179 99 int ack;
bborredon 0:6d75da25c179 100
bborredon 0:6d75da25c179 101 // Check error
bborredon 0:6d75da25c179 102 if(_errnum)
bborredon 0:6d75da25c179 103 return;
bborredon 0:6d75da25c179 104
bborredon 0:6d75da25c179 105 // No error
bborredon 0:6d75da25c179 106 _errnum = PCF8574_NoError;
bborredon 0:6d75da25c179 107
bborredon 0:6d75da25c179 108 // Write port
bborredon 0:6d75da25c179 109 ack = _i2c.write(_PCF8574_address | _address,(char *)&data,sizeof(data));
bborredon 0:6d75da25c179 110
bborredon 0:6d75da25c179 111 // Check error
bborredon 0:6d75da25c179 112 if(ack != 0) {
bborredon 0:6d75da25c179 113 _errnum = PCF8574_I2cError;
bborredon 0:6d75da25c179 114 }
bborredon 0:6d75da25c179 115 }
bborredon 0:6d75da25c179 116
bborredon 0:6d75da25c179 117 // Write IO pin
bborredon 0:6d75da25c179 118 void PCF8574::write(uint8_t pin, uint8_t value)
bborredon 0:6d75da25c179 119 {
bborredon 0:6d75da25c179 120 uint8_t data;
bborredon 0:6d75da25c179 121
bborredon 0:6d75da25c179 122 // Read IO port value
bborredon 0:6d75da25c179 123 data = read();
bborredon 0:6d75da25c179 124
bborredon 0:6d75da25c179 125 // Change bit pin
bborredon 0:6d75da25c179 126 if(value)
bborredon 0:6d75da25c179 127 BIT_SET(data,pin);
bborredon 0:6d75da25c179 128 else
bborredon 0:6d75da25c179 129 BIT_CLEAR(data,pin);
bborredon 0:6d75da25c179 130
bborredon 0:6d75da25c179 131 // Write new IO port data
bborredon 0:6d75da25c179 132 write(data);
bborredon 0:6d75da25c179 133 }
bborredon 0:6d75da25c179 134
bborredon 0:6d75da25c179 135 // Write to IO pins with a bitset and a bitset mask
bborredon 0:6d75da25c179 136 void PCF8574::write(bitset<8> data, bitset<8> mask)
bborredon 0:6d75da25c179 137 {
bborredon 0:6d75da25c179 138 uint8_t i;
bborredon 0:6d75da25c179 139 bitset<8> nd;
bborredon 0:6d75da25c179 140
bborredon 0:6d75da25c179 141 nd = (bitset<8>) read();
bborredon 0:6d75da25c179 142 for(i = 0;i < 8;i++) {
bborredon 0:6d75da25c179 143 if(mask[i])
bborredon 0:6d75da25c179 144 nd[i] = data[i];
bborredon 0:6d75da25c179 145 }
bborredon 0:6d75da25c179 146
bborredon 0:6d75da25c179 147 write((uint8_t) nd.to_ulong());
bborredon 0:6d75da25c179 148 }
bborredon 0:6d75da25c179 149
bborredon 0:6d75da25c179 150 // Set pin and callback interrupt
bborredon 0:6d75da25c179 151 void PCF8574::interrupt(PinName intr,void (*ftpr)(uint8_t, PCF8574 *))
bborredon 0:6d75da25c179 152 {
bborredon 0:6d75da25c179 153
bborredon 0:6d75da25c179 154 // Check error
bborredon 0:6d75da25c179 155 if(_errnum)
bborredon 0:6d75da25c179 156 return;
bborredon 0:6d75da25c179 157
bborredon 0:6d75da25c179 158 // No error
bborredon 0:6d75da25c179 159 _errnum = PCF8574_NoError;
bborredon 0:6d75da25c179 160
bborredon 0:6d75da25c179 161 // Create InterruptIn instance if needed
bborredon 0:6d75da25c179 162 if(_intr == NULL) {
bborredon 0:6d75da25c179 163 _intr = new InterruptIn(intr);
bborredon 0:6d75da25c179 164
bborredon 0:6d75da25c179 165 // Set InterruptIn callback
bborredon 0:6d75da25c179 166 if(_intr != NULL)
bborredon 0:6d75da25c179 167 _intr->fall(_InterruptCB);
bborredon 0:6d75da25c179 168 else
bborredon 0:6d75da25c179 169 _errnum = PCF8574_IntrError;
bborredon 0:6d75da25c179 170 }
bborredon 0:6d75da25c179 171
bborredon 0:6d75da25c179 172 _ptf = ftpr; // User callback address
bborredon 0:6d75da25c179 173 pt_pcf8574 = this; // Object instance
bborredon 0:6d75da25c179 174 _intr_data = read(); // IO port value
bborredon 0:6d75da25c179 175 _intr_flag = 1; // Function called
bborredon 0:6d75da25c179 176 }
bborredon 0:6d75da25c179 177
bborredon 0:6d75da25c179 178 // Get current error number
bborredon 0:6d75da25c179 179 uint8_t PCF8574::getError(void)
bborredon 0:6d75da25c179 180 {
bborredon 0:6d75da25c179 181 return(_errnum);
bborredon 0:6d75da25c179 182 }
bborredon 0:6d75da25c179 183
bborredon 0:6d75da25c179 184 // Memorize IO port value and bits that have changed when interrupt
bborredon 0:6d75da25c179 185 void PCF8574::setIntrData(bitset<8> data, bitset<8> changed)
bborredon 0:6d75da25c179 186 {
bborredon 0:6d75da25c179 187 _intr_data = data;
bborredon 0:6d75da25c179 188 _intr_bits_changed = changed;
bborredon 0:6d75da25c179 189 }
bborredon 0:6d75da25c179 190
bborredon 0:6d75da25c179 191 // Get IO port value and bits that have changed when interrupt
bborredon 0:6d75da25c179 192 void PCF8574::getIntrData(bitset<8>& data, bitset<8>& changed)
bborredon 0:6d75da25c179 193 {
bborredon 0:6d75da25c179 194 data = _intr_data;
bborredon 0:6d75da25c179 195 changed = _intr_bits_changed;
bborredon 0:6d75da25c179 196 }
bborredon 0:6d75da25c179 197
bborredon 0:6d75da25c179 198 // Redefine () operator
bborredon 0:6d75da25c179 199 PCF8574::operator uint8_t()
bborredon 0:6d75da25c179 200 {
bborredon 0:6d75da25c179 201 return read();
bborredon 0:6d75da25c179 202 }
bborredon 0:6d75da25c179 203
bborredon 0:6d75da25c179 204 // Redefine = operator
bborredon 0:6d75da25c179 205 PCF8574 &PCF8574::operator=(uint8_t data)
bborredon 0:6d75da25c179 206 {
bborredon 0:6d75da25c179 207 write((int)data);
bborredon 0:6d75da25c179 208
bborredon 0:6d75da25c179 209 return(*this);
bborredon 0:6d75da25c179 210 }