http://mbed.org/users/okini3939/notebook/melinverter
Dependents: MelInverter_sample
MelInverter.cpp@0:db82bb30177e, 2012-03-29 (annotated)
- Committer:
- okini3939
- Date:
- Thu Mar 29 06:13:13 2012 +0000
- Revision:
- 0:db82bb30177e
- Child:
- 1:5963d2a1c30f
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 0:db82bb30177e | 1 | /** |
okini3939 | 0:db82bb30177e | 2 | * Mitsubishi Inverter Protocol library for mbed |
okini3939 | 0:db82bb30177e | 3 | * Copyright (c) 2012 Suga |
okini3939 | 0:db82bb30177e | 4 | * Released under the MIT License: http://mbed.org/license/mit |
okini3939 | 0:db82bb30177e | 5 | */ |
okini3939 | 0:db82bb30177e | 6 | |
okini3939 | 0:db82bb30177e | 7 | /** @file |
okini3939 | 0:db82bb30177e | 8 | * @brief Mitsubishi Inverter Protocol library for mbed |
okini3939 | 0:db82bb30177e | 9 | * @note need: http://mbed.org/users/okini3939/libraries/RingBuffer/latest |
okini3939 | 0:db82bb30177e | 10 | * FR-E700 |
okini3939 | 0:db82bb30177e | 11 | * Pr.79=2, Pr.340=1, Pr.549=0 |
okini3939 | 0:db82bb30177e | 12 | * 19200bps, 8bit data, Stop 2bit, Even parity, CR |
okini3939 | 0:db82bb30177e | 13 | */ |
okini3939 | 0:db82bb30177e | 14 | |
okini3939 | 0:db82bb30177e | 15 | #include "dbg.h" |
okini3939 | 0:db82bb30177e | 16 | #include "mbed.h" |
okini3939 | 0:db82bb30177e | 17 | #include "MelInverter.h" |
okini3939 | 0:db82bb30177e | 18 | |
okini3939 | 0:db82bb30177e | 19 | MelInverter::MelInverter (PinName p_tx, PinName p_rx) : _mel(p_tx, p_rx), _buf_data(40) { |
okini3939 | 0:db82bb30177e | 20 | _mel.baud(19200); |
okini3939 | 0:db82bb30177e | 21 | _mel.format(8, Serial::Even, 2); |
okini3939 | 0:db82bb30177e | 22 | _mel.attach(this, &MelInverter::isr_mel, Serial::RxIrq); |
okini3939 | 0:db82bb30177e | 23 | } |
okini3939 | 0:db82bb30177e | 24 | |
okini3939 | 0:db82bb30177e | 25 | void MelInverter::isr_mel () { |
okini3939 | 0:db82bb30177e | 26 | static int len, mode, sum, s; |
okini3939 | 0:db82bb30177e | 27 | static char tmp[20]; |
okini3939 | 0:db82bb30177e | 28 | char dat; |
okini3939 | 0:db82bb30177e | 29 | |
okini3939 | 0:db82bb30177e | 30 | dat = _mel.getc(); |
okini3939 | 0:db82bb30177e | 31 | |
okini3939 | 0:db82bb30177e | 32 | if (dat == INVCTRL_CR) { |
okini3939 | 0:db82bb30177e | 33 | _mel_mode = MELMODE_NONE; |
okini3939 | 0:db82bb30177e | 34 | } |
okini3939 | 0:db82bb30177e | 35 | |
okini3939 | 0:db82bb30177e | 36 | switch (_mel_mode) { |
okini3939 | 0:db82bb30177e | 37 | case MELMODE_NONE: |
okini3939 | 0:db82bb30177e | 38 | switch (dat) { |
okini3939 | 0:db82bb30177e | 39 | case INVCTRL_STX: |
okini3939 | 0:db82bb30177e | 40 | // Start of text |
okini3939 | 0:db82bb30177e | 41 | DBG("INVCTRL_STX\r\n"); |
okini3939 | 0:db82bb30177e | 42 | _mel_mode = MELMODE_STX; |
okini3939 | 0:db82bb30177e | 43 | mode = 0; |
okini3939 | 0:db82bb30177e | 44 | len = 0; |
okini3939 | 0:db82bb30177e | 45 | sum = 0; |
okini3939 | 0:db82bb30177e | 46 | s = 0; |
okini3939 | 0:db82bb30177e | 47 | _iid = 0; |
okini3939 | 0:db82bb30177e | 48 | break; |
okini3939 | 0:db82bb30177e | 49 | case INVCTRL_ACK: |
okini3939 | 0:db82bb30177e | 50 | // Acknowledge |
okini3939 | 0:db82bb30177e | 51 | DBG("INVCTRL_ACK\r\n"); |
okini3939 | 0:db82bb30177e | 52 | _mel_mode = MELMODE_ACK; |
okini3939 | 0:db82bb30177e | 53 | len = 0; |
okini3939 | 0:db82bb30177e | 54 | _iid = 0; |
okini3939 | 0:db82bb30177e | 55 | break; |
okini3939 | 0:db82bb30177e | 56 | case INVCTRL_NAK: |
okini3939 | 0:db82bb30177e | 57 | // Negative acknowledge |
okini3939 | 0:db82bb30177e | 58 | DBG("INVCTRL_NAK\r\n"); |
okini3939 | 0:db82bb30177e | 59 | _mel_mode = MELMODE_NAK; |
okini3939 | 0:db82bb30177e | 60 | len = 0; |
okini3939 | 0:db82bb30177e | 61 | _iid = 0; |
okini3939 | 0:db82bb30177e | 62 | break; |
okini3939 | 0:db82bb30177e | 63 | } |
okini3939 | 0:db82bb30177e | 64 | break; |
okini3939 | 0:db82bb30177e | 65 | |
okini3939 | 0:db82bb30177e | 66 | case MELMODE_STX: |
okini3939 | 0:db82bb30177e | 67 | if (mode == 0) { |
okini3939 | 0:db82bb30177e | 68 | // device id |
okini3939 | 0:db82bb30177e | 69 | tmp[len] = dat; |
okini3939 | 0:db82bb30177e | 70 | len ++; |
okini3939 | 0:db82bb30177e | 71 | sum += (unsigned char)dat; |
okini3939 | 0:db82bb30177e | 72 | if (len >= 2) { |
okini3939 | 0:db82bb30177e | 73 | tmp[len] = 0; |
okini3939 | 0:db82bb30177e | 74 | _iid = strtol(tmp, NULL, 16); |
okini3939 | 0:db82bb30177e | 75 | mode ++; |
okini3939 | 0:db82bb30177e | 76 | } |
okini3939 | 0:db82bb30177e | 77 | } else |
okini3939 | 0:db82bb30177e | 78 | if (mode == 1) { |
okini3939 | 0:db82bb30177e | 79 | if (dat == INVCTRL_ETX) { |
okini3939 | 0:db82bb30177e | 80 | // End of text |
okini3939 | 0:db82bb30177e | 81 | len = 0; |
okini3939 | 0:db82bb30177e | 82 | s = 0; |
okini3939 | 0:db82bb30177e | 83 | mode ++; |
okini3939 | 0:db82bb30177e | 84 | } else { |
okini3939 | 0:db82bb30177e | 85 | _buf_data.put(dat); |
okini3939 | 0:db82bb30177e | 86 | sum += (unsigned char)dat; |
okini3939 | 0:db82bb30177e | 87 | } |
okini3939 | 0:db82bb30177e | 88 | } else |
okini3939 | 0:db82bb30177e | 89 | if (mode == 2) { |
okini3939 | 0:db82bb30177e | 90 | s = (s << 4) + x2i(dat); |
okini3939 | 0:db82bb30177e | 91 | len ++; |
okini3939 | 0:db82bb30177e | 92 | if (len >= 2) { |
okini3939 | 0:db82bb30177e | 93 | if (s == (sum & 0xff)) { |
okini3939 | 0:db82bb30177e | 94 | _mel_ok = 1; |
okini3939 | 0:db82bb30177e | 95 | _mel_recv = 1; |
okini3939 | 0:db82bb30177e | 96 | _res.attach_us(this, &MelInverter::isr_ack, 10000); |
okini3939 | 0:db82bb30177e | 97 | } else { |
okini3939 | 0:db82bb30177e | 98 | _mel_failure = 1; |
okini3939 | 0:db82bb30177e | 99 | _mel_recv = 1; |
okini3939 | 0:db82bb30177e | 100 | _res.attach_us(this, &MelInverter::isr_nak, 10000); |
okini3939 | 0:db82bb30177e | 101 | DBG("sum error %02x\r\n", sum & 0xff); |
okini3939 | 0:db82bb30177e | 102 | } |
okini3939 | 0:db82bb30177e | 103 | mode ++; |
okini3939 | 0:db82bb30177e | 104 | } |
okini3939 | 0:db82bb30177e | 105 | } |
okini3939 | 0:db82bb30177e | 106 | break; |
okini3939 | 0:db82bb30177e | 107 | |
okini3939 | 0:db82bb30177e | 108 | case MELMODE_ACK: |
okini3939 | 0:db82bb30177e | 109 | if (len < 2) { |
okini3939 | 0:db82bb30177e | 110 | // device id |
okini3939 | 0:db82bb30177e | 111 | tmp[len] = dat; |
okini3939 | 0:db82bb30177e | 112 | len ++; |
okini3939 | 0:db82bb30177e | 113 | if (len >= 2) { |
okini3939 | 0:db82bb30177e | 114 | tmp[len] = 0; |
okini3939 | 0:db82bb30177e | 115 | _iid = strtol(tmp, NULL, 16); |
okini3939 | 0:db82bb30177e | 116 | _mel_ok = 1; |
okini3939 | 0:db82bb30177e | 117 | } |
okini3939 | 0:db82bb30177e | 118 | } |
okini3939 | 0:db82bb30177e | 119 | break; |
okini3939 | 0:db82bb30177e | 120 | |
okini3939 | 0:db82bb30177e | 121 | case MELMODE_NAK: |
okini3939 | 0:db82bb30177e | 122 | if (len < 2) { |
okini3939 | 0:db82bb30177e | 123 | // device id |
okini3939 | 0:db82bb30177e | 124 | tmp[len] = dat; |
okini3939 | 0:db82bb30177e | 125 | len ++; |
okini3939 | 0:db82bb30177e | 126 | if (len >= 2) { |
okini3939 | 0:db82bb30177e | 127 | tmp[len] = 0; |
okini3939 | 0:db82bb30177e | 128 | _iid = strtol(tmp, NULL, 16); |
okini3939 | 0:db82bb30177e | 129 | _mel_failure = 1; |
okini3939 | 0:db82bb30177e | 130 | } |
okini3939 | 0:db82bb30177e | 131 | } |
okini3939 | 0:db82bb30177e | 132 | break; |
okini3939 | 0:db82bb30177e | 133 | } |
okini3939 | 0:db82bb30177e | 134 | |
okini3939 | 0:db82bb30177e | 135 | } |
okini3939 | 0:db82bb30177e | 136 | |
okini3939 | 0:db82bb30177e | 137 | void MelInverter::isr_ack () { |
okini3939 | 0:db82bb30177e | 138 | _res.detach(); |
okini3939 | 0:db82bb30177e | 139 | _mel.putc(INVCTRL_ACK); |
okini3939 | 0:db82bb30177e | 140 | _mel.printf("%02X\r", _iid); |
okini3939 | 0:db82bb30177e | 141 | DBG("ACK\r\n"); |
okini3939 | 0:db82bb30177e | 142 | } |
okini3939 | 0:db82bb30177e | 143 | |
okini3939 | 0:db82bb30177e | 144 | void MelInverter::isr_nak () { |
okini3939 | 0:db82bb30177e | 145 | _res.detach(); |
okini3939 | 0:db82bb30177e | 146 | _mel.putc(INVCTRL_NAK); |
okini3939 | 0:db82bb30177e | 147 | _mel.printf("%02X\r", _iid); |
okini3939 | 0:db82bb30177e | 148 | DBG("ACK\r\n"); |
okini3939 | 0:db82bb30177e | 149 | } |
okini3939 | 0:db82bb30177e | 150 | |
okini3939 | 0:db82bb30177e | 151 | int MelInverter::send (int iid, MELCMD cmd, char *data) { |
okini3939 | 0:db82bb30177e | 152 | int i, sum = 0; |
okini3939 | 0:db82bb30177e | 153 | char buf[40]; |
okini3939 | 0:db82bb30177e | 154 | |
okini3939 | 0:db82bb30177e | 155 | _mel.putc(INVCTRL_ENQ); |
okini3939 | 0:db82bb30177e | 156 | sprintf(buf, "%02X%02X%01X", iid, cmd, MELDELAY); |
okini3939 | 0:db82bb30177e | 157 | strncat(buf, data, 20); |
okini3939 | 0:db82bb30177e | 158 | for (i = 0; i < strlen(buf); i ++) { |
okini3939 | 0:db82bb30177e | 159 | _mel.putc(buf[i]); |
okini3939 | 0:db82bb30177e | 160 | sum += (unsigned char)buf[i]; |
okini3939 | 0:db82bb30177e | 161 | } |
okini3939 | 0:db82bb30177e | 162 | _mel.printf("%02X\r", sum & 0xff); |
okini3939 | 0:db82bb30177e | 163 | DBG("command: %d %02X %s\r\n", iid, cmd, buf); |
okini3939 | 0:db82bb30177e | 164 | while (!_mel_ok && !_mel_failure); |
okini3939 | 0:db82bb30177e | 165 | return (_mel_ok == 1); |
okini3939 | 0:db82bb30177e | 166 | } |
okini3939 | 0:db82bb30177e | 167 | |
okini3939 | 0:db82bb30177e | 168 | int MelInverter::recv (int iid, char *buf, int len) { |
okini3939 | 0:db82bb30177e | 169 | int r; |
okini3939 | 0:db82bb30177e | 170 | |
okini3939 | 0:db82bb30177e | 171 | while (iid != _iid && _mel_recv == 0); |
okini3939 | 0:db82bb30177e | 172 | |
okini3939 | 0:db82bb30177e | 173 | _mel_recv = 0; |
okini3939 | 0:db82bb30177e | 174 | r = _buf_data.get(buf, len); |
okini3939 | 0:db82bb30177e | 175 | return r; |
okini3939 | 0:db82bb30177e | 176 | } |
okini3939 | 0:db82bb30177e | 177 | |
okini3939 | 0:db82bb30177e | 178 | |
okini3939 | 0:db82bb30177e | 179 | int MelInverter::x2i (char c) { |
okini3939 | 0:db82bb30177e | 180 | if (c >= '0' && c <= '9') { |
okini3939 | 0:db82bb30177e | 181 | return c - '0'; |
okini3939 | 0:db82bb30177e | 182 | } else |
okini3939 | 0:db82bb30177e | 183 | if (c >= 'A' && c <= 'F') { |
okini3939 | 0:db82bb30177e | 184 | return c - 'A' + 10; |
okini3939 | 0:db82bb30177e | 185 | } else |
okini3939 | 0:db82bb30177e | 186 | if (c >= 'a' && c <= 'f') { |
okini3939 | 0:db82bb30177e | 187 | return c - 'a' + 10; |
okini3939 | 0:db82bb30177e | 188 | } |
okini3939 | 0:db82bb30177e | 189 | return 0; |
okini3939 | 0:db82bb30177e | 190 | } |
okini3939 | 0:db82bb30177e | 191 | |
okini3939 | 0:db82bb30177e | 192 | char MelInverter::i2x (int i) { |
okini3939 | 0:db82bb30177e | 193 | if (i >= 0 && i <= 9) { |
okini3939 | 0:db82bb30177e | 194 | return i + '0'; |
okini3939 | 0:db82bb30177e | 195 | } else |
okini3939 | 0:db82bb30177e | 196 | if (i >= 10 && i <= 15) { |
okini3939 | 0:db82bb30177e | 197 | return i - 10 + 'A'; |
okini3939 | 0:db82bb30177e | 198 | } |
okini3939 | 0:db82bb30177e | 199 | return 0; |
okini3939 | 0:db82bb30177e | 200 | } |
okini3939 | 0:db82bb30177e | 201 |