Feature/make pretty apps and ports (#80)

* Added pretty-apps and pretty-ports make targets

* pretty-fied apps folder C files

* Pretty-fied ports folder C and H files

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2020-04-30 10:13:11 -05:00
committed by GitHub
parent 0abcbea971
commit fdd49f1791
152 changed files with 9668 additions and 11674 deletions
+39 -49
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Input Objects customize for your use */
@@ -44,8 +44,7 @@ static uint8_t Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(
uint32_t object_instance)
bool Analog_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_INPUTS)
return true;
@@ -54,34 +53,30 @@ bool Analog_Input_Valid_Instance(
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Count(
void)
unsigned Analog_Input_Count(void)
{
return MAX_ANALOG_INPUTS;
}
/* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance(
unsigned index)
uint32_t Analog_Input_Index_To_Instance(unsigned index)
{
return index;
}
char *Analog_Input_Name(
uint32_t object_instance)
char *Analog_Input_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_ANALOG_INPUTS) {
sprintf(text_string, "AI-%lu", (unsigned long) object_instance);
sprintf(text_string, "AI-%lu", (unsigned long)object_instance);
return text_string;
}
return NULL;
}
float Analog_Input_Present_Value(
uint32_t object_instance)
float Analog_Input_Present_Value(uint32_t object_instance)
{
float value = 0.0;
@@ -91,9 +86,7 @@ float Analog_Input_Present_Value(
return value;
}
void Analog_Input_Present_Value_Set(
uint32_t object_instance,
float value)
void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
{
if (object_instance < MAX_ANALOG_INPUTS) {
Present_Value[object_instance] = value;
@@ -102,10 +95,9 @@ void Analog_Input_Present_Value_Set(
/* return apdu length, or -1 on error */
/* assumption - object has already exists */
int Analog_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
uint8_t *apdu = NULL;
@@ -117,16 +109,15 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Input_Name(rpdata->object_instance));
characterstring_init_ansi(
&char_string, Analog_Input_Name(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
@@ -135,9 +126,8 @@ int Analog_Input_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break;
case PROP_PRESENT_VALUE:
apdu_len =
encode_application_real(&apdu[0],
Analog_Input_Present_Value(rpdata->object_instance));
apdu_len = encode_application_real(
&apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
+25 -30
View File
@@ -43,20 +43,17 @@
/* me */
#include "bacnet/apdu.h"
uint16_t apdu_timeout(
void)
uint16_t apdu_timeout(void)
{
return 3000;
}
uint8_t apdu_retries(
void)
uint8_t apdu_retries(void)
{
return 3;
}
bool apdu_service_supported(
BACNET_SERVICES_SUPPORTED service_supported)
bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
{
bool status = false;
@@ -75,15 +72,14 @@ bool apdu_service_supported(
return status;
}
uint16_t apdu_decode_confirmed_service_request(
uint8_t * apdu, /* APDU data */
uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA * service_data,
uint8_t * service_choice,
uint8_t ** service_request,
uint16_t * service_request_len)
BACNET_CONFIRMED_SERVICE_DATA *service_data,
uint8_t *service_choice,
uint8_t **service_request,
uint16_t *service_request_len)
{
uint16_t len = 0; /* counts where we are in PDU */
uint16_t len = 0; /* counts where we are in PDU */
service_data->segmented_message = (apdu[0] & BIT(3)) ? true : false;
service_data->more_follows = (apdu[0] & BIT(2)) ? true : false;
@@ -110,8 +106,7 @@ uint16_t apdu_decode_confirmed_service_request(
When the initiation of communications is disabled,
all APDUs shall be processed and responses returned as
required... */
static bool apdu_confirmed_dcc_disabled(
uint8_t service_choice)
static bool apdu_confirmed_dcc_disabled(uint8_t service_choice)
{
bool status = false;
@@ -136,8 +131,7 @@ static bool apdu_confirmed_dcc_disabled(
DISABLE_INITIATION, the responding BACnet-user shall
discontinue the initiation of messages except for I-Am
requests issued in accordance with the Who-Is service procedure.*/
static bool apdu_unconfirmed_dcc_disabled(
uint8_t service_choice)
static bool apdu_unconfirmed_dcc_disabled(uint8_t service_choice)
{
bool status = false;
@@ -159,36 +153,37 @@ static bool apdu_unconfirmed_dcc_disabled(
return status;
}
void apdu_handler(
BACNET_ADDRESS * src,
uint8_t * apdu, /* APDU data */
void apdu_handler(BACNET_ADDRESS *src,
uint8_t *apdu, /* APDU data */
uint16_t apdu_len)
{
BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 };
uint8_t service_choice = 0;
uint8_t *service_request = NULL;
uint16_t service_request_len = 0;
uint16_t len = 0; /* counts where we are in PDU */
uint16_t len = 0; /* counts where we are in PDU */
if (apdu) {
/* PDU Type */
switch (apdu[0] & 0xF0) {
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */
len = apdu_decode_confirmed_service_request(
&apdu[0], /* APDU data */
apdu_len, &service_data, &service_choice, &service_request,
&service_request_len);
if (apdu_confirmed_dcc_disabled(service_choice)) {
/* When network communications are completely disabled,
only DeviceCommunicationControl and ReinitializeDevice APDUs
shall be processed and no messages shall be initiated. */
only DeviceCommunicationControl and ReinitializeDevice
APDUs shall be processed and no messages shall be
initiated. */
break;
}
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
handler_read_property(service_request, service_request_len,
src, &service_data);
} else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
handler_write_property(service_request,
service_request_len, src, &service_data);
handler_write_property(service_request, service_request_len,
src, &service_data);
} else if (service_choice ==
SERVICE_CONFIRMED_REINITIALIZE_DEVICE) {
handler_reinitialize_device(service_request,
@@ -208,10 +203,10 @@ void apdu_handler(
service_request_len = apdu_len - 2;
if (apdu_unconfirmed_dcc_disabled(service_choice)) {
/* When network communications are disabled,
only DeviceCommunicationControl and ReinitializeDevice APDUs
shall be processed and no messages shall be initiated.
If communications have been initiation disabled, then
WhoIs may be processed. */
only DeviceCommunicationControl and ReinitializeDevice
APDUs shall be processed and no messages shall be
initiated. If communications have been initiation
disabled, then WhoIs may be processed. */
break;
}
if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) {
+49 -60
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Value Objects - customize for your use */
@@ -32,7 +32,7 @@
#include "bacnet/bacdcode.h"
#include "bacnet/bacenum.h"
#include "bacnet/bacapp.h"
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/wp.h"
#include "bacnet/rp.h"
#include "bacnet/basic/object/av.h"
@@ -54,8 +54,7 @@ static uint8_t Present_Value[MAX_ANALOG_VALUES];
/* we need to have our arrays initialized before answering any calls */
static bool Analog_Value_Initialized = false;
void Analog_Value_Init(
void)
void Analog_Value_Init(void)
{
unsigned i;
@@ -74,8 +73,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Value_Valid_Instance(
uint32_t object_instance)
bool Analog_Value_Valid_Instance(uint32_t object_instance)
{
Analog_Value_Init();
if (object_instance < MAX_ANALOG_VALUES)
@@ -86,8 +84,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Value_Count(
void)
unsigned Analog_Value_Count(void)
{
Analog_Value_Init();
return MAX_ANALOG_VALUES;
@@ -96,8 +93,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance(
unsigned index)
uint32_t Analog_Value_Index_To_Instance(unsigned index)
{
Analog_Value_Init();
return index;
@@ -106,8 +102,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index(
uint32_t object_instance)
unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ANALOG_VALUES;
@@ -118,8 +113,7 @@ unsigned Analog_Value_Instance_To_Index(
return index;
}
float Analog_Value_Present_Value(
uint32_t object_instance)
float Analog_Value_Present_Value(uint32_t object_instance)
{
float value = ANALOG_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -135,10 +129,9 @@ float Analog_Value_Present_Value(
}
/* note: the object name must be unique within this device */
char *Analog_Value_Name(
uint32_t object_instance)
char *Analog_Value_Name(uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
static char text_string[32] = ""; /* okay for single thread */
if (object_instance < MAX_ANALOG_VALUES) {
sprintf(text_string, "AV-%lu", object_instance);
@@ -149,14 +142,13 @@ char *Analog_Value_Name(
}
/* return apdu len, or -1 on error */
int Analog_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float real_value = (float) 1.414;
float real_value = (float)1.414;
unsigned object_index = 0;
unsigned i = 0;
bool state = false;
@@ -170,14 +162,13 @@ int Analog_Value_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Value_Name(rpdata->object_instance));
characterstring_init_ansi(
&char_string, Analog_Value_Name(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
@@ -287,10 +278,9 @@ int Analog_Value_Read_Property(
}
/* returns true if successful */
bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
bool status = false; /* return value */
unsigned int object_index = 0;
unsigned int priority = 0;
uint8_t level = ANALOG_LEVEL_NULL;
@@ -304,9 +294,8 @@ bool Analog_Value_Write_Property(
return false;
}
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
len = bacapp_decode_application_data(
wp_data->application_data, wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
/* error while decoding - a value larger than we can handle */
@@ -329,19 +318,19 @@ bool Analog_Value_Write_Property(
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(priority != 6 /* reserved */) &&
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
level = (uint8_t) value.type.Real;
object_index =
Analog_Value_Instance_To_Index
(wp_data->object_instance);
level = (uint8_t)value.type.Real;
object_index = Analog_Value_Instance_To_Index(
wp_data->object_instance);
priority--;
Present_Value[object_index] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set 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;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
+37 -46
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Input Objects customize for your use */
@@ -40,8 +40,7 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
static void Binary_Input_Initialize(
void)
static void Binary_Input_Initialize(void)
{
static bool initialized = false;
unsigned i;
@@ -55,8 +54,7 @@ static void Binary_Input_Initialize(
}
/* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance(
uint32_t object_instance)
bool Binary_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_INPUTS)
return true;
@@ -65,15 +63,13 @@ bool Binary_Input_Valid_Instance(
}
/* we simply have 0-n object instances. */
unsigned Binary_Input_Count(
void)
unsigned Binary_Input_Count(void)
{
return MAX_BINARY_INPUTS;
}
/* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance(
unsigned index)
uint32_t Binary_Input_Index_To_Instance(unsigned index)
{
return index;
}
@@ -81,8 +77,7 @@ uint32_t Binary_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_INPUTS;
@@ -92,8 +87,7 @@ unsigned Binary_Input_Instance_To_Index(
return index;
}
BACNET_BINARY_PV Binary_Input_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0;
@@ -107,10 +101,9 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
return value;
}
char *Binary_Input_Name(
uint32_t object_instance)
char *Binary_Input_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_BINARY_INPUTS) {
sprintf(text_string, "BI-%lu", object_instance);
@@ -122,10 +115,9 @@ char *Binary_Input_Name(
/* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_POLARITY polarity = POLARITY_NORMAL;
@@ -140,15 +132,14 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_BINARY_INPUT, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* note: object name must be unique in our device */
characterstring_init_ansi(&char_string,
Binary_Input_Name(rpdata->object_instance));
characterstring_init_ansi(
&char_string, Binary_Input_Name(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
+46 -59
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Value Objects - customize for your use */
@@ -31,7 +31,7 @@
#include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacenum.h"
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/wp.h"
#include "bacnet/rp.h"
#include "bacnet/basic/object/bv.h"
@@ -40,8 +40,7 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
static void Binary_Value_Initialize(
void)
static void Binary_Value_Initialize(void)
{
static bool initialized = false;
unsigned i;
@@ -55,8 +54,7 @@ static void Binary_Value_Initialize(
}
/* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance(
uint32_t object_instance)
bool Binary_Value_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_VALUES)
return true;
@@ -65,22 +63,19 @@ bool Binary_Value_Valid_Instance(
}
/* we simply have 0-n object instances. */
unsigned Binary_Value_Count(
void)
unsigned Binary_Value_Count(void)
{
return MAX_BINARY_VALUES;
}
/* we simply have 0-n object instances. */
uint32_t Binary_Value_Index_To_Instance(
unsigned index)
uint32_t Binary_Value_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. */
unsigned Binary_Value_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_VALUES;
@@ -90,8 +85,7 @@ unsigned Binary_Value_Instance_To_Index(
return index;
}
BACNET_BINARY_PV Binary_Value_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
@@ -104,10 +98,9 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
}
/* note: the object name must be unique within this device */
char *Binary_Value_Name(
uint32_t object_instance)
char *Binary_Value_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_BINARY_VALUES) {
sprintf(text_string, "BV-%lu", object_instance);
@@ -118,11 +111,10 @@ char *Binary_Value_Name(
}
/* return apdu len, or -1 on error */
int Binary_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
@@ -140,16 +132,15 @@ int Binary_Value_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Value_Name(rpdata->object_instance));
characterstring_init_ansi(
&char_string, Binary_Value_Name(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
@@ -158,8 +149,7 @@ int Binary_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break;
case PROP_PRESENT_VALUE:
present_value =
Binary_Value_Present_Value(rpdata->object_instance);
present_value = Binary_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
@@ -200,10 +190,9 @@ int Binary_Value_Read_Property(
}
/* returns true if successful */
bool Binary_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
bool status = false; /* return value */
unsigned int object_index = 0;
unsigned int priority = 0;
BACNET_BINARY_PV level = BINARY_NULL;
@@ -216,9 +205,8 @@ bool Binary_Value_Write_Property(
return false;
}
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
len = bacapp_decode_application_data(
wp_data->application_data, wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
/* error while decoding - a value larger than we can handle */
@@ -241,13 +229,12 @@ bool Binary_Value_Write_Property(
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(priority != 6 /* reserved */) &&
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = value.type.Enumerated;
object_index =
Binary_Value_Instance_To_Index
(wp_data->object_instance);
object_index = Binary_Value_Instance_To_Index(
wp_data->object_instance);
priority--;
/* NOTE: this Binary value has no priority array */
Present_Value[object_index] = level;
+97 -128
View File
@@ -1,36 +1,36 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <string.h> /* for memmove */
#include <string.h> /* for memmove */
#include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacstr.h"
#include "bacnet/bacenum.h"
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/apdu.h"
#include "bacnet/datalink/dlmstp.h"
#include "rs485.h"
@@ -42,7 +42,7 @@
#include "bacnet/wp.h"
#include "bacnet/dcc.h"
#include "bacnet/version.h"
#include "bacnet/basic/object/device.h" /* me */
#include "bacnet/basic/object/device.h" /* me */
/* note: you really only need to define variables for
properties that are writable or that may change.
@@ -54,8 +54,7 @@ static uint8_t Database_Revision;
BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
static char Reinit_Password[16] = "filister";
bool Device_Reinitialize(
BACNET_REINITIALIZE_DEVICE_DATA * rd_data)
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
{
bool status = false;
@@ -98,16 +97,14 @@ bool Device_Reinitialize(
return status;
}
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(
void)
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(void)
{
return Reinitialize_State;
}
void Device_Init(
object_functions_t * object_table)
void Device_Init(object_functions_t *object_table)
{
(void) object_table;
(void)object_table;
Reinitialize_State = BACNET_REINIT_IDLE;
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
/* FIXME: Get the data from the eeprom */
@@ -118,14 +115,12 @@ void Device_Init(
}
/* methods to manipulate the data */
uint32_t Device_Object_Instance_Number(
void)
uint32_t Device_Object_Instance_Number(void)
{
return Object_Instance_Number;
}
bool Device_Set_Object_Instance_Number(
uint32_t object_id)
bool Device_Set_Object_Instance_Number(uint32_t object_id)
{
bool status = true; /* return value */
@@ -144,66 +139,56 @@ bool Device_Set_Object_Instance_Number(
return status;
}
bool Device_Valid_Object_Instance_Number(
uint32_t object_id)
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
{
/* BACnet allows for a wildcard instance number */
return (Object_Instance_Number == object_id);
}
BACNET_DEVICE_STATUS Device_System_Status(
void)
BACNET_DEVICE_STATUS Device_System_Status(void)
{
return System_Status;
}
int Device_Set_System_Status(
BACNET_DEVICE_STATUS status,
bool local)
int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
{
if (status < MAX_DEVICE_STATUS) {
System_Status = status;
}
}
uint16_t Device_Vendor_Identifier(
void)
uint16_t Device_Vendor_Identifier(void)
{
return BACNET_VENDOR_ID;
}
uint8_t Device_Protocol_Version(
void)
uint8_t Device_Protocol_Version(void)
{
return BACNET_PROTOCOL_VERSION;
}
uint8_t Device_Protocol_Revision(
void)
uint8_t Device_Protocol_Revision(void)
{
return BACNET_PROTOCOL_REVISION;
}
BACNET_SEGMENTATION Device_Segmentation_Supported(
void)
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
{
return SEGMENTATION_NONE;
}
uint32_t Device_Database_Revision(
void)
uint32_t Device_Database_Revision(void)
{
return Database_Revision;
}
/* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */
unsigned Device_Object_List_Count(
void)
unsigned Device_Object_List_Count(void)
{
unsigned count = 1; /* at least 1 for device object */
/* FIXME: add objects as needed */
/* FIXME: add objects as needed */
count += Binary_Value_Count();
count += Analog_Input_Count();
count += Binary_Input_Count();
@@ -215,9 +200,7 @@ unsigned Device_Object_List_Count(
/* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */
bool Device_Object_List_Identifier(
uint32_t array_index,
BACNET_OBJECT_TYPE *object_type,
uint32_t * instance)
uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
{
bool status = false;
uint32_t object_index = 0;
@@ -287,13 +270,12 @@ bool Device_Object_List_Identifier(
}
/* returns true if successful */
int Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata)
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
{
static char string_buffer[28];
static BACNET_CHARACTER_STRING char_string;
int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */
int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */
BACNET_BIT_STRING bit_string;
uint32_t i = 0;
BACNET_OBJECT_TYPE object_type = OBJECT_NONE;
@@ -313,12 +295,11 @@ int Device_Read_Property_Local(
/* FIXME: change the hardcoded names to suit your application */
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance_Number);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_DEVICE, Object_Instance_Number);
break;
case PROP_OBJECT_NAME:
(void) strcpypgm2ram(&string_buffer[0], "PIC18F6720 Device");
(void)strcpypgm2ram(&string_buffer[0], "PIC18F6720 Device");
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
@@ -327,68 +308,64 @@ int Device_Read_Property_Local(
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
break;
case PROP_DESCRIPTION:
(void) strcpypgm2ram(&string_buffer[0], "BACnet Demo");
(void)strcpypgm2ram(&string_buffer[0], "BACnet Demo");
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_SYSTEM_STATUS:
apdu_len =
encode_application_enumerated(&apdu[0],
Device_System_Status());
encode_application_enumerated(&apdu[0], Device_System_Status());
break;
case PROP_VENDOR_NAME:
(void) strcpypgm2ram(&string_buffer[0], BACNET_VENDOR_NAME);
(void)strcpypgm2ram(&string_buffer[0], BACNET_VENDOR_NAME);
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_VENDOR_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0],
Device_Vendor_Identifier());
apdu_len = encode_application_unsigned(
&apdu[0], Device_Vendor_Identifier());
break;
case PROP_MODEL_NAME:
(void) strcpypgm2ram(&string_buffer[0], "GNU Demo");
(void)strcpypgm2ram(&string_buffer[0], "GNU Demo");
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_FIRMWARE_REVISION:
(void) strcpypgm2ram(&string_buffer[0], BACNET_VERSION_TEXT);
(void)strcpypgm2ram(&string_buffer[0], BACNET_VERSION_TEXT);
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_APPLICATION_SOFTWARE_VERSION:
(void) strcpypgm2ram(&string_buffer[0], "1.0");
(void)strcpypgm2ram(&string_buffer[0], "1.0");
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_LOCATION:
(void) strcpypgm2ram(&string_buffer[0], "USA");
(void)strcpypgm2ram(&string_buffer[0], "USA");
characterstring_init_ansi(&char_string, string_buffer);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_PROTOCOL_VERSION:
apdu_len =
encode_application_unsigned(&apdu[0],
Device_Protocol_Version());
apdu_len = encode_application_unsigned(
&apdu[0], Device_Protocol_Version());
break;
case PROP_PROTOCOL_REVISION:
apdu_len =
encode_application_unsigned(&apdu[0],
Device_Protocol_Revision());
apdu_len = encode_application_unsigned(
&apdu[0], Device_Protocol_Revision());
break;
case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */
bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t) i,
apdu_service_supported(i));
bitstring_set_bit(
&bit_string, (uint8_t)i, apdu_service_supported(i));
}
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
@@ -398,7 +375,7 @@ int Device_Read_Property_Local(
bitstring_init(&bit_string);
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
/* initialize all the object types to not-supported */
bitstring_set_bit(&bit_string, (uint8_t) i, false);
bitstring_set_bit(&bit_string, (uint8_t)i, false);
}
/* FIXME: indicate the objects that YOU support */
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
@@ -419,11 +396,10 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) {
if (Device_Object_List_Identifier(i, &object_type,
&instance)) {
len =
encode_application_object_id(&apdu[apdu_len],
object_type, instance);
if (Device_Object_List_Identifier(
i, &object_type, &instance)) {
len = encode_application_object_id(
&apdu[apdu_len], object_type, instance);
apdu_len += len;
/* assume next one is the same size as this one */
/* can we all fit into the APDU? */
@@ -442,11 +418,10 @@ int Device_Read_Property_Local(
}
}
} else {
if (Device_Object_List_Identifier(rpdata->array_index,
&object_type, &instance))
apdu_len =
encode_application_object_id(&apdu[0], object_type,
instance);
if (Device_Object_List_Identifier(
rpdata->array_index, &object_type, &instance))
apdu_len = encode_application_object_id(
&apdu[0], object_type, instance);
else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -458,9 +433,8 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len =
encode_application_enumerated(&apdu[0],
Device_Segmentation_Supported());
apdu_len = encode_application_enumerated(
&apdu[0], Device_Segmentation_Supported());
break;
case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
@@ -472,14 +446,12 @@ int Device_Read_Property_Local(
/* FIXME: encode the list here, if it exists */
break;
case PROP_DATABASE_REVISION:
apdu_len =
encode_application_unsigned(&apdu[0],
Device_Database_Revision());
apdu_len = encode_application_unsigned(
&apdu[0], Device_Database_Revision());
break;
case PROP_MAX_INFO_FRAMES:
apdu_len =
encode_application_unsigned(&apdu[0],
dlmstp_max_info_frames());
encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
break;
case PROP_MAX_MASTER:
apdu_len =
@@ -496,14 +468,14 @@ int Device_Read_Property_Local(
case PROP_UTC_OFFSET:
/* Note: BACnet Time Zone is offset of local time and UTC,
rather than offset of GMT. It is expressed in minutes */
apdu_len = encode_application_signed(&apdu[0], 5 * 60 /* EST */ );
apdu_len = encode_application_signed(&apdu[0], 5 * 60 /* EST */);
break;
case PROP_LOCAL_DATE:
/* FIXME: if you support date */
local_date.year = 2006; /* AD */
local_date.month = 4; /* Jan=1..Dec=12 */
local_date.day = 11; /* 1..31 */
local_date.wday = 0; /* 1=Mon..7=Sun */
local_date.year = 2006; /* AD */
local_date.month = 4; /* Jan=1..Dec=12 */
local_date.day = 11; /* 1..31 */
local_date.wday = 0; /* 1=Mon..7=Sun */
apdu_len = encode_application_date(&apdu[0], &local_date);
break;
case PROP_DAYLIGHT_SAVINGS_STATUS:
@@ -531,8 +503,7 @@ int Device_Read_Property_Local(
return apdu_len;
}
int Device_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = BACNET_STATUS_ERROR;
@@ -572,10 +543,9 @@ int Device_Read_Property(
return apdu_len;
}
bool Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
@@ -585,9 +555,8 @@ bool Device_Write_Property_Local(
return false;
}
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
len = bacapp_decode_application_data(
wp_data->application_data, wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
/* error while decoding - a value larger than we can handle */
@@ -606,8 +575,8 @@ bool Device_Write_Property_Local(
case PROP_OBJECT_IDENTIFIER:
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
(Device_Set_Object_Instance_Number(value.type.
Object_Id.instance))) {
(Device_Set_Object_Instance_Number(
value.type.Object_Id.instance))) {
/* we could send an I-Am broadcast to let the world know */
status = true;
} else {
@@ -660,10 +629,11 @@ bool Device_Write_Property_Local(
if (len <= 20) {
/* FIXME: set the name */
/* Display_Set_Name(
characterstring_value(&value.type.Character_String)); */
/* FIXME: All the object names in a device must be unique.
Disallow setting the Device Object Name to any objects in
the device. */
characterstring_value(&value.type.Character_String));
*/
/* FIXME: All the object names in a device must be
unique. Disallow setting the Device Object Name to
any objects in the device. */
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code =
@@ -729,10 +699,9 @@ bool Device_Write_Property_Local(
return status;
}
bool Device_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* Ever the pessamist! */
bool status = false; /* Ever the pessamist! */
struct object_functions *pObject = NULL;
/* initialize the default return values */
+58 -72
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
@@ -48,16 +48,18 @@ static DLMSTP_PACKET Receive_Buffer;
volatile struct mstp_port_struct_t MSTP_Port;
#pragma udata
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
#define INCREMENT_AND_LIMIT_UINT16(x) \
{ \
if (x < 0xFFFF) \
x++; \
}
void dlmstp_millisecond_timer(
void)
void dlmstp_millisecond_timer(void)
{
INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer);
}
void dlmstp_reinit(
void)
void dlmstp_reinit(void)
{
RS485_Reinit();
dlmstp_set_my_address(DEFAULT_MAC_ADDRESS);
@@ -65,8 +67,7 @@ void dlmstp_reinit(
dlmstp_set_max_master(DEFAULT_MAX_MASTER);
}
void dlmstp_init(
void)
void dlmstp_init(void)
{
uint8_t data;
@@ -79,24 +80,22 @@ void dlmstp_init(
MSTP_Init(&MSTP_Port);
}
void dlmstp_cleanup(
void)
void dlmstp_cleanup(void)
{
/* nothing to do for static buffers */
}
/* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
{ /* number of bytes of data */
int bytes_sent = 0;
unsigned npdu_len = 0;
uint8_t frame_type = 0;
BACNET_ADDRESS src;
unsigned i = 0; /* loop counter */
unsigned i = 0; /* loop counter */
if (MSTP_Port.TxReady == false) {
if (npdu_data->data_expecting_reply)
@@ -115,8 +114,7 @@ int dlmstp_send_pdu(
if ((MAX_HEADER + pdu_len) > MAX_MPDU) {
return -4;
}
bytes_sent =
MSTP_Create_Frame((uint8_t *) & MSTP_Port.TxBuffer[0],
bytes_sent = MSTP_Create_Frame((uint8_t *)&MSTP_Port.TxBuffer[0],
sizeof(MSTP_Port.TxBuffer), MSTP_Port.TxFrameType,
MSTP_Port.TxDestination, MSTP_Port.This_Station, pdu, pdu_len);
MSTP_Port.TxLength = bytes_sent;
@@ -127,8 +125,7 @@ int dlmstp_send_pdu(
return bytes_sent;
}
void dlmstp_task(
void)
void dlmstp_task(void)
{
bool bytes_remaining;
bool received_frame;
@@ -139,8 +136,8 @@ void dlmstp_task(
do {
bytes_remaining = RS485_Check_UART_Data(&MSTP_Port);
MSTP_Receive_Frame_FSM(&MSTP_Port);
received_frame = MSTP_Port.ReceivedValidFrame ||
MSTP_Port.ReceivedInvalidFrame;
received_frame =
MSTP_Port.ReceivedValidFrame || MSTP_Port.ReceivedInvalidFrame;
if (received_frame)
break;
} while (bytes_remaining);
@@ -167,9 +164,7 @@ void dlmstp_task(
return;
}
void dlmstp_fill_bacnet_address(
BACNET_ADDRESS * src,
uint8_t mstp_address)
void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
{
int i = 0;
@@ -193,19 +188,17 @@ void dlmstp_fill_bacnet_address(
}
/* for the MS/TP state machine to use for putting received data */
uint16_t dlmstp_put_receive(
uint8_t src, /* source MS/TP address */
uint8_t * pdu, /* PDU data */
uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
uint8_t *pdu, /* PDU data */
uint16_t pdu_len)
{ /* amount of PDU data */
{ /* amount of PDU data */
/* PDU is already in the Receive_Buffer */
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
Receive_Buffer.pdu_len = pdu_len;
Receive_Buffer.ready = true;
}
void dlmstp_set_my_address(
uint8_t mac_address)
void dlmstp_set_my_address(uint8_t mac_address)
{
/* Master Nodes can only have address 0-127 */
if (mac_address <= 127) {
@@ -222,8 +215,7 @@ void dlmstp_set_my_address(
return;
}
uint8_t dlmstp_my_address(
void)
uint8_t dlmstp_my_address(void)
{
return MSTP_Port.This_Station;
}
@@ -235,8 +227,7 @@ uint8_t dlmstp_my_address(
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(
uint8_t max_info_frames)
void dlmstp_set_max_info_frames(uint8_t max_info_frames)
{
if (max_info_frames >= 1) {
MSTP_Port.Nmax_info_frames = max_info_frames;
@@ -250,8 +241,7 @@ void dlmstp_set_max_info_frames(
return;
}
unsigned dlmstp_max_info_frames(
void)
unsigned dlmstp_max_info_frames(void)
{
return MSTP_Port.Nmax_info_frames;
}
@@ -261,8 +251,7 @@ unsigned dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(
uint8_t max_master)
void dlmstp_set_max_master(uint8_t max_master)
{
if (max_master <= 127) {
if (MSTP_Port.This_Station <= max_master) {
@@ -278,20 +267,18 @@ void dlmstp_set_max_master(
return;
}
uint8_t dlmstp_max_master(
void)
uint8_t dlmstp_max_master(void)
{
return MSTP_Port.Nmax_master;
}
void dlmstp_get_my_address(
BACNET_ADDRESS * my_address)
void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
{
int i = 0; /* counter */
int i = 0; /* counter */
my_address->mac_len = 1;
my_address->mac[0] = MSTP_Port.This_Station;
my_address->net = 0; /* local only, no routing */
my_address->net = 0; /* local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
@@ -300,16 +287,15 @@ void dlmstp_get_my_address(
return;
}
void dlmstp_get_broadcast_address(
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
dest->mac_len = 1;
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* always zero when DNET is broadcast */
dest->len = 0; /* always zero when DNET is broadcast */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
+84 -100
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include "stdint.h"
#include "hardware.h"
#include "rs485.h"
@@ -30,42 +30,32 @@
/* from main.c */
extern volatile uint8_t Milliseconds;
void InterruptHandlerHigh(
void);
void InterruptHandlerLow(
void);
void Interrupt_Timer2(
void);
void Interrupt_Timer3(
void);
void Interrupt_Timer4(
void);
void Interrupt_USART_Rx(
void);
void Interrupt_USART_Tx(
void);
void Interrupt_CCP2(
void);
void INT0_Interrupt(
void);
void InterruptHandlerHigh(void);
void InterruptHandlerLow(void);
void Interrupt_Timer2(void);
void Interrupt_Timer3(void);
void Interrupt_Timer4(void);
void Interrupt_USART_Rx(void);
void Interrupt_USART_Tx(void);
void Interrupt_CCP2(void);
void INT0_Interrupt(void);
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh(
void)
void InterruptVectorHigh(void)
{
/* jump to interrupt routine */
_asm goto InterruptHandlerHigh _endasm}
_asm goto InterruptHandlerHigh _endasm
}
#pragma code
#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow(
void)
void InterruptVectorLow(void)
{
/* jump to interrupt routine */
_asm goto InterruptHandlerLow _endasm}
_asm goto InterruptHandlerLow _endasm
}
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh(
void)
void InterruptHandlerHigh(void)
{
#if 0
/* check for USART Rx int */
@@ -92,11 +82,10 @@ void InterruptHandlerHigh(
}
}
#pragma interruptlow InterruptHandlerLow save = PROD, section(".tmpdata"), TABLAT, TBLPTR, section \
("MATH_DATA")
#pragma interruptlow InterruptHandlerLow save = PROD, section(".tmpdata"), \
TABLAT, TBLPTR, section("MATH_DATA")
void InterruptHandlerLow(
void)
void InterruptHandlerLow(void)
{
/* check for timer2 int */
if ((PIR1bits.TMR2IF) && (PIE1bits.TMR2IE)) {
@@ -133,74 +122,69 @@ void InterruptHandlerLow(
RS485_Interrupt_Rx();
}
/* Unused Interrupts
//check for timer1 int
if ((PIR1bits.TMR1IF) && (PIE1bits.TMR1IE))
{
PIR1bits.TMR1IF = 0;
Interrupt_Timer1();
}
/* Unused Interrupts
//check for timer1 int
if ((PIR1bits.TMR1IF) && (PIE1bits.TMR1IE))
{
PIR1bits.TMR1IF = 0;
Interrupt_Timer1();
}
//check for compare int
if ((PIR1bits.CCP1IF) && (PIE1bits.CCP1IE))
{
PIR1bits.CCP1IF = 0;
Interrupt_CCP1();
}
//check for compare int
if ((PIR1bits.CCP1IF) && (PIE1bits.CCP1IE))
{
PIR1bits.CCP1IF = 0;
Interrupt_CCP1();
}
//check for compare int
if ((PIR3bits.CCP3IF) && (PIE3bits.CCP3IE))
{
PIR3bits.CCP3IF = 0;
Interrupt_CCP3();
}
//check for compare int
if ((PIR3bits.CCP3IF) && (PIE3bits.CCP3IE))
{
PIR3bits.CCP3IF = 0;
Interrupt_CCP3();
}
//check for compare int
if ((PIR3bits.CCP4IF) && (PIE3bits.CCP4IE))
{
PIR3bits.CCP4IF = 0;
//check for compare int
if ((PIR3bits.CCP4IF) && (PIE3bits.CCP4IE))
{
PIR3bits.CCP4IF = 0;
Interrupt_CCP4();
}
Interrupt_CCP4();
}
//check for AD int
if ((PIR1bits.ADIF) && (PIE1bits.ADIE))
{
PIR1bits.ADIF = 0;
Interrupt_ADC();
}
//check for AD int
if ((PIR1bits.ADIF) && (PIE1bits.ADIE))
{
PIR1bits.ADIF = 0;
Interrupt_ADC();
}
//check for MSSP int
if ((PIR1bits.SSPIF) && (PIE1bits.SSPIE))
{
PIR1bits.SSPIF = 0;
Interrupt_SSP();
}
//check for MSSP int
if ((PIR1bits.SSPIF) && (PIE1bits.SSPIE))
{
PIR1bits.SSPIF = 0;
Interrupt_SSP();
}
*/
*/
}
void Interrupt_Timer2(
void)
void Interrupt_Timer2(void)
{
}
void Interrupt_Timer3(
void)
void Interrupt_Timer3(void)
{
}
/* Timer4 is set to go off every 1ms. This is our system tick */
void Interrupt_Timer4(
void)
void Interrupt_Timer4(void)
{
/* Milisecond is our system tick */
if (Milliseconds < 0xFF)
++Milliseconds;
}
void Interrupt_CCP2(
void)
void Interrupt_CCP2(void)
{
}
+30 -36
View File
@@ -1,31 +1,31 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <string.h> /* for memmove */
#include <string.h> /* for memmove */
#include <stdlib.h>
#include <string.h>
#include "stdint.h"
@@ -92,8 +92,7 @@
volatile uint8_t Milliseconds = 0;
volatile uint8_t Zero_Cross_Timeout = 0;
void Reinitialize(
void)
void Reinitialize(void)
{
uint8_t i;
char name = 0;
@@ -101,8 +100,7 @@ void Reinitialize(
_asm reset _endasm return;
}
void Global_Int(
enum INT_STATE state)
void Global_Int(enum INT_STATE state)
{
static uint8_t intstate = 0;
@@ -125,8 +123,7 @@ void Global_Int(
}
}
void Hardware_Initialize(
void)
void Hardware_Initialize(void)
{
TRISA = 0x00;
TRISB = 0x00;
@@ -153,8 +150,7 @@ void Hardware_Initialize(
Global_Int(INT_ENABLED);
}
void Initialize_Variables(
void)
void Initialize_Variables(void)
{
/* Check to see if we need to initialize our eeproms */
ENABLE_TIMER4_INT();
@@ -164,8 +160,7 @@ void Initialize_Variables(
Milliseconds = 0;
}
void MainTasks(
void)
void MainTasks(void)
{
static uint16_t millisecond_counter = 0;
/* Handle our millisecond counters */
@@ -180,8 +175,7 @@ void MainTasks(
}
}
void main(
void)
void main(void)
{
RCONbits.NOT_POR = 1;
RCONbits.NOT_RI = 1;
+163 -143
View File
@@ -150,25 +150,27 @@
#define Tusage_timeout 20
/* we need to be able to increment without rolling over */
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;}
#define INCREMENT_AND_LIMIT_UINT8(x) \
{ \
if (x < 0xFF) \
x++; \
}
bool MSTP_Line_Active(
volatile struct mstp_port_struct_t *mstp_port)
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port)
{
return (mstp_port->EventCount > Nmin_octets);
}
unsigned MSTP_Create_Frame(
uint8_t * buffer, /* where frame is loaded */
unsigned buffer_len, /* amount of space available */
unsigned MSTP_Create_Frame(uint8_t *buffer, /* where frame is loaded */
unsigned buffer_len, /* amount of space available */
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t *data, /* any data to be sent - may be null */
unsigned data_len)
{ /* number of bytes of data (up to 501) */
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
{ /* number of bytes of data (up to 501) */
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
unsigned index = 0; /* used to load the data portion of the frame */
/* not enough to do a header */
@@ -209,47 +211,48 @@ unsigned MSTP_Create_Frame(
return 0;
}
return index; /* returns the frame length */
return index; /* returns the frame length */
}
void MSTP_Create_And_Send_Frame(
volatile struct mstp_port_struct_t *mstp_port, /* port to send from */
volatile struct mstp_port_struct_t *mstp_port, /* port to send from */
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t *data, /* any data to be sent - may be null */
unsigned data_len)
{ /* number of bytes of data (up to 501) */
uint8_t buffer[MAX_MPDU] = { 0 }; /* buffer for sending */
uint16_t len = 0; /* number of bytes to send */
{ /* number of bytes of data (up to 501) */
uint8_t buffer[MAX_MPDU] = { 0 }; /* buffer for sending */
uint16_t len = 0; /* number of bytes to send */
len = (uint16_t) MSTP_Create_Frame(&buffer[0], /* where frame is loaded */
len = (uint16_t)MSTP_Create_Frame(&buffer[0], /* where frame is loaded */
sizeof(buffer), /* amount of space available */
frame_type, /* type of frame to send - see defines */
destination, /* destination address */
frame_type, /* type of frame to send - see defines */
destination, /* destination address */
source, /* source address */
data, /* any data to be sent - may be null */
data_len); /* number of bytes of data (up to 501) */
data, /* any data to be sent - may be null */
data_len); /* number of bytes of data (up to 501) */
RS485_Send_Frame(mstp_port, &buffer[0], len);
/* FIXME: be sure to reset SilenceTimer after each octet is sent! */
}
void MSTP_Receive_Frame_FSM(
volatile struct mstp_port_struct_t *mstp_port)
void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
{
#if PRINT_ENABLED_RECEIVE_DATA
static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE;
#endif
#if PRINT_ENABLED_RECEIVE
fprintf(stderr,
"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\n",
"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u "
"Silence=%u\n",
mstptext_receive_state(mstp_port->receive_state),
mstp_port->DataRegister, mstp_port->HeaderCRC, mstp_port->Index,
mstp_port->EventCount, mstp_port->DataLength, mstp_port->SilenceTimer);
#endif
switch (mstp_port->receive_state) {
/* In the IDLE state, the node waits for the beginning of a frame. */
/* In the IDLE state, the node waits for the beginning of a frame.
*/
case MSTP_RECEIVE_STATE_IDLE:
/* EatAnError */
if (mstp_port->ReceiveError == true) {
@@ -283,7 +286,8 @@ void MSTP_Receive_Frame_FSM(
}
}
break;
/* In the PREAMBLE state, the node waits for the second octet of the preamble. */
/* In the PREAMBLE state, the node waits for the second octet of the
* preamble. */
case MSTP_RECEIVE_STATE_PREAMBLE:
/* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) {
@@ -330,11 +334,13 @@ void MSTP_Receive_Frame_FSM(
}
}
break;
/* In the HEADER state, the node waits for the fixed message header. */
/* In the HEADER state, the node waits for the fixed message header.
*/
case MSTP_RECEIVE_STATE_HEADER:
/* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) {
/* indicate that an error has occurred during the reception of a frame */
/* indicate that an error has occurred during the reception of a
* frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -344,7 +350,8 @@ void MSTP_Receive_Frame_FSM(
mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* indicate that an error has occurred during the reception of a frame */
/* indicate that an error has occurred during the reception of a
* frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -356,9 +363,8 @@ void MSTP_Receive_Frame_FSM(
if (mstp_port->Index == 0) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->HeaderCRC = CRC_Calc_Header(
mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->FrameType = mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 1;
@@ -368,9 +374,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 1) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->HeaderCRC = CRC_Calc_Header(
mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->DestinationAddress = mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 2;
@@ -380,9 +385,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 2) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->HeaderCRC = CRC_Calc_Header(
mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->SourceAddress = mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 3;
@@ -392,9 +396,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 3) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->HeaderCRC = CRC_Calc_Header(
mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->DataLength = mstp_port->DataRegister * 256;
mstp_port->DataAvailable = false;
mstp_port->Index = 4;
@@ -404,9 +407,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 4) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->HeaderCRC = CRC_Calc_Header(
mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->DataLength += mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 5;
@@ -416,21 +418,21 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 5) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->HeaderCRC = CRC_Calc_Header(
mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->DataAvailable = false;
/* don't wait for next state - do it here */
if (mstp_port->HeaderCRC != 0x55) {
/* BadCRC */
/* indicate that an error has occurred during the reception of a frame */
/* indicate that an error has occurred during the
* reception of a frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} else {
if ((mstp_port->DestinationAddress ==
mstp_port->This_Station)
|| (mstp_port->DestinationAddress ==
mstp_port->This_Station) ||
(mstp_port->DestinationAddress ==
MSTP_BROADCAST_ADDRESS)) {
/* FrameTooLong */
if (mstp_port->DataLength > MAX_MPDU) {
@@ -443,7 +445,8 @@ void MSTP_Receive_Frame_FSM(
}
/* NoData */
else if (mstp_port->DataLength == 0) {
/* indicate that a frame with no data has been received */
/* indicate that a frame with no data has been
* received */
mstp_port->ReceivedValidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state =
@@ -465,7 +468,6 @@ void MSTP_Receive_Frame_FSM(
}
}
}
/* not per MS/TP standard, but it is a case not covered */
else {
@@ -480,11 +482,13 @@ void MSTP_Receive_Frame_FSM(
}
}
break;
/* In the DATA state, the node waits for the data portion of a frame. */
/* In the DATA state, the node waits for the data portion of a
* frame. */
case MSTP_RECEIVE_STATE_DATA:
/* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) {
/* indicate that an error has occurred during the reception of a frame */
/* indicate that an error has occurred during the reception of a
* frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -493,7 +497,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->ReceiveError == true) {
mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0;
/* indicate that an error has occurred during the reception of a frame */
/* indicate that an error has occurred during the reception of a
* frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -503,9 +508,8 @@ void MSTP_Receive_Frame_FSM(
#endif
/* DataOctet */
if (mstp_port->Index < mstp_port->DataLength) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->DataCRC = CRC_Calc_Data(
mstp_port->DataRegister, mstp_port->DataCRC);
mstp_port->InputBuffer[mstp_port->Index] =
mstp_port->DataRegister;
mstp_port->Index++;
@@ -513,17 +517,15 @@ void MSTP_Receive_Frame_FSM(
}
/* CRC1 */
else if (mstp_port->Index == mstp_port->DataLength) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->DataCRC = CRC_Calc_Data(
mstp_port->DataRegister, mstp_port->DataCRC);
mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
}
/* CRC2 */
else if (mstp_port->Index == (mstp_port->DataLength + 1)) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->DataCRC = CRC_Calc_Data(
mstp_port->DataRegister, mstp_port->DataCRC);
/* STATE DATA CRC - no need for new state */
/* indicate the complete reception of a valid frame */
if (mstp_port->DataCRC == 0xF0B8)
@@ -553,11 +555,10 @@ void MSTP_Receive_Frame_FSM(
return;
}
static bool mstp_compare_data_expecting_reply(
uint8_t * request_pdu,
static bool mstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint16_t request_pdu_len,
uint8_t src_address,
uint8_t * reply_pdu,
uint8_t *reply_pdu,
uint16_t reply_pdu_len,
uint8_t dest_address)
{
@@ -578,9 +579,8 @@ static bool mstp_compare_data_expecting_reply(
/* decode the request data */
request.address.mac[0] = src_address;
request.address.mac_len = 1;
offset =
npdu_decode(&request_pdu[0], NULL, &request.address,
&request.npdu_data);
offset = npdu_decode(
&request_pdu[0], NULL, &request.address, &request.npdu_data);
if (request.npdu_data.network_layer_message) {
return false;
}
@@ -597,8 +597,7 @@ static bool mstp_compare_data_expecting_reply(
/* decode the reply data */
reply.address.mac[0] = dest_address;
reply.address.mac_len = 1;
offset =
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) {
return false;
}
@@ -639,7 +638,8 @@ static bool mstp_compare_data_expecting_reply(
return false;
}
}
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) {
if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false;
}
#if 0
@@ -657,8 +657,7 @@ static bool mstp_compare_data_expecting_reply(
}
/* returns true if we need to transition immediately */
bool MSTP_Master_Node_FSM(
volatile struct mstp_port_struct_t * mstp_port)
bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
{
int mtu_len = 0;
int frame_type = 0;
@@ -684,11 +683,12 @@ bool MSTP_Master_Node_FSM(
if (mstp_port->master_state != master_state) {
master_state = mstp_port->master_state;
fprintf(stderr,
"MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u %s\n",
mstp_port->This_Station, next_this_station,
mstp_port->Next_Station, next_next_station,
mstp_port->Poll_Station, next_poll_station, mstp_port->EventCount,
mstp_port->TokenCount, mstp_port->SilenceTimer,
"MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u "
"%s\n",
mstp_port->This_Station, next_this_station, mstp_port->Next_Station,
next_next_station, mstp_port->Poll_Station, next_poll_station,
mstp_port->EventCount, mstp_port->TokenCount,
mstp_port->SilenceTimer,
mstptext_master_state(mstp_port->master_state));
}
#endif
@@ -711,7 +711,7 @@ bool MSTP_Master_Node_FSM(
/* LostToken */
if (mstp_port->SilenceTimer >= Tno_token) {
/* assume that the token has been lost */
mstp_port->EventCount = 0; /* Addendum 135-2004d-8 */
mstp_port->EventCount = 0; /* Addendum 135-2004d-8 */
mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN;
/* set the receive frame flags to false in case we received
some bytes and had a timeout for some reason */
@@ -727,16 +727,17 @@ bool MSTP_Master_Node_FSM(
} else if (mstp_port->ReceivedValidFrame == true) {
#if PRINT_ENABLED_MASTER
fprintf(stderr,
"MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u ST=%u Type=%s\n",
"MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u "
"FC=%u ST=%u Type=%s\n",
mstp_port->SourceAddress, mstp_port->DestinationAddress,
mstp_port->DataLength, mstp_port->FrameCount,
mstp_port->SilenceTimer,
mstptext_frame_type(mstp_port->FrameType));
#endif
/* destined for me! */
if ((mstp_port->DestinationAddress == mstp_port->This_Station)
|| (mstp_port->DestinationAddress ==
MSTP_BROADCAST_ADDRESS)) {
if ((mstp_port->DestinationAddress ==
mstp_port->This_Station) ||
(mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS)) {
switch (mstp_port->FrameType) {
/* ReceivedToken */
case FRAME_TYPE_TOKEN:
@@ -763,16 +764,18 @@ bool MSTP_Master_Node_FSM(
}
break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* indicate successful reception to the higher layers */
/* indicate successful reception to the higher
* layers */
dlmstp_put_receive(mstp_port->SourceAddress,
(uint8_t *) & mstp_port->InputBuffer[0],
(uint8_t *)&mstp_port->InputBuffer[0],
mstp_port->DataLength);
break;
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
/*mstp_port->ReplyPostponedTimer = 0; */
/* indicate successful reception to the higher layers */
/* indicate successful reception to the higher
* layers */
dlmstp_put_receive(mstp_port->SourceAddress,
(uint8_t *) & mstp_port->InputBuffer[0],
(uint8_t *)&mstp_port->InputBuffer[0],
mstp_port->DataLength);
/* broadcast DER just remains IDLE */
if (mstp_port->DestinationAddress !=
@@ -786,7 +789,7 @@ bool MSTP_Master_Node_FSM(
FRAME_TYPE_TEST_RESPONSE,
mstp_port->SourceAddress,
mstp_port->This_Station,
(uint8_t *) & mstp_port->InputBuffer[0],
(uint8_t *)&mstp_port->InputBuffer[0],
mstp_port->DataLength);
break;
case FRAME_TYPE_TEST_RESPONSE:
@@ -808,8 +811,8 @@ bool MSTP_Master_Node_FSM(
transition_now = true;
} else {
uint8_t destination = mstp_port->TxBuffer[3];
RS485_Send_Frame(mstp_port,
(uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength);
RS485_Send_Frame(mstp_port, (uint8_t *)&mstp_port->TxBuffer[0],
mstp_port->TxLength);
mstp_port->FrameCount++;
switch (mstp_port->TxFrameType) {
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
@@ -845,8 +848,10 @@ bool MSTP_Master_Node_FSM(
mstp_port->FrameCount = mstp_port->Nmax_info_frames;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
/* Any retry of the data frame shall await the next entry */
/* to the USE_TOKEN state. (Because of the length of the timeout, */
/* this transition will cause the token to be passed regardless */
/* to the USE_TOKEN state. (Because of the length of the
* timeout, */
/* this transition will cause the token to be passed regardless
*/
/* of the initial value of FrameCount.) */
transition_now = true;
} else {
@@ -854,8 +859,7 @@ bool MSTP_Master_Node_FSM(
/* InvalidFrame */
/* error in frame reception */
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state =
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
transition_now = true;
} else if (mstp_port->ReceivedValidFrame == true) {
if (mstp_port->DestinationAddress ==
@@ -872,10 +876,14 @@ bool MSTP_Master_Node_FSM(
break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* ReceivedReply */
/* or a proprietary type that indicates a reply */
/* indicate successful reception to the higher layers */
dlmstp_put_receive(mstp_port->SourceAddress, /* source MS/TP address */
(uint8_t *) & mstp_port->InputBuffer[0],
/* or a proprietary type that indicates a reply
*/
/* indicate successful reception to the higher
* layers */
dlmstp_put_receive(
mstp_port->SourceAddress, /* source MS/TP
address */
(uint8_t *)&mstp_port->InputBuffer[0],
mstp_port->DataLength);
mstp_port->master_state =
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
@@ -890,7 +898,7 @@ bool MSTP_Master_Node_FSM(
} else {
/* ReceivedUnexpectedFrame */
/* an unexpected frame was received */
/* This may indicate the presence of multiple tokens. */
/* This may indicate the presence of multiple tokens. */
/* Synchronize with the network. */
/* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
@@ -927,7 +935,8 @@ bool MSTP_Master_Node_FSM(
(mstp_port->Next_Station != next_this_station)) {
/* SoleMaster */
/* there are no other known master nodes to */
/* which the token may be sent (true master-slave operation). */
/* which the token may be sent (true master-slave
* operation). */
mstp_port->FrameCount = 0;
mstp_port->TokenCount++;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
@@ -935,9 +944,12 @@ bool MSTP_Master_Node_FSM(
} else {
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */
/* if there are no addresses between TS and NS, since there is no */
/* address at which a new master node may be found in that case. */
/* The comparison of NS and TS+1 eliminates the Poll For
* Master */
/* if there are no addresses between TS and NS, since there
* is no */
/* address at which a new master node may be found in that
* case. */
mstp_port->TokenCount++;
/* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN,
@@ -957,11 +969,12 @@ bool MSTP_Master_Node_FSM(
/* no known successor node */
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
mstp_port->TokenCount =
1; /* changed in Errata SSPC-135-2004 */
/* mstp_port->EventCount = 0; removed in Addendum
* 135-2004d-8 */
/* find a new successor to TS */
mstp_port->master_state =
MSTP_MASTER_STATE_POLL_FOR_MASTER;
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} else {
/* ResetMaintenancePFM */
mstp_port->Poll_Station = mstp_port->This_Station;
@@ -970,7 +983,8 @@ bool MSTP_Master_Node_FSM(
mstp_port->Next_Station, mstp_port->This_Station, NULL,
0);
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
mstp_port->TokenCount =
1; /* changed in Errata SSPC-135-2004 */
mstp_port->EventCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
}
@@ -990,7 +1004,8 @@ bool MSTP_Master_Node_FSM(
if (mstp_port->SilenceTimer < Tusage_timeout) {
if (mstp_port->EventCount > Nmin_octets) {
/* SawTokenUser */
/* Assume that a frame has been sent by the new token user. */
/* Assume that a frame has been sent by the new token user.
*/
/* Enter the IDLE state to process the frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
transition_now = true;
@@ -1019,16 +1034,18 @@ bool MSTP_Master_Node_FSM(
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
/* mstp_port->EventCount = 0; removed in Addendum
* 135-2004d-8 */
/* find a new successor to TS */
mstp_port->master_state =
MSTP_MASTER_STATE_POLL_FOR_MASTER;
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
}
}
break;
/* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater */
/* than Tno_token, indicating that there has been no network activity */
/* for that period of time. The timeout is continued to determine */
/* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes
* greater */
/* than Tno_token, indicating that there has been no network
* activity */
/* for that period of time. The timeout is continued to determine */
/* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN:
my_timeout = Tno_token + (Tslot * mstp_port->This_Station);
@@ -1036,7 +1053,8 @@ bool MSTP_Master_Node_FSM(
if (mstp_port->EventCount > Nmin_octets) {
/* SawFrame */
/* Some other node exists at a lower address. */
/* Enter the IDLE state to receive and process the incoming frame. */
/* Enter the IDLE state to receive and process the incoming
* frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
transition_now = true;
}
@@ -1056,10 +1074,11 @@ bool MSTP_Master_Node_FSM(
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */
mstp_port->master_state =
MSTP_MASTER_STATE_POLL_FOR_MASTER;
/* mstp_port->EventCount = 0; removed Addendum 135-2004d-8
*/
/* enter the POLL_FOR_MASTER state to find a new successor
* to TS. */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
}
}
break;
@@ -1068,8 +1087,9 @@ bool MSTP_Master_Node_FSM(
/* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (mstp_port->ReceivedValidFrame == true) {
if ((mstp_port->DestinationAddress == mstp_port->This_Station)
&& (mstp_port->FrameType ==
if ((mstp_port->DestinationAddress ==
mstp_port->This_Station) &&
(mstp_port->FrameType ==
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */
mstp_port->SoleMaster = false;
@@ -1128,7 +1148,8 @@ bool MSTP_Master_Node_FSM(
/* Re-enter the current state. */
} else {
/* DeclareSoleMaster */
/* to indicate that this station is the only master */
/* to indicate that this station is the only master
*/
mstp_port->SoleMaster = true;
mstp_port->FrameCount = 0;
mstp_port->master_state =
@@ -1148,11 +1169,10 @@ bool MSTP_Master_Node_FSM(
/* Compare the APDU type received and
see if the message is that same APDU type
along with the matching src/dest and invoke ID */
matched =
mstp_compare_data_expecting_reply(&mstp_port->InputBuffer
[0], mstp_port->DataLength, mstp_port->SourceAddress,
&mstp_port->TxBuffer[8], mstp_port->TxLength,
mstp_port->TxDestination);
matched = mstp_compare_data_expecting_reply(
&mstp_port->InputBuffer[0], mstp_port->DataLength,
mstp_port->SourceAddress, &mstp_port->TxBuffer[8],
mstp_port->TxLength, mstp_port->TxDestination);
}
if (matched && mstp_port->TxReady) {
/* Reply */
@@ -1160,10 +1180,11 @@ bool MSTP_Master_Node_FSM(
/* within Treply_delay after the reception of the */
/* final octet of the requesting frame */
/* (the mechanism used to determine this is a local matter), */
/* then call MSTP_Create_And_Send_Frame to transmit the reply frame */
/* then call MSTP_Create_And_Send_Frame to transmit the reply
* frame */
/* and enter the IDLE state to wait for the next frame. */
RS485_Send_Frame(mstp_port,
(uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength);
RS485_Send_Frame(mstp_port, (uint8_t *)&mstp_port->TxBuffer[0],
mstp_port->TxLength);
mstp_port->TxReady = false;
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} else if (mstp_port->SilenceTimer > Treply_delay) {
@@ -1193,10 +1214,9 @@ bool MSTP_Master_Node_FSM(
/* note: This_Station should be set with the MAC address */
/* note: Nmax_info_frames should be set */
/* note: Nmax_master should be set */
void MSTP_Init(
volatile struct mstp_port_struct_t *mstp_port)
void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
{
int i; /*loop counter */
int i; /*loop counter */
if (mstp_port) {
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -1223,7 +1243,7 @@ void MSTP_Init(
mstp_port->ReceivedValidFrame = false;
mstp_port->RetryCount = 0;
mstp_port->SilenceTimer = 0;
/* mstp_port->ReplyPostponedTimer = 0; */
/* mstp_port->ReplyPostponedTimer = 0; */
mstp_port->SoleMaster = false;
mstp_port->SourceAddress = 0;
mstp_port->TokenCount = 0;
@@ -1233,7 +1253,8 @@ void MSTP_Init(
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
#endif
/* An array of octets, used to store PDU octets prior to being transmitted. */
/* An array of octets, used to store PDU octets prior to being
* transmitted. */
/* This array is only used for APDU messages */
for (i = 0; i < sizeof(mstp_port->TxBuffer); i++) {
mstp_port->TxBuffer[i] = 0;
@@ -1241,6 +1262,5 @@ void MSTP_Init(
mstp_port->TxLength = 0;
mstp_port->TxReady = false;
mstp_port->TxFrameType = 0;
}
}
+82 -91
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* The module handles sending data out the RS-485 port */
/* and handles receiving data from the RS-485 port. */
@@ -52,17 +52,17 @@ volatile uint8_t RS485_Tx_Buffer[128];
#pragma udata
/****************************************************************************
* DESCRIPTION: Transmits a frame using the UART
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
* DESCRIPTION: Transmits a frame using the UART
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
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) */
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) */
uint16_t i = 0; /* loop counter */
{ /* number of bytes of data (up to 501) */
uint16_t i = 0; /* loop counter */
uint8_t turnaround_time;
if (!buffer)
@@ -102,13 +102,12 @@ void RS485_Send_Frame(
}
/****************************************************************************
* DESCRIPTION: Checks for data on the receive UART, and handles errors
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Check_UART_Data(
volatile struct mstp_port_struct_t * mstp_port)
* DESCRIPTION: Checks for data on the receive UART, and handles errors
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
{
/* check for data */
if (!FIFO_Empty(&FIFO_Rx)) {
@@ -128,8 +127,7 @@ bool RS485_Check_UART_Data(
NOTES: none
*************************************************************************** */
void RS485_Interrupt_Rx(
void)
void RS485_Interrupt_Rx(void)
{
uint8_t data_byte;
@@ -154,14 +152,14 @@ void RS485_Interrupt_Rx(
NOTES: none
*************************************************************************** */
void RS485_Interrupt_Tx(
void)
void RS485_Interrupt_Tx(void)
{
if (!FIFO_Empty(&FIFO_Tx)) {
TXREG2 = FIFO_Get(&FIFO_Tx);
} else {
/* wait for the USART to be empty */
while (!TXSTA2bits.TRMT);
while (!TXSTA2bits.TRMT)
;
/* disable this interrupt */
PIE3bits.TX2IE = 0;
/* enable the receiver */
@@ -174,25 +172,23 @@ void RS485_Interrupt_Tx(
}
/****************************************************************************
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Baud_Rate(
void)
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Baud_Rate(void)
{
return RS485_Baud_Rate;
}
/****************************************************************************
* DESCRIPTION: Sets the baud rate for the chip USART
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Set_Baud_Rate(
uint32_t baud)
* DESCRIPTION: Sets the baud rate for the chip USART
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Set_Baud_Rate(uint32_t baud)
{
bool valid = true;
@@ -223,16 +219,14 @@ bool RS485_Set_Baud_Rate(
}
/****************************************************************************
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode.
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Initialize_Port(
void)
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode.
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Initialize_Port(void)
{
/* Reset USART registers to POR state */
TXSTA2 = 0;
RCSTA2 = 0;
@@ -304,39 +298,36 @@ void RS485_Initialize_Port(
}
/****************************************************************************
* DESCRIPTION: Disables the RS485 hardware
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Disable_Port(
void)
* DESCRIPTION: Disables the RS485 hardware
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Disable_Port(void)
{
RCSTA2 &= 0x4F; /* Disable the receiver */
TXSTA2bits.TXEN = 0; /* and transmitter */
PIE3 &= 0xCF; /* Disable both interrupts */
RCSTA2 &= 0x4F; /* Disable the receiver */
TXSTA2bits.TXEN = 0; /* and transmitter */
PIE3 &= 0xCF; /* Disable both interrupts */
}
/****************************************************************************
* DESCRIPTION: Reinitializes the port
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Reinit(
void)
* DESCRIPTION: Reinitializes the port
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Reinit(void)
{
RS485_Set_Baud_Rate(38400);
}
/****************************************************************************
* DESCRIPTION: Initializes the data and the port
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Initialize(
void)
* DESCRIPTION: Initializes the data and the port
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Initialize(void)
{
/* Init the Rs485 buffers */
FIFO_Init(&FIFO_Rx, RS485_Rx_Buffer, sizeof(RS485_Rx_Buffer));