Initial commit on github.
This commit is contained in:
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* 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[SERIAL_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[SERIAL_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 (dd >= 0x00 && dd <= 0x06) {
|
||||
eb_bcd_to_int(day, &dd);
|
||||
sprintf(tgt, "%s", days[day]);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
eb_dat_to_str(unsigned char dd, unsigned char mm, unsigned char yy, char *tgt)
|
||||
{
|
||||
if (dd >= 0x00 && dd <= 0x1F &&
|
||||
mm >= 0x00 && mm <= 0x0C &&
|
||||
yy >= 0x00 && yy <= 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 >= 0x00 && hh <= 0x17 &&
|
||||
mm >= 0x00 && mm <= 0x3B &&
|
||||
ss >= 0x00 && ss <= 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user