16-Bit I/O Expander with Serial Interface (SPI)
Dependents: relaekort_til_motorstyring Nucleo_MCP23S17_Test BSM02 POT_V_1_1
Diff: MCP23S17.cpp
- Revision:
- 2:b74bf9a31168
- Child:
- 3:b2a44e1e54b8
diff -r bc9b12ad251d -r b74bf9a31168 MCP23S17.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP23S17.cpp Tue Apr 21 16:20:23 2015 +0000 @@ -0,0 +1,372 @@ +/* mbed MCP23S17 Library, for driving the MCP23S17 16-Bit I/O Expander with Serial Interface (SPI) + * Copyright (c) 2015, Created by Steen Joergensen (stjo2809) inspired by Romilly Cocking MCP23S17 library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + #include "mbed.h" + #include "MCP23S17.h" + +//============================================================================= +// Public functions +//============================================================================= + + MCP23S17::MCP23S17(int hardwareaddress, SPI& spi, PinName nCs, PinName nReset) : _hardwareaddress(hardwareaddress), _spi(spi), _nCs(nCs), _nReset(nReset) + { + _make_opcode(_hardwareaddress); + _initialization(); + } + + MCP23S17::MCP23S17(int hardwareaddress, SPI& spi, PinName nCs) : _hardwareaddress(hardwareaddress), _spi(spi), _nCs(nCs), _nReset(NC) // _nReset(NC) added for the compiler + { + _make_opcode(_hardwareaddress); + _initialization(); + } + + char MCP23S17::read(char reg_address) + { + return _read(reg_address); + } + + void MCP23S17::write(char reg_address, char data) + { + _write(reg_address, data); + } + + void MCP23S17::bit(char reg_address, int bitnumber, bool high_low) + { + char i; + + if(bitnumber >= 1 || bitnumber <= 8) + { + if(high_low == 1) + { + i = _read(reg_address); + i = i | (0x01 << (bitnumber-1)); + _write(reg_address, i); + } + if(high_low == 0) + { + i = _read(reg_address); + i = i & ~(0x01 << (bitnumber-1)); + _write(reg_address, i); + } + } + } + + void MCP23S17::reset() + { + _nReset = 0; + wait_us(5); + _nReset = 1; + _initialization(); + } + + char MCP23S17::iodira() + { + return _read(IODIRA_ADDR); + } + + void MCP23S17::iodira(char data) + { + _write(IODIRA_ADDR, data); + } + + char MCP23S17::iodirb() + { + return _read(IODIRB_ADDR); + } + + void MCP23S17::iodirb(char data) + { + _write(IODIRB_ADDR, data); + } + + char MCP23S17::ipola() + { + return _read(IPOLA_ADDR); + } + + void MCP23S17::ipola(char data) + { + _write(IPOLA_ADDR, data); + } + + char MCP23S17::ipolb() + { + return _read(IPOLB_ADDR); + } + + void MCP23S17::ipolb(char data) + { + _write(IPOLB_ADDR, data); + } + + char MCP23S17::gpintena() + { + return _read(GPINTENA_ADDR); + } + + void MCP23S17::gpintena(char data) + { + _write(GPINTENA_ADDR, data); + } + + char MCP23S17::gpintenb() + { + return _read(GPINTENB_ADDR); + } + + void MCP23S17::gpintenb(char data) + { + _write(GPINTENB_ADDR, data); + } + + char MCP23S17::defvala() + { + return _read(DEFVALA_ADDR); + } + + void MCP23S17::defvala(char data) + { + _write(DEFVALA_ADDR, data); + } + + char MCP23S17::defvalb() + { + return _read(DEFVALB_ADDR); + } + + void MCP23S17::defvalb(char data) + { + _write(DEFVALB_ADDR, data); + } + + char MCP23S17::intcona() + { + return _read(INTCONA_ADDR); + } + + void MCP23S17::intcona(char data) + { + _write(INTCONA_ADDR, data); + } + + char MCP23S17::intconb() + { + return _read(INTCONB_ADDR); + } + + void MCP23S17::intconb(char data) + { + _write(INTCONB_ADDR, data); + } + + char MCP23S17::iocon() + { + return _read(IOCON_ADDR); + } + + void MCP23S17::iocon(char data) + { + _write(IOCON_ADDR, data); + } + + char MCP23S17::gppua() + { + return _read(GPPUA_ADDR); + } + + void MCP23S17::gppua(char data) + { + _write(GPPUA_ADDR, data); + } + + char MCP23S17::gppub() + { + return _read(GPPUB_ADDR); + } + + void MCP23S17::gppub(char data) + { + _write(GPPUB_ADDR, data); + } + + char MCP23S17::intfa() + { + return _read(INTFA_ADDR); + } + + char MCP23S17::intfb() + { + return _read(INTFB_ADDR); + } + + char MCP23S17::intcapa() + { + return _read(INTCAPA_ADDR); + } + + char MCP23S17::intcapb() + { + return _read(INTCAPB_ADDR); + } + + char MCP23S17::gpioa() + { + return _read(GPIOA_ADDR); + } + + void MCP23S17::gpioa(char data) + { + _write(GPIOA_ADDR, data); + } + + char MCP23S17::gpiob() + { + return _read(GPIOB_ADDR); + } + + void MCP23S17::gpiob(char data) + { + _write(GPIOB_ADDR, data); + } + + char MCP23S17::olata() + { + return _read(OLATA_ADDR); + } + + void MCP23S17::olata(char data) + { + _write(OLATA_ADDR, data); + } + + char MCP23S17::olatb() + { + return _read(OLATB_ADDR); + } + + void MCP23S17::olatb(char data) + { + _write(OLATB_ADDR, data); + } + + void MCP23S17::intmirror(bool mirror) + { + char kopi_iocon = _read(IOCON_ADDR); + if (mirror) + { + kopi_iocon = kopi_iocon | INTERRUPT_MIRROR_BIT; + } + else + { + kopi_iocon = kopi_iocon & ~INTERRUPT_MIRROR_BIT; + } + _write(IOCON_ADDR, kopi_iocon); + } + + void MCP23S17::intpol(bool polarity) + { + char kopi_iocon = _read(IOCON_ADDR); + if (polarity == false) + { + kopi_iocon = kopi_iocon | INTERRUPT_POLARITY_BIT; + } + else + { + kopi_iocon = kopi_iocon & ~INTERRUPT_POLARITY_BIT; + } + _write(IOCON_ADDR, kopi_iocon); + } + +//============================================================================= +// Private functions +//============================================================================= + + void MCP23S17::_initialization() + { + _write(IOCON_ADDR, 0x2A); // setup af control register (BANK = 0, MIRROR = 0, SEQOP = 1, DISSLW = 0, HAEN = 1, ODR = 0, INTPOL = 1, NC = 0) + } + + void MCP23S17::_make_opcode(int _hardwareaddress) + { + switch(_hardwareaddress) + { + case 0: + _writeopcode = 0x40; + _readopcode = 0x41; + break; + + case 1: + _writeopcode = 0x42; + _readopcode = 0x43; + break; + + case 2: + _writeopcode = 0x44; + _readopcode = 0x45; + break; + + case 3: + _writeopcode = 0x46; + _readopcode = 0x47; + break; + + case 4: + _writeopcode = 0x48; + _readopcode = 0x49; + break; + + case 5: + _writeopcode = 0x4A; + _readopcode = 0x4B; + break; + + case 6: + _writeopcode = 0x4C; + _readopcode = 0x4D; + break; + + case 7: + _writeopcode = 0x4E; + _readopcode = 0x4F; + break; + } + } + + char MCP23S17::_read(char address) + { + _nCs = 0; + _spi.write(_readopcode); + _spi.write(address); + char response = _spi.write(0xFF); // 0xFF data to get response + _nCs = 1; + return response; + } + + void MCP23S17::_write(char address, char data) + { + _nCs = 0; + _spi.write(_writeopcode); + _spi.write(address); + _spi.write(data); + _nCs = 1; + } +