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.
X10.h@0:12ed8bd4909a, 2014-06-28 (annotated)
- Committer:
- WiredHome
- Date:
- Sat Jun 28 19:45:20 2014 +0000
- Revision:
- 0:12ed8bd4909a
- Child:
- 1:4006f1419bc2
Working X10 Driver for CM17a module.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:12ed8bd4909a | 1 | |
WiredHome | 0:12ed8bd4909a | 2 | |
WiredHome | 0:12ed8bd4909a | 3 | #ifndef X10_H |
WiredHome | 0:12ed8bd4909a | 4 | #define X10_H |
WiredHome | 0:12ed8bd4909a | 5 | #include "mbed.h" |
WiredHome | 0:12ed8bd4909a | 6 | #include "rtos.h" |
WiredHome | 0:12ed8bd4909a | 7 | |
WiredHome | 0:12ed8bd4909a | 8 | /// X10Interface is an interface to a CM17a module. This interface |
WiredHome | 0:12ed8bd4909a | 9 | /// accepts various commands and translates and forwards those |
WiredHome | 0:12ed8bd4909a | 10 | /// to a connected CM17a (Firecracker) device. |
WiredHome | 0:12ed8bd4909a | 11 | /// |
WiredHome | 0:12ed8bd4909a | 12 | /// The system architecture for which this is relevant: |
WiredHome | 0:12ed8bd4909a | 13 | /// @code |
WiredHome | 0:12ed8bd4909a | 14 | /// +---------+ +---------+ +=========+ +---------+ |
WiredHome | 0:12ed8bd4909a | 15 | /// | Web |- Internet-| Web |- Network -| X10 | | CM17a | |
WiredHome | 0:12ed8bd4909a | 16 | /// | Browser | | Server | | | Server |-- RS232 --| Module | |
WiredHome | 0:12ed8bd4909a | 17 | /// +---------+ +---------+ .../ +=========+ +---------+ |
WiredHome | 0:12ed8bd4909a | 18 | /// / |
WiredHome | 0:12ed8bd4909a | 19 | /// ~|+|~~~~~~~ AC Line ~~~|+|~~~~~~~~~~~~~~~~~~~|+|~~~~~~~~~~~~~~~~|+|~ /_ |
WiredHome | 0:12ed8bd4909a | 20 | /// ~|+|~~~~~~~~~~~~~~~~~~~|+|~~~~~~~~~~~~~~~~~~~|+|~~~~~~~~~~~~~~~~|+|~ / |
WiredHome | 0:12ed8bd4909a | 21 | /// | | | | / |
WiredHome | 0:12ed8bd4909a | 22 | /// +---------+ +---------+ +---------+ +---------+ |
WiredHome | 0:12ed8bd4909a | 23 | /// | X10 | | X10 | | X10 | | TM751 | |
WiredHome | 0:12ed8bd4909a | 24 | /// | Module | | Module | | Module | | Module | |
WiredHome | 0:12ed8bd4909a | 25 | /// +---------+ +---------+ +---------+ +---------+ |
WiredHome | 0:12ed8bd4909a | 26 | /// | | | | |
WiredHome | 0:12ed8bd4909a | 27 | /// +---------+ +---------+ +---------+ +---------+ |
WiredHome | 0:12ed8bd4909a | 28 | /// |Appliance| |Appliance| |Appliance| |Appliance| |
WiredHome | 0:12ed8bd4909a | 29 | /// | | | | | | | | |
WiredHome | 0:12ed8bd4909a | 30 | /// +---------+ +---------+ +---------+ +---------+ |
WiredHome | 0:12ed8bd4909a | 31 | /// @endcode |
WiredHome | 0:12ed8bd4909a | 32 | /// |
WiredHome | 0:12ed8bd4909a | 33 | /// Other PCs in the house also had the SW component needed to send a message to |
WiredHome | 0:12ed8bd4909a | 34 | /// the X10 Server, and in the corner of one of them is a scheduled task (e.g. |
WiredHome | 0:12ed8bd4909a | 35 | /// cron job) to perform some automated control. This is suggested by the '...' |
WiredHome | 0:12ed8bd4909a | 36 | /// in the diagram above. |
WiredHome | 0:12ed8bd4909a | 37 | /// |
WiredHome | 0:12ed8bd4909a | 38 | /// The problem with this configuration is that the Web Server and the X10 Server |
WiredHome | 0:12ed8bd4909a | 39 | /// were PCs; consuming PC class power. For a while, they were one in the same PC, |
WiredHome | 0:12ed8bd4909a | 40 | /// but over time the network evolved and they split. The X10 Server was a bit more |
WiredHome | 0:12ed8bd4909a | 41 | /// power hungry than I would like, and needs to change. This X10Interface is a key |
WiredHome | 0:12ed8bd4909a | 42 | /// component in that change. |
WiredHome | 0:12ed8bd4909a | 43 | /// |
WiredHome | 0:12ed8bd4909a | 44 | /// The Software Architecture for the Network connected X10 Server and CM17a module: |
WiredHome | 0:12ed8bd4909a | 45 | /// @code |
WiredHome | 0:12ed8bd4909a | 46 | /// __ mbed module ____________________ |
WiredHome | 0:12ed8bd4909a | 47 | /// / \ |
WiredHome | 0:12ed8bd4909a | 48 | /// +---------+ +---------+ +---------+ +---------+ |
WiredHome | 0:12ed8bd4909a | 49 | /// | Network |- Network -| Socket |-----------|X10 | | CM17a | |
WiredHome | 0:12ed8bd4909a | 50 | /// | Device | | Listener| |Interface|-- DB-9 ---| Module | |
WiredHome | 0:12ed8bd4909a | 51 | /// +---------+ +---------+ +---------+ +---------+ |
WiredHome | 0:12ed8bd4909a | 52 | /// \__________________________________/ |
WiredHome | 0:12ed8bd4909a | 53 | /// @endcode |
WiredHome | 0:12ed8bd4909a | 54 | /// |
WiredHome | 0:12ed8bd4909a | 55 | class X10Interface |
WiredHome | 0:12ed8bd4909a | 56 | { |
WiredHome | 0:12ed8bd4909a | 57 | public: |
WiredHome | 0:12ed8bd4909a | 58 | typedef enum SIGNAL { |
WiredHome | 0:12ed8bd4909a | 59 | RESET = 0, |
WiredHome | 0:12ed8bd4909a | 60 | HIGH = 1, |
WiredHome | 0:12ed8bd4909a | 61 | LOW = 2, |
WiredHome | 0:12ed8bd4909a | 62 | STANDBY = 3 |
WiredHome | 0:12ed8bd4909a | 63 | } signal_t; |
WiredHome | 0:12ed8bd4909a | 64 | |
WiredHome | 0:12ed8bd4909a | 65 | /// return codes used by all features |
WiredHome | 0:12ed8bd4909a | 66 | typedef enum |
WiredHome | 0:12ed8bd4909a | 67 | { |
WiredHome | 0:12ed8bd4909a | 68 | ERR_SUCCESS, ///< Command was process successfully. |
WiredHome | 0:12ed8bd4909a | 69 | ERR_BADARGS, ///< Bad arguments were supplied, could not process. |
WiredHome | 0:12ed8bd4909a | 70 | ERR_NODESPEC, ///< Invalid house or unit code was supplied. |
WiredHome | 0:12ed8bd4909a | 71 | ERR_COMERR, ///< Could not properly queue commands for transmit (buffer full?). |
WiredHome | 0:12ed8bd4909a | 72 | ERR_BADSTEP, ///< Brighten and Dim commands only accept the range '1' to '6' |
WiredHome | 0:12ed8bd4909a | 73 | ERR_BADCMD ///< Parsing could not extract the command. |
WiredHome | 0:12ed8bd4909a | 74 | } ERR_EXIT; |
WiredHome | 0:12ed8bd4909a | 75 | |
WiredHome | 0:12ed8bd4909a | 76 | /// Constructor for the X10 interface |
WiredHome | 0:12ed8bd4909a | 77 | /// |
WiredHome | 0:12ed8bd4909a | 78 | /// This instantiates the X10 Interface object. When a command is received |
WiredHome | 0:12ed8bd4909a | 79 | /// it sends this to the connected CM17a module for transmitting. |
WiredHome | 0:12ed8bd4909a | 80 | /// |
WiredHome | 0:12ed8bd4909a | 81 | /// @code |
WiredHome | 0:12ed8bd4909a | 82 | /// |
WiredHome | 0:12ed8bd4909a | 83 | /// GND DTR TxD RxD DCD DB-9 Standard Pinout |
WiredHome | 0:12ed8bd4909a | 84 | /// 5 4 3 2 1 used by CM17a module |
WiredHome | 0:12ed8bd4909a | 85 | /// 9 8 7 6 |
WiredHome | 0:12ed8bd4909a | 86 | /// RI CTS RTS DSR |
WiredHome | 0:12ed8bd4909a | 87 | /// |
WiredHome | 0:12ed8bd4909a | 88 | /// DB-9 LowPower | Standby | '1' | Wait | '0' | Wait | '1' | Wait... |
WiredHome | 0:12ed8bd4909a | 89 | /// ___ _______ ___________________ ________ |
WiredHome | 0:12ed8bd4909a | 90 | /// DTR(4) _________| // |_____| |_____| |
WiredHome | 0:12ed8bd4909a | 91 | /// ___ ____________________ _____________________ |
WiredHome | 0:12ed8bd4909a | 92 | /// RTS(7) _________| // |_____| |
WiredHome | 0:12ed8bd4909a | 93 | /// |
WiredHome | 0:12ed8bd4909a | 94 | /// | bit period | = 1/BaudRate |
WiredHome | 0:12ed8bd4909a | 95 | /// GND(5) |
WiredHome | 0:12ed8bd4909a | 96 | /// @endcode |
WiredHome | 0:12ed8bd4909a | 97 | /// |
WiredHome | 0:12ed8bd4909a | 98 | /// @param[in] RTS is the mbed pin that the CM17a RTS pin is connected to. |
WiredHome | 0:12ed8bd4909a | 99 | /// @param[in] DTR is the mbed pin that the CM17a DTR pin is connected to. |
WiredHome | 0:12ed8bd4909a | 100 | /// @param[in] MultiMessageDelay_s is the delay in seconds between messages |
WiredHome | 0:12ed8bd4909a | 101 | /// when more than one message is queued at once. Default is 2. |
WiredHome | 0:12ed8bd4909a | 102 | /// @param[in] BaudRate is the desired baudrate for the communications |
WiredHome | 0:12ed8bd4909a | 103 | /// to the CM17a module. A 'bit' in BaudRate terms is the period |
WiredHome | 0:12ed8bd4909a | 104 | /// of an asserted 1 (or 0) followed by one of the 'wait' periods. |
WiredHome | 0:12ed8bd4909a | 105 | /// While there is not a known reason to change it, values in the |
WiredHome | 0:12ed8bd4909a | 106 | /// range 200 to 10000 have been tested successfully. |
WiredHome | 0:12ed8bd4909a | 107 | /// The default value is 2000. |
WiredHome | 0:12ed8bd4909a | 108 | /// |
WiredHome | 0:12ed8bd4909a | 109 | X10Interface(PinName RTS, PinName DTR, uint8_t MultiMessageDelay_s = 2, uint32_t BaudRate = 2000); |
WiredHome | 0:12ed8bd4909a | 110 | |
WiredHome | 0:12ed8bd4909a | 111 | /// Parse a command for the X10 Communications. |
WiredHome | 0:12ed8bd4909a | 112 | /// |
WiredHome | 0:12ed8bd4909a | 113 | /// This method accepts several different types and formats for commands. |
WiredHome | 0:12ed8bd4909a | 114 | /// |
WiredHome | 0:12ed8bd4909a | 115 | /// @note This method will modify the provided message as it parses it. |
WiredHome | 0:12ed8bd4909a | 116 | /// |
WiredHome | 0:12ed8bd4909a | 117 | /// @verbatim |
WiredHome | 0:12ed8bd4909a | 118 | /// <House><Unit> <cmd> [<House><Unit> <cmd> [...]] |
WiredHome | 0:12ed8bd4909a | 119 | /// House is 'a' - 'p' |
WiredHome | 0:12ed8bd4909a | 120 | /// Unit is '1' - '16' |
WiredHome | 0:12ed8bd4909a | 121 | /// cmd is 1=on, 0=off, +1 to +6 to brighten, -1 to -6 to dim. |
WiredHome | 0:12ed8bd4909a | 122 | /// /XXXX sends the hex value XXXX to the module. |
WiredHome | 0:12ed8bd4909a | 123 | /// ##### sets the baudrate to the value ##### |
WiredHome | 0:12ed8bd4909a | 124 | /// @endverbatim |
WiredHome | 0:12ed8bd4909a | 125 | /// |
WiredHome | 0:12ed8bd4909a | 126 | /// @param[in] message is the pointer to the buffer to process. The |
WiredHome | 0:12ed8bd4909a | 127 | /// buffer is modified, but there is no information sent back. |
WiredHome | 0:12ed8bd4909a | 128 | /// @returns X10Interface::ERR_EXIT code. |
WiredHome | 0:12ed8bd4909a | 129 | /// |
WiredHome | 0:12ed8bd4909a | 130 | ERR_EXIT ParseCommand(char * message); |
WiredHome | 0:12ed8bd4909a | 131 | |
WiredHome | 0:12ed8bd4909a | 132 | /// Set the communication baudrate to the CM17a module. |
WiredHome | 0:12ed8bd4909a | 133 | /// |
WiredHome | 0:12ed8bd4909a | 134 | /// @param[in] baudrate is the new baudrate. While any value is accepted, |
WiredHome | 0:12ed8bd4909a | 135 | /// the module may not operate under all possible settings. |
WiredHome | 0:12ed8bd4909a | 136 | /// @returns X10Interface::ERR_EXIT code. |
WiredHome | 0:12ed8bd4909a | 137 | /// |
WiredHome | 0:12ed8bd4909a | 138 | ERR_EXIT baud(uint32_t baudrate); |
WiredHome | 0:12ed8bd4909a | 139 | |
WiredHome | 0:12ed8bd4909a | 140 | /// Set the delay between messages when multiple messages are processed from |
WiredHome | 0:12ed8bd4909a | 141 | /// one command. |
WiredHome | 0:12ed8bd4909a | 142 | /// |
WiredHome | 0:12ed8bd4909a | 143 | /// @param[in] MultiMessageDelay_s is the delay in seconds that is applied |
WiredHome | 0:12ed8bd4909a | 144 | /// between commands to the CM17a. If this delay is not long enough, |
WiredHome | 0:12ed8bd4909a | 145 | /// commands might not be delivered to the receivers. |
WiredHome | 0:12ed8bd4909a | 146 | /// @returns X10Interface::ERR_EXIT code. |
WiredHome | 0:12ed8bd4909a | 147 | /// |
WiredHome | 0:12ed8bd4909a | 148 | ERR_EXIT delay(uint8_t MultiMessageDelay_s); |
WiredHome | 0:12ed8bd4909a | 149 | |
WiredHome | 0:12ed8bd4909a | 150 | private: |
WiredHome | 0:12ed8bd4909a | 151 | ERR_EXIT cm17a_Header(void); |
WiredHome | 0:12ed8bd4909a | 152 | ERR_EXIT enqueueData(uint16_t word); |
WiredHome | 0:12ed8bd4909a | 153 | ERR_EXIT cm17a_Footer(void); |
WiredHome | 0:12ed8bd4909a | 154 | ERR_EXIT DoCommand(const char* szDevice, const char* szOp); |
WiredHome | 0:12ed8bd4909a | 155 | uint16_t cm17a_CmdLookup(int iHouse, int iUnit, enum command_index command); |
WiredHome | 0:12ed8bd4909a | 156 | ERR_EXIT cm17a_CmdSend(int iHouse, int iUnit, enum command_index command); |
WiredHome | 0:12ed8bd4909a | 157 | ERR_EXIT cm17a_CmdSend(uint16_t command); |
WiredHome | 0:12ed8bd4909a | 158 | ERR_EXIT write_stream(const unsigned char* data, size_t byte_count); |
WiredHome | 0:12ed8bd4909a | 159 | ERR_EXIT parse_device(const char* szDevice, int* iHouse, int* iUnit); |
WiredHome | 0:12ed8bd4909a | 160 | |
WiredHome | 0:12ed8bd4909a | 161 | Ticker ticker; // used to manage the bitstream timing |
WiredHome | 0:12ed8bd4909a | 162 | Timer timer; // used for delays between messages |
WiredHome | 0:12ed8bd4909a | 163 | void x10stream(void); |
WiredHome | 0:12ed8bd4909a | 164 | BusOut * cm17Pins; |
WiredHome | 0:12ed8bd4909a | 165 | char commandBuffer[100]; // for parsing command streams |
WiredHome | 0:12ed8bd4909a | 166 | int mIndex; |
WiredHome | 0:12ed8bd4909a | 167 | |
WiredHome | 0:12ed8bd4909a | 168 | // This is the queue of stuff to send to the unit. It must be |
WiredHome | 0:12ed8bd4909a | 169 | // able to hold multiple messages, the equivalent of: |
WiredHome | 0:12ed8bd4909a | 170 | // a1 1 a2 0 a3 +1 a15 0 ... |
WiredHome | 0:12ed8bd4909a | 171 | // All commands for the CM17a are held in the lower 8 bits |
WiredHome | 0:12ed8bd4909a | 172 | // If the upper 8-bits is non-zero, it is a special command |
WiredHome | 0:12ed8bd4909a | 173 | // (typically to introduce delays between messages). |
WiredHome | 0:12ed8bd4909a | 174 | uint16_t bitBuffer[20]; |
WiredHome | 0:12ed8bd4909a | 175 | int bitEnqueue; |
WiredHome | 0:12ed8bd4909a | 176 | int bitDequeue; |
WiredHome | 0:12ed8bd4909a | 177 | |
WiredHome | 0:12ed8bd4909a | 178 | // Used when processing the queue to the port pins |
WiredHome | 0:12ed8bd4909a | 179 | int mask; |
WiredHome | 0:12ed8bd4909a | 180 | uint32_t bitperiod_us; |
WiredHome | 0:12ed8bd4909a | 181 | uint8_t multiMsgDelay_s; |
WiredHome | 0:12ed8bd4909a | 182 | }; |
WiredHome | 0:12ed8bd4909a | 183 | |
WiredHome | 0:12ed8bd4909a | 184 | |
WiredHome | 0:12ed8bd4909a | 185 | #endif // X10_H |