From e0cf05f74aebbc16cfb864c173845f10a5e805a1 Mon Sep 17 00:00:00 2001 From: petermcs Date: Sat, 14 Jan 2012 12:28:44 +0000 Subject: [PATCH] Added in 76800 baud rate as it works on Win 7 with the B&B Electronics USOPTL4 USB adaptor that I have, YMMV. Added gettimeofday() function to allow me build with VS2008 C++ Express Edition --- bacnet-stack/demo/mstpcap/main.c | 73 ++++++++++++++++++++++++++++++++ bacnet-stack/ports/win32/rs485.c | 23 ++++++++++ 2 files changed, 96 insertions(+) diff --git a/bacnet-stack/demo/mstpcap/main.c b/bacnet-stack/demo/mstpcap/main.c index d2e645f5..abb16178 100644 --- a/bacnet-stack/demo/mstpcap/main.c +++ b/bacnet-stack/demo/mstpcap/main.c @@ -507,6 +507,79 @@ static void write_global_header( } } +#if defined(_MSC_VER) + +/* + * Missing gettimeofday function for compiling with MS Visual Studio + * Visual C++ Express Edition. + * Courtesy of the Unix to Windows Porting Dictionary for HPC + * at http://suacommunity.com/dictionary/gettimeofday-entry.php + */ + +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +struct timezone +{ + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +// Definition of a gettimeofday function + +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ +// Define a structure to receive the current Windows filetime + FILETIME ft; + +// Initialize the present time to 0 and the timezone to UTC + unsigned __int64 tmpres = 0; + static int tzflag = 0; + + if (NULL != tv) + { + GetSystemTimeAsFileTime(&ft); + +// The GetSystemTimeAsFileTime returns the number of 100 nanosecond +// intervals since Jan 1, 1601 in a structure. Copy the high bits to +// the 64 bit tmpres, shift it left by 32 then or in the low 32 bits. + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + +// Convert to microseconds by dividing by 10 + tmpres /= 10; + +// The Unix epoch starts on Jan 1 1970. Need to subtract the difference +// in seconds from Jan 1 1601. + tmpres -= DELTA_EPOCH_IN_MICROSECS; + +// Finally change microseconds to seconds and place in the seconds value. +// The modulus picks up the microseconds. + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (NULL != tz) + { + if (!tzflag) + { + _tzset(); + tzflag++; + } + +// Adjust for the timezone west of Greenwich + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} +#endif + static void write_received_packet( volatile struct mstp_port_struct_t *mstp_port) { diff --git a/bacnet-stack/ports/win32/rs485.c b/bacnet-stack/ports/win32/rs485.c index cb5e674f..4b4babcf 100644 --- a/bacnet-stack/ports/win32/rs485.c +++ b/bacnet-stack/ports/win32/rs485.c @@ -303,6 +303,14 @@ uint32_t RS485_Get_Baud_Rate( return 128000; case CBR_256000: return 256000; + case 76800: + /* See comments in RS485_Set_Baud_Rate() below + * also look at definition of CBR_xx in winbase.h + * some serial drivers will only support the defined + * baud rates but others will try and configure the + * requested baud rate (or as close as they can get) + */ + return 76800; case CBR_9600: default: return 9600; @@ -366,6 +374,21 @@ bool RS485_Set_Baud_Rate( case 256000: RS485_Baud = CBR_256000; break; + case 76800: + /* I'm using the B&B Electronics USOPTL4 USB RS485 adapter + * on Win 7 and building with VS2008 Express Edition and it + * seems to work for the most part if I use the following. + * I get the occasional data errors especially if the devices + * are transmitting with 1 stop bit (some devices receive with + * 1 stop bit but effectivly end up transmitting with 2 stop + * bits, usually because of synchroisation issues in some UARTs + * which mean that if you wait until the serialiser has finished + * with the current character and then load the TX buffer it has + * to wait until the next bit boundary to start transmitting. + * PMcS + */ + RS485_Baud = 76800; + break; default: valid = false; break;