# Documentation : MCP23018 ## Pinout and Pin assignments * `+` indicates connected pin * `o` indicates unconnected pin * `=` is used to list other things the pin is connected to * `-`s inserted between some of the pin functions for readability ### MCP23018 Vss(GND) +01---.---28+ NC NC +02 27+ GPA7 GPB0 +03 26+ GPA6 GPB1 +04 25+ GPA5 GPB2 +05 24+ GPA4 GPB3 +06 23+ GPA3 GPB4 +07 22+ GPA2 GPB5 +08 21+ GPA1 GPB6 +09 20+ GPA0 GPB7 +10 19+ INTA Vdd(Vcc) +11 18+ INTB SCL +12 17+ NC SDA +13 16+ RESET NC +14-------15+ ADDR ### MCP23018 Pin Assignments power_negative Vss(GND) +01---.---28o NC NC o02 27o GPA7 row_5 GPB0 +03 26+ GPA6 column_6 row_4 GPB1 +04 25+ GPA5 column_5 row_3 GPB2 +05 24+ GPA4 column_4 row_2 GPB3 +06 23+ GPA3 column_3 row_1 GPB4 +07 22+ GPA2 column_2 row_0 GPB5 +08 21+ GPA1 column_1 GPB6 o09 20+ GPA0 column_0 GPB7 o10 19o INTA power_positive Vdd(Vcc) +11 18o INTB I2C SCL +12 17o NC I2C SDA +13 16+ RESET = Vdd(Vcc) (see note) NC o14-------15+ ADDR = Vss(GND) (see note) * notes: * Row and column assignments are to matrix positions, which may or may or may not correspond to the physical position of the key: e.g. the key where `row_4` and `column_2` cross will be scanned into the matrix at `[4][2]`, wherever it happens to be located on the keyboard. Mapping from one to the other (which only matters for defining layouts) is handled elsewhere. * ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND). * The user-defined bits are the three least significant * I2C addresses are 7 bits long (the last bit in the byte is used for indicating read/write) * RESET (pin16) must be externally biased. Since we're not going to trigger it ourselves, we can tie it high. * This is not noted in the I2C Pinout Description section of the MCP23018 datasheet, but it's true (empirically), and it is noted in the SPI Pinout Description section, and in the MCP23017 datasheet. * I'm not the first person who's failed to notice ;) * * ## Notes about Registers register address function (for all bits) -------- ------- ----------------------- IODIRA 0x00 \ 1: set corresponding pin as input IODIRB 0x01 / 0: set ................. as output GPPUA 0x0C \ 1: set corresponding pin internal pull-up on GPPUB 0x0D / 0: set .......................... pull-up off GPIOA 0x12 \ read: returns the value on the port GPIOB 0x13 / write: modifies the OLAT register OLATA 0x14 \ read: returns the value of this register OLATB 0x15 / write: modifies the output latches that control the pins configured as output * IOCON register (see datasheet section 1.6, table 1-5, register 1-8) * BANK: bit 7; read/write; default = 0 * 1: The registers associated with each port are separated into different banks * 0: The registers are in the same bank (addresses are sequential) * SEQOP: bit 5; read/write; default = 0 * 1: Sequential operation disabled, address pointer does not increment * 0: Sequential operation enabled, address pointer increments * notes: * All addresses given for IOCON.BANK = 0, since that's the default value of the bit, and that's what we'll be using. * Initially, we want either columns or rows (see <../options.h>) set as hi-Z without pull-ups, and the other set of pins set as input with pull-ups. During the update function, we'll cycle through setting the first set low and checking each pin in the second set. * abbreviations: * IODIR = I/O Direction Register * IOCON = I/O Control Register * GPPU = GPIO Pull-Up Resistor Register * GPIO = General Purpose I/O Port Register * OLAT = Output Latch Register ## I²C Device Protocol (see datasheet section 1.3, figure 1-1) S : Start OP : Device opcode SR : Restart ADDR : Device address P : Stop Dout : Data out from MCP23018 W : Write Din : Data in to MCP23018 R : Read S OP W ADDR ----> Din ... Din --> P | |--> SR OP R Dout ... Dout ---> P |<--------------------------| | |--> SR OP W ADDR ... Din --> P | |--> P S OP R ----> Dout ... Dout --> P | |--> SR OP R Dout ... Dout ---> P |<--------------------------| | |--> SR OP W ADDR Din ... Din --> P | |--> P Byte and Sequential Write ------------------------- Byte : S OP W ADDR --> Din --> P Sequential : S OP W ADDR --> Din ... Din --> P Byte and Sequential Read ------------------------ Byte : S OP W ADDR --> SR OP R Dout --> P Sequential : S OP W ADDR --> SR OP R Dout ... Dout --> P * notes: * We'll be using sequential mode (ICON.SEQOP = 0; default) (see datasheet section 1.3.1). ------------------------------------------------------------------------------- Copyright © 2012 Ben Blazak Released under The MIT License (MIT) (see "license.md") Project located at