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:
+61
-59
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 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) 2014 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 <stdbool.h>
|
||||
#include <asf.h>
|
||||
@@ -34,10 +34,10 @@ static uint16_t ADC_Channel_Value[ADC_CHANNELS_MAX];
|
||||
static uint8_t ADC_Current_Channel;
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: set the active channel in the ADC
|
||||
* RETURN: nothing
|
||||
* NOTES: called from ISR, so handle as non-blocking
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: set the active channel in the ADC
|
||||
* RETURN: nothing
|
||||
* NOTES: called from ISR, so handle as non-blocking
|
||||
**************************************************************************/
|
||||
static void adc_set_channel(unsigned channel)
|
||||
{
|
||||
struct adc_channel_config adc_ch_conf;
|
||||
@@ -84,10 +84,10 @@ static void adc_set_channel(unsigned channel)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: run the active channels through the ADC
|
||||
* RETURN: nothing
|
||||
* NOTES: called from ISR, so handle as non-blocking
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: run the active channels through the ADC
|
||||
* RETURN: nothing
|
||||
* NOTES: called from ISR, so handle as non-blocking
|
||||
**************************************************************************/
|
||||
static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t raw_value)
|
||||
{
|
||||
unsigned channel;
|
||||
@@ -104,27 +104,28 @@ static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t raw_value)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: initialize Analog to Digital Converter (ADC)
|
||||
* RETURN: nothing
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: initialize Analog to Digital Converter (ADC)
|
||||
* RETURN: nothing
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
void adc_init(void)
|
||||
{
|
||||
struct adc_config adc_conf;
|
||||
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 7),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 0),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 2),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 3),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 3),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 4),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 5),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 6),IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 7), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 0), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 2), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 3), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 3), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 4), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 5), IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 6), IOPORT_DIR_INPUT);
|
||||
/* Clear the ADC configuration structs */
|
||||
adc_read_configuration(&ADCA, &adc_conf);
|
||||
adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_AREFA);
|
||||
adc_set_conversion_parameters(
|
||||
&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_AREFA);
|
||||
adc_set_clock_rate(&adc_conf, 200000UL);
|
||||
adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
|
||||
adc_write_configuration(&ADCA, &adc_conf);
|
||||
@@ -135,16 +136,17 @@ void adc_init(void)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Get a result from the ADC 10-bit value
|
||||
* RETURN: 12-bit ADC value
|
||||
* NOTES: channel 0..9 are supported
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: Get a result from the ADC 10-bit value
|
||||
* RETURN: 12-bit ADC value
|
||||
* NOTES: channel 0..9 are supported
|
||||
**************************************************************************/
|
||||
uint16_t adc_result_12bit(uint8_t channel)
|
||||
{
|
||||
uint16_t value = 0;
|
||||
|
||||
if (channel < ADC_CHANNELS_MAX) {
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
||||
{
|
||||
value = ADC_Channel_Value[channel];
|
||||
}
|
||||
}
|
||||
@@ -153,10 +155,10 @@ uint16_t adc_result_12bit(uint8_t channel)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Get a result from the ADC 10-bit value
|
||||
* RETURN: 10-bit ADC value
|
||||
* NOTES: channel 0..9 are supported
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: Get a result from the ADC 10-bit value
|
||||
* RETURN: 10-bit ADC value
|
||||
* NOTES: channel 0..9 are supported
|
||||
**************************************************************************/
|
||||
uint16_t adc_result_10bit(uint8_t channel)
|
||||
{
|
||||
uint16_t result;
|
||||
@@ -168,10 +170,10 @@ uint16_t adc_result_10bit(uint8_t channel)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Get a result from the ADC 8-bit value
|
||||
* RETURN: 8-bit ADC value
|
||||
* NOTES: channel 0..9 are supported
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: Get a result from the ADC 8-bit value
|
||||
* RETURN: 8-bit ADC value
|
||||
* NOTES: channel 0..9 are supported
|
||||
**************************************************************************/
|
||||
uint8_t adc_result_8bit(uint8_t channel)
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
+93
-130
@@ -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,30 +44,16 @@ static bool Out_Of_Service[MAX_ANALOG_INPUTS];
|
||||
static BACNET_ENGINEERING_UNITS Units[MAX_ANALOG_INPUTS];
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Analog_Input_Properties_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_PRESENT_VALUE,
|
||||
PROP_STATUS_FLAGS,
|
||||
PROP_EVENT_STATE,
|
||||
PROP_OUT_OF_SERVICE,
|
||||
PROP_UNITS,
|
||||
-1
|
||||
};
|
||||
static const int Analog_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
|
||||
PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 };
|
||||
|
||||
static const int Analog_Input_Properties_Optional[] = {
|
||||
-1
|
||||
};
|
||||
static const int Analog_Input_Properties_Optional[] = { -1 };
|
||||
|
||||
static const int Analog_Input_Properties_Proprietary[] = {
|
||||
-1
|
||||
};
|
||||
static const int Analog_Input_Properties_Proprietary[] = { -1 };
|
||||
|
||||
void Analog_Input_Property_Lists(
|
||||
const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary)
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||
{
|
||||
if (pRequired)
|
||||
*pRequired = Analog_Input_Properties_Required;
|
||||
@@ -79,22 +65,19 @@ void Analog_Input_Property_Lists(
|
||||
return;
|
||||
}
|
||||
|
||||
void Analog_Input_Init(
|
||||
void)
|
||||
void Analog_Input_Init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
unsigned Analog_Input_Instance_To_Index(
|
||||
uint32_t instance)
|
||||
unsigned Analog_Input_Instance_To_Index(uint32_t instance)
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
@@ -102,13 +85,12 @@ unsigned Analog_Input_Instance_To_Index(
|
||||
/* 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)
|
||||
{
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,22 +98,20 @@ 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;
|
||||
}
|
||||
|
||||
bool Analog_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name)
|
||||
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32]; /* okay for single thread */
|
||||
static char text_string[32]; /* okay for single thread */
|
||||
bool status = false;
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
sprintf(text_string, "AI-%lu", object_instance);
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
@@ -139,67 +119,59 @@ bool Analog_Input_Object_Name(
|
||||
return status;
|
||||
}
|
||||
|
||||
float Analog_Input_Present_Value(
|
||||
uint32_t object_instance)
|
||||
float Analog_Input_Present_Value(uint32_t object_instance)
|
||||
{
|
||||
float value = 0.0;
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
value = Present_Value[index];
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
Present_Value[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
bool Analog_Input_Out_Of_Service(
|
||||
uint32_t object_instance)
|
||||
bool Analog_Input_Out_Of_Service(uint32_t object_instance)
|
||||
{
|
||||
unsigned index = 0;
|
||||
bool value = false;
|
||||
unsigned index = 0;
|
||||
bool value = false;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
value = Out_Of_Service[index];
|
||||
}
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
value = Out_Of_Service[index];
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
void Analog_Input_Out_Of_Service_Set(
|
||||
uint32_t object_instance,
|
||||
bool value)
|
||||
void Analog_Input_Out_Of_Service_Set(uint32_t object_instance, bool value)
|
||||
{
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
Out_Of_Service[index] = value;
|
||||
}
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
Out_Of_Service[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
bool Analog_Input_Units_Set(
|
||||
uint32_t object_instance,
|
||||
uint16_t value)
|
||||
bool Analog_Input_Units_Set(uint32_t object_instance, uint16_t value)
|
||||
{
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
bool status = false;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
Units[index] = value;
|
||||
status = true;
|
||||
}
|
||||
@@ -207,14 +179,13 @@ bool Analog_Input_Units_Set(
|
||||
return status;
|
||||
}
|
||||
|
||||
uint16_t Analog_Input_Units(
|
||||
uint32_t object_instance)
|
||||
uint16_t Analog_Input_Units(uint32_t object_instance)
|
||||
{
|
||||
unsigned index = 0;
|
||||
unsigned index = 0;
|
||||
uint16_t value = UNITS_NO_UNITS;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
value = Units[index];
|
||||
}
|
||||
|
||||
@@ -223,10 +194,9 @@ uint16_t Analog_Input_Units(
|
||||
|
||||
/* return apdu length, or -1 on error */
|
||||
/* assumption - object 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_CHARACTER_STRING char_string = { 0 };
|
||||
BACNET_BIT_STRING bit_string = { 0 };
|
||||
uint8_t *apdu = NULL;
|
||||
@@ -238,9 +208,8 @@ 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], rpdata->object_type,
|
||||
rpdata->object_instance);
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], rpdata->object_type, rpdata->object_instance);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
Analog_Input_Object_Name(rpdata->object_instance, &char_string);
|
||||
@@ -252,9 +221,8 @@ int Analog_Input_Read_Property(
|
||||
encode_application_enumerated(&apdu[0], rpdata->object_type);
|
||||
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);
|
||||
@@ -270,12 +238,12 @@ int Analog_Input_Read_Property(
|
||||
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
apdu_len = encode_application_boolean(&apdu[0],
|
||||
Analog_Input_Out_Of_Service(rpdata->object_instance));
|
||||
apdu_len = encode_application_boolean(
|
||||
&apdu[0], Analog_Input_Out_Of_Service(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_UNITS:
|
||||
apdu_len = encode_application_enumerated(&apdu[0],
|
||||
Analog_Input_Units(rpdata->object_instance));
|
||||
apdu_len = encode_application_enumerated(
|
||||
&apdu[0], Analog_Input_Units(rpdata->object_instance));
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
@@ -294,17 +262,15 @@ int Analog_Input_Read_Property(
|
||||
}
|
||||
|
||||
/* returns true if successful */
|
||||
bool Analog_Input_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
bool status = false; /* return value */
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
|
||||
/* 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 */
|
||||
@@ -319,14 +285,14 @@ bool Analog_Input_Write_Property(
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch ((int) wp_data->object_property) {
|
||||
switch ((int)wp_data->object_property) {
|
||||
case PROP_PRESENT_VALUE:
|
||||
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
if (Analog_Input_Out_Of_Service(wp_data->object_instance)) {
|
||||
Analog_Input_Present_Value_Set(wp_data->object_instance,
|
||||
value.type.Real);
|
||||
Analog_Input_Present_Value_Set(
|
||||
wp_data->object_instance, value.type.Real);
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
@@ -335,23 +301,20 @@ bool Analog_Input_Write_Property(
|
||||
}
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
status =
|
||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
|
||||
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Analog_Input_Out_Of_Service_Set(
|
||||
wp_data->object_instance,
|
||||
value.type.Boolean);
|
||||
wp_data->object_instance, value.type.Boolean);
|
||||
}
|
||||
break;
|
||||
case PROP_UNITS:
|
||||
status =
|
||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Analog_Input_Out_Of_Service_Set(
|
||||
wp_data->object_instance,
|
||||
value.type.Enumerated);
|
||||
wp_data->object_instance, value.type.Enumerated);
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
|
||||
+71
-75
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2013 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) 2013 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 <stdbool.h>
|
||||
#include <string.h>
|
||||
@@ -77,10 +77,10 @@ static struct mstimer Reinit_Timer;
|
||||
static uint8_t PDUBuffer[MAX_MPDU];
|
||||
|
||||
/**************************************************************************
|
||||
* Description: handles reinitializing the device after a few seconds
|
||||
* Returns: none
|
||||
* Notes: gives the device enough time to acknowledge the RD request
|
||||
**************************************************************************/
|
||||
* Description: handles reinitializing the device after a few seconds
|
||||
* Returns: none
|
||||
* Notes: gives the device enough time to acknowledge the RD request
|
||||
**************************************************************************/
|
||||
static void reinit_task(void)
|
||||
{
|
||||
BACNET_REINITIALIZED_STATE state = BACNET_REINIT_IDLE;
|
||||
@@ -100,12 +100,11 @@ static void reinit_task(void)
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Description: handles recurring strictly timed task
|
||||
* Returns: none
|
||||
* Notes: called by ISR every 5 milliseconds
|
||||
**************************************************************************/
|
||||
void bacnet_task_timed(
|
||||
void)
|
||||
* Description: handles recurring strictly timed task
|
||||
* Returns: none
|
||||
* Notes: called by ISR every 5 milliseconds
|
||||
**************************************************************************/
|
||||
void bacnet_task_timed(void)
|
||||
{
|
||||
struct mstp_rx_packet *pkt = NULL;
|
||||
uint16_t pdu_len = 0;
|
||||
@@ -113,7 +112,7 @@ void bacnet_task_timed(
|
||||
|
||||
pdu_len = dlmstp_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 5);
|
||||
if (pdu_len) {
|
||||
pkt = (struct mstp_rx_packet *) Ringbuf_Data_Peek(&Receive_Queue);
|
||||
pkt = (struct mstp_rx_packet *)Ringbuf_Data_Peek(&Receive_Queue);
|
||||
if (pkt) {
|
||||
memcpy(pkt->buffer, PDUBuffer, MAX_MPDU);
|
||||
bacnet_address_copy(&pkt->src, &src);
|
||||
@@ -124,38 +123,38 @@ void bacnet_task_timed(
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Description: handles recurring task
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
**************************************************************************/
|
||||
* Description: handles recurring task
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
**************************************************************************/
|
||||
static void bacnet_test_task(void)
|
||||
{
|
||||
static unsigned index = 0;
|
||||
uint32_t instance;
|
||||
float float_value;
|
||||
uint16_t adc_value;
|
||||
static unsigned index = 0;
|
||||
uint32_t instance;
|
||||
float float_value;
|
||||
uint16_t adc_value;
|
||||
|
||||
instance = Analog_Input_Index_To_Instance(index);
|
||||
if (!Analog_Input_Out_Of_Service(instance)) {
|
||||
adc_value = adc_result_12bit(index);
|
||||
adc_value = adc_result_12bit(index);
|
||||
float_value = adc_value;
|
||||
float_value /= 4095;
|
||||
Analog_Input_Present_Value_Set(instance, float_value);
|
||||
}
|
||||
index++;
|
||||
if (index >= MAX_ANALOG_INPUTS) {
|
||||
if (index >= MAX_ANALOG_INPUTS) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Description: handles recurring task
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
**************************************************************************/
|
||||
* Description: handles recurring task
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
**************************************************************************/
|
||||
void bacnet_task(void)
|
||||
{
|
||||
struct mstp_rx_packet pkt = {{0}};
|
||||
struct mstp_rx_packet pkt = { { 0 } };
|
||||
bool pdu_available = false;
|
||||
|
||||
/* hello, World! */
|
||||
@@ -167,68 +166,65 @@ void bacnet_task(void)
|
||||
if (mstimer_expired(&DCC_Timer)) {
|
||||
mstimer_reset(&DCC_Timer);
|
||||
dcc_timer_seconds(DCC_CYCLE_SECONDS);
|
||||
led_on_interval(LED_DEBUG,500);
|
||||
led_on_interval(LED_DEBUG, 500);
|
||||
}
|
||||
if (mstimer_expired(&TSM_Timer)) {
|
||||
mstimer_reset(&TSM_Timer);
|
||||
tsm_timer_milliseconds(mstimer_interval(&TSM_Timer));
|
||||
}
|
||||
reinit_task();
|
||||
bacnet_test_task();
|
||||
bacnet_test_task();
|
||||
/* handle the messaging */
|
||||
if ((!dlmstp_send_pdu_queue_full()) &&
|
||||
(!Ringbuf_Empty(&Receive_Queue))) {
|
||||
if ((!dlmstp_send_pdu_queue_full()) && (!Ringbuf_Empty(&Receive_Queue))) {
|
||||
Ringbuf_Pop(&Receive_Queue, (uint8_t *)&pkt);
|
||||
pdu_available = true;
|
||||
}
|
||||
if (pdu_available) {
|
||||
led_on_interval(LED_APDU,125);
|
||||
led_on_interval(LED_APDU, 125);
|
||||
npdu_handler(&pkt.src, &pkt.buffer[0], pkt.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Description: initializes the BACnet library
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
**************************************************************************/
|
||||
* Description: initializes the BACnet library
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
**************************************************************************/
|
||||
void bacnet_init(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
Ringbuf_Init(&Receive_Queue, (uint8_t *) & Receive_Buffer,
|
||||
Ringbuf_Init(&Receive_Queue, (uint8_t *)&Receive_Buffer,
|
||||
sizeof(struct mstp_rx_packet), MSTP_RECEIVE_PACKET_COUNT);
|
||||
dlmstp_init(NULL);
|
||||
/* initialize objects */
|
||||
Device_Init(NULL);
|
||||
/* set up our confirmed service unrecognized service handler - required! */
|
||||
apdu_set_unrecognized_service_handler_handler
|
||||
(handler_unrecognized_service);
|
||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||
/* we need to handle who-is to support dynamic device binding */
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
||||
/* Set the handlers for any confirmed services that we support. */
|
||||
/* We must implement read property - it's required! */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
handler_read_property);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||
handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
||||
handler_reinitialize_device);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
handler_write_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
/* handle communication so we can shut up when asked */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
/* start the cyclic 1 second timer for DCC */
|
||||
mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS*1000);
|
||||
mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS * 1000);
|
||||
/* start the cyclic 1 second timer for COV */
|
||||
mstimer_set(&COV_Timer, COV_CYCLE_SECONDS*1000);
|
||||
mstimer_set(&COV_Timer, COV_CYCLE_SECONDS * 1000);
|
||||
/* start the cyclic 1 second timer for TSM */
|
||||
mstimer_set(&TSM_Timer, TSM_CYCLE_SECONDS*1000);
|
||||
for (i = 0; i < MAX_ANALOG_INPUTS; i++) {
|
||||
mstimer_set(&TSM_Timer, TSM_CYCLE_SECONDS * 1000);
|
||||
for (i = 0; i < MAX_ANALOG_INPUTS; i++) {
|
||||
Analog_Input_Units_Set(
|
||||
Analog_Input_Index_To_Instance(i),
|
||||
UNITS_PERCENT);
|
||||
Analog_Input_Index_To_Instance(i), UNITS_PERCENT);
|
||||
}
|
||||
}
|
||||
|
||||
+65
-84
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2011 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) 2011 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 <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
@@ -34,13 +34,11 @@
|
||||
#include "bname.h"
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Test the BACnet CharacterString for validity
|
||||
* RETURN: true if valid
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
static bool bacnet_name_isvalid(uint8_t encoding,
|
||||
uint8_t length,
|
||||
char *str)
|
||||
* DESCRIPTION: Test the BACnet CharacterString for validity
|
||||
* RETURN: true if valid
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
static bool bacnet_name_isvalid(uint8_t encoding, uint8_t length, char *str)
|
||||
{
|
||||
bool valid = false;
|
||||
|
||||
@@ -57,14 +55,11 @@ static bool bacnet_name_isvalid(uint8_t encoding,
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Copy the name from non-volatile memory at offset
|
||||
* RETURN: number of bytes read, or -1 on error
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
int bacnet_name_copy(
|
||||
uint16_t offset,
|
||||
uint8_t *dest,
|
||||
uint8_t dest_len)
|
||||
* DESCRIPTION: Copy the name from non-volatile memory at offset
|
||||
* RETURN: number of bytes read, or -1 on error
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
int bacnet_name_copy(uint16_t offset, uint8_t *dest, uint8_t dest_len)
|
||||
{
|
||||
uint8_t encoding = 0;
|
||||
uint8_t length = 0;
|
||||
@@ -74,9 +69,8 @@ int bacnet_name_copy(
|
||||
|
||||
nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
|
||||
nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
|
||||
nvm_read(NVM_NAME_STRING(offset),
|
||||
(uint8_t *) & name, NVM_NAME_SIZE);
|
||||
if (bacnet_name_isvalid(encoding, length, name)) {
|
||||
nvm_read(NVM_NAME_STRING(offset), (uint8_t *)&name, NVM_NAME_SIZE);
|
||||
if (bacnet_name_isvalid(encoding, length, name)) {
|
||||
if (dest_len > NVM_NAME_SIZE) {
|
||||
dest_len = NVM_NAME_SIZE;
|
||||
}
|
||||
@@ -98,12 +92,11 @@ int bacnet_name_copy(
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Encode the name in a buffer in the sequence stored in EEPROM.
|
||||
* RETURN: number of bytes in buffer, or 0 if too big to fit.
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
uint8_t bacnet_name_encode(
|
||||
uint8_t *buffer,
|
||||
* DESCRIPTION: Encode the name in a buffer in the sequence stored in EEPROM.
|
||||
* RETURN: number of bytes in buffer, or 0 if too big to fit.
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
uint8_t bacnet_name_encode(uint8_t *buffer,
|
||||
uint8_t buffer_len,
|
||||
uint8_t encoding,
|
||||
char *str,
|
||||
@@ -112,13 +105,13 @@ uint8_t bacnet_name_encode(
|
||||
unsigned len = 0;
|
||||
unsigned i = 0;
|
||||
|
||||
if (str_len < (255-2)) {
|
||||
if (str_len < (255 - 2)) {
|
||||
len = 1 + 1 + str_len;
|
||||
if (len <= buffer_len) {
|
||||
buffer[NVM_NAME_LENGTH(0)] = str_len;
|
||||
buffer[NVM_NAME_ENCODING(0)] = encoding;
|
||||
for (i = 0; i < str_len; i++) {
|
||||
buffer[NVM_NAME_STRING(0)+i] = str[i];
|
||||
buffer[NVM_NAME_STRING(0) + i] = str[i];
|
||||
}
|
||||
} else {
|
||||
len = 0;
|
||||
@@ -129,30 +122,21 @@ uint8_t bacnet_name_encode(
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Store the name to non-volatile memory at offset
|
||||
* RETURN: true if name is a valid set of characters
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
* DESCRIPTION: Store the name to non-volatile memory at offset
|
||||
* RETURN: true if name is a valid set of characters
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
bool bacnet_name_save(
|
||||
uint16_t offset,
|
||||
uint8_t encoding,
|
||||
char *str,
|
||||
uint8_t str_len)
|
||||
uint16_t offset, uint8_t encoding, char *str, uint8_t str_len)
|
||||
{
|
||||
uint8_t buffer[NVM_NAME_SIZE] = { 0 };
|
||||
uint8_t length = 0;
|
||||
|
||||
if (bacnet_name_isvalid(encoding, str_len, str)) {
|
||||
length = bacnet_name_encode(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
encoding,
|
||||
str,
|
||||
str_len);
|
||||
length =
|
||||
bacnet_name_encode(buffer, sizeof(buffer), encoding, str, str_len);
|
||||
if (length) {
|
||||
nvm_write(
|
||||
offset,
|
||||
&buffer[0],length);
|
||||
nvm_write(offset, &buffer[0], length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -160,8 +144,7 @@ bool bacnet_name_save(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bacnet_name_set(uint16_t offset,
|
||||
BACNET_CHARACTER_STRING * char_string)
|
||||
bool bacnet_name_set(uint16_t offset, BACNET_CHARACTER_STRING *char_string)
|
||||
{
|
||||
uint8_t encoding = 0;
|
||||
uint8_t length = 0;
|
||||
@@ -176,9 +159,9 @@ bool bacnet_name_set(uint16_t offset,
|
||||
bool bacnet_name_write_unique(uint16_t offset,
|
||||
int object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * char_string,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
BACNET_CHARACTER_STRING *char_string,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
bool status = false;
|
||||
size_t length = 0;
|
||||
@@ -193,8 +176,8 @@ bool bacnet_name_write_unique(uint16_t offset,
|
||||
} else if (length <= NVM_NAME_SIZE) {
|
||||
encoding = characterstring_encoding(char_string);
|
||||
if (encoding < MAX_CHARACTER_STRING_ENCODING) {
|
||||
if (Device_Valid_Object_Name(char_string, &duplicate_type,
|
||||
&duplicate_instance)) {
|
||||
if (Device_Valid_Object_Name(
|
||||
char_string, &duplicate_type, &duplicate_instance)) {
|
||||
if ((duplicate_type == object_type) &&
|
||||
(duplicate_instance == object_instance)) {
|
||||
/* writing same name to same object */
|
||||
@@ -226,9 +209,9 @@ bool bacnet_name_write_unique(uint16_t offset,
|
||||
|
||||
/* no required minumum length or duplicate checking */
|
||||
bool bacnet_name_write(uint16_t offset,
|
||||
BACNET_CHARACTER_STRING * char_string,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
BACNET_CHARACTER_STRING *char_string,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
bool status = false;
|
||||
size_t length = 0;
|
||||
@@ -255,16 +238,14 @@ bool bacnet_name_write(uint16_t offset,
|
||||
return status;
|
||||
}
|
||||
|
||||
void bacnet_name_init(uint16_t offset,
|
||||
char *default_string)
|
||||
void bacnet_name_init(uint16_t offset, char *default_string)
|
||||
{
|
||||
(void) bacnet_name_save(offset, CHARACTER_UTF8, default_string,
|
||||
strlen(default_string));
|
||||
(void)bacnet_name_save(
|
||||
offset, CHARACTER_UTF8, default_string, strlen(default_string));
|
||||
}
|
||||
|
||||
void bacnet_name(uint16_t offset,
|
||||
BACNET_CHARACTER_STRING * char_string,
|
||||
char *default_string)
|
||||
void bacnet_name(
|
||||
uint16_t offset, BACNET_CHARACTER_STRING *char_string, char *default_string)
|
||||
{
|
||||
uint8_t encoding = 0;
|
||||
uint8_t length = 0;
|
||||
@@ -272,7 +253,7 @@ void bacnet_name(uint16_t offset,
|
||||
|
||||
nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
|
||||
nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
|
||||
nvm_read(NVM_NAME_STRING(offset), (uint8_t *) & name[0], NVM_NAME_SIZE);
|
||||
nvm_read(NVM_NAME_STRING(offset), (uint8_t *)&name[0], NVM_NAME_SIZE);
|
||||
if (bacnet_name_isvalid(encoding, length, name)) {
|
||||
characterstring_init(char_string, encoding, &name[0], length);
|
||||
} else if (default_string) {
|
||||
|
||||
+135
-187
@@ -1,27 +1,27 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 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) 2015 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 <stdlib.h>
|
||||
@@ -45,8 +45,8 @@
|
||||
#include "bacnet/basic/object/ai.h"
|
||||
|
||||
/* forward prototype */
|
||||
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA * wp_data);
|
||||
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
|
||||
bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
|
||||
|
||||
static struct my_object_functions {
|
||||
BACNET_OBJECT_TYPE Object_Type;
|
||||
@@ -62,19 +62,16 @@ static struct my_object_functions {
|
||||
object_cov_function Object_COV;
|
||||
object_cov_clear_function Object_COV_Clear;
|
||||
} Object_Table[] = {
|
||||
{
|
||||
OBJECT_DEVICE, NULL,
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number, Device_Object_Name,
|
||||
Device_Read_Property_Local, Device_Write_Property_Local,
|
||||
Device_Property_Lists,
|
||||
NULL, NULL, NULL}, {
|
||||
OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
|
||||
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
|
||||
Analog_Input_Object_Name, Analog_Input_Read_Property,
|
||||
Analog_Input_Write_Property, Analog_Input_Property_Lists,
|
||||
NULL, NULL, NULL}, {
|
||||
MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
|
||||
{ OBJECT_DEVICE, NULL, Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number, Device_Object_Name,
|
||||
Device_Read_Property_Local, Device_Write_Property_Local,
|
||||
Device_Property_Lists, NULL, NULL, NULL },
|
||||
{ OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
|
||||
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
|
||||
Analog_Input_Object_Name, Analog_Input_Read_Property,
|
||||
Analog_Input_Write_Property, Analog_Input_Property_Lists, NULL, NULL,
|
||||
NULL },
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
/* note: you really only need to define variables for
|
||||
@@ -87,44 +84,23 @@ static uint32_t Database_Revision;
|
||||
static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Device_Properties_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_SYSTEM_STATUS,
|
||||
PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER,
|
||||
PROP_MODEL_NAME,
|
||||
PROP_FIRMWARE_REVISION,
|
||||
PROP_APPLICATION_SOFTWARE_VERSION,
|
||||
PROP_PROTOCOL_VERSION,
|
||||
PROP_PROTOCOL_REVISION,
|
||||
PROP_PROTOCOL_SERVICES_SUPPORTED,
|
||||
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
|
||||
PROP_OBJECT_LIST,
|
||||
PROP_MAX_APDU_LENGTH_ACCEPTED,
|
||||
PROP_SEGMENTATION_SUPPORTED,
|
||||
PROP_APDU_TIMEOUT,
|
||||
PROP_NUMBER_OF_APDU_RETRIES,
|
||||
PROP_DEVICE_ADDRESS_BINDING,
|
||||
PROP_DATABASE_REVISION,
|
||||
-1
|
||||
};
|
||||
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
|
||||
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
|
||||
PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED,
|
||||
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST,
|
||||
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
|
||||
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING,
|
||||
PROP_DATABASE_REVISION, -1 };
|
||||
|
||||
static const int Device_Properties_Optional[] = {
|
||||
PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_LOCATION,
|
||||
-1
|
||||
};
|
||||
static const int Device_Properties_Optional[] = { PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES, PROP_DESCRIPTION, PROP_LOCATION, -1 };
|
||||
|
||||
static const int Device_Properties_Proprietary[] = {
|
||||
-1
|
||||
};
|
||||
static const int Device_Properties_Proprietary[] = { -1 };
|
||||
|
||||
static struct my_object_functions
|
||||
*Device_Objects_Find_Functions(BACNET_OBJECT_TYPE Object_Type)
|
||||
static struct my_object_functions *Device_Objects_Find_Functions(
|
||||
BACNET_OBJECT_TYPE Object_Type)
|
||||
{
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
@@ -142,7 +118,7 @@ static struct my_object_functions
|
||||
|
||||
/* Encodes the property APDU and returns the length,
|
||||
or sets the error, and returns BACNET_STATUS_ERROR */
|
||||
int Device_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = BACNET_STATUS_ERROR;
|
||||
struct my_object_functions *pObject = NULL;
|
||||
@@ -163,7 +139,7 @@ int Device_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false;
|
||||
struct my_object_functions *pObject = NULL;
|
||||
@@ -192,8 +168,7 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
}
|
||||
|
||||
/* for a given object type, returns the special property list */
|
||||
void Device_Objects_Property_List(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
struct special_property_list_t *pPropertyList)
|
||||
{
|
||||
@@ -216,24 +191,23 @@ void Device_Objects_Property_List(
|
||||
}
|
||||
|
||||
/* Fetch the counts if available otherwise zero them */
|
||||
pPropertyList->Required.count =
|
||||
pPropertyList->Required.pList ==
|
||||
NULL ? 0 : property_list_count(pPropertyList->Required.pList);
|
||||
pPropertyList->Required.count = pPropertyList->Required.pList == NULL
|
||||
? 0
|
||||
: property_list_count(pPropertyList->Required.pList);
|
||||
|
||||
pPropertyList->Optional.count =
|
||||
pPropertyList->Optional.pList ==
|
||||
NULL ? 0 : property_list_count(pPropertyList->Optional.pList);
|
||||
pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL
|
||||
? 0
|
||||
: property_list_count(pPropertyList->Optional.pList);
|
||||
|
||||
pPropertyList->Proprietary.count =
|
||||
pPropertyList->Proprietary.pList ==
|
||||
NULL ? 0 : property_list_count(pPropertyList->Proprietary.pList);
|
||||
pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL
|
||||
? 0
|
||||
: property_list_count(pPropertyList->Proprietary.pList);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Device_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary)
|
||||
void Device_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||
{
|
||||
if (pRequired)
|
||||
*pRequired = Device_Properties_Required;
|
||||
@@ -256,10 +230,9 @@ uint32_t Device_Index_To_Instance(unsigned index)
|
||||
return Object_Instance_Number;
|
||||
}
|
||||
|
||||
static char *Device_Name_Default(
|
||||
void)
|
||||
static char *Device_Name_Default(void)
|
||||
{
|
||||
static char text_string[32]; /* okay for single thread */
|
||||
static char text_string[32]; /* okay for single thread */
|
||||
|
||||
sprintf(text_string, "DEVICE-%lu", Object_Instance_Number);
|
||||
|
||||
@@ -267,8 +240,7 @@ static char *Device_Name_Default(
|
||||
}
|
||||
|
||||
bool Device_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name)
|
||||
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
@@ -300,7 +272,7 @@ const char *Device_Application_Software_Version(void)
|
||||
return BACNET_VERSION_TEXT;
|
||||
}
|
||||
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA * rd_data)
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
@@ -326,13 +298,13 @@ 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)
|
||||
{
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
/* we don't use the object table passed in
|
||||
since there is extra stuff we don't need in there. */
|
||||
(void) object_table;
|
||||
(void)object_table;
|
||||
/* our local object table */
|
||||
pObject = &Object_Table[0];
|
||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
||||
@@ -375,8 +347,7 @@ 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)
|
||||
{
|
||||
/*return value - 0 = ok, -1 = bad value, -2 = not allowed */
|
||||
int result = -1;
|
||||
@@ -409,22 +380,20 @@ void Device_Inc_Database_Revision(void)
|
||||
Database_Revision++;
|
||||
}
|
||||
|
||||
bool Device_Encode_Value_List(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_VALUE * value_list)
|
||||
BACNET_PROPERTY_VALUE *value_list)
|
||||
{
|
||||
bool status = false; /* Ever the pessamist! */
|
||||
bool status = false; /* Ever the pessamist! */
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
pObject = Device_Objects_Find_Functions(object_type);
|
||||
if (pObject != NULL) {
|
||||
if (pObject->Object_Valid_Instance &&
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
if (pObject->Object_Value_List) {
|
||||
status = pObject->Object_Value_List(
|
||||
object_instance,
|
||||
value_list);
|
||||
status =
|
||||
pObject->Object_Value_List(object_instance, value_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -432,20 +401,17 @@ bool Device_Encode_Value_List(
|
||||
return (status);
|
||||
}
|
||||
|
||||
bool Device_COV(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance)
|
||||
bool Device_COV(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
{
|
||||
bool status = false; /* Ever the pessamist! */
|
||||
bool status = false; /* Ever the pessamist! */
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
pObject = Device_Objects_Find_Functions(object_type);
|
||||
if (pObject != NULL) {
|
||||
if (pObject->Object_Valid_Instance &&
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
if (pObject->Object_COV) {
|
||||
status = pObject->Object_COV(
|
||||
object_instance);
|
||||
status = pObject->Object_COV(object_instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -453,16 +419,14 @@ bool Device_COV(
|
||||
return (status);
|
||||
}
|
||||
|
||||
void Device_COV_Clear(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance)
|
||||
void Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
{
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
pObject = Device_Objects_Find_Functions(object_type);
|
||||
if (pObject != NULL) {
|
||||
if (pObject->Object_Valid_Instance &&
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
if (pObject->Object_COV_Clear) {
|
||||
pObject->Object_COV_Clear(object_instance);
|
||||
}
|
||||
@@ -470,10 +434,9 @@ void Device_COV_Clear(
|
||||
}
|
||||
}
|
||||
|
||||
bool Device_Value_List_Supported(
|
||||
BACNET_OBJECT_TYPE object_type)
|
||||
bool Device_Value_List_Supported(BACNET_OBJECT_TYPE object_type)
|
||||
{
|
||||
bool status = false; /* Ever the pessimist! */
|
||||
bool status = false; /* Ever the pessimist! */
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
pObject = Device_Objects_Find_Functions(object_type);
|
||||
@@ -505,9 +468,8 @@ unsigned Device_Object_List_Count(void)
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Device_Object_List_Identifier(uint32_t array_index,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * instance)
|
||||
bool Device_Object_List_Identifier(
|
||||
uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
|
||||
{
|
||||
bool status = false;
|
||||
uint32_t count = 0;
|
||||
@@ -538,9 +500,9 @@ bool Device_Object_List_Identifier(uint32_t array_index,
|
||||
return status;
|
||||
}
|
||||
|
||||
bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING * object_name1,
|
||||
bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * object_instance)
|
||||
uint32_t *object_instance)
|
||||
{
|
||||
bool found = false;
|
||||
BACNET_OBJECT_TYPE type = OBJECT_NONE;
|
||||
@@ -554,7 +516,7 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING * object_name1,
|
||||
for (i = 1; i <= max_objects; i++) {
|
||||
check_id = Device_Object_List_Identifier(i, &type, &instance);
|
||||
if (check_id) {
|
||||
pObject = Device_Objects_Find_Functions((BACNET_OBJECT_TYPE) type);
|
||||
pObject = Device_Objects_Find_Functions((BACNET_OBJECT_TYPE)type);
|
||||
if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
|
||||
(pObject->Object_Name(instance, &object_name2) &&
|
||||
characterstring_same(object_name1, &object_name2))) {
|
||||
@@ -573,13 +535,13 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING * object_name1,
|
||||
return found;
|
||||
}
|
||||
|
||||
bool Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance)
|
||||
bool Device_Valid_Object_Id(
|
||||
BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
bool status = false; /* return value */
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
pObject = Device_Objects_Find_Functions((BACNET_OBJECT_TYPE) object_type);
|
||||
pObject = Device_Objects_Find_Functions((BACNET_OBJECT_TYPE)object_type);
|
||||
if ((pObject != NULL) && (pObject->Object_Valid_Instance != NULL)) {
|
||||
status = pObject->Object_Valid_Instance(object_instance);
|
||||
}
|
||||
@@ -589,7 +551,7 @@ bool Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type,
|
||||
|
||||
bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name)
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
struct my_object_functions *pObject = NULL;
|
||||
bool found = false;
|
||||
@@ -603,10 +565,10 @@ bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
|
||||
}
|
||||
|
||||
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */
|
||||
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
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 = { 0 };
|
||||
BACNET_CHARACTER_STRING char_string = { 0 };
|
||||
uint32_t i = 0;
|
||||
@@ -621,11 +583,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
return 0;
|
||||
}
|
||||
apdu = rpdata->application_data;
|
||||
switch ((int) rpdata->object_property) {
|
||||
switch ((int)rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], rpdata->object_type,
|
||||
rpdata->object_instance);
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], rpdata->object_type, rpdata->object_instance);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
Device_Object_Name(rpdata->object_instance, &char_string);
|
||||
@@ -637,21 +598,19 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
encode_application_enumerated(&apdu[0], rpdata->object_type);
|
||||
break;
|
||||
case PROP_DESCRIPTION:
|
||||
bacnet_name(NVM_DEVICE_DESCRIPTION, &char_string,
|
||||
"default description");
|
||||
bacnet_name(
|
||||
NVM_DEVICE_DESCRIPTION, &char_string, "default description");
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_LOCATION:
|
||||
bacnet_name(NVM_DEVICE_LOCATION, &char_string,
|
||||
"default location");
|
||||
bacnet_name(NVM_DEVICE_LOCATION, &char_string, "default location");
|
||||
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:
|
||||
characterstring_init_ansi(&char_string, Device_Vendor_Name());
|
||||
@@ -667,14 +626,13 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_FIRMWARE_REVISION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Device_Firmware_Revision());
|
||||
characterstring_init_ansi(&char_string, Device_Firmware_Revision());
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_APPLICATION_SOFTWARE_VERSION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Device_Application_Software_Version());
|
||||
characterstring_init_ansi(
|
||||
&char_string, Device_Application_Software_Version());
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
@@ -684,16 +642,15 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
break;
|
||||
case PROP_PROTOCOL_REVISION:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0],
|
||||
BACNET_PROTOCOL_REVISION);
|
||||
encode_application_unsigned(&apdu[0], BACNET_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((BACNET_SERVICES_SUPPORTED) i));
|
||||
bitstring_set_bit(&bit_string, (uint8_t)i,
|
||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
|
||||
}
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
@@ -703,7 +660,7 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
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);
|
||||
}
|
||||
/* set the object types with objects to supported */
|
||||
i = 0;
|
||||
@@ -727,11 +684,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
/* 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? */
|
||||
@@ -751,11 +707,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
@@ -767,9 +722,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
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());
|
||||
@@ -781,14 +735,12 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
/* 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 =
|
||||
@@ -817,17 +769,16 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
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 - false=error */
|
||||
bool status = false; /* return value - false=error */
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
uint8_t max_master = 0;
|
||||
|
||||
/* 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 */
|
||||
@@ -842,14 +793,14 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch ((int) wp_data->object_property) {
|
||||
switch ((int)wp_data->object_property) {
|
||||
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))) {
|
||||
nvm_write(NVM_DEVICE_0,
|
||||
(uint8_t *) & value.type.Object_Id.instance, 4);
|
||||
(uint8_t *)&value.type.Object_Id.instance, 4);
|
||||
/* we could send an I-Am broadcast to let the world know */
|
||||
status = true;
|
||||
} else {
|
||||
@@ -894,8 +845,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||
status =
|
||||
bacnet_name_write_unique(NVM_DEVICE_NAME,
|
||||
status = bacnet_name_write_unique(NVM_DEVICE_NAME,
|
||||
wp_data->object_type, wp_data->object_instance,
|
||||
&value.type.Character_String, &wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
@@ -906,8 +856,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
break;
|
||||
case PROP_DESCRIPTION:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||
status =
|
||||
bacnet_name_write(NVM_DEVICE_DESCRIPTION,
|
||||
status = bacnet_name_write(NVM_DEVICE_DESCRIPTION,
|
||||
&value.type.Character_String, &wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
} else {
|
||||
@@ -917,8 +866,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
break;
|
||||
case PROP_LOCATION:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||
status =
|
||||
bacnet_name_write(NVM_DEVICE_LOCATION,
|
||||
status = bacnet_name_write(NVM_DEVICE_LOCATION,
|
||||
&value.type.Character_String, &wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
} else {
|
||||
|
||||
+81
-84
@@ -68,19 +68,19 @@ static volatile struct mstp_flag_t {
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if an invalid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedInvalidFrame:1;
|
||||
unsigned ReceivedInvalidFrame : 1;
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if a valid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedValidFrame:1;
|
||||
unsigned ReceivedValidFrame : 1;
|
||||
/* set to TRUE when we get a frame not for us */
|
||||
unsigned ReceivedValidFrameNotForUs:1;
|
||||
unsigned ReceivedValidFrameNotForUs : 1;
|
||||
/* A Boolean flag set to TRUE by the master machine if this node is the */
|
||||
/* only known master node. */
|
||||
unsigned SoleMaster:1;
|
||||
unsigned SoleMaster : 1;
|
||||
/* A Boolean flag set TRUE by the datalink if a
|
||||
packet has been received, but not processed. */
|
||||
unsigned ReceivePacketPending:1;
|
||||
unsigned ReceivePacketPending : 1;
|
||||
} MSTP_Flag;
|
||||
|
||||
/* Used to store the data length of a received frame. */
|
||||
@@ -154,7 +154,7 @@ static volatile uint8_t Nmax_master = 127;
|
||||
/* The maximum time a node may wait after reception of a frame that expects */
|
||||
/* a reply before sending the first octet of a reply or Reply Postponed */
|
||||
/* frame: 250 milliseconds. */
|
||||
#define Treply_delay (250-50)
|
||||
#define Treply_delay (250 - 50)
|
||||
|
||||
/* The width of the time slot within which a node may generate a token: */
|
||||
/* 10 milliseconds. */
|
||||
@@ -166,7 +166,11 @@ static volatile uint8_t Nmax_master = 127;
|
||||
#define Tusage_delay 15
|
||||
|
||||
/* 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++; \
|
||||
}
|
||||
|
||||
/* data structure for MS/TP PDU Queue */
|
||||
struct mstp_pdu_packet {
|
||||
@@ -182,7 +186,7 @@ bool dlmstp_init(char *ifname)
|
||||
{
|
||||
ifname = ifname;
|
||||
|
||||
Ringbuf_Init(&PDU_Queue, (uint8_t *) & PDU_Buffer,
|
||||
Ringbuf_Init(&PDU_Queue, (uint8_t *)&PDU_Buffer,
|
||||
sizeof(struct mstp_pdu_packet), MSTP_PDU_PACKET_COUNT);
|
||||
|
||||
return true;
|
||||
@@ -193,8 +197,7 @@ void dlmstp_cleanup(void)
|
||||
/* nothing to do for static buffers */
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -217,10 +220,10 @@ void dlmstp_fill_bacnet_address(BACNET_ADDRESS * src,
|
||||
}
|
||||
}
|
||||
|
||||
static bool dlmstp_compare_data_expecting_reply(uint8_t * request_pdu,
|
||||
static bool dlmstp_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)
|
||||
{
|
||||
@@ -241,9 +244,8 @@ static bool dlmstp_compare_data_expecting_reply(uint8_t * request_pdu,
|
||||
/* 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;
|
||||
}
|
||||
@@ -260,8 +262,7 @@ static bool dlmstp_compare_data_expecting_reply(uint8_t * request_pdu,
|
||||
/* 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;
|
||||
}
|
||||
@@ -302,7 +303,8 @@ static bool dlmstp_compare_data_expecting_reply(uint8_t * request_pdu,
|
||||
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
|
||||
@@ -332,21 +334,22 @@ static bool dlmstp_compare_data_expecting_reply(uint8_t * request_pdu,
|
||||
/* Data CRC: (present only if Length is non-zero) two octets, */
|
||||
/* least significant octet first */
|
||||
/* (pad): (optional) at most one octet of padding: X'FF' */
|
||||
static void MSTP_Send_Frame(uint8_t frame_type, /* type of frame to send - see defines */
|
||||
static void MSTP_Send_Frame(
|
||||
uint8_t frame_type, /* type of frame to send - see defines */
|
||||
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t destination, /* destination address */
|
||||
|
||||
uint8_t source, /* source address */
|
||||
uint8_t source, /* source address */
|
||||
|
||||
uint8_t * data, /* any data to be sent - may be null */
|
||||
uint8_t *data, /* any data to be sent - may be null */
|
||||
|
||||
uint16_t 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 */
|
||||
uint8_t buffer[8]; /* stores the header and header crc */
|
||||
uint8_t buffer_crc[2]; /* stores the data crc */
|
||||
uint16_t i = 0; /* used to calculate CRC for data */
|
||||
{ /* 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 */
|
||||
uint8_t buffer[8]; /* stores the header and header crc */
|
||||
uint8_t buffer_crc[2]; /* stores the data crc */
|
||||
uint16_t i = 0; /* used to calculate CRC for data */
|
||||
|
||||
/* create the MS/TP header */
|
||||
buffer[0] = 0x55;
|
||||
@@ -640,7 +643,7 @@ static void MSTP_Slave_Node_FSM(void)
|
||||
/* source address */
|
||||
uint8_t source;
|
||||
/* any data to be sent - may be null */
|
||||
uint8_t * data;
|
||||
uint8_t *data;
|
||||
/* amount of data to be sent - may be 0 */
|
||||
uint16_t data_len;
|
||||
/* packet from the PDU Queue */
|
||||
@@ -657,7 +660,7 @@ static void MSTP_Slave_Node_FSM(void)
|
||||
/* The ANSWER_DATA_REQUEST state is entered when a */
|
||||
/* BACnet Data Expecting Reply, a Test_Request, or */
|
||||
/* a proprietary frame that expects a reply is received. */
|
||||
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
|
||||
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
|
||||
if (pkt != NULL) {
|
||||
uint8_t frame_type;
|
||||
if (pkt->data_expecting_reply) {
|
||||
@@ -667,13 +670,13 @@ static void MSTP_Slave_Node_FSM(void)
|
||||
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
||||
}
|
||||
MSTP_Send_Frame(frame_type, pkt->destination_mac,
|
||||
This_Station, (uint8_t *) & pkt->buffer[0],
|
||||
This_Station, (uint8_t *)&pkt->buffer[0],
|
||||
pkt->length);
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
/* clear our flag we were holding for comparison */
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
/* clear the queue */
|
||||
(void) Ringbuf_Pop(&PDU_Queue, NULL);
|
||||
(void)Ringbuf_Pop(&PDU_Queue, NULL);
|
||||
} else if (rs485_silence_elapsed(Treply_delay)) {
|
||||
/* If no reply will be available from the higher layers
|
||||
within Treply_delay after the reception of the final
|
||||
@@ -693,8 +696,8 @@ static void MSTP_Slave_Node_FSM(void)
|
||||
source = This_Station;
|
||||
data = &InputBuffer[0];
|
||||
data_len = DataLength;
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE,
|
||||
destination, source, data, data_len);
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, destination, source,
|
||||
data, data_len);
|
||||
break;
|
||||
case FRAME_TYPE_TOKEN:
|
||||
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||
@@ -738,7 +741,7 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* source address */
|
||||
uint8_t source;
|
||||
/* any data to be sent - may be null */
|
||||
uint8_t * data;
|
||||
uint8_t *data;
|
||||
/* amount of data to be sent - may be 0 */
|
||||
uint16_t data_len;
|
||||
/* timeout values */
|
||||
@@ -828,8 +831,8 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
source = This_Station;
|
||||
data = &InputBuffer[0];
|
||||
data_len = DataLength;
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE,
|
||||
destination, source, data, data_len);
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, destination,
|
||||
source, data, data_len);
|
||||
break;
|
||||
case FRAME_TYPE_TEST_RESPONSE:
|
||||
default:
|
||||
@@ -854,14 +857,14 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
transition_now = true;
|
||||
} else {
|
||||
uint8_t frame_type;
|
||||
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
|
||||
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
|
||||
if (pkt->data_expecting_reply) {
|
||||
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
|
||||
} else {
|
||||
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
||||
}
|
||||
MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station,
|
||||
(uint8_t *) & pkt->buffer[0], pkt->length);
|
||||
(uint8_t *)&pkt->buffer[0], pkt->length);
|
||||
FrameCount++;
|
||||
switch (frame_type) {
|
||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||
@@ -881,7 +884,7 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||
break;
|
||||
}
|
||||
(void) Ringbuf_Pop(&PDU_Queue, NULL);
|
||||
(void)Ringbuf_Pop(&PDU_Queue, NULL);
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||
@@ -994,8 +997,8 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
may be found in that case. */
|
||||
TokenCount++;
|
||||
/* transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
EventCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
|
||||
@@ -1009,7 +1012,7 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* no known successor node */
|
||||
Next_Station = This_Station;
|
||||
RetryCount = 0;
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
/* EventCount = 0; removed in Addendum 135-2004d-8 */
|
||||
/* find a new successor to TS */
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
@@ -1017,10 +1020,10 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* ResetMaintenancePFM */
|
||||
Poll_Station = This_Station;
|
||||
/* transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||
EventCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
|
||||
}
|
||||
@@ -1041,8 +1044,8 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* RetrySendToken */
|
||||
RetryCount++;
|
||||
/* Transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
EventCount = 0;
|
||||
/* re-enter the current state to listen for NS */
|
||||
/* to begin using the token. */
|
||||
@@ -1120,15 +1123,15 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
if (MSTP_Flag.ReceivedValidFrame == true) {
|
||||
destination = DestinationAddress;
|
||||
if ((destination == This_Station)
|
||||
&& (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
|
||||
if ((destination == This_Station) &&
|
||||
(FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
|
||||
/* ReceivedReplyToPFM */
|
||||
MSTP_Flag.SoleMaster = false;
|
||||
Next_Station = SourceAddress;
|
||||
EventCount = 0;
|
||||
/* Transmit a Token frame to NS */
|
||||
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
|
||||
This_Station, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
|
||||
Poll_Station = This_Station;
|
||||
TokenCount = 0;
|
||||
RetryCount = 0;
|
||||
@@ -1197,12 +1200,11 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
data_len = DataLength;
|
||||
timeout = rs485_silence_elapsed(Treply_delay);
|
||||
if (!timeout) {
|
||||
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
|
||||
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
|
||||
if (pkt != NULL) {
|
||||
matched =
|
||||
dlmstp_compare_data_expecting_reply(data,
|
||||
data_len, destination, &pkt->buffer[0],
|
||||
pkt->length, pkt->destination_mac);
|
||||
matched = dlmstp_compare_data_expecting_reply(data,
|
||||
data_len, destination, &pkt->buffer[0], pkt->length,
|
||||
pkt->destination_mac);
|
||||
} else {
|
||||
matched = false;
|
||||
}
|
||||
@@ -1219,17 +1221,15 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
if (pkt->data_expecting_reply) {
|
||||
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
|
||||
} else {
|
||||
frame_type =
|
||||
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
||||
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
||||
}
|
||||
MSTP_Send_Frame(frame_type, pkt->destination_mac,
|
||||
This_Station, (uint8_t *) & pkt->buffer[0],
|
||||
pkt->length);
|
||||
MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station,
|
||||
(uint8_t *)&pkt->buffer[0], pkt->length);
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
/* clear our flag we were holding for comparison */
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
/* clear the queue */
|
||||
(void) Ringbuf_Pop(&PDU_Queue, NULL);
|
||||
(void)Ringbuf_Pop(&PDU_Queue, NULL);
|
||||
} else if ((pkt != NULL) || timeout) {
|
||||
/* DeferredReply */
|
||||
/* If no reply will be available from the higher layers */
|
||||
@@ -1240,8 +1240,8 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* Any reply shall wait until this node receives the token. */
|
||||
/* Call MSTP_Send_Frame to transmit a Reply Postponed frame, */
|
||||
/* and enter the IDLE state. */
|
||||
MSTP_Send_Frame(FRAME_TYPE_REPLY_POSTPONED, destination,
|
||||
source, NULL, 0);
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_REPLY_POSTPONED, destination, source, NULL, 0);
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
/* clear our flag we were holding for comparison */
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
@@ -1268,19 +1268,19 @@ bool dlmstp_send_pdu_queue_full(void)
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, zero on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
|
||||
BACNET_NPDU_DATA * npdu_data, /* network information */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
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;
|
||||
struct mstp_pdu_packet *pkt;
|
||||
uint16_t i = 0;
|
||||
|
||||
pkt = (struct mstp_pdu_packet *) Ringbuf_Data_Peek(&PDU_Queue);
|
||||
pkt = (struct mstp_pdu_packet *)Ringbuf_Data_Peek(&PDU_Queue);
|
||||
if (pkt) {
|
||||
pkt->data_expecting_reply = npdu_data->data_expecting_reply;
|
||||
for (i = 0; i < pdu_len; i++) {
|
||||
@@ -1311,12 +1311,10 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
*
|
||||
* @return Return the length of the packet
|
||||
*/
|
||||
uint16_t dlmstp_receive(BACNET_ADDRESS * src,
|
||||
uint8_t * pdu,
|
||||
uint16_t max_pdu,
|
||||
unsigned timeout)
|
||||
uint16_t dlmstp_receive(
|
||||
BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout)
|
||||
{
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
bool transmitting = false;
|
||||
|
||||
(void)timeout;
|
||||
@@ -1401,8 +1399,7 @@ uint8_t dlmstp_mac_address(void)
|
||||
/* node, its value shall be 1. */
|
||||
void dlmstp_set_max_info_frames(uint8_t max_info_frames)
|
||||
{
|
||||
if ((max_info_frames >= 1) &&
|
||||
(max_info_frames <= MSTP_PDU_PACKET_COUNT)) {
|
||||
if ((max_info_frames >= 1) && (max_info_frames <= MSTP_PDU_PACKET_COUNT)) {
|
||||
Nmax_info_frames = max_info_frames;
|
||||
}
|
||||
|
||||
@@ -1433,13 +1430,13 @@ uint8_t dlmstp_max_master(void)
|
||||
return 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] = 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;
|
||||
@@ -1448,15 +1445,15 @@ void dlmstp_get_my_address(BACNET_ADDRESS * 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;
|
||||
}
|
||||
|
||||
+72
-74
@@ -1,26 +1,26 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 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) 2009 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 "board.h"
|
||||
#include "ioport.h"
|
||||
@@ -28,18 +28,18 @@
|
||||
#include "led.h"
|
||||
|
||||
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
|
||||
#define RS485_XPLAINED_LD1 IOPORT_CREATE_PIN(PORTC, 6)
|
||||
#define RS485_XPLAINED_LD2 IOPORT_CREATE_PIN(PORTC, 7)
|
||||
#define RS485_XPLAINED_LD3 IOPORT_CREATE_PIN(PORTC, 4)
|
||||
#define RS485_XPLAINED_LD4 IOPORT_CREATE_PIN(PORTC, 5)
|
||||
#define RS485_XPLAINED_LD1 IOPORT_CREATE_PIN(PORTC, 6)
|
||||
#define RS485_XPLAINED_LD2 IOPORT_CREATE_PIN(PORTC, 7)
|
||||
#define RS485_XPLAINED_LD3 IOPORT_CREATE_PIN(PORTC, 4)
|
||||
#define RS485_XPLAINED_LD4 IOPORT_CREATE_PIN(PORTC, 5)
|
||||
|
||||
static struct itimer Off_Delay_Timer[LEDS_MAX];
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Turn on an LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
* Description: Turn on an LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_on(uint8_t index)
|
||||
{
|
||||
switch (index) {
|
||||
@@ -64,10 +64,10 @@ void led_on(uint8_t index)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Turn off an LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
* Description: Turn off an LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_off(uint8_t index)
|
||||
{
|
||||
switch (index) {
|
||||
@@ -92,10 +92,10 @@ void led_off(uint8_t index)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Get the state of the LED
|
||||
* Returns: true if on, false if off.
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
* Description: Get the state of the LED
|
||||
* Returns: true if on, false if off.
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
bool led_state(uint8_t index)
|
||||
{
|
||||
switch (index) {
|
||||
@@ -115,10 +115,10 @@ bool led_state(uint8_t index)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Toggle the state of the setup LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
* Description: Toggle the state of the setup LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_toggle(uint8_t index)
|
||||
{
|
||||
if (led_state(index)) {
|
||||
@@ -129,12 +129,11 @@ void led_toggle(uint8_t index)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Delay before going off to give minimum brightness.
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_off_delay(uint8_t index,
|
||||
uint32_t delay_ms)
|
||||
* Description: Delay before going off to give minimum brightness.
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_off_delay(uint8_t index, uint32_t delay_ms)
|
||||
{
|
||||
if (index < LEDS_MAX) {
|
||||
timer_interval_start(&Off_Delay_Timer[index], delay_ms);
|
||||
@@ -142,12 +141,11 @@ void led_off_delay(uint8_t index,
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Turn on, and delay before going off.
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_on_interval(uint8_t index,
|
||||
uint16_t interval_ms)
|
||||
* Description: Turn on, and delay before going off.
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_on_interval(uint8_t index, uint16_t interval_ms)
|
||||
{
|
||||
if (index < LEDS_MAX) {
|
||||
led_on(index);
|
||||
@@ -156,13 +154,13 @@ void led_on_interval(uint8_t index,
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Task for blinking LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
* Description: Task for blinking LED
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_task(void)
|
||||
{
|
||||
uint8_t i; /* loop counter */
|
||||
uint8_t i; /* loop counter */
|
||||
|
||||
for (i = 0; i < LEDS_MAX; i++) {
|
||||
if (timer_interval_expired(&Off_Delay_Timer[i])) {
|
||||
@@ -173,27 +171,27 @@ void led_task(void)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Description: Initialize the LED hardware
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
* Description: Initialize the LED hardware
|
||||
* Returns: none
|
||||
* Notes: none
|
||||
*************************************************************************/
|
||||
void led_init(void)
|
||||
{
|
||||
uint8_t i; /* loop counter */
|
||||
uint8_t i; /* loop counter */
|
||||
|
||||
/* configure the LEDs for Rx and Tx indication */
|
||||
ioport_configure_pin(RS485_XPLAINED_LD1,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(RS485_XPLAINED_LD2,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(RS485_XPLAINED_LD3,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(RS485_XPLAINED_LD4,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(
|
||||
RS485_XPLAINED_LD1, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(
|
||||
RS485_XPLAINED_LD2, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(
|
||||
RS485_XPLAINED_LD3, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(
|
||||
RS485_XPLAINED_LD4, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
/* initialize the timers, while giving LEDs a brief test */
|
||||
for (i = 0; i < LEDS_MAX; i++) {
|
||||
led_on(i);
|
||||
led_off_delay(i,500);
|
||||
}
|
||||
led_off_delay(i, 500);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ int main(void)
|
||||
mstimer_init();
|
||||
rs485_init();
|
||||
led_init();
|
||||
adc_init();
|
||||
adc_init();
|
||||
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
|
||||
// Enable display backlight
|
||||
gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
|
||||
|
||||
@@ -88,8 +88,7 @@ unsigned long mstimer_now(void)
|
||||
*
|
||||
* @return true if successfully added and enabled
|
||||
*/
|
||||
void mstimer_callback(
|
||||
struct mstimer_callback_data_t *new_cb,
|
||||
void mstimer_callback(struct mstimer_callback_data_t *new_cb,
|
||||
mstimer_callback_function callback,
|
||||
unsigned long milliseconds)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||
* @date 2013
|
||||
* @brief Store and retrieve non-volatile data
|
||||
*
|
||||
*/
|
||||
* @file
|
||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||
* @date 2013
|
||||
* @brief Store and retrieve non-volatile data
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nvmdata.h"
|
||||
@@ -12,8 +12,8 @@
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
/**
|
||||
* Initializes the non-volatile memory module
|
||||
*/
|
||||
* Initializes the non-volatile memory module
|
||||
*/
|
||||
void nvm_data_init(void)
|
||||
{
|
||||
uint32_t device_id = 127;
|
||||
@@ -32,7 +32,7 @@ void nvm_data_init(void)
|
||||
}
|
||||
dlmstp_set_max_master(max_master);
|
||||
/* Get the device ID from the EEPROM */
|
||||
nvm_read(NVM_DEVICE_0, (uint8_t *) & device_id, sizeof(device_id));
|
||||
nvm_read(NVM_DEVICE_0, (uint8_t *)&device_id, sizeof(device_id));
|
||||
if (device_id < BACNET_MAX_INSTANCE) {
|
||||
Device_Set_Object_Instance_Number(device_id);
|
||||
} else {
|
||||
|
||||
+31
-39
@@ -41,18 +41,18 @@
|
||||
#include "rs485.h"
|
||||
|
||||
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
|
||||
#define RS485_RE IOPORT_CREATE_PIN(PORTC, 1)
|
||||
#define RS485_DE IOPORT_CREATE_PIN(PORTC, 0)
|
||||
#define RS485_TXD IOPORT_CREATE_PIN(PORTC, 3)
|
||||
#define RS485_RXD IOPORT_CREATE_PIN(PORTC, 2)
|
||||
#define RS485_USART USARTC0
|
||||
#define RS485_RE IOPORT_CREATE_PIN(PORTC, 1)
|
||||
#define RS485_DE IOPORT_CREATE_PIN(PORTC, 0)
|
||||
#define RS485_TXD IOPORT_CREATE_PIN(PORTC, 3)
|
||||
#define RS485_RXD IOPORT_CREATE_PIN(PORTC, 2)
|
||||
#define RS485_USART USARTC0
|
||||
#define RS485_TXC_vect USARTC0_TXC_vect
|
||||
#define RS485_RXC_vect USARTC0_RXC_vect
|
||||
#else
|
||||
#define RS485_RE IOPORT_CREATE_PIN(PORTE, 0)
|
||||
#define RS485_DE IOPORT_CREATE_PIN(PORTE, 0)
|
||||
#define RS485_TXD IOPORT_CREATE_PIN(PORTE, 3)
|
||||
#define RS485_RXD IOPORT_CREATE_PIN(PORTE, 2)
|
||||
#define RS485_RE IOPORT_CREATE_PIN(PORTE, 0)
|
||||
#define RS485_DE IOPORT_CREATE_PIN(PORTE, 0)
|
||||
#define RS485_TXD IOPORT_CREATE_PIN(PORTE, 3)
|
||||
#define RS485_RXD IOPORT_CREATE_PIN(PORTE, 2)
|
||||
#define RS485_USART USARTE0
|
||||
#define RS485_TXC_vect USARTE0_TXC_vect
|
||||
#define RS485_RXC_vect USARTE0_RXC_vect
|
||||
@@ -164,9 +164,9 @@ bool rs485_turnaround_elapsed(void)
|
||||
*
|
||||
* @return true if a byte is available
|
||||
*/
|
||||
bool rs485_byte_available(uint8_t * data_register)
|
||||
bool rs485_byte_available(uint8_t *data_register)
|
||||
{
|
||||
bool data_available = false; /* return value */
|
||||
bool data_available = false; /* return value */
|
||||
|
||||
if (FIFO_Empty(&Receive_Queue)) {
|
||||
led_off_delay(LED_RS485_RX, 2);
|
||||
@@ -202,14 +202,13 @@ bool rs485_frame_sent(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit one or more bytes on RS-485. Can be called while transmitting to add
|
||||
* additional bytes to transmit queue.
|
||||
*
|
||||
* @param buffer - array of one or more bytes to transmit
|
||||
* @param nbytes - number of bytes to transmit
|
||||
*/
|
||||
bool rs485_bytes_send(uint8_t * buffer,
|
||||
uint16_t nbytes)
|
||||
* Transmit one or more bytes on RS-485. Can be called while transmitting to
|
||||
* add additional bytes to transmit queue.
|
||||
*
|
||||
* @param buffer - array of one or more bytes to transmit
|
||||
* @param nbytes - number of bytes to transmit
|
||||
*/
|
||||
bool rs485_bytes_send(uint8_t *buffer, uint16_t nbytes)
|
||||
{
|
||||
bool status = false;
|
||||
bool start_required = false;
|
||||
@@ -234,8 +233,8 @@ bool rs485_bytes_send(uint8_t * buffer,
|
||||
}
|
||||
|
||||
/**
|
||||
* RS485 RX interrupt
|
||||
*/
|
||||
* RS485 RX interrupt
|
||||
*/
|
||||
ISR(RS485_RXC_vect)
|
||||
{
|
||||
unsigned char ch;
|
||||
@@ -246,8 +245,8 @@ ISR(RS485_RXC_vect)
|
||||
}
|
||||
|
||||
/**
|
||||
* RS485 TX interrupt
|
||||
*/
|
||||
* RS485 TX interrupt
|
||||
*/
|
||||
ISR(RS485_TXC_vect)
|
||||
{
|
||||
uint8_t ch;
|
||||
@@ -268,8 +267,7 @@ ISR(RS485_TXC_vect)
|
||||
*
|
||||
* @return baud - RS-485 baud rate in bits per second (bps)
|
||||
*/
|
||||
uint32_t rs485_baud_rate(
|
||||
void)
|
||||
uint32_t rs485_baud_rate(void)
|
||||
{
|
||||
return Baud_Rate;
|
||||
}
|
||||
@@ -281,8 +279,7 @@ uint32_t rs485_baud_rate(
|
||||
*
|
||||
* @return true if set and valid
|
||||
*/
|
||||
bool rs485_baud_rate_set(
|
||||
uint32_t baud)
|
||||
bool rs485_baud_rate_set(uint32_t baud)
|
||||
{
|
||||
bool valid = true;
|
||||
unsigned long frequency;
|
||||
@@ -295,7 +292,7 @@ bool rs485_baud_rate_set(
|
||||
case 76800:
|
||||
case 115200:
|
||||
frequency = sysclk_get_peripheral_bus_hz(&RS485_USART);
|
||||
valid = usart_set_baudrate (&RS485_USART, baud, frequency);
|
||||
valid = usart_set_baudrate(&RS485_USART, baud, frequency);
|
||||
if (valid) {
|
||||
Baud_Rate = baud;
|
||||
}
|
||||
@@ -308,7 +305,6 @@ bool rs485_baud_rate_set(
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the RS-485 UART interface, receive interrupts enabled
|
||||
*/
|
||||
@@ -318,22 +314,18 @@ void rs485_init(void)
|
||||
|
||||
/* initialize the Rx and Tx byte queues */
|
||||
FIFO_Init(&Receive_Queue, &Receive_Queue_Data[0],
|
||||
(unsigned) sizeof(Receive_Queue_Data));
|
||||
(unsigned)sizeof(Receive_Queue_Data));
|
||||
FIFO_Init(&Transmit_Queue, &Transmit_Queue_Data[0],
|
||||
(unsigned) sizeof(Transmit_Queue_Data));
|
||||
(unsigned)sizeof(Transmit_Queue_Data));
|
||||
/* initialize the silence timer */
|
||||
rs485_silence_reset();
|
||||
/* configure the TX pin */
|
||||
ioport_configure_pin(RS485_TXD,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
|
||||
ioport_configure_pin(RS485_TXD, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
|
||||
/* configure the RX pin */
|
||||
ioport_configure_pin(RS485_RXD,
|
||||
IOPORT_DIR_INPUT);
|
||||
ioport_configure_pin(RS485_RXD, IOPORT_DIR_INPUT);
|
||||
/* configure the RTS pins */
|
||||
ioport_configure_pin(RS485_RE,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(RS485_DE,
|
||||
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(RS485_RE, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
ioport_configure_pin(RS485_DE, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
|
||||
option.baudrate = Baud_Rate;
|
||||
option.charlength = USART_CHSIZE_8BIT_gc;
|
||||
option.paritytype = USART_PMODE_DISABLED_gc;
|
||||
|
||||
+70
-73
@@ -1,47 +1,47 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 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) 2009 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 "board.h"
|
||||
/* me */
|
||||
#include "stack.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* stack checking technique by Michael McTernan */
|
||||
/* With AVR gcc, two symbols are defined by the linker
|
||||
that can make this easy. These are _end and __stack
|
||||
which define the first free byte of SRAM after
|
||||
program variables, and the starting address of
|
||||
/* With AVR gcc, two symbols are defined by the linker
|
||||
that can make this easy. These are _end and __stack
|
||||
which define the first free byte of SRAM after
|
||||
program variables, and the starting address of
|
||||
the stack, respectively.
|
||||
|
||||
The stack starts at __stack, which is conventionally
|
||||
the highest byte of SRAM, and grows towards zero;
|
||||
_end will be somewhere between zero and __stack.
|
||||
If the stack ever falls below _end, it has almost
|
||||
The stack starts at __stack, which is conventionally
|
||||
the highest byte of SRAM, and grows towards zero;
|
||||
_end will be somewhere between zero and __stack.
|
||||
If the stack ever falls below _end, it has almost
|
||||
certainly corrupted program data.
|
||||
|
||||
The following C declarations gain access to these
|
||||
linker symbols:
|
||||
The following C declarations gain access to these
|
||||
linker symbols:
|
||||
*/
|
||||
extern uint8_t _end;
|
||||
extern uint8_t __stack;
|
||||
@@ -49,22 +49,20 @@ extern uint8_t __stack;
|
||||
/* canary value */
|
||||
#define STACK_CANARY (0xC5)
|
||||
|
||||
/* This is declared in such a way that AVR-libc will
|
||||
execute the assembly before the program has started
|
||||
running or configured the stack. It also runs at a
|
||||
point before some of the normal runtime setup,
|
||||
hence assembly should be used as C may not be
|
||||
fully reliable (this is discussed in the AVR libc manual).
|
||||
/* This is declared in such a way that AVR-libc will
|
||||
execute the assembly before the program has started
|
||||
running or configured the stack. It also runs at a
|
||||
point before some of the normal runtime setup,
|
||||
hence assembly should be used as C may not be
|
||||
fully reliable (this is discussed in the AVR libc manual).
|
||||
*/
|
||||
void stack_init(
|
||||
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
|
||||
void stack_init(void) __attribute__((naked)) __attribute__((section(".init1")));
|
||||
|
||||
/* The function itself simply fills the stack with the canary value,
|
||||
the idea being that stack usage will overwrite this with some
|
||||
other value, hence making stack usage detectable.
|
||||
/* The function itself simply fills the stack with the canary value,
|
||||
the idea being that stack usage will overwrite this with some
|
||||
other value, hence making stack usage detectable.
|
||||
*/
|
||||
void stack_init(
|
||||
void)
|
||||
void stack_init(void)
|
||||
{
|
||||
#if 0
|
||||
uint8_t *p = &_end;
|
||||
@@ -74,36 +72,40 @@ void stack_init(
|
||||
p++;
|
||||
}
|
||||
#else
|
||||
__asm volatile (
|
||||
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
|
||||
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
|
||||
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
|
||||
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
|
||||
__asm volatile(" ldi r30,lo8(_end)\n"
|
||||
" ldi r31,hi8(_end)\n"
|
||||
" ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
|
||||
" ldi r25,hi8(__stack)\n"
|
||||
" rjmp .cmp\n"
|
||||
".loop:\n"
|
||||
" st Z+,r24\n"
|
||||
".cmp:\n"
|
||||
" cpi r30,lo8(__stack)\n"
|
||||
" cpc r31,r25\n"
|
||||
" brlo .loop\n"
|
||||
" breq .loop" ::);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned stack_size(
|
||||
void)
|
||||
unsigned stack_size(void)
|
||||
{
|
||||
return (&__stack) - (&_end);
|
||||
}
|
||||
|
||||
uint8_t stack_byte(
|
||||
unsigned offset)
|
||||
uint8_t stack_byte(unsigned offset)
|
||||
{
|
||||
return *(&_end + offset);
|
||||
}
|
||||
|
||||
/* The following function can be used to count
|
||||
how many bytes of stack have not been overwritten.
|
||||
This function can be called at any time
|
||||
to check how much stack space has never been over written.
|
||||
If it returns 0, you are probably in trouble as
|
||||
all the stack has been used, most likely destroying
|
||||
some program variables.
|
||||
/* The following function can be used to count
|
||||
how many bytes of stack have not been overwritten.
|
||||
This function can be called at any time
|
||||
to check how much stack space has never been over written.
|
||||
If it returns 0, you are probably in trouble as
|
||||
all the stack has been used, most likely destroying
|
||||
some program variables.
|
||||
*/
|
||||
unsigned stack_unused(
|
||||
void)
|
||||
unsigned stack_unused(void)
|
||||
{
|
||||
uint8_t *p = &_end;
|
||||
unsigned count = 0;
|
||||
@@ -118,26 +120,21 @@ unsigned stack_unused(
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
void stack_init(
|
||||
void)
|
||||
void stack_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned stack_size(
|
||||
void)
|
||||
unsigned stack_size(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t stack_byte(
|
||||
unsigned offset)
|
||||
uint8_t stack_byte(unsigned offset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned stack_unused(
|
||||
void)
|
||||
unsigned stack_unused(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user