The iPod controller that I submitted for the mbed challenge

Dependencies:   mbed Motordriver PID

user_interface/MCP23017.h

Committer:
networker
Date:
2011-05-04
Revision:
0:371773dd3dd1

File content as of revision 0:371773dd3dd1:

/* 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 Initial Release
* version 0.3 Cleaned up
*/
#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 IOCON_ODR       0x04 // Open drain, also disables int polarity!
#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 };

extern DigitalOut Busy;

class MCP23017 {
    FunctionPointer fp;
    bool posted;
public:
    /** Create an MCP23017 object connected to the specified I2C object and using the specified deviceAddress
    *
    * @param I2C &i2c the I2C port to connect to
    * @param char deviceAddress the address of the MSC23017
    */
    MCP23017(I2C &i2c, char deviceAddress);
    MCP23017(const MCP23017& m):_i2c(m._i2c) {
        printf("copy constructor\n");
    }

    /** Set I/O direction of specified MCP23017 Port
    *
    * @param Port Port address (Port_A or Port_B)
    * @param char direction pin direction (0 = output, 1 = input)
    */
    void direction(Port port, char direction);

    /** Set Pull-Up Resistors on specified MCP23017 Port
    *
    * @param Port Port address (Port_A or Port_B)
    * @param char offOrOn per pin (0 = off, 1 = on)
    */
    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);

    /** Read from specified MCP23017 Port
    *
    * @param Port Port address (Port_A or Port_B)
    * @returns data from Port
    */
    char read(Port port);
    int readW(char address);
    /** Write to specified MCP23017 Port
    *
    * @param Port Port address (Port_A or Port_B)
    * @param char byte data to write
    */
    void write(Port port, char byte);
    void write(Port port, const char *buffer, int len, bool rpt=false);
    enum i2c_status { i2c_ok, i2c_busy, i2c_nack, i2c_pending};
    i2c_status _read(char reg, char *data, int size);
    i2c_status _write(char *data, int size, bool rpt = false);//first element of data is the register address
    bool testbusy() {
        __disable_irq();
        if (busy) {
            __enable_irq();
            return true;
        }
        busy = true;
        Busy = 1;
        __enable_irq();
        return false;
    }
    bool isbusy() {
        return busy;
    }
    void releasebusy() {
        busy = false;
        Busy = 0;
        if (posted) {
            posted = false;
            fp.call();
        }
    }
    template<typename T>
    void post(T *object, void (T::*member)()) {
        if (posted)
            return;
        fp.attach(object, member);
        posted = true;
    }
protected:
    I2C &_i2c;
    char _readOpcode;
    char _writeOpcode;
    bool busy;

    /** Init MCP23017
    *
    * @param
    * @returns
    */
    void _init();

    /** Write to specified MCP23017 register
    *
    * @param char address the internal registeraddress of the MSC23017
    */
    void _write(char address, char byte);

    /** Read from specified MCP23017 register
    *
    * @param char address the internal registeraddress of the MSC23017
    * @returns data from register
    */
    short _read(char address);
};

#endif