Corrected EOL line style and line endings on files.

This commit is contained in:
skarg
2009-07-24 16:19:48 +00:00
parent 0e5a1cee0a
commit ece1f05de9
5 changed files with 1447 additions and 1447 deletions
+120 -120
View File
@@ -1,120 +1,120 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2004 Steve Karg Copyright (C) 2004 Steve Karg
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307 Boston, MA 02111-1307
USA. USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef MSTPDEF_H #ifndef MSTPDEF_H
#define MSTPDEF_H #define MSTPDEF_H
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "bacdef.h" #include "bacdef.h"
/* The value 255 is used to denote broadcast when used as a */ /* The value 255 is used to denote broadcast when used as a */
/* destination address but is not allowed as a value for a station. */ /* destination address but is not allowed as a value for a station. */
/* Station addresses for master nodes can be 0-127. */ /* Station addresses for master nodes can be 0-127. */
/* Station addresses for slave nodes can be 127-254. */ /* Station addresses for slave nodes can be 127-254. */
#define MSTP_BROADCAST_ADDRESS 255 #define MSTP_BROADCAST_ADDRESS 255
/* MS/TP Frame Type */ /* MS/TP Frame Type */
/* Frame Types 8 through 127 are reserved by ASHRAE. */ /* Frame Types 8 through 127 are reserved by ASHRAE. */
#define FRAME_TYPE_TOKEN 0 #define FRAME_TYPE_TOKEN 0
#define FRAME_TYPE_POLL_FOR_MASTER 1 #define FRAME_TYPE_POLL_FOR_MASTER 1
#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2 #define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2
#define FRAME_TYPE_TEST_REQUEST 3 #define FRAME_TYPE_TEST_REQUEST 3
#define FRAME_TYPE_TEST_RESPONSE 4 #define FRAME_TYPE_TEST_RESPONSE 4
#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5 #define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5
#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6 #define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6
#define FRAME_TYPE_REPLY_POSTPONED 7 #define FRAME_TYPE_REPLY_POSTPONED 7
/* Frame Types 128 through 255: Proprietary Frames */ /* Frame Types 128 through 255: Proprietary Frames */
/* These frames are available to vendors as proprietary (non-BACnet) frames. */ /* These frames are available to vendors as proprietary (non-BACnet) frames. */
/* The first two octets of the Data field shall specify the unique vendor */ /* The first two octets of the Data field shall specify the unique vendor */
/* identification code, most significant octet first, for the type of */ /* identification code, most significant octet first, for the type of */
/* vendor-proprietary frame to be conveyed. The length of the data portion */ /* vendor-proprietary frame to be conveyed. The length of the data portion */
/* of a Proprietary frame shall be in the range of 2 to 501 octets. */ /* of a Proprietary frame shall be in the range of 2 to 501 octets. */
#define FRAME_TYPE_PROPRIETARY_MIN 128 #define FRAME_TYPE_PROPRIETARY_MIN 128
#define FRAME_TYPE_PROPRIETARY_MAX 255 #define FRAME_TYPE_PROPRIETARY_MAX 255
/* The initial CRC16 checksum value */ /* The initial CRC16 checksum value */
#define CRC16_INITIAL_VALUE (0xFFFF) #define CRC16_INITIAL_VALUE (0xFFFF)
/* receive FSM states */ /* receive FSM states */
typedef enum { typedef enum {
MSTP_RECEIVE_STATE_IDLE = 0, MSTP_RECEIVE_STATE_IDLE = 0,
MSTP_RECEIVE_STATE_PREAMBLE = 1, MSTP_RECEIVE_STATE_PREAMBLE = 1,
MSTP_RECEIVE_STATE_HEADER = 2, MSTP_RECEIVE_STATE_HEADER = 2,
MSTP_RECEIVE_STATE_DATA = 3 MSTP_RECEIVE_STATE_DATA = 3
} MSTP_RECEIVE_STATE; } MSTP_RECEIVE_STATE;
/* master node FSM states */ /* master node FSM states */
typedef enum { typedef enum {
MSTP_MASTER_STATE_INITIALIZE = 0, MSTP_MASTER_STATE_INITIALIZE = 0,
MSTP_MASTER_STATE_IDLE = 1, MSTP_MASTER_STATE_IDLE = 1,
MSTP_MASTER_STATE_USE_TOKEN = 2, MSTP_MASTER_STATE_USE_TOKEN = 2,
MSTP_MASTER_STATE_WAIT_FOR_REPLY = 3, MSTP_MASTER_STATE_WAIT_FOR_REPLY = 3,
MSTP_MASTER_STATE_DONE_WITH_TOKEN = 4, MSTP_MASTER_STATE_DONE_WITH_TOKEN = 4,
MSTP_MASTER_STATE_PASS_TOKEN = 5, MSTP_MASTER_STATE_PASS_TOKEN = 5,
MSTP_MASTER_STATE_NO_TOKEN = 6, MSTP_MASTER_STATE_NO_TOKEN = 6,
MSTP_MASTER_STATE_POLL_FOR_MASTER = 7, MSTP_MASTER_STATE_POLL_FOR_MASTER = 7,
MSTP_MASTER_STATE_ANSWER_DATA_REQUEST = 8 MSTP_MASTER_STATE_ANSWER_DATA_REQUEST = 8
} MSTP_MASTER_STATE; } MSTP_MASTER_STATE;
/* The time without a DataAvailable or ReceiveError event before declaration */ /* The time without a DataAvailable or ReceiveError event before declaration */
/* of loss of token: 500 milliseconds. */ /* of loss of token: 500 milliseconds. */
#define Tno_token 500 #define Tno_token 500
/* The minimum time after the end of the stop bit of the final octet of a */ /* The minimum time after the end of the stop bit of the final octet of a */
/* received frame before a node may enable its EIA-485 driver: 40 bit times. */ /* received frame before a node may enable its EIA-485 driver: 40 bit times. */
/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */ /* At 9600 baud, 40 bit times would be about 4.166 milliseconds */
/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */ /* At 19200 baud, 40 bit times would be about 2.083 milliseconds */
/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */ /* At 38400 baud, 40 bit times would be about 1.041 milliseconds */
/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */ /* At 57600 baud, 40 bit times would be about 0.694 milliseconds */
/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */ /* At 76800 baud, 40 bit times would be about 0.520 milliseconds */
/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */ /* At 115200 baud, 40 bit times would be about 0.347 milliseconds */
/* 40 bits is 4 octets including a start and stop bit with each octet */ /* 40 bits is 4 octets including a start and stop bit with each octet */
#define Tturnaround (40UL) #define Tturnaround (40UL)
/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */ /* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */
#define DEFAULT_MAX_INFO_FRAMES 1 #define DEFAULT_MAX_INFO_FRAMES 1
#define DEFAULT_MAX_MASTER 127 #define DEFAULT_MAX_MASTER 127
#define DEFAULT_MAC_ADDRESS 127 #define DEFAULT_MAC_ADDRESS 127
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+94 -94
View File
@@ -1,94 +1,94 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
/* prescale select bits */ /* prescale select bits */
#if (F_CPU >> 1) < 1000000 #if (F_CPU >> 1) < 1000000
#define ADPS_8BIT (1) #define ADPS_8BIT (1)
#define ADPS_10BIT (3) #define ADPS_10BIT (3)
#elif (F_CPU >> 2) < 1000000 #elif (F_CPU >> 2) < 1000000
#define ADPS_8BIT (2) #define ADPS_8BIT (2)
#define ADPS_10BIT (4) #define ADPS_10BIT (4)
#elif (F_CPU >> 3) < 1000000 #elif (F_CPU >> 3) < 1000000
#define ADPS_8BIT (3) #define ADPS_8BIT (3)
#define ADPS_10BIT (5) #define ADPS_10BIT (5)
#elif (F_CPU >> 4) < 1000000 #elif (F_CPU >> 4) < 1000000
#define ADPS_8BIT (4) #define ADPS_8BIT (4)
#define ADPS_10BIT (6) #define ADPS_10BIT (6)
#elif (F_CPU >> 5) < 1000000 #elif (F_CPU >> 5) < 1000000
#define ADPS_8BIT (5) #define ADPS_8BIT (5)
#define ADPS_10BIT (7) #define ADPS_10BIT (7)
#else #else
#error "ADC: F_CPU too large for accuracy." #error "ADC: F_CPU too large for accuracy."
#endif #endif
/* we could have array of ADC results */ /* we could have array of ADC results */
static volatile uint8_t Sample_Result; static volatile uint8_t Sample_Result;
ISR(ADC_vect) ISR(ADC_vect)
{ {
/* since we configured as ADLAR=1, get value from ADCH */ /* since we configured as ADLAR=1, get value from ADCH */
Sample_Result = ADCH; Sample_Result = ADCH;
} }
uint8_t adc_result( uint8_t adc_result(
uint8_t channel) /* 0..7 = ADC0..ADC7, respectively */ uint8_t channel) /* 0..7 = ADC0..ADC7, respectively */
{ {
return Sample_Result; return Sample_Result;
} }
void adc_init(void) void adc_init(void)
{ {
/* set prescaler */ /* set prescaler */
ADCSRA |= ADPS_8BIT; ADCSRA |= ADPS_8BIT;
/* Initial channel selection */ /* Initial channel selection */
/* ADLAR = Left Adjust Result /* ADLAR = Left Adjust Result
REFSx = hardware setup: cap on AREF REFSx = hardware setup: cap on AREF
*/ */
ADMUX = 7 /* channel */ | (1 << ADLAR) | (0 << REFS1) | (1 << REFS0); ADMUX = 7 /* channel */ | (1 << ADLAR) | (0 << REFS1) | (1 << REFS0);
/* ADEN = Enable /* ADEN = Enable
ADSC = Start conversion ADSC = Start conversion
ADIF = Interrupt Flag ADIF = Interrupt Flag
ADIE = Interrupt Enable ADIE = Interrupt Enable
ADATE = Auto Trigger Enable ADATE = Auto Trigger Enable
*/ */
ADCSRA |= (1 << ADEN) | (1 << ADIE) | (1 << ADIF) | (1 << ADATE); ADCSRA |= (1 << ADEN) | (1 << ADIE) | (1 << ADIF) | (1 << ADATE);
/* trigger selection bits /* trigger selection bits
0 0 0 Free Running mode 0 0 0 Free Running mode
0 0 1 Analog Comparator 0 0 1 Analog Comparator
0 1 0 External Interrupt Request 0 0 1 0 External Interrupt Request 0
0 1 1 Timer/Counter0 Compare Match 0 1 1 Timer/Counter0 Compare Match
1 0 0 Timer/Counter0 Overflow 1 0 0 Timer/Counter0 Overflow
1 0 1 Timer/Counter1 Compare Match B 1 0 1 Timer/Counter1 Compare Match B
1 1 0 Timer/Counter1 Overflow 1 1 0 Timer/Counter1 Overflow
1 1 1 Timer/Counter1 Capture Event 1 1 1 Timer/Counter1 Capture Event
*/ */
ADCSRB |= (0 << ADTS2) | (0 << ADTS1) | (0 << ADTS0); ADCSRB |= (0 << ADTS2) | (0 << ADTS1) | (0 << ADTS0);
/* start the conversions */ /* start the conversions */
ADCSRA |= (1 << ADSC); ADCSRA |= (1 << ADSC);
/* Clear the Power Reduction bit */ /* Clear the Power Reduction bit */
BIT_CLEAR(PRR, PRADC); BIT_CLEAR(PRR, PRADC);
} }
+40 -40
View File
@@ -1,40 +1,40 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef ADC_H #ifndef ADC_H
#define ADC_H #define ADC_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
uint8_t adc_result(uint8_t channel); uint8_t adc_result(uint8_t channel);
void adc_init(void); void adc_init(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+457 -457
View File
@@ -1,457 +1,457 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* Analog Value Objects - customize for your use */ /* Analog Value Objects - customize for your use */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#if defined(__GNUC__) && (__GNUC__ > 4) && (__GNUC_MINOR__ > 2) #if defined(__GNUC__) && (__GNUC__ > 4) && (__GNUC_MINOR__ > 2)
#include <math.h> /* for NAN */ #include <math.h> /* for NAN */
#else #else
#define NAN __builtin_nan("") #define NAN __builtin_nan("")
#endif #endif
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "bacapp.h" #include "bacapp.h"
#include "config.h" /* the custom stuff */ #include "config.h" /* the custom stuff */
#include "wp.h" #include "wp.h"
#ifndef MAX_ANALOG_VALUES #ifndef MAX_ANALOG_VALUES
#define MAX_ANALOG_VALUES 4 #define MAX_ANALOG_VALUES 4
#endif #endif
static float Present_Value[MAX_ANALOG_VALUES]; static float Present_Value[MAX_ANALOG_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Value_Properties_Required[] = { static const int Analog_Value_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS, PROP_STATUS_FLAGS,
PROP_EVENT_STATE, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, PROP_OUT_OF_SERVICE,
PROP_UNITS, PROP_UNITS,
-1 -1
}; };
static const int Analog_Value_Properties_Optional[] = { static const int Analog_Value_Properties_Optional[] = {
PROP_DESCRIPTION, PROP_DESCRIPTION,
PROP_PRIORITY_ARRAY, PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT, PROP_RELINQUISH_DEFAULT,
-1 -1
}; };
static const int Analog_Value_Properties_Proprietary[] = { static const int Analog_Value_Properties_Proprietary[] = {
-1 -1
}; };
void Analog_Value_Property_Lists( void Analog_Value_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Analog_Value_Properties_Required; *pRequired = Analog_Value_Properties_Required;
if (pOptional) if (pOptional)
*pOptional = Analog_Value_Properties_Optional; *pOptional = Analog_Value_Properties_Optional;
if (pProprietary) if (pProprietary)
*pProprietary = Analog_Value_Properties_Proprietary; *pProprietary = Analog_Value_Properties_Proprietary;
return; return;
} }
void Analog_Value_Init( void Analog_Value_Init(
void) void)
{ {
return; return;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(
uint32_t object_instance) uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
return true; return true;
return false; return false;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(
void) void)
{ {
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(
unsigned index) unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(
uint32_t object_instance) uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_VALUES; unsigned index = MAX_ANALOG_VALUES;
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
index = object_instance; index = object_instance;
return index; return index;
} }
float Analog_Value_Present_Value( float Analog_Value_Present_Value(
uint32_t object_instance) uint32_t object_instance)
{ {
float value = NAN; float value = NAN;
unsigned index = 0; unsigned index = 0;
index = Analog_Value_Instance_To_Index(object_instance); index = Analog_Value_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_VALUES) { if (index < MAX_ANALOG_VALUES) {
value = Present_Value[index]; value = Present_Value[index];
} }
return value; return value;
} }
bool Analog_Value_Present_Value_Set( bool Analog_Value_Present_Value_Set(
uint32_t object_instance, uint32_t object_instance,
float value, float value,
uint8_t priority) uint8_t priority)
{ {
unsigned index = 0; unsigned index = 0;
bool status = false; bool status = false;
priority = priority; priority = priority;
index = Analog_Value_Instance_To_Index(object_instance); index = Analog_Value_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_VALUES) { if (index < MAX_ANALOG_VALUES) {
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) && (priority != 6 /* reserved */ ) &&
(value >= 0.0) && (value <= 100.0)) { (value >= 0.0) && (value <= 100.0)) {
Present_Value[index] = value; Present_Value[index] = value;
/* Note: you could set the physical output here if we /* Note: you could set the physical output here if we
are the highest priority. are the highest priority.
However, if Out of Service is TRUE, then don't set the However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing output) */
status = true; status = true;
} }
} }
return status; return status;
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
char *Analog_Value_Name( char *Analog_Value_Name(
uint32_t object_instance) uint32_t object_instance)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
unsigned index = 0; unsigned index = 0;
index = Analog_Value_Instance_To_Index(object_instance); index = Analog_Value_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_VALUES) { if (index < MAX_ANALOG_VALUES) {
sprintf(text_string, "AV-%lu", object_instance); sprintf(text_string, "AV-%lu", object_instance);
return text_string; return text_string;
} }
return NULL; return NULL;
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Encode_Property_APDU( int Analog_Value_Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
float real_value = 1.414F; float real_value = 1.414F;
#if 0 #if 0
unsigned object_index = 0; unsigned object_index = 0;
unsigned i = 0; unsigned i = 0;
bool state = false; bool state = false;
#endif #endif
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
object_instance); object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Analog_Value_Name(object_instance)); Analog_Value_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
real_value = Analog_Value_Present_Value(object_instance); real_value = Analog_Value_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value); apdu_len = encode_application_real(&apdu[0], real_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
#if 0 #if 0
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
state = Analog_Value_Out_Of_Service[object_index]; state = Analog_Value_Out_Of_Service[object_index];
#endif #endif
apdu_len = encode_application_boolean(&apdu[0], false); apdu_len = encode_application_boolean(&apdu[0], false);
break; break;
case PROP_UNITS: case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break; break;
#if 0 #if 0
case PROP_PRIORITY_ARRAY: case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
if (array_index == 0) if (array_index == 0)
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. */ /* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) { else if (array_index == BACNET_ARRAY_ALL) {
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) { for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */ /* FIXME: check if we have room before adding it to APDU */
if (Present_Value[object_index][i] == ANALOG_LEVEL_NULL) if (Present_Value[object_index][i] == ANALOG_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
else { else {
real_value = Present_Value[object_index][i]; real_value = Present_Value[object_index][i];
len = len =
encode_application_real(&apdu[apdu_len], encode_application_real(&apdu[apdu_len],
real_value); real_value);
} }
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
*error_class = ERROR_CLASS_SERVICES; *error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1; apdu_len = -1;
break; break;
} }
} }
} else { } else {
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) { if (array_index <= BACNET_MAX_PRIORITY) {
if (Present_Value[object_index][array_index - 1] == if (Present_Value[object_index][array_index - 1] ==
ANALOG_LEVEL_NULL) ANALOG_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]); apdu_len = encode_application_null(&apdu[0]);
else { else {
real_value = real_value =
Present_Value[object_index][array_index - 1]; Present_Value[object_index][array_index - 1];
apdu_len = apdu_len =
encode_application_real(&apdu[0], real_value); encode_application_real(&apdu[0], real_value);
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX; *error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1; apdu_len = -1;
} }
} }
break; break;
case PROP_RELINQUISH_DEFAULT: case PROP_RELINQUISH_DEFAULT:
real_value = ANALOG_RELINQUISH_DEFAULT; real_value = ANALOG_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value); apdu_len = encode_application_real(&apdu[0], real_value);
break; break;
#endif #endif
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
return apdu_len; return apdu_len;
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
#if 0 #if 0
unsigned int object_index = 0; unsigned int object_index = 0;
unsigned int priority = 0; unsigned int priority = 0;
#endif #endif
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { if (!Analog_Value_Valid_Instance(wp_data->object_instance)) {
*error_class = ERROR_CLASS_OBJECT; *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len =
bacapp_decode_application_data(wp_data->application_data, bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */ /* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) { if (value.tag == BACNET_APPLICATION_TAG_REAL) {
if (Analog_Value_Present_Value_Set( if (Analog_Value_Present_Value_Set(
wp_data->object_instance, wp_data->object_instance,
value.type.Real, value.type.Real,
wp_data->priority)) { wp_data->priority)) {
status = true; status = true;
} else if (wp_data->priority == 6) { } else if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
object. */ object. */
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
#if 0 #if 0
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) { } else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
if (Analog_Value_Present_Value_Set( if (Analog_Value_Present_Value_Set(
wp_data->object_instance, wp_data->object_instance,
NAN, NAN,
wp_data->priority)) { wp_data->priority)) {
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
#endif #endif
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; *error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
#if 0 #if 0
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index = object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance); Analog_Value_Instance_To_Index(wp_data->object_instance);
Analog_Value_Out_Of_Service[object_index] = value.type.Boolean; Analog_Value_Out_Of_Service[object_index] = value.type.Boolean;
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; *error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
#endif #endif
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break; break;
} }
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
void testAnalog_Value( void testAnalog_Value(
Test * pTest) Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = { 0 }; uint8_t apdu[MAX_APDU] = { 0 };
int len = 0; int len = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE; BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE;
uint32_t decoded_instance = 0; uint32_t decoded_instance = 0;
uint32_t instance = 123; uint32_t instance = 123;
BACNET_ERROR_CLASS error_class; BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
len = len =
Analog_Value_Encode_Property_APDU(&apdu[0], instance, Analog_Value_Encode_Property_APDU(&apdu[0], instance,
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = len =
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance); decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE);
ct_test(pTest, decoded_instance == instance); ct_test(pTest, decoded_instance == instance);
return; return;
} }
#ifdef TEST_ANALOG_VALUE #ifdef TEST_ANALOG_VALUE
int main( int main(
void) void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
pTest = ct_create("BACnet Analog Value", NULL); pTest = ct_create("BACnet Analog Value", NULL);
/* individual tests */ /* individual tests */
rc = ct_addTestFunction(pTest, testAnalog_Value); rc = ct_addTestFunction(pTest, testAnalog_Value);
assert(rc); assert(rc);
ct_setStream(pTest, stdout); ct_setStream(pTest, stdout);
ct_run(pTest); ct_run(pTest);
(void) ct_report(pTest); (void) ct_report(pTest);
ct_destroy(pTest); ct_destroy(pTest);
return 0; return 0;
} }
#endif /* TEST_ANALOG_VALUE */ #endif /* TEST_ANALOG_VALUE */
#endif /* TEST */ #endif /* TEST */
File diff suppressed because it is too large Load Diff