Fixing DOS/Unix/MAC EOL and line endings using fixup.sh script.

This commit is contained in:
skarg
2011-07-09 17:25:42 +00:00
parent 51c6134e15
commit ff393a665a
28 changed files with 8475 additions and 8475 deletions
+176 -176
View File
@@ -1,187 +1,187 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com> * Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "wp.h" #include "wp.h"
#include "wpm.h" #include "wpm.h"
/* device object has the handling for all objects */ /* device object has the handling for all objects */
#include "device.h" #include "device.h"
#include "handlers.h" #include "handlers.h"
/** @file h_wpm.c Handles Write Property Multiple requests. */ /** @file h_wpm.c Handles Write Property Multiple requests. */
/** Handler for a WriteProperty Service request. /** Handler for a WriteProperty Service request.
* @ingroup DSWP * @ingroup DSWP
* This handler will be invoked by apdu_handler() if it has been enabled * This handler will be invoked by apdu_handler() if it has been enabled
* by a call to apdu_set_confirmed_handler(). * by a call to apdu_set_confirmed_handler().
* This handler builds a response packet, which is * This handler builds a response packet, which is
* - an Abort if * - an Abort if
* - the message is segmented * - the message is segmented
* - if decoding fails * - if decoding fails
* - an ACK if Device_Write_Property_Multiple() succeeds * - an ACK if Device_Write_Property_Multiple() succeeds
* - an Error if Device_Write_PropertyMultiple() encounters an error * - an Error if Device_Write_PropertyMultiple() encounters an error
* *
* @param service_request [in] The contents of the service request. * @param service_request [in] The contents of the service request.
* @param service_len [in] The length of the service_request. * @param service_len [in] The length of the service_request.
* @param src [in] BACNET_ADDRESS of the source of the message * @param src [in] BACNET_ADDRESS of the source of the message
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_write_property_multiple( void handler_write_property_multiple(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
int len = 0; int len = 0;
int apdu_len = 0; int apdu_len = 0;
int npdu_len = 0; int npdu_len = 0;
int pdu_len = 0; int pdu_len = 0;
int decode_len = 0; int decode_len = 0;
bool error = false; bool error = false;
BACNET_WRITE_PROPERTY_DATA wp_data; BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
int bytes_sent = 0; int bytes_sent = 0;
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WPM: Segmented message. Sending Abort!\n"); fprintf(stderr, "WPM: Segmented message. Sending Abort!\n");
#endif #endif
goto WPM_ABORT; goto WPM_ABORT;
} }
/* decode service request */ /* decode service request */
decode_len = 0; decode_len = 0;
do do
{ {
/* decode Object Identifier /* decode Object Identifier
*/ */
len = wpm_decode_object_id(&service_request[decode_len], len = wpm_decode_object_id(&service_request[decode_len],
service_len - decode_len, &wp_data); service_len - decode_len, &wp_data);
if (len > 0) if (len > 0)
{ {
uint8_t tag_number = 0; uint8_t tag_number = 0;
decode_len += len; decode_len += len;
/* Opening tag 1 - List of Properties /* Opening tag 1 - List of Properties
*/ */
if (decode_is_opening_tag_number(&service_request[decode_len++], 1)) if (decode_is_opening_tag_number(&service_request[decode_len++], 1))
{ {
do do
{ {
/* decode a 'Property Identifier'; (3) an optional 'Property Array Index'; /* decode a 'Property Identifier'; (3) an optional 'Property Array Index';
*/ */
/* (4) a 'Property Value'; and (5) an optional 'Priority'. /* (4) a 'Property Value'; and (5) an optional 'Priority'.
*/ */
len = wpm_decode_object_property(&service_request[decode_len], len = wpm_decode_object_property(&service_request[decode_len],
service_len - decode_len, &wp_data); service_len - decode_len, &wp_data);
if (len > 0) if (len > 0)
{ {
decode_len += len; decode_len += len;
if (Device_Write_Property(&wp_data) == false) if (Device_Write_Property(&wp_data) == false)
{ {
error = true; error = true;
break; /* do while (decoding List of Properties) break; /* do while (decoding List of Properties)
*/ */
} }
} }
else else
{ {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Bad Encoding!\n"); fprintf(stderr, "Bad Encoding!\n");
#endif #endif
wp_data.error_class = ERROR_CLASS_PROPERTY; wp_data.error_class = ERROR_CLASS_PROPERTY;
wp_data.error_code = ERROR_CODE_OTHER; wp_data.error_code = ERROR_CODE_OTHER;
error = true; error = true;
break; /* do while (decoding List of Properties) break; /* do while (decoding List of Properties)
*/ */
} }
/* Closing tag 1 - List of Properties /* Closing tag 1 - List of Properties
*/ */
if (decode_is_closing_tag_number(&service_request[decode_len], 1)) if (decode_is_closing_tag_number(&service_request[decode_len], 1))
{ {
tag_number = 1; tag_number = 1;
decode_len++; decode_len++;
} }
else else
tag_number = 0; /* it was not tag 1, decode next Property Identifier ... tag_number = 0; /* it was not tag 1, decode next Property Identifier ...
*/ */
} }
while(tag_number != 1); /* end decoding List of Properties for "that" object while(tag_number != 1); /* end decoding List of Properties for "that" object
*/ */
if (error) if (error)
break; /*do while (decode service request) break; /*do while (decode service request)
*/ */
} }
} }
else else
{ {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Bad Encoding!\n"); fprintf(stderr, "Bad Encoding!\n");
#endif #endif
wp_data.error_class = ERROR_CLASS_OBJECT; wp_data.error_class = ERROR_CLASS_OBJECT;
wp_data.error_code = ERROR_CODE_OTHER; wp_data.error_code = ERROR_CODE_OTHER;
error = true; error = true;
break; /*do while (decode service request) break; /*do while (decode service request)
*/ */
} }
} }
while(decode_len < service_len); while(decode_len < service_len);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
apdu_len = 0; apdu_len = 0;
if (error == false) if (error == false)
apdu_len = wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len], apdu_len = wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
File diff suppressed because it is too large Load Diff
+123 -123
View File
@@ -1,124 +1,124 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com> * Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef NC_H #ifndef NC_H
#define NC_H #define NC_H
#include "event.h" #include "event.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#define NC_RESCAN_RECIPIENTS_SECS 60 #define NC_RESCAN_RECIPIENTS_SECS 60
/* max "length" of recipient_list */ /* max "length" of recipient_list */
#define NC_MAX_RECIPIENTS 10 #define NC_MAX_RECIPIENTS 10
/* Recipient types */ /* Recipient types */
typedef enum { typedef enum {
RECIPIENT_TYPE_NOTINITIALIZED = 0, RECIPIENT_TYPE_NOTINITIALIZED = 0,
RECIPIENT_TYPE_DEVICE = 1, RECIPIENT_TYPE_DEVICE = 1,
RECIPIENT_TYPE_ADDRESS = 2 RECIPIENT_TYPE_ADDRESS = 2
} NC_RECIPIENT_TYPE; } NC_RECIPIENT_TYPE;
/* BACnetRecipient sructuer*/ /* BACnetRecipient sructuer*/
/* /*
BACnetRecipient ::= CHOICE { BACnetRecipient ::= CHOICE {
device [0] BACnetObjectIdentifier, device [0] BACnetObjectIdentifier,
address [1] BACnetAddress address [1] BACnetAddress
} }
*/ */
typedef struct BACnet_Recipient { typedef struct BACnet_Recipient {
uint8_t RecipientType; /* Type of Recipient */ uint8_t RecipientType; /* Type of Recipient */
union { union {
uint32_t DeviceIdentifier; uint32_t DeviceIdentifier;
BACNET_ADDRESS Address; BACNET_ADDRESS Address;
} _; } _;
} BACNET_RECIPIENT; } BACNET_RECIPIENT;
/* BACnetDestination structure */ /* BACnetDestination structure */
typedef struct BACnet_Destination { typedef struct BACnet_Destination {
uint8_t ValidDays; uint8_t ValidDays;
BACNET_TIME FromTime; BACNET_TIME FromTime;
BACNET_TIME ToTime; BACNET_TIME ToTime;
BACNET_RECIPIENT Recipient; BACNET_RECIPIENT Recipient;
uint32_t ProcessIdentifier; uint32_t ProcessIdentifier;
uint8_t Transitions; uint8_t Transitions;
bool ConfirmedNotify; bool ConfirmedNotify;
} BACNET_DESTINATION; } BACNET_DESTINATION;
/* Structure containing configuration for a Notification Class */ /* Structure containing configuration for a Notification Class */
typedef struct Notification_Class_info { typedef struct Notification_Class_info {
uint8_t Priority[3]; /* BACnetARRAY[3] of Unsigned */ uint8_t Priority[3]; /* BACnetARRAY[3] of Unsigned */
uint8_t Ack_Required; /* BACnetEventTransitionBits */ uint8_t Ack_Required; /* BACnetEventTransitionBits */
BACNET_DESTINATION Recipient_List[NC_MAX_RECIPIENTS]; /* List of BACnetDestination */ BACNET_DESTINATION Recipient_List[NC_MAX_RECIPIENTS]; /* List of BACnetDestination */
} NOTIFICATION_CLASS_INFO; } NOTIFICATION_CLASS_INFO;
void Notification_Class_Property_Lists( void Notification_Class_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary); const int **pProprietary);
void Notification_Class_Init(void); void Notification_Class_Init(void);
bool Notification_Class_Valid_Instance( bool Notification_Class_Valid_Instance(
uint32_t object_instance); uint32_t object_instance);
unsigned Notification_Class_Count(void); unsigned Notification_Class_Count(void);
uint32_t Notification_Class_Index_To_Instance(unsigned index); uint32_t Notification_Class_Index_To_Instance(unsigned index);
unsigned Notification_Class_Instance_To_Index( unsigned Notification_Class_Instance_To_Index(
uint32_t object_instance); uint32_t object_instance);
bool Notification_Class_Object_Name( bool Notification_Class_Object_Name(
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name); BACNET_CHARACTER_STRING *object_name);
int Notification_Class_Read_Property( int Notification_Class_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata); BACNET_READ_PROPERTY_DATA * rpdata);
bool Notification_Class_Write_Property( bool Notification_Class_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data); BACNET_WRITE_PROPERTY_DATA * wp_data);
void Notification_Class_common_reporting_function( void Notification_Class_common_reporting_function(
BACNET_EVENT_NOTIFICATION_DATA * event_data); BACNET_EVENT_NOTIFICATION_DATA * event_data);
void Notification_Class_find_recipient(void); void Notification_Class_find_recipient(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#define NOTIFICATION_CLASS_OBJ_FUNCTIONS \ #define NOTIFICATION_CLASS_OBJ_FUNCTIONS \
OBJECT_NOTIFICATION_CLASS, Notification_Class_Init, Notification_Class_Count, \ OBJECT_NOTIFICATION_CLASS, Notification_Class_Init, Notification_Class_Count, \
Notification_Class_Index_To_Instance, Notification_Class_Valid_Instance, \ Notification_Class_Index_To_Instance, Notification_Class_Valid_Instance, \
Notification_Class_Object_Name, Notification_Class_Read_Property, \ Notification_Class_Object_Name, Notification_Class_Read_Property, \
Notification_Class_Write_Property, Notification_Class_Property_Lists, \ Notification_Class_Write_Property, Notification_Class_Property_Lists, \
NULL, NULL, NULL NULL, NULL, NULL
#endif /* NC_H #endif /* NC_H
+77 -77
View File
@@ -1,77 +1,77 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2006 John Minack Copyright (C) 2006 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef LSO_H #ifndef LSO_H
#define LSO_H #define LSO_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "bacenum.h" #include "bacenum.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacstr.h" #include "bacstr.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* Life Safety Operation Service */ /* Life Safety Operation Service */
typedef struct { typedef struct {
uint32_t processId; uint32_t processId;
BACNET_CHARACTER_STRING requestingSrc; BACNET_CHARACTER_STRING requestingSrc;
BACNET_LIFE_SAFETY_OPERATION operation; BACNET_LIFE_SAFETY_OPERATION operation;
BACNET_OBJECT_ID targetObject; BACNET_OBJECT_ID targetObject;
} BACNET_LSO_DATA; } BACNET_LSO_DATA;
int lso_encode_adpu( int lso_encode_adpu(
uint8_t * apdu, uint8_t * apdu,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_LSO_DATA * data); BACNET_LSO_DATA * data);
/* decode the service request only */ /* decode the service request only */
int lso_decode_service_request( int lso_decode_service_request(
uint8_t * apdu, uint8_t * apdu,
unsigned apdu_len, unsigned apdu_len,
BACNET_LSO_DATA * data); BACNET_LSO_DATA * data);
#ifdef TEST #ifdef TEST
#include "ctest.h" #include "ctest.h"
void testLSO( void testLSO(
Test * pTest); Test * pTest);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+78 -78
View File
@@ -1,78 +1,78 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com> * Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef WRITEPROPERTYMULTIPLE_H #ifndef WRITEPROPERTYMULTIPLE_H
#define WRITEPROPERTYMULTIPLE_H #define WRITEPROPERTYMULTIPLE_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "bacdcode.h" #include "bacdcode.h"
#include "bacapp.h" #include "bacapp.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* decode the service request only */ /* decode the service request only */
int wpm_decode_object_id(uint8_t * apdu, uint16_t apdu_len, int wpm_decode_object_id(uint8_t * apdu, uint16_t apdu_len,
BACNET_WRITE_PROPERTY_DATA * data); BACNET_WRITE_PROPERTY_DATA * data);
int wpm_decode_object_property(uint8_t * apdu, int wpm_decode_object_property(uint8_t * apdu,
uint16_t apdu_len, uint16_t apdu_len,
BACNET_WRITE_PROPERTY_DATA * wpm_data); BACNET_WRITE_PROPERTY_DATA * wpm_data);
/* encode service */ /* encode service */
int wpm_ack_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id); int wpm_ack_encode_apdu_init(uint8_t *apdu, uint8_t invoke_id);
int wpm_error_ack_encode_apdu(uint8_t * apdu, uint8_t invoke_id, int wpm_error_ack_encode_apdu(uint8_t * apdu, uint8_t invoke_id,
BACNET_WRITE_PROPERTY_DATA * wp_data); BACNET_WRITE_PROPERTY_DATA * wp_data);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
/** @defgroup DSWP Data Sharing - Write Property Multiple Service (DS-WPM) /** @defgroup DSWP Data Sharing - Write Property Multiple Service (DS-WPM)
* @ingroup DataShare * @ingroup DataShare
* 15.10 WriteProperty Multiple Service <br> * 15.10 WriteProperty Multiple Service <br>
* The WritePropertyMultiple service is used by a client BACnet-user * The WritePropertyMultiple service is used by a client BACnet-user
* to modify the value of one or more specified properties of a BACnet object. * to modify the value of one or more specified properties of a BACnet object.
* This service potentially allows write access to any property of any object, * This service potentially allows write access to any property of any object,
* whether a BACnet-defined object or not. * whether a BACnet-defined object or not.
* Properties shall be modified by the WritePropertyMultiple service * Properties shall be modified by the WritePropertyMultiple service
* in the order specified in the 'List of Write Access Specifications' parameter, * in the order specified in the 'List of Write Access Specifications' parameter,
* and execution of the service shall continue until all of the specified * and execution of the service shall continue until all of the specified
* properties have been written to or a property is encountered that * properties have been written to or a property is encountered that
* for some reason cannot be modified as requested. * for some reason cannot be modified as requested.
* Some implementors may wish to restrict write access to certain properties * Some implementors may wish to restrict write access to certain properties
* of certain objects. In such cases, an attempt to modify a restricted property * of certain objects. In such cases, an attempt to modify a restricted property
* shall result in the return of an error of 'Error Class' PROPERTY and 'Error Code' * shall result in the return of an error of 'Error Class' PROPERTY and 'Error Code'
* WRITE_ACCESS_DENIED. Note that these restricted properties may be accessible * WRITE_ACCESS_DENIED. Note that these restricted properties may be accessible
* through the use of Virtual Terminal services or other means at the discretion * through the use of Virtual Terminal services or other means at the discretion
* of the implementor. * of the implementor.
*/ */
#endif #endif
+275 -275
View File
@@ -1,275 +1,275 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "hardware.h" #include "hardware.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacstr.h" #include "bacstr.h"
#include "nvdata.h" #include "nvdata.h"
#include "seeprom.h" #include "seeprom.h"
#include "device.h" #include "device.h"
#include "bname.h" #include "bname.h"
/* Basic UTF-8 manipulation routines /* Basic UTF-8 manipulation routines
by Jeff Bezanson by Jeff Bezanson
placed in the public domain Fall 2005 */ placed in the public domain Fall 2005 */
static const char trailingBytesForUTF8[256] = { static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
}; };
/* based on the valid_utf8 routine from the PCRE library by Philip Hazel /* based on the valid_utf8 routine from the PCRE library by Philip Hazel
length is in bytes, since without knowing whether the string is valid length is in bytes, since without knowing whether the string is valid
it's hard to know how many characters there are! */ it's hard to know how many characters there are! */
static int utf8_isvalid(const char *str, int length) static int utf8_isvalid(const char *str, int length)
{ {
const unsigned char *p, *pend = (unsigned char*)str + length; const unsigned char *p, *pend = (unsigned char*)str + length;
unsigned char c; unsigned char c;
int ab; int ab;
for (p = (unsigned char*)str; p < pend; p++) { for (p = (unsigned char*)str; p < pend; p++) {
c = *p; c = *p;
/* null in middle of string */ /* null in middle of string */
if (c == 0) { if (c == 0) {
return 0; return 0;
} }
/* ASCII character */ /* ASCII character */
if (c < 128) { if (c < 128) {
continue; continue;
} }
if ((c & 0xc0) != 0xc0) { if ((c & 0xc0) != 0xc0) {
return 0; return 0;
} }
ab = trailingBytesForUTF8[c]; ab = trailingBytesForUTF8[c];
if (length < ab) { if (length < ab) {
return 0; return 0;
} }
length -= ab; length -= ab;
p++; p++;
/* Check top bits in the second byte */ /* Check top bits in the second byte */
if ((*p & 0xc0) != 0x80) { if ((*p & 0xc0) != 0x80) {
return 0; return 0;
} }
/* Check for overlong sequences for each different length */ /* Check for overlong sequences for each different length */
switch (ab) { switch (ab) {
/* Check for xx00 000x */ /* Check for xx00 000x */
case 1: case 1:
if ((c & 0x3e) == 0) return 0; if ((c & 0x3e) == 0) return 0;
continue; /* We know there aren't any more bytes to check */ continue; /* We know there aren't any more bytes to check */
/* Check for 1110 0000, xx0x xxxx */ /* Check for 1110 0000, xx0x xxxx */
case 2: case 2:
if (c == 0xe0 && (*p & 0x20) == 0) return 0; if (c == 0xe0 && (*p & 0x20) == 0) return 0;
break; break;
/* Check for 1111 0000, xx00 xxxx */ /* Check for 1111 0000, xx00 xxxx */
case 3: case 3:
if (c == 0xf0 && (*p & 0x30) == 0) return 0; if (c == 0xf0 && (*p & 0x30) == 0) return 0;
break; break;
/* Check for 1111 1000, xx00 0xxx */ /* Check for 1111 1000, xx00 0xxx */
case 4: case 4:
if (c == 0xf8 && (*p & 0x38) == 0) return 0; if (c == 0xf8 && (*p & 0x38) == 0) return 0;
break; break;
/* Check for leading 0xfe or 0xff, /* Check for leading 0xfe or 0xff,
and then for 1111 1100, xx00 00xx */ and then for 1111 1100, xx00 00xx */
case 5: case 5:
if (c == 0xfe || c == 0xff || if (c == 0xfe || c == 0xff ||
(c == 0xfc && (*p & 0x3c) == 0)) return 0; (c == 0xfc && (*p & 0x3c) == 0)) return 0;
break; break;
} }
/* Check for valid bytes after the 2nd, if any; all must start 10 */ /* Check for valid bytes after the 2nd, if any; all must start 10 */
while (--ab > 0) { while (--ab > 0) {
if ((*(++p) & 0xc0) != 0x80) return 0; if ((*(++p) & 0xc0) != 0x80) return 0;
} }
} }
return 1; return 1;
} }
static bool bacnet_name_isvalid( static bool bacnet_name_isvalid(
uint8_t encoding, uint8_t encoding,
uint8_t length, uint8_t length,
char *str) char *str)
{ {
bool valid = false; bool valid = false;
if ((encoding < MAX_CHARACTER_STRING_ENCODING) && if ((encoding < MAX_CHARACTER_STRING_ENCODING) &&
(length <= NV_EEPROM_NAME_SIZE)) { (length <= NV_EEPROM_NAME_SIZE)) {
if (encoding == CHARACTER_ANSI_X34) { if (encoding == CHARACTER_ANSI_X34) {
if (utf8_isvalid(str, length)) { if (utf8_isvalid(str, length)) {
valid = true; valid = true;
} }
} else { } else {
valid = true; valid = true;
} }
} }
return valid; return valid;
} }
bool bacnet_name_set( bool bacnet_name_set(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string) BACNET_CHARACTER_STRING *char_string)
{ {
uint8_t encoding = 0; uint8_t encoding = 0;
uint8_t length = 0; uint8_t length = 0;
char *str = NULL; char *str = NULL;
length = characterstring_length(char_string); length = characterstring_length(char_string);
encoding = characterstring_encoding(char_string); encoding = characterstring_encoding(char_string);
str = characterstring_value(char_string); str = characterstring_value(char_string);
if (bacnet_name_isvalid(encoding, length, str)) { if (bacnet_name_isvalid(encoding, length, str)) {
seeprom_bytes_write( seeprom_bytes_write(
NV_EEPROM_NAME_LENGTH(offset), NV_EEPROM_NAME_LENGTH(offset),
&length, 1); &length, 1);
seeprom_bytes_write( seeprom_bytes_write(
NV_EEPROM_NAME_ENCODING(offset), NV_EEPROM_NAME_ENCODING(offset),
&encoding, 1); &encoding, 1);
seeprom_bytes_write( seeprom_bytes_write(
NV_EEPROM_NAME_STRING(offset), NV_EEPROM_NAME_STRING(offset),
(uint8_t *)str, (uint8_t *)str,
length); length);
return true; return true;
} }
return false; return false;
} }
bool bacnet_name_write( bool bacnet_name_write(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
bool status = false; bool status = false;
size_t length = 0; size_t length = 0;
uint8_t encoding = 0; uint8_t encoding = 0;
length = characterstring_length(char_string); length = characterstring_length(char_string);
if (length < 1) { if (length < 1) {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (length <= NV_EEPROM_NAME_SIZE) { } else if (length <= NV_EEPROM_NAME_SIZE) {
encoding = characterstring_encoding(char_string); encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) { if (encoding < MAX_CHARACTER_STRING_ENCODING) {
if (Device_Valid_Object_Name(char_string, NULL, NULL)) { if (Device_Valid_Object_Name(char_string, NULL, NULL)) {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_DUPLICATE_NAME; *error_code = ERROR_CODE_DUPLICATE_NAME;
} else { } else {
status = bacnet_name_set(offset, char_string); status = bacnet_name_set(offset, char_string);
if (status) { if (status) {
Device_Inc_Database_Revision(); Device_Inc_Database_Revision();
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
} }
return status; return status;
} }
/* no required minumum length or duplicate checking */ /* no required minumum length or duplicate checking */
bool bacnet_name_write_other( bool bacnet_name_write_other(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
bool status = false; bool status = false;
size_t length = 0; size_t length = 0;
uint8_t encoding = 0; uint8_t encoding = 0;
length = characterstring_length(char_string); length = characterstring_length(char_string);
if (length <= NV_EEPROM_NAME_SIZE) { if (length <= NV_EEPROM_NAME_SIZE) {
encoding = characterstring_encoding(char_string); encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) { if (encoding < MAX_CHARACTER_STRING_ENCODING) {
status = bacnet_name_set(offset, char_string); status = bacnet_name_set(offset, char_string);
if (!status) { if (!status) {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
} }
return status; return status;
} }
void bacnet_name_init( void bacnet_name_init(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
char *default_string) char *default_string)
{ {
characterstring_init_ansi(char_string, default_string); characterstring_init_ansi(char_string, default_string);
(void)bacnet_name_set(offset, char_string); (void)bacnet_name_set(offset, char_string);
} }
void bacnet_name( void bacnet_name(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
char *default_string) char *default_string)
{ {
uint8_t encoding = 0; uint8_t encoding = 0;
uint8_t length = 0; uint8_t length = 0;
char name[NV_EEPROM_NAME_SIZE + 1] = ""; char name[NV_EEPROM_NAME_SIZE + 1] = "";
seeprom_bytes_read(NV_EEPROM_NAME_ENCODING(offset), &encoding, 1); seeprom_bytes_read(NV_EEPROM_NAME_ENCODING(offset), &encoding, 1);
seeprom_bytes_read(NV_EEPROM_NAME_LENGTH(offset), &length, 1); seeprom_bytes_read(NV_EEPROM_NAME_LENGTH(offset), &length, 1);
seeprom_bytes_read(NV_EEPROM_NAME_STRING(offset), (uint8_t *) & name, seeprom_bytes_read(NV_EEPROM_NAME_STRING(offset), (uint8_t *) & name,
NV_EEPROM_NAME_SIZE); NV_EEPROM_NAME_SIZE);
if (bacnet_name_isvalid(length, encoding, name)) { if (bacnet_name_isvalid(length, encoding, name)) {
characterstring_init(char_string, encoding, &name[0], length); characterstring_init(char_string, encoding, &name[0], length);
} else if (default_string) { } else if (default_string) {
bacnet_name_init(offset, char_string, default_string); bacnet_name_init(offset, char_string, default_string);
} }
} }
+60 -60
View File
@@ -1,60 +1,60 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef BACNET_NAME_H #ifndef BACNET_NAME_H
#define BACNET_NAME_H #define BACNET_NAME_H
#include <stdint.h> #include <stdint.h>
#include "bacstr.h" #include "bacstr.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
bool bacnet_name_set( bool bacnet_name_set(
uint16_t eeprom_offset, uint16_t eeprom_offset,
BACNET_CHARACTER_STRING *char_string); BACNET_CHARACTER_STRING *char_string);
void bacnet_name_init( void bacnet_name_init(
uint16_t eeprom_offset, uint16_t eeprom_offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
char *default_string); char *default_string);
void bacnet_name( void bacnet_name(
uint16_t eeprom_offset, uint16_t eeprom_offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
char *default_string); char *default_string);
bool bacnet_name_write( bool bacnet_name_write(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code); BACNET_ERROR_CODE *error_code);
/* no required minumum length or duplicate checking */ /* no required minumum length or duplicate checking */
bool bacnet_name_write_other( bool bacnet_name_write_other(
uint16_t offset, uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code); BACNET_ERROR_CODE *error_code);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+426 -426
View File
@@ -1,426 +1,426 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "config.h" #include "config.h"
#include "mstpdef.h" #include "mstpdef.h"
#include "automac.h" #include "automac.h"
/* MS/TP Auto MAC address functionality */ /* MS/TP Auto MAC address functionality */
/* table to track tokens and poll-for-master frames */ /* table to track tokens and poll-for-master frames */
typedef struct { typedef struct {
/* Poll For Master indicates empty slot */ /* Poll For Master indicates empty slot */
bool pfm:1; bool pfm:1;
/* a device that emits a frame indicates a used slot */ /* a device that emits a frame indicates a used slot */
bool emitter:1; bool emitter:1;
/* token - indicates a token was passed from this slot */ /* token - indicates a token was passed from this slot */
/* important to know who the Next Station is */ /* important to know who the Next Station is */
bool token:1; bool token:1;
/* reserve some slots for fixed addresses */ /* reserve some slots for fixed addresses */
bool reserved:1; bool reserved:1;
} AUTO_MAC_DATA; } AUTO_MAC_DATA;
/* starting number available for AutoMAC */ /* starting number available for AutoMAC */
#define MAC_SLOTS_OFFSET 32 #define MAC_SLOTS_OFFSET 32
/* total number of slots */ /* total number of slots */
#define MAC_SLOTS_MAX 128 #define MAC_SLOTS_MAX 128
static AUTO_MAC_DATA Auto_MAC_Data[MAC_SLOTS_MAX]; static AUTO_MAC_DATA Auto_MAC_Data[MAC_SLOTS_MAX];
/* my automatic MAC address */ /* my automatic MAC address */
static uint8_t My_MAC_Address; static uint8_t My_MAC_Address;
/* my no-token silence timer time slot in milliseconds */ /* my no-token silence timer time slot in milliseconds */
static uint16_t My_Time_Slot; static uint16_t My_Time_Slot;
/* indication that PFM has happened for a full cycle */ /* indication that PFM has happened for a full cycle */
static bool PFM_Cycle_Complete; static bool PFM_Cycle_Complete;
/* indicate that we are an auto-mode node */ /* indicate that we are an auto-mode node */
static bool Auto_Mode_Enabled; static bool Auto_Mode_Enabled;
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Indication that we are an automode node * DESCRIPTION: Indication that we are an automode node
* RETURN: true if automode enabled * RETURN: true if automode enabled
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool automac_enabled(void) bool automac_enabled(void)
{ {
return Auto_Mode_Enabled; return Auto_Mode_Enabled;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets the automode status * DESCRIPTION: Sets the automode status
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_enabled_set(bool status) void automac_enabled_set(bool status)
{ {
Auto_Mode_Enabled = status; Auto_Mode_Enabled = status;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Indication that PFM has happened for a full cycle * DESCRIPTION: Indication that PFM has happened for a full cycle
* RETURN: true if full * RETURN: true if full
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool automac_pfm_cycle_complete(void) bool automac_pfm_cycle_complete(void)
{ {
return PFM_Cycle_Complete; return PFM_Cycle_Complete;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Indicates that an address is used or taken * DESCRIPTION: Indicates that an address is used or taken
* RETURN: true if used * RETURN: true if used
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static bool automac_address_used(uint8_t mac) static bool automac_address_used(uint8_t mac)
{ {
bool status = false; bool status = false;
if (mac < MAC_SLOTS_MAX) { if (mac < MAC_SLOTS_MAX) {
if ((Auto_MAC_Data[mac].emitter) || if ((Auto_MAC_Data[mac].emitter) ||
(Auto_MAC_Data[mac].reserved) || (Auto_MAC_Data[mac].reserved) ||
(Auto_MAC_Data[mac].token)) { (Auto_MAC_Data[mac].token)) {
status = true; status = true;
} }
} }
return status; return status;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Validates an address as available, not taken, and within bounds * DESCRIPTION: Validates an address as available, not taken, and within bounds
* RETURN: true if valid * RETURN: true if valid
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool automac_free_address_valid(uint8_t mac) bool automac_free_address_valid(uint8_t mac)
{ {
bool status = false; bool status = false;
if (mac < MAC_SLOTS_MAX) { if (mac < MAC_SLOTS_MAX) {
if ((Auto_MAC_Data[mac].pfm) && if ((Auto_MAC_Data[mac].pfm) &&
(!automac_address_used(mac))) { (!automac_address_used(mac))) {
status = true; status = true;
} }
} }
return status; return status;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Determines the next station address to send the token * DESCRIPTION: Determines the next station address to send the token
* RETURN: Next_Station, or 255 if there are no next stations * RETURN: Next_Station, or 255 if there are no next stations
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint8_t automac_next_station(uint8_t mac) uint8_t automac_next_station(uint8_t mac)
{ {
uint8_t i = 0; /* loop counter */ uint8_t i = 0; /* loop counter */
uint8_t next_station = 255; /* return value */ uint8_t next_station = 255; /* return value */
uint8_t test_station = 0; /* station number to test for token */ uint8_t test_station = 0; /* station number to test for token */
test_station = (mac + 1) % 128; test_station = (mac + 1) % 128;
for (i = 0; i < MAC_SLOTS_MAX; i++) { for (i = 0; i < MAC_SLOTS_MAX; i++) {
if (Auto_MAC_Data[test_station].token) { if (Auto_MAC_Data[test_station].token) {
next_station = test_station; next_station = test_station;
break; break;
} }
test_station = (test_station + 1) % MAC_SLOTS_MAX; test_station = (test_station + 1) % MAC_SLOTS_MAX;
} }
return next_station; return next_station;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Determines the number of free MAC addresses * DESCRIPTION: Determines the number of free MAC addresses
* RETURN: Number of free MAC addresses * RETURN: Number of free MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint8_t automac_free_address_count(void) uint8_t automac_free_address_count(void)
{ {
uint8_t i = 0; uint8_t i = 0;
uint8_t slots = 0; uint8_t slots = 0;
for (i = 0; i < MAC_SLOTS_MAX; i++) { for (i = 0; i < MAC_SLOTS_MAX; i++) {
if (automac_free_address_valid(i)) { if (automac_free_address_valid(i)) {
slots++; slots++;
} }
} }
return slots; return slots;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Determines the number of free MAC addresses * DESCRIPTION: Determines the number of free MAC addresses
* RETURN: Number of free MAC addresses * RETURN: Number of free MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint8_t automac_free_address_mac(uint8_t count) uint8_t automac_free_address_mac(uint8_t count)
{ {
uint8_t i = 0; uint8_t i = 0;
uint8_t slots = 0; uint8_t slots = 0;
uint8_t mac = 255; uint8_t mac = 255;
for (i = 0; i < MAC_SLOTS_MAX; i++) { for (i = 0; i < MAC_SLOTS_MAX; i++) {
if (automac_free_address_valid(i)) { if (automac_free_address_valid(i)) {
if (slots == count) { if (slots == count) {
mac = i; mac = i;
break; break;
} }
slots++; slots++;
} }
} }
return mac; return mac;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Gets a free random address to use * DESCRIPTION: Gets a free random address to use
* RETURN: free MAC addresses * RETURN: free MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint8_t automac_free_address_random(void) uint8_t automac_free_address_random(void)
{ {
uint8_t count = 0; uint8_t count = 0;
uint8_t random_count = 0; uint8_t random_count = 0;
uint8_t mac = 255; uint8_t mac = 255;
count = automac_free_address_count(); count = automac_free_address_count();
if (count) { if (count) {
random_count = rand()%count; random_count = rand()%count;
mac = automac_free_address_mac(random_count); mac = automac_free_address_mac(random_count);
} }
return mac; return mac;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Gets the address stored. * DESCRIPTION: Gets the address stored.
* RETURN: MAC addresses * RETURN: MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint8_t automac_address(void) uint8_t automac_address(void)
{ {
return My_MAC_Address; return My_MAC_Address;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets the MAC address * DESCRIPTION: Sets the MAC address
* RETURN: MAC addresses * RETURN: MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_address_set(uint8_t mac) void automac_address_set(uint8_t mac)
{ {
My_MAC_Address = mac; My_MAC_Address = mac;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Gets the address stored. * DESCRIPTION: Gets the address stored.
* RETURN: MAC addresses * RETURN: MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint16_t automac_time_slot(void) uint16_t automac_time_slot(void)
{ {
return My_Time_Slot; return My_Time_Slot;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets the MAC address * DESCRIPTION: Sets the MAC address
* RETURN: MAC addresses * RETURN: MAC addresses
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_address_init(void) void automac_address_init(void)
{ {
My_MAC_Address = MAC_SLOTS_OFFSET + rand()%(MAC_SLOTS_MAX-MAC_SLOTS_OFFSET); My_MAC_Address = MAC_SLOTS_OFFSET + rand()%(MAC_SLOTS_MAX-MAC_SLOTS_OFFSET);
/* at least as long as a dropped token - worst case */ /* at least as long as a dropped token - worst case */
My_Time_Slot = Tno_token + (MAC_SLOTS_MAX * Tslot); My_Time_Slot = Tno_token + (MAC_SLOTS_MAX * Tslot);
My_Time_Slot += (uint16_t)My_MAC_Address * Tslot; My_Time_Slot += (uint16_t)My_MAC_Address * Tslot;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets an open address slot * DESCRIPTION: Sets an open address slot
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_pfm_set(uint8_t mac) void automac_pfm_set(uint8_t mac)
{ {
if (mac < MAC_SLOTS_MAX) { if (mac < MAC_SLOTS_MAX) {
if (Auto_MAC_Data[mac].pfm) { if (Auto_MAC_Data[mac].pfm) {
/* indicate that we have completed enough PFM to continue */ /* indicate that we have completed enough PFM to continue */
if (automac_free_address_count() > 0) { if (automac_free_address_count() > 0) {
PFM_Cycle_Complete = true; PFM_Cycle_Complete = true;
} }
} }
Auto_MAC_Data[mac].pfm = true; Auto_MAC_Data[mac].pfm = true;
} }
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets a used address slot * DESCRIPTION: Sets a used address slot
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_token_set(uint8_t mac) void automac_token_set(uint8_t mac)
{ {
if (mac < MAC_SLOTS_MAX) { if (mac < MAC_SLOTS_MAX) {
Auto_MAC_Data[mac].token = true; Auto_MAC_Data[mac].token = true;
} }
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets a used address slot * DESCRIPTION: Sets a used address slot
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_emitter_set(uint8_t mac) void automac_emitter_set(uint8_t mac)
{ {
if (mac < MAC_SLOTS_MAX) { if (mac < MAC_SLOTS_MAX) {
Auto_MAC_Data[mac].emitter = true; Auto_MAC_Data[mac].emitter = true;
} }
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Initializes the auto MAC module * DESCRIPTION: Initializes the auto MAC module
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void automac_init(void) void automac_init(void)
{ {
uint8_t i = 0; uint8_t i = 0;
for (i = 0; i < MAC_SLOTS_MAX; i++) { for (i = 0; i < MAC_SLOTS_MAX; i++) {
Auto_MAC_Data[i].token = false; Auto_MAC_Data[i].token = false;
Auto_MAC_Data[i].emitter = false; Auto_MAC_Data[i].emitter = false;
Auto_MAC_Data[i].pfm = false; Auto_MAC_Data[i].pfm = false;
if (i < MAC_SLOTS_OFFSET) { if (i < MAC_SLOTS_OFFSET) {
Auto_MAC_Data[i].reserved = true; Auto_MAC_Data[i].reserved = true;
} else { } else {
Auto_MAC_Data[i].reserved = false; Auto_MAC_Data[i].reserved = false;
} }
} }
automac_address_init(); automac_address_init();
PFM_Cycle_Complete = false; PFM_Cycle_Complete = false;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "ctest.h" #include "ctest.h"
/* test the ring buffer */ /* test the ring buffer */
void test_Auto_MAC( void test_Auto_MAC(
Test * pTest) Test * pTest)
{ {
uint8_t mac = 255; uint8_t mac = 255;
automac_init(); automac_init();
ct_test(pTest, automac_free_address_count() == 0); ct_test(pTest, automac_free_address_count() == 0);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == 255); ct_test(pTest, mac == 255);
automac_pfm_set(MAC_SLOTS_OFFSET); automac_pfm_set(MAC_SLOTS_OFFSET);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == MAC_SLOTS_OFFSET); ct_test(pTest, mac == MAC_SLOTS_OFFSET);
ct_test(pTest, automac_free_address_count() == 1); ct_test(pTest, automac_free_address_count() == 1);
automac_token_set(MAC_SLOTS_OFFSET); automac_token_set(MAC_SLOTS_OFFSET);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == 255); ct_test(pTest, mac == 255);
ct_test(pTest, automac_free_address_count() == 0); ct_test(pTest, automac_free_address_count() == 0);
automac_pfm_set(127); automac_pfm_set(127);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == 127); ct_test(pTest, mac == 127);
ct_test(pTest, automac_free_address_count() == 1); ct_test(pTest, automac_free_address_count() == 1);
automac_token_set(127); automac_token_set(127);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == 255); ct_test(pTest, mac == 255);
ct_test(pTest, automac_free_address_count() == 0); ct_test(pTest, automac_free_address_count() == 0);
/* the ANSI rand() uses consistent sequence based on seed */ /* the ANSI rand() uses consistent sequence based on seed */
srand(42); srand(42);
mac = automac_free_address_random(); mac = automac_free_address_random();
ct_test(pTest, mac == 255); ct_test(pTest, mac == 255);
automac_pfm_set(MAC_SLOTS_OFFSET+1); automac_pfm_set(MAC_SLOTS_OFFSET+1);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1)); ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1));
mac = automac_free_address_random(); mac = automac_free_address_random();
ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1)); ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1));
/* test 2 free addresses */ /* test 2 free addresses */
automac_pfm_set(MAC_SLOTS_OFFSET+2); automac_pfm_set(MAC_SLOTS_OFFSET+2);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1)); ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1));
mac = automac_free_address_mac(1); mac = automac_free_address_mac(1);
ct_test(pTest, mac == (MAC_SLOTS_OFFSET+2)); ct_test(pTest, mac == (MAC_SLOTS_OFFSET+2));
mac = automac_free_address_random(); mac = automac_free_address_random();
ct_test(pTest, ct_test(pTest,
(mac == (MAC_SLOTS_OFFSET+1)) || (mac == (MAC_SLOTS_OFFSET+1)) ||
(mac == (MAC_SLOTS_OFFSET+2))); (mac == (MAC_SLOTS_OFFSET+2)));
/* test 3 free addresses */ /* test 3 free addresses */
automac_pfm_set(126); automac_pfm_set(126);
mac = automac_free_address_mac(0); mac = automac_free_address_mac(0);
ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1)); ct_test(pTest, mac == (MAC_SLOTS_OFFSET+1));
mac = automac_free_address_mac(1); mac = automac_free_address_mac(1);
ct_test(pTest, mac == (MAC_SLOTS_OFFSET+2)); ct_test(pTest, mac == (MAC_SLOTS_OFFSET+2));
mac = automac_free_address_mac(2); mac = automac_free_address_mac(2);
ct_test(pTest, mac == 126); ct_test(pTest, mac == 126);
mac = automac_free_address_random(); mac = automac_free_address_random();
ct_test(pTest, ct_test(pTest,
(mac == (MAC_SLOTS_OFFSET+1))|| (mac == (MAC_SLOTS_OFFSET+1))||
(mac == (MAC_SLOTS_OFFSET+2))|| (mac == (MAC_SLOTS_OFFSET+2))||
(mac == 126)); (mac == 126));
/* test the stored address */ /* test the stored address */
mac = automac_address(); mac = automac_address();
ct_test(pTest, mac < MAC_SLOTS_MAX); ct_test(pTest, mac < MAC_SLOTS_MAX);
automac_address_set(MAC_SLOTS_OFFSET); automac_address_set(MAC_SLOTS_OFFSET);
mac = automac_address(); mac = automac_address();
ct_test(pTest, mac == MAC_SLOTS_OFFSET); ct_test(pTest, mac == MAC_SLOTS_OFFSET);
automac_init(); automac_init();
automac_token_set(0x6B); automac_token_set(0x6B);
mac = automac_next_station(0x25); mac = automac_next_station(0x25);
ct_test(pTest, mac == 0x6B); ct_test(pTest, mac == 0x6B);
} }
#ifdef TEST_AUTOMAC #ifdef TEST_AUTOMAC
int main( int main(
void) void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
pTest = ct_create("Auto MAC", NULL); pTest = ct_create("Auto MAC", NULL);
/* individual tests */ /* individual tests */
rc = ct_addTestFunction(pTest, test_Auto_MAC); rc = ct_addTestFunction(pTest, test_Auto_MAC);
assert(rc); assert(rc);
ct_setStream(pTest, stdout); ct_setStream(pTest, stdout);
ct_run(pTest); ct_run(pTest);
(void) ct_report(pTest); (void) ct_report(pTest);
ct_destroy(pTest); ct_destroy(pTest);
return 0; return 0;
} }
#endif #endif
#endif #endif
+59 -59
View File
@@ -1,59 +1,59 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef AUTOMAC_H #ifndef AUTOMAC_H
#define AUTOMAC_H #define AUTOMAC_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
/* MS/TP Auto MAC address functionality */ /* MS/TP Auto MAC address functionality */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void automac_init(void); void automac_init(void);
bool automac_free_address_valid(uint8_t mac); bool automac_free_address_valid(uint8_t mac);
uint8_t automac_free_address_count(void); uint8_t automac_free_address_count(void);
uint8_t automac_free_address_mac(uint8_t count); uint8_t automac_free_address_mac(uint8_t count);
uint8_t automac_free_address_random(void); uint8_t automac_free_address_random(void);
void automac_pfm_set(uint8_t mac); void automac_pfm_set(uint8_t mac);
void automac_token_set(uint8_t mac); void automac_token_set(uint8_t mac);
void automac_emitter_set(uint8_t mac); void automac_emitter_set(uint8_t mac);
uint8_t automac_next_station(uint8_t mac); uint8_t automac_next_station(uint8_t mac);
uint8_t automac_address(void); uint8_t automac_address(void);
void automac_address_set(uint8_t mac); void automac_address_set(uint8_t mac);
void automac_address_init(void); void automac_address_init(void);
uint16_t automac_time_slot(void); uint16_t automac_time_slot(void);
bool automac_pfm_cycle_complete(void); bool automac_pfm_cycle_complete(void);
bool automac_enabled(void); bool automac_enabled(void);
void automac_enabled_set(bool status); void automac_enabled_set(bool status);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+133 -133
View File
@@ -1,133 +1,133 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
/* hardware layer includes */ /* hardware layer includes */
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "rs485.h" #include "rs485.h"
/* BACnet Stack includes */ /* BACnet Stack includes */
#include "datalink.h" #include "datalink.h"
#include "npdu.h" #include "npdu.h"
#include "handlers.h" #include "handlers.h"
#include "client.h" #include "client.h"
#include "txbuf.h" #include "txbuf.h"
#include "dcc.h" #include "dcc.h"
#include "iam.h" #include "iam.h"
/* BACnet objects */ /* BACnet objects */
#include "device.h" #include "device.h"
#include "bo.h" #include "bo.h"
/* me */ /* me */
#include "bacnet.h" #include "bacnet.h"
/* timer for device communications control */ /* timer for device communications control */
static struct itimer DCC_Timer; static struct itimer DCC_Timer;
#define DCC_CYCLE_SECONDS 1 #define DCC_CYCLE_SECONDS 1
void bacnet_init( void bacnet_init(
void) void)
{ {
dlmstp_set_mac_address(255); dlmstp_set_mac_address(255);
dlmstp_set_max_master(127); dlmstp_set_max_master(127);
/* initialize datalink layer */ /* initialize datalink layer */
dlmstp_init(NULL); dlmstp_init(NULL);
/* initialize objects */ /* initialize objects */
Device_Init(NULL); Device_Init(NULL);
/* set up our confirmed service unrecognized service handler - required! */ /* set up our confirmed service unrecognized service handler - required! */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service); (handler_unrecognized_service);
/* we need to handle who-is to support dynamic device binding */ /* 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_IS, handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple); handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
handler_reinitialize_device); handler_reinitialize_device);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property); handler_write_property);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
/* start the cyclic 1 second timer for DCC */ /* start the cyclic 1 second timer for DCC */
timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS); timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS);
/* Hello World! */ /* Hello World! */
Send_I_Am(&Handler_Transmit_Buffer[0]); Send_I_Am(&Handler_Transmit_Buffer[0]);
} }
static uint8_t PDUBuffer[MAX_MPDU]; static uint8_t PDUBuffer[MAX_MPDU];
void bacnet_task( void bacnet_task(
void) void)
{ {
uint16_t pdu_len; uint16_t pdu_len;
BACNET_ADDRESS src; /* source address */ BACNET_ADDRESS src; /* source address */
uint8_t i; uint8_t i;
BACNET_BINARY_PV binary_value = BINARY_INACTIVE; BACNET_BINARY_PV binary_value = BINARY_INACTIVE;
BACNET_POLARITY polarity; BACNET_POLARITY polarity;
bool out_of_service; bool out_of_service;
/* Binary Output */ /* Binary Output */
for (i = 0; i < MAX_BINARY_OUTPUTS; i++) { for (i = 0; i < MAX_BINARY_OUTPUTS; i++) {
out_of_service = Binary_Output_Out_Of_Service(i); out_of_service = Binary_Output_Out_Of_Service(i);
if (!out_of_service) { if (!out_of_service) {
binary_value = Binary_Output_Present_Value(i); binary_value = Binary_Output_Present_Value(i);
polarity = Binary_Output_Polarity(i); polarity = Binary_Output_Polarity(i);
if (polarity != POLARITY_NORMAL) { if (polarity != POLARITY_NORMAL) {
if (binary_value == BINARY_ACTIVE) { if (binary_value == BINARY_ACTIVE) {
binary_value = BINARY_INACTIVE; binary_value = BINARY_INACTIVE;
} else { } else {
binary_value = BINARY_ACTIVE; binary_value = BINARY_ACTIVE;
} }
} }
if (binary_value == BINARY_ACTIVE) { if (binary_value == BINARY_ACTIVE) {
if (i == 0) { if (i == 0) {
/* led_on(LED_2); */ /* led_on(LED_2); */
} else { } else {
/* led_on(LED_3); */ /* led_on(LED_3); */
} }
} else { } else {
if (i == 0) { if (i == 0) {
/* led_off(LED_2); */ /* led_off(LED_2); */
} else { } else {
/* led_off(LED_3); */ /* led_off(LED_3); */
} }
} }
} }
} }
/* handle the communication timer */ /* handle the communication timer */
if (timer_interval_expired(&DCC_Timer)) { if (timer_interval_expired(&DCC_Timer)) {
timer_interval_reset(&DCC_Timer); timer_interval_reset(&DCC_Timer);
dcc_timer_seconds(DCC_CYCLE_SECONDS); dcc_timer_seconds(DCC_CYCLE_SECONDS);
} }
/* handle the messaging */ /* handle the messaging */
pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0);
if (pdu_len) { if (pdu_len) {
npdu_handler(&src, &PDUBuffer[0], pdu_len); npdu_handler(&src, &PDUBuffer[0], pdu_len);
} }
} }
+41 -41
View File
@@ -1,41 +1,41 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef BACNET_H #ifndef BACNET_H
#define BACNET_H #define BACNET_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void bacnet_init( void bacnet_init(
void); void);
void bacnet_task( void bacnet_task(
void); void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+33 -33
View File
@@ -1,33 +1,33 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef HARDWARE_H #ifndef HARDWARE_H
#define HARDWARE_H #define HARDWARE_H
#include "stm32f10x_conf.h" #include "stm32f10x_conf.h"
#include "stm32f10x_it.h" #include "stm32f10x_it.h"
#define MAX_BINARY_OUTPUTS 2 #define MAX_BINARY_OUTPUTS 2
#endif #endif
+308 -308
View File
@@ -1,308 +1,308 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "led.h" #include "led.h"
static struct itimer Off_Delay_Timer_Rx; static struct itimer Off_Delay_Timer_Rx;
static struct itimer Off_Delay_Timer_Tx; static struct itimer Off_Delay_Timer_Tx;
static bool Rx_State; static bool Rx_State;
static bool Tx_State; static bool Tx_State;
static bool LD3_State; static bool LD3_State;
/************************************************************************* /*************************************************************************
* Description: Activate the LED * Description: Activate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_tx_on( void led_tx_on(
void) void)
{ {
GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_SET); GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_SET);
timer_interval_no_expire(&Off_Delay_Timer_Tx); timer_interval_no_expire(&Off_Delay_Timer_Tx);
Tx_State = true; Tx_State = true;
} }
/************************************************************************* /*************************************************************************
* Description: Activate the LED * Description: Activate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_rx_on( void led_rx_on(
void) void)
{ {
GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_SET); GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_SET);
timer_interval_no_expire(&Off_Delay_Timer_Rx); timer_interval_no_expire(&Off_Delay_Timer_Rx);
Rx_State = true; Rx_State = true;
} }
/************************************************************************* /*************************************************************************
* Description: Deactivate the LED * Description: Deactivate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_tx_off( void led_tx_off(
void) void)
{ {
GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_RESET);
timer_interval_no_expire(&Off_Delay_Timer_Tx); timer_interval_no_expire(&Off_Delay_Timer_Tx);
Tx_State = false; Tx_State = false;
} }
/************************************************************************* /*************************************************************************
* Description: Deactivate the LED * Description: Deactivate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_rx_off( void led_rx_off(
void) void)
{ {
GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_RESET);
timer_interval_no_expire(&Off_Delay_Timer_Rx); timer_interval_no_expire(&Off_Delay_Timer_Rx);
Rx_State = false; Rx_State = false;
} }
/************************************************************************* /*************************************************************************
* Description: Get the state of the LED * Description: Get the state of the LED
* Returns: true if on, false if off. * Returns: true if on, false if off.
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool led_rx_state(void) bool led_rx_state(void)
{ {
return Rx_State; return Rx_State;
} }
/************************************************************************* /*************************************************************************
* Description: Get the state of the LED * Description: Get the state of the LED
* Returns: true if on, false if off. * Returns: true if on, false if off.
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool led_tx_state(void) bool led_tx_state(void)
{ {
return Tx_State; return Tx_State;
} }
/************************************************************************* /*************************************************************************
* Description: Toggle the state of the LED * Description: Toggle the state of the LED
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_tx_toggle(void) void led_tx_toggle(void)
{ {
if (led_tx_state()) { if (led_tx_state()) {
led_tx_off(); led_tx_off();
} else { } else {
led_tx_on(); led_tx_on();
} }
} }
/************************************************************************* /*************************************************************************
* Description: Toggle the state of the LED * Description: Toggle the state of the LED
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_rx_toggle(void) void led_rx_toggle(void)
{ {
if (led_rx_state()) { if (led_rx_state()) {
led_rx_off(); led_rx_off();
} else { } else {
led_rx_on(); led_rx_on();
} }
} }
/************************************************************************* /*************************************************************************
* Description: Delay before going off to give minimum brightness. * Description: Delay before going off to give minimum brightness.
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_rx_off_delay( void led_rx_off_delay(
uint32_t delay_ms) uint32_t delay_ms)
{ {
timer_interval_start(&Off_Delay_Timer_Rx, delay_ms); timer_interval_start(&Off_Delay_Timer_Rx, delay_ms);
} }
/************************************************************************* /*************************************************************************
* Description: Delay before going off to give minimum brightness. * Description: Delay before going off to give minimum brightness.
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_tx_off_delay( void led_tx_off_delay(
uint32_t delay_ms) uint32_t delay_ms)
{ {
timer_interval_start(&Off_Delay_Timer_Tx, delay_ms); timer_interval_start(&Off_Delay_Timer_Tx, delay_ms);
} }
/************************************************************************* /*************************************************************************
* Description: Turn on, and delay before going off. * Description: Turn on, and delay before going off.
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_rx_on_interval( void led_rx_on_interval(
uint16_t interval_ms) uint16_t interval_ms)
{ {
led_rx_on(); led_rx_on();
timer_interval_start(&Off_Delay_Timer_Rx, interval_ms); timer_interval_start(&Off_Delay_Timer_Rx, interval_ms);
} }
/************************************************************************* /*************************************************************************
* Description: Turn on, and delay before going off. * Description: Turn on, and delay before going off.
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_tx_on_interval( void led_tx_on_interval(
uint16_t interval_ms) uint16_t interval_ms)
{ {
led_tx_on(); led_tx_on();
timer_interval_start(&Off_Delay_Timer_Tx, interval_ms); timer_interval_start(&Off_Delay_Timer_Tx, interval_ms);
} }
/************************************************************************* /*************************************************************************
* Description: Task for blinking LED * Description: Task for blinking LED
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_task( void led_task(
void) void)
{ {
if (timer_interval_expired(&Off_Delay_Timer_Rx)) { if (timer_interval_expired(&Off_Delay_Timer_Rx)) {
timer_interval_no_expire(&Off_Delay_Timer_Rx); timer_interval_no_expire(&Off_Delay_Timer_Rx);
led_rx_off(); led_rx_off();
} }
if (timer_interval_expired(&Off_Delay_Timer_Tx)) { if (timer_interval_expired(&Off_Delay_Timer_Tx)) {
timer_interval_no_expire(&Off_Delay_Timer_Tx); timer_interval_no_expire(&Off_Delay_Timer_Tx);
led_tx_off(); led_tx_off();
} }
} }
/************************************************************************* /*************************************************************************
* Description: Activate the LED * Description: Activate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_ld4_on( void led_ld4_on(
void) void)
{ {
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET); GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
} }
/************************************************************************* /*************************************************************************
* Description: Deactivate the LED * Description: Deactivate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_ld4_off( void led_ld4_off(
void) void)
{ {
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET); GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
} }
/************************************************************************* /*************************************************************************
* Description: Activate the LED * Description: Activate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_ld3_on( void led_ld3_on(
void) void)
{ {
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET); GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
LD3_State = true; LD3_State = true;
} }
/************************************************************************* /*************************************************************************
* Description: Deactivate the LED * Description: Deactivate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void led_ld3_off( void led_ld3_off(
void) void)
{ {
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET); GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET);
LD3_State = false; LD3_State = false;
} }
/************************************************************************* /*************************************************************************
* Description: Get the state of the LED * Description: Get the state of the LED
* Returns: true if on, false if off. * Returns: true if on, false if off.
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool led_ld3_state(void) bool led_ld3_state(void)
{ {
return LD3_State; return LD3_State;
} }
/************************************************************************* /*************************************************************************
* Description: Toggle the state of the LED * Description: Toggle the state of the LED
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_ld3_toggle(void) void led_ld3_toggle(void)
{ {
if (led_ld3_state()) { if (led_ld3_state()) {
led_ld3_off(); led_ld3_off();
} else { } else {
led_ld3_on(); led_ld3_on();
} }
} }
/************************************************************************* /*************************************************************************
* Description: Initialize the LED hardware * Description: Initialize the LED hardware
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_init( void led_init(
void) void)
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure); GPIO_StructInit(&GPIO_InitStructure);
/* Configure the Receive LED on MS/TP board */ /* Configure the Receive LED on MS/TP board */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure the Transmit LED on MS/TP board */ /* Configure the Transmit LED on MS/TP board */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* Configure the LD4 on Discovery board */ /* Configure the LD4 on Discovery board */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure the LD3 on Discovery board */ /* Configure the LD3 on Discovery board */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable the GPIO_LED Clock */ /* Enable the GPIO_LED Clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
led_tx_on(); led_tx_on();
led_rx_on(); led_rx_on();
led_ld3_on(); led_ld3_on();
led_ld4_on(); led_ld4_on();
} }
+75 -75
View File
@@ -1,75 +1,75 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef LED_H #ifndef LED_H
#define LED_H #define LED_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void led_ld3_on( void led_ld3_on(
void); void);
void led_ld4_on( void led_ld4_on(
void); void);
void led_ld3_off( void led_ld3_off(
void); void);
void led_ld4_off( void led_ld4_off(
void); void);
bool led_ld3_state(void); bool led_ld3_state(void);
void led_ld3_toggle(void); void led_ld3_toggle(void);
void led_tx_on(void); void led_tx_on(void);
void led_rx_on(void); void led_rx_on(void);
void led_tx_on_interval( void led_tx_on_interval(
uint16_t interval_ms); uint16_t interval_ms);
void led_rx_on_interval( void led_rx_on_interval(
uint16_t interval_ms); uint16_t interval_ms);
void led_tx_off(void); void led_tx_off(void);
void led_rx_off(void); void led_rx_off(void);
void led_tx_off_delay( void led_tx_off_delay(
uint32_t delay_ms); uint32_t delay_ms);
void led_rx_off_delay( void led_rx_off_delay(
uint32_t delay_ms); uint32_t delay_ms);
void led_tx_toggle(void); void led_tx_toggle(void);
void led_rx_toggle(void); void led_rx_toggle(void);
bool led_tx_state(void); bool led_tx_state(void);
bool led_rx_state(void); bool led_rx_state(void);
void led_task( void led_task(
void); void);
void led_init( void led_init(
void); void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+142 -142
View File
@@ -1,142 +1,142 @@
/************************************************************************ /************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*************************************************************************/ *************************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "timer.h" #include "timer.h"
#include "rs485.h" #include "rs485.h"
#include "led.h" #include "led.h"
#include "bacnet.h" #include "bacnet.h"
/* local version override */ /* local version override */
char *BACnet_Version = "1.0"; char *BACnet_Version = "1.0";
#ifdef USE_FULL_ASSERT #ifdef USE_FULL_ASSERT
/** /**
* @brief Reports the name of the source file and the source line number * @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred. * where the assert_param error has occurred.
* @param file: pointer to the source file name * @param file: pointer to the source file name
* @param line: assert_param error line source number * @param line: assert_param error line source number
* @retval None * @retval None
*/ */
void assert_failed(uint8_t* file, uint32_t line) void assert_failed(uint8_t* file, uint32_t line)
{ {
/* User can add his own implementation to report the file name and line number, /* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */ /* Infinite loop */
while (1) while (1)
{ {
} }
} }
#endif #endif
/* Private define ------------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/
#define LSE_FAIL_FLAG 0x80 #define LSE_FAIL_FLAG 0x80
#define LSE_PASS_FLAG 0x100 #define LSE_PASS_FLAG 0x100
void lse_init(void) void lse_init(void)
{ {
uint32_t LSE_Delay = 0; uint32_t LSE_Delay = 0;
struct etimer Delay_Timer; struct etimer Delay_Timer;
/* Enable access to the backup register => LSE can be enabled */ /* Enable access to the backup register => LSE can be enabled */
PWR_BackupAccessCmd(ENABLE); PWR_BackupAccessCmd(ENABLE);
/* Enable LSE (Low Speed External Oscillation) */ /* Enable LSE (Low Speed External Oscillation) */
RCC_LSEConfig(RCC_LSE_ON); RCC_LSEConfig(RCC_LSE_ON);
/* Check the LSE Status */ /* Check the LSE Status */
while(1) while(1)
{ {
if(LSE_Delay < LSE_FAIL_FLAG) if(LSE_Delay < LSE_FAIL_FLAG)
{ {
timer_elapsed_start(&Delay_Timer); timer_elapsed_start(&Delay_Timer);
while (!timer_elapsed_milliseconds(&Delay_Timer,500)) { while (!timer_elapsed_milliseconds(&Delay_Timer,500)) {
/* do nothing */ /* do nothing */
} }
/* check whether LSE is ready, with 4 seconds timeout */ /* check whether LSE is ready, with 4 seconds timeout */
LSE_Delay += 0x10; LSE_Delay += 0x10;
if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET) if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET)
{ {
/* Set flag: LSE PASS */ /* Set flag: LSE PASS */
LSE_Delay |= LSE_PASS_FLAG; LSE_Delay |= LSE_PASS_FLAG;
led_ld4_off(); led_ld4_off();
/* Disable LSE */ /* Disable LSE */
RCC_LSEConfig(RCC_LSE_OFF); RCC_LSEConfig(RCC_LSE_OFF);
break; break;
} }
} }
/* LSE_FAIL_FLAG = 0x80 */ /* LSE_FAIL_FLAG = 0x80 */
else if(LSE_Delay >= LSE_FAIL_FLAG) else if(LSE_Delay >= LSE_FAIL_FLAG)
{ {
if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{ {
/* Set flag: LSE FAIL */ /* Set flag: LSE FAIL */
LSE_Delay |= LSE_FAIL_FLAG; LSE_Delay |= LSE_FAIL_FLAG;
led_ld4_on(); led_ld4_on();
} }
/* Disable LSE */ /* Disable LSE */
RCC_LSEConfig(RCC_LSE_OFF); RCC_LSEConfig(RCC_LSE_OFF);
break; break;
} }
} }
} }
int main( int main(
void) void)
{ {
struct itimer Blink_Timer; struct itimer Blink_Timer;
/*At this stage the microcontroller clock setting is already configured, /*At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main. file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file */ system_stm32f10x.c file */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
led_init(); led_init();
RCC_APB2PeriphClockCmd( RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE); RCC_APB2Periph_GPIOE, ENABLE);
timer_init(); timer_init();
lse_init(); lse_init();
led_init(); led_init();
rs485_init(); rs485_init();
bacnet_init(); bacnet_init();
timer_interval_start(&Blink_Timer, 125); timer_interval_start(&Blink_Timer, 125);
for (;;) { for (;;) {
if (timer_interval_expired(&Blink_Timer)) { if (timer_interval_expired(&Blink_Timer)) {
timer_interval_reset(&Blink_Timer); timer_interval_reset(&Blink_Timer);
led_ld3_toggle(); led_ld3_toggle();
} }
led_task(); led_task();
bacnet_task(); bacnet_task();
} }
} }
+340 -340
View File
@@ -1,340 +1,340 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* Module Description: * Module Description:
* Handle the configuration and operation of the RS485 bus. * Handle the configuration and operation of the RS485 bus.
**************************************************************************/ **************************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "bits.h" #include "bits.h"
#include "fifo.h" #include "fifo.h"
#include "led.h" #include "led.h"
#include "rs485.h" #include "rs485.h"
/* buffer for storing received bytes - size must be power of two */ /* buffer for storing received bytes - size must be power of two */
static uint8_t Receive_Buffer_Data[512]; static uint8_t Receive_Buffer_Data[512];
static FIFO_BUFFER Receive_Buffer; static FIFO_BUFFER Receive_Buffer;
/* amount of silence on the wire */ /* amount of silence on the wire */
static struct etimer Silence_Timer; static struct etimer Silence_Timer;
/* baud rate */ /* baud rate */
static uint32_t Baud_Rate = 38400; static uint32_t Baud_Rate = 38400;
/* The minimum time after the end of the stop bit of the final octet of a */ /* The minimum time after the end of the stop bit of the final octet of a */
/* received frame before a node may enable its EIA-485 driver: 40 bit times. */ /* received frame before a node may enable its EIA-485 driver: 40 bit times. */
/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */ /* At 9600 baud, 40 bit times would be about 4.166 milliseconds */
/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */ /* At 19200 baud, 40 bit times would be about 2.083 milliseconds */
/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */ /* At 38400 baud, 40 bit times would be about 1.041 milliseconds */
/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */ /* At 57600 baud, 40 bit times would be about 0.694 milliseconds */
/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */ /* At 76800 baud, 40 bit times would be about 0.520 milliseconds */
/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */ /* At 115200 baud, 40 bit times would be about 0.347 milliseconds */
/* 40 bits is 4 octets including a start and stop bit with each octet */ /* 40 bits is 4 octets including a start and stop bit with each octet */
#define Tturnaround (40UL) #define Tturnaround (40UL)
/************************************************************************* /*************************************************************************
* Description: Reset the silence on the wire timer. * Description: Reset the silence on the wire timer.
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void rs485_silence_reset(void) void rs485_silence_reset(void)
{ {
timer_elapsed_start(&Silence_Timer); timer_elapsed_start(&Silence_Timer);
} }
/************************************************************************* /*************************************************************************
* Description: Determine the amount of silence on the wire from the timer. * Description: Determine the amount of silence on the wire from the timer.
* Returns: true if the amount of time has elapsed * Returns: true if the amount of time has elapsed
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
bool rs485_silence_elapsed(uint32_t interval) bool rs485_silence_elapsed(uint32_t interval)
{ {
return timer_elapsed_milliseconds(&Silence_Timer, interval); return timer_elapsed_milliseconds(&Silence_Timer, interval);
} }
/************************************************************************* /*************************************************************************
* Description: Baud rate determines turnaround time. * Description: Baud rate determines turnaround time.
* Returns: amount of milliseconds * Returns: amount of milliseconds
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
static uint16_t rs485_turnaround_time( static uint16_t rs485_turnaround_time(
void) void)
{ {
/* delay after reception before transmitting - per MS/TP spec */ /* delay after reception before transmitting - per MS/TP spec */
/* wait a minimum 40 bit times since reception */ /* wait a minimum 40 bit times since reception */
/* at least 2 ms for errors: rounding, clock tick */ /* at least 2 ms for errors: rounding, clock tick */
return (2 + ((Tturnaround * 1000UL) / Baud_Rate)); return (2 + ((Tturnaround * 1000UL) / Baud_Rate));
} }
/************************************************************************* /*************************************************************************
* Description: Use the silence timer to determine turnaround time. * Description: Use the silence timer to determine turnaround time.
* Returns: true if turnaround time has expired. * Returns: true if turnaround time has expired.
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
bool rs485_turnaround_elapsed( bool rs485_turnaround_elapsed(
void) void)
{ {
return timer_elapsed_milliseconds( return timer_elapsed_milliseconds(
&Silence_Timer, &Silence_Timer,
rs485_turnaround_time()); rs485_turnaround_time());
} }
/************************************************************************* /*************************************************************************
* Description: Determines if an error occured while receiving * Description: Determines if an error occured while receiving
* Returns: true an error occurred. * Returns: true an error occurred.
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
bool rs485_receive_error( bool rs485_receive_error(
void) void)
{ {
return false; return false;
} }
/*********************************************************************//** /*********************************************************************//**
* @brief USARTx interrupt handler sub-routine * @brief USARTx interrupt handler sub-routine
* @param[in] None * @param[in] None
* @return None * @return None
**********************************************************************/ **********************************************************************/
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
{ {
uint8_t data_byte; uint8_t data_byte;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
/* Read one byte from the receive data register */ /* Read one byte from the receive data register */
data_byte = USART_ReceiveData(USART2); data_byte = USART_ReceiveData(USART2);
(void)FIFO_Put(&Receive_Buffer, data_byte); (void)FIFO_Put(&Receive_Buffer, data_byte);
} }
} }
/************************************************************************* /*************************************************************************
* DESCRIPTION: Return true if a byte is available * DESCRIPTION: Return true if a byte is available
* RETURN: true if a byte is available, with the byte in the parameter * RETURN: true if a byte is available, with the byte in the parameter
* NOTES: none * NOTES: none
**************************************************************************/ **************************************************************************/
bool rs485_byte_available( bool rs485_byte_available(
uint8_t * data_register) uint8_t * data_register)
{ {
bool data_available = false; /* return value */ bool data_available = false; /* return value */
if (!FIFO_Empty(&Receive_Buffer)) { if (!FIFO_Empty(&Receive_Buffer)) {
*data_register = FIFO_Get(&Receive_Buffer); *data_register = FIFO_Get(&Receive_Buffer);
timer_elapsed_start(&Silence_Timer); timer_elapsed_start(&Silence_Timer);
data_available = true; data_available = true;
led_rx_on_interval(10); led_rx_on_interval(10);
} }
return data_available; return data_available;
} }
/************************************************************************* /*************************************************************************
* DESCRIPTION: Sends a byte of data * DESCRIPTION: Sends a byte of data
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
**************************************************************************/ **************************************************************************/
void rs485_byte_send(uint8_t tx_byte) void rs485_byte_send(uint8_t tx_byte)
{ {
led_tx_on_interval(10); led_tx_on_interval(10);
USART_SendData(USART2, tx_byte); USART_SendData(USART2, tx_byte);
timer_elapsed_start(&Silence_Timer); timer_elapsed_start(&Silence_Timer);
} }
/************************************************************************* /*************************************************************************
* Description: Determines if a byte in the USART has been shifted from * Description: Determines if a byte in the USART has been shifted from
* register * register
* Returns: true if the USART register is empty * Returns: true if the USART register is empty
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
bool rs485_byte_sent(void) bool rs485_byte_sent(void)
{ {
return USART_GetFlagStatus(USART2, USART_FLAG_TXE); return USART_GetFlagStatus(USART2, USART_FLAG_TXE);
} }
/************************************************************************* /*************************************************************************
* Description: Determines if the entire frame is sent from USART FIFO * Description: Determines if the entire frame is sent from USART FIFO
* Returns: true if the USART FIFO is empty * Returns: true if the USART FIFO is empty
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
bool rs485_frame_sent(void) bool rs485_frame_sent(void)
{ {
return USART_GetFlagStatus(USART2, USART_FLAG_TC); return USART_GetFlagStatus(USART2, USART_FLAG_TC);
} }
/************************************************************************* /*************************************************************************
* DESCRIPTION: Send some data and wait until it is sent * DESCRIPTION: Send some data and wait until it is sent
* RETURN: true if a collision or timeout occurred * RETURN: true if a collision or timeout occurred
* NOTES: none * NOTES: none
**************************************************************************/ **************************************************************************/
void rs485_bytes_send( void rs485_bytes_send(
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
uint16_t nbytes) /* number of bytes of data */ uint16_t nbytes) /* number of bytes of data */
{ {
uint8_t tx_byte; uint8_t tx_byte;
while (nbytes) { while (nbytes) {
/* Send the data byte */ /* Send the data byte */
tx_byte = *buffer; tx_byte = *buffer;
/* Send one byte */ /* Send one byte */
USART_SendData(USART2, tx_byte); USART_SendData(USART2, tx_byte);
while (!rs485_byte_sent()) { while (!rs485_byte_sent()) {
/* do nothing - wait until Tx buffer is empty */ /* do nothing - wait until Tx buffer is empty */
} }
buffer++; buffer++;
nbytes--; nbytes--;
} }
/* was the frame sent? */ /* was the frame sent? */
while (!rs485_frame_sent()) { while (!rs485_frame_sent()) {
/* do nothing - wait until the entire frame in the /* do nothing - wait until the entire frame in the
Transmit Shift Register has been shifted out */ Transmit Shift Register has been shifted out */
} }
timer_elapsed_start(&Silence_Timer); timer_elapsed_start(&Silence_Timer);
return; return;
} }
/************************************************************************* /*************************************************************************
* Description: Configures the baud rate of the USART * Description: Configures the baud rate of the USART
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
static void rs485_baud_rate_configure( static void rs485_baud_rate_configure(
void) void)
{ {
USART_InitTypeDef USART_InitStructure; USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = Baud_Rate; USART_InitStructure.USART_BaudRate = Baud_Rate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None; USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USARTx */ /* Configure USARTx */
USART_Init(USART2, &USART_InitStructure); USART_Init(USART2, &USART_InitStructure);
} }
/************************************************************************* /*************************************************************************
* Description: Sets the baud rate to non-volatile storeage and configures USART * Description: Sets the baud rate to non-volatile storeage and configures USART
* Returns: true if a value baud rate was saved * Returns: true if a value baud rate was saved
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
bool rs485_baud_rate_set( bool rs485_baud_rate_set(
uint32_t baud) uint32_t baud)
{ {
bool valid = true; bool valid = true;
switch (baud) { switch (baud) {
case 9600: case 9600:
case 19200: case 19200:
case 38400: case 38400:
case 57600: case 57600:
case 76800: case 76800:
case 115200: case 115200:
Baud_Rate = baud; Baud_Rate = baud;
rs485_baud_rate_configure(); rs485_baud_rate_configure();
break; break;
default: default:
valid = false; valid = false;
break; break;
} }
return valid; return valid;
} }
/************************************************************************* /*************************************************************************
* Description: Determines the baud rate in bps * Description: Determines the baud rate in bps
* Returns: baud rate in bps * Returns: baud rate in bps
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
uint32_t rs485_baud_rate( uint32_t rs485_baud_rate(
void) void)
{ {
return Baud_Rate; return Baud_Rate;
} }
/************************************************************************* /*************************************************************************
* Description: Enable the Request To Send (RTS) aka Transmit Enable pin * Description: Enable the Request To Send (RTS) aka Transmit Enable pin
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void rs485_rts_enable( void rs485_rts_enable(
bool enable) bool enable)
{ {
if (enable) { if (enable) {
GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET); GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);
} else { } else {
GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET); GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);
} }
} }
/************************************************************************* /*************************************************************************
* Description: Initialize the room network USART * Description: Initialize the room network USART
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void rs485_init(void) void rs485_init(void)
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
GPIO_StructInit(&GPIO_InitStructure); GPIO_StructInit(&GPIO_InitStructure);
/* Configure USARTx Rx as input floating */ /* Configure USARTx Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USARTx Tx as alternate function push-pull */ /* Configure USARTx Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure the Request To Send (RTS) aka Transmit Enable pin */ /* Configure the Request To Send (RTS) aka Transmit Enable pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable USARTx Clock */ /* Enable USARTx Clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Enable GPIO Clock */ /* Enable GPIO Clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure the NVIC Preemption Priority Bits */ /* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USARTx Interrupt */ /* Enable the USARTx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
/* enable the USART to generate interrupts */ /* enable the USART to generate interrupts */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
rs485_baud_rate_set(Baud_Rate); rs485_baud_rate_set(Baud_Rate);
USART_Cmd(USART2, ENABLE); USART_Cmd(USART2, ENABLE);
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
(unsigned)sizeof(Receive_Buffer_Data)); (unsigned)sizeof(Receive_Buffer_Data));
timer_elapsed_start(&Silence_Timer); timer_elapsed_start(&Silence_Timer);
} }
+66 -66
View File
@@ -1,66 +1,66 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* Module Description: * Module Description:
* Handle the configuration and operation of the RS485 bus. * Handle the configuration and operation of the RS485 bus.
**************************************************************************/ **************************************************************************/
#ifndef RS485_H #ifndef RS485_H
#define RS485_H #define RS485_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void rs485_init( void rs485_init(
void); void);
void rs485_rts_enable( void rs485_rts_enable(
bool enable); bool enable);
bool rs485_byte_available( bool rs485_byte_available(
uint8_t * data_register); uint8_t * data_register);
bool rs485_receive_error( bool rs485_receive_error(
void); void);
void rs485_bytes_send( void rs485_bytes_send(
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
uint16_t nbytes); /* number of bytes of data */ uint16_t nbytes); /* number of bytes of data */
uint32_t rs485_baud_rate( uint32_t rs485_baud_rate(
void); void);
bool rs485_baud_rate_set( bool rs485_baud_rate_set(
uint32_t baud); uint32_t baud);
/* a granular approach */ /* a granular approach */
void rs485_byte_send( void rs485_byte_send(
uint8_t data_register); uint8_t data_register);
bool rs485_byte_sent(void); bool rs485_byte_sent(void);
bool rs485_frame_sent(void); bool rs485_frame_sent(void);
bool rs485_turnaround_elapsed( bool rs485_turnaround_elapsed(
void); void);
void rs485_silence_reset(void); void rs485_silence_reset(void);
bool rs485_silence_elapsed(uint32_t interval); bool rs485_silence_elapsed(uint32_t interval);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+74 -74
View File
@@ -1,74 +1,74 @@
/** /**
****************************************************************************** ******************************************************************************
* @file I2C/EEPROM/stm32f10x_conf.h * @file I2C/EEPROM/stm32f10x_conf.h
* @author MCD Application Team * @author MCD Application Team
* @version V3.4.0 * @version V3.4.0
* @date 10/15/2010 * @date 10/15/2010
* @brief Library configuration file. * @brief Library configuration file.
****************************************************************************** ******************************************************************************
* @copy * @copy
* *
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* *
* <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2> * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
*/ */
/* Define to prevent recursive inclusion -------------------------------------*/ /* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_CONF_H #ifndef __STM32F10x_CONF_H
#define __STM32F10x_CONF_H #define __STM32F10x_CONF_H
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
/* Uncomment the line below to enable peripheral header file inclusion */ /* Uncomment the line below to enable peripheral header file inclusion */
#include "stm32f10x_adc.h" #include "stm32f10x_adc.h"
#include "stm32f10x_bkp.h" #include "stm32f10x_bkp.h"
#include "stm32f10x_can.h" #include "stm32f10x_can.h"
#include "stm32f10x_cec.h" #include "stm32f10x_cec.h"
#include "stm32f10x_crc.h" #include "stm32f10x_crc.h"
#include "stm32f10x_dac.h" #include "stm32f10x_dac.h"
#include "stm32f10x_dbgmcu.h" #include "stm32f10x_dbgmcu.h"
#include "stm32f10x_dma.h" #include "stm32f10x_dma.h"
#include "stm32f10x_exti.h" #include "stm32f10x_exti.h"
#include "stm32f10x_flash.h" #include "stm32f10x_flash.h"
#include "stm32f10x_fsmc.h" #include "stm32f10x_fsmc.h"
#include "stm32f10x_gpio.h" #include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h" #include "stm32f10x_i2c.h"
#include "stm32f10x_iwdg.h" #include "stm32f10x_iwdg.h"
#include "stm32f10x_pwr.h" #include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h" #include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h" #include "stm32f10x_rtc.h"
#include "stm32f10x_sdio.h" #include "stm32f10x_sdio.h"
#include "stm32f10x_spi.h" #include "stm32f10x_spi.h"
#include "stm32f10x_tim.h" #include "stm32f10x_tim.h"
#include "stm32f10x_usart.h" #include "stm32f10x_usart.h"
#include "stm32f10x_wwdg.h" #include "stm32f10x_wwdg.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
/* Exported types ------------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the /* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */ Standard Peripheral Library drivers code */
#ifdef USE_FULL_ASSERT #ifdef USE_FULL_ASSERT
/** /**
* @brief The assert_param macro is used for function's parameters check. * @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function * @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source * which reports the name of the source file and the source
* line number of the call that failed. * line number of the call that failed.
* If expr is true, it returns no value. * If expr is true, it returns no value.
* @retval None * @retval None
*/ */
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line); void assert_failed(uint8_t* file, uint32_t line);
#else #else
#define assert_param(expr) ((void)0) #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */ #endif /* USE_FULL_ASSERT */
#endif /* __STM32F10x_CONF_H */ #endif /* __STM32F10x_CONF_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
+133 -133
View File
@@ -1,133 +1,133 @@
/** /**
****************************************************************************** ******************************************************************************
* @file I2C/EEPROM/stm32f10x_it.c * @file I2C/EEPROM/stm32f10x_it.c
* @author MCD Application Team * @author MCD Application Team
* @version V3.4.0 * @version V3.4.0
* @date 10/15/2010 * @date 10/15/2010
* @brief Main Interrupt Service Routines. * @brief Main Interrupt Service Routines.
* This file provides template for all exceptions handler and * This file provides template for all exceptions handler and
* peripherals interrupt service routine. * peripherals interrupt service routine.
****************************************************************************** ******************************************************************************
* @copy * @copy
* *
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* *
* <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2> * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
*/ */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h" #include "stm32f10x_it.h"
/** @addtogroup STM32F10x_StdPeriph_Examples /** @addtogroup STM32F10x_StdPeriph_Examples
* @{ * @{
*/ */
/** @addtogroup I2C_EEPROM /** @addtogroup I2C_EEPROM
* @{ * @{
*/ */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/
/******************************************************************************/ /******************************************************************************/
/* Cortex-M3 Processor Exceptions Handlers */ /* Cortex-M3 Processor Exceptions Handlers */
/******************************************************************************/ /******************************************************************************/
/** /**
* @brief This function handles NMI exception. * @brief This function handles NMI exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void NMI_Handler(void) void NMI_Handler(void)
{ {
} }
/** /**
* @brief This function handles Hard Fault exception. * @brief This function handles Hard Fault exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void HardFault_Handler(void) void HardFault_Handler(void)
{ {
/* Go to infinite loop when Hard Fault exception occurs */ /* Go to infinite loop when Hard Fault exception occurs */
while (1) while (1)
{ {
} }
} }
/** /**
* @brief This function handles Memory Manage exception. * @brief This function handles Memory Manage exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void MemManage_Handler(void) void MemManage_Handler(void)
{ {
/* Go to infinite loop when Memory Manage exception occurs */ /* Go to infinite loop when Memory Manage exception occurs */
while (1) while (1)
{ {
} }
} }
/** /**
* @brief This function handles Bus Fault exception. * @brief This function handles Bus Fault exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void BusFault_Handler(void) void BusFault_Handler(void)
{ {
/* Go to infinite loop when Bus Fault exception occurs */ /* Go to infinite loop when Bus Fault exception occurs */
while (1) while (1)
{ {
} }
} }
/** /**
* @brief This function handles Usage Fault exception. * @brief This function handles Usage Fault exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void UsageFault_Handler(void) void UsageFault_Handler(void)
{ {
/* Go to infinite loop when Usage Fault exception occurs */ /* Go to infinite loop when Usage Fault exception occurs */
while (1) while (1)
{ {
} }
} }
/** /**
* @brief This function handles SVCall exception. * @brief This function handles SVCall exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void SVC_Handler(void) void SVC_Handler(void)
{ {
} }
/** /**
* @brief This function handles Debug Monitor exception. * @brief This function handles Debug Monitor exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void DebugMon_Handler(void) void DebugMon_Handler(void)
{ {
} }
/** /**
* @brief This function handles PendSV_Handler exception. * @brief This function handles PendSV_Handler exception.
* @param None * @param None
* @retval None * @retval None
*/ */
void PendSV_Handler(void) void PendSV_Handler(void)
{ {
} }
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
+44 -44
View File
@@ -1,44 +1,44 @@
/** /**
****************************************************************************** ******************************************************************************
* @file I2C/EEPROM/stm32f10x_it.h * @file I2C/EEPROM/stm32f10x_it.h
* @author MCD Application Team * @author MCD Application Team
* @version V3.4.0 * @version V3.4.0
* @date 10/15/2010 * @date 10/15/2010
* @brief This file contains the headers of the interrupt handlers. * @brief This file contains the headers of the interrupt handlers.
****************************************************************************** ******************************************************************************
* @copy * @copy
* *
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* *
* <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2> * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
*/ */
/* Define to prevent recursive inclusion -------------------------------------*/ /* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_IT_H #ifndef __STM32F10x_IT_H
#define __STM32F10x_IT_H #define __STM32F10x_IT_H
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h" #include "stm32f10x.h"
/* Exported types ------------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */
void NMI_Handler(void); void NMI_Handler(void);
void HardFault_Handler(void); void HardFault_Handler(void);
void MemManage_Handler(void); void MemManage_Handler(void);
void BusFault_Handler(void); void BusFault_Handler(void);
void UsageFault_Handler(void); void UsageFault_Handler(void);
void SVC_Handler(void); void SVC_Handler(void);
void DebugMon_Handler(void); void DebugMon_Handler(void);
void PendSV_Handler(void); void PendSV_Handler(void);
#endif /* __STM32F10x_IT_H */ #endif /* __STM32F10x_IT_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
File diff suppressed because it is too large Load Diff
+431 -431
View File
@@ -1,431 +1,431 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "timer.h" #include "timer.h"
/* generic elapsed timer handling */ /* generic elapsed timer handling */
/* interval not to exceed 49.7 days */ /* interval not to exceed 49.7 days */
/* interval of 1ms may be 0 to 1ms */ /* interval of 1ms may be 0 to 1ms */
/************************************************************************* /*************************************************************************
* Description: Sets the start time for an elapsed timer * Description: Sets the start time for an elapsed timer
* Returns: the value of the start timer * Returns: the value of the start timer
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_elapsed_start( void timer_elapsed_start(
struct etimer *t) struct etimer *t)
{ {
uint32_t now = timer_milliseconds(); uint32_t now = timer_milliseconds();
if (t) { if (t) {
t->start = now; t->start = now;
} }
} }
/************************************************************************* /*************************************************************************
* Description: Gets the amount of elapsed time in milliseconds * Description: Gets the amount of elapsed time in milliseconds
* Returns: elapsed time in milliseconds * Returns: elapsed time in milliseconds
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
uint32_t timer_elapsed_time( uint32_t timer_elapsed_time(
struct etimer *t) struct etimer *t)
{ {
uint32_t now = timer_milliseconds(); uint32_t now = timer_milliseconds();
uint32_t delta = 0; uint32_t delta = 0;
if (t) { if (t) {
delta = now - t->start; delta = now - t->start;
} }
return delta; return delta;
} }
/************************************************************************* /*************************************************************************
* Description: Sets the start time with an offset * Description: Sets the start time with an offset
* Returns: elapsed time in milliseconds * Returns: elapsed time in milliseconds
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_elapsed_start_offset( void timer_elapsed_start_offset(
struct etimer *t, struct etimer *t,
uint32_t offset) uint32_t offset)
{ {
uint32_t now = timer_milliseconds(); uint32_t now = timer_milliseconds();
if (t) { if (t) {
t->start = now + offset; t->start = now + offset;
} }
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_elapsed_milliseconds( bool timer_elapsed_milliseconds(
struct etimer *t, struct etimer *t,
uint32_t milliseconds) uint32_t milliseconds)
{ {
return (timer_elapsed_time(t) >= milliseconds); return (timer_elapsed_time(t) >= milliseconds);
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_elapsed_seconds( bool timer_elapsed_seconds(
struct etimer * t, struct etimer * t,
uint32_t seconds) uint32_t seconds)
{ {
uint32_t milliseconds = seconds; uint32_t milliseconds = seconds;
milliseconds *= 1000L; milliseconds *= 1000L;
return timer_elapsed_milliseconds(t, milliseconds); return timer_elapsed_milliseconds(t, milliseconds);
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_elapsed_minutes( bool timer_elapsed_minutes(
struct etimer * t, struct etimer * t,
uint32_t minutes) uint32_t minutes)
{ {
uint32_t milliseconds = minutes; uint32_t milliseconds = minutes;
milliseconds *= 1000L; milliseconds *= 1000L;
milliseconds *= 60L; milliseconds *= 60L;
return timer_elapsed_milliseconds(t, milliseconds); return timer_elapsed_milliseconds(t, milliseconds);
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_elapsed_milliseconds_short( bool timer_elapsed_milliseconds_short(
struct etimer * t, struct etimer * t,
uint16_t value) uint16_t value)
{ {
uint32_t milliseconds; uint32_t milliseconds;
milliseconds = value; milliseconds = value;
return (timer_elapsed_time(t) >= milliseconds); return (timer_elapsed_time(t) >= milliseconds);
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_elapsed_seconds_short( bool timer_elapsed_seconds_short(
struct etimer * t, struct etimer * t,
uint16_t value) uint16_t value)
{ {
return timer_elapsed_seconds(t, value); return timer_elapsed_seconds(t, value);
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_elapsed_minutes_short( bool timer_elapsed_minutes_short(
struct etimer * t, struct etimer * t,
uint16_t value) uint16_t value)
{ {
return timer_elapsed_minutes(t, value); return timer_elapsed_minutes(t, value);
} }
/************************************************************************* /*************************************************************************
* Description: Starts an interval timer * Description: Starts an interval timer
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_interval_start( void timer_interval_start(
struct itimer *t, struct itimer *t,
uint32_t interval) uint32_t interval)
{ {
if (t) { if (t) {
t->start = timer_milliseconds(); t->start = timer_milliseconds();
t->interval = interval; t->interval = interval;
} }
} }
/************************************************************************* /*************************************************************************
* Description: Starts an interval timer * Description: Starts an interval timer
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_interval_start_seconds( void timer_interval_start_seconds(
struct itimer *t, struct itimer *t,
uint32_t seconds) uint32_t seconds)
{ {
uint32_t interval = seconds; uint32_t interval = seconds;
interval *= 1000L; interval *= 1000L;
timer_interval_start(t, interval); timer_interval_start(t, interval);
} }
/************************************************************************* /*************************************************************************
* Description: Starts an interval timer * Description: Starts an interval timer
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_interval_start_minutes( void timer_interval_start_minutes(
struct itimer *t, struct itimer *t,
uint32_t minutes) uint32_t minutes)
{ {
uint32_t interval = minutes; uint32_t interval = minutes;
interval *= 1000L; interval *= 1000L;
interval *= 60L; interval *= 60L;
timer_interval_start(t, interval); timer_interval_start(t, interval);
} }
/************************************************************************* /*************************************************************************
* Description: Determines the amount of time that has elapsed * Description: Determines the amount of time that has elapsed
* Returns: elapsed milliseconds * Returns: elapsed milliseconds
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
uint32_t timer_interval_elapsed( uint32_t timer_interval_elapsed(
struct itimer *t) struct itimer *t)
{ {
uint32_t now = timer_milliseconds(); uint32_t now = timer_milliseconds();
uint32_t delta = 0; uint32_t delta = 0;
if (t) { if (t) {
delta = now - t->start; delta = now - t->start;
} }
return delta; return delta;
} }
/************************************************************************* /*************************************************************************
* Description: Determines the amount of time that has elapsed * Description: Determines the amount of time that has elapsed
* Returns: elapsed milliseconds * Returns: elapsed milliseconds
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
uint32_t timer_interval( uint32_t timer_interval(
struct itimer * t) struct itimer * t)
{ {
uint32_t interval = 0; uint32_t interval = 0;
if (t) { if (t) {
interval = t->interval; interval = t->interval;
} }
return interval; return interval;
} }
/************************************************************************* /*************************************************************************
* Description: Tests to see if time has elapsed * Description: Tests to see if time has elapsed
* Returns: true if time has elapsed * Returns: true if time has elapsed
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool timer_interval_expired( bool timer_interval_expired(
struct itimer * t) struct itimer * t)
{ {
bool expired = false; bool expired = false;
if (t) { if (t) {
if (t->interval) { if (t->interval) {
expired = timer_interval_elapsed(t) >= t->interval; expired = timer_interval_elapsed(t) >= t->interval;
} }
} }
return expired; return expired;
} }
/************************************************************************* /*************************************************************************
* Description: Sets the interval value to zero so it never expires * Description: Sets the interval value to zero so it never expires
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_interval_no_expire( void timer_interval_no_expire(
struct itimer *t) struct itimer *t)
{ {
if (t) { if (t) {
t->interval = 0; t->interval = 0;
} }
} }
/************************************************************************* /*************************************************************************
* Description: Adds another interval to the start time. Used for cyclic * Description: Adds another interval to the start time. Used for cyclic
* timers that won't lose ticks. * timers that won't lose ticks.
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_interval_reset( void timer_interval_reset(
struct itimer *t) struct itimer *t)
{ {
if (t) { if (t) {
t->start += t->interval; t->start += t->interval;
} }
} }
/************************************************************************* /*************************************************************************
* Description: Restarts the timer with the same interval * Description: Restarts the timer with the same interval
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_interval_restart( void timer_interval_restart(
struct itimer *t) struct itimer *t)
{ {
if (t) { if (t) {
t->start = timer_milliseconds(); t->start = timer_milliseconds();
} }
} }
/************************************************************************* /*************************************************************************
* Description: Return the elapsed time * Description: Return the elapsed time
* Returns: number of milliseconds elapsed * Returns: number of milliseconds elapsed
* Notes: only up to 255ms elapsed * Notes: only up to 255ms elapsed
**************************************************************************/ **************************************************************************/
uint8_t timer_milliseconds_delta( uint8_t timer_milliseconds_delta(
uint8_t start) uint8_t start)
{ {
return (timer_milliseconds_byte() - start); return (timer_milliseconds_byte() - start);
} }
/************************************************************************* /*************************************************************************
* Description: Mark the start of a delta timer * Description: Mark the start of a delta timer
* Returns: mark timer starting tick * Returns: mark timer starting tick
* Notes: only up to 255ms elapsed * Notes: only up to 255ms elapsed
**************************************************************************/ **************************************************************************/
uint8_t timer_milliseconds_mark( uint8_t timer_milliseconds_mark(
void) void)
{ {
return timer_milliseconds_byte(); return timer_milliseconds_byte();
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
static uint32_t Milliseconds; static uint32_t Milliseconds;
uint32_t timer_milliseconds( uint32_t timer_milliseconds(
void) void)
{ {
return Milliseconds; return Milliseconds;
} }
uint32_t timer_milliseconds_set( uint32_t timer_milliseconds_set(
uint32_t value) uint32_t value)
{ {
uint32_t old_value = Milliseconds; uint32_t old_value = Milliseconds;
Milliseconds = value; Milliseconds = value;
return old_value; return old_value;
} }
void testElapsedTimer( void testElapsedTimer(
Test * pTest) Test * pTest)
{ {
struct etimer t; struct etimer t;
uint32_t test_time = 0; uint32_t test_time = 0;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
timer_elapsed_start(&t); timer_elapsed_start(&t);
ct_test(pTest, timer_elapsed_time(&t) == test_time); ct_test(pTest, timer_elapsed_time(&t) == test_time);
test_time = 0xffff; test_time = 0xffff;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
ct_test(pTest, timer_elapsed_time(&t) == test_time); ct_test(pTest, timer_elapsed_time(&t) == test_time);
test_time = 0xffffffff; test_time = 0xffffffff;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
ct_test(pTest, timer_elapsed_time(&t) == test_time); ct_test(pTest, timer_elapsed_time(&t) == test_time);
} }
void testIntervalTimer( void testIntervalTimer(
Test * pTest) Test * pTest)
{ {
struct itimer t; struct itimer t;
uint32_t interval = 0; uint32_t interval = 0;
uint32_t test_time = 0; uint32_t test_time = 0;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
timer_interval_start(&t, interval); timer_interval_start(&t, interval);
test_time = 0xffff; test_time = 0xffff;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
ct_test(pTest, timer_interval(&t) == interval); ct_test(pTest, timer_interval(&t) == interval);
ct_test(pTest, timer_interval_elapsed(&t) == test_time); ct_test(pTest, timer_interval_elapsed(&t) == test_time);
test_time = 0xffffffff; test_time = 0xffffffff;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
ct_test(pTest, timer_interval(&t) == interval); ct_test(pTest, timer_interval(&t) == interval);
ct_test(pTest, timer_interval_elapsed(&t) == test_time); ct_test(pTest, timer_interval_elapsed(&t) == test_time);
test_time = 0; test_time = 0;
timer_milliseconds_set(test_time); timer_milliseconds_set(test_time);
interval = 0xffff; interval = 0xffff;
timer_interval_start(&t, interval); timer_interval_start(&t, interval);
ct_test(pTest, timer_interval(&t) == interval); ct_test(pTest, timer_interval(&t) == interval);
interval = 0xffffffff; interval = 0xffffffff;
timer_interval_start(&t, interval); timer_interval_start(&t, interval);
ct_test(pTest, timer_interval(&t) == interval); ct_test(pTest, timer_interval(&t) == interval);
interval = 0; interval = 0;
timer_interval_start_seconds(&t, interval); timer_interval_start_seconds(&t, interval);
ct_test(pTest, timer_interval(&t) == interval); ct_test(pTest, timer_interval(&t) == interval);
interval = 60L; interval = 60L;
timer_interval_start_seconds(&t, interval); timer_interval_start_seconds(&t, interval);
interval *= 1000L; interval *= 1000L;
ct_test(pTest, timer_interval(&t) == interval); ct_test(pTest, timer_interval(&t) == interval);
} }
#ifdef TEST_TIMER #ifdef TEST_TIMER
int main( int main(
void) void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
pTest = ct_create("Timer", NULL); pTest = ct_create("Timer", NULL);
/* individual tests */ /* individual tests */
rc = ct_addTestFunction(pTest, testElapsedTimer); rc = ct_addTestFunction(pTest, testElapsedTimer);
assert(rc); assert(rc);
rc = ct_addTestFunction(pTest, testIntervalTimer); rc = ct_addTestFunction(pTest, testIntervalTimer);
assert(rc); assert(rc);
ct_setStream(pTest, stdout); ct_setStream(pTest, stdout);
ct_run(pTest); ct_run(pTest);
(void) ct_report(pTest); (void) ct_report(pTest);
ct_destroy(pTest); ct_destroy(pTest);
return 0; return 0;
} }
#endif #endif
#endif #endif
+115 -115
View File
@@ -1,115 +1,115 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef TIMER_H #ifndef TIMER_H
#define TIMER_H #define TIMER_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
/* Timer Module */ /* Timer Module */
/* elapsed timer structure */ /* elapsed timer structure */
struct etimer { struct etimer {
uint32_t start; uint32_t start;
}; };
/* interval timer structure */ /* interval timer structure */
struct itimer { struct itimer {
uint32_t start; uint32_t start;
uint32_t interval; uint32_t interval;
}; };
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* these 3 functions are created in the hardware specific module */ /* these 3 functions are created in the hardware specific module */
void timer_init( void timer_init(
void); void);
uint32_t timer_milliseconds( uint32_t timer_milliseconds(
void); void);
uint8_t timer_milliseconds_byte( uint8_t timer_milliseconds_byte(
void); void);
/* these functions are in the generic timer.c module */ /* these functions are in the generic timer.c module */
/* elapsed timer */ /* elapsed timer */
void timer_elapsed_start( void timer_elapsed_start(
struct etimer *t); struct etimer *t);
void timer_elapsed_start_offset( void timer_elapsed_start_offset(
struct etimer *t, struct etimer *t,
uint32_t offset); uint32_t offset);
uint32_t timer_elapsed_time( uint32_t timer_elapsed_time(
struct etimer *t); struct etimer *t);
bool timer_elapsed_milliseconds( bool timer_elapsed_milliseconds(
struct etimer *t, struct etimer *t,
uint32_t value); uint32_t value);
bool timer_elapsed_seconds( bool timer_elapsed_seconds(
struct etimer *t, struct etimer *t,
uint32_t value); uint32_t value);
bool timer_elapsed_minutes( bool timer_elapsed_minutes(
struct etimer *t, struct etimer *t,
uint32_t value); uint32_t value);
bool timer_elapsed_milliseconds_short( bool timer_elapsed_milliseconds_short(
struct etimer *t, struct etimer *t,
uint16_t value); uint16_t value);
bool timer_elapsed_seconds_short( bool timer_elapsed_seconds_short(
struct etimer *t, struct etimer *t,
uint16_t value); uint16_t value);
bool timer_elapsed_minutes_short( bool timer_elapsed_minutes_short(
struct etimer *t, struct etimer *t,
uint16_t value); uint16_t value);
/* interval timer */ /* interval timer */
void timer_interval_start( void timer_interval_start(
struct itimer *t, struct itimer *t,
uint32_t interval); uint32_t interval);
void timer_interval_start_seconds( void timer_interval_start_seconds(
struct itimer *t, struct itimer *t,
uint32_t interval); uint32_t interval);
void timer_interval_start_minutes( void timer_interval_start_minutes(
struct itimer *t, struct itimer *t,
uint32_t interval); uint32_t interval);
bool timer_interval_expired( bool timer_interval_expired(
struct itimer *t); struct itimer *t);
uint32_t timer_interval( uint32_t timer_interval(
struct itimer *t); struct itimer *t);
uint32_t timer_interval_elapsed( uint32_t timer_interval_elapsed(
struct itimer *t); struct itimer *t);
void timer_interval_no_expire( void timer_interval_no_expire(
struct itimer *t); struct itimer *t);
void timer_interval_reset( void timer_interval_reset(
struct itimer *t); struct itimer *t);
void timer_interval_restart( void timer_interval_restart(
struct itimer *t); struct itimer *t);
/* special for 8-bit microcontrollers - limited to 255ms */ /* special for 8-bit microcontrollers - limited to 255ms */
uint8_t timer_milliseconds_delta( uint8_t timer_milliseconds_delta(
uint8_t start); uint8_t start);
uint8_t timer_milliseconds_mark( uint8_t timer_milliseconds_mark(
void); void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+121 -121
View File
@@ -1,121 +1,121 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* Module Description: * Module Description:
* Generate a periodic timer tick for use by generic timers in the code. * Generate a periodic timer tick for use by generic timers in the code.
* *
*************************************************************************/ *************************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "debug.h" #include "debug.h"
/* counter for the various timers */ /* counter for the various timers */
static volatile uint32_t Millisecond_Counter; static volatile uint32_t Millisecond_Counter;
/************************************************************************* /*************************************************************************
* Description: Activate the LED * Description: Activate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
static void timer_debug_on( static void timer_debug_on(
void) void)
{ {
GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_SET); GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_SET);
} }
/************************************************************************* /*************************************************************************
* Description: Activate the LED * Description: Activate the LED
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
static void timer_debug_off( static void timer_debug_off(
void) void)
{ {
GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET);
} }
/************************************************************************* /*************************************************************************
* Description: Toggle the state of the setup LED * Description: Toggle the state of the setup LED
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void timer_debug_toggle(void) void timer_debug_toggle(void)
{ {
static bool state = false; static bool state = false;
if (state) { if (state) {
timer_debug_off(); timer_debug_off();
state = false; state = false;
} else { } else {
timer_debug_on(); timer_debug_on();
state = true; state = true;
} }
} }
/************************************************************************* /*************************************************************************
* Description: Interrupt Service Routine * Description: Interrupt Service Routine
* Returns: nothing * Returns: nothing
* Notes: reserved name for ISR handlers * Notes: reserved name for ISR handlers
*************************************************************************/ *************************************************************************/
void SysTick_Handler(void) void SysTick_Handler(void)
{ {
/* increment the tick count */ /* increment the tick count */
Millisecond_Counter++; Millisecond_Counter++;
timer_debug_toggle(); timer_debug_toggle();
} }
/************************************************************************* /*************************************************************************
* Description: returns the current millisecond count * Description: returns the current millisecond count
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
uint32_t timer_milliseconds(void) uint32_t timer_milliseconds(void)
{ {
return Millisecond_Counter; return Millisecond_Counter;
} }
/************************************************************************* /*************************************************************************
* Description: Timer setup for 1 millisecond timer * Description: Timer setup for 1 millisecond timer
* Returns: none * Returns: none
* Notes: peripheral frequency defined in hardware.h * Notes: peripheral frequency defined in hardware.h
*************************************************************************/ *************************************************************************/
void timer_init(void) void timer_init(void)
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure); GPIO_StructInit(&GPIO_InitStructure);
/* Configure the Receive LED */ /* Configure the Receive LED */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Setup SysTick Timer for 1ms interrupts */ /* Setup SysTick Timer for 1ms interrupts */
if (SysTick_Config(SystemCoreClock / 1000)) { if (SysTick_Config(SystemCoreClock / 1000)) {
/* Capture error */ /* Capture error */
while (1); while (1);
} }
} }
+173 -173
View File
@@ -1,180 +1,180 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com> * Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdint.h> #include <stdint.h>
#include "bacapp.h" #include "bacapp.h"
#include "bacenum.h" #include "bacenum.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacdef.h" #include "bacdef.h"
#include "wp.h" #include "wp.h"
#include "wpm.h" #include "wpm.h"
/** @file wpm.c Encode/Decode BACnet Write Property Multiple APDUs */ /** @file wpm.c Encode/Decode BACnet Write Property Multiple APDUs */
/* decode service */ /* decode service */
int wpm_decode_object_id(uint8_t * apdu, uint16_t apdu_len, int wpm_decode_object_id(uint8_t * apdu, uint16_t apdu_len,
BACNET_WRITE_PROPERTY_DATA * data) BACNET_WRITE_PROPERTY_DATA * data)
{ {
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint32_t object_instance = 0; uint32_t object_instance = 0;
uint16_t object_type = 0; uint16_t object_type = 0;
uint16_t len = 0; uint16_t len = 0;
if((apdu )&& (apdu_len)) if((apdu )&& (apdu_len))
{ {
/* Context tag 0 - Object ID /* Context tag 0 - Object ID
*/ */
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
if(tag_number == 0) if(tag_number == 0)
{ {
len += decode_object_id(&apdu[len], &object_type, &object_instance); len += decode_object_id(&apdu[len], &object_type, &object_instance);
data->object_type = object_type; data->object_type = object_type;
data->object_instance = object_instance; data->object_instance = object_instance;
} }
else else
return -1; return -1;
} }
else else
return -1; return -1;
return len; return len;
} }
int wpm_decode_object_property(uint8_t * apdu, int wpm_decode_object_property(uint8_t * apdu,
uint16_t apdu_len, uint16_t apdu_len,
BACNET_WRITE_PROPERTY_DATA * wp_data) BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint32_t ulVal = 0; uint32_t ulVal = 0;
int len = 0, i = 0; int len = 0, i = 0;
if((apdu) && (apdu_len) && (wp_data)) if((apdu) && (apdu_len) && (wp_data))
{ {
wp_data->array_index = BACNET_ARRAY_ALL; wp_data->array_index = BACNET_ARRAY_ALL;
wp_data->priority = BACNET_NO_PRIORITY; wp_data->priority = BACNET_NO_PRIORITY;
wp_data->application_data_len = 0; wp_data->application_data_len = 0;
/* tag 0 - Property Identifier /* tag 0 - Property Identifier
*/ */
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
if(tag_number == 0) if(tag_number == 0)
{ {
len += decode_enumerated(&apdu[len], len_value, &ulVal); len += decode_enumerated(&apdu[len], len_value, &ulVal);
wp_data->object_property = ulVal; wp_data->object_property = ulVal;
} }
else else
return -1; return -1;
/* tag 1 - Property Array Index - optional /* tag 1 - Property Array Index - optional
*/ */
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
if(tag_number ==1) if(tag_number ==1)
{ {
len += decode_unsigned(&apdu[len],len_value, &ulVal); len += decode_unsigned(&apdu[len],len_value, &ulVal);
wp_data->array_index = ulVal; wp_data->array_index = ulVal;
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
} }
/* tag 2 - Property Value /* tag 2 - Property Value
*/ */
if((tag_number == 2) && (decode_is_opening_tag(&apdu[len-1]))) if((tag_number == 2) && (decode_is_opening_tag(&apdu[len-1])))
{ {
len--; len--;
wp_data->application_data_len = bacapp_data_len(&apdu[len], wp_data->application_data_len = bacapp_data_len(&apdu[len],
apdu_len - len, wp_data->object_property); apdu_len - len, wp_data->object_property);
len++; len++;
/* copy application data /* copy application data
*/ */
for(i = 0; i < wp_data->application_data_len; i++) for(i = 0; i < wp_data->application_data_len; i++)
wp_data->application_data[i] = apdu[len+i]; wp_data->application_data[i] = apdu[len+i];
len += wp_data->application_data_len; len += wp_data->application_data_len;
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
/* closing tag 2 /* closing tag 2
*/ */
if((tag_number != 2) &&(decode_is_closing_tag(&apdu[len-1]))) if((tag_number != 2) &&(decode_is_closing_tag(&apdu[len-1])))
return -1; return -1;
} }
else else
return -1; return -1;
/* tag 3 - Priority - optional /* tag 3 - Priority - optional
*/ */
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
if(tag_number == 3) if(tag_number == 3)
{ {
uint32_t priority = BACNET_NO_PRIORITY; uint32_t priority = BACNET_NO_PRIORITY;
len += decode_unsigned(&apdu[len], len_value, &priority); len += decode_unsigned(&apdu[len], len_value, &priority);
wp_data->priority = priority; wp_data->priority = priority;
} }
else else
len--; len--;
} }
else else
return -1; return -1;
return len; return len;
} }
int wpm_ack_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id) int wpm_ack_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id)
{ {
int len = 0; int len = 0;
if (apdu) { if (apdu) {
apdu[len++] = PDU_TYPE_SIMPLE_ACK; apdu[len++] = PDU_TYPE_SIMPLE_ACK;
apdu[len++] = invoke_id; apdu[len++] = invoke_id;
apdu[len++] = SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE; apdu[len++] = SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE;
} }
return len; return len;
} }
int wpm_error_ack_encode_apdu(uint8_t * apdu, uint8_t invoke_id, int wpm_error_ack_encode_apdu(uint8_t * apdu, uint8_t invoke_id,
BACNET_WRITE_PROPERTY_DATA * wp_data) BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
int len = 0; int len = 0;
if (apdu) if (apdu)
{ {
apdu[len++] = PDU_TYPE_ERROR; apdu[len++] = PDU_TYPE_ERROR;
apdu[len++] = invoke_id; apdu[len++] = invoke_id;
apdu[len++] = SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE; apdu[len++] = SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE;
len += encode_opening_tag(&apdu[len], 0); len += encode_opening_tag(&apdu[len], 0);
len += encode_application_enumerated(&apdu[len], wp_data->error_class); len += encode_application_enumerated(&apdu[len], wp_data->error_class);
len += encode_application_enumerated(&apdu[len], wp_data->error_code); len += encode_application_enumerated(&apdu[len], wp_data->error_code);
len += encode_closing_tag(&apdu[len], 0); len += encode_closing_tag(&apdu[len], 0);
len += encode_opening_tag(&apdu[len], 1); len += encode_opening_tag(&apdu[len], 1);
len += encode_context_object_id(&apdu[len], 0, len += encode_context_object_id(&apdu[len], 0,
wp_data->object_type, wp_data->object_instance); wp_data->object_type, wp_data->object_instance);
len += encode_context_enumerated(&apdu[len], 1, len += encode_context_enumerated(&apdu[len], 1,
wp_data->object_property); wp_data->object_property);