Release 1.01
mcp23s08.cpp@2:1d5204d29bc5, 2019-09-17 (annotated)
- Committer:
- foxbrianr
- Date:
- Tue Sep 17 13:48:28 2019 +0000
- Revision:
- 2:1d5204d29bc5
- Parent:
- 0:b6d729ae4f27
Beta 2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
foxbrianr | 2:1d5204d29bc5 | 1 | /**************************************************************************//** |
foxbrianr | 2:1d5204d29bc5 | 2 | * @file mcp23s08.cpp |
foxbrianr | 2:1d5204d29bc5 | 3 | * @brief Base class for wrapping the interface with the GPIO Extender . |
foxbrianr | 2:1d5204d29bc5 | 4 | * @version: V1.0 |
foxbrianr | 2:1d5204d29bc5 | 5 | * @date: 9/17/2019 |
foxbrianr | 2:1d5204d29bc5 | 6 | |
foxbrianr | 2:1d5204d29bc5 | 7 | * |
foxbrianr | 2:1d5204d29bc5 | 8 | * @note |
foxbrianr | 2:1d5204d29bc5 | 9 | * Copyright (C) 2019 E3 Design. All rights reserved. |
foxbrianr | 2:1d5204d29bc5 | 10 | * |
foxbrianr | 2:1d5204d29bc5 | 11 | * @par |
foxbrianr | 2:1d5204d29bc5 | 12 | * E3 Designers LLC is supplying this software for use with Cortex-M3 LPC1768 |
foxbrianr | 2:1d5204d29bc5 | 13 | * processor based microcontroller for the ESCM 2000 Monitor and Display. |
foxbrianr | 2:1d5204d29bc5 | 14 | * * |
foxbrianr | 2:1d5204d29bc5 | 15 | * @par |
foxbrianr | 2:1d5204d29bc5 | 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED |
foxbrianr | 2:1d5204d29bc5 | 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
foxbrianr | 2:1d5204d29bc5 | 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. |
foxbrianr | 2:1d5204d29bc5 | 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR |
foxbrianr | 2:1d5204d29bc5 | 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
foxbrianr | 2:1d5204d29bc5 | 21 | * |
foxbrianr | 2:1d5204d29bc5 | 22 | ******************************************************************************/ |
foxbrianr | 0:b6d729ae4f27 | 23 | #include "mbed.h" |
foxbrianr | 0:b6d729ae4f27 | 24 | #include "mcp23s08.h" |
foxbrianr | 0:b6d729ae4f27 | 25 | |
foxbrianr | 0:b6d729ae4f27 | 26 | #define INPUT 0 |
foxbrianr | 0:b6d729ae4f27 | 27 | #define OUTPUT 1 |
foxbrianr | 0:b6d729ae4f27 | 28 | |
foxbrianr | 0:b6d729ae4f27 | 29 | #define LOW 0 |
foxbrianr | 0:b6d729ae4f27 | 30 | #define HIGH 1 |
foxbrianr | 0:b6d729ae4f27 | 31 | |
foxbrianr | 0:b6d729ae4f27 | 32 | mcp23s08::mcp23s08(PinName mosi, PinName miso, PinName clk, PinName cs_pin,const uint8_t haenAdrs) : SPI(mosi, miso, clk), cs(cs_pin) { |
foxbrianr | 0:b6d729ae4f27 | 33 | format(8, 3); |
foxbrianr | 0:b6d729ae4f27 | 34 | frequency(2000000); |
foxbrianr | 0:b6d729ae4f27 | 35 | |
foxbrianr | 0:b6d729ae4f27 | 36 | postSetup(haenAdrs); |
foxbrianr | 0:b6d729ae4f27 | 37 | |
foxbrianr | 0:b6d729ae4f27 | 38 | } |
foxbrianr | 0:b6d729ae4f27 | 39 | |
foxbrianr | 0:b6d729ae4f27 | 40 | |
foxbrianr | 0:b6d729ae4f27 | 41 | void mcp23s08::postSetup(const uint8_t haenAdrs){ |
foxbrianr | 0:b6d729ae4f27 | 42 | if (haenAdrs >= 0x20 && haenAdrs <= 0x23){//HAEN works between 0x20...0x23 |
foxbrianr | 0:b6d729ae4f27 | 43 | _adrs = haenAdrs; |
foxbrianr | 0:b6d729ae4f27 | 44 | _useHaen = 1; |
foxbrianr | 0:b6d729ae4f27 | 45 | } else { |
foxbrianr | 0:b6d729ae4f27 | 46 | _adrs = 0; |
foxbrianr | 0:b6d729ae4f27 | 47 | _useHaen = 0; |
foxbrianr | 0:b6d729ae4f27 | 48 | } |
foxbrianr | 0:b6d729ae4f27 | 49 | _readCmd = (_adrs << 1) | 1; |
foxbrianr | 0:b6d729ae4f27 | 50 | _writeCmd = _adrs << 1; |
foxbrianr | 0:b6d729ae4f27 | 51 | //setup register values for this chip |
foxbrianr | 0:b6d729ae4f27 | 52 | IOCON = 0x05; |
foxbrianr | 0:b6d729ae4f27 | 53 | IODIR = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 54 | GPPU = 0x06; |
foxbrianr | 0:b6d729ae4f27 | 55 | GPIO = 0x09; |
foxbrianr | 0:b6d729ae4f27 | 56 | GPINTEN = 0x02; |
foxbrianr | 0:b6d729ae4f27 | 57 | IPOL = 0x01; |
foxbrianr | 0:b6d729ae4f27 | 58 | DEFVAL = 0x03; |
foxbrianr | 0:b6d729ae4f27 | 59 | INTF = 0x07; |
foxbrianr | 0:b6d729ae4f27 | 60 | INTCAP = 0x08; |
foxbrianr | 0:b6d729ae4f27 | 61 | OLAT = 0x0A; |
foxbrianr | 0:b6d729ae4f27 | 62 | INTCON = 0x04; |
foxbrianr | 0:b6d729ae4f27 | 63 | } |
foxbrianr | 0:b6d729ae4f27 | 64 | |
foxbrianr | 0:b6d729ae4f27 | 65 | void mcp23s08::begin(bool protocolInitOverride) { |
foxbrianr | 0:b6d729ae4f27 | 66 | |
foxbrianr | 0:b6d729ae4f27 | 67 | cs=1; |
foxbrianr | 0:b6d729ae4f27 | 68 | wait(0.1); |
foxbrianr | 0:b6d729ae4f27 | 69 | _useHaen == 1 ? writeByte(IOCON,0b00101000) : writeByte(IOCON,0b00100000); |
foxbrianr | 0:b6d729ae4f27 | 70 | /* |
foxbrianr | 0:b6d729ae4f27 | 71 | if (_useHaen){ |
foxbrianr | 0:b6d729ae4f27 | 72 | writeByte(IOCON,0b00101000);//read datasheet for details! |
foxbrianr | 0:b6d729ae4f27 | 73 | } else { |
foxbrianr | 0:b6d729ae4f27 | 74 | writeByte(IOCON,0b00100000); |
foxbrianr | 0:b6d729ae4f27 | 75 | } |
foxbrianr | 0:b6d729ae4f27 | 76 | */ |
foxbrianr | 0:b6d729ae4f27 | 77 | _gpioDirection = 0xFF;//all in |
foxbrianr | 0:b6d729ae4f27 | 78 | _gpioState = 0x00;//all low |
foxbrianr | 0:b6d729ae4f27 | 79 | } |
foxbrianr | 0:b6d729ae4f27 | 80 | |
foxbrianr | 0:b6d729ae4f27 | 81 | |
foxbrianr | 0:b6d729ae4f27 | 82 | uint8_t mcp23s08::readAddress(uint8_t addr){ |
foxbrianr | 0:b6d729ae4f27 | 83 | uint8_t low_byte = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 84 | startSend(1); |
foxbrianr | 0:b6d729ae4f27 | 85 | SPI::write(addr); |
foxbrianr | 0:b6d729ae4f27 | 86 | low_byte = (uint8_t)SPI::write(0x00); |
foxbrianr | 0:b6d729ae4f27 | 87 | endSend(); |
foxbrianr | 0:b6d729ae4f27 | 88 | return low_byte; |
foxbrianr | 0:b6d729ae4f27 | 89 | } |
foxbrianr | 0:b6d729ae4f27 | 90 | |
foxbrianr | 0:b6d729ae4f27 | 91 | |
foxbrianr | 0:b6d729ae4f27 | 92 | |
foxbrianr | 0:b6d729ae4f27 | 93 | void mcp23s08::gpioPinMode(uint8_t mode){ |
foxbrianr | 0:b6d729ae4f27 | 94 | if (mode == INPUT){ |
foxbrianr | 0:b6d729ae4f27 | 95 | _gpioDirection = 0xFF; |
foxbrianr | 0:b6d729ae4f27 | 96 | } else if (mode == OUTPUT){ |
foxbrianr | 0:b6d729ae4f27 | 97 | _gpioDirection = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 98 | _gpioState = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 99 | } else { |
foxbrianr | 0:b6d729ae4f27 | 100 | _gpioDirection = mode; |
foxbrianr | 0:b6d729ae4f27 | 101 | } |
foxbrianr | 0:b6d729ae4f27 | 102 | writeByte(IODIR,_gpioDirection); |
foxbrianr | 0:b6d729ae4f27 | 103 | } |
foxbrianr | 0:b6d729ae4f27 | 104 | |
foxbrianr | 0:b6d729ae4f27 | 105 | void mcp23s08::gpioPinMode(uint8_t pin, bool mode){ |
foxbrianr | 0:b6d729ae4f27 | 106 | if (pin < 8){//0...7 |
foxbrianr | 0:b6d729ae4f27 | 107 | mode == INPUT ? _gpioDirection |= (1 << pin) :_gpioDirection &= ~(1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 108 | writeByte(IODIR,_gpioDirection); |
foxbrianr | 0:b6d729ae4f27 | 109 | } |
foxbrianr | 0:b6d729ae4f27 | 110 | } |
foxbrianr | 0:b6d729ae4f27 | 111 | |
foxbrianr | 0:b6d729ae4f27 | 112 | void mcp23s08::gpioPort(uint8_t value){ |
foxbrianr | 0:b6d729ae4f27 | 113 | if (value == HIGH){ |
foxbrianr | 0:b6d729ae4f27 | 114 | _gpioState = 0xFF; |
foxbrianr | 0:b6d729ae4f27 | 115 | } else if (value == LOW){ |
foxbrianr | 0:b6d729ae4f27 | 116 | _gpioState = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 117 | } else { |
foxbrianr | 0:b6d729ae4f27 | 118 | _gpioState = value; |
foxbrianr | 0:b6d729ae4f27 | 119 | } |
foxbrianr | 0:b6d729ae4f27 | 120 | writeByte(GPIO,_gpioState); |
foxbrianr | 0:b6d729ae4f27 | 121 | } |
foxbrianr | 0:b6d729ae4f27 | 122 | |
foxbrianr | 0:b6d729ae4f27 | 123 | |
foxbrianr | 0:b6d729ae4f27 | 124 | uint8_t mcp23s08::readGpioPort(){ |
foxbrianr | 0:b6d729ae4f27 | 125 | return readAddress(GPIO); |
foxbrianr | 0:b6d729ae4f27 | 126 | } |
foxbrianr | 0:b6d729ae4f27 | 127 | |
foxbrianr | 0:b6d729ae4f27 | 128 | uint8_t mcp23s08::readGpioPortFast(){ |
foxbrianr | 0:b6d729ae4f27 | 129 | return _gpioState; |
foxbrianr | 0:b6d729ae4f27 | 130 | } |
foxbrianr | 0:b6d729ae4f27 | 131 | |
foxbrianr | 0:b6d729ae4f27 | 132 | int mcp23s08::gpioDigitalReadFast(uint8_t pin){ |
foxbrianr | 0:b6d729ae4f27 | 133 | if (pin < 8){//0...7 |
foxbrianr | 0:b6d729ae4f27 | 134 | int temp = _gpioState & (1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 135 | return temp; |
foxbrianr | 0:b6d729ae4f27 | 136 | } else { |
foxbrianr | 0:b6d729ae4f27 | 137 | return 0; |
foxbrianr | 0:b6d729ae4f27 | 138 | } |
foxbrianr | 0:b6d729ae4f27 | 139 | } |
foxbrianr | 0:b6d729ae4f27 | 140 | |
foxbrianr | 0:b6d729ae4f27 | 141 | void mcp23s08::portPullup(uint8_t data) { |
foxbrianr | 0:b6d729ae4f27 | 142 | if (data == HIGH){ |
foxbrianr | 0:b6d729ae4f27 | 143 | _gpioState = 0xFF; |
foxbrianr | 0:b6d729ae4f27 | 144 | } else if (data == LOW){ |
foxbrianr | 0:b6d729ae4f27 | 145 | _gpioState = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 146 | } else { |
foxbrianr | 0:b6d729ae4f27 | 147 | _gpioState = data; |
foxbrianr | 0:b6d729ae4f27 | 148 | } |
foxbrianr | 0:b6d729ae4f27 | 149 | writeByte(GPPU, _gpioState); |
foxbrianr | 0:b6d729ae4f27 | 150 | } |
foxbrianr | 0:b6d729ae4f27 | 151 | |
foxbrianr | 0:b6d729ae4f27 | 152 | |
foxbrianr | 0:b6d729ae4f27 | 153 | |
foxbrianr | 0:b6d729ae4f27 | 154 | |
foxbrianr | 0:b6d729ae4f27 | 155 | void mcp23s08::gpioDigitalWrite(uint8_t pin, bool value){ |
foxbrianr | 0:b6d729ae4f27 | 156 | if (pin < 8){//0...7 |
foxbrianr | 0:b6d729ae4f27 | 157 | value == HIGH ? _gpioState |= (1 << pin) : _gpioState &= ~(1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 158 | writeByte(GPIO,_gpioState); |
foxbrianr | 0:b6d729ae4f27 | 159 | } |
foxbrianr | 0:b6d729ae4f27 | 160 | } |
foxbrianr | 0:b6d729ae4f27 | 161 | |
foxbrianr | 0:b6d729ae4f27 | 162 | void mcp23s08::gpioDigitalWriteFast(uint8_t pin, bool value){ |
foxbrianr | 0:b6d729ae4f27 | 163 | if (pin < 8){//0...8 |
foxbrianr | 0:b6d729ae4f27 | 164 | value == HIGH ? _gpioState |= (1 << pin) : _gpioState &= ~(1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 165 | } |
foxbrianr | 0:b6d729ae4f27 | 166 | } |
foxbrianr | 0:b6d729ae4f27 | 167 | |
foxbrianr | 0:b6d729ae4f27 | 168 | void mcp23s08::gpioPortUpdate(){ |
foxbrianr | 0:b6d729ae4f27 | 169 | writeByte(GPIO,_gpioState); |
foxbrianr | 0:b6d729ae4f27 | 170 | } |
foxbrianr | 0:b6d729ae4f27 | 171 | |
foxbrianr | 0:b6d729ae4f27 | 172 | int mcp23s08::gpioDigitalRead(uint8_t pin){ |
foxbrianr | 0:b6d729ae4f27 | 173 | if (pin < 8) return (int)(readAddress(GPIO) & 1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 174 | return 0; |
foxbrianr | 0:b6d729ae4f27 | 175 | } |
foxbrianr | 0:b6d729ae4f27 | 176 | |
foxbrianr | 0:b6d729ae4f27 | 177 | uint8_t mcp23s08::gpioRegisterReadByte(uint8_t reg){ |
foxbrianr | 0:b6d729ae4f27 | 178 | uint8_t data = 0; |
foxbrianr | 0:b6d729ae4f27 | 179 | startSend(1); |
foxbrianr | 0:b6d729ae4f27 | 180 | SPI::write(reg); |
foxbrianr | 0:b6d729ae4f27 | 181 | data = (uint8_t)SPI::write(0x00); |
foxbrianr | 0:b6d729ae4f27 | 182 | endSend(); |
foxbrianr | 0:b6d729ae4f27 | 183 | return data; |
foxbrianr | 0:b6d729ae4f27 | 184 | } |
foxbrianr | 0:b6d729ae4f27 | 185 | |
foxbrianr | 0:b6d729ae4f27 | 186 | |
foxbrianr | 0:b6d729ae4f27 | 187 | void mcp23s08::gpioRegisterWriteByte(uint8_t reg,uint8_t data){ |
foxbrianr | 0:b6d729ae4f27 | 188 | writeByte(reg,(uint8_t)data); |
foxbrianr | 0:b6d729ae4f27 | 189 | } |
foxbrianr | 0:b6d729ae4f27 | 190 | |
foxbrianr | 0:b6d729ae4f27 | 191 | /* ------------------------------ Low Level ----------------*/ |
foxbrianr | 0:b6d729ae4f27 | 192 | void mcp23s08::startSend(bool mode){ |
foxbrianr | 0:b6d729ae4f27 | 193 | cs=0; |
foxbrianr | 0:b6d729ae4f27 | 194 | mode == 1 ? SPI::write(_readCmd) : SPI::write(_writeCmd); |
foxbrianr | 0:b6d729ae4f27 | 195 | } |
foxbrianr | 0:b6d729ae4f27 | 196 | |
foxbrianr | 0:b6d729ae4f27 | 197 | void mcp23s08::endSend(){ |
foxbrianr | 0:b6d729ae4f27 | 198 | cs=1; |
foxbrianr | 0:b6d729ae4f27 | 199 | } |
foxbrianr | 0:b6d729ae4f27 | 200 | |
foxbrianr | 0:b6d729ae4f27 | 201 | |
foxbrianr | 0:b6d729ae4f27 | 202 | void mcp23s08::writeByte(uint8_t addr, uint8_t data){ |
foxbrianr | 0:b6d729ae4f27 | 203 | startSend(0); |
foxbrianr | 0:b6d729ae4f27 | 204 | SPI::write(addr); |
foxbrianr | 0:b6d729ae4f27 | 205 | SPI::write(data); |
foxbrianr | 0:b6d729ae4f27 | 206 | endSend(); |
foxbrianr | 0:b6d729ae4f27 | 207 | } |