BACnet router added.

This commit is contained in:
vasyl-tkhir
2012-09-27 14:36:11 +00:00
parent ad8378ef62
commit 2f73bcae44
23 changed files with 3934 additions and 90 deletions
+209 -57
View File
@@ -63,6 +63,8 @@
#include <sys/select.h>
#include <sys/time.h>
#include "dlmstp_linux.h"
/* Posix serial programming reference:
http://www.easysw.com/~mike/serial/serial.html */
@@ -195,6 +197,87 @@ uint32_t RS485_Get_Baud_Rate(
return baud;
}
/****************************************************************************
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Port_Baud_Rate(
volatile struct mstp_port_struct_t *mstp_port)
{
uint32_t baud = 0;
SHARED_MSTP_DATA * poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
switch (poSharedData->RS485_Baud) {
case B0:
baud = 0;
break;
case B50:
baud = 50;
break;
case B75:
baud = 75;
break;
case B110:
baud = 110;
break;
case B134:
baud = 134;
break;
case B150:
baud = 150;
break;
case B200:
baud = 200;
break;
case B300:
baud = 300;
break;
case B600:
baud = 600;
break;
case B1200:
baud = 1200;
break;
case B1800:
baud = 1800;
break;
case B2400:
baud = 2400;
break;
case B4800:
baud = 4800;
break;
case B9600:
baud = 9600;
break;
case B19200:
baud = 19200;
break;
case B38400:
baud = 38400;
break;
case B57600:
baud = 57600;
break;
case B115200:
baud = 115200;
break;
case B230400:
baud = 230400;
break;
default:
baud = 9600;
break;
}
return baud;
}
/****************************************************************************
* DESCRIPTION: Sets the baud rate for the chip USART
* RETURN: none
@@ -286,35 +369,66 @@ void RS485_Send_Frame(
volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
uint16_t nbytes)
{ /* number of bytes of data (up to 501) */
{ /* number of bytes of data (up to 501) */
uint32_t turnaround_time = Tturnaround * 1000;
uint32_t baud = RS485_Get_Baud_Rate();
uint32_t baud;
ssize_t written = 0;
int greska;
/* sleeping for turnaround time is necessary to give other devices
time to change from sending to receiving state. */
usleep(turnaround_time / baud);
/*
On success, the number of bytes written are returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately. If count is zero and the file descriptor refers to a
regular file, 0 will be returned without causing any other effect. For
a special file, the results are not portable.
*/
written = write(RS485_Handle, buffer, nbytes);
greska = errno;
if (written <= 0) {
printf("write error: %s\n", strerror(greska));
} else {
/* wait until all output has been transmitted. */
tcdrain(RS485_Handle);
}
/* tcdrain(RS485_Handle); */
/* per MSTP spec, sort of */
if (mstp_port) {
mstp_port->SilenceTimerReset();
}
SHARED_MSTP_DATA * poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
baud = RS485_Get_Baud_Rate();
/* sleeping for turnaround time is necessary to give other devices
time to change from sending to receiving state. */
usleep(turnaround_time / baud);
/*
On success, the number of bytes written are returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately. If count is zero and the file descriptor refers to a
regular file, 0 will be returned without causing any other effect. For
a special file, the results are not portable.
*/
written = write(RS485_Handle, buffer, nbytes);
greska = errno;
if (written <= 0) {
printf("write error: %s\n", strerror(greska));
} else {
/* wait until all output has been transmitted. */
tcdrain(RS485_Handle);
}
/* tcdrain(RS485_Handle); */
/* per MSTP spec, sort of */
if (mstp_port) {
mstp_port->SilenceTimerReset((void*)mstp_port);
}
}
else
{
baud = RS485_Get_Port_Baud_Rate(mstp_port);
/* sleeping for turnaround time is necessary to give other devices
time to change from sending to receiving state. */
usleep(turnaround_time / baud);
/*
On success, the number of bytes written are returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately. If count is zero and the file descriptor refers to a
regular file, 0 will be returned without causing any other effect. For
a special file, the results are not portable.
*/
written = write(poSharedData->RS485_Handle, buffer, nbytes);
greska = errno;
if (written <= 0) {
printf("write error: %s\n", strerror(greska));
} else {
/* wait until all output has been transmitted. */
tcdrain(poSharedData->RS485_Handle);
}
/* tcdrain(RS485_Handle); */
/* per MSTP spec, sort of */
if (mstp_port) {
mstp_port->SilenceTimerReset((void*)mstp_port);
}
}
return;
}
@@ -333,37 +447,75 @@ void RS485_Check_UART_Data(
uint8_t buf[2048];
int n;
if (mstp_port->ReceiveError == true) {
/* do nothing but wait for state machine to clear the error */
/* burning time, so wait a longer time */
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
} else if (mstp_port->DataAvailable == false) {
/* wait for state machine to read from the DataRegister */
if (FIFO_Count(&Rx_FIFO) > 0) {
/* data is available */
mstp_port->DataRegister = FIFO_Get(&Rx_FIFO);
mstp_port->DataAvailable = true;
/* FIFO is giving data - don't wait very long */
waiter.tv_sec = 0;
waiter.tv_usec = 10;
} else {
/* FIFO is empty - wait a longer time */
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
}
}
/* grab bytes and stuff them into the FIFO every time */
FD_ZERO(&input);
FD_SET(RS485_Handle, &input);
n = select(RS485_Handle + 1, &input, NULL, NULL, &waiter);
if (n < 0) {
return;
}
if (FD_ISSET(RS485_Handle, &input)) {
n = read(RS485_Handle, buf, sizeof(buf));
FIFO_Add(&Rx_FIFO, &buf[0], n);
}
SHARED_MSTP_DATA * poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
if (mstp_port->ReceiveError == true) {
/* do nothing but wait for state machine to clear the error */
/* burning time, so wait a longer time */
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
} else if (mstp_port->DataAvailable == false) {
/* wait for state machine to read from the DataRegister */
if (FIFO_Count(&Rx_FIFO) > 0) {
/* data is available */
mstp_port->DataRegister = FIFO_Get(&Rx_FIFO);
mstp_port->DataAvailable = true;
/* FIFO is giving data - don't wait very long */
waiter.tv_sec = 0;
waiter.tv_usec = 10;
} else {
/* FIFO is empty - wait a longer time */
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
}
}
/* grab bytes and stuff them into the FIFO every time */
FD_ZERO(&input);
FD_SET(RS485_Handle, &input);
n = select(RS485_Handle + 1, &input, NULL, NULL, &waiter);
if (n < 0) {
return;
}
if (FD_ISSET(RS485_Handle, &input)) {
n = read(RS485_Handle, buf, sizeof(buf));
FIFO_Add(&Rx_FIFO, &buf[0], n);
}
}
else
{
if (mstp_port->ReceiveError == true) {
/* do nothing but wait for state machine to clear the error */
/* burning time, so wait a longer time */
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
} else if (mstp_port->DataAvailable == false) {
/* wait for state machine to read from the DataRegister */
if (FIFO_Count(&poSharedData->Rx_FIFO) > 0) {
/* data is available */
mstp_port->DataRegister = FIFO_Get(&poSharedData->Rx_FIFO);
mstp_port->DataAvailable = true;
/* FIFO is giving data - don't wait very long */
waiter.tv_sec = 0;
waiter.tv_usec = 10;
} else {
/* FIFO is empty - wait a longer time */
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
}
}
/* grab bytes and stuff them into the FIFO every time */
FD_ZERO(&input);
FD_SET(poSharedData->RS485_Handle, &input);
n = select(poSharedData->RS485_Handle + 1, &input, NULL, NULL, &waiter);
if (n < 0) {
return;
}
if (FD_ISSET(poSharedData->RS485_Handle, &input)) {
n = read(poSharedData->RS485_Handle, buf, sizeof(buf));
FIFO_Add(&poSharedData->Rx_FIFO, &buf[0], n);
}
}
}
void RS485_Cleanup(