Feature/make pretty apps and ports (#80)

* Added pretty-apps and pretty-ports make targets

* pretty-fied apps folder C files

* Pretty-fied ports folder C and H files

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2020-04-30 10:13:11 -05:00
committed by GitHub
parent 0abcbea971
commit fdd49f1791
152 changed files with 9668 additions and 11674 deletions
+61 -59
View File
@@ -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
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Input Objects customize for your use */
@@ -44,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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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);
+1 -2
View File
@@ -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)
{
+9 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}