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

Dependents:   FLIGHT_CONTROL_AND_COMMUNICATIONS_SYSTEM

Committer:
AjK
Date:
Sun Jan 16 18:27:44 2011 +0000
Revision:
0:055897ab699b
Child:
1:46c8c60e744a
1.0 Initial release

Who changed what in which revision?

UserRevisionLine numberNew 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
AjK 0:055897ab699b 24 #ifndef AJK_MAX31000_H
AjK 0:055897ab699b 25 #define AJK_MAX31000_H
AjK 0:055897ab699b 26
AjK 0:055897ab699b 27 #ifndef MBED_H
AjK 0:055897ab699b 28 #include "mbed.h"
AjK 0:055897ab699b 29 #endif
AjK 0:055897ab699b 30
AjK 0:055897ab699b 31 #ifndef MAX3100_TX_BUFFER_SIZE
AjK 0:055897ab699b 32 #define MAX3100_TX_BUFFER_SIZE 32
AjK 0:055897ab699b 33 #endif
AjK 0:055897ab699b 34
AjK 0:055897ab699b 35 #ifndef MAX3100_RX_BUFFER_SIZE
AjK 0:055897ab699b 36 #define MAX3100_RX_BUFFER_SIZE 32
AjK 0:055897ab699b 37 #endif
AjK 0:055897ab699b 38
AjK 0:055897ab699b 39 #ifndef MAX3100_SPI_FREQ
AjK 0:055897ab699b 40 #define MAX3100_SPI_FREQ 5000000
AjK 0:055897ab699b 41 #endif
AjK 0:055897ab699b 42
AjK 0:055897ab699b 43 #define MAX3100_CONF_WR (3U << 14)
AjK 0:055897ab699b 44 #define MAX3100_CONF_RD (1U << 14)
AjK 0:055897ab699b 45 #define MAX3100_CONF_T (1U << 14)
AjK 0:055897ab699b 46 #define MAX3100_CONF_R (1U << 15)
AjK 0:055897ab699b 47 #define MAX3100_FEN(x) (x << 13)
AjK 0:055897ab699b 48 #define MAX3100_SHDNi(x) (x << 12)
AjK 0:055897ab699b 49 #define MAX3100_TM(x) (x << 11)
AjK 0:055897ab699b 50 #define MAX3100_RM(x) (x << 10)
AjK 0:055897ab699b 51 #define MAX3100_PM(x) (x << 9)
AjK 0:055897ab699b 52 #define MAX3100_RAM(x) (x << 8)
AjK 0:055897ab699b 53 #define MAX3100_IR(x) (x << 7)
AjK 0:055897ab699b 54 #define MAX3100_ST(x) (x << 6)
AjK 0:055897ab699b 55 #define MAX3100_PE(x) (x << 5)
AjK 0:055897ab699b 56 #define MAX3100_L(x) (x << 4)
AjK 0:055897ab699b 57 #define MAX3100_BAUD(x) (x << 0)
AjK 0:055897ab699b 58
AjK 0:055897ab699b 59 #define MAX3100_DATA_WR (2U << 14)
AjK 0:055897ab699b 60 #define MAX3100_DATA_RD (0)
AjK 0:055897ab699b 61 #define MAX3100_TE(x) (x << 10)
AjK 0:055897ab699b 62 #define MAX3100_RAFE(x) (x << 10)
AjK 0:055897ab699b 63 #define MAX3100_RTS(x) (x << 9)
AjK 0:055897ab699b 64 #define MAX3100_CTS(x) (x << 9)
AjK 0:055897ab699b 65 #define MAX3100_PT(x) (x << 8)
AjK 0:055897ab699b 66 #define MAX3100_PR(x) (x << 8)
AjK 0:055897ab699b 67
AjK 0:055897ab699b 68 namespace AjK {
AjK 0:055897ab699b 69
AjK 0:055897ab699b 70 class MAX3100Dummy;
AjK 0:055897ab699b 71
AjK 0:055897ab699b 72 /** MAX3100 An external serial IO device.
AjK 0:055897ab699b 73 *
AjK 0:055897ab699b 74 * The MAX3100 librray is designed to allow the easy attachment of additional
AjK 0:055897ab699b 75 * serial ports to the Mbed. We all know that the Mbed already has 3 potential
AjK 0:055897ab699b 76 * serial ports. But maybe you need more ports or maybe you need to use the Mbed
AjK 0:055897ab699b 77 * pins for an alternative function. The MAX3100 may well be able to help in
AjK 0:055897ab699b 78 * situations like these.
AjK 0:055897ab699b 79 *
AjK 0:055897ab699b 80 * Each MAX3100 device you create in is TX/RX buffered with 32 characters in a circular
AjK 0:055897ab699b 81 * buffer system.
AjK 0:055897ab699b 82 *
AjK 0:055897ab699b 83 * The MAX3100 uses at least one Mbed SPI port and additional DigitalOut and InterruptIn
AjK 0:055897ab699b 84 * pins to work. However, you can attach multiple MAX3100 devices to a single SPI "bus".
AjK 0:055897ab699b 85 *
AjK 0:055897ab699b 86 * For more information on attaching multiple devices see all the examples listed below.
AjK 0:055897ab699b 87 *
AjK 0:055897ab699b 88 * @see example1.h
AjK 0:055897ab699b 89 * @see example2.h
AjK 0:055897ab699b 90 * @see example3.h
AjK 0:055897ab699b 91 * @see http://pdfserv.maxim-ic.com/en/ds/MAX3100.pdf
AjK 0:055897ab699b 92 */
AjK 0:055897ab699b 93 class MAX3100 : public Stream {
AjK 0:055897ab699b 94
AjK 0:055897ab699b 95 protected:
AjK 0:055897ab699b 96
AjK 0:055897ab699b 97 SPI *_spi;
AjK 0:055897ab699b 98 DigitalOut *_cs;
AjK 0:055897ab699b 99 InterruptIn *_irq;
AjK 0:055897ab699b 100
AjK 0:055897ab699b 101 uint16_t tx_buffer[MAX3100_TX_BUFFER_SIZE];
AjK 0:055897ab699b 102 int tx_buffer_in;
AjK 0:055897ab699b 103 int tx_buffer_out;
AjK 0:055897ab699b 104 bool tx_buffer_full;
AjK 0:055897ab699b 105
AjK 0:055897ab699b 106 uint16_t rx_buffer[MAX3100_RX_BUFFER_SIZE];
AjK 0:055897ab699b 107 int rx_buffer_in;
AjK 0:055897ab699b 108 int rx_buffer_out;
AjK 0:055897ab699b 109 bool rx_buffer_full;
AjK 0:055897ab699b 110
AjK 0:055897ab699b 111 uint16_t config;
AjK 0:055897ab699b 112 int _device;
AjK 0:055897ab699b 113 int _parity;
AjK 0:055897ab699b 114
AjK 0:055897ab699b 115 virtual int _putc(int c) { return putc(c); }
AjK 0:055897ab699b 116 virtual int _getc() { return getc(); }
AjK 0:055897ab699b 117
AjK 0:055897ab699b 118 /** init
AjK 0:055897ab699b 119 *
AjK 0:055897ab699b 120 * Initialise the device.
AjK 0:055897ab699b 121 * @param PinName SPI mosi
AjK 0:055897ab699b 122 * @param PinName SPI miso
AjK 0:055897ab699b 123 * @param PinName SPI sclk
AjK 0:055897ab699b 124 * @param PinName DigitalOut cs
AjK 0:055897ab699b 125 * @param PinName InterruptIn irq
AjK 0:055897ab699b 126 * @param SPI * A pointer to a shared SPI bus
AjK 0:055897ab699b 127 */
AjK 0:055897ab699b 128 void init(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq, SPI *spi = (SPI *)NULL);
AjK 0:055897ab699b 129
AjK 0:055897ab699b 130 uint16_t spiwrite(uint16_t val);
AjK 0:055897ab699b 131 uint16_t config_write(uint16_t val);
AjK 0:055897ab699b 132 uint16_t config_read(void);
AjK 0:055897ab699b 133
AjK 0:055897ab699b 134 // C style callback function pointer for external CS control.
AjK 0:055897ab699b 135 void (*_cs_function)(int, int);
AjK 0:055897ab699b 136
AjK 0:055897ab699b 137 // C++ style callback method pointer for external CS control
AjK 0:055897ab699b 138 MAX3100Dummy *_cs_obj;
AjK 0:055897ab699b 139 void (MAX3100Dummy::*_cs_method)(int, int);
AjK 0:055897ab699b 140
AjK 0:055897ab699b 141 // Internal CS control.
AjK 0:055897ab699b 142 void cs_value(int);
AjK 0:055897ab699b 143
AjK 0:055897ab699b 144 // calculate byte parity.
AjK 0:055897ab699b 145 int parityCal(uint8_t c);
AjK 0:055897ab699b 146
AjK 0:055897ab699b 147 // http://mbed.org/forum/bugs-suggestions/topic/1498
AjK 0:055897ab699b 148 void topic_1498(PinName p);
AjK 0:055897ab699b 149
AjK 0:055897ab699b 150 public:
AjK 0:055897ab699b 151
AjK 0:055897ab699b 152 /** Constructor
AjK 0:055897ab699b 153 */
AjK 0:055897ab699b 154 MAX3100() { error( "No pins supplied to constructor" ); }
AjK 0:055897ab699b 155
AjK 0:055897ab699b 156 /** Constructor
AjK 0:055897ab699b 157 */
AjK 0:055897ab699b 158 MAX3100(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq, int device = 0) {
AjK 0:055897ab699b 159 _device = device;
AjK 0:055897ab699b 160 init( mosi, miso, sclk, cs, irq);
AjK 0:055897ab699b 161 }
AjK 0:055897ab699b 162
AjK 0:055897ab699b 163 /** Constructor
AjK 0:055897ab699b 164 */
AjK 0:055897ab699b 165 MAX3100(SPI *spi, PinName cs, PinName irq, int device = 0) {
AjK 0:055897ab699b 166 _device = device;
AjK 0:055897ab699b 167 init( NC, NC, NC, cs, irq, spi);
AjK 0:055897ab699b 168 }
AjK 0:055897ab699b 169
AjK 0:055897ab699b 170 /** Destructor
AjK 0:055897ab699b 171 */
AjK 0:055897ab699b 172 virtual ~MAX3100() {
AjK 0:055897ab699b 173 if ( _spi ) delete( _spi );
AjK 0:055897ab699b 174 if ( _irq ) delete( _irq );
AjK 0:055897ab699b 175 if ( _cs ) delete( _cs );
AjK 0:055897ab699b 176 }
AjK 0:055897ab699b 177
AjK 0:055897ab699b 178 enum Parity {
AjK 0:055897ab699b 179 None = 0
AjK 0:055897ab699b 180 , Odd
AjK 0:055897ab699b 181 , Even
AjK 0:055897ab699b 182 , Forced1
AjK 0:055897ab699b 183 , Forced0
AjK 0:055897ab699b 184 };
AjK 0:055897ab699b 185
AjK 0:055897ab699b 186 /** setParity
AjK 0:055897ab699b 187 *
AjK 0:055897ab699b 188 * Set the parity of the system. Default is None.
AjK 0:055897ab699b 189 *
AjK 0:055897ab699b 190 * @param Parity None, Odd, Even
AjK 0:055897ab699b 191 */
AjK 0:055897ab699b 192 void setParity(int p) { _parity = p; }
AjK 0:055897ab699b 193
AjK 0:055897ab699b 194 /** setStopBits
AjK 0:055897ab699b 195 *
AjK 0:055897ab699b 196 * Set the number of stop bits. Default is One.
AjK 0:055897ab699b 197 *
AjK 0:055897ab699b 198 * @param int 1 or 2
AjK 0:055897ab699b 199 */
AjK 0:055897ab699b 200 void setStopBits(int i);
AjK 0:055897ab699b 201
AjK 0:055897ab699b 202 /** System interrupt service routine.
AjK 0:055897ab699b 203 */
AjK 0:055897ab699b 204 void isr(void);
AjK 0:055897ab699b 205
AjK 0:055897ab699b 206 /** baud
AjK 0:055897ab699b 207 * Set the system baud. Default is "10" (9600). Note,
AjK 0:055897ab699b 208 * this is not like Mbed's Serial where you pass the
AjK 0:055897ab699b 209 * baud rate you want. The MAX3100 has 16 possible
AjK 0:055897ab699b 210 * preset prescalers you can choose from. See the datasheet
AjK 0:055897ab699b 211 * for more info.
AjK 0:055897ab699b 212 *
AjK 0:055897ab699b 213 * @see http://pdfserv.maxim-ic.com/en/ds/MAX3100.pdf
AjK 0:055897ab699b 214 * @param int A number from 0 to 15 indicating which prescaler to use.
AjK 0:055897ab699b 215 */
AjK 0:055897ab699b 216 void baud(int baudrate);
AjK 0:055897ab699b 217
AjK 0:055897ab699b 218 /** enableRxIrq
AjK 0:055897ab699b 219 */
AjK 0:055897ab699b 220 void enableRxIrq(void);
AjK 0:055897ab699b 221
AjK 0:055897ab699b 222 /** disableRxIrq
AjK 0:055897ab699b 223 */
AjK 0:055897ab699b 224 void disableRxIrq(void);
AjK 0:055897ab699b 225
AjK 0:055897ab699b 226 /** enableTxIrq
AjK 0:055897ab699b 227 */
AjK 0:055897ab699b 228 void enableTxIrq(void);
AjK 0:055897ab699b 229
AjK 0:055897ab699b 230 /** disableTxIrq
AjK 0:055897ab699b 231 */
AjK 0:055897ab699b 232 void disableTxIrq(void);
AjK 0:055897ab699b 233
AjK 0:055897ab699b 234 /** putc
AjK 0:055897ab699b 235 * @param int c The byte to write.
AjK 0:055897ab699b 236 */
AjK 0:055897ab699b 237 int putc(int c);
AjK 0:055897ab699b 238
AjK 0:055897ab699b 239 /** puts
AjK 0:055897ab699b 240 * @param char * The string to print.
AjK 0:055897ab699b 241 */
AjK 0:055897ab699b 242 void puts(char *s);
AjK 0:055897ab699b 243
AjK 0:055897ab699b 244 /** getc
AjK 0:055897ab699b 245 * @return int c The byte read or -1 if no bytes to read.
AjK 0:055897ab699b 246 */
AjK 0:055897ab699b 247 int getc(void);
AjK 0:055897ab699b 248
AjK 0:055897ab699b 249 /** gets
AjK 0:055897ab699b 250 * Get a string. Note, this method blocks until size bytes are read.
AjK 0:055897ab699b 251 * @param char *s where to place the incoming bytes.
AjK 0:055897ab699b 252 * @param int size How many bytes to read.
AjK 0:055897ab699b 253 * @return char * The value of *s passed in.
AjK 0:055897ab699b 254 */
AjK 0:055897ab699b 255 char *gets(char *s, int size);
AjK 0:055897ab699b 256
AjK 0:055897ab699b 257 /** peek
AjK 0:055897ab699b 258 * like getc() but does NOT remove the byte from the buffer.
AjK 0:055897ab699b 259 * @see getc*(
AjK 0:055897ab699b 260 */
AjK 0:055897ab699b 261 int peek(void);
AjK 0:055897ab699b 262
AjK 0:055897ab699b 263 /** readable
AjK 0:055897ab699b 264 * Are any byte(s) available in the RX buffer?
AjK 0:055897ab699b 265 * @return 0 if none, 1 otherwise.
AjK 0:055897ab699b 266 */
AjK 0:055897ab699b 267 int readable(void) { return (rx_buffer_in != rx_buffer_out || rx_buffer_full) ? 1 : 0; }
AjK 0:055897ab699b 268
AjK 0:055897ab699b 269 /** writable
AjK 0:055897ab699b 270 * Can we write a byte to teh serial stream?
AjK 0:055897ab699b 271 * @return non-zero if we can, zero otherwise.
AjK 0:055897ab699b 272 */
AjK 0:055897ab699b 273 int writable(void) { return tx_buffer_full ? 0 : 1; }
AjK 0:055897ab699b 274
AjK 0:055897ab699b 275 /** setDevice
AjK 0:055897ab699b 276 * Give this device an "address".
AjK 0:055897ab699b 277 * @param int i An address to use in callbacks.
AjK 0:055897ab699b 278 */
AjK 0:055897ab699b 279 void setDevice(int i) { _device = i; }
AjK 0:055897ab699b 280
AjK 0:055897ab699b 281 /** flushTxBuffer
AjK 0:055897ab699b 282 *
AjK 0:055897ab699b 283 * Flush the TX buffer.
AjK 0:055897ab699b 284 */
AjK 0:055897ab699b 285 void flushTxBuffer(void) { tx_buffer_in = tx_buffer_out = 0; tx_buffer_full = false; }
AjK 0:055897ab699b 286
AjK 0:055897ab699b 287 /** flushRxBuffer
AjK 0:055897ab699b 288 *
AjK 0:055897ab699b 289 * Flush the RX buffer.
AjK 0:055897ab699b 290 */
AjK 0:055897ab699b 291 void flushRxBuffer(void) { rx_buffer_in = rx_buffer_out = 0; rx_buffer_full = false; }
AjK 0:055897ab699b 292
AjK 0:055897ab699b 293 /** attach_cs
AjK 0:055897ab699b 294 * Attach a C style callback function pointer. Used if an external function
AjK 0:055897ab699b 295 * is controlling the chip CS line.
AjK 0:055897ab699b 296 * @param function A C function pointer
AjK 0:055897ab699b 297 */
AjK 0:055897ab699b 298 void attach_cs(void (*function)(int, int) = 0) { _cs_function = function; }
AjK 0:055897ab699b 299
AjK 0:055897ab699b 300 /** attach_cs
AjK 0:055897ab699b 301 * Attach a C++ object/method pointer. Used if an external function
AjK 0:055897ab699b 302 * @param object An object that conatins the callback method.
AjK 0:055897ab699b 303 * @param method The method within the object to call.
AjK 0:055897ab699b 304 */
AjK 0:055897ab699b 305 template<class T>
AjK 0:055897ab699b 306 void attach_cs(T* item, void (T::*method)(int, int)) { _cs_obj = (MAX3100Dummy *)item; _cs_method = (void (MAX3100Dummy::*)(int, int))method; }
AjK 0:055897ab699b 307
AjK 0:055897ab699b 308 };
AjK 0:055897ab699b 309
AjK 0:055897ab699b 310 }; // namespace AjK ends.
AjK 0:055897ab699b 311
AjK 0:055897ab699b 312 using namespace AjK;
AjK 0:055897ab699b 313
AjK 0:055897ab699b 314 #endif