MAX3100, an external serial device to add additional serial ports via SPI
Diff: example3.h
- Revision:
- 0:055897ab699b
- Child:
- 1:46c8c60e744a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example3.h Sun Jan 16 18:27:44 2011 +0000 @@ -0,0 +1,153 @@ +/* + Copyright (c) 2011 Andy Kirkham + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifdef MAX3100_EXAMPLE_COMPILE + +/* + * NOTE! Unlike examples 1 & 2 (which are tested in the real world) this example + * is theoretical only as I have not tested it. It should work but if you try it + * and it doesn't work let me know! It's shown here as a starting point to demo + * how to share multiple MAX3100 interrupts and address multiple chips using + * external hardware to manage each MAX3100's CS signal. + * + * Connecting up the MAX3100 for this test program. Note, to form a "loopback" + * the MAX3100 TX pin (13) is connected to the RX pin (12). Don't forget thwe Xtal + * and power pins that are not shown here. Although I do PullUp mode on the IRQ pin + * I still needed a real external pull up resistor on the IRQ line. You may need one + * also. + * + * __________ + * / \ + * Mbed p8 |---> 1| A0 Y0 | 15 -----> MAX0 + * p9 |---> 2| A1 Y1 | 14 -----> MAX1 + * p10 |---> 3| A2 Y2 | 13 -----> MAX2 + * p11 |---> 5| CS3 Y3 | 12 -----> MAX3 (and on to MAX7) + * \__________/ TTL138 (Tie CS1 to +ve and CS2 to 0v) + * + * ____________ + * / \ U1 + * Mbed MOSI p5 |-------*---------------> 1| Din TX | 13 ------\ + * MISO p6 |-----*-|---------------> 2| Dout | | + * SCLK p7 |---*-|-|---------------> 3| Sclk RX | 12 ------/ + * | | | MAX0 --> 4| CS | + * p12 |-*-|-|-|---------------> 5| IRQ | MAX3100 + * | | | | +5v ---> 6| SHTD | Xtal and PWR not shown. + * | | | | \____________/ + * | | | | ____________ + * | | | | / \ U2 + * | | | *---------------> 1| Din TX | 13 ------\ + * | | *-|---------------> 2| Dout | | + * | *-|-|---------------> 3| Sclk RX | 12 ------/ + * | | | | MAX1 --> 4| CS | + * *-|-|-|---------------> 5| IRQ | MAX3100 + * | | | | +5v ---> 6| SHTD | Xtal and PWR not shown. + * | | | | \____________/ + * | | | | ____________ + * | | | | / \ U3 + * | | | \---------------> 1| Din TX | 13 ------\ + * | | \-----------------> 2| Dout | | + * | \-------------------> 3| Sclk RX | 12 ------/ + * | MAX2 --> 4| CS | + * \---------------------> 5| IRQ | MAX3100 + * +5v ---> 6| SHTD | Xtal and PWR not shown. + * \____________/ + * + * Assume a further 5 MAX3100 devices connected to the bus in the same way + * to make a total of 8 MAX3100 serial devices connected to a single SPI bus. + * Additionally, they all share the same interrupt signal. This is possible + * because the MAX3100 IRQ output is open drain. So you will need an external 1k + * pull up resistor on the IRQ signal. + */ + +#include "mbed.h" +#include "MAX3100.h" + +Serial pc(USBTX, USBRX); +SPI spi(p5, p6, p7); +BusOut addr(p8, p9, p10); +DigitalOut cs(p11); +InterruptIn irq(p12); +MAX3100 *max[8]; + +// Class used to decode the address and handle shared interrupts. +class MAX3100_Addr { +public: + void cs_select(int device, int val) { + addr = device & 0x7; // Select device. + cs.write(val & 1); // Assert/deassert chip CS. + } + void isr(void) { + for (int i = 0; i < 8; i++) { + if (max[i] != (MAX3100 *)NULL) max[i]->isr(); + } + } +}; + +MAX3100_Addr address; + +int main() { + int index; + + cs = 1; + + // Set the PC USB serial baud rate. + pc.baud(115200); + + // Format the SPI interface. + spi.format(16, 0); + spi.frequency(MAX3100_SPI_FREQ); + + // Create the 8 devices and set them up. + for (int index = 0; index < 8; index++) { + max[index] = new MAX3100(&spi, NC, NC); + max[index]->setDevice(index); + max[index]->enableRxIrq(); + max[index]->enableTxIrq(); + max[index]->attach_cs(&address, &MAX3100_Addr::cs_select); + } + + // Connect the interrupt signal. + irq.fall(&address, &MAX3100_Addr::isr); + + // Any byte received on the "USB serial port" is sent to all MAX3100 devices. + // Any byte received by a MAX3100 device is sent to the "USB serial port". + while (1) { + if (pc.readable()) { + int c = pc.getc(); + for (index = 0; index < 8; index++) { + if (max[index] != (MAX3100 *)NULL) { + while (!max[index]->writable()); + max[index]->putc(c); + } + } + } + for (index = 0; index < 8; index++) { + if (max[index] != (MAX3100 *)NULL) { + if (max[index]->readable()) { + pc.putc(max[index]->getc()); + } + } + } + } +} + +#endif