http://mbed.org/users/okini3939/notebook/melinverter

Dependents:   MelInverter_sample

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?

UserRevisionLine numberNew 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