Added support for banked registers

Dependents:   Component_Test_Interface FalconWing MX_Spoile_Test Simple_Power_Distribution ... more

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Sat Dec 18 18:49:19 2010 +0000
Child:
1:e2edbd61f4d0
Commit message:
Initial Version

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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP23017.cpp	Sat Dec 18 18:49:19 2010 +0000
@@ -0,0 +1,132 @@
+/* MCP23017 - drive the Microchip MCP23017 16-bit Port Extender using I2C
+* Copyright (c) 2010 Wim Huiskamp, Romilly Cocking (original version for SPI)
+*
+* Released under the MIT License: http://mbed.org/license/mit
+*
+* version 0.2
+*/
+
+#include "mbed.h"
+#include "MCP23017.h"
+
+MCP23017::MCP23017(I2C &i2c, char deviceAddress) : _i2c(i2c) {
+    _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write
+    _readOpcode  = deviceAddress | 0x01; // low order bit = 1 for read
+    _init();
+}
+
+char MCP23017::_read(char address) {
+    char data[2];
+    char result;
+
+    data[0] = address;
+    _i2c.write(_writeOpcode, data, 1);      // Select Register for reading
+    result = _i2c.read(_readOpcode);        // Read from selected Register
+    
+    return result;
+}
+
+
+void MCP23017::_write(char address, char byte) {
+    char data[2];
+
+    data[0] = address;
+    data[1] = byte;
+    _i2c.write(_writeOpcode, data, 2);    // Write data to selected Register
+}
+
+
+void MCP23017::_init() {
+    _write(IOCON, (IOCON_BYTE_MODE | IOCON_HAEN )); // Hardware addressing on, operations toggle between A and B registers
+
+}
+
+void MCP23017::direction(Port port, char direction) {
+    _write(port + IODIRA, direction);
+}
+
+void MCP23017::configurePullUps(Port port, char offOrOn) {
+    _write(port + GPPUA, offOrOn);
+}
+
+void MCP23017::interruptEnable(Port port, char interruptsEnabledMask) {
+    _write(port + GPINTENA, 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);
+
+}
+
+void  MCP23017::interruptPolarity(Polarity polarity) {
+    char iocon = _read(IOCON);
+    if (polarity == ACTIVE_LOW) {
+        iocon = iocon & ~INTERRUPT_POLARITY_BIT;
+    } else {
+        iocon = iocon | INTERRUPT_POLARITY_BIT;
+    }
+    _write(IOCON, iocon);
+}
+
+void MCP23017::defaultValue(Port port, char valuesToCompare) {
+    _write(port + DEFVALA, valuesToCompare);
+}
+
+void MCP23017::interruptControl(Port port, char interruptControlBits) {
+    _write(port + INTCONA, interruptControlBits);
+}
+
+void MCP23017::write(Port port, char byte) {
+    _write(port + OLATA, byte);
+    
+//faster    (56 sec for lcd init)
+//   char data[2];
+//
+//   data[0] = OLATA + port;
+//   data[1] = byte;
+//   _i2c.write(_writeOpcode, data, 2);    // Write data to selected Register
+
+//faster  47 sec for complete init
+//   _i2c.start();
+//   _i2c.write(_writeOpcode);    // Select Device
+//   _i2c.write(OLATA + port);    // Select Register
+//   _i2c.write(byte);            // Write data to selected Register
+//   _i2c.stop();  
+}
+    
+
+char MCP23017::read(Port port) {
+    return _read(port + GPIOA);
+}
+
+// Optimised Databus write operation for Graphics LCD.
+//   Port A is used as databus, Port B is used as controlbus.
+//
+void MCP23017::databus_write(char data, char ctrl_1, char ctrl_2, char ctrl_3, char ctrl_4) {
+
+   _i2c.start();
+   _i2c.write(_writeOpcode);    // Select Device
+   _i2c.write(OLATA);           // Select Register A
+
+//Remove separate CS Low, to speed up
+//   _i2c.write(data);            // Write data to Port A Register and Auto-incr to Register B
+//   _i2c.write(ctrl_1);          // Write control to Port B  and Auto-incr to Register A
+   
+   _i2c.write(data);            // Write data to Port A Register and Auto-incr to Register B
+   _i2c.write(ctrl_2);          // Write control to Port B  and Auto-incr to Register A
+   
+   _i2c.write(data);            // Write data to Port A Register and Auto-incr to Register B
+   _i2c.write(ctrl_3);          // Write control to Port B  and Auto-incr to Register A
+
+//Remove separate CS High, to speed up
+//   _i2c.write(data);            // Write data to Port A Register and Auto-incr to Register B
+//   _i2c.write(ctrl_4);          // Write control to Port B  and Auto-incr to Register A
+   
+   _i2c.stop();  
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP23017.h	Sat Dec 18 18:49:19 2010 +0000
@@ -0,0 +1,72 @@
+/* MCP23017 - drive the Microchip MCP23017 16-bit Port Extender using I2C
+* Copyright (c) 2010 Wim Huiskamp, Romilly Cocking (original version for SPI)
+*
+* Released under the MIT License: http://mbed.org/license/mit
+*
+* version 0.2
+*/
+#include "mbed.h"
+
+#ifndef  MCP23017_H
+#define  MCP23017_H
+
+// All register addresses assume IOCON.BANK = 0 (POR default)
+#define IODIRA   0x00
+#define IODIRB   0x01
+#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 GPPUA    0x0C
+#define GPPUB    0x0D
+#define INTFA    0x0E
+#define INTFB    0x0F
+#define INTCAPA  0x10
+#define INTCAPB  0x11
+#define GPIOA    0x12
+#define GPIOB    0x13
+#define OLATA    0x14
+#define OLATB    0x15
+
+// 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
+#define IOCON_HAEN      0x08 // Hardware address enable
+
+#define INTERRUPT_POLARITY_BIT 0x02
+#define INTERRUPT_MIRROR_BIT   0x40
+
+#define PORT_DIR_OUT   0x00
+#define PORT_DIR_IN    0xFF
+
+enum Polarity { ACTIVE_LOW , ACTIVE_HIGH };
+enum Port { PORT_A, PORT_B };
+
+class MCP23017 {
+public:
+    MCP23017(I2C &i2c, char deviceAddress);
+    void direction(Port port, char direction);
+    void configurePullUps(Port port, char offOrOn);
+    void interruptEnable(Port port, char interruptsEnabledMask);
+    void interruptPolarity(Polarity polarity);
+    void mirrorInterrupts(bool mirror);
+    void defaultValue(Port port, char valuesToCompare);
+    void interruptControl(Port port, char interruptControlBits);
+    char read(Port port);
+    void write(Port port, char byte);
+    void databus_write(char data, char ctrl_1, char ctrl_2, char ctrl_3, char ctrl_4);
+protected:
+    I2C &_i2c;
+    void _init();
+    void _write(char address, char byte);
+    char _read(char address);
+    char _readOpcode;
+    char _writeOpcode;
+};
+
+#endif
\ No newline at end of file