This library contains a simple device driver for the X10 CM17a module. It also contains a simple X10Server, which listens for network commands to be forwarded to the module.

Dependents:   X10Svr

X10.h

Committer:
WiredHome
Date:
2015-07-07
Revision:
1:4006f1419bc2
Parent:
0:12ed8bd4909a

File content as of revision 1:4006f1419bc2:



#ifndef X10_H
#define X10_H
#include "mbed.h"
#include "rtos.h"

/// X10Interface is an interface to a CM17a module. This interface
/// accepts various commands and translates and forwards those
/// to a connected CM17a (Firecracker) device.
///
/// The system architecture for which this is relevant:
/// @code
///  +---------+           +---------+           +=========+           +---------+
///  | Web     |- Internet-| Web     |- Network -| X10     |           | CM17a   |
///  | Browser |           | Server  |       |   | Server  |-- RS232 --| Module  |
///  +---------+           +---------+   .../    +=========+           +---------+
///                                                                            /
///    ~|+|~~~~~~~ AC Line ~~~|+|~~~~~~~~~~~~~~~~~~~|+|~~~~~~~~~~~~~~~~|+|~   /_
///    ~|+|~~~~~~~~~~~~~~~~~~~|+|~~~~~~~~~~~~~~~~~~~|+|~~~~~~~~~~~~~~~~|+|~    /
///      |                     |                     |                  |     /
///  +---------+           +---------+           +---------+           +---------+
///  | X10     |           | X10     |           | X10     |           | TM751   |
///  | Module  |           | Module  |           | Module  |           | Module  |
///  +---------+           +---------+           +---------+           +---------+
///      |                     |                     |                  |     
///  +---------+           +---------+           +---------+           +---------+
///  |Appliance|           |Appliance|           |Appliance|           |Appliance|
///  |         |           |         |           |         |           |         |
///  +---------+           +---------+           +---------+           +---------+
/// @endcode
///
/// Other PCs in the house also had the SW component needed to send a message to
/// the X10 Server, and in the corner of one of them is a scheduled task (e.g. 
/// cron job) to perform some automated control. This is suggested by the '...'
/// in the diagram above.
///
/// The problem with this configuration is that the Web Server and the X10 Server
/// were PCs; consuming PC class power. For a while, they were one in the same PC,
/// but over time the network evolved and they split. The X10 Server was a bit more 
/// power hungry than I would like, and needs to change. This X10Interface is a key
/// component in that change.
///
/// The Software Architecture for the Network connected X10 Server and CM17a module:
/// @code
///                       __ mbed module ____________________
///                      /                                   \
///  +---------+           +---------+           +---------+           +---------+
///  | Network |- Network -| Socket  |-----------|X10      |           | CM17a   |
///  | Device  |           | Listener|           |Interface|-- DB-9 ---| Module  |
///  +---------+           +---------+           +---------+           +---------+
///                       \__________________________________/
/// @endcode
///
class X10Interface
{
public:
    typedef enum SIGNAL {
        RESET = 0,
        HIGH = 1,
        LOW = 2,
        STANDBY = 3
    } signal_t;

    /// return codes used by all features
    typedef enum
        {
        ERR_SUCCESS,            ///< Command was process successfully.
        ERR_BADARGS,            ///< Bad arguments were supplied, could not process.
        ERR_NODESPEC,           ///< Invalid house or unit code was supplied.
        ERR_COMERR,             ///< Could not properly queue commands for transmit (buffer full?).
        ERR_BADSTEP,            ///< Brighten and Dim commands only accept the range '1' to '6'
        ERR_BADCMD              ///< Parsing could not extract the command.
        } ERR_EXIT;

    /// Constructor for the X10 interface
    ///
    /// This instantiates the X10 Interface object. When a command is received
    /// it sends this to the connected CM17a module for transmitting.
    ///
    /// @code
    /// 
    ///        GND   DTR   TxD   RxD   DCD       DB-9 Standard Pinout
    ///         5     4     3     2     1        used by CM17a module
    ///            9     8     7     6
    ///           RI    CTS   RTS   DSR
    ///
    /// DB-9    LowPower | Standby    | '1' | Wait | '0' | Wait | '1' | Wait...
    ///                   ___  _______       ___________________       ________
    /// DTR(4)  _________|   //       |_____|                   |_____|        
    ///                   ___  ____________________       _____________________
    /// RTS(7)  _________|   //                    |_____|                     
    ///
    ///                               | bit period | = 1/BaudRate
    /// GND(5)
    /// @endcode
    ///
    /// @param[in] RTS is the mbed pin that the CM17a RTS pin is connected to.
    /// @param[in] DTR is the mbed pin that the CM17a DTR pin is connected to.
    /// @param[in] MultiMessageDelay_s is the delay in seconds between messages
    ///             when more than one message is queued at once. Default is 2.
    /// @param[in] BaudRate is the desired baudrate for the communications
    ///             to the CM17a module. A 'bit' in BaudRate terms is the period
    ///             of an asserted 1 (or 0) followed by one of the 'wait' periods.
    ///             While there is not a known reason to change it, values in the 
    ///             range 200 to 10000 have been tested successfully.
    ///             The default value is 2000.
    ///
    X10Interface(PinName RTS, PinName DTR, uint8_t MultiMessageDelay_s = 1, uint32_t BaudRate = 10000);
    
    /// Parse a command for the X10 Communications.
    ///
    /// This method accepts several different types and formats for commands.
    ///
    /// @note This method will modify the provided message as it parses it.
    ///
    /// @verbatim
    ///  <House><Unit> <cmd> [<House><Unit> <cmd> [...]]
    ///     House is 'a' - 'p'
    ///     Unit is '1' - '16'
    ///     cmd is 1=on, 0=off, +1 to +6 to brighten, -1 to -6 to dim.
    ///  /XXXX sends the hex value XXXX to the module.
    ///  ##### sets the baudrate to the value #####
    /// @endverbatim
    ///
    /// @param[in] message is the pointer to the buffer to process. The
    ///         buffer is modified, but there is no information sent back.
    /// @returns X10Interface::ERR_EXIT code.
    ///
    ERR_EXIT ParseCommand(char * message);
    
    /// Set the communication baudrate to the CM17a module.
    ///
    /// @param[in] baudrate is the new baudrate. While any value is accepted,
    ///         the module may not operate under all possible settings.
    /// @returns X10Interface::ERR_EXIT code.
    ///
    ERR_EXIT baud(uint32_t baudrate);
    
    /// Set the delay between messages when multiple messages are processed from
    /// one command.
    ///
    /// @param[in] MultiMessageDelay_s is the delay in seconds that is applied 
    ///         between commands to the CM17a. If this delay is not long enough,
    ///         commands might not be delivered to the receivers.
    /// @returns X10Interface::ERR_EXIT code.
    ///
    ERR_EXIT delay(uint8_t MultiMessageDelay_s);
    
private:
    ERR_EXIT cm17a_Header(void);
    ERR_EXIT enqueueData(uint16_t word);
    ERR_EXIT cm17a_Footer(void);
    ERR_EXIT DoCommand(const char* szDevice, const char* szOp);
    uint16_t cm17a_CmdLookup(int iHouse, int iUnit, enum command_index command);
    ERR_EXIT cm17a_CmdSend(int iHouse, int iUnit, enum command_index command);
    ERR_EXIT cm17a_CmdSend(uint16_t command);
    ERR_EXIT write_stream(const unsigned char* data, size_t byte_count);
    ERR_EXIT parse_device(const char* szDevice, int* iHouse, int* iUnit);

    Ticker ticker;              // used to manage the bitstream timing
    Timer timer;                // used for delays between messages
    void x10stream(void);
    BusOut * cm17Pins;
    char commandBuffer[100];    // for parsing command streams
    int mIndex;
    
    // This is the queue of stuff to send to the unit. It must be
    // able to hold multiple messages, the equivalent of:
    // a1 1 a2 0 a3 +1 a15 0 ...
    // All commands for the CM17a are held in the lower 8 bits
    // If the upper 8-bits is non-zero, it is a special command
    // (typically to introduce delays between messages).
    uint16_t bitBuffer[20];
    int bitEnqueue;
    int bitDequeue;
    
    // Used when processing the queue to the port pins
    int mask;
    uint32_t bitperiod_us;
    uint8_t multiMsgDelay_s;
};


#endif // X10_H