Romilly Cocking
/
MCP23S17Test
Library test v 0.4
main.cpp@2:2e8fca65efaf, 2010-08-22 (annotated)
- Committer:
- romilly
- Date:
- Sun Aug 22 15:39:32 2010 +0000
- Revision:
- 2:2e8fca65efaf
- Parent:
- 1:d7fe22a24841
- Child:
- 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 | 2:2e8fca65efaf | 7 | * NB this code is inteded 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 | 2:2e8fca65efaf | 10 | * version 0.2 |
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 | 2:2e8fca65efaf | 25 | DigitalInOut chipB0(p10); // connected to Port B bit 0 of the MCP23S17 |
romilly | 2:2e8fca65efaf | 26 | DigitalIn chipIntA(p16); // connected to INTA on the MCP23S17 |
romilly | 2:2e8fca65efaf | 27 | DigitalIn chipIntB(p18); // connected to INTB on the MCP23S17 |
romilly | 0:d58b942de71e | 28 | |
romilly | 2:2e8fca65efaf | 29 | void reset() { |
romilly | 2:2e8fca65efaf | 30 | // I'm not sure we need the delays, but better safe than sorry. |
romilly | 2:2e8fca65efaf | 31 | chipNotReset = 0; // reset chip |
romilly | 2:2e8fca65efaf | 32 | wait_us(10); |
romilly | 2:2e8fca65efaf | 33 | chipNotReset = 1; |
romilly | 2:2e8fca65efaf | 34 | wait_us(10); |
romilly | 2:2e8fca65efaf | 35 | } |
romilly | 2:2e8fca65efaf | 36 | |
romilly | 2:2e8fca65efaf | 37 | void checkEqual(int expected, int actual, char * description) { |
romilly | 0:d58b942de71e | 38 | if (expected != actual) { |
romilly | 2:2e8fca65efaf | 39 | printf("%s **TEST FAILED** - expected %i but get %i\r\n", description, expected, actual); |
romilly | 0:d58b942de71e | 40 | exit(-1); |
romilly | 0:d58b942de71e | 41 | } |
romilly | 0:d58b942de71e | 42 | } |
romilly | 0:d58b942de71e | 43 | |
romilly | 2:2e8fca65efaf | 44 | void testInputFromPortA() { |
romilly | 2:2e8fca65efaf | 45 | reset(); |
romilly | 2:2e8fca65efaf | 46 | chipA0.output(); // prepare to output from the mbed |
romilly | 2:2e8fca65efaf | 47 | chip.directionA(0x01); // chip Port A bit 0 set to input |
romilly | 2:2e8fca65efaf | 48 | chipA0 = 0; |
romilly | 2:2e8fca65efaf | 49 | checkEqual(0, chip.inputA() && 0x1,"read from A0"); |
romilly | 2:2e8fca65efaf | 50 | chipA0 = 1; |
romilly | 2:2e8fca65efaf | 51 | checkEqual(1, chip.inputA() && 0x1,"read from A0"); |
romilly | 2:2e8fca65efaf | 52 | } |
romilly | 2:2e8fca65efaf | 53 | |
romilly | 2:2e8fca65efaf | 54 | void testInputFromPortB() { |
romilly | 2:2e8fca65efaf | 55 | reset(); |
romilly | 2:2e8fca65efaf | 56 | chipB0.output(); // output from the mbed |
romilly | 2:2e8fca65efaf | 57 | chip.directionB(0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 58 | chipB0 = 0; |
romilly | 2:2e8fca65efaf | 59 | checkEqual(0, chip.inputB() && 0x1,"read from B0"); |
romilly | 2:2e8fca65efaf | 60 | chipB0 = 1; |
romilly | 2:2e8fca65efaf | 61 | checkEqual(1, chip.inputB() && 0x1,"read from B0"); |
romilly | 2:2e8fca65efaf | 62 | } |
romilly | 2:2e8fca65efaf | 63 | |
romilly | 2:2e8fca65efaf | 64 | void testOutputToPortA() { |
romilly | 2:2e8fca65efaf | 65 | reset(); |
romilly | 2:2e8fca65efaf | 66 | chipA0.input(); // input to the mbed |
romilly | 2:2e8fca65efaf | 67 | chip.directionA(0xFE); // bit 0 set to output |
romilly | 2:2e8fca65efaf | 68 | chip.outputA(0x00); |
romilly | 2:2e8fca65efaf | 69 | checkEqual(0, int(chipA0),"write to A0"); |
romilly | 2:2e8fca65efaf | 70 | chip.outputA(0x01); |
romilly | 2:2e8fca65efaf | 71 | checkEqual(1, int(chipA0),"write to A0"); |
romilly | 2:2e8fca65efaf | 72 | } |
romilly | 2:2e8fca65efaf | 73 | |
romilly | 2:2e8fca65efaf | 74 | void testOutputToPortB() { |
romilly | 2:2e8fca65efaf | 75 | reset(); |
romilly | 2:2e8fca65efaf | 76 | chipB0.input(); // input to the mbed |
romilly | 2:2e8fca65efaf | 77 | chip.directionB(0xFE); // bit 0 set to output |
romilly | 2:2e8fca65efaf | 78 | chip.outputB(0x00); |
romilly | 2:2e8fca65efaf | 79 | checkEqual(0, int(chipB0),"write to B0"); |
romilly | 2:2e8fca65efaf | 80 | chip.outputB(0x01); |
romilly | 2:2e8fca65efaf | 81 | checkEqual(1, int(chipB0),"write to B0"); |
romilly | 2:2e8fca65efaf | 82 | } |
romilly | 2:2e8fca65efaf | 83 | |
romilly | 2:2e8fca65efaf | 84 | void testInterruptEnableOnPortA() { |
romilly | 2:2e8fca65efaf | 85 | // NB by default both int pins are Active-LOW |
romilly | 2:2e8fca65efaf | 86 | reset(); |
romilly | 1:d7fe22a24841 | 87 | chipA0.output(); // output from the mbed |
romilly | 2:2e8fca65efaf | 88 | chip.directionA(0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 89 | chipA0 = 1; |
romilly | 2:2e8fca65efaf | 90 | checkEqual(1, int(chipIntA),"interrupts not yet enabled"); |
romilly | 2:2e8fca65efaf | 91 | chipA0 = 0; |
romilly | 2:2e8fca65efaf | 92 | chip.interruptEnableA(0x01); // interupt enabled on pin 0 |
romilly | 2:2e8fca65efaf | 93 | checkEqual(1, int(chipIntA), "value has not changed"); |
romilly | 2:2e8fca65efaf | 94 | chipA0 = 1; |
romilly | 2:2e8fca65efaf | 95 | wait_us(1); // test fails without this - mbed is too darned fast! |
romilly | 2:2e8fca65efaf | 96 | checkEqual(0, int(chipIntA), "value has changed"); |
romilly | 2:2e8fca65efaf | 97 | } |
romilly | 2:2e8fca65efaf | 98 | |
romilly | 2:2e8fca65efaf | 99 | void testInterruptEnableOnPortB() { |
romilly | 2:2e8fca65efaf | 100 | // NB by default both int pins are Active-LOW |
romilly | 2:2e8fca65efaf | 101 | reset(); |
romilly | 2:2e8fca65efaf | 102 | chipB0.output(); // output from the mbed |
romilly | 2:2e8fca65efaf | 103 | chip.directionB(0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 104 | chipB0 = 1; |
romilly | 2:2e8fca65efaf | 105 | chip.interruptEnableB(0x01); // interupt enabled on pin 0 |
romilly | 2:2e8fca65efaf | 106 | wait_us(1); |
romilly | 2:2e8fca65efaf | 107 | checkEqual(0, int(chipIntB), "interruptB"); |
romilly | 2:2e8fca65efaf | 108 | } |
romilly | 2:2e8fca65efaf | 109 | |
romilly | 2:2e8fca65efaf | 110 | void testMirrorInterrupts() { |
romilly | 2:2e8fca65efaf | 111 | reset(); |
romilly | 1:d7fe22a24841 | 112 | chipB0.output(); // output from the mbed |
romilly | 2:2e8fca65efaf | 113 | chip.directionB(0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 114 | chipB0 = 1; |
romilly | 2:2e8fca65efaf | 115 | chip.interruptEnableB(0x01); // interupt enabled on pin 0 |
romilly | 2:2e8fca65efaf | 116 | wait_us(1); |
romilly | 2:2e8fca65efaf | 117 | checkEqual(0, int(chipIntB), "interruptB"); |
romilly | 2:2e8fca65efaf | 118 | checkEqual(1, int(chipIntA), "before mirroring"); // no interrupt A yet |
romilly | 2:2e8fca65efaf | 119 | chip.mirrorInterrupts(true); |
romilly | 2:2e8fca65efaf | 120 | wait_us(1); |
romilly | 2:2e8fca65efaf | 121 | checkEqual(0, int(chipIntA), "after mirroring"); |
romilly | 2:2e8fca65efaf | 122 | chip.mirrorInterrupts(false); |
romilly | 2:2e8fca65efaf | 123 | wait_us(1); |
romilly | 2:2e8fca65efaf | 124 | checkEqual(1, int(chipIntA), "after mirroring turned off"); |
romilly | 2:2e8fca65efaf | 125 | } |
romilly | 2:2e8fca65efaf | 126 | |
romilly | 2:2e8fca65efaf | 127 | void testInterruptPolarity() { |
romilly | 2:2e8fca65efaf | 128 | // NB by default both int pins are Active-LOW |
romilly | 2:2e8fca65efaf | 129 | // interrupt off (so LHIGH) after POR |
romilly | 2:2e8fca65efaf | 130 | reset(); |
romilly | 2:2e8fca65efaf | 131 | checkEqual(1, int(chipIntA),"interrupt ACTIVE_LOW by default"); |
romilly | 2:2e8fca65efaf | 132 | chip.interruptPolarity(ACTIVE_HIGH); |
romilly | 2:2e8fca65efaf | 133 | wait_us(1); |
romilly | 2:2e8fca65efaf | 134 | checkEqual(0, int(chipIntA), "interrupt ACTIVE_HIGH"); |
romilly | 2:2e8fca65efaf | 135 | chip.interruptPolarity(ACTIVE_LOW); |
romilly | 2:2e8fca65efaf | 136 | wait_us(1); |
romilly | 2:2e8fca65efaf | 137 | checkEqual(1, int(chipIntA), "interrupt ACTIVE_LOW"); |
romilly | 0:d58b942de71e | 138 | } |
romilly | 2:2e8fca65efaf | 139 | |
romilly | 2:2e8fca65efaf | 140 | void testInterruptControlAndDefaultValueOnPortA() { |
romilly | 2:2e8fca65efaf | 141 | reset(); |
romilly | 2:2e8fca65efaf | 142 | chipA0.output(); // output from the mbed |
romilly | 2:2e8fca65efaf | 143 | chip.directionA(0x01); // bit 0 set to input |
romilly | 2:2e8fca65efaf | 144 | chipA0 = 0; |
romilly | 2:2e8fca65efaf | 145 | checkEqual(1, int(chipIntA),"interrupt ACTIVE_LOW by default"); |
romilly | 2:2e8fca65efaf | 146 | chip.interruptEnableA(0x01); // interupt enabled on pin 0 |
romilly | 2:2e8fca65efaf | 147 | chip.defaultValueA(0x01); // default value != input value |
romilly | 2:2e8fca65efaf | 148 | checkEqual(1, int(chipIntA),"still no interrupt"); // interrupt control still set to interrupt on change |
romilly | 2:2e8fca65efaf | 149 | chip.interruptControlA(0x01); |
romilly | 2:2e8fca65efaf | 150 | wait_us(1); |
romilly | 2:2e8fca65efaf | 151 | checkEqual(0, int(chipIntA), "expecting interrupt as default != input"); |
romilly | 2:2e8fca65efaf | 152 | } |
romilly | 2:2e8fca65efaf | 153 | |
romilly | 2:2e8fca65efaf | 154 | int main() { |
romilly | 2:2e8fca65efaf | 155 | testInputFromPortA(); |
romilly | 2:2e8fca65efaf | 156 | testInputFromPortB(); |
romilly | 2:2e8fca65efaf | 157 | testOutputToPortA(); |
romilly | 2:2e8fca65efaf | 158 | testOutputToPortB(); |
romilly | 2:2e8fca65efaf | 159 | testInterruptEnableOnPortA(); |
romilly | 2:2e8fca65efaf | 160 | testInterruptEnableOnPortB(); |
romilly | 2:2e8fca65efaf | 161 | testInterruptPolarity(); |
romilly | 2:2e8fca65efaf | 162 | testMirrorInterrupts(); |
romilly | 2:2e8fca65efaf | 163 | testInterruptControlAndDefaultValueOnPortA(); |
romilly | 2:2e8fca65efaf | 164 | printf("all tests OK\r\n"); |
romilly | 2:2e8fca65efaf | 165 | } |