L VD / MAX3100
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX3100.h Source File

MAX3100.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 
00024 #ifndef AJK_MAX31000_H
00025 #define AJK_MAX31000_H
00026 
00027 #ifndef MBED_H
00028 #include "mbed.h"
00029 #include <Stream.h>
00030 #endif
00031 
00032 #ifndef MAX3100_TX_BUFFER_SIZE
00033 #define MAX3100_TX_BUFFER_SIZE  32
00034 #endif
00035 
00036 #ifndef MAX3100_RX_BUFFER_SIZE
00037 #define MAX3100_RX_BUFFER_SIZE  32
00038 #endif
00039 
00040 #ifndef MAX3100_SPI_FREQ
00041 #define MAX3100_SPI_FREQ    5000000
00042 #endif
00043 
00044 #define MAX3100_CONF_WR     (3U << 14)
00045 #define MAX3100_CONF_RD     (1U << 14)
00046 #define MAX3100_CONF_T      (1U << 14)
00047 #define MAX3100_CONF_R      (1U << 15)
00048 #define MAX3100_FEN(x)      (x << 13)
00049 #define MAX3100_SHDNi(x)    (x << 12)
00050 #define MAX3100_TM(x)       (x << 11)
00051 #define MAX3100_RM(x)       (x << 10)
00052 #define MAX3100_PM(x)       (x <<  9)
00053 #define MAX3100_RAM(x)      (x <<  8)
00054 #define MAX3100_IR(x)       (x <<  7)
00055 #define MAX3100_ST(x)       (x <<  6)
00056 #define MAX3100_PE(x)       (x <<  5)
00057 #define MAX3100_L(x)        (x <<  4)
00058 #define MAX3100_BAUD(x)     (x <<  0)        
00059 
00060 #define MAX3100_DATA_WR     (2U << 14)
00061 #define MAX3100_DATA_RD     (0)
00062 #define MAX3100_TE(x)       (x << 10)
00063 #define MAX3100_RAFE(x)     (x << 10)
00064 #define MAX3100_RTS(x)      (x <<  9)
00065 #define MAX3100_CTS(x)      (x <<  9)
00066 #define MAX3100_PT(x)       (x <<  8)
00067 #define MAX3100_PR(x)       (x <<  8)
00068 
00069 namespace AjK {
00070 
00071 class MAX3100Dummy;
00072 
00073 /** MAX3100 An external serial IO device.
00074  *
00075  * The MAX3100 librray is designed to allow the easy attachment of additional
00076  * serial ports to the Mbed. We all know that the Mbed already has 3 potential
00077  * serial ports. But maybe you need more ports or maybe you need to use the Mbed
00078  * pins for an alternative function. The MAX3100 may well be able to help in 
00079  * situations like these. 
00080  *
00081  * Each MAX3100 device you create in is TX/RX buffered with 32 characters in a circular
00082  * buffer system.
00083  *
00084  * The MAX3100 uses at least one Mbed SPI port and additional DigitalOut and InterruptIn
00085  * pins to work. However, you can attach multiple MAX3100 devices to a single SPI "bus".
00086  *
00087  * For more information on attaching multiple devices see all the examples listed below.
00088  *
00089  * @see example1.h
00090  * @see example2.h
00091  * @see example3.h
00092  * @see http://pdfserv.maxim-ic.com/en/ds/MAX3100.pdf
00093  */
00094 class MAX3100 : public Stream {
00095 
00096 protected:
00097     
00098     SPI         *_spi;
00099     DigitalOut  *_cs;
00100     InterruptIn *_irq;
00101     
00102     uint16_t tx_buffer[MAX3100_TX_BUFFER_SIZE];
00103     int  tx_buffer_in;
00104     int  tx_buffer_out;
00105     bool tx_buffer_full;
00106     
00107     uint16_t rx_buffer[MAX3100_RX_BUFFER_SIZE];
00108     int  rx_buffer_in;
00109     int  rx_buffer_out;
00110     bool rx_buffer_full;
00111     
00112     uint16_t    config;
00113     int         _device;
00114     int         _parity;
00115     
00116     uint32_t _irqMask0, _irqMask2;
00117     
00118     void irqDisable(void);
00119     void irqEnable(void);
00120         
00121     virtual int _putc(int c) { return putc(c); }
00122     virtual int _getc()      { return getc(); }
00123 
00124     /** init
00125      *
00126      * Initialise the device.
00127      * @param PinName SPI mosi
00128      * @param PinName SPI miso
00129      * @param PinName SPI sclk
00130      * @param PinName DigitalOut cs
00131      * @param PinName InterruptIn irq
00132      * @param SPI * A pointer to a shared SPI bus
00133      */
00134     void init(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq, SPI *spi = (SPI *)NULL);    
00135     
00136     uint16_t spiwrite(uint16_t val);        
00137     uint16_t config_write(uint16_t val);
00138     uint16_t config_read(void);
00139 
00140     // C style callback function pointer for external CS control.    
00141     void (*_cs_function)(int, int); 
00142     
00143     // C++ style callback method pointer for external CS control
00144     MAX3100Dummy  *_cs_obj;
00145     void (MAX3100Dummy::*_cs_method)(int, int);
00146 
00147     // C style callback function pointer for user isr callback.    
00148     void (*_isr_user_function)(int); 
00149 
00150     // C++ style callback method pointer for external CS control
00151     MAX3100Dummy  *_isr_user_obj;
00152     void (MAX3100Dummy::*_isr_user_method)(int);
00153     
00154     // Internal CS control.
00155     void cs_value(int);
00156     
00157     // calculate byte parity.
00158     int parityCal(uint8_t c);
00159 
00160     // // http://mbed.org/forum/bugs-suggestions/topic/1498
00161     // void topic_1498(PinName p); 
00162 
00163 public:
00164     
00165     static const int ISR    = 0;
00166     
00167     static const int ISR_RX = 1;
00168     
00169     static const int ISR_TX = 2;
00170     
00171     /** Constructor
00172      */
00173     MAX3100() { error( "No pins supplied to constructor" ); }
00174     
00175     /** Constructor
00176      */
00177     MAX3100(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq, int device = 0) {
00178         _device = device;
00179         init( mosi, miso, sclk, cs, irq);
00180     }
00181     
00182     /** Constructor
00183      */
00184     MAX3100(SPI *spi, PinName cs, PinName irq, int device = 0) {
00185         _device = device;
00186         init( NC, NC, NC, cs, irq, spi);
00187     }
00188     
00189     /** Destructor
00190      */
00191     virtual ~MAX3100() { 
00192         if ( _spi )     delete( _spi );
00193         if ( _irq )     delete( _irq );
00194         if ( _cs  )     delete( _cs );
00195     }
00196 
00197     enum Parity {
00198         None = 0
00199         , Odd
00200         , Even
00201         , Forced1   
00202         , Forced0
00203     };    
00204     
00205     /** setParity
00206      *
00207      * Set the parity of the system. Default is None.
00208      *
00209      * @param Parity None, Odd, Even
00210      */
00211     void setParity(int p) { _parity = p; }
00212     
00213     /** setStopBits
00214      *
00215      * Set the number of stop bits. Default is One.
00216      *
00217      * @param int 1 or 2
00218      */
00219     void setStopBits(int i);
00220     
00221     /** System interrupt service routine.
00222      */
00223     void isr(void);
00224     
00225     /** baud
00226      * Set the system baud. Default is "10" (9600). Note,
00227      * this is not like Mbed's Serial where you pass the
00228      * baud rate you want. The MAX3100 has 16 possible 
00229      * preset prescalers you can choose from. See the datasheet
00230      * for more info. 
00231      *
00232      * @see http://pdfserv.maxim-ic.com/en/ds/MAX3100.pdf
00233      * @param int A number from 0 to 15 indicating which prescaler to use.
00234      */
00235     void baud(int baudrate);
00236     
00237     /** enableRxIrq
00238      */
00239     void enableRxIrq(void);
00240     
00241     /** disableRxIrq
00242      */
00243     void disableRxIrq(void);
00244     
00245     /** enableTxIrq
00246      */
00247     void enableTxIrq(void);
00248     
00249     /** disableTxIrq
00250      */
00251     void disableTxIrq(void);
00252     
00253     /** putc
00254      * @param int c The byte to write.
00255      */
00256     int  putc(int c);
00257     
00258     /** puts
00259      * @param char * The string to print.
00260      */
00261     void puts(char *s);
00262     
00263     /** getc
00264      * @return int c The byte read or -1 if no bytes to read.
00265      */
00266     int  getc(void); 
00267     
00268     /** gets
00269      * Get a string. Note, this method blocks until size bytes are read.
00270      * @param char *s where to place the incoming bytes.
00271      * @param int size How many bytes to read.
00272      * @return char * The value of *s passed in.
00273      */
00274     char *gets(char *s, int size);   
00275     
00276     /** peek
00277      * like getc() but does NOT remove the byte from the buffer.
00278      * @see getc*(
00279      */
00280     int  peek(void);
00281     
00282     /** readable
00283      * Are any byte(s) available in the RX buffer?
00284      * @return 0 if none, 1 otherwise.
00285      */
00286     int  readable(void) { return (rx_buffer_in != rx_buffer_out || rx_buffer_full) ? 1 : 0; }
00287     
00288     /** writable
00289      * Can we write a byte to teh serial stream?
00290      * @return non-zero if we can, zero otherwise.
00291      */
00292     int  writable(void) { return tx_buffer_full ? 0 : 1; }
00293     
00294     /** setDevice
00295      * Give this device an "address".
00296      * @param int i An address to use in callbacks.
00297      */
00298     void setDevice(int i) { _device = i; }
00299     
00300     /** flushTxBuffer
00301      *
00302      * Flush the TX buffer.
00303      */
00304     void flushTxBuffer(void) { tx_buffer_in = tx_buffer_out = 0; tx_buffer_full = false; }
00305     
00306     /** flushRxBuffer
00307      *
00308      * Flush the RX buffer.
00309      */
00310     void flushRxBuffer(void) { rx_buffer_in = rx_buffer_out = 0; rx_buffer_full = false; }
00311     
00312     // /** irqMask
00313     //  * Setup the mask for enable/disable interrupts.
00314     //  * @see example3.h
00315     //  * @param PinName p The InterruptIn pin.
00316     //  */
00317     // void irqMask(PinName p);
00318 
00319     /** attach_cs
00320      * Attach a C style callback function pointer. Used if an external function
00321      * is controlling the chip CS line.
00322      * @param function A C function pointer
00323      */
00324     void attach_cs(void (*function)(int, int) = 0) { _cs_function = function; }
00325     
00326     /** attach_cs
00327      * Attach a C++ object/method pointer. Used if an external function
00328      * @param object An object that conatins the callback method.
00329      * @param method The method within the object to call.
00330      */
00331     template<class T> 
00332     void attach_cs(T* item, void (T::*method)(int, int)) { 
00333         _cs_obj = (MAX3100Dummy *)item; _cs_method = (void (MAX3100Dummy::*)(int, int))method; 
00334     }
00335     
00336     /** attach_isr_user
00337      * is controlling the chip CS line.
00338      * @param function A C function pointer
00339      */
00340     void attach_isr_user(void (*function)(int) = 0) { _isr_user_function = function; }
00341     
00342     /** attach_isr_user
00343      * @param object An object that conatins the callback method.
00344      * @param method The method within the object to call.
00345      */
00346     template<class T> 
00347     void attach_isr_user(T* item, void (T::*method)(int)) { 
00348         _isr_user_obj = (MAX3100Dummy *)item; _isr_user_method = (void (MAX3100Dummy::*)(int))method; 
00349     }
00350     
00351 };
00352 
00353 }; // namespace AjK ends.
00354 
00355 using namespace AjK;
00356 
00357 #endif