Release 1.01
mcp23s08.cpp@0:b6d729ae4f27, 2019-07-25 (annotated)
- Committer:
- foxbrianr
- Date:
- Thu Jul 25 00:43:08 2019 +0000
- Revision:
- 0:b6d729ae4f27
- Child:
- 2:1d5204d29bc5
Baseline for testing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
foxbrianr | 0:b6d729ae4f27 | 1 | #include "mbed.h" |
foxbrianr | 0:b6d729ae4f27 | 2 | #include "mcp23s08.h" |
foxbrianr | 0:b6d729ae4f27 | 3 | |
foxbrianr | 0:b6d729ae4f27 | 4 | #define INPUT 0 |
foxbrianr | 0:b6d729ae4f27 | 5 | #define OUTPUT 1 |
foxbrianr | 0:b6d729ae4f27 | 6 | |
foxbrianr | 0:b6d729ae4f27 | 7 | #define LOW 0 |
foxbrianr | 0:b6d729ae4f27 | 8 | #define HIGH 1 |
foxbrianr | 0:b6d729ae4f27 | 9 | |
foxbrianr | 0:b6d729ae4f27 | 10 | 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 | 11 | format(8, 3); |
foxbrianr | 0:b6d729ae4f27 | 12 | frequency(2000000); |
foxbrianr | 0:b6d729ae4f27 | 13 | |
foxbrianr | 0:b6d729ae4f27 | 14 | postSetup(haenAdrs); |
foxbrianr | 0:b6d729ae4f27 | 15 | |
foxbrianr | 0:b6d729ae4f27 | 16 | } |
foxbrianr | 0:b6d729ae4f27 | 17 | |
foxbrianr | 0:b6d729ae4f27 | 18 | |
foxbrianr | 0:b6d729ae4f27 | 19 | void mcp23s08::postSetup(const uint8_t haenAdrs){ |
foxbrianr | 0:b6d729ae4f27 | 20 | if (haenAdrs >= 0x20 && haenAdrs <= 0x23){//HAEN works between 0x20...0x23 |
foxbrianr | 0:b6d729ae4f27 | 21 | _adrs = haenAdrs; |
foxbrianr | 0:b6d729ae4f27 | 22 | _useHaen = 1; |
foxbrianr | 0:b6d729ae4f27 | 23 | } else { |
foxbrianr | 0:b6d729ae4f27 | 24 | _adrs = 0; |
foxbrianr | 0:b6d729ae4f27 | 25 | _useHaen = 0; |
foxbrianr | 0:b6d729ae4f27 | 26 | } |
foxbrianr | 0:b6d729ae4f27 | 27 | _readCmd = (_adrs << 1) | 1; |
foxbrianr | 0:b6d729ae4f27 | 28 | _writeCmd = _adrs << 1; |
foxbrianr | 0:b6d729ae4f27 | 29 | //setup register values for this chip |
foxbrianr | 0:b6d729ae4f27 | 30 | IOCON = 0x05; |
foxbrianr | 0:b6d729ae4f27 | 31 | IODIR = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 32 | GPPU = 0x06; |
foxbrianr | 0:b6d729ae4f27 | 33 | GPIO = 0x09; |
foxbrianr | 0:b6d729ae4f27 | 34 | GPINTEN = 0x02; |
foxbrianr | 0:b6d729ae4f27 | 35 | IPOL = 0x01; |
foxbrianr | 0:b6d729ae4f27 | 36 | DEFVAL = 0x03; |
foxbrianr | 0:b6d729ae4f27 | 37 | INTF = 0x07; |
foxbrianr | 0:b6d729ae4f27 | 38 | INTCAP = 0x08; |
foxbrianr | 0:b6d729ae4f27 | 39 | OLAT = 0x0A; |
foxbrianr | 0:b6d729ae4f27 | 40 | INTCON = 0x04; |
foxbrianr | 0:b6d729ae4f27 | 41 | } |
foxbrianr | 0:b6d729ae4f27 | 42 | |
foxbrianr | 0:b6d729ae4f27 | 43 | void mcp23s08::begin(bool protocolInitOverride) { |
foxbrianr | 0:b6d729ae4f27 | 44 | |
foxbrianr | 0:b6d729ae4f27 | 45 | cs=1; |
foxbrianr | 0:b6d729ae4f27 | 46 | wait(0.1); |
foxbrianr | 0:b6d729ae4f27 | 47 | _useHaen == 1 ? writeByte(IOCON,0b00101000) : writeByte(IOCON,0b00100000); |
foxbrianr | 0:b6d729ae4f27 | 48 | /* |
foxbrianr | 0:b6d729ae4f27 | 49 | if (_useHaen){ |
foxbrianr | 0:b6d729ae4f27 | 50 | writeByte(IOCON,0b00101000);//read datasheet for details! |
foxbrianr | 0:b6d729ae4f27 | 51 | } else { |
foxbrianr | 0:b6d729ae4f27 | 52 | writeByte(IOCON,0b00100000); |
foxbrianr | 0:b6d729ae4f27 | 53 | } |
foxbrianr | 0:b6d729ae4f27 | 54 | */ |
foxbrianr | 0:b6d729ae4f27 | 55 | _gpioDirection = 0xFF;//all in |
foxbrianr | 0:b6d729ae4f27 | 56 | _gpioState = 0x00;//all low |
foxbrianr | 0:b6d729ae4f27 | 57 | } |
foxbrianr | 0:b6d729ae4f27 | 58 | |
foxbrianr | 0:b6d729ae4f27 | 59 | |
foxbrianr | 0:b6d729ae4f27 | 60 | uint8_t mcp23s08::readAddress(uint8_t addr){ |
foxbrianr | 0:b6d729ae4f27 | 61 | uint8_t low_byte = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 62 | startSend(1); |
foxbrianr | 0:b6d729ae4f27 | 63 | SPI::write(addr); |
foxbrianr | 0:b6d729ae4f27 | 64 | low_byte = (uint8_t)SPI::write(0x00); |
foxbrianr | 0:b6d729ae4f27 | 65 | endSend(); |
foxbrianr | 0:b6d729ae4f27 | 66 | return low_byte; |
foxbrianr | 0:b6d729ae4f27 | 67 | } |
foxbrianr | 0:b6d729ae4f27 | 68 | |
foxbrianr | 0:b6d729ae4f27 | 69 | |
foxbrianr | 0:b6d729ae4f27 | 70 | |
foxbrianr | 0:b6d729ae4f27 | 71 | void mcp23s08::gpioPinMode(uint8_t mode){ |
foxbrianr | 0:b6d729ae4f27 | 72 | if (mode == INPUT){ |
foxbrianr | 0:b6d729ae4f27 | 73 | _gpioDirection = 0xFF; |
foxbrianr | 0:b6d729ae4f27 | 74 | } else if (mode == OUTPUT){ |
foxbrianr | 0:b6d729ae4f27 | 75 | _gpioDirection = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 76 | _gpioState = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 77 | } else { |
foxbrianr | 0:b6d729ae4f27 | 78 | _gpioDirection = mode; |
foxbrianr | 0:b6d729ae4f27 | 79 | } |
foxbrianr | 0:b6d729ae4f27 | 80 | writeByte(IODIR,_gpioDirection); |
foxbrianr | 0:b6d729ae4f27 | 81 | } |
foxbrianr | 0:b6d729ae4f27 | 82 | |
foxbrianr | 0:b6d729ae4f27 | 83 | void mcp23s08::gpioPinMode(uint8_t pin, bool mode){ |
foxbrianr | 0:b6d729ae4f27 | 84 | if (pin < 8){//0...7 |
foxbrianr | 0:b6d729ae4f27 | 85 | mode == INPUT ? _gpioDirection |= (1 << pin) :_gpioDirection &= ~(1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 86 | writeByte(IODIR,_gpioDirection); |
foxbrianr | 0:b6d729ae4f27 | 87 | } |
foxbrianr | 0:b6d729ae4f27 | 88 | } |
foxbrianr | 0:b6d729ae4f27 | 89 | |
foxbrianr | 0:b6d729ae4f27 | 90 | void mcp23s08::gpioPort(uint8_t value){ |
foxbrianr | 0:b6d729ae4f27 | 91 | if (value == HIGH){ |
foxbrianr | 0:b6d729ae4f27 | 92 | _gpioState = 0xFF; |
foxbrianr | 0:b6d729ae4f27 | 93 | } else if (value == LOW){ |
foxbrianr | 0:b6d729ae4f27 | 94 | _gpioState = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 95 | } else { |
foxbrianr | 0:b6d729ae4f27 | 96 | _gpioState = value; |
foxbrianr | 0:b6d729ae4f27 | 97 | } |
foxbrianr | 0:b6d729ae4f27 | 98 | writeByte(GPIO,_gpioState); |
foxbrianr | 0:b6d729ae4f27 | 99 | } |
foxbrianr | 0:b6d729ae4f27 | 100 | |
foxbrianr | 0:b6d729ae4f27 | 101 | |
foxbrianr | 0:b6d729ae4f27 | 102 | uint8_t mcp23s08::readGpioPort(){ |
foxbrianr | 0:b6d729ae4f27 | 103 | return readAddress(GPIO); |
foxbrianr | 0:b6d729ae4f27 | 104 | } |
foxbrianr | 0:b6d729ae4f27 | 105 | |
foxbrianr | 0:b6d729ae4f27 | 106 | uint8_t mcp23s08::readGpioPortFast(){ |
foxbrianr | 0:b6d729ae4f27 | 107 | return _gpioState; |
foxbrianr | 0:b6d729ae4f27 | 108 | } |
foxbrianr | 0:b6d729ae4f27 | 109 | |
foxbrianr | 0:b6d729ae4f27 | 110 | int mcp23s08::gpioDigitalReadFast(uint8_t pin){ |
foxbrianr | 0:b6d729ae4f27 | 111 | if (pin < 8){//0...7 |
foxbrianr | 0:b6d729ae4f27 | 112 | int temp = _gpioState & (1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 113 | return temp; |
foxbrianr | 0:b6d729ae4f27 | 114 | } else { |
foxbrianr | 0:b6d729ae4f27 | 115 | return 0; |
foxbrianr | 0:b6d729ae4f27 | 116 | } |
foxbrianr | 0:b6d729ae4f27 | 117 | } |
foxbrianr | 0:b6d729ae4f27 | 118 | |
foxbrianr | 0:b6d729ae4f27 | 119 | void mcp23s08::portPullup(uint8_t data) { |
foxbrianr | 0:b6d729ae4f27 | 120 | if (data == HIGH){ |
foxbrianr | 0:b6d729ae4f27 | 121 | _gpioState = 0xFF; |
foxbrianr | 0:b6d729ae4f27 | 122 | } else if (data == LOW){ |
foxbrianr | 0:b6d729ae4f27 | 123 | _gpioState = 0x00; |
foxbrianr | 0:b6d729ae4f27 | 124 | } else { |
foxbrianr | 0:b6d729ae4f27 | 125 | _gpioState = data; |
foxbrianr | 0:b6d729ae4f27 | 126 | } |
foxbrianr | 0:b6d729ae4f27 | 127 | writeByte(GPPU, _gpioState); |
foxbrianr | 0:b6d729ae4f27 | 128 | } |
foxbrianr | 0:b6d729ae4f27 | 129 | |
foxbrianr | 0:b6d729ae4f27 | 130 | |
foxbrianr | 0:b6d729ae4f27 | 131 | |
foxbrianr | 0:b6d729ae4f27 | 132 | |
foxbrianr | 0:b6d729ae4f27 | 133 | void mcp23s08::gpioDigitalWrite(uint8_t pin, bool value){ |
foxbrianr | 0:b6d729ae4f27 | 134 | if (pin < 8){//0...7 |
foxbrianr | 0:b6d729ae4f27 | 135 | value == HIGH ? _gpioState |= (1 << pin) : _gpioState &= ~(1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 136 | writeByte(GPIO,_gpioState); |
foxbrianr | 0:b6d729ae4f27 | 137 | } |
foxbrianr | 0:b6d729ae4f27 | 138 | } |
foxbrianr | 0:b6d729ae4f27 | 139 | |
foxbrianr | 0:b6d729ae4f27 | 140 | void mcp23s08::gpioDigitalWriteFast(uint8_t pin, bool value){ |
foxbrianr | 0:b6d729ae4f27 | 141 | if (pin < 8){//0...8 |
foxbrianr | 0:b6d729ae4f27 | 142 | value == HIGH ? _gpioState |= (1 << pin) : _gpioState &= ~(1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 143 | } |
foxbrianr | 0:b6d729ae4f27 | 144 | } |
foxbrianr | 0:b6d729ae4f27 | 145 | |
foxbrianr | 0:b6d729ae4f27 | 146 | void mcp23s08::gpioPortUpdate(){ |
foxbrianr | 0:b6d729ae4f27 | 147 | writeByte(GPIO,_gpioState); |
foxbrianr | 0:b6d729ae4f27 | 148 | } |
foxbrianr | 0:b6d729ae4f27 | 149 | |
foxbrianr | 0:b6d729ae4f27 | 150 | int mcp23s08::gpioDigitalRead(uint8_t pin){ |
foxbrianr | 0:b6d729ae4f27 | 151 | if (pin < 8) return (int)(readAddress(GPIO) & 1 << pin); |
foxbrianr | 0:b6d729ae4f27 | 152 | return 0; |
foxbrianr | 0:b6d729ae4f27 | 153 | } |
foxbrianr | 0:b6d729ae4f27 | 154 | |
foxbrianr | 0:b6d729ae4f27 | 155 | uint8_t mcp23s08::gpioRegisterReadByte(uint8_t reg){ |
foxbrianr | 0:b6d729ae4f27 | 156 | uint8_t data = 0; |
foxbrianr | 0:b6d729ae4f27 | 157 | startSend(1); |
foxbrianr | 0:b6d729ae4f27 | 158 | SPI::write(reg); |
foxbrianr | 0:b6d729ae4f27 | 159 | data = (uint8_t)SPI::write(0x00); |
foxbrianr | 0:b6d729ae4f27 | 160 | endSend(); |
foxbrianr | 0:b6d729ae4f27 | 161 | return data; |
foxbrianr | 0:b6d729ae4f27 | 162 | } |
foxbrianr | 0:b6d729ae4f27 | 163 | |
foxbrianr | 0:b6d729ae4f27 | 164 | |
foxbrianr | 0:b6d729ae4f27 | 165 | void mcp23s08::gpioRegisterWriteByte(uint8_t reg,uint8_t data){ |
foxbrianr | 0:b6d729ae4f27 | 166 | writeByte(reg,(uint8_t)data); |
foxbrianr | 0:b6d729ae4f27 | 167 | } |
foxbrianr | 0:b6d729ae4f27 | 168 | |
foxbrianr | 0:b6d729ae4f27 | 169 | /* ------------------------------ Low Level ----------------*/ |
foxbrianr | 0:b6d729ae4f27 | 170 | void mcp23s08::startSend(bool mode){ |
foxbrianr | 0:b6d729ae4f27 | 171 | cs=0; |
foxbrianr | 0:b6d729ae4f27 | 172 | mode == 1 ? SPI::write(_readCmd) : SPI::write(_writeCmd); |
foxbrianr | 0:b6d729ae4f27 | 173 | } |
foxbrianr | 0:b6d729ae4f27 | 174 | |
foxbrianr | 0:b6d729ae4f27 | 175 | void mcp23s08::endSend(){ |
foxbrianr | 0:b6d729ae4f27 | 176 | cs=1; |
foxbrianr | 0:b6d729ae4f27 | 177 | } |
foxbrianr | 0:b6d729ae4f27 | 178 | |
foxbrianr | 0:b6d729ae4f27 | 179 | |
foxbrianr | 0:b6d729ae4f27 | 180 | void mcp23s08::writeByte(uint8_t addr, uint8_t data){ |
foxbrianr | 0:b6d729ae4f27 | 181 | startSend(0); |
foxbrianr | 0:b6d729ae4f27 | 182 | SPI::write(addr); |
foxbrianr | 0:b6d729ae4f27 | 183 | SPI::write(data); |
foxbrianr | 0:b6d729ae4f27 | 184 | endSend(); |
foxbrianr | 0:b6d729ae4f27 | 185 | } |