Files
ebusd/lib/ebus-decode.c
T

440 lines
7.6 KiB
C

/*
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
* crc calculations from http://www.mikrocontroller.net/topic/75698
*
* This file is part of ebusd.
*
* ebusd is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ebusd is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ebusd. If not, see http://www.gnu.org/licenses/.
*/
/**
* @file ebus-decode.c
* @brief ebus decode functions
* @author roland.jax@liwest.at
* @version 0.1
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "ebus-decode.h"
const char *days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
int
eb_htoi(const char *buf)
{
int ret;
ret = -1;
if (isxdigit(*buf)) {
if (isalpha(*buf))
ret = 55;
else
ret = 48;
ret = toupper(*buf) - ret;
}
return ret;
}
void
eb_esc(unsigned char *buf, int *buflen)
{
unsigned char tmp[BUS_DEVICE_BUFSIZE];
int tmplen, i;
memset(tmp, '\0', sizeof(tmp));
i = 0;
tmplen = 0;
while (i < *buflen) {
if (buf[i] == EBUS_SYN) {
tmp[tmplen] = EBUS_SYN_ESC_A9;
tmplen++;
tmp[tmplen] = EBUS_SYN_ESC_01;
tmplen++;
} else if (buf[i] == EBUS_SYN_ESC_A9) {
tmp[tmplen] = EBUS_SYN_ESC_A9;
tmplen++;
tmp[tmplen] = EBUS_SYN_ESC_00;
tmplen++;
} else {
tmp[tmplen] = buf[i];
tmplen++;
}
i++;
}
memset(buf, '\0', sizeof(buf));
for (i = 0; i < tmplen; i++)
buf[i] = tmp[i];
*buflen = tmplen;
}
void
eb_unesc(unsigned char *buf, int *buflen)
{
unsigned char tmp[BUS_DEVICE_BUFSIZE];
int tmplen, i, found;
memset(tmp, '\0', sizeof(tmp));
i = 0;
tmplen = 0;
found = 0;
while (i < *buflen) {
if (buf[i] == EBUS_SYN_ESC_A9) {
found = 1;
} else if (found == 1) {
if (buf[i] == EBUS_SYN_ESC_01) {
tmp[tmplen] = EBUS_SYN;
tmplen++;
} else {
tmp[tmplen] = EBUS_SYN_ESC_A9;
tmplen++;
}
found = 0;
} else {
tmp[tmplen] = buf[i];
tmplen++;
}
i++;
}
memset(buf, '\0', sizeof(buf));
for (i = 0; i < tmplen; i++)
buf[i] = tmp[i];
*buflen = tmplen;
}
int
eb_day_to_str(unsigned char day, char *tgt)
{
int dd;
if ((day & 0x0F) >= 0x00 && (day & 0x0F) <= 0x06) {
eb_bcd_to_int(day, &dd);
sprintf(tgt, "%s", days[dd]);
} else {
return -1;
}
return 0;
}
int
eb_dat_to_str(unsigned char dd, unsigned char mm, unsigned char yy, char *tgt)
{
if ((dd & 0x7F) >= 0x00 && (dd & 0x7F) <= 0x1F &&
(mm & 0x7F) >= 0x00 && (mm & 0x7F) <= 0x0C &&
(yy & 0x7F) >= 0x00 && (yy & 0x7F) <= 0x63 )
sprintf(tgt, "%02d.%02d.%04d", dd, mm, yy + 2000);
else
return -1;
return 0;
}
int
eb_str_to_dat(int dd, int mm, int yy, unsigned char *tgt)
{
if (yy > 2000)
yy -= 2000;
if (dd >= 0 && dd <= 31 &&
mm >= 0 && mm <= 12 &&
yy >= 0 && yy <= 99 )
sprintf((char *) tgt, "%02x%02x%02x", dd, mm, yy);
else
return -1;
return 0;
}
int
eb_tim_to_str(unsigned char hh, unsigned char mm, unsigned char ss, char *tgt)
{
if ((hh & 0x7F) >= 0x00 && (hh & 0x7F) <= 0x17 &&
(mm & 0x7F) >= 0x00 && (mm & 0x7F) <= 0x3B &&
(ss & 0x7F) >= 0x00 && (ss & 0x7F) <= 0x3B )
sprintf(tgt, "%02d:%02d:%02d", hh, mm, ss);
else
return -1;
return 0;
}
int
eb_str_to_tim(int hh, int mm, int ss, unsigned char *tgt)
{
if (hh >= 0 && hh <= 23 &&
mm >= 0 && mm <= 59 &&
ss >= 0 && ss <= 59 )
sprintf((char *) tgt, "%02x%02x%02x", hh, mm, ss);
else
return -1;
return 0;
}
int
eb_bcd_to_int(unsigned char src, int *tgt)
{
if ((src & 0x0F) > 0x09 || ((src >> 4) & 0x0F) > 0x09) {
*tgt = (int) (0xFF);
return 0;
} else {
*tgt = (int) ( ( ((src & 0xF0) >> 4) * 10) + (src & 0x0F) );
return 1;
}
}
int
eb_int_to_bcd(int src, unsigned char *tgt)
{
if (src > 99) {
*tgt = (unsigned char) (0xFF);
return 0;
} else {
*tgt = (unsigned char) ( ((src / 10) << 4) | (src % 10) );
return 1;
}
}
int
eb_d1b_to_int(unsigned char src, int *tgt)
{
if ((src & 0x80) == 0x80) {
*tgt = (int) (- ( ((unsigned char) (~ src)) + 1) );
if (*tgt == -0x80)
return 0;
else
return -1;
} else {
*tgt = (int) (src);
return 1;
}
}
int
eb_int_to_d1b(int src, unsigned char *tgt)
{
if (src < -127 || src > 127) {
*tgt = (unsigned char) (0x80);
return 0;
} else {
if (src >= 0) {
*tgt = (unsigned char) (src);
return 1;
} else {
*tgt = (unsigned char) (- (~ (src - 1) ) );
return -1;
}
}
}
int
eb_d1c_to_float(unsigned char src, float *tgt)
{
if (src > 0xC8) {
*tgt = (float) (0xFF);
return 0;
} else {
*tgt = (float) (src / 2.0);
return 1;
}
}
int
eb_float_to_d1c(float src, unsigned char *tgt)
{
if (src < 0.0 || src > 100.0) {
*tgt = (unsigned char) (0xFF);
return 0;
} else {
*tgt = (unsigned char) (src * 2.0);
return 1;
}
}
int
eb_d2b_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt)
{
if ((src_msb & 0x80) == 0x80) {
*tgt = (float)
(- ( ((unsigned char) (~ src_msb)) +
( ( ((unsigned char) (~ src_lsb)) + 1) / 256.0) ) );
if (src_msb == 0x80 && src_lsb == 0x00)
return 0;
else
return -1;
} else {
*tgt = (float) (src_msb + (src_lsb / 256.0));
return 1;
}
}
int
eb_float_to_d2b(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb)
{
if (src < -127.999 || src > 127.999) {
*tgt_msb = (unsigned char) (0x80);
*tgt_lsb = (unsigned char) (0x00);
return 0;
} else {
*tgt_lsb = (unsigned char) ((src - ((unsigned char) src)) * 256.0);
if (src < 0.0 && *tgt_lsb != 0x00)
*tgt_msb = (unsigned char) (src - 1);
else
*tgt_msb = (unsigned char) (src);
if (src >= 0.0)
return 1;
else
return -1;
}
}
int
eb_d2c_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt)
{
if ((src_msb & 0x80) == 0x80) {
*tgt = (float)
(- ( ( ( ((unsigned char) (~ src_msb)) * 16.0) ) +
( ( ((unsigned char) (~ src_lsb)) & 0xF0) >> 4) +
( ( ( ((unsigned char) (~ src_lsb)) & 0x0F) +1 ) / 16.0) ) );
if (src_msb == 0x80 && src_lsb == 0x00)
return 0;
else
return -1;
} else {
*tgt = (float) ( (src_msb * 16.0) + ((src_lsb & 0xF0) >> 4) +
((src_lsb & 0x0F) / 16.0) );
return 1;
}
}
int
eb_float_to_d2c(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb)
{
if (src < -2047.999 || src > 2047.999) {
*tgt_msb = (unsigned char) (0x80);
*tgt_lsb = (unsigned char) (0x00);
return 0;
} else {
*tgt_lsb =
( ((unsigned char) ( ((unsigned char) src) % 16) << 4) +
((unsigned char) ( (src - ((unsigned char) src)) * 16.0)) );
if (src < 0.0 && *tgt_lsb != 0x00)
*tgt_msb = (unsigned char) ((src / 16.0) - 1);
else
*tgt_msb = (unsigned char) (src / 16.0);
if (src >= 0.0)
return 1;
else
return -1;
}
}
unsigned char
eb_calc_crc_byte(unsigned char byte, unsigned char init_crc)
{
unsigned char crc, polynom;
int i;
crc = init_crc;
for (i = 0; i < 8; i++) {
if (crc & 0x80)
polynom = (unsigned char) 0x9B;
else
polynom = (unsigned char) 0;
crc = (unsigned char) ((crc & ~0x80) << 1);
if (byte & 0x80)
crc = (unsigned char) (crc | 1);
crc = (unsigned char) (crc ^ polynom);
byte = (unsigned char) (byte << 1);
}
return crc;
}
unsigned char
eb_calc_crc(const unsigned char *buf, int buflen)
{
int i;
unsigned char crc = 0;
for (i = 0 ; i < buflen ; i++, buf++)
crc = eb_calc_crc_byte(*buf, crc);
return crc;
}