Romilly Cocking
/
MCP23S17Test
Library test v 0.4
main.cpp@4:15297eea34f6, 2010-08-28 (annotated)
- Committer:
- romilly
- Date:
- Sat Aug 28 09:51:44 2010 +0000
- Revision:
- 4:15297eea34f6
- Parent:
- 3:8f437a811ecf
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
romilly | 0:d58b942de71e | 1 | /* Test drive the MCP23S17 library |
romilly | 0:d58b942de71e | 2 | * Copyright (c) 2010 Romilly Cocking |
romilly | 0:d58b942de71e | 3 | * Released under the MIT License: http://mbed.org/license/mit |
romilly | 2:2e8fca65efaf | 4 | * |
romilly | 0:d58b942de71e | 5 | * See http://mbed.org/users/romilly/notebook/mcp23s17-addressable-16-bit-io-expander-with-spi/ |
romilly | 2:2e8fca65efaf | 6 | * |
romilly | 4:15297eea34f6 | 7 | * NB this code is intended to test the driver library, not the chip |
romilly | 2:2e8fca65efaf | 8 | * which is assumed to work as specified |
romilly | 2:2e8fca65efaf | 9 | * MCP23S17 datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf |
romilly | 4:15297eea34f6 | 10 | * version 0.4 |
romilly | 0:d58b942de71e | 11 | */ |
romilly | 2:2e8fca65efaf | 12 | |
romilly | 0:d58b942de71e | 13 | #include "mbed.h" |
romilly | 0:d58b942de71e | 14 | #include "MCP23S17.h" |
romilly | 0:d58b942de71e | 15 | |
romilly | 0:d58b942de71e | 16 | SPI spi(p5, p6, p7); |
romilly | 0:d58b942de71e | 17 | |
romilly | 2:2e8fca65efaf | 18 | // A0, A1, A2 of the MCP23S17 are tied to ground on the breadboard, so the 8-bit address for writes is 0x40 |
romilly | 2:2e8fca65efaf | 19 | // This is referred to as the opcode in the device datasheet |
romilly | 2:2e8fca65efaf | 20 | char writeOpcode = 0x40; |
romilly | 2:2e8fca65efaf | 21 | // mbed pin20 is connected to ~chipSelect of the MCP23S17 |
romilly | 2:2e8fca65efaf | 22 | MCP23S17 chip = MCP23S17(spi, p20, writeOpcode); // create MCP23S17 |
romilly | 2:2e8fca65efaf | 23 | DigitalOut chipNotReset(p14); // connected to ~reset of the MCP23S17 |
romilly | 2:2e8fca65efaf | 24 | DigitalInOut chipA0(p12); // connected to Port A bit 0 of the MCP23S17 |
romilly | 4:15297eea34f6 | 25 | DigitalInOut chipA1(p30); // connected to Port A bit 1 via 100k resistor |
romilly | 2:2e8fca65efaf | 26 | DigitalInOut chipB0(p10); // connected to Port B bit 0 of the MCP23S17 |
romilly | 2:2e8fca65efaf | 27 | DigitalIn chipIntA(p16); // connected to INTA on the MCP23S17 |
romilly | 2:2e8fca65efaf | 28 | DigitalIn chipIntB(p18); // connected to INTB on the MCP23S17 |
romilly | 0:d58b942de71e | 29 | |
romilly | 2:2e8fca65efaf | 30 | void reset() { |
romilly | 2:2e8fca65efaf | 31 | // I'm not sure we need the delays, but better safe than sorry. |
romilly | 4:15297eea34f6 | 32 | // Ensure mbed bi-directional pins set to input |
romilly | 4:15297eea34f6 | 33 | chipA0.input(); |
romilly | 4:15297eea34f6 | 34 | chipA1.input(); |
romilly | 4:15297eea34f6 | 35 | chipB0.input(); |
romilly | 2:2e8fca65efaf | 36 | chipNotReset = 0; // reset chip |
romilly | 2:2e8fca65efaf | 37 | wait_us(10); |
romilly | 2:2e8fca65efaf | 38 | chipNotReset = 1; |
romilly | 2:2e8fca65efaf | 39 | wait_us(10); |
romilly | 2:2e8fca65efaf | 40 | } |
romilly | 2:2e8fca65efaf | 41 | |
romilly | 2:2e8fca65efaf | 42 | void checkEqual(int expected, int actual, char * description) { |
romilly | 0:d58b942de71e | 43 | if (expected != actual) { |
romilly | 2:2e8fca65efaf | 44 | printf("%s **TEST FAILED** - expected %i but get %i\r\n", description, expected, actual); |
romilly | 0:d58b942de71e | 45 | exit(-1); |
romilly | 0:d58b942de71e | 46 | } |
romilly | 0:d58b942de71e | 47 | } |
romilly | 0:d58b942de71e | 48 | |
romilly | 2:2e8fca65efaf | 49 | void testInputFromPortA() { |
romilly | 2:2e8fca65efaf | 50 | reset(); |
romilly | 2:2e8fca65efaf | 51 | chipA0.output(); // prepare to output from the mbed |
romilly | 3:8f437a811ecf | 52 | chip.direction(PORT_A,0x01); // chip Port A bit 0 set to input |
romilly | 2:2e8fca65efaf | 53 | chipA0 = 0; |
romilly | 3:8f437a811ecf | 54 | checkEqual(0, chip.read(PORT_A) && 0x1,"read from A0"); |
romilly | 2:2e8fca65efaf | 55 | chipA0 = 1; |
romilly | 3:8f437a811ecf | 56 | checkEqual(1, chip.read(PORT_A) && 0x1,"read from A0"); |
romilly | 2:2e8fca65efaf | 57 | } |
romilly | 2:2e8fca65efaf | 58 | |
romilly | 2:2e8fca65efaf | 59 | void testInputFromPortB() { |
romilly | 2:2e8fca65efaf | 60 | reset(); |
romilly | 2:2e8fca65efaf | 61 | chipB0.output(); // output from the mbed |
romilly | 3:8f437a811ecf | 62 | chip.direction(PORT_B,0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 63 | chipB0 = 0; |
romilly | 3:8f437a811ecf | 64 | checkEqual(0, chip.read(PORT_B) && 0x1,"read from B0"); |
romilly | 2:2e8fca65efaf | 65 | chipB0 = 1; |
romilly | 3:8f437a811ecf | 66 | checkEqual(1, chip.read(PORT_B) && 0x1,"read from B0"); |
romilly | 2:2e8fca65efaf | 67 | } |
romilly | 2:2e8fca65efaf | 68 | |
romilly | 2:2e8fca65efaf | 69 | void testOutputToPortA() { |
romilly | 2:2e8fca65efaf | 70 | reset(); |
romilly | 2:2e8fca65efaf | 71 | chipA0.input(); // input to the mbed |
romilly | 3:8f437a811ecf | 72 | chip.direction(PORT_A, 0xFE); // bit 0 set to output |
romilly | 3:8f437a811ecf | 73 | chip.write(PORT_A,0x00); |
romilly | 2:2e8fca65efaf | 74 | checkEqual(0, int(chipA0),"write to A0"); |
romilly | 3:8f437a811ecf | 75 | chip.write(PORT_A,0x01); |
romilly | 2:2e8fca65efaf | 76 | checkEqual(1, int(chipA0),"write to A0"); |
romilly | 2:2e8fca65efaf | 77 | } |
romilly | 2:2e8fca65efaf | 78 | |
romilly | 2:2e8fca65efaf | 79 | void testOutputToPortB() { |
romilly | 2:2e8fca65efaf | 80 | reset(); |
romilly | 2:2e8fca65efaf | 81 | chipB0.input(); // input to the mbed |
romilly | 3:8f437a811ecf | 82 | chip.direction(PORT_B, 0xFE); // bit 0 set to output |
romilly | 3:8f437a811ecf | 83 | chip.write(PORT_B,0x00); |
romilly | 2:2e8fca65efaf | 84 | checkEqual(0, int(chipB0),"write to B0"); |
romilly | 3:8f437a811ecf | 85 | chip.write(PORT_B,0x01); |
romilly | 2:2e8fca65efaf | 86 | checkEqual(1, int(chipB0),"write to B0"); |
romilly | 2:2e8fca65efaf | 87 | } |
romilly | 2:2e8fca65efaf | 88 | |
romilly | 2:2e8fca65efaf | 89 | void testInterruptEnableOnPortA() { |
romilly | 2:2e8fca65efaf | 90 | // NB by default both int pins are Active-LOW |
romilly | 2:2e8fca65efaf | 91 | reset(); |
romilly | 1:d7fe22a24841 | 92 | chipA0.output(); // output from the mbed |
romilly | 3:8f437a811ecf | 93 | chip.direction(PORT_A, 0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 94 | chipA0 = 1; |
romilly | 2:2e8fca65efaf | 95 | checkEqual(1, int(chipIntA),"interrupts not yet enabled"); |
romilly | 2:2e8fca65efaf | 96 | chipA0 = 0; |
romilly | 3:8f437a811ecf | 97 | chip.interruptEnable(PORT_A, 0x01); // interupt enabled on pin A0 |
romilly | 2:2e8fca65efaf | 98 | checkEqual(1, int(chipIntA), "value has not changed"); |
romilly | 2:2e8fca65efaf | 99 | chipA0 = 1; |
romilly | 2:2e8fca65efaf | 100 | wait_us(1); // test fails without this - mbed is too darned fast! |
romilly | 2:2e8fca65efaf | 101 | checkEqual(0, int(chipIntA), "value has changed"); |
romilly | 2:2e8fca65efaf | 102 | } |
romilly | 2:2e8fca65efaf | 103 | |
romilly | 2:2e8fca65efaf | 104 | void testInterruptEnableOnPortB() { |
romilly | 2:2e8fca65efaf | 105 | // NB by default both int pins are Active-LOW |
romilly | 2:2e8fca65efaf | 106 | reset(); |
romilly | 2:2e8fca65efaf | 107 | chipB0.output(); // output from the mbed |
romilly | 3:8f437a811ecf | 108 | chip.direction(PORT_B, 0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 109 | chipB0 = 1; |
romilly | 3:8f437a811ecf | 110 | chip.interruptEnable(PORT_B, 0x01); // interupt enabled on pin 0 |
romilly | 4:15297eea34f6 | 111 | wait_us(1); |
romilly | 2:2e8fca65efaf | 112 | checkEqual(0, int(chipIntB), "interruptB"); |
romilly | 2:2e8fca65efaf | 113 | } |
romilly | 2:2e8fca65efaf | 114 | |
romilly | 2:2e8fca65efaf | 115 | void testMirrorInterrupts() { |
romilly | 2:2e8fca65efaf | 116 | reset(); |
romilly | 1:d7fe22a24841 | 117 | chipB0.output(); // output from the mbed |
romilly | 3:8f437a811ecf | 118 | chip.direction(PORT_B, 0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 119 | chipB0 = 1; |
romilly | 3:8f437a811ecf | 120 | chip.interruptEnable(PORT_B, 0x01); // interupt enabled on pin 0 |
romilly | 4:15297eea34f6 | 121 | wait_us(1); |
romilly | 2:2e8fca65efaf | 122 | checkEqual(0, int(chipIntB), "interruptB"); |
romilly | 2:2e8fca65efaf | 123 | checkEqual(1, int(chipIntA), "before mirroring"); // no interrupt A yet |
romilly | 2:2e8fca65efaf | 124 | chip.mirrorInterrupts(true); |
romilly | 4:15297eea34f6 | 125 | wait_us(1); |
romilly | 2:2e8fca65efaf | 126 | checkEqual(0, int(chipIntA), "after mirroring"); |
romilly | 2:2e8fca65efaf | 127 | chip.mirrorInterrupts(false); |
romilly | 4:15297eea34f6 | 128 | wait_us(1); |
romilly | 2:2e8fca65efaf | 129 | checkEqual(1, int(chipIntA), "after mirroring turned off"); |
romilly | 2:2e8fca65efaf | 130 | } |
romilly | 2:2e8fca65efaf | 131 | |
romilly | 2:2e8fca65efaf | 132 | void testInterruptPolarity() { |
romilly | 2:2e8fca65efaf | 133 | // NB by default both int pins are Active-LOW |
romilly | 3:8f437a811ecf | 134 | // interrupt off (so HIGH) after POR |
romilly | 2:2e8fca65efaf | 135 | reset(); |
romilly | 2:2e8fca65efaf | 136 | checkEqual(1, int(chipIntA),"interrupt ACTIVE_LOW by default"); |
romilly | 2:2e8fca65efaf | 137 | chip.interruptPolarity(ACTIVE_HIGH); |
romilly | 2:2e8fca65efaf | 138 | wait_us(1); |
romilly | 2:2e8fca65efaf | 139 | checkEqual(0, int(chipIntA), "interrupt ACTIVE_HIGH"); |
romilly | 2:2e8fca65efaf | 140 | chip.interruptPolarity(ACTIVE_LOW); |
romilly | 2:2e8fca65efaf | 141 | wait_us(1); |
romilly | 2:2e8fca65efaf | 142 | checkEqual(1, int(chipIntA), "interrupt ACTIVE_LOW"); |
romilly | 0:d58b942de71e | 143 | } |
romilly | 2:2e8fca65efaf | 144 | |
romilly | 2:2e8fca65efaf | 145 | void testInterruptControlAndDefaultValueOnPortA() { |
romilly | 4:15297eea34f6 | 146 | reset(); |
romilly | 4:15297eea34f6 | 147 | chipA0.output(); // output from the mbed |
romilly | 4:15297eea34f6 | 148 | chip.direction(PORT_A, 0x01); // bit 0 set to input |
romilly | 4:15297eea34f6 | 149 | chipA0 = 0; |
romilly | 4:15297eea34f6 | 150 | checkEqual(1, int(chipIntA),"interrupt ACTIVE_LOW by default"); |
romilly | 4:15297eea34f6 | 151 | chip.interruptEnable(PORT_A, 0x01); // interupt enabled on pin 0 |
romilly | 4:15297eea34f6 | 152 | chip.defaultValue(PORT_A, 0x01); // default value != input value |
romilly | 4:15297eea34f6 | 153 | checkEqual(1, int(chipIntA),"still no interrupt"); // interrupt control still set to interrupt on change |
romilly | 4:15297eea34f6 | 154 | chip.interruptControl(PORT_A, 0x01); |
romilly | 4:15297eea34f6 | 155 | wait_us(1); |
romilly | 4:15297eea34f6 | 156 | checkEqual(0, int(chipIntA), "expecting interrupt as default != input"); |
romilly | 4:15297eea34f6 | 157 | } |
romilly | 4:15297eea34f6 | 158 | |
romilly | 4:15297eea34f6 | 159 | void testConfigurePullUpsOnPortA() { |
romilly | 4:15297eea34f6 | 160 | reset(); |
romilly | 4:15297eea34f6 | 161 | chipA1.output(); |
romilly | 4:15297eea34f6 | 162 | checkEqual(0, chip.read(PORT_A), "without pull-up input should be 0"); |
romilly | 4:15297eea34f6 | 163 | chip.configurePullUps(PORT_A, 0x02); // pin A1 pull-up enabled |
romilly | 4:15297eea34f6 | 164 | checkEqual(2, chip.read(PORT_A), "pull-up should raise chip input to 1"); |
romilly | 2:2e8fca65efaf | 165 | } |
romilly | 2:2e8fca65efaf | 166 | |
romilly | 2:2e8fca65efaf | 167 | int main() { |
romilly | 2:2e8fca65efaf | 168 | testInputFromPortA(); |
romilly | 2:2e8fca65efaf | 169 | testInputFromPortB(); |
romilly | 2:2e8fca65efaf | 170 | testOutputToPortA(); |
romilly | 2:2e8fca65efaf | 171 | testOutputToPortB(); |
romilly | 2:2e8fca65efaf | 172 | testInterruptEnableOnPortA(); |
romilly | 2:2e8fca65efaf | 173 | testInterruptEnableOnPortB(); |
romilly | 2:2e8fca65efaf | 174 | testInterruptPolarity(); |
romilly | 2:2e8fca65efaf | 175 | testMirrorInterrupts(); |
romilly | 2:2e8fca65efaf | 176 | testInterruptControlAndDefaultValueOnPortA(); |
romilly | 4:15297eea34f6 | 177 | testConfigurePullUpsOnPortA(); |
romilly | 3:8f437a811ecf | 178 | // testInterruptControlAndDefaultValueOnPortB(); |
romilly | 3:8f437a811ecf | 179 | // testInterruptCaptureA(); |
romilly | 3:8f437a811ecf | 180 | // testInterruptCaptureB(); |
romilly | 2:2e8fca65efaf | 181 | printf("all tests OK\r\n"); |
romilly | 2:2e8fca65efaf | 182 | } |