MAX3100, an external serial device to add additional serial ports via SPI
Diff: MAX3100.h
- Revision:
- 0:055897ab699b
- Child:
- 1:46c8c60e744a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX3100.h Sun Jan 16 18:27:44 2011 +0000 @@ -0,0 +1,314 @@ +/* + 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. +*/ + + +#ifndef AJK_MAX31000_H +#define AJK_MAX31000_H + +#ifndef MBED_H +#include "mbed.h" +#endif + +#ifndef MAX3100_TX_BUFFER_SIZE +#define MAX3100_TX_BUFFER_SIZE 32 +#endif + +#ifndef MAX3100_RX_BUFFER_SIZE +#define MAX3100_RX_BUFFER_SIZE 32 +#endif + +#ifndef MAX3100_SPI_FREQ +#define MAX3100_SPI_FREQ 5000000 +#endif + +#define MAX3100_CONF_WR (3U << 14) +#define MAX3100_CONF_RD (1U << 14) +#define MAX3100_CONF_T (1U << 14) +#define MAX3100_CONF_R (1U << 15) +#define MAX3100_FEN(x) (x << 13) +#define MAX3100_SHDNi(x) (x << 12) +#define MAX3100_TM(x) (x << 11) +#define MAX3100_RM(x) (x << 10) +#define MAX3100_PM(x) (x << 9) +#define MAX3100_RAM(x) (x << 8) +#define MAX3100_IR(x) (x << 7) +#define MAX3100_ST(x) (x << 6) +#define MAX3100_PE(x) (x << 5) +#define MAX3100_L(x) (x << 4) +#define MAX3100_BAUD(x) (x << 0) + +#define MAX3100_DATA_WR (2U << 14) +#define MAX3100_DATA_RD (0) +#define MAX3100_TE(x) (x << 10) +#define MAX3100_RAFE(x) (x << 10) +#define MAX3100_RTS(x) (x << 9) +#define MAX3100_CTS(x) (x << 9) +#define MAX3100_PT(x) (x << 8) +#define MAX3100_PR(x) (x << 8) + +namespace AjK { + +class MAX3100Dummy; + +/** MAX3100 An external serial IO device. + * + * The MAX3100 librray is designed to allow the easy attachment of additional + * serial ports to the Mbed. We all know that the Mbed already has 3 potential + * serial ports. But maybe you need more ports or maybe you need to use the Mbed + * pins for an alternative function. The MAX3100 may well be able to help in + * situations like these. + * + * Each MAX3100 device you create in is TX/RX buffered with 32 characters in a circular + * buffer system. + * + * The MAX3100 uses at least one Mbed SPI port and additional DigitalOut and InterruptIn + * pins to work. However, you can attach multiple MAX3100 devices to a single SPI "bus". + * + * For more information on attaching multiple devices see all the examples listed below. + * + * @see example1.h + * @see example2.h + * @see example3.h + * @see http://pdfserv.maxim-ic.com/en/ds/MAX3100.pdf + */ +class MAX3100 : public Stream { + +protected: + + SPI *_spi; + DigitalOut *_cs; + InterruptIn *_irq; + + uint16_t tx_buffer[MAX3100_TX_BUFFER_SIZE]; + int tx_buffer_in; + int tx_buffer_out; + bool tx_buffer_full; + + uint16_t rx_buffer[MAX3100_RX_BUFFER_SIZE]; + int rx_buffer_in; + int rx_buffer_out; + bool rx_buffer_full; + + uint16_t config; + int _device; + int _parity; + + virtual int _putc(int c) { return putc(c); } + virtual int _getc() { return getc(); } + + /** init + * + * Initialise the device. + * @param PinName SPI mosi + * @param PinName SPI miso + * @param PinName SPI sclk + * @param PinName DigitalOut cs + * @param PinName InterruptIn irq + * @param SPI * A pointer to a shared SPI bus + */ + void init(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq, SPI *spi = (SPI *)NULL); + + uint16_t spiwrite(uint16_t val); + uint16_t config_write(uint16_t val); + uint16_t config_read(void); + + // C style callback function pointer for external CS control. + void (*_cs_function)(int, int); + + // C++ style callback method pointer for external CS control + MAX3100Dummy *_cs_obj; + void (MAX3100Dummy::*_cs_method)(int, int); + + // Internal CS control. + void cs_value(int); + + // calculate byte parity. + int parityCal(uint8_t c); + + // http://mbed.org/forum/bugs-suggestions/topic/1498 + void topic_1498(PinName p); + +public: + + /** Constructor + */ + MAX3100() { error( "No pins supplied to constructor" ); } + + /** Constructor + */ + MAX3100(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq, int device = 0) { + _device = device; + init( mosi, miso, sclk, cs, irq); + } + + /** Constructor + */ + MAX3100(SPI *spi, PinName cs, PinName irq, int device = 0) { + _device = device; + init( NC, NC, NC, cs, irq, spi); + } + + /** Destructor + */ + virtual ~MAX3100() { + if ( _spi ) delete( _spi ); + if ( _irq ) delete( _irq ); + if ( _cs ) delete( _cs ); + } + + enum Parity { + None = 0 + , Odd + , Even + , Forced1 + , Forced0 + }; + + /** setParity + * + * Set the parity of the system. Default is None. + * + * @param Parity None, Odd, Even + */ + void setParity(int p) { _parity = p; } + + /** setStopBits + * + * Set the number of stop bits. Default is One. + * + * @param int 1 or 2 + */ + void setStopBits(int i); + + /** System interrupt service routine. + */ + void isr(void); + + /** baud + * Set the system baud. Default is "10" (9600). Note, + * this is not like Mbed's Serial where you pass the + * baud rate you want. The MAX3100 has 16 possible + * preset prescalers you can choose from. See the datasheet + * for more info. + * + * @see http://pdfserv.maxim-ic.com/en/ds/MAX3100.pdf + * @param int A number from 0 to 15 indicating which prescaler to use. + */ + void baud(int baudrate); + + /** enableRxIrq + */ + void enableRxIrq(void); + + /** disableRxIrq + */ + void disableRxIrq(void); + + /** enableTxIrq + */ + void enableTxIrq(void); + + /** disableTxIrq + */ + void disableTxIrq(void); + + /** putc + * @param int c The byte to write. + */ + int putc(int c); + + /** puts + * @param char * The string to print. + */ + void puts(char *s); + + /** getc + * @return int c The byte read or -1 if no bytes to read. + */ + int getc(void); + + /** gets + * Get a string. Note, this method blocks until size bytes are read. + * @param char *s where to place the incoming bytes. + * @param int size How many bytes to read. + * @return char * The value of *s passed in. + */ + char *gets(char *s, int size); + + /** peek + * like getc() but does NOT remove the byte from the buffer. + * @see getc*( + */ + int peek(void); + + /** readable + * Are any byte(s) available in the RX buffer? + * @return 0 if none, 1 otherwise. + */ + int readable(void) { return (rx_buffer_in != rx_buffer_out || rx_buffer_full) ? 1 : 0; } + + /** writable + * Can we write a byte to teh serial stream? + * @return non-zero if we can, zero otherwise. + */ + int writable(void) { return tx_buffer_full ? 0 : 1; } + + /** setDevice + * Give this device an "address". + * @param int i An address to use in callbacks. + */ + void setDevice(int i) { _device = i; } + + /** flushTxBuffer + * + * Flush the TX buffer. + */ + void flushTxBuffer(void) { tx_buffer_in = tx_buffer_out = 0; tx_buffer_full = false; } + + /** flushRxBuffer + * + * Flush the RX buffer. + */ + void flushRxBuffer(void) { rx_buffer_in = rx_buffer_out = 0; rx_buffer_full = false; } + + /** attach_cs + * Attach a C style callback function pointer. Used if an external function + * is controlling the chip CS line. + * @param function A C function pointer + */ + void attach_cs(void (*function)(int, int) = 0) { _cs_function = function; } + + /** attach_cs + * Attach a C++ object/method pointer. Used if an external function + * @param object An object that conatins the callback method. + * @param method The method within the object to call. + */ + template<class T> + void attach_cs(T* item, void (T::*method)(int, int)) { _cs_obj = (MAX3100Dummy *)item; _cs_method = (void (MAX3100Dummy::*)(int, int))method; } + +}; + +}; // namespace AjK ends. + +using namespace AjK; + +#endif