MAX3100, an external serial device to add additional serial ports via SPI
example3.h@1:46c8c60e744a, 2011-01-17 (annotated)
- Committer:
- AjK
- Date:
- Mon Jan 17 01:14:16 2011 +0000
- Revision:
- 1:46c8c60e744a
- Parent:
- 0:055897ab699b
1.1 See ChangeLog.h
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:055897ab699b | 1 | /* |
AjK | 0:055897ab699b | 2 | Copyright (c) 2011 Andy Kirkham |
AjK | 0:055897ab699b | 3 | |
AjK | 0:055897ab699b | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy |
AjK | 0:055897ab699b | 5 | of this software and associated documentation files (the "Software"), to deal |
AjK | 0:055897ab699b | 6 | in the Software without restriction, including without limitation the rights |
AjK | 0:055897ab699b | 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
AjK | 0:055897ab699b | 8 | copies of the Software, and to permit persons to whom the Software is |
AjK | 0:055897ab699b | 9 | furnished to do so, subject to the following conditions: |
AjK | 0:055897ab699b | 10 | |
AjK | 0:055897ab699b | 11 | The above copyright notice and this permission notice shall be included in |
AjK | 0:055897ab699b | 12 | all copies or substantial portions of the Software. |
AjK | 0:055897ab699b | 13 | |
AjK | 0:055897ab699b | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
AjK | 0:055897ab699b | 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
AjK | 0:055897ab699b | 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
AjK | 0:055897ab699b | 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
AjK | 0:055897ab699b | 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
AjK | 0:055897ab699b | 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
AjK | 0:055897ab699b | 20 | THE SOFTWARE. |
AjK | 0:055897ab699b | 21 | */ |
AjK | 0:055897ab699b | 22 | |
AjK | 0:055897ab699b | 23 | #ifdef MAX3100_EXAMPLE_COMPILE |
AjK | 0:055897ab699b | 24 | |
AjK | 0:055897ab699b | 25 | /* |
AjK | 0:055897ab699b | 26 | * NOTE! Unlike examples 1 & 2 (which are tested in the real world) this example |
AjK | 0:055897ab699b | 27 | * is theoretical only as I have not tested it. It should work but if you try it |
AjK | 0:055897ab699b | 28 | * and it doesn't work let me know! It's shown here as a starting point to demo |
AjK | 0:055897ab699b | 29 | * how to share multiple MAX3100 interrupts and address multiple chips using |
AjK | 0:055897ab699b | 30 | * external hardware to manage each MAX3100's CS signal. |
AjK | 0:055897ab699b | 31 | * |
AjK | 0:055897ab699b | 32 | * Connecting up the MAX3100 for this test program. Note, to form a "loopback" |
AjK | 0:055897ab699b | 33 | * the MAX3100 TX pin (13) is connected to the RX pin (12). Don't forget thwe Xtal |
AjK | 0:055897ab699b | 34 | * and power pins that are not shown here. Although I do PullUp mode on the IRQ pin |
AjK | 0:055897ab699b | 35 | * I still needed a real external pull up resistor on the IRQ line. You may need one |
AjK | 0:055897ab699b | 36 | * also. |
AjK | 0:055897ab699b | 37 | * |
AjK | 0:055897ab699b | 38 | * __________ |
AjK | 0:055897ab699b | 39 | * / \ |
AjK | 0:055897ab699b | 40 | * Mbed p8 |---> 1| A0 Y0 | 15 -----> MAX0 |
AjK | 0:055897ab699b | 41 | * p9 |---> 2| A1 Y1 | 14 -----> MAX1 |
AjK | 0:055897ab699b | 42 | * p10 |---> 3| A2 Y2 | 13 -----> MAX2 |
AjK | 0:055897ab699b | 43 | * p11 |---> 5| CS3 Y3 | 12 -----> MAX3 (and on to MAX7) |
AjK | 0:055897ab699b | 44 | * \__________/ TTL138 (Tie CS1 to +ve and CS2 to 0v) |
AjK | 0:055897ab699b | 45 | * |
AjK | 0:055897ab699b | 46 | * ____________ |
AjK | 0:055897ab699b | 47 | * / \ U1 |
AjK | 0:055897ab699b | 48 | * Mbed MOSI p5 |-------*---------------> 1| Din TX | 13 ------\ |
AjK | 0:055897ab699b | 49 | * MISO p6 |-----*-|---------------> 2| Dout | | |
AjK | 0:055897ab699b | 50 | * SCLK p7 |---*-|-|---------------> 3| Sclk RX | 12 ------/ |
AjK | 0:055897ab699b | 51 | * | | | MAX0 --> 4| CS | |
AjK | 0:055897ab699b | 52 | * p12 |-*-|-|-|---------------> 5| IRQ | MAX3100 |
AjK | 0:055897ab699b | 53 | * | | | | +5v ---> 6| SHTD | Xtal and PWR not shown. |
AjK | 0:055897ab699b | 54 | * | | | | \____________/ |
AjK | 0:055897ab699b | 55 | * | | | | ____________ |
AjK | 0:055897ab699b | 56 | * | | | | / \ U2 |
AjK | 0:055897ab699b | 57 | * | | | *---------------> 1| Din TX | 13 ------\ |
AjK | 0:055897ab699b | 58 | * | | *-|---------------> 2| Dout | | |
AjK | 0:055897ab699b | 59 | * | *-|-|---------------> 3| Sclk RX | 12 ------/ |
AjK | 0:055897ab699b | 60 | * | | | | MAX1 --> 4| CS | |
AjK | 0:055897ab699b | 61 | * *-|-|-|---------------> 5| IRQ | MAX3100 |
AjK | 0:055897ab699b | 62 | * | | | | +5v ---> 6| SHTD | Xtal and PWR not shown. |
AjK | 0:055897ab699b | 63 | * | | | | \____________/ |
AjK | 0:055897ab699b | 64 | * | | | | ____________ |
AjK | 0:055897ab699b | 65 | * | | | | / \ U3 |
AjK | 0:055897ab699b | 66 | * | | | \---------------> 1| Din TX | 13 ------\ |
AjK | 0:055897ab699b | 67 | * | | \-----------------> 2| Dout | | |
AjK | 0:055897ab699b | 68 | * | \-------------------> 3| Sclk RX | 12 ------/ |
AjK | 0:055897ab699b | 69 | * | MAX2 --> 4| CS | |
AjK | 0:055897ab699b | 70 | * \---------------------> 5| IRQ | MAX3100 |
AjK | 0:055897ab699b | 71 | * +5v ---> 6| SHTD | Xtal and PWR not shown. |
AjK | 0:055897ab699b | 72 | * \____________/ |
AjK | 0:055897ab699b | 73 | * |
AjK | 0:055897ab699b | 74 | * Assume a further 5 MAX3100 devices connected to the bus in the same way |
AjK | 0:055897ab699b | 75 | * to make a total of 8 MAX3100 serial devices connected to a single SPI bus. |
AjK | 0:055897ab699b | 76 | * Additionally, they all share the same interrupt signal. This is possible |
AjK | 0:055897ab699b | 77 | * because the MAX3100 IRQ output is open drain. So you will need an external 1k |
AjK | 0:055897ab699b | 78 | * pull up resistor on the IRQ signal. |
AjK | 0:055897ab699b | 79 | */ |
AjK | 0:055897ab699b | 80 | |
AjK | 0:055897ab699b | 81 | #include "mbed.h" |
AjK | 0:055897ab699b | 82 | #include "MAX3100.h" |
AjK | 0:055897ab699b | 83 | |
AjK | 0:055897ab699b | 84 | Serial pc(USBTX, USBRX); |
AjK | 0:055897ab699b | 85 | SPI spi(p5, p6, p7); |
AjK | 0:055897ab699b | 86 | BusOut addr(p8, p9, p10); |
AjK | 0:055897ab699b | 87 | DigitalOut cs(p11); |
AjK | 0:055897ab699b | 88 | InterruptIn irq(p12); |
AjK | 0:055897ab699b | 89 | MAX3100 *max[8]; |
AjK | 0:055897ab699b | 90 | |
AjK | 0:055897ab699b | 91 | // Class used to decode the address and handle shared interrupts. |
AjK | 0:055897ab699b | 92 | class MAX3100_Addr { |
AjK | 0:055897ab699b | 93 | public: |
AjK | 0:055897ab699b | 94 | void cs_select(int device, int val) { |
AjK | 0:055897ab699b | 95 | addr = device & 0x7; // Select device. |
AjK | 0:055897ab699b | 96 | cs.write(val & 1); // Assert/deassert chip CS. |
AjK | 0:055897ab699b | 97 | } |
AjK | 0:055897ab699b | 98 | void isr(void) { |
AjK | 0:055897ab699b | 99 | for (int i = 0; i < 8; i++) { |
AjK | 0:055897ab699b | 100 | if (max[i] != (MAX3100 *)NULL) max[i]->isr(); |
AjK | 0:055897ab699b | 101 | } |
AjK | 0:055897ab699b | 102 | } |
AjK | 0:055897ab699b | 103 | }; |
AjK | 0:055897ab699b | 104 | |
AjK | 0:055897ab699b | 105 | MAX3100_Addr address; |
AjK | 0:055897ab699b | 106 | |
AjK | 0:055897ab699b | 107 | int main() { |
AjK | 0:055897ab699b | 108 | int index; |
AjK | 0:055897ab699b | 109 | |
AjK | 0:055897ab699b | 110 | cs = 1; |
AjK | 0:055897ab699b | 111 | |
AjK | 0:055897ab699b | 112 | // Set the PC USB serial baud rate. |
AjK | 0:055897ab699b | 113 | pc.baud(115200); |
AjK | 0:055897ab699b | 114 | |
AjK | 0:055897ab699b | 115 | // Format the SPI interface. |
AjK | 0:055897ab699b | 116 | spi.format(16, 0); |
AjK | 0:055897ab699b | 117 | spi.frequency(MAX3100_SPI_FREQ); |
AjK | 0:055897ab699b | 118 | |
AjK | 0:055897ab699b | 119 | // Create the 8 devices and set them up. |
AjK | 0:055897ab699b | 120 | for (int index = 0; index < 8; index++) { |
AjK | 0:055897ab699b | 121 | max[index] = new MAX3100(&spi, NC, NC); |
AjK | 0:055897ab699b | 122 | max[index]->setDevice(index); |
AjK | 0:055897ab699b | 123 | max[index]->enableRxIrq(); |
AjK | 0:055897ab699b | 124 | max[index]->enableTxIrq(); |
AjK | 0:055897ab699b | 125 | max[index]->attach_cs(&address, &MAX3100_Addr::cs_select); |
AjK | 1:46c8c60e744a | 126 | max[index]->irqMask(p12); // Tell objects where shared InterruptIn is. |
AjK | 0:055897ab699b | 127 | } |
AjK | 0:055897ab699b | 128 | |
AjK | 0:055897ab699b | 129 | // Connect the interrupt signal. |
AjK | 0:055897ab699b | 130 | irq.fall(&address, &MAX3100_Addr::isr); |
AjK | 0:055897ab699b | 131 | |
AjK | 0:055897ab699b | 132 | // Any byte received on the "USB serial port" is sent to all MAX3100 devices. |
AjK | 0:055897ab699b | 133 | // Any byte received by a MAX3100 device is sent to the "USB serial port". |
AjK | 0:055897ab699b | 134 | while (1) { |
AjK | 0:055897ab699b | 135 | if (pc.readable()) { |
AjK | 0:055897ab699b | 136 | int c = pc.getc(); |
AjK | 0:055897ab699b | 137 | for (index = 0; index < 8; index++) { |
AjK | 0:055897ab699b | 138 | if (max[index] != (MAX3100 *)NULL) { |
AjK | 0:055897ab699b | 139 | max[index]->putc(c); |
AjK | 0:055897ab699b | 140 | } |
AjK | 0:055897ab699b | 141 | } |
AjK | 0:055897ab699b | 142 | } |
AjK | 0:055897ab699b | 143 | for (index = 0; index < 8; index++) { |
AjK | 0:055897ab699b | 144 | if (max[index] != (MAX3100 *)NULL) { |
AjK | 0:055897ab699b | 145 | if (max[index]->readable()) { |
AjK | 0:055897ab699b | 146 | pc.putc(max[index]->getc()); |
AjK | 0:055897ab699b | 147 | } |
AjK | 0:055897ab699b | 148 | } |
AjK | 0:055897ab699b | 149 | } |
AjK | 0:055897ab699b | 150 | } |
AjK | 0:055897ab699b | 151 | } |
AjK | 0:055897ab699b | 152 | |
AjK | 0:055897ab699b | 153 | #endif |