http://mbed.org/users/okini3939/notebook/melinverter
Dependents: MelInverter_sample
MelInverter.cpp@2:b1ef1c4d9c12, 2012-09-28 (annotated)
- Committer:
- okini3939
- Date:
- Fri Sep 28 03:28:47 2012 +0000
- Revision:
- 2:b1ef1c4d9c12
- Parent:
- 1:5963d2a1c30f
fix baud
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 | 2:b1ef1c4d9c12 | 19 | MelInverter::MelInverter (PinName p_tx, PinName p_rx, int baud) : _mel(p_tx, p_rx), _buf_data(40) { |
okini3939 | 2:b1ef1c4d9c12 | 20 | _mel.baud(baud); |
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 | 1:5963d2a1c30f | 38 | switch (dat) { |
okini3939 | 1:5963d2a1c30f | 39 | case INVCTRL_STX: |
okini3939 | 1:5963d2a1c30f | 40 | // Start of text |
okini3939 | 1:5963d2a1c30f | 41 | DBG("INVCTRL_STX\r\n"); |
okini3939 | 1:5963d2a1c30f | 42 | _mel_mode = MELMODE_STX; |
okini3939 | 1:5963d2a1c30f | 43 | mode = 0; |
okini3939 | 1:5963d2a1c30f | 44 | len = 0; |
okini3939 | 1:5963d2a1c30f | 45 | sum = 0; |
okini3939 | 1:5963d2a1c30f | 46 | s = 0; |
okini3939 | 1:5963d2a1c30f | 47 | _iid = 0; |
okini3939 | 1:5963d2a1c30f | 48 | break; |
okini3939 | 1:5963d2a1c30f | 49 | case INVCTRL_ACK: |
okini3939 | 1:5963d2a1c30f | 50 | // Acknowledge |
okini3939 | 1:5963d2a1c30f | 51 | DBG("INVCTRL_ACK\r\n"); |
okini3939 | 1:5963d2a1c30f | 52 | _mel_mode = MELMODE_ACK; |
okini3939 | 1:5963d2a1c30f | 53 | len = 0; |
okini3939 | 1:5963d2a1c30f | 54 | _iid = 0; |
okini3939 | 1:5963d2a1c30f | 55 | break; |
okini3939 | 1:5963d2a1c30f | 56 | case INVCTRL_NAK: |
okini3939 | 1:5963d2a1c30f | 57 | // Negative acknowledge |
okini3939 | 1:5963d2a1c30f | 58 | DBG("INVCTRL_NAK\r\n"); |
okini3939 | 1:5963d2a1c30f | 59 | _mel_mode = MELMODE_NAK; |
okini3939 | 1:5963d2a1c30f | 60 | len = 0; |
okini3939 | 1:5963d2a1c30f | 61 | _iid = 0; |
okini3939 | 1:5963d2a1c30f | 62 | break; |
okini3939 | 1:5963d2a1c30f | 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 | 1:5963d2a1c30f | 154 | Timer timer; |
okini3939 | 0:db82bb30177e | 155 | |
okini3939 | 2:b1ef1c4d9c12 | 156 | _mel_ok = 0; |
okini3939 | 2:b1ef1c4d9c12 | 157 | _mel_failure = 0; |
okini3939 | 0:db82bb30177e | 158 | _mel.putc(INVCTRL_ENQ); |
okini3939 | 0:db82bb30177e | 159 | sprintf(buf, "%02X%02X%01X", iid, cmd, MELDELAY); |
okini3939 | 0:db82bb30177e | 160 | strncat(buf, data, 20); |
okini3939 | 0:db82bb30177e | 161 | for (i = 0; i < strlen(buf); i ++) { |
okini3939 | 0:db82bb30177e | 162 | _mel.putc(buf[i]); |
okini3939 | 0:db82bb30177e | 163 | sum += (unsigned char)buf[i]; |
okini3939 | 0:db82bb30177e | 164 | } |
okini3939 | 0:db82bb30177e | 165 | _mel.printf("%02X\r", sum & 0xff); |
okini3939 | 0:db82bb30177e | 166 | DBG("command: %d %02X %s\r\n", iid, cmd, buf); |
okini3939 | 1:5963d2a1c30f | 167 | |
okini3939 | 1:5963d2a1c30f | 168 | timer.start(); |
okini3939 | 1:5963d2a1c30f | 169 | while (_mel_ok == 0 && _mel_failure == 0) { |
okini3939 | 1:5963d2a1c30f | 170 | if (timer.read_ms() >= MELTIMEOUT) { |
okini3939 | 1:5963d2a1c30f | 171 | DBG("timeout\r\n"); |
okini3939 | 1:5963d2a1c30f | 172 | timer.stop(); |
okini3939 | 1:5963d2a1c30f | 173 | return 0; |
okini3939 | 1:5963d2a1c30f | 174 | } |
okini3939 | 1:5963d2a1c30f | 175 | } |
okini3939 | 1:5963d2a1c30f | 176 | timer.stop(); |
okini3939 | 2:b1ef1c4d9c12 | 177 | DBG("ok\r\n"); |
okini3939 | 2:b1ef1c4d9c12 | 178 | return _mel_ok == 1 ? 0 : -1; |
okini3939 | 0:db82bb30177e | 179 | } |
okini3939 | 0:db82bb30177e | 180 | |
okini3939 | 0:db82bb30177e | 181 | int MelInverter::recv (int iid, char *buf, int len) { |
okini3939 | 0:db82bb30177e | 182 | int r; |
okini3939 | 1:5963d2a1c30f | 183 | Timer timer; |
okini3939 | 0:db82bb30177e | 184 | |
okini3939 | 1:5963d2a1c30f | 185 | timer.start(); |
okini3939 | 1:5963d2a1c30f | 186 | while (iid != _iid && _mel_recv == 0) { |
okini3939 | 1:5963d2a1c30f | 187 | if (timer.read_ms() >= MELTIMEOUT) { |
okini3939 | 1:5963d2a1c30f | 188 | DBG("timeout\r\n"); |
okini3939 | 1:5963d2a1c30f | 189 | return 0; |
okini3939 | 1:5963d2a1c30f | 190 | } |
okini3939 | 1:5963d2a1c30f | 191 | } |
okini3939 | 0:db82bb30177e | 192 | |
okini3939 | 0:db82bb30177e | 193 | _mel_recv = 0; |
okini3939 | 0:db82bb30177e | 194 | r = _buf_data.get(buf, len); |
okini3939 | 0:db82bb30177e | 195 | return r; |
okini3939 | 0:db82bb30177e | 196 | } |
okini3939 | 0:db82bb30177e | 197 | |
okini3939 | 0:db82bb30177e | 198 | |
okini3939 | 0:db82bb30177e | 199 | int MelInverter::x2i (char c) { |
okini3939 | 0:db82bb30177e | 200 | if (c >= '0' && c <= '9') { |
okini3939 | 0:db82bb30177e | 201 | return c - '0'; |
okini3939 | 0:db82bb30177e | 202 | } else |
okini3939 | 0:db82bb30177e | 203 | if (c >= 'A' && c <= 'F') { |
okini3939 | 0:db82bb30177e | 204 | return c - 'A' + 10; |
okini3939 | 0:db82bb30177e | 205 | } else |
okini3939 | 0:db82bb30177e | 206 | if (c >= 'a' && c <= 'f') { |
okini3939 | 0:db82bb30177e | 207 | return c - 'a' + 10; |
okini3939 | 0:db82bb30177e | 208 | } |
okini3939 | 0:db82bb30177e | 209 | return 0; |
okini3939 | 0:db82bb30177e | 210 | } |
okini3939 | 0:db82bb30177e | 211 | |
okini3939 | 0:db82bb30177e | 212 | char MelInverter::i2x (int i) { |
okini3939 | 0:db82bb30177e | 213 | if (i >= 0 && i <= 9) { |
okini3939 | 0:db82bb30177e | 214 | return i + '0'; |
okini3939 | 0:db82bb30177e | 215 | } else |
okini3939 | 0:db82bb30177e | 216 | if (i >= 10 && i <= 15) { |
okini3939 | 0:db82bb30177e | 217 | return i - 10 + 'A'; |
okini3939 | 0:db82bb30177e | 218 | } |
okini3939 | 0:db82bb30177e | 219 | return 0; |
okini3939 | 0:db82bb30177e | 220 | } |
okini3939 | 0:db82bb30177e | 221 |