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 -61
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 <stdbool.h>
#include <stdint.h>
#include "hardware.h"
@@ -28,23 +28,23 @@
#include "adc.h"
/* prescale select bits */
#if (F_CPU >> 1) < 1000000
#define ADPS_8BIT (1)
#define ADPS_10BIT (3)
#if (F_CPU >> 1) < 1000000
#define ADPS_8BIT (1)
#define ADPS_10BIT (3)
#elif (F_CPU >> 2) < 1000000
#define ADPS_8BIT (2)
#define ADPS_10BIT (4)
#define ADPS_8BIT (2)
#define ADPS_10BIT (4)
#elif (F_CPU >> 3) < 1000000
#define ADPS_8BIT (3)
#define ADPS_10BIT (5)
#define ADPS_8BIT (3)
#define ADPS_10BIT (5)
#elif (F_CPU >> 4) < 1000000
#define ADPS_8BIT (4)
#define ADPS_10BIT (6)
#define ADPS_8BIT (4)
#define ADPS_10BIT (6)
#elif (F_CPU >> 5) < 1000000
#define ADPS_8BIT (5)
#define ADPS_10BIT (7)
#define ADPS_8BIT (5)
#define ADPS_10BIT (7)
#else
#error "ADC: F_CPU too large for accuracy."
#error "ADC: F_CPU too large for accuracy."
#endif
/* ADMUX: channel bits 0..4
@@ -59,54 +59,55 @@
ADATE = Auto Trigger Enable
*/
void adc_enable(
uint8_t index)
void adc_enable(uint8_t index)
{
index = index;
/* do nothing */
}
/**************************************************
* Description: Run a Analog to Digital conversion
* Returns: none
* Notes: none
**************************************************/
uint8_t adc_result_8bit(
uint8_t channel)
{ /* 0..7 = ADC0..ADC7, respectively */
uint8_t value = 0; /* return value */
* Description: Run a Analog to Digital conversion
* Returns: none
* Notes: none
**************************************************/
uint8_t adc_result_8bit(uint8_t channel)
{ /* 0..7 = ADC0..ADC7, respectively */
uint8_t value = 0; /* return value */
while (ADCSRA & (1 << ADSC));
while (ADCSRA & (1 << ADSC))
;
ADMUX = channel | (1 << ADLAR) | (0 << REFS1) | (1 << REFS0);
/* Delay needed for the stabilization of the ADC input voltage */
_delay_us(10);
/* Start the analog to digital conversion */
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | ADPS_8BIT;
/* Wait for the analog to digital conversion to complete */
while ((ADCSRA & (1 << ADIF)) == 0);
while ((ADCSRA & (1 << ADIF)) == 0)
;
value = ADCH;
return value;
}
/**************************************************
* Description: Run a Analog to Digital conversion
* Returns: none
* Notes: none
**************************************************/
uint16_t adc_result_10bit(
uint8_t channel)
{ /* 0..7 = ADC0..ADC7, respectively */
* Description: Run a Analog to Digital conversion
* Returns: none
* Notes: none
**************************************************/
uint16_t adc_result_10bit(uint8_t channel)
{ /* 0..7 = ADC0..ADC7, respectively */
uint16_t value = 0; /* return value */
while (ADCSRA & (1 << ADSC));
while (ADCSRA & (1 << ADSC))
;
ADMUX = channel | (0 << ADLAR) | (0 << REFS1) | (1 << REFS0);
/* Delay needed for the stabilization of the ADC input voltage */
_delay_us(10);
/* Start the analog to digital conversion */
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | ADPS_10BIT;
/* Wait for the analog to digital conversion to complete */
while ((ADCSRA & (1 << ADIF)) == 0);
while ((ADCSRA & (1 << ADIF)) == 0)
;
value = ADCL;
value |= (ADCH << 8);
@@ -114,12 +115,11 @@ uint16_t adc_result_10bit(
}
/**************************************************
* Description: Initializes the Analog to Digital Converter
* Returns: none
* Notes: none
**************************************************/
void adc_init(
void)
* Description: Initializes the Analog to Digital Converter
* Returns: none
* Notes: none
**************************************************/
void adc_init(void)
{
/* configure ADC for Free Running Mode - ADTS = 000 */
/* AIN1 is applied to the negative input of the Analog Comparator - ACME */
+42 -46
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 <stdbool.h>
#include <stdint.h>
#include "hardware.h"
@@ -28,23 +28,23 @@
#include "adc.h"
/* prescale select bits */
#if (F_CPU >> 1) < 1000000
#define ADPS_8BIT (1)
#define ADPS_10BIT (3)
#if (F_CPU >> 1) < 1000000
#define ADPS_8BIT (1)
#define ADPS_10BIT (3)
#elif (F_CPU >> 2) < 1000000
#define ADPS_8BIT (2)
#define ADPS_10BIT (4)
#define ADPS_8BIT (2)
#define ADPS_10BIT (4)
#elif (F_CPU >> 3) < 1000000
#define ADPS_8BIT (3)
#define ADPS_10BIT (5)
#define ADPS_8BIT (3)
#define ADPS_10BIT (5)
#elif (F_CPU >> 4) < 1000000
#define ADPS_8BIT (4)
#define ADPS_10BIT (6)
#define ADPS_8BIT (4)
#define ADPS_10BIT (6)
#elif (F_CPU >> 5) < 1000000
#define ADPS_8BIT (5)
#define ADPS_10BIT (7)
#define ADPS_8BIT (5)
#define ADPS_10BIT (7)
#else
#error "ADC: F_CPU too large for accuracy."
#error "ADC: F_CPU too large for accuracy."
#endif
/* Array of ADC results */
@@ -86,9 +86,8 @@ ISR(ADC_vect)
BIT_SET(ADCSRA, ADSC);
}
void adc_enable(
uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */
void adc_enable(uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */
if (Enabled_Channels) {
/* ADC interupt is already started */
BIT_SET(Enabled_Channels, index);
@@ -106,9 +105,8 @@ void adc_enable(
}
}
uint8_t adc_result_8bit(
uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */
uint8_t adc_result_8bit(uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */
uint8_t result = 0;
uint8_t sreg;
@@ -116,16 +114,15 @@ uint8_t adc_result_8bit(
adc_enable(index);
sreg = SREG;
__disable_interrupt();
result = (uint8_t) (Sample_Result[index] >> 2);
result = (uint8_t)(Sample_Result[index] >> 2);
SREG = sreg;
}
return result;
}
uint16_t adc_result_10bit(
uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */
uint16_t adc_result_10bit(uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */
uint16_t result = 0;
uint8_t sreg;
@@ -140,8 +137,7 @@ uint16_t adc_result_10bit(
return result;
}
void adc_init(
void)
void adc_init(void)
{
/* Initial channel selection */
/* ADLAR = Left Adjust Result
+43 -68
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 */
@@ -42,30 +42,16 @@
static float Present_Value[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;
@@ -77,8 +63,7 @@ void Analog_Input_Property_Lists(
return;
}
void Analog_Input_Init(
void)
void Analog_Input_Init(void)
{
return;
}
@@ -86,8 +71,7 @@ void Analog_Input_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(
uint32_t object_instance)
bool Analog_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_INPUTS)
return true;
@@ -96,24 +80,21 @@ bool Analog_Input_Valid_Instance(
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Count(
void)
unsigned Analog_Input_Count(void)
{
return MAX_ANALOG_INPUTS;
}
/* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance(
unsigned index)
uint32_t Analog_Input_Index_To_Instance(unsigned index)
{
return index;
}
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;
if (object_instance < MAX_ANALOG_INPUTS) {
@@ -124,8 +105,7 @@ 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;
@@ -136,9 +116,7 @@ float Analog_Input_Present_Value(
return value;
}
void Analog_Input_Present_Value_Set(
uint32_t object_instance,
float value)
void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
{
if (object_instance < MAX_ANALOG_INPUTS) {
Present_Value[object_instance] = value;
@@ -147,10 +125,9 @@ void Analog_Input_Present_Value_Set(
/* 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;
@@ -162,9 +139,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);
@@ -176,9 +152,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);
+53 -79
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Value Objects - customize for your use */
@@ -33,7 +33,7 @@
#include "bacnet/bacdcode.h"
#include "bacnet/bacenum.h"
#include "bacnet/bacapp.h"
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/wp.h"
#include "bacnet/basic/object/av.h"
#include "bacnet/basic/services.h"
@@ -46,17 +46,9 @@
static float Present_Value[MAX_ANALOG_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Value_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_Value_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_Value_Properties_Optional[] = {
#if 0
@@ -66,14 +58,10 @@ static const int Analog_Value_Properties_Optional[] = {
-1
};
static const int Analog_Value_Properties_Proprietary[] = {
-1
};
static const int Analog_Value_Properties_Proprietary[] = { -1 };
void Analog_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary)
const int **pRequired, const int **pOptional, const int **pProprietary)
{
if (pRequired)
*pRequired = Analog_Value_Properties_Required;
@@ -85,8 +73,7 @@ void Analog_Value_Property_Lists(
return;
}
void Analog_Value_Init(
void)
void Analog_Value_Init(void)
{
return;
}
@@ -94,8 +81,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Value_Valid_Instance(
uint32_t object_instance)
bool Analog_Value_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_VALUES)
return true;
@@ -105,8 +91,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Value_Count(
void)
unsigned Analog_Value_Count(void)
{
return MAX_ANALOG_VALUES;
}
@@ -114,8 +99,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance(
unsigned index)
uint32_t Analog_Value_Index_To_Instance(unsigned index)
{
return index;
}
@@ -123,8 +107,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index(
uint32_t object_instance)
unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ANALOG_VALUES;
@@ -134,8 +117,7 @@ unsigned Analog_Value_Instance_To_Index(
return index;
}
float Analog_Value_Present_Value(
uint32_t object_instance)
float Analog_Value_Present_Value(uint32_t object_instance)
{
float value = 0;
unsigned index = 0;
@@ -149,9 +131,7 @@ float Analog_Value_Present_Value(
}
bool Analog_Value_Present_Value_Set(
uint32_t object_instance,
float value,
uint8_t priority)
uint32_t object_instance, float value, uint8_t priority)
{
unsigned index = 0;
bool status = false;
@@ -160,8 +140,8 @@ bool Analog_Value_Present_Value_Set(
index = Analog_Value_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_VALUES) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value >= 0.0) && (value <= 100.0)) {
(priority != 6 /* reserved */) && (value >= 0.0) &&
(value <= 100.0)) {
Present_Value[index] = value;
/* Note: you could set the physical output here if we
are the highest priority.
@@ -176,10 +156,9 @@ bool Analog_Value_Present_Value_Set(
/* note: the object name must be unique within this device */
bool Analog_Value_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 */
unsigned index = 0;
bool status = false;
@@ -193,10 +172,9 @@ bool Analog_Value_Object_Name(
}
/* return apdu len, or -1 on error */
int Analog_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
float real_value = 1.414F;
BACNET_CHARACTER_STRING char_string = { 0 };
@@ -214,9 +192,8 @@ int Analog_Value_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], 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_Value_Object_Name(rpdata->object_instance, &char_string);
@@ -332,10 +309,9 @@ int Analog_Value_Read_Property(
}
/* returns true if successful */
bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
bool status = false; /* return value */
#if 0
unsigned int object_index = 0;
unsigned int priority = 0;
@@ -344,9 +320,8 @@ bool Analog_Value_Write_Property(
int len = 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 */
@@ -363,18 +338,17 @@ bool Analog_Value_Write_Property(
}
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code);
if (status) {
status =
Analog_Value_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
value.type.Real, wp_data->priority);
if (!status) {
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
/* Command priority 6 is reserved for use by Minimum
On/Off algorithm and may not be used for other
purposes in any object. */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
+42 -47
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2010 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) 2010 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>
/* hardware layer includes */
@@ -55,18 +55,16 @@ static uint8_t MSTP_MAC_Address;
static struct mstimer DCC_Timer;
#define DCC_CYCLE_SECONDS 1
static bool seeprom_version_test(
void)
static bool seeprom_version_test(void)
{
uint16_t version = 0;
uint16_t id = 0;
bool status = false;
int rv;
rv = seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *) & id, 2);
rv = seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
if (rv > 0) {
rv = seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *) & version,
2);
rv = seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2);
}
if ((rv > 0) && (id == SEEPROM_ID) && (version == SEEPROM_VERSION)) {
@@ -74,8 +72,8 @@ static bool seeprom_version_test(
} else if (rv > 0) {
version = SEEPROM_VERSION;
id = SEEPROM_ID;
seeprom_bytes_write(NV_SEEPROM_TYPE_0, (uint8_t *) & id, 2);
seeprom_bytes_write(NV_SEEPROM_VERSION_0, (uint8_t *) & version, 2);
seeprom_bytes_write(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
seeprom_bytes_write(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2);
} else {
while (1) {
/* SEEPROM is faulty! */
@@ -90,8 +88,8 @@ static void device_id_init(uint8_t mac)
uint32_t device_id = 0;
/* Get the device ID from the eeprom */
eeprom_bytes_read(NV_EEPROM_DEVICE_0, (uint8_t *) & device_id,
sizeof(device_id));
eeprom_bytes_read(
NV_EEPROM_DEVICE_0, (uint8_t *)&device_id, sizeof(device_id));
if (device_id < BACNET_MAX_INSTANCE) {
Device_Set_Object_Instance_Number(device_id);
} else {
@@ -100,8 +98,7 @@ static void device_id_init(uint8_t mac)
}
}
void bacnet_init(
void)
void bacnet_init(void)
{
uint8_t max_master = 0;
@@ -121,33 +118,31 @@ void bacnet_init(
Device_Init(NULL);
device_id_init(MSTP_MAC_Address);
/* 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 shutup 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);
/* Hello World! */
Send_I_Am(&Handler_Transmit_Buffer[0]);
}
static uint8_t PDUBuffer[MAX_MPDU];
void bacnet_task(
void)
void bacnet_task(void)
{
uint8_t mstp_mac_address;
uint16_t pdu_len;
+42 -66
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Input Objects customize for your use */
@@ -42,30 +42,16 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_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_POLARITY,
-1
};
static const int Binary_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_POLARITY, -1 };
static const int Binary_Input_Properties_Optional[] = {
-1
};
static const int Binary_Input_Properties_Optional[] = { -1 };
static const int Binary_Input_Properties_Proprietary[] = {
-1
};
static const int Binary_Input_Properties_Proprietary[] = { -1 };
void Binary_Input_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary)
const int **pRequired, const int **pOptional, const int **pProprietary)
{
if (pRequired) {
*pRequired = Binary_Input_Properties_Required;
@@ -80,8 +66,7 @@ void Binary_Input_Property_Lists(
return;
}
void Binary_Input_Init(
void)
void Binary_Input_Init(void)
{
unsigned i;
@@ -91,8 +76,7 @@ void Binary_Input_Init(
}
/* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance(
uint32_t object_instance)
bool Binary_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_INPUTS)
return true;
@@ -101,15 +85,13 @@ bool Binary_Input_Valid_Instance(
}
/* we simply have 0-n object instances. */
unsigned Binary_Input_Count(
void)
unsigned Binary_Input_Count(void)
{
return MAX_BINARY_INPUTS;
}
/* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance(
unsigned index)
uint32_t Binary_Input_Index_To_Instance(unsigned index)
{
return index;
}
@@ -117,8 +99,7 @@ uint32_t Binary_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_INPUTS;
@@ -128,8 +109,7 @@ unsigned Binary_Input_Instance_To_Index(
return index;
}
BACNET_BINARY_PV Binary_Input_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0;
@@ -143,8 +123,7 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
}
bool Binary_Input_Present_Value_Set(
uint32_t object_instance,
BACNET_BINARY_PV value)
uint32_t object_instance, BACNET_BINARY_PV value)
{
unsigned index = 0;
@@ -158,10 +137,9 @@ bool Binary_Input_Present_Value_Set(
}
bool Binary_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;
if (object_instance < MAX_BINARY_INPUTS) {
@@ -174,10 +152,9 @@ bool Binary_Input_Object_Name(
/* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string = { 0 };
BACNET_POLARITY polarity = POLARITY_NORMAL;
BACNET_BINARY_PV value = BINARY_INACTIVE;
@@ -191,9 +168,8 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], 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:
Binary_Input_Object_Name(rpdata->object_instance, &char_string);
+46 -60
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>
@@ -35,10 +35,7 @@
#include "bacnet/basic/object/device.h"
#include "bname.h"
static bool bacnet_name_isvalid(
uint8_t encoding,
uint8_t length,
char *str)
static bool bacnet_name_isvalid(uint8_t encoding, uint8_t length, char *str)
{
bool valid = false;
@@ -55,32 +52,27 @@ static bool bacnet_name_isvalid(
}
bool bacnet_name_save(
uint16_t offset,
uint8_t encoding,
char *str,
uint8_t length)
uint16_t offset, uint8_t encoding, char *str, uint8_t length)
{
uint8_t buffer[NV_EEPROM_NAME_SIZE] = { 0 };
uint8_t i = 0;
if (bacnet_name_isvalid(encoding, length, str)) {
eeprom_bytes_write(NV_EEPROM_NAME_LENGTH(offset), &length, 1);
eeprom_bytes_write(NV_EEPROM_NAME_ENCODING(offset),
(uint8_t *) & encoding, 1);
eeprom_bytes_write(
NV_EEPROM_NAME_ENCODING(offset), (uint8_t *)&encoding, 1);
for (i = 0; i < length; i++) {
buffer[i] = str[i];
}
eeprom_bytes_write(NV_EEPROM_NAME_STRING(offset), &buffer[0],
NV_EEPROM_NAME_SIZE);
eeprom_bytes_write(
NV_EEPROM_NAME_STRING(offset), &buffer[0], NV_EEPROM_NAME_SIZE);
return true;
}
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;
@@ -92,13 +84,12 @@ bool bacnet_name_set(
return bacnet_name_save(offset, encoding, str, length);
}
bool bacnet_name_write_unique(
uint16_t offset,
bool bacnet_name_write_unique(uint16_t offset,
BACNET_OBJECT_TYPE 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;
@@ -113,8 +104,8 @@ bool bacnet_name_write_unique(
} else if (length <= NV_EEPROM_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 */
@@ -145,11 +136,10 @@ bool bacnet_name_write_unique(
}
/* 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)
bool bacnet_name_write(uint16_t offset,
BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code)
{
bool status = false;
size_t length = 0;
@@ -176,18 +166,14 @@ bool bacnet_name_write(
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)
uint16_t offset, BACNET_CHARACTER_STRING *char_string, char *default_string)
{
uint8_t encoding = 0;
uint8_t length = 0;
@@ -195,8 +181,8 @@ void bacnet_name(
eeprom_bytes_read(NV_EEPROM_NAME_ENCODING(offset), &encoding, 1);
eeprom_bytes_read(NV_EEPROM_NAME_LENGTH(offset), &length, 1);
eeprom_bytes_read(NV_EEPROM_NAME_STRING(offset), (uint8_t *) & name,
NV_EEPROM_NAME_SIZE);
eeprom_bytes_read(
NV_EEPROM_NAME_STRING(offset), (uint8_t *)&name, NV_EEPROM_NAME_SIZE);
if (bacnet_name_isvalid(encoding, length, name)) {
characterstring_init(char_string, encoding, &name[0], length);
} else if (default_string) {
+96 -134
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* 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.
*
*********************************************************************/
/* Binary Output Objects - customize for your use */
@@ -31,7 +31,7 @@
#include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacenum.h"
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/config.h" /* the custom stuff */
#include "bacnet/wp.h"
#include "hardware.h"
#include "led.h"
@@ -55,34 +55,18 @@ static uint8_t Out_Of_Service[MAX_BINARY_OUTPUTS];
static uint8_t Polarity[MAX_BINARY_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Output_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_POLARITY,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
static const int Binary_Output_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_POLARITY, PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT, -1 };
static const int Binary_Output_Properties_Optional[] = {
PROP_ACTIVE_TEXT,
PROP_INACTIVE_TEXT,
-1
};
static const int Binary_Output_Properties_Optional[] = { PROP_ACTIVE_TEXT,
PROP_INACTIVE_TEXT, -1 };
static const int Binary_Output_Properties_Proprietary[] = {
-1
};
static const int Binary_Output_Properties_Proprietary[] = { -1 };
void Binary_Output_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary)
const int **pRequired, const int **pOptional, const int **pProprietary)
{
if (pRequired)
*pRequired = Binary_Output_Properties_Required;
@@ -95,8 +79,7 @@ void Binary_Output_Property_Lists(
}
/* we simply have 0-n object instances. */
bool Binary_Output_Valid_Instance(
uint32_t object_instance)
bool Binary_Output_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_OUTPUTS)
return true;
@@ -105,22 +88,19 @@ bool Binary_Output_Valid_Instance(
}
/* we simply have 0-n object instances. */
unsigned Binary_Output_Count(
void)
unsigned Binary_Output_Count(void)
{
return MAX_BINARY_OUTPUTS;
}
/* we simply have 0-n object instances. */
uint32_t Binary_Output_Index_To_Instance(
unsigned index)
uint32_t Binary_Output_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. */
unsigned Binary_Output_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_OUTPUTS;
@@ -130,8 +110,7 @@ unsigned Binary_Output_Instance_To_Index(
return index;
}
static BACNET_BINARY_PV Present_Value(
unsigned int index)
static BACNET_BINARY_PV Present_Value(unsigned int index)
{
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
BACNET_BINARY_PV current_value = RELINQUISH_DEFAULT;
@@ -139,9 +118,9 @@ static BACNET_BINARY_PV Present_Value(
if (index < MAX_BINARY_OUTPUTS) {
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
current_value = (BACNET_BINARY_PV) Binary_Output_Level[index][i];
current_value = (BACNET_BINARY_PV)Binary_Output_Level[index][i];
if (current_value != BINARY_NULL) {
value = (BACNET_BINARY_PV) Binary_Output_Level[index][i];
value = (BACNET_BINARY_PV)Binary_Output_Level[index][i];
break;
}
}
@@ -150,8 +129,7 @@ static BACNET_BINARY_PV Present_Value(
return value;
}
BACNET_BINARY_PV Binary_Output_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t object_instance)
{
unsigned index = 0;
@@ -161,17 +139,15 @@ BACNET_BINARY_PV Binary_Output_Present_Value(
}
bool Binary_Output_Present_Value_Set(
uint32_t instance,
BACNET_BINARY_PV binary_value,
unsigned priority)
{ /* 0..15 */
uint32_t instance, BACNET_BINARY_PV binary_value, unsigned priority)
{ /* 0..15 */
bool status = false;
if (instance < MAX_BINARY_OUTPUTS) {
if (priority < BACNET_MAX_PRIORITY) {
Binary_Output_Level[instance][priority] = (uint8_t) binary_value;
Binary_Output_Level[instance][priority] = (uint8_t)binary_value;
seeprom_bytes_write(NV_SEEPROM_BINARY_OUTPUT(instance,
NV_SEEPROM_BO_PRIORITY_ARRAY_1 + priority),
NV_SEEPROM_BO_PRIORITY_ARRAY_1 + priority),
&Binary_Output_Level[instance][priority], 1);
status = true;
}
@@ -180,17 +156,16 @@ bool Binary_Output_Present_Value_Set(
return status;
}
bool Binary_Output_Polarity_Set(
uint32_t instance,
BACNET_POLARITY polarity)
bool Binary_Output_Polarity_Set(uint32_t instance, BACNET_POLARITY polarity)
{
bool status = false;
if (instance < MAX_BINARY_OUTPUTS) {
if (polarity < MAX_POLARITY) {
Polarity[instance] = polarity;
seeprom_bytes_write(NV_SEEPROM_BINARY_OUTPUT(instance,
NV_SEEPROM_BO_POLARITY), &Polarity[instance], 1);
seeprom_bytes_write(
NV_SEEPROM_BINARY_OUTPUT(instance, NV_SEEPROM_BO_POLARITY),
&Polarity[instance], 1);
status = true;
}
}
@@ -198,31 +173,28 @@ bool Binary_Output_Polarity_Set(
return status;
}
BACNET_POLARITY Binary_Output_Polarity(
uint32_t instance)
BACNET_POLARITY Binary_Output_Polarity(uint32_t instance)
{
BACNET_POLARITY polarity = POLARITY_NORMAL;
if (instance < MAX_BINARY_OUTPUTS) {
polarity = (BACNET_POLARITY) Polarity[instance];
polarity = (BACNET_POLARITY)Polarity[instance];
}
return polarity;
}
void Binary_Output_Out_Of_Service_Set(
uint32_t instance,
bool flag)
void Binary_Output_Out_Of_Service_Set(uint32_t instance, bool flag)
{
if (instance < MAX_BINARY_OUTPUTS) {
Out_Of_Service[instance] = flag;
seeprom_bytes_write(NV_SEEPROM_BINARY_OUTPUT(instance,
NV_SEEPROM_BO_OUT_OF_SERVICE), &Out_Of_Service[instance], 1);
seeprom_bytes_write(
NV_SEEPROM_BINARY_OUTPUT(instance, NV_SEEPROM_BO_OUT_OF_SERVICE),
&Out_Of_Service[instance], 1);
}
}
bool Binary_Output_Out_Of_Service(
uint32_t instance)
bool Binary_Output_Out_Of_Service(uint32_t instance)
{
bool flag = false;
@@ -235,10 +207,9 @@ bool Binary_Output_Out_Of_Service(
/* note: the object name must be unique within this device */
bool Binary_Output_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;
if (object_instance < MAX_BINARY_OUTPUTS) {
@@ -250,11 +221,10 @@ bool Binary_Output_Object_Name(
}
/* return apdu len, or -1 on error */
int Binary_Output_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string = { 0 };
BACNET_CHARACTER_STRING char_string = { 0 };
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
@@ -270,9 +240,8 @@ int Binary_Output_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:
Binary_Output_Object_Name(rpdata->object_instance, &char_string);
@@ -312,8 +281,7 @@ int Binary_Output_Read_Property(
object_index =
Binary_Output_Instance_To_Index(rpdata->object_instance);
apdu_len =
encode_application_enumerated(&apdu[0],
Polarity[object_index]);
encode_application_enumerated(&apdu[0], Polarity[object_index]);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
@@ -327,14 +295,13 @@ int Binary_Output_Read_Property(
Binary_Output_Instance_To_Index(rpdata->object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
present_value = (BACNET_BINARY_PV)
Binary_Output_Level[object_index][i];
present_value =
(BACNET_BINARY_PV)Binary_Output_Level[object_index][i];
if (present_value == BINARY_NULL) {
len = encode_application_null(&apdu[apdu_len]);
} else {
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
len = encode_application_enumerated(
&apdu[apdu_len], present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
@@ -351,14 +318,13 @@ int Binary_Output_Read_Property(
Binary_Output_Instance_To_Index(rpdata->object_instance);
if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
present_value = (BACNET_BINARY_PV)
Binary_Output_Level[object_index][rpdata->array_index -
1];
Binary_Output_Level[object_index]
[rpdata->array_index - 1];
if (present_value == BINARY_NULL) {
apdu_len = encode_application_null(&apdu[apdu_len]);
} else {
apdu_len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
apdu_len = encode_application_enumerated(
&apdu[apdu_len], present_value);
}
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -399,19 +365,17 @@ int Binary_Output_Read_Property(
}
/* returns true if successful */
bool Binary_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
bool status = false; /* return value */
unsigned int priority = 0;
BACNET_BINARY_PV level = BINARY_NULL;
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 */
@@ -430,19 +394,19 @@ bool Binary_Output_Write_Property(
case PROP_PRESENT_VALUE:
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) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(priority != 6 /* reserved */) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV) value.type.Enumerated;
level = (BACNET_BINARY_PV)value.type.Enumerated;
priority--;
Binary_Output_Present_Value_Set(wp_data->object_instance,
level, priority);
Binary_Output_Present_Value_Set(
wp_data->object_instance, level, priority);
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
@@ -456,21 +420,20 @@ bool Binary_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code);
if (status) {
level = BINARY_NULL;
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Output_Present_Value_Set
(wp_data->object_instance, level, priority);
Binary_Output_Present_Value_Set(
wp_data->object_instance, level, priority);
} else if (priority == 6) {
status = false;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
/* Command priority 6 is reserved for use by Minimum
On/Off algorithm and may not be used for other
purposes in any object. */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
@@ -482,22 +445,21 @@ bool Binary_Output_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) {
Binary_Output_Out_Of_Service_Set(wp_data->object_instance,
value.type.Boolean);
Binary_Output_Out_Of_Service_Set(
wp_data->object_instance, value.type.Boolean);
}
break;
case PROP_POLARITY:
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) {
if (value.type.Enumerated < MAX_POLARITY) {
Binary_Output_Polarity_Set(wp_data->object_instance,
(BACNET_POLARITY) value.type.Enumerated);
(BACNET_POLARITY)value.type.Enumerated);
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -528,8 +490,7 @@ bool Binary_Output_Write_Property(
return status;
}
void Binary_Output_Init(
void)
void Binary_Output_Init(void)
{
unsigned i, j;
@@ -541,14 +502,15 @@ void Binary_Output_Init(
if (Polarity[i] >= MAX_POLARITY) {
Binary_Output_Polarity_Set(i, POLARITY_NORMAL);
}
seeprom_bytes_read(NV_SEEPROM_BINARY_OUTPUT(i,
NV_SEEPROM_BO_OUT_OF_SERVICE), &Out_Of_Service[i], 1);
seeprom_bytes_read(
NV_SEEPROM_BINARY_OUTPUT(i, NV_SEEPROM_BO_OUT_OF_SERVICE),
&Out_Of_Service[i], 1);
if (Out_Of_Service[i] > 1) {
Binary_Output_Out_Of_Service_Set(i, false);
}
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
seeprom_bytes_read(NV_SEEPROM_BINARY_OUTPUT(i,
NV_SEEPROM_BO_PRIORITY_ARRAY_1 + j),
seeprom_bytes_read(
NV_SEEPROM_BINARY_OUTPUT(i, NV_SEEPROM_BO_PRIORITY_ARRAY_1 + j),
&Binary_Output_Level[i][j], 1);
}
}
+140 -156
View File
@@ -1,35 +1,33 @@
/*****************************************************************************
*
* Atmel Corporation
*
* File : main.c
* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5)
* Revision : $Revision: 1.7 $
* Date : $Date: Tuesday, June 07, 200 $
* Updated by : $Author: raapeland $
*
* Support mail : avr@atmel.com
*
* Target platform : All AVRs with bootloader support
*
* AppNote : AVR109 - Self-programming
*
* Description : This Program allows an AVR with bootloader capabilities to
* Read/write its own Flash/EEprom. To enter Programming mode
* an input pin is checked. If this pin is pulled low, programming mode
* is entered. If not, normal execution is done from $0000
* "reset" vector in Application area.
*
* Preparations : Use the preprocessor.xls file for obtaining a customized
* defines.h file and linker-file code-segment definition for
* the device you are compiling for.
****************************************************************************/
*
* Atmel Corporation
*
* File : main.c
* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5)
* Revision : $Revision: 1.7 $
* Date : $Date: Tuesday, June 07, 200 $
* Updated by : $Author: raapeland $
*
* Support mail : avr@atmel.com
*
* Target platform : All AVRs with bootloader support
*
* AppNote : AVR109 - Self-programming
*
* Description : This Program allows an AVR with bootloader capabilities to
* Read/write its own Flash/EEprom. To enter Programming mode
* an input pin is checked. If this pin is pulled low,
*programming mode is entered. If not, normal execution is done from $0000
* "reset" vector in Application area.
*
* Preparations : Use the preprocessor.xls file for obtaining a customized
* defines.h file and linker-file code-segment definition for
* the device you are compiling for.
****************************************************************************/
#include "defines.h"
#include "serial.h"
#include "flash.h"
/* Uncomment the following to save code space */
/*#define REMOVE_AVRPROG_SUPPORT */
/*#define REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */
@@ -52,70 +50,66 @@
#endif /* LARGE_MEMORY */
#ifndef REMOVE_BLOCK_SUPPORT
unsigned char BlockLoad(
unsigned int size,
unsigned char mem,
ADDR_T * address);
void BlockRead(
unsigned int size,
unsigned char mem,
ADDR_T * address);
unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address);
void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address);
/* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n = PAGESIZE, where n=1,2,3... */
/* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n =
* PAGESIZE, where n=1,2,3... */
#define BLOCKSIZE PAGESIZE
#endif /* REMOVE_BLOCK_SUPPORT */
#ifdef __ICCAVR__
__C_task void main(
void)
__C_task void main(void)
#else /* ! __ICCAVR__ */
int main(
void)
int main(void)
#endif /* __ICCAVR__ */
{
ADDR_T address;
unsigned int temp_int;
unsigned char val;
/* Initialization */
void (
*funcptr) (
void) = 0x0000; /* Set up function pointer to RESET vector. */
PROGPORT |= (1 << PROG_NO); /* Enable pull-up on PROG_NO line on PROGPORT. */
initbootuart(); /* Initialize UART. */
void (*funcptr)(void) =
0x0000; /* Set up function pointer to RESET vector. */
PROGPORT |=
(1 << PROG_NO); /* Enable pull-up on PROG_NO line on PROGPORT. */
initbootuart(); /* Initialize UART. */
/* Branch to bootloader or application code? */
if (!(PROGPIN & (1 << PROG_NO))) { /* If PROGPIN is pulled low, enter programmingmode. */
if (!(PROGPIN & (1 << PROG_NO))) { /* If PROGPIN is pulled low, enter
programmingmode. */
/* Main loop */
for (;;) {
val = recchar(); /* Wait for command character. */
val = recchar(); /* Wait for command character. */
/* Check autoincrement status. */
if (val == 'a') {
sendchar('Y'); /* Yes, we do autoincrement. */
sendchar('Y'); /* Yes, we do autoincrement. */
}
/* Set address. */
else if (val == 'A') { /* Set address... *//* NOTE: Flash addresses are given in words, not bytes. */
address = (recchar() << 8) | recchar(); /* Read address high and low byte. */
else if (val == 'A') {
/* Set address... */ /* NOTE: Flash addresses are given in
words, not bytes. */
address = (recchar() << 8) |
recchar(); /* Read address high and low byte. */
sendchar('\r'); /* Send OK back. */
}
/* Chip erase. */
else if (val == 'e') {
for (address = 0; address < APP_END; address += PAGESIZE) { /* NOTE: Here we use address as a byte-address, not word-address, for convenience. */
for (address = 0; address < APP_END; address +=
PAGESIZE) { /* NOTE: Here we use address as a byte-address,
not word-address, for convenience. */
_WAIT_FOR_SPM();
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
_PAGE_ERASE(address);
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
}
@@ -124,25 +118,23 @@ int main(
#ifndef REMOVE_BLOCK_SUPPORT
/* Check block load support. */
else if (val == 'b') {
sendchar('Y'); /* Report block load supported. */
sendchar((BLOCKSIZE >> 8) & 0xFF); /* MSB first. */
sendchar(BLOCKSIZE & 0xFF); /* Report BLOCKSIZE (bytes). */
sendchar('Y'); /* Report block load supported. */
sendchar((BLOCKSIZE >> 8) & 0xFF); /* MSB first. */
sendchar(BLOCKSIZE & 0xFF); /* Report BLOCKSIZE (bytes). */
}
/* Start block load. */
else if (val == 'B') {
temp_int = (recchar() << 8) | recchar(); /* Get block size. */
val = recchar(); /* Get memtype. */
sendchar(BlockLoad(temp_int, val, &address)); /* Block load. */
temp_int = (recchar() << 8) | recchar(); /* Get block size. */
val = recchar(); /* Get memtype. */
sendchar(BlockLoad(temp_int, val, &address)); /* Block load. */
}
/* Start block read. */
else if (val == 'g') {
temp_int = (recchar() << 8) | recchar(); /* Get block size. */
val = recchar(); /* Get memtype */
BlockRead(temp_int, val, &address); /* Block read */
temp_int = (recchar() << 8) | recchar(); /* Get block size. */
val = recchar(); /* Get memtype */
BlockRead(temp_int, val, &address); /* Block read */
}
#endif /* REMOVE_BLOCK_SUPPORT */
@@ -153,53 +145,58 @@ int main(
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION();
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 1));
sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 0));
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
address++; /* Auto-advance to next Flash word. */
address++; /* Auto-advance to next Flash word. */
}
/* Write program memory, low byte. */
else if (val == 'c') { /* NOTE: Always use this command before sending high byte. */
temp_int = recchar(); /* Get low byte for later _FILL_TEMP_WORD. */
else if (val == 'c') { /* NOTE: Always use this command before
sending high byte. */
temp_int =
recchar(); /* Get low byte for later _FILL_TEMP_WORD. */
sendchar('\r'); /* Send OK back. */
}
/* Write program memory, high byte. */
else if (val == 'C') {
temp_int |= (recchar() << 8); /* Get and insert high byte. */
temp_int |= (recchar() << 8); /* Get and insert high byte. */
_WAIT_FOR_SPM();
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
_FILL_TEMP_WORD((address << 1), temp_int); /* Convert word-address to byte-address and fill. */
_FILL_TEMP_WORD(
(address << 1), temp_int); /* Convert word-address to
byte-address and fill. */
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
address++; /* Auto-advance to next Flash word. */
address++; /* Auto-advance to next Flash word. */
sendchar('\r'); /* Send OK back. */
}
/* Write page. */
else if (val == 'm') {
if (address >= (APP_END >> 1)) { /* Protect bootloader area. */
if (address >= (APP_END >> 1)) { /* Protect bootloader area. */
sendchar('?');
} else {
_WAIT_FOR_SPM();
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
_PAGE_WRITE(address << 1); /* Convert word-address to byte-address and write. */
_PAGE_WRITE(address << 1); /* Convert word-address to
byte-address and write. */
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
}
@@ -211,26 +208,26 @@ int main(
/* Write EEPROM memory. */
else if (val == 'D') {
_WAIT_FOR_SPM();
EEARL = address; /* Setup EEPROM address. */
EEARL = address; /* Setup EEPROM address. */
EEARH = (address >> 8);
EEDR = recchar(); /* Get byte. */
EECR |= (1 << EEMWE); /* Write byte. */
EEDR = recchar(); /* Get byte. */
EECR |= (1 << EEMWE); /* Write byte. */
EECR |= (1 << EEWE);
while (EECR & (1 << EEWE)) /* Wait for write operation to finish. */
while (EECR &
(1 << EEWE)) /* Wait for write operation to finish. */
;
address++; /* Auto-advance to next EEPROM byte. */
address++; /* Auto-advance to next EEPROM byte. */
sendchar('\r'); /* Send OK back. */
}
/* Read EEPROM memory. */
else if (val == 'd') {
EEARL = address; /* Setup EEPROM address. */
EEARL = address; /* Setup EEPROM address. */
EEARH = (address >> 8);
EECR |= (1 << EERE); /* Read byte... */
EECR |= (1 << EERE); /* Read byte... */
sendchar(EEDR); /* ...and send it back. */
address++; /* Auto-advance to next EEPROM byte. */
address++; /* Auto-advance to next EEPROM byte. */
}
#endif /* REMOVE_EEPROM_BYTE_SUPPORT */
@@ -238,7 +235,7 @@ int main(
/* Write lockbits. */
else if (val == 'l') {
_WAIT_FOR_SPM();
_SET_LOCK_BITS(recchar()); /* Read and set lock bits. */
_SET_LOCK_BITS(recchar()); /* Read and set lock bits. */
sendchar('\r'); /* Send OK back. */
}
#if defined(_GET_LOCK_BITS)
@@ -248,21 +245,18 @@ int main(
sendchar(_GET_LOCK_BITS());
}
/* Read fuse bits. */
else if (val == 'F') {
_WAIT_FOR_SPM();
sendchar(_GET_LOW_FUSES());
}
/* Read high fuse bits. */
else if (val == 'N') {
_WAIT_FOR_SPM();
sendchar(_GET_HIGH_FUSES());
}
/* Read extended fuse bits. */
else if (val == 'Q') {
_WAIT_FOR_SPM();
@@ -277,42 +271,40 @@ int main(
sendchar('\r'); /* Nothing special to do, just answer OK. */
}
/* Exit bootloader. */
else if (val == 'E') {
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION();
sendchar('\r');
funcptr(); /* Jump to Reset vector 0x0000 in Application Section. */
funcptr(); /* Jump to Reset vector 0x0000 in Application
Section. */
}
/* Get programmer type. */
else if (val == 'p') {
sendchar('S'); /* Answer 'SERIAL'. */
sendchar('S'); /* Answer 'SERIAL'. */
}
/* Return supported device codes. */
else if (val == 't') {
#if PARTCODE+0 > 0
sendchar(PARTCODE); /* Supports only this device, of course. */
#if PARTCODE + 0 > 0
sendchar(PARTCODE); /* Supports only this device, of course. */
#endif /* PARTCODE */
sendchar(0); /* Send list terminator. */
sendchar(0); /* Send list terminator. */
}
/* Set LED, clear LED and set device type. */
else if ((val == 'x') || (val == 'y') || (val == 'T')) {
recchar(); /* Ignore the command and it's parameter. */
recchar(); /* Ignore the command and it's parameter. */
sendchar('\r'); /* Send OK back. */
}
#endif /* REMOVE_AVRPROG_SUPPORT */
/* Return programmer identifier. */
else if (val == 'S') {
sendchar('A'); /* Return 'AVRBOOT'. */
sendchar('V'); /* Software identifier (aka programmer signature) is always 7 characters. */
sendchar('A'); /* Return 'AVRBOOT'. */
sendchar('V'); /* Software identifier (aka programmer signature)
is always 7 characters. */
sendchar('R');
sendchar('B');
sendchar('O');
@@ -320,14 +312,12 @@ int main(
sendchar('T');
}
/* Return software version. */
else if (val == 'V') {
sendchar('1');
sendchar('5');
}
/* Return signature bytes. */
else if (val == 's') {
sendchar(SIGNATURE_BYTE_3);
@@ -335,25 +325,20 @@ int main(
sendchar(SIGNATURE_BYTE_1);
}
/* The last command to accept is ESC (synchronization). */
else if (val != 0x1b) { /* If not ESC, then it is unrecognized... */
else if (val != 0x1b) { /* If not ESC, then it is unrecognized... */
sendchar('?');
}
} /* end: for(;;) */
} /* end: for(;;) */
} else {
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION();
funcptr(); /* Jump to Reset vector 0x0000 in Application Section. */
funcptr(); /* Jump to Reset vector 0x0000 in Application Section. */
}
} /* end: main */
} /* end: main */
#ifndef REMOVE_BLOCK_SUPPORT
unsigned char BlockLoad(
unsigned int size,
unsigned char mem,
ADDR_T * address)
unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address)
{
unsigned char buffer[BLOCKSIZE];
unsigned int data;
@@ -368,51 +353,54 @@ unsigned char BlockLoad(
/* Then program the EEPROM */
_WAIT_FOR_SPM();
for (tempaddress = 0; tempaddress < size; tempaddress++) {
EEARL = *address; /* Setup EEPROM address */
EEARL = *address; /* Setup EEPROM address */
EEARH = ((*address) >> 8);
EEDR = buffer[tempaddress]; /* Get byte. */
EECR |= (1 << EEMWE); /* Write byte. */
EECR |= (1 << EEMWE); /* Write byte. */
EECR |= (1 << EEWE);
while (EECR & (1 << EEWE)) /* Wait for write operation to finish. */
while (EECR & (1 << EEWE)) /* Wait for write operation to finish. */
;
(*address)++; /* Select next EEPROM byte */
(*address)++; /* Select next EEPROM byte */
}
return '\r'; /* Report programming OK */
return '\r'; /* Report programming OK */
}
/* Flash memory type. */
else if (mem == 'F') { /* NOTE: For flash programming, 'address' is given in words. */
(*address) <<= 1; /* Convert address to bytes temporarily. */
tempaddress = (*address); /* Store address in page. */
else if (mem ==
'F') { /* NOTE: For flash programming, 'address' is given in words. */
(*address) <<= 1; /* Convert address to bytes temporarily. */
tempaddress = (*address); /* Store address in page. */
do {
data = recchar();
data |= (recchar() << 8);
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
_FILL_TEMP_WORD(*address, data);
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
(*address) += 2; /* Select next word in memory. */
size -= 2; /* Reduce number of bytes to write by two. */
(*address) += 2; /* Select next word in memory. */
size -= 2; /* Reduce number of bytes to write by two. */
} while (size); /* Loop until all bytes written. */
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
_PAGE_WRITE(tempaddress);
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION();
(*address) >>= 1; /* Convert address back to Flash words again. */
return '\r'; /* Report programming OK */
(*address) >>= 1; /* Convert address back to Flash words again. */
return '\r'; /* Report programming OK */
}
/* Invalid memory type? */
@@ -421,46 +409,42 @@ unsigned char BlockLoad(
}
}
void BlockRead(
unsigned int size,
unsigned char mem,
ADDR_T * address)
void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address)
{
/* EEPROM memory type. */
if (mem == 'E') { /* Read EEPROM */
if (mem == 'E') { /* Read EEPROM */
do {
EEARL = *address; /* Setup EEPROM address */
EEARL = *address; /* Setup EEPROM address */
EEARH = ((*address) >> 8);
(*address)++; /* Select next EEPROM byte */
EECR |= (1 << EERE); /* Read EEPROM */
sendchar(EEDR); /* Transmit EEPROM dat ato PC */
(*address)++; /* Select next EEPROM byte */
EECR |= (1 << EERE); /* Read EEPROM */
sendchar(EEDR); /* Transmit EEPROM dat ato PC */
size--; /* Decrease number of bytes to read */
size--; /* Decrease number of bytes to read */
} while (size); /* Repeat until all block has been read */
}
/* Flash memory type. */
else if (mem == 'F') {
(*address) <<= 1; /* Convert address to bytes temporarily. */
(*address) <<= 1; /* Convert address to bytes temporarily. */
do {
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif
sendchar(_LOAD_PROGRAM_MEMORY(*address));
sendchar(_LOAD_PROGRAM_MEMORY((*address) + 1));
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#pragma diag_default = Pe1053 /* Back to default. */
#endif
(*address) += 2; /* Select next word in memory. */
size -= 2; /* Subtract two bytes from number of bytes to read */
(*address) += 2; /* Select next word in memory. */
size -= 2; /* Subtract two bytes from number of bytes to read */
} while (size); /* Repeat until all block has been read */
(*address) >>= 1; /* Convert address back to Flash words again. */
(*address) >>= 1; /* Convert address back to Flash words again. */
}
}
#endif /* REMOVE_BLOCK_SUPPORT */
/* end of file */
+28 -31
View File
@@ -1,44 +1,41 @@
/*****************************************************************************
*
* Atmel Corporation
*
* File : serial.c
* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5)
* Revision : $Revision: 1.7 $
* Date : $Date: Tuesday, June 07, 200 $
* Updated by : $Author: raapeland $
*
* Support mail : avr@atmel.com
*
* Target platform : All AVRs with bootloader support
*
* AppNote : AVR109 - Self-programming
*
* Description : UART communication routines
****************************************************************************/
*
* Atmel Corporation
*
* File : serial.c
* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5)
* Revision : $Revision: 1.7 $
* Date : $Date: Tuesday, June 07, 200 $
* Updated by : $Author: raapeland $
*
* Support mail : avr@atmel.com
*
* Target platform : All AVRs with bootloader support
*
* AppNote : AVR109 - Self-programming
*
* Description : UART communication routines
****************************************************************************/
#include "defines.h"
void initbootuart(
void)
void initbootuart(void)
{
BAUD_RATE_LOW_REG = BRREG_VALUE;
UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) | (1 << ENABLE_TRANSMITTER_BIT); /* enable receive and transmit */
UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) |
(1 << ENABLE_TRANSMITTER_BIT); /* enable receive and transmit */
}
void sendchar(
unsigned char c)
void sendchar(unsigned char c)
{
UART_DATA_REG = c; /* prepare transmission */
while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT))); /* wait until byte sendt */
UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); /* delete TXCflag */
UART_DATA_REG = c; /* prepare transmission */
while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT)))
; /* wait until byte sendt */
UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); /* delete TXCflag */
}
unsigned char recchar(
void)
unsigned char recchar(void)
{
while (!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT))); /* wait for data */
while (!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT)))
; /* wait for data */
return UART_DATA_REG;
}
+139 -212
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -50,10 +50,8 @@
static const char *BACnet_Version = BACNET_VERSION_TEXT;
/* 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;
@@ -65,31 +63,28 @@ static struct my_object_functions {
read_property_function Object_Read_Property;
write_property_function Object_Write_Property;
rpm_property_lists_function Object_RPM_List;
} Object_Table[] = {
{
OBJECT_DEVICE, NULL, /* don't init - recursive! */
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}, {
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, NULL,
Analog_Input_Property_Lists}, {
OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
Analog_Value_Object_Name, Analog_Value_Read_Property,
Analog_Value_Write_Property, Analog_Value_Property_Lists}, {
OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
Binary_Input_Object_Name, Binary_Input_Read_Property, NULL,
Binary_Input_Property_Lists}, {
OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
Binary_Output_Object_Name, Binary_Output_Read_Property,
Binary_Output_Write_Property, Binary_Output_Property_Lists}, {
MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
} Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
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 },
{ 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, NULL,
Analog_Input_Property_Lists },
{ OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
Analog_Value_Object_Name, Analog_Value_Read_Property,
Analog_Value_Write_Property, Analog_Value_Property_Lists },
{ OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
Binary_Input_Object_Name, Binary_Input_Read_Property, NULL,
Binary_Input_Property_Lists },
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
Binary_Output_Object_Name, Binary_Output_Read_Property,
Binary_Output_Write_Property, Binary_Output_Property_Lists },
{ MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };
/* note: you really only need to define variables for
properties that are writable or that may change.
@@ -102,44 +97,20 @@ static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
static const char *Reinit_Password = "rehmite";
/* 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[] = {
512,
513,
9600,
-1
};
static const int Device_Properties_Proprietary[] = { 512, 513, 9600, -1 };
static struct my_object_functions *Device_Objects_Find_Functions(
BACNET_OBJECT_TYPE Object_Type)
@@ -161,8 +132,7 @@ static struct my_object_functions *Device_Objects_Find_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;
@@ -183,8 +153,7 @@ int Device_Read_Property(
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;
@@ -212,8 +181,7 @@ bool Device_Write_Property(
return status;
}
static unsigned my_property_list_count(
const int *pList)
static unsigned my_property_list_count(const int *pList)
{
unsigned property_count = 0;
@@ -228,8 +196,7 @@ static unsigned my_property_list_count(
}
/* 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)
{
@@ -252,25 +219,23 @@ void Device_Objects_Property_List(
}
/* Fetch the counts if available otherwise zero them */
pPropertyList->Required.count =
pPropertyList->Required.pList ==
NULL ? 0 : my_property_list_count(pPropertyList->Required.pList);
pPropertyList->Required.count = pPropertyList->Required.pList == NULL
? 0
: my_property_list_count(pPropertyList->Required.pList);
pPropertyList->Optional.count =
pPropertyList->Optional.pList ==
NULL ? 0 : my_property_list_count(pPropertyList->Optional.pList);
pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL
? 0
: my_property_list_count(pPropertyList->Optional.pList);
pPropertyList->Proprietary.count =
pPropertyList->Proprietary.pList ==
NULL ? 0 : my_property_list_count(pPropertyList->Proprietary.pList);
pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL
? 0
: my_property_list_count(pPropertyList->Proprietary.pList);
return;
}
void Device_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary)
const int **pRequired, const int **pOptional, const int **pProprietary)
{
if (pRequired)
*pRequired = Device_Properties_Required;
@@ -282,23 +247,20 @@ void Device_Property_Lists(
return;
}
unsigned Device_Count(
void)
unsigned Device_Count(void)
{
return 1;
}
uint32_t Device_Index_To_Instance(
unsigned index)
uint32_t Device_Index_To_Instance(unsigned index)
{
index = 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);
@@ -306,8 +268,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;
@@ -319,8 +280,7 @@ bool Device_Object_Name(
return status;
}
bool Device_Reinitialize(
BACNET_REINITIALIZE_DEVICE_DATA * rd_data)
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
{
bool status = false;
@@ -363,20 +323,18 @@ bool Device_Reinitialize(
return status;
}
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(
void)
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(void)
{
return Reinitialize_State;
}
void Device_Init(
object_functions_t * object_table)
void Device_Init(object_functions_t *object_table)
{
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) {
@@ -389,14 +347,12 @@ void Device_Init(
}
/* methods to manipulate the data */
uint32_t Device_Object_Instance_Number(
void)
uint32_t Device_Object_Instance_Number(void)
{
return Object_Instance_Number;
}
bool Device_Set_Object_Instance_Number(
uint32_t object_id)
bool Device_Set_Object_Instance_Number(uint32_t object_id)
{
bool status = true; /* return value */
@@ -411,21 +367,17 @@ bool Device_Set_Object_Instance_Number(
return status;
}
bool Device_Valid_Object_Instance_Number(
uint32_t object_id)
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
{
return (Object_Instance_Number == object_id);
}
BACNET_DEVICE_STATUS Device_System_Status(
void)
BACNET_DEVICE_STATUS Device_System_Status(void)
{
return System_Status;
}
int Device_Set_System_Status(
BACNET_DEVICE_STATUS status,
bool local)
int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
{
/*return value - 0 = ok, -1 = bad value, -2 = not allowed */
int result = -1;
@@ -438,34 +390,29 @@ int Device_Set_System_Status(
return result;
}
uint16_t Device_Vendor_Identifier(
void)
uint16_t Device_Vendor_Identifier(void)
{
return BACNET_VENDOR_ID;
}
BACNET_SEGMENTATION Device_Segmentation_Supported(
void)
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
{
return SEGMENTATION_NONE;
}
uint32_t Device_Database_Revision(
void)
uint32_t Device_Database_Revision(void)
{
return Database_Revision;
}
void Device_Inc_Database_Revision(
void)
void Device_Inc_Database_Revision(void)
{
Database_Revision++;
}
/* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */
unsigned Device_Object_List_Count(
void)
unsigned Device_Object_List_Count(void)
{
unsigned count = 0; /* number of objects */
struct my_object_functions *pObject = NULL;
@@ -483,9 +430,7 @@ unsigned Device_Object_List_Count(
}
bool Device_Object_List_Identifier(
uint32_t array_index,
BACNET_OBJECT_TYPE *object_type,
uint32_t * instance)
uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
{
bool status = false;
uint32_t count = 0;
@@ -516,10 +461,9 @@ bool Device_Object_List_Identifier(
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;
@@ -533,7 +477,7 @@ bool Device_Valid_Object_Name(
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))) {
@@ -553,13 +497,12 @@ bool Device_Valid_Object_Name(
}
bool Device_Valid_Object_Id(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance)
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);
}
@@ -567,10 +510,9 @@ bool Device_Valid_Object_Id(
return status;
}
bool Device_Object_Name_Copy(
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;
@@ -584,11 +526,10 @@ bool Device_Object_Name_Copy(
}
/* 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;
@@ -603,11 +544,10 @@ int Device_Read_Property_Local(
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);
@@ -625,15 +565,14 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_LOCATION:
bacnet_name(NV_EEPROM_DEVICE_LOCATION, &char_string,
"default location");
bacnet_name(
NV_EEPROM_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, BACNET_VENDOR_NAME);
@@ -664,16 +603,15 @@ int Device_Read_Property_Local(
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;
@@ -683,7 +621,7 @@ int Device_Read_Property_Local(
bitstring_init(&bit_string);
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
/* initialize all the object types to not-supported */
bitstring_set_bit(&bit_string, (uint8_t) i, false);
bitstring_set_bit(&bit_string, (uint8_t)i, false);
}
/* set the object types with objects to supported */
i = 0;
@@ -707,11 +645,10 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) {
if (Device_Object_List_Identifier(i, &object_type,
&instance)) {
len =
encode_application_object_id(&apdu[apdu_len],
object_type, instance);
if (Device_Object_List_Identifier(
i, &object_type, &instance)) {
len = encode_application_object_id(
&apdu[apdu_len], object_type, instance);
apdu_len += len;
/* assume next one is the same size as this one */
/* can we all fit into the APDU? */
@@ -731,11 +668,10 @@ int Device_Read_Property_Local(
}
}
} else {
if (Device_Object_List_Identifier(rpdata->array_index,
&object_type, &instance))
apdu_len =
encode_application_object_id(&apdu[0], object_type,
instance);
if (Device_Object_List_Identifier(
rpdata->array_index, &object_type, &instance))
apdu_len = encode_application_object_id(
&apdu[0], object_type, instance);
else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -747,9 +683,8 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len =
encode_application_enumerated(&apdu[0],
Device_Segmentation_Supported());
apdu_len = encode_application_enumerated(
&apdu[0], Device_Segmentation_Supported());
break;
case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
@@ -761,14 +696,12 @@ int Device_Read_Property_Local(
/* FIXME: encode the list here, if it exists */
break;
case PROP_DATABASE_REVISION:
apdu_len =
encode_application_unsigned(&apdu[0],
Device_Database_Revision());
apdu_len = encode_application_unsigned(
&apdu[0], Device_Database_Revision());
break;
case PROP_MAX_INFO_FRAMES:
apdu_len =
encode_application_unsigned(&apdu[0],
dlmstp_max_info_frames());
encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
break;
case PROP_MAX_MASTER:
apdu_len =
@@ -781,8 +714,7 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
break;
case 9600:
apdu_len =
encode_application_unsigned(&apdu[0], rs485_baud_rate());
apdu_len = encode_application_unsigned(&apdu[0], rs485_baud_rate());
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -801,18 +733,16 @@ int Device_Read_Property_Local(
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 */
@@ -827,14 +757,14 @@ bool Device_Write_Property_Local(
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))) {
eeprom_bytes_write(NV_EEPROM_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 {
@@ -879,8 +809,7 @@ bool Device_Write_Property_Local(
break;
case PROP_OBJECT_NAME:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status =
bacnet_name_write_unique(NV_EEPROM_DEVICE_NAME,
status = bacnet_name_write_unique(NV_EEPROM_DEVICE_NAME,
wp_data->object_type, wp_data->object_instance,
&value.type.Character_String, &wp_data->error_class,
&wp_data->error_code);
@@ -891,8 +820,7 @@ bool Device_Write_Property_Local(
break;
case PROP_DESCRIPTION:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status =
bacnet_name_write(NV_EEPROM_DEVICE_DESCRIPTION,
status = bacnet_name_write(NV_EEPROM_DEVICE_DESCRIPTION,
&value.type.Character_String, &wp_data->error_class,
&wp_data->error_code);
} else {
@@ -902,8 +830,7 @@ bool Device_Write_Property_Local(
break;
case PROP_LOCATION:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status =
bacnet_name_write(NV_EEPROM_DEVICE_LOCATION,
status = bacnet_name_write(NV_EEPROM_DEVICE_LOCATION,
&value.type.Character_String, &wp_data->error_class,
&wp_data->error_code);
} else {
+86 -107
View File
@@ -68,19 +68,19 @@ static 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. */
@@ -182,7 +182,11 @@ static 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 {
@@ -194,26 +198,22 @@ struct mstp_pdu_packet {
static struct mstp_pdu_packet PDU_Buffer[MSTP_PDU_PACKET_COUNT];
static RING_BUFFER PDU_Queue;
bool dlmstp_init(
char *ifname)
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;
}
void dlmstp_cleanup(
void)
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;
@@ -236,11 +236,10 @@ void dlmstp_fill_bacnet_address(
}
}
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)
{
@@ -261,9 +260,8 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the request data */
request.address.mac[0] = src_address;
request.address.mac_len = 1;
offset =
npdu_decode(&request_pdu[0], NULL, &request.address,
&request.npdu_data);
offset = npdu_decode(
&request_pdu[0], NULL, &request.address, &request.npdu_data);
if (request.npdu_data.network_layer_message) {
return false;
}
@@ -280,8 +278,7 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */
reply.address.mac[0] = dest_address;
reply.address.mac_len = 1;
offset =
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) {
return false;
}
@@ -322,7 +319,8 @@ static bool dlmstp_compare_data_expecting_reply(
return false;
}
}
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) {
if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false;
}
#if 0
@@ -354,16 +352,16 @@ static bool dlmstp_compare_data_expecting_reply(
/* (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 */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t *data, /* any data to be sent - may be null */
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;
@@ -401,8 +399,7 @@ static void MSTP_Send_Frame(
rs485_rts_enable(false);
}
static void MSTP_Receive_Frame_FSM(
void)
static void MSTP_Receive_Frame_FSM(void)
{
/* stores the latest received data octet */
uint8_t DataRegister = 0;
@@ -638,8 +635,7 @@ static void MSTP_Receive_Frame_FSM(
#ifdef MSTP_DEBUG_STATES
static MSTP_MASTER_STATE Master_State_Log[128];
static unsigned master_state_log_index = 0;
void log_master_state(
MSTP_MASTER_STATE state)
void log_master_state(MSTP_MASTER_STATE state)
{
Master_State_Log[master_state_log_index] = state;
master_state_log_index++;
@@ -652,8 +648,7 @@ void log_master_state(
#endif
/* returns true if we need to transition immediately */
static bool MSTP_Master_Node_FSM(
void)
static bool MSTP_Master_Node_FSM(void)
{
/* The number of frames sent by this node during a single token hold. */
/* When this counter reaches the value Nmax_info_frames, the node must */
@@ -758,9 +753,8 @@ static bool MSTP_Master_Node_FSM(
}
break;
case FRAME_TYPE_TEST_REQUEST:
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE,
SourceAddress, This_Station, &InputBuffer[0],
DataLength);
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress,
This_Station, &InputBuffer[0], DataLength);
break;
case FRAME_TYPE_TEST_RESPONSE:
default:
@@ -785,14 +779,14 @@ static bool MSTP_Master_Node_FSM(
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:
@@ -812,7 +806,7 @@ static bool MSTP_Master_Node_FSM(
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:
@@ -924,8 +918,8 @@ static bool MSTP_Master_Node_FSM(
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;
@@ -939,7 +933,7 @@ static bool MSTP_Master_Node_FSM(
/* 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;
@@ -947,10 +941,10 @@ static bool MSTP_Master_Node_FSM(
/* 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;
}
@@ -971,8 +965,8 @@ static bool MSTP_Master_Node_FSM(
/* 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. */
@@ -1049,15 +1043,15 @@ static bool MSTP_Master_Node_FSM(
/* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (MSTP_Flag.ReceivedValidFrame == true) {
if ((DestinationAddress == This_Station)
&& (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
if ((DestinationAddress == 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;
@@ -1122,12 +1116,11 @@ static bool MSTP_Master_Node_FSM(
/* a proprietary frame that expects a reply is received. */
timeout = rs485_silence_time_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(&InputBuffer[0],
DataLength, SourceAddress, &pkt->buffer[0],
pkt->length, pkt->destination_mac);
matched = dlmstp_compare_data_expecting_reply(
&InputBuffer[0], DataLength, SourceAddress,
&pkt->buffer[0], pkt->length, pkt->destination_mac);
} else {
matched = false;
}
@@ -1144,17 +1137,15 @@ static bool MSTP_Master_Node_FSM(
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 */
@@ -1180,8 +1171,7 @@ static bool MSTP_Master_Node_FSM(
return transition_now;
}
static void MSTP_Slave_Node_FSM(
void)
static void MSTP_Slave_Node_FSM(void)
{
/* packet from the PDU Queue */
struct mstp_pdu_packet *pkt;
@@ -1215,9 +1205,8 @@ static void MSTP_Slave_Node_FSM(
}
} else if (MSTP_Flag.ReceivePacketPending) {
if (!Ringbuf_Empty(&PDU_Queue)) {
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
matched =
dlmstp_compare_data_expecting_reply(&InputBuffer[0],
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
matched = dlmstp_compare_data_expecting_reply(&InputBuffer[0],
DataLength, SourceAddress, &pkt->buffer[0], pkt->length,
pkt->destination_mac);
if (matched) {
@@ -1235,8 +1224,8 @@ static void MSTP_Slave_Node_FSM(
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);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
(uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&PDU_Queue, NULL);
}
/* clear our flag we were holding for comparison */
MSTP_Flag.ReceivePacketPending = false;
@@ -1252,17 +1241,16 @@ static void MSTP_Slave_Node_FSM(
}
/* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
{ /* number of bytes of data */
int bytes_sent = 0;
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++) {
@@ -1284,13 +1272,12 @@ int dlmstp_send_pdu(
}
/* Return the length of the packet */
uint16_t dlmstp_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
/* set the input buffer to the same data storage for zero copy */
if (!InputBuffer) {
@@ -1335,8 +1322,7 @@ uint16_t dlmstp_receive(
return pdu_len;
}
void dlmstp_set_mac_address(
uint8_t mac_address)
void dlmstp_set_mac_address(uint8_t mac_address)
{
/* Master Nodes can only have address 0-127 */
if (mac_address <= 127) {
@@ -1348,8 +1334,7 @@ void dlmstp_set_mac_address(
return;
}
uint8_t dlmstp_mac_address(
void)
uint8_t dlmstp_mac_address(void)
{
return This_Station;
}
@@ -1361,8 +1346,7 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(
uint8_t max_info_frames)
void dlmstp_set_max_info_frames(uint8_t max_info_frames)
{
if (max_info_frames >= MSTP_PDU_PACKET_COUNT) {
Nmax_info_frames = max_info_frames;
@@ -1371,8 +1355,7 @@ void dlmstp_set_max_info_frames(
return;
}
uint8_t dlmstp_max_info_frames(
void)
uint8_t dlmstp_max_info_frames(void)
{
return Nmax_info_frames;
}
@@ -1382,8 +1365,7 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(
uint8_t max_master)
void dlmstp_set_max_master(uint8_t max_master)
{
if (max_master <= 127) {
if (This_Station <= max_master) {
@@ -1394,20 +1376,18 @@ void dlmstp_set_max_master(
return;
}
uint8_t dlmstp_max_master(
void)
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;
@@ -1416,16 +1396,15 @@ void dlmstp_get_my_address(
return;
}
void dlmstp_get_broadcast_address(
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
dest->mac_len = 1;
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* always zero when DNET is broadcast */
dest->len = 0; /* always zero when DNET is broadcast */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
+29 -31
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 <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -29,13 +29,12 @@
/* Internal EEPROM of the AVR - http://supp.iar.com/Support/?note=45745 */
int eeprom_bytes_read(
uint16_t eeaddr, /* EEPROM starting memory address (offset of zero) */
uint8_t * buf, /* data to store */
uint16_t eeaddr, /* EEPROM starting memory address (offset of zero) */
uint8_t *buf, /* data to store */
int len)
{ /* number of bytes of data to read */
int count = 0; /* return value */
{ /* number of bytes of data to read */
int count = 0; /* return value */
while (len) {
__EEGET(buf[count], eeaddr);
@@ -47,11 +46,10 @@ int eeprom_bytes_read(
return count;
}
int eeprom_bytes_write(
uint16_t eeaddr, /* EEPROM starting memory address */
uint8_t * buf, /* data to send */
int eeprom_bytes_write(uint16_t eeaddr, /* EEPROM starting memory address */
uint8_t *buf, /* data to send */
int len)
{ /* number of bytes of data */
{ /* number of bytes of data */
int count = 0;
while (len) {
+56 -56
View File
@@ -1,27 +1,27 @@
/************************************************************************
*
* 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 "hardware.h"
#if defined(__GNUC__) && (__GNUC__ >= 4)
@@ -53,39 +53,39 @@ FUSES = {
any fuses listed below are cleared fuses,
or are CKSEL or SUT bits that are zero. */
.low = (FUSE_CKSEL3 & FUSE_SUT1),
/* == HIGH FUSE or HFUSE settings == */
/* BOOTRST: Enable Bootloader Reset Vector */
/* EESAVE: Enable preserve EEPROM on Chip Erase */
/* WDTON: Enable watchdog timer always on */
/* SPIEN: Enable Serial Program and Data Downloading */
/* JTAGEN: Enable JTAG */
/* OCDEN: Enable OCD */
/* BOOTSZ configuration:
BOOTSZ1 BOOTSZ0 Boot Size
------- ------- ---------
1 1 512
1 0 1024
0 1 2048
0 0 4096
*/
/* note: fuses are enabled by clearing the bit, so
any fuses listed below are cleared fuses,
or are BOOTSZ bits that are zero. */
.high = (FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
/* == EXTENDED FUSE or EFUSE settings == */
/* BODLEVEL configuration
BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage
--------- --------- --------- --------
1 1 1 disabled
1 1 0 1.8V
1 0 1 2.7V
1 0 0 4.3V
*/
/* note: fuses are enabled by clearing the bit, so
any fuses listed below are cleared fuses,
or are BODLEVEL bits that are zero. */
/* Brown-out detection VCC=4.3V */
.extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0)
/* == HIGH FUSE or HFUSE settings == */
/* BOOTRST: Enable Bootloader Reset Vector */
/* EESAVE: Enable preserve EEPROM on Chip Erase */
/* WDTON: Enable watchdog timer always on */
/* SPIEN: Enable Serial Program and Data Downloading */
/* JTAGEN: Enable JTAG */
/* OCDEN: Enable OCD */
/* BOOTSZ configuration:
BOOTSZ1 BOOTSZ0 Boot Size
------- ------- ---------
1 1 512
1 0 1024
0 1 2048
0 0 4096
*/
/* note: fuses are enabled by clearing the bit, so
any fuses listed below are cleared fuses,
or are BOOTSZ bits that are zero. */
.high = (FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
/* == EXTENDED FUSE or EFUSE settings == */
/* BODLEVEL configuration
BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage
--------- --------- --------- --------
1 1 1 disabled
1 1 0 1.8V
1 0 1 2.7V
1 0 0 4.3V
*/
/* note: fuses are enabled by clearing the bit, so
any fuses listed below are cleared fuses,
or are BODLEVEL bits that are zero. */
/* Brown-out detection VCC=4.3V */
.extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0)
};
/* AVR lock bits - unlocked */
+24 -25
View File
@@ -1,33 +1,32 @@
/**************************************************************************
*
* 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 "hardware.h"
/* me */
#include "init.h"
void init(
void)
void init(void)
{
/* clear the MCU Status Register */
MCUSR = 0;
+31 -38
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* 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 <stdbool.h>
#include "hardware.h"
@@ -43,8 +43,7 @@ static struct mstimer Debounce_Timer;
#if BDK_V1_HACK
/* version 1 BDK workaournd for floating inputs */
static void input_switch_workaround(
void)
static void input_switch_workaround(void)
{
/* configure the port pins for the switch - as outputs */
BIT_SET(DDRA, DDA0);
@@ -76,8 +75,7 @@ static void input_switch_workaround(
#endif
/* debounce the inputs */
void input_task(
void)
void input_task(void)
{
uint8_t value;
static uint8_t old_address = 0;
@@ -100,7 +98,7 @@ void input_task(
Address_Switch = old_address;
}
old_address = value;
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
/* pins used are PB3, PB2, PB1 */
value = BITMASK_CHECK(PINB, 0x0E);
value >>= 1;
@@ -119,20 +117,17 @@ void input_task(
#endif
}
uint8_t input_address(
void)
uint8_t input_address(void)
{
return Address_Switch;
}
uint8_t input_rotary_value(
uint8_t index)
uint8_t input_rotary_value(uint8_t index)
{
return Buttons;
}
bool input_button_value(
uint8_t index)
bool input_button_value(uint8_t index)
{
bool value = false;
@@ -159,9 +154,7 @@ bool input_button_value(
return value;
}
void input_init(
void)
void input_init(void)
{
/* configure the port pins for the switch */
BIT_CLEAR(DDRA, DDA0);
@@ -180,7 +173,7 @@ void input_init(
BIT_SET(PORTA, PORTA5);
BIT_SET(PORTA, PORTA6);
/* configure the port pins for rotary switch inputs */
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_CLEAR(DDRB, DDB1);
BIT_CLEAR(DDRB, DDB2);
BIT_CLEAR(DDRB, DDB3);
+71 -81
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 "hardware.h"
#include "bacnet/basic/sys/mstimer.h"
@@ -33,12 +33,11 @@
static struct mstimer Off_Delay_Timer[MAX_LEDS];
/*************************************************************************
* Description: Turn on an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_on(
uint8_t index)
* Description: Turn on an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_on(uint8_t index)
{
switch (index) {
case 0:
@@ -48,14 +47,14 @@ void led_on(
BIT_SET(PORTD, PD6);
break;
case 2:
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_SET(PORTB, PB0);
#else
BIT_SET(PORTC, PC7);
#endif
break;
case 3:
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_SET(PORTB, PB4);
#else
BIT_SET(PORTC, PC6);
@@ -70,12 +69,11 @@ void led_on(
}
/*************************************************************************
* Description: Turn off an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_off(
uint8_t index)
* Description: Turn off an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_off(uint8_t index)
{
switch (index) {
case 0:
@@ -85,14 +83,14 @@ void led_off(
BIT_CLEAR(PORTD, PD6);
break;
case 2:
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_CLEAR(PORTB, PB0);
#else
BIT_CLEAR(PORTC, PC7);
#endif
break;
case 3:
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_CLEAR(PORTB, PB4);
#else
BIT_CLEAR(PORTC, PC6);
@@ -107,12 +105,11 @@ void led_off(
}
/*************************************************************************
* Description: Get the state of the LED
* Returns: true if on, false if off.
* Notes: none
*************************************************************************/
bool led_state(
uint8_t index)
* Description: Get the state of the LED
* Returns: true if on, false if off.
* Notes: none
*************************************************************************/
bool led_state(uint8_t index)
{
switch (index) {
case 0:
@@ -120,13 +117,13 @@ bool led_state(
case 1:
return (BIT_CHECK(PIND, PIND6));
case 2:
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
return (BIT_CHECK(PINB, PINC0));
#else
return (BIT_CHECK(PINC, PINC7));
#endif
case 3:
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
return (BIT_CHECK(PINB, PINC4));
#else
return (BIT_CHECK(PINC, PINC6));
@@ -139,12 +136,11 @@ bool led_state(
}
/*************************************************************************
* Description: Toggle the state of the setup LED
* Returns: none
* Notes: none
*************************************************************************/
void led_toggle(
uint8_t index)
* Description: Toggle the state of the setup LED
* Returns: none
* Notes: none
*************************************************************************/
void led_toggle(uint8_t index)
{
if (led_state(index)) {
led_off(index);
@@ -154,13 +150,11 @@ void led_toggle(
}
/*************************************************************************
* 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 < MAX_LEDS) {
mstimer_set(&Off_Delay_Timer[index], delay_ms);
@@ -168,13 +162,11 @@ void led_off_delay(
}
/*************************************************************************
* 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 < MAX_LEDS) {
led_on(index);
@@ -183,14 +175,13 @@ void led_on_interval(
}
/*************************************************************************
* Description: Task for blinking LED
* Returns: none
* Notes: none
*************************************************************************/
void led_task(
void)
* 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 < MAX_LEDS; i++) {
if (mstimer_expired(&Off_Delay_Timer[i])) {
@@ -201,19 +192,18 @@ void led_task(
}
/*************************************************************************
* Description: Initialize the LED hardware
* Returns: none
* Notes: none
*************************************************************************/
void led_init(
void)
* 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 port pins as outputs */
BIT_SET(DDRD, DDD7);
BIT_SET(DDRD, DDD6);
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_SET(DDRB, DDB0);
BIT_SET(DDRB, DDB4);
#else
+24 -25
View File
@@ -1,27 +1,27 @@
/************************************************************************
*
* 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 <stdbool.h>
#include <stdint.h>
@@ -47,8 +47,7 @@ char *BACnet_Version = BACNET_VERSION_TEXT;
/* For porting to IAR, see:
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
int main(
void)
int main(void)
{
init();
/* Configure the watchdog timer - Disabled for debugging */
+51 -55
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 <stdbool.h>
#include <stdint.h>
#include "hardware.h"
@@ -32,8 +32,7 @@
/* Timer2 Prescaling: 1, 8, 32, 64, 128, 256, or 1024 */
#define TIMER_MICROSECONDS 1000UL
#define TIMER_TICKS(p) \
(((((F_CPU)/(p))/1000UL) \
*(TIMER_MICROSECONDS))/1000UL)
(((((F_CPU) / (p)) / 1000UL) * (TIMER_MICROSECONDS)) / 1000UL)
#define TIMER_TICKS_MAX 255UL
/* adjust the prescaler for the processor clock */
#if (TIMER_TICKS(1) <= TIMER_TICKS_MAX)
@@ -55,18 +54,17 @@
#endif
#define TIMER2_TICKS TIMER_TICKS(TIMER2_PRESCALER)
/* Timer counts up from count to TIMER_TICKS_MAX and then signals overflow */
#define TIMER2_COUNT (TIMER_TICKS_MAX-TIMER2_TICKS)
#define TIMER2_COUNT (TIMER_TICKS_MAX - TIMER2_TICKS)
/* counter for the the timer which wraps every 49.7 days */
static volatile uint32_t Millisecond_Counter;
/*************************************************************************
* Description: Timer Interrupt Handler
* Returns: nothing
* Notes: none
*************************************************************************/
static inline void timer_interrupt_handler(
void)
* Description: Timer Interrupt Handler
* Returns: nothing
* Notes: none
*************************************************************************/
static inline void timer_interrupt_handler(void)
{
/* Set the counter for the next interrupt */
TCNT2 = TIMER2_COUNT;
@@ -74,24 +72,23 @@ static inline void timer_interrupt_handler(
}
/*************************************************************************
* Description: Timer Interrupt Service Routine - Timer Overflowed!
* Returns: none
* Notes: Global interupts must be enabled
*************************************************************************/
* Description: Timer Interrupt Service Routine - Timer Overflowed!
* Returns: none
* Notes: Global interupts must be enabled
*************************************************************************/
ISR(TIMER2_OVF_vect)
{
timer_interrupt_handler();
}
/*************************************************************************
* Description: returns the current millisecond count
* Returns: none
* Notes: This method only disables the timer overflow interrupt.
*************************************************************************/
unsigned long mstimer_now(
void)
* Description: returns the current millisecond count
* Returns: none
* Notes: This method only disables the timer overflow interrupt.
*************************************************************************/
unsigned long mstimer_now(void)
{
unsigned long timer_value; /* return value */
unsigned long timer_value; /* return value */
/* Disable the overflow interrupt.
Prevents value corruption that would happen if interrupted */
@@ -104,12 +101,11 @@ unsigned long mstimer_now(
}
/*************************************************************************
* Description: Initialization for Timer
* Returns: none
* Notes: none
*************************************************************************/
void mstimer_init(
void)
* Description: Initialization for Timer
* Returns: none
* Notes: none
*************************************************************************/
void mstimer_init(void)
{
/* Normal Operation */
TCCR2A = 0;
@@ -125,19 +121,19 @@ void mstimer_init(
1 1 0 CLKt2s/256
1 1 1 CLKt2s/1024
*/
#if (TIMER2_PRESCALER==1)
#if (TIMER2_PRESCALER == 1)
TCCR2B = _BV(CS20);
#elif (TIMER2_PRESCALER==8)
#elif (TIMER2_PRESCALER == 8)
TCCR2B = _BV(CS21);
#elif (TIMER2_PRESCALER==32)
#elif (TIMER2_PRESCALER == 32)
TCCR2B = _BV(CS21) | _BV(CS20);
#elif (TIMER2_PRESCALER==64)
#elif (TIMER2_PRESCALER == 64)
TCCR2B = _BV(CS22);
#elif (TIMER2_PRESCALER==128)
#elif (TIMER2_PRESCALER == 128)
TCCR2B = _BV(CS22) | _BV(CS20);
#elif (TIMER2_PRESCALER==256)
#elif (TIMER2_PRESCALER == 256)
TCCR2B = _BV(CS22) | _BV(CS21);
#elif (TIMER2_PRESCALER==1024)
#elif (TIMER2_PRESCALER == 1024)
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
#else
#error Timer2 Prescale: Invalid Value
+106 -121
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 <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -44,7 +44,7 @@ static uint32_t Baud_Rate = 9600;
/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */
/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */
/* 40 bits is 4 octets including a start and stop bit with each octet */
#define Tturnaround (40UL)
#define Tturnaround (40UL)
/* turnaround_time_milliseconds = (Tturnaround*1000UL)/Baud_Rate; */
/* buffer for storing received bytes - size must be power of two */
@@ -54,46 +54,42 @@ static FIFO_BUFFER Receive_Buffer;
static struct mstimer Silence_Timer;
/****************************************************************************
* DESCRIPTION: Determines the amount of silence time elapsed
* RETURN: true if the amount of silence time has elapsed
* NOTES: none
*****************************************************************************/
bool rs485_silence_time_elapsed(
uint16_t milliseconds)
* DESCRIPTION: Determines the amount of silence time elapsed
* RETURN: true if the amount of silence time has elapsed
* NOTES: none
*****************************************************************************/
bool rs485_silence_time_elapsed(uint16_t milliseconds)
{
return (mstimer_elapsed(&Silence_Timer) > milliseconds);
}
/****************************************************************************
* DESCRIPTION: Resets the silence timer
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_silence_time_reset(
void)
* DESCRIPTION: Resets the silence timer
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_silence_time_reset(void)
{
mstimer_set(&Silence_Timer, 0);
}
/****************************************************************************
* DESCRIPTION: Configures the RTS output
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_rts_init(
void)
* DESCRIPTION: Configures the RTS output
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_rts_init(void)
{
/* configure the port pin as an output */
BIT_SET(DDRD, DDD4);
}
/****************************************************************************
* DESCRIPTION: enable the transmit-enable line on the RS-485 transceiver
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_rts_enable(
bool enable)
* DESCRIPTION: enable the transmit-enable line on the RS-485 transceiver
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_rts_enable(bool enable)
{
if (enable) {
BIT_SET(PORTD, PD4);
@@ -103,23 +99,21 @@ void rs485_rts_enable(
}
/****************************************************************************
* DESCRIPTION: enable the UART receiver and interrupt
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_receiver_enable(
void)
* DESCRIPTION: enable the UART receiver and interrupt
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_receiver_enable(void)
{
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);
}
/****************************************************************************
* DESCRIPTION: delay for 40 bit times
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_turnaround_delay(
void)
* DESCRIPTION: delay for 40 bit times
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_turnaround_delay(void)
{
uint8_t nbytes = 4;
@@ -144,10 +138,10 @@ void rs485_turnaround_delay(
}
/****************************************************************************
* DESCRIPTION: Interrupt service routine for UART Receiver
* RETURN: nothing
* NOTES: none
*****************************************************************************/
* DESCRIPTION: Interrupt service routine for UART Receiver
* RETURN: nothing
* NOTES: none
*****************************************************************************/
ISR(USART0_RX_vect)
{
uint8_t data_byte;
@@ -158,19 +152,18 @@ ISR(USART0_RX_vect)
#ifdef MSTP_MONITOR
UDR1 = data_byte;
#endif
(void) FIFO_Put(&Receive_Buffer, data_byte);
(void)FIFO_Put(&Receive_Buffer, data_byte);
}
}
/****************************************************************************
* DESCRIPTION: Checks for data on the receive UART, and handles errors
* RETURN: none
* NOTES: none
*****************************************************************************/
bool rs485_byte_available(
uint8_t * data_register)
* DESCRIPTION: Checks for data on the receive UART, and handles errors
* RETURN: none
* NOTES: none
*****************************************************************************/
bool rs485_byte_available(uint8_t *data_register)
{
bool data_available = false; /* return value */
bool data_available = false; /* return value */
if (!FIFO_Empty(&Receive_Buffer)) {
led_on_interval(LED_4, 1);
@@ -184,25 +177,23 @@ bool rs485_byte_available(
}
/****************************************************************************
* DESCRIPTION: returns an error indication if errors are enabled
* RETURN: nothing
* NOTES: none
*****************************************************************************/
bool rs485_receive_error(
void)
* DESCRIPTION: returns an error indication if errors are enabled
* RETURN: nothing
* NOTES: none
*****************************************************************************/
bool rs485_receive_error(void)
{
return false;
}
/****************************************************************************
* DESCRIPTION: Transmits a frame using the UART
* RETURN: none
* NOTES: none
*****************************************************************************/
void rs485_bytes_send(
uint8_t * buffer, /* data to send */
* DESCRIPTION: Transmits a frame using the UART
* RETURN: none
* NOTES: none
*****************************************************************************/
void rs485_bytes_send(uint8_t *buffer, /* data to send */
uint16_t nbytes)
{ /* number of bytes of data */
{ /* number of bytes of data */
led_on(LED_5);
while (!BIT_CHECK(UCSR0A, UDRE0)) {
/* do nothing - wait until Tx buffer is empty */
@@ -233,23 +224,21 @@ void rs485_bytes_send(
}
/****************************************************************************
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: baud rate in bps
* NOTES: none
*****************************************************************************/
uint32_t rs485_baud_rate(
void)
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: baud rate in bps
* NOTES: none
*****************************************************************************/
uint32_t rs485_baud_rate(void)
{
return Baud_Rate;
}
/****************************************************************************
* DESCRIPTION: configure the UART baud rate
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_baud_rate_configure(
void)
* DESCRIPTION: configure the UART baud rate
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_baud_rate_configure(void)
{
/* 2x speed mode */
BIT_SET(UCSR0A, U2X0);
@@ -258,12 +247,11 @@ static void rs485_baud_rate_configure(
}
/****************************************************************************
* DESCRIPTION: set the UART baud rate to a standard value
* RETURN: true if the baud rate is valid
* NOTES: none
*****************************************************************************/
bool rs485_baud_rate_set(
uint32_t baud)
* DESCRIPTION: set the UART baud rate to a standard value
* RETURN: true if the baud rate is valid
* NOTES: none
*****************************************************************************/
bool rs485_baud_rate_set(uint32_t baud)
{
bool valid = true;
uint8_t baud_k = 0;
@@ -290,12 +278,11 @@ bool rs485_baud_rate_set(
}
/****************************************************************************
* DESCRIPTION: initialize the hardware UART
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_usart_init(
void)
* DESCRIPTION: initialize the hardware UART
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_usart_init(void)
{
/* enable the internal pullup on RXD0 */
BIT_CLEAR(DDRD, DDD0);
@@ -314,12 +301,11 @@ static void rs485_usart_init(
}
/****************************************************************************
* DESCRIPTION: read any non-volatile data
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_init_nvdata(
void)
* DESCRIPTION: read any non-volatile data
* RETURN: nothing
* NOTES: none
*****************************************************************************/
static void rs485_init_nvdata(void)
{
uint8_t baud_k = 9; /* from EEPROM value */
@@ -354,15 +340,14 @@ static void rs485_init_nvdata(
}
/****************************************************************************
* DESCRIPTION: initialize the module
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_init(
void)
* DESCRIPTION: initialize the module
* RETURN: nothing
* NOTES: none
*****************************************************************************/
void rs485_init(void)
{
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
(unsigned) sizeof(Receive_Buffer_Data));
(unsigned)sizeof(Receive_Buffer_Data));
rs485_silence_time_reset();
rs485_rts_init();
rs485_usart_init();
+91 -85
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* Used algorithm and code from Joerg Wunsch and Ruwan Jayanetti.
* http://www.nongnu.org/avr-libc/user-manual/group__twi__demo.html
*
* 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>
* Used algorithm and code from Joerg Wunsch and Ruwan Jayanetti.
* http://www.nongnu.org/avr-libc/user-manual/group__twi__demo.html
*
* 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>
@@ -57,7 +57,8 @@
#endif
/* The lower 3 bits of TWSR are reserved on the ATmega163 */
#define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3))
#define TW_STATUS_MASK \
(_BV(TWS7) | _BV(TWS6) | _BV(TWS5) | _BV(TWS4) | _BV(TWS3))
/* start condition transmitted */
#define TW_START 0x08
/* repeated start condition transmitted */
@@ -93,21 +94,20 @@
/* Number of iterations is the max amount to wait for write cycle
to complete a full page write */
/* .005s/.000025=200 */
#define MAX_ITER (((SEEPROM_I2C_CLOCK/1000)/10)*SEEPROM_WRITE_CYCLE)
#define MAX_ITER (((SEEPROM_I2C_CLOCK / 1000) / 10) * SEEPROM_WRITE_CYCLE)
/*************************************************************************
* DESCRIPTION: Return bytes from SEEPROM memory at address
* RETURN: number of bytes read, or -1 on error
* NOTES: none
**************************************************************************/
int seeprom_bytes_read(
uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t * buf, /* data to store */
* DESCRIPTION: Return bytes from SEEPROM memory at address
* RETURN: number of bytes read, or -1 on error
* NOTES: none
**************************************************************************/
int seeprom_bytes_read(uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t *buf, /* data to store */
int len)
{ /* number of bytes of data to read */
{ /* number of bytes of data to read */
uint8_t sla, twcr, n = 0;
int rv = 0;
uint8_t twst; /* status - only valid while TWINT is set. */
uint8_t twst; /* status - only valid while TWINT is set. */
uint16_t timeout = 0xFFFF;
#if SEEPROM_WORD_ADDRESS_16BIT
@@ -118,11 +118,11 @@ int seeprom_bytes_read(
sla = SEEPROM_I2C_ADDRESS | (((eeaddr >> 8) & 0x07) << 1);
#endif
/* First cycle: master transmitter mode */
restart:
restart:
if (n++ >= MAX_ITER) {
return -1;
}
begin:
begin:
/* send start condition */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
/* wait for transmission */
@@ -159,7 +159,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_SLA_ACK:
@@ -184,7 +185,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_DATA_ACK:
@@ -203,7 +205,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_DATA_ACK:
@@ -229,7 +232,8 @@ int seeprom_bytes_read(
/* send repeated start condition */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_START:
@@ -247,7 +251,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MR_SLA_ACK:
@@ -272,7 +277,8 @@ int seeprom_bytes_read(
/* clear int to start transmission */
TWCR = twcr;
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MR_DATA_NACK:
@@ -288,32 +294,32 @@ int seeprom_bytes_read(
goto error;
}
}
quit:
quit:
/* Except in the case of lost arbitration, all bus transactions
must properly be terminated by the master initiating a
stop condition. */
/* send stop condition */
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
return rv;
error:
error:
rv = -1;
goto quit;
}
/*************************************************************************
* DESCRIPTION: Write some data and wait until it is sent
* RETURN: number of bytes written, or -1 on error
* NOTES: only writes from offset to end of page.
**************************************************************************/
* DESCRIPTION: Write some data and wait until it is sent
* RETURN: number of bytes written, or -1 on error
* NOTES: only writes from offset to end of page.
**************************************************************************/
static int seeprom_bytes_write_page(
uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t * buf, /* data to send */
uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t *buf, /* data to send */
int len)
{ /* number of bytes of data */
{ /* number of bytes of data */
uint8_t sla, n = 0;
int rv = 0;
uint16_t endaddr;
uint8_t twst; /* status - only valid while TWINT is set. */
uint8_t twst; /* status - only valid while TWINT is set. */
uint16_t page_end_addr;
uint16_t timeout = 0xFFFF;
@@ -330,11 +336,11 @@ static int seeprom_bytes_write_page(
/* patch high bits of EEPROM address into SLA */
sla = SEEPROM_I2C_ADDRESS | (((eeaddr >> 8) & 0x07) << 1);
#endif
restart:
restart:
if (n++ >= MAX_ITER) {
return -1;
}
begin:
begin:
/* Writing to the EEPROM device is simpler than reading,
since only a master transmitter mode transfer is needed.
Note that the first packet after the SLA+W selection is
@@ -373,7 +379,8 @@ static int seeprom_bytes_write_page(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_SLA_ACK:
@@ -394,7 +401,8 @@ static int seeprom_bytes_write_page(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_DATA_ACK:
@@ -413,8 +421,7 @@ static int seeprom_bytes_write_page(
/* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) {
};
while ((TWCR & _BV(TWINT)) == 0) { };
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_DATA_ACK:
@@ -432,7 +439,8 @@ static int seeprom_bytes_write_page(
/* start transmission */
TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0);
while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK;
switch (twst) {
case TW_MT_DATA_NACK:
@@ -446,36 +454,35 @@ static int seeprom_bytes_write_page(
goto error;
}
}
quit:
quit:
/* send stop condition */
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
return rv;
error:
error:
rv = -1;
goto quit;
}
/*************************************************************************
* DESCRIPTION: Write some data and wait until it is sent
* RETURN: number of bytes written, or -1 on error
* NOTES:
* When the word address, internally generated,
* reaches the page boundary, the following
* byte is placed at the beginning of the same
* page. If more than 64 data words are
* transmitted to the EEPROM, the data word
* address will "roll over" and previous data will be
* overwritten. The address "roll over" during write
* is from the last byte of the current page to the
* first byte of the same page.
**************************************************************************/
int seeprom_bytes_write(
uint16_t off, /* SEEPROM starting memory address */
uint8_t * buf, /* data to send */
* DESCRIPTION: Write some data and wait until it is sent
* RETURN: number of bytes written, or -1 on error
* NOTES:
* When the word address, internally generated,
* reaches the page boundary, the following
* byte is placed at the beginning of the same
* page. If more than 64 data words are
* transmitted to the EEPROM, the data word
* address will "roll over" and previous data will be
* overwritten. The address "roll over" during write
* is from the last byte of the current page to the
* first byte of the same page.
**************************************************************************/
int seeprom_bytes_write(uint16_t off, /* SEEPROM starting memory address */
uint8_t *buf, /* data to send */
int len)
{ /* number of bytes of data */
{ /* number of bytes of data */
int status = 0;
int rv = 0;
@@ -497,12 +504,11 @@ int seeprom_bytes_write(
}
/*************************************************************************
* Description: Initialize the SEEPROM TWI connection
* Returns: none
* Notes: none
**************************************************************************/
void seeprom_init(
void)
* Description: Initialize the SEEPROM TWI connection
* Returns: none
* Notes: none
**************************************************************************/
void seeprom_init(void)
{
/* bit rate prescaler */
TWSR = 0;
+37 -47
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 <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -35,8 +35,7 @@ static uint32_t Baud_Rate = 9600;
static uint8_t Receive_Buffer_Data[128];
static FIFO_BUFFER Receive_Buffer;
static void serial_receiver_enable(
void)
static void serial_receiver_enable(void)
{
UCSR1B = _BV(TXEN1) | _BV(RXEN1) | _BV(RXCIE1);
}
@@ -48,14 +47,13 @@ ISR(USART1_RX_vect)
if (BIT_CHECK(UCSR1A, RXC1)) {
/* data is available */
data_byte = UDR1;
(void) FIFO_Put(&Receive_Buffer, data_byte);
(void)FIFO_Put(&Receive_Buffer, data_byte);
}
}
bool serial_byte_get(
uint8_t * data_register)
bool serial_byte_get(uint8_t *data_register)
{
bool data_available = false; /* return value */
bool data_available = false; /* return value */
if (!FIFO_Empty(&Receive_Buffer)) {
*data_register = FIFO_Get(&Receive_Buffer);
@@ -65,10 +63,9 @@ bool serial_byte_get(
return data_available;
}
bool serial_byte_peek(
uint8_t * data_register)
bool serial_byte_peek(uint8_t *data_register)
{
bool data_available = false; /* return value */
bool data_available = false; /* return value */
if (!FIFO_Empty(&Receive_Buffer)) {
*data_register = FIFO_Peek(&Receive_Buffer);
@@ -78,10 +75,9 @@ bool serial_byte_peek(
return data_available;
}
void serial_bytes_send(
uint8_t * buffer, /* data to send */
void serial_bytes_send(uint8_t *buffer, /* data to send */
uint16_t nbytes)
{ /* number of bytes of data */
{ /* number of bytes of data */
while (!BIT_CHECK(UCSR1A, UDRE1)) {
/* do nothing - wait until Tx buffer is empty */
}
@@ -105,8 +101,7 @@ void serial_bytes_send(
return;
}
void serial_byte_send(
uint8_t ch)
void serial_byte_send(uint8_t ch)
{
while (!BIT_CHECK(UCSR1A, UDRE1)) {
/* do nothing - wait until Tx buffer is empty */
@@ -117,8 +112,7 @@ void serial_byte_send(
return;
}
void serial_byte_transmit_complete(
void)
void serial_byte_transmit_complete(void)
{
/* was the frame sent? */
while (!BIT_CHECK(UCSR1A, TXC1)) {
@@ -129,14 +123,12 @@ void serial_byte_transmit_complete(
BIT_SET(UCSR1A, TXC1);
}
uint32_t serial_baud_rate(
void)
uint32_t serial_baud_rate(void)
{
return Baud_Rate;
}
bool serial_baud_rate_set(
uint32_t baud)
bool serial_baud_rate_set(uint32_t baud)
{
bool valid = true;
@@ -162,8 +154,7 @@ bool serial_baud_rate_set(
return valid;
}
static void serial_usart_init(
void)
static void serial_usart_init(void)
{
/* enable the internal pullup on RXD1 */
BIT_CLEAR(DDRD, DDD2);
@@ -181,11 +172,10 @@ static void serial_usart_init(
power_usart1_enable();
}
void serial_init(
void)
void serial_init(void)
{
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
(unsigned) sizeof(Receive_Buffer_Data));
(unsigned)sizeof(Receive_Buffer_Data));
serial_usart_init();
serial_baud_rate_set(Baud_Rate);
serial_receiver_enable();
+44 -47
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* 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 "hardware.h"
/* me */
#include "stack.h"
@@ -32,11 +32,9 @@ extern uint8_t _end;
extern uint8_t __stack;
#define STACK_CANARY (0xC5)
void stack_init(
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
void stack_init(void) __attribute__((naked)) __attribute__((section(".init1")));
void stack_init(
void)
void stack_init(void)
{
#if 0
uint8_t *p = &_end;
@@ -46,28 +44,32 @@ 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);
}
unsigned stack_unused(
void)
unsigned stack_unused(void)
{
uint8_t *p = &_end;
unsigned count = 0;
@@ -82,26 +84,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;
}
+65 -77
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2010 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) 2010 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>
@@ -42,26 +42,24 @@
#endif
#define BINARY_STRING_MAX 3
const char * const binary_string[BINARY_STRING_MAX] = {
"INACTIVE", "ACTIVE", "RELINQUISH"
};
const char *const binary_string[BINARY_STRING_MAX] = { "INACTIVE", "ACTIVE",
"RELINQUISH" };
/* timer for test task */
static struct mstimer Test_Timer;
/* MAC Address of MS/TP */
static uint8_t MSTP_MAC_Address;
void test_init(
void)
void test_init(void)
{
#ifdef MSTP_MONITOR
serial_baud_rate_set(115200);
#else
serial_baud_rate_set(9600);
#endif
mstimer_set(&Test_Timer, 1*1000);
mstimer_set(&Test_Timer, 1 * 1000);
/* configure a port pin as output */
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_SET(DDRD, DDB5);
#else
BIT_SET(DDRB, DDB0);
@@ -69,10 +67,10 @@ void test_init(
}
/**
* @brief send a string of text to the RS-232 port
* @param text - C string of text (null terminated)
*/
static void test_write_string(const char * text)
* @brief send a string of text to the RS-232 port
* @param text - C string of text (null terminated)
*/
static void test_write_string(const char *text)
{
size_t len = 0;
@@ -82,16 +80,14 @@ static void test_write_string(const char * text)
}
}
/*************************************************************************
* Description: Turn on a pin
* Returns: none
* Notes: none
*************************************************************************/
static inline void test_pin_on(
void)
* Description: Turn on a pin
* Returns: none
* Notes: none
*************************************************************************/
static inline void test_pin_on(void)
{
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_SET(PORTD, PD5);
#else
BIT_SET(PORTB, PB0);
@@ -99,14 +95,13 @@ static inline void test_pin_on(
}
/*************************************************************************
* Description: Turn off a pin
* Returns: none
* Notes: none
*************************************************************************/
static inline void test_pin_off(
void)
* Description: Turn off a pin
* Returns: none
* Notes: none
*************************************************************************/
static inline void test_pin_off(void)
{
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
BIT_CLEAR(PORTD, PD5);
#else
BIT_CLEAR(PORTB, PB0);
@@ -114,14 +109,13 @@ static inline void test_pin_off(
}
/*************************************************************************
* Description: Get the state of the test pin
* Returns: true if on, false if off.
* Notes: none
*************************************************************************/
static inline bool test_pin_state(
void)
* Description: Get the state of the test pin
* Returns: true if on, false if off.
* Notes: none
*************************************************************************/
static inline bool test_pin_state(void)
{
#if (BDK_VERSION==4)
#if (BDK_VERSION == 4)
return (BIT_CHECK(PIND, PD5));
#else
return (BIT_CHECK(PINB, PB0));
@@ -129,12 +123,11 @@ static inline bool test_pin_state(
}
/*************************************************************************
* Description: Toggle the test pin
* Returns: none
* Notes: none
*************************************************************************/
static inline void test_pin_toggle(
void)
* Description: Toggle the test pin
* Returns: none
* Notes: none
*************************************************************************/
static inline void test_pin_toggle(void)
{
if (test_pin_state()) {
test_pin_off();
@@ -144,8 +137,7 @@ static inline void test_pin_toggle(
}
#ifdef MSTP_MONITOR
void test_task(
void)
void test_task(void)
{
if (mstimer_expired(&Test_Timer)) {
mstimer_reset(&Test_Timer);
@@ -155,8 +147,7 @@ void test_task(
#else
char Send_Buffer[32];
void test_task(
void)
void test_task(void)
{
uint8_t data_register = 0;
uint16_t id = 0;
@@ -172,7 +163,7 @@ void test_task(
Send_Buffer[12] = (MSTP_MAC_Address & BIT(4)) ? '1' : '0';
Send_Buffer[13] = (MSTP_MAC_Address & BIT(5)) ? '1' : '0';
Send_Buffer[14] = (MSTP_MAC_Address & BIT(6)) ? '1' : '0';
serial_bytes_send((uint8_t *) Send_Buffer, 17);
serial_bytes_send((uint8_t *)Send_Buffer, 17);
}
if (serial_byte_get(&data_register)) {
/* echo the character */
@@ -206,22 +197,19 @@ void test_task(
rs485_baud_rate_set(9600);
break;
case 'e':
seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *) & id, 2);
seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
sprintf(Send_Buffer, "\r\n%04X", id);
serial_bytes_send((uint8_t *) Send_Buffer,
strlen(Send_Buffer));
serial_bytes_send((uint8_t *)Send_Buffer, strlen(Send_Buffer));
break;
case 'b':
sprintf(Send_Buffer, "\r\n%lubps",
(unsigned long) rs485_baud_rate());
serial_bytes_send((uint8_t *) Send_Buffer,
strlen(Send_Buffer));
(unsigned long)rs485_baud_rate());
serial_bytes_send((uint8_t *)Send_Buffer, strlen(Send_Buffer));
break;
case 'm':
sprintf(Send_Buffer, "\r\nMax:%u",
(unsigned) dlmstp_max_master());
serial_bytes_send((uint8_t *) Send_Buffer,
strlen(Send_Buffer));
sprintf(
Send_Buffer, "\r\nMax:%u", (unsigned)dlmstp_max_master());
serial_bytes_send((uint8_t *)Send_Buffer, strlen(Send_Buffer));
break;
default:
break;
+35 -40
View File
@@ -1,32 +1,31 @@
/**************************************************************************
*
* 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 "hardware.h"
#include "watchdog.h"
#if !defined(__GNUC__)
static inline void wdt_enable(
int value)
static inline void wdt_enable(int value)
{
__disable_interrupt();
__watchdog_reset();
@@ -38,8 +37,7 @@ static inline void wdt_enable(
__enable_interrupt(); */
}
static inline void wdt_disable(
void)
static inline void wdt_disable(void)
{
__disable_interrupt();
__watchdog_reset();
@@ -53,31 +51,28 @@ static inline void wdt_disable(
__enable_interrupt();
}
static inline void wdt_reset(
void)
static inline void wdt_reset(void)
{
__watchdog_reset();
}
#endif
/*************************************************************************
* Description: Reset the watchdog timer
* Returns: none
* Notes: none
**************************************************************************/
void watchdog_reset(
void)
* Description: Reset the watchdog timer
* Returns: none
* Notes: none
**************************************************************************/
void watchdog_reset(void)
{
wdt_reset();
}
/*************************************************************************
* Description: Initialize the watchdog timer
* Returns: none
* Notes: none
**************************************************************************/
void watchdog_init(
unsigned milliseconds)
* Description: Initialize the watchdog timer
* Returns: none
* Notes: none
**************************************************************************/
void watchdog_init(unsigned milliseconds)
{
unsigned value = WDTO_15MS;
if (milliseconds) {