MAX3100, an external serial device to add additional serial ports via SPI

Dependents:   FLIGHT_CONTROL_AND_COMMUNICATIONS_SYSTEM

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers example3.h Source File

example3.h

00001 /*
00002     Copyright (c) 2011 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021 */
00022 
00023 #ifdef MAX3100_EXAMPLE_COMPILE
00024 
00025 /*
00026  * NOTE! Unlike examples 1 & 2 (which are tested in the real world) this example
00027  * is theoretical only as I have not tested it. It should work but if you try it 
00028  * and it doesn't work let me know! It's shown here as a starting point to demo
00029  * how to share multiple MAX3100 interrupts and address multiple chips using
00030  * external hardware to manage each MAX3100's CS signal.
00031  * 
00032  * Connecting up the MAX3100 for this test program. Note, to form a "loopback"
00033  * the MAX3100 TX pin (13) is connected to the RX pin (12). Don't forget thwe Xtal
00034  * and power pins that are not shown here. Although I do PullUp mode on the IRQ pin
00035  * I still needed a real external pull up resistor on the IRQ line. You may need one
00036  * also.
00037  *
00038  *                      __________
00039  *                     /          \
00040  *      Mbed p8 |---> 1| A0    Y0 | 15 -----> MAX0
00041  *           p9 |---> 2| A1    Y1 | 14 -----> MAX1
00042  *          p10 |---> 3| A2    Y2 | 13 -----> MAX2
00043  *          p11 |---> 5| CS3   Y3 | 12 -----> MAX3 (and on to MAX7)
00044  *                     \__________/ TTL138 (Tie CS1 to +ve and CS2 to 0v)
00045  *
00046  *                                          ____________
00047  *                                         /            \ U1
00048  * Mbed MOSI p5 |-------*---------------> 1| Din     TX | 13 ------\
00049  *      MISO p6 |-----*-|---------------> 2| Dout       |          |
00050  *      SCLK p7 |---*-|-|---------------> 3| Sclk    RX | 12 ------/
00051  *                  | | |        MAX0 --> 4| CS         |
00052  *          p12 |-*-|-|-|---------------> 5| IRQ        | MAX3100 
00053  *                | | | |        +5v ---> 6| SHTD       | Xtal and PWR not shown.
00054  *                | | | |                  \____________/
00055  *                | | | |                   ____________
00056  *                | | | |                  /            \ U2
00057  *                | | | *---------------> 1| Din     TX | 13 ------\
00058  *                | | *-|---------------> 2| Dout       |          |
00059  *                | *-|-|---------------> 3| Sclk    RX | 12 ------/
00060  *                | | | |        MAX1 --> 4| CS         |
00061  *                *-|-|-|---------------> 5| IRQ        | MAX3100
00062  *                | | | |        +5v ---> 6| SHTD       | Xtal and PWR not shown.
00063  *                | | | |                  \____________/
00064  *                | | | |                   ____________
00065  *                | | | |                  /            \ U3
00066  *                | | | \---------------> 1| Din     TX | 13 ------\
00067  *                | | \-----------------> 2| Dout       |          |
00068  *                | \-------------------> 3| Sclk    RX | 12 ------/
00069  *                |              MAX2 --> 4| CS         |
00070  *                \---------------------> 5| IRQ        | MAX3100
00071  *                               +5v ---> 6| SHTD       | Xtal and PWR not shown.
00072  *                                         \____________/
00073  *
00074  * Assume a further 5 MAX3100 devices connected to the bus in the same way
00075  * to make a total of 8 MAX3100 serial devices connected to a single SPI bus.
00076  * Additionally, they all share the same interrupt signal. This is possible 
00077  * because the MAX3100 IRQ output is open drain. So you will need an external 1k
00078  * pull up resistor on the IRQ signal.
00079  */
00080 
00081 #include "mbed.h"
00082 #include "MAX3100.h"
00083 
00084 Serial       pc(USBTX, USBRX);
00085 SPI          spi(p5, p6, p7);
00086 BusOut       addr(p8, p9, p10);
00087 DigitalOut   cs(p11);
00088 InterruptIn  irq(p12);
00089 MAX3100      *max[8];
00090 
00091 // Class used to decode the address and handle shared interrupts.
00092 class MAX3100_Addr {
00093 public:
00094     void cs_select(int device, int val) { 
00095         addr = device & 0x7; // Select device.
00096         cs.write(val & 1);   // Assert/deassert chip CS.
00097     }
00098     void isr(void) {
00099         for (int i = 0; i < 8; i++) {
00100             if (max[i] != (MAX3100 *)NULL) max[i]->isr();
00101         }
00102     }
00103 };
00104 
00105 MAX3100_Addr address;
00106 
00107 int main() {
00108     int index;
00109     
00110     cs = 1;
00111     
00112     // Set the PC USB serial baud rate.
00113     pc.baud(115200);
00114 
00115     // Format the SPI interface.    
00116     spi.format(16, 0);
00117     spi.frequency(MAX3100_SPI_FREQ);
00118     
00119     // Create the 8 devices and set them up.
00120     for (int index = 0; index < 8; index++) {
00121         max[index] = new MAX3100(&spi, NC, NC);  
00122         max[index]->setDevice(index);   
00123         max[index]->enableRxIrq();
00124         max[index]->enableTxIrq();
00125         max[index]->attach_cs(&address, &MAX3100_Addr::cs_select);
00126         max[index]->irqMask(p12); // Tell objects where shared InterruptIn is.
00127     }
00128     
00129     // Connect the interrupt signal.
00130     irq.fall(&address, &MAX3100_Addr::isr);
00131     
00132     // Any byte received on the "USB serial port" is sent to all MAX3100 devices.
00133     // Any byte received by a MAX3100 device is sent to the "USB serial port".
00134     while (1) {
00135         if (pc.readable()) {
00136             int c = pc.getc();
00137             for (index = 0; index < 8; index++) {
00138                 if (max[index] != (MAX3100 *)NULL) {
00139                     max[index]->putc(c);            
00140                 }
00141             }            
00142         }
00143         for (index = 0; index < 8; index++) {
00144             if (max[index] != (MAX3100 *)NULL) {
00145                 if (max[index]->readable()) {
00146                     pc.putc(max[index]->getc());
00147                 }    
00148             }
00149         }        
00150     }    
00151 }
00152 
00153 #endif