Added support for banked registers
Dependents: Component_Test_Interface FalconWing MX_Spoile_Test Simple_Power_Distribution ... more
Revision 4:868db61f5f4e, committed 2012-02-13
- Comitter:
- wim
- Date:
- Mon Feb 13 21:54:29 2012 +0000
- Parent:
- 3:72da9cd002bd
- Child:
- 5:5696b886a895
- Commit message:
- v05
Changed in this revision
| MCP23017.cpp | Show annotated file Show diff for this revision Revisions of this file |
| MCP23017.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/MCP23017.cpp Sun Aug 21 13:59:48 2011 +0000
+++ b/MCP23017.cpp Mon Feb 13 21:54:29 2012 +0000
@@ -6,6 +6,7 @@
* version 0.2 Initial Release
* version 0.3 Cleaned up
* version 0.4 Fixed problem with _read method
+* version 0.5 Added support for 'Banked' access to registers
*/
#include "mbed.h"
@@ -57,7 +58,10 @@
* @returns
*/
void MCP23017::_init() {
- _write(IOCON, (IOCON_BYTE_MODE | IOCON_HAEN )); // Hardware addressing on, operations toggle between A and B registers
+
+ _bankMode = NOT_BNK; // This may not be true after software reset without hardware reset !!!
+
+ _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BYTE_MODE | IOCON_HAEN )); // Hardware addressing on, no-autoincrement, 16 bit mode (operations toggle between A and B registers)
}
@@ -67,7 +71,7 @@
* @param char direction pin direction (0 = output, 1 = input)
*/
void MCP23017::direction(Port port, char direction) {
- _write(port + IODIRA, direction);
+ _write(IODIR_AB[_bankMode][port], direction);
}
/** Set Pull-Up Resistors on specified MCP23017 Port
@@ -76,40 +80,73 @@
* @param char offOrOn per pin (0 = off, 1 = on)
*/
void MCP23017::configurePullUps(Port port, char offOrOn) {
- _write(port + GPPUA, offOrOn);
+
+ _write(GPPU_AB[_bankMode][port], offOrOn);
}
+/** Configere the Banked or Non-Banked mode
+*
+* @param Bank bankMode
+* @param char offOrOn per pin (0 = off, 1 = on)
+*/
+void MCP23017::configureBanked(Bank bankMode) {
+
+ if (bankMode == NOT_BNK) {
+ // Non-Banked sequential registers (default POR)
+ // Hardware addressing on, , no-autoincrement, 16 bit mode (operations do toggle between A and B registers)
+ _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BYTE_MODE | IOCON_HAEN ));
+ _bankMode = NOT_BNK;
+ }
+ else {
+ // Banked registers
+ // Hardware addressing on, no-autoincrement, 8 bit mode
+ _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BANK | IOCON_BYTE_MODE | IOCON_HAEN ));
+ _bankMode = BNK;
+ }
+}
+
+
void MCP23017::interruptEnable(Port port, char interruptsEnabledMask) {
- _write(port + GPINTENA, interruptsEnabledMask);
+
+ _write(GPINTEN_AB[_bankMode][port], interruptsEnabledMask);
+
}
void MCP23017::mirrorInterrupts(bool mirror) {
- char iocon = _read(IOCON);
- if (mirror) {
- iocon = iocon | INTERRUPT_MIRROR_BIT;
- } else {
- iocon = iocon & ~INTERRUPT_MIRROR_BIT;
- }
- _write(IOCON, iocon);
+ char iocon = _read(IOCON_AB[_bankMode][PORT_A]);
+
+ if (mirror) {
+ iocon = iocon | INTERRUPT_MIRROR_BIT;
+ }
+ else {
+ iocon = iocon & ~INTERRUPT_MIRROR_BIT;
+ }
+
+ _write(IOCON_AB[_bankMode][PORT_A], iocon);
}
void MCP23017::interruptPolarity(Polarity polarity) {
- char iocon = _read(IOCON);
+ char iocon = _read(IOCON_AB[_bankMode][PORT_A]);
+
if (polarity == ACTIVE_LOW) {
iocon = iocon & ~INTERRUPT_POLARITY_BIT;
} else {
iocon = iocon | INTERRUPT_POLARITY_BIT;
}
- _write(IOCON, iocon);
+ _write(IOCON_AB[_bankMode][PORT_A], iocon);
}
void MCP23017::defaultValue(Port port, char valuesToCompare) {
- _write(port + DEFVALA, valuesToCompare);
+
+ _write(DEFVAL_AB[_bankMode][port], valuesToCompare);
+
}
void MCP23017::interruptControl(Port port, char interruptControlBits) {
- _write(port + INTCONA, interruptControlBits);
+
+ _write(INTCON_AB[_bankMode][port], interruptControlBits);
+
}
/** Write to specified MCP23017 Port
@@ -118,7 +155,7 @@
* @param char byte data to write
*/
void MCP23017::write(Port port, char byte) {
- _write(port + OLATA, byte);
+ _write(OLAT_AB[_bankMode][port], byte);
}
/** Read from specified MCP23017 Port
@@ -127,6 +164,6 @@
* @returns data from Port
*/
char MCP23017::read(Port port) {
- return _read(port + GPIOA);
+ return _read(GPIO_AB[_bankMode][port]);
}
--- a/MCP23017.h Sun Aug 21 13:59:48 2011 +0000
+++ b/MCP23017.h Mon Feb 13 21:54:29 2012 +0000
@@ -6,6 +6,7 @@
* version 0.2 Initial Release
* version 0.3 Cleaned up
* version 0.4 Fixed problem with _read method
+* version 0.5 Added support for 'Banked' access to registers
*/
#include "mbed.h"
@@ -15,14 +16,16 @@
// All register addresses assume IOCON.BANK = 0 (POR default)
#define IODIRA 0x00
#define IODIRB 0x01
+#define IPOLA 0x02
+#define IPOLB 0x03
#define GPINTENA 0x04
#define GPINTENB 0x05
#define DEFVALA 0x06
#define DEFVALB 0x07
#define INTCONA 0x08
#define INTCONB 0x09
-#define IOCON 0x0A
-//#define IOCON 0x0B
+#define IOCONA 0x0A
+#define IOCONB 0x0B
#define GPPUA 0x0C
#define GPPUB 0x0D
#define INTFA 0x0E
@@ -34,10 +37,50 @@
#define OLATA 0x14
#define OLATB 0x15
+// The following register addresses assume IOCON.BANK = 1
+#define IODIRA_BNK 0x00
+#define IPOLA_BNK 0x01
+#define GPINTENA_BNK 0x02
+#define DEFVALA_BNK 0x03
+#define INTCONA_BNK 0x04
+#define GPPUA_BNK 0x05
+#define INTFA_BNK 0x06
+#define IOCONA_BNK 0x07
+#define INTCAPA_BNK 0x08
+#define GPIOA_BNK 0x09
+#define OLATA_BNK 0x0A
+
+#define IODIRB_BNK 0x10
+#define IPOLB_BNK 0x11
+#define GPINTENB_BNK 0x12
+#define DEFVALB_BNK 0x13
+#define INTCONB_BNK 0x14
+#define IOCONB_BNK 0x15
+#define GPPUB_BNK 0x16
+#define INTFB_BNK 0x17
+#define INTCAPB_BNK 0x18
+#define GPIOB_BNK 0x19
+#define OLATB_BNK 0x1A
+
+// This array allows structured access to Port_A and Port_B registers for both bankModes
+const int IODIR_AB[2][2] = {{IODIRA, IODIRB}, {IODIRA_BNK, IODIRB_BNK}};
+const int IPOL_AB[2][2] = {{IPOLA, IPOLB}, {IPOLA_BNK, IPOLB_BNK}};
+const int GPINTEN_AB[2][2] = {{GPINTENA, GPINTENB}, {GPINTENA_BNK, GPINTENB_BNK}};
+const int DEFVAL_AB[2][2] = {{DEFVALA, DEFVALB}, {DEFVALA_BNK, DEFVALB_BNK}};
+const int INTCON_AB[2][2] = {{INTCONA, INTCONB}, {INTCONA_BNK, INTCONB_BNK}};
+const int IOCON_AB[2][2] = {{IOCONA, IOCONB}, {IOCONA_BNK, IOCONB_BNK}};
+const int GPPU_AB[2][2] = {{GPPUA, GPPUB}, {GPPUA_BNK, GPPUB_BNK}};
+const int INTF_AB[2][2] = {{INTFA, INTFB}, {INTFA_BNK, INTFB_BNK}};
+const int INTCAP_AB[2][2] = {{INTCAPA, INTCAPB}, {INTCAPA_BNK, INTCAPB_BNK}};
+const int GPIO_AB[2][2] = {{GPIOA, GPIOB}, {GPIOA_BNK, GPIOB_BNK}};
+const int OLAT_AB[2][2] = {{OLATA, OLATB}, {OLATA_BNK, OLATB_BNK}};
+
+
// Control settings
#define IOCON_BANK 0x80 // Banked registers for Port A and B
#define IOCON_BYTE_MODE 0x20 // Disables sequential operation, Address Ptr does not increment
// If Disabled and Bank = 0, operations toggle between Port A and B registers
+ // If Disabled and Bank = 1, operations do not increment registeraddress
#define IOCON_HAEN 0x08 // Hardware address enable
#define INTERRUPT_POLARITY_BIT 0x02
@@ -47,7 +90,8 @@
#define PORT_DIR_IN 0xFF
enum Polarity { ACTIVE_LOW , ACTIVE_HIGH };
-enum Port { PORT_A, PORT_B };
+enum Port { PORT_A=0, PORT_B=1 };
+enum Bank { NOT_BNK=0, BNK=1 };
class MCP23017 {
public:
@@ -72,6 +116,7 @@
*/
void configurePullUps(Port port, char offOrOn);
+ void configureBanked(Bank bankmode);
void interruptEnable(Port port, char interruptsEnabledMask);
void interruptPolarity(Polarity polarity);
void mirrorInterrupts(bool mirror);
@@ -96,6 +141,7 @@
I2C &_i2c;
char _readOpcode;
char _writeOpcode;
+ Bank _bankMode;
/** Init MCP23017
*
MCP2317 I2C 16 bit I/O expander