http://mbed.org/users/okini3939/notebook/melinverter
Dependents: MelInverter_sample
MelInverter.cpp
- Committer:
- okini3939
- Date:
- 2012-03-29
- Revision:
- 0:db82bb30177e
- Child:
- 1:5963d2a1c30f
File content as of revision 0:db82bb30177e:
/** * Mitsubishi Inverter Protocol library for mbed * Copyright (c) 2012 Suga * Released under the MIT License: http://mbed.org/license/mit */ /** @file * @brief Mitsubishi Inverter Protocol library for mbed * @note need: http://mbed.org/users/okini3939/libraries/RingBuffer/latest * FR-E700 * Pr.79=2, Pr.340=1, Pr.549=0 * 19200bps, 8bit data, Stop 2bit, Even parity, CR */ #include "dbg.h" #include "mbed.h" #include "MelInverter.h" MelInverter::MelInverter (PinName p_tx, PinName p_rx) : _mel(p_tx, p_rx), _buf_data(40) { _mel.baud(19200); _mel.format(8, Serial::Even, 2); _mel.attach(this, &MelInverter::isr_mel, Serial::RxIrq); } void MelInverter::isr_mel () { static int len, mode, sum, s; static char tmp[20]; char dat; dat = _mel.getc(); if (dat == INVCTRL_CR) { _mel_mode = MELMODE_NONE; } switch (_mel_mode) { case MELMODE_NONE: switch (dat) { case INVCTRL_STX: // Start of text DBG("INVCTRL_STX\r\n"); _mel_mode = MELMODE_STX; mode = 0; len = 0; sum = 0; s = 0; _iid = 0; break; case INVCTRL_ACK: // Acknowledge DBG("INVCTRL_ACK\r\n"); _mel_mode = MELMODE_ACK; len = 0; _iid = 0; break; case INVCTRL_NAK: // Negative acknowledge DBG("INVCTRL_NAK\r\n"); _mel_mode = MELMODE_NAK; len = 0; _iid = 0; break; } break; case MELMODE_STX: if (mode == 0) { // device id tmp[len] = dat; len ++; sum += (unsigned char)dat; if (len >= 2) { tmp[len] = 0; _iid = strtol(tmp, NULL, 16); mode ++; } } else if (mode == 1) { if (dat == INVCTRL_ETX) { // End of text len = 0; s = 0; mode ++; } else { _buf_data.put(dat); sum += (unsigned char)dat; } } else if (mode == 2) { s = (s << 4) + x2i(dat); len ++; if (len >= 2) { if (s == (sum & 0xff)) { _mel_ok = 1; _mel_recv = 1; _res.attach_us(this, &MelInverter::isr_ack, 10000); } else { _mel_failure = 1; _mel_recv = 1; _res.attach_us(this, &MelInverter::isr_nak, 10000); DBG("sum error %02x\r\n", sum & 0xff); } mode ++; } } break; case MELMODE_ACK: if (len < 2) { // device id tmp[len] = dat; len ++; if (len >= 2) { tmp[len] = 0; _iid = strtol(tmp, NULL, 16); _mel_ok = 1; } } break; case MELMODE_NAK: if (len < 2) { // device id tmp[len] = dat; len ++; if (len >= 2) { tmp[len] = 0; _iid = strtol(tmp, NULL, 16); _mel_failure = 1; } } break; } } void MelInverter::isr_ack () { _res.detach(); _mel.putc(INVCTRL_ACK); _mel.printf("%02X\r", _iid); DBG("ACK\r\n"); } void MelInverter::isr_nak () { _res.detach(); _mel.putc(INVCTRL_NAK); _mel.printf("%02X\r", _iid); DBG("ACK\r\n"); } int MelInverter::send (int iid, MELCMD cmd, char *data) { int i, sum = 0; char buf[40]; _mel.putc(INVCTRL_ENQ); sprintf(buf, "%02X%02X%01X", iid, cmd, MELDELAY); strncat(buf, data, 20); for (i = 0; i < strlen(buf); i ++) { _mel.putc(buf[i]); sum += (unsigned char)buf[i]; } _mel.printf("%02X\r", sum & 0xff); DBG("command: %d %02X %s\r\n", iid, cmd, buf); while (!_mel_ok && !_mel_failure); return (_mel_ok == 1); } int MelInverter::recv (int iid, char *buf, int len) { int r; while (iid != _iid && _mel_recv == 0); _mel_recv = 0; r = _buf_data.get(buf, len); return r; } int MelInverter::x2i (char c) { if (c >= '0' && c <= '9') { return c - '0'; } else if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } else if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } return 0; } char MelInverter::i2x (int i) { if (i >= 0 && i <= 9) { return i + '0'; } else if (i >= 10 && i <= 15) { return i - 10 + 'A'; } return 0; }