This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
// $Id$
|
||||
// File: 18f252.lkr
|
||||
// Sample linker script for the PIC18F252 processor
|
||||
|
||||
LIBPATH .
|
||||
|
||||
FILES c018i.o
|
||||
FILES clib.lib
|
||||
FILES p18f252.lib
|
||||
|
||||
CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED
|
||||
CODEPAGE NAME=page START=0x2A END=0x7FFF
|
||||
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
|
||||
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
|
||||
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
|
||||
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
|
||||
|
||||
ACCESSBANK NAME=accessram START=0x0 END=0x7F
|
||||
DATABANK NAME=gpr0 START=0x80 END=0xFF
|
||||
DATABANK NAME=gpr1 START=0x100 END=0x1FF
|
||||
DATABANK NAME=gpr2 START=0x200 END=0x2FF
|
||||
DATABANK NAME=gpr3 START=0x300 END=0x3FF
|
||||
DATABANK NAME=gpr4 START=0x400 END=0x4FF
|
||||
DATABANK NAME=gpr5 START=0x500 END=0x5FF
|
||||
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED
|
||||
|
||||
SECTION NAME=CONFIG ROM=config
|
||||
|
||||
STACK SIZE=0x100 RAM=gpr5
|
||||
@@ -1,131 +0,0 @@
|
||||
[HEADER]
|
||||
magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13}
|
||||
file_version=1.0
|
||||
[PATH_INFO]
|
||||
dir_src=
|
||||
dir_bin=
|
||||
dir_tmp=
|
||||
dir_sin=
|
||||
dir_inc=C:\code\bacnet-stack;C:\code\bacnet-stack\demo\handler;C:\code\bacnet-stack\demo\object;C:\code\bacnet-stack\ports\pic18
|
||||
dir_lib=C:\mcc18\lib
|
||||
dir_lkr=
|
||||
[CAT_FILTERS]
|
||||
filter_src=*.asm;*.c
|
||||
filter_inc=*.h;*.inc
|
||||
filter_obj=*.o
|
||||
filter_lib=*.lib
|
||||
filter_lkr=*.lkr
|
||||
[OTHER_FILES]
|
||||
file_000=no
|
||||
file_001=no
|
||||
file_002=no
|
||||
file_003=no
|
||||
file_004=no
|
||||
file_005=no
|
||||
file_006=no
|
||||
file_007=no
|
||||
file_008=no
|
||||
file_009=no
|
||||
file_010=no
|
||||
file_011=no
|
||||
file_012=no
|
||||
file_013=no
|
||||
file_014=no
|
||||
file_015=no
|
||||
file_016=no
|
||||
file_017=no
|
||||
file_018=no
|
||||
file_019=no
|
||||
file_020=no
|
||||
file_021=no
|
||||
file_022=no
|
||||
file_023=no
|
||||
file_024=no
|
||||
file_025=no
|
||||
file_026=no
|
||||
file_027=no
|
||||
file_028=no
|
||||
file_029=no
|
||||
file_030=no
|
||||
file_031=no
|
||||
file_032=no
|
||||
file_033=no
|
||||
file_034=no
|
||||
file_035=no
|
||||
file_036=no
|
||||
file_037=no
|
||||
file_038=no
|
||||
file_039=no
|
||||
file_040=no
|
||||
file_041=no
|
||||
file_042=no
|
||||
file_043=no
|
||||
file_044=no
|
||||
file_045=no
|
||||
file_046=no
|
||||
file_047=no
|
||||
file_048=no
|
||||
file_049=no
|
||||
file_050=no
|
||||
file_051=no
|
||||
[FILE_INFO]
|
||||
file_000=C:\code\bacnet-stack\abort.c
|
||||
file_001=C:\code\bacnet-stack\apdu.c
|
||||
file_002=C:\code\bacnet-stack\bacapp.c
|
||||
file_003=C:\code\bacnet-stack\bacdcode.c
|
||||
file_004=C:\code\bacnet-stack\bacerror.c
|
||||
file_005=C:\code\bacnet-stack\bacstr.c
|
||||
file_006=C:\code\bacnet-stack\crc.c
|
||||
file_007=C:\code\bacnet-stack\datalink.c
|
||||
file_008=C:\code\bacnet-stack\dcc.c
|
||||
file_009=C:\code\bacnet-stack\iam.c
|
||||
file_010=C:\code\bacnet-stack\mstp.c
|
||||
file_011=C:\code\bacnet-stack\npdu.c
|
||||
file_012=C:\code\bacnet-stack\rd.c
|
||||
file_013=C:\code\bacnet-stack\reject.c
|
||||
file_014=C:\code\bacnet-stack\rp.c
|
||||
file_015=C:\code\bacnet-stack\whois.c
|
||||
file_016=C:\code\bacnet-stack\demo\handler\h_dcc.c
|
||||
file_017=C:\code\bacnet-stack\demo\handler\h_rd.c
|
||||
file_018=main.c
|
||||
file_019=dlmstp.c
|
||||
file_020=rs485.c
|
||||
file_021=device.c
|
||||
file_022=C:\code\bacnet-stack\wp.h
|
||||
file_023=C:\code\bacnet-stack\abort.h
|
||||
file_024=C:\code\bacnet-stack\apdu.h
|
||||
file_025=C:\code\bacnet-stack\bacapp.h
|
||||
file_026=C:\code\bacnet-stack\bacdcode.h
|
||||
file_027=C:\code\bacnet-stack\bacdef.h
|
||||
file_028=C:\code\bacnet-stack\bacenum.h
|
||||
file_029=C:\code\bacnet-stack\bacerror.h
|
||||
file_030=C:\code\bacnet-stack\bacstr.h
|
||||
file_031=C:\code\bacnet-stack\config.h
|
||||
file_032=C:\code\bacnet-stack\crc.h
|
||||
file_033=C:\code\bacnet-stack\datalink.h
|
||||
file_034=C:\code\bacnet-stack\dcc.h
|
||||
file_035=C:\code\bacnet-stack\dlmstp.h
|
||||
file_036=C:\code\bacnet-stack\iam.h
|
||||
file_037=C:\code\bacnet-stack\mstp.h
|
||||
file_038=C:\code\bacnet-stack\npdu.h
|
||||
file_039=C:\code\bacnet-stack\rd.h
|
||||
file_040=C:\code\bacnet-stack\reject.h
|
||||
file_041=C:\code\bacnet-stack\rp.h
|
||||
file_042=C:\code\bacnet-stack\rs485.h
|
||||
file_043=C:\code\bacnet-stack\whois.h
|
||||
file_044=C:\code\bacnet-stack\demo\handler\client.h
|
||||
file_045=C:\code\bacnet-stack\demo\handler\handlers.h
|
||||
file_046=C:\code\bacnet-stack\demo\object\ai.h
|
||||
file_047=C:\code\bacnet-stack\demo\object\ao.h
|
||||
file_048=C:\code\bacnet-stack\demo\object\device.h
|
||||
file_049=stdbool.h
|
||||
file_050=stdint.h
|
||||
file_051=hardware.h
|
||||
[SUITE_INFO]
|
||||
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
|
||||
suite_state=
|
||||
[TOOL_SETTINGS]
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/o"$(TARGETBASE).cof" /M"$(BINDIR_)$(TARGETBASE).map"
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP -DBIG_ENDIAN=1 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}=
|
||||
Binary file not shown.
@@ -1,151 +0,0 @@
|
||||
[HEADER]
|
||||
magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13}
|
||||
file_version=1.0
|
||||
[PATH_INFO]
|
||||
dir_src=
|
||||
dir_bin=
|
||||
dir_tmp=
|
||||
dir_sin=
|
||||
dir_inc=c:\mcc18\h;c:\code\bacnet-stack;c:\code\bacnet-stack\ports\pic18;c:\code\bacnet-stack\demo\object;c:\code\bacnet-stack\demo\handler
|
||||
dir_lib=c:\mcc18\lib
|
||||
dir_lkr=
|
||||
[CAT_FILTERS]
|
||||
filter_src=*.asm;*.c
|
||||
filter_inc=*.h;*.inc
|
||||
filter_obj=*.o
|
||||
filter_lib=*.lib
|
||||
filter_lkr=*.lkr
|
||||
[OTHER_FILES]
|
||||
file_000=no
|
||||
file_001=no
|
||||
file_002=no
|
||||
file_003=no
|
||||
file_004=no
|
||||
file_005=no
|
||||
file_006=no
|
||||
file_007=no
|
||||
file_008=no
|
||||
file_009=no
|
||||
file_010=no
|
||||
file_011=no
|
||||
file_012=no
|
||||
file_013=no
|
||||
file_014=no
|
||||
file_015=no
|
||||
file_016=no
|
||||
file_017=no
|
||||
file_018=no
|
||||
file_019=no
|
||||
file_020=no
|
||||
file_021=no
|
||||
file_022=no
|
||||
file_023=no
|
||||
file_024=no
|
||||
file_025=no
|
||||
file_026=no
|
||||
file_027=no
|
||||
file_028=no
|
||||
file_029=no
|
||||
file_030=no
|
||||
file_031=no
|
||||
file_032=no
|
||||
file_033=no
|
||||
file_034=no
|
||||
file_035=no
|
||||
file_036=no
|
||||
file_037=no
|
||||
file_038=no
|
||||
file_039=no
|
||||
file_040=no
|
||||
file_041=no
|
||||
file_042=no
|
||||
file_043=no
|
||||
file_044=no
|
||||
file_045=no
|
||||
file_046=no
|
||||
file_047=no
|
||||
file_048=no
|
||||
file_049=no
|
||||
file_050=no
|
||||
file_051=no
|
||||
file_052=no
|
||||
file_053=no
|
||||
file_054=no
|
||||
file_055=no
|
||||
file_056=no
|
||||
file_057=no
|
||||
file_058=no
|
||||
[FILE_INFO]
|
||||
file_000=rs485.c
|
||||
file_001=main.c
|
||||
file_002=init.c
|
||||
file_003=isr.c
|
||||
file_004=timer.c
|
||||
file_005=C:\code\bacnet-stack\rp.c
|
||||
file_006=C:\code\bacnet-stack\whois.c
|
||||
file_007=C:\code\bacnet-stack\abort.c
|
||||
file_008=C:\code\bacnet-stack\apdu.c
|
||||
file_009=C:\code\bacnet-stack\bacdcode.c
|
||||
file_010=C:\code\bacnet-stack\bacerror.c
|
||||
file_011=C:\code\bacnet-stack\crc.c
|
||||
file_012=C:\code\bacnet-stack\datalink.c
|
||||
file_013=C:\code\bacnet-stack\iam.c
|
||||
file_014=C:\code\bacnet-stack\mstp.c
|
||||
file_015=C:\code\bacnet-stack\npdu.c
|
||||
file_016=C:\code\bacnet-stack\reject.c
|
||||
file_017=C:\code\bacnet-stack\dcc.c
|
||||
file_018=C:\code\bacnet-stack\bacstr.c
|
||||
file_019=C:\code\bacnet-stack\bacapp.c
|
||||
file_020=device.c
|
||||
file_021=dlmstp.c
|
||||
file_022=C:\code\bacnet-stack\demo\handler\h_rd.c
|
||||
file_023=C:\code\bacnet-stack\demo\handler\h_dcc.c
|
||||
file_024=C:\code\bacnet-stack\rd.c
|
||||
file_025=C:\code\bacnet-stack\demo\handler\txbuf.c
|
||||
file_026=C:\code\bacnet-stack\demo\handler\h_whois.c
|
||||
file_027=C:\code\bacnet-stack\demo\handler\noserv.c
|
||||
file_028=stdbool.h
|
||||
file_029=stdint.h
|
||||
file_030=init.h
|
||||
file_031=timer.h
|
||||
file_032=C:\code\bacnet-stack\whois.h
|
||||
file_033=C:\code\bacnet-stack\abort.h
|
||||
file_034=C:\code\bacnet-stack\apdu.h
|
||||
file_035=C:\code\bacnet-stack\bacdcode.h
|
||||
file_036=C:\code\bacnet-stack\bacdef.h
|
||||
file_037=C:\code\bacnet-stack\bacenum.h
|
||||
file_038=C:\code\bacnet-stack\bacerror.h
|
||||
file_039=C:\code\bacnet-stack\bigend.h
|
||||
file_040=C:\code\bacnet-stack\bits.h
|
||||
file_041=C:\code\bacnet-stack\bytes.h
|
||||
file_042=C:\code\bacnet-stack\config.h
|
||||
file_043=C:\code\bacnet-stack\crc.h
|
||||
file_044=C:\code\bacnet-stack\datalink.h
|
||||
file_045=C:\code\bacnet-stack\dlmstp.h
|
||||
file_046=C:\code\bacnet-stack\mstp.h
|
||||
file_047=C:\code\bacnet-stack\npdu.h
|
||||
file_048=C:\code\bacnet-stack\reject.h
|
||||
file_049=C:\code\bacnet-stack\ringbuf.h
|
||||
file_050=C:\code\bacnet-stack\rs485.h
|
||||
file_051=C:\code\bacnet-stack\demo\object\ai.h
|
||||
file_052=C:\code\bacnet-stack\demo\object\ao.h
|
||||
file_053=C:\code\bacnet-stack\demo\object\device.h
|
||||
file_054=C:\code\bacnet-stack\dcc.h
|
||||
file_055=C:\code\bacnet-stack\bacstr.h
|
||||
file_056=C:\code\bacnet-stack\bacapp.h
|
||||
file_057=C:\code\bacnet-stack\rd.h
|
||||
file_058=18f252.lkr
|
||||
[SUITE_INFO]
|
||||
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
|
||||
suite_state=
|
||||
[TOOL_SETTINGS]
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof"
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DTSM_ENABLED=0 -DPRINT_ENABLED=0 -DBACDL_MSTP=1 -mL -pa=1
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}=
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}001=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}001=/o"$(TARGETBASE).cof"
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}001=-Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}001=
|
||||
[ACTIVE_FILE_SETTINGS]
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}001_active=yes
|
||||
Binary file not shown.
@@ -1,408 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005,2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h> /* for memmove */
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "apdu.h"
|
||||
#include "device.h" /* me */
|
||||
|
||||
/* note: you really only need to define variables for
|
||||
properties that are writable or that may change.
|
||||
The properties that are constant can be hard coded
|
||||
into the read-property encoding. */
|
||||
static uint32_t Object_Instance_Number = 0;
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
static uint16_t APDU_Timeout = 3000;
|
||||
static uint8_t Number_Of_APDU_Retries = 3;
|
||||
|
||||
/* methods to manipulate the data */
|
||||
uint32_t Device_Object_Instance_Number(void)
|
||||
{
|
||||
return Object_Instance_Number;
|
||||
}
|
||||
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
bool status = true; /* return value */
|
||||
|
||||
if (object_id <= BACNET_MAX_INSTANCE)
|
||||
Object_Instance_Number = object_id;
|
||||
else
|
||||
status = false;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
/* BACnet allows for a wildcard instance number */
|
||||
return ((Object_Instance_Number == object_id) ||
|
||||
(object_id == BACNET_MAX_INSTANCE));
|
||||
}
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(void)
|
||||
{
|
||||
return System_Status;
|
||||
}
|
||||
|
||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status)
|
||||
{
|
||||
/* FIXME: bounds check? */
|
||||
System_Status = status;
|
||||
}
|
||||
|
||||
/* FIXME: put your vendor ID here! */
|
||||
uint16_t Device_Vendor_Identifier(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Device_Protocol_Version(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t Device_Protocol_Revision(void)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/* FIXME: MAX_APDU is defined in config.ini - set it! */
|
||||
uint16_t Device_Max_APDU_Length_Accepted(void)
|
||||
{
|
||||
return MAX_APDU;
|
||||
}
|
||||
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
|
||||
{
|
||||
return SEGMENTATION_NONE;
|
||||
}
|
||||
|
||||
uint16_t Device_APDU_Timeout(void)
|
||||
{
|
||||
return APDU_Timeout;
|
||||
}
|
||||
|
||||
/* in milliseconds */
|
||||
void Device_Set_APDU_Timeout(uint16_t timeout)
|
||||
{
|
||||
APDU_Timeout = timeout;
|
||||
}
|
||||
|
||||
uint8_t Device_Number_Of_APDU_Retries(void)
|
||||
{
|
||||
return Number_Of_APDU_Retries;
|
||||
}
|
||||
|
||||
void Device_Set_Number_Of_APDU_Retries(uint8_t retries)
|
||||
{
|
||||
Number_Of_APDU_Retries = retries;
|
||||
}
|
||||
|
||||
uint8_t Device_Database_Revision(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Since many network clients depend on the object list */
|
||||
/* for discovery, it must be consistent! */
|
||||
unsigned Device_Object_List_Count(void)
|
||||
{
|
||||
unsigned count = 1;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Device_Object_List_Identifier(unsigned array_index,
|
||||
int *object_type, uint32_t * instance)
|
||||
{
|
||||
bool status = false;
|
||||
unsigned object_index = 0;
|
||||
unsigned object_count = 0;
|
||||
|
||||
/* device object */
|
||||
if (array_index == 1) {
|
||||
*object_type = OBJECT_DEVICE;
|
||||
*instance = Object_Instance_Number;
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return the length of the apdu encoded or -1 for error or
|
||||
-2 for abort */
|
||||
int Device_Encode_Property_APDU(uint8_t * apdu,
|
||||
BACNET_PROPERTY_ID property,
|
||||
int32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
int len = 0; /* apdu len intermediate value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
unsigned i = 0;
|
||||
int object_type = 0;
|
||||
uint32_t instance = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
/* FIXME: change the hardcoded names to suit your application */
|
||||
switch (property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_DEVICE,
|
||||
Object_Instance_Number);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string, (char *) "TD");
|
||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE);
|
||||
break;
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string, (char *) "Tiny");
|
||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_SYSTEM_STATUS:
|
||||
apdu_len =
|
||||
encode_tagged_enumerated(&apdu[0], Device_System_Status());
|
||||
break;
|
||||
case PROP_VENDOR_NAME:
|
||||
characterstring_init_ansi(&char_string, (char *) "ASHRAE");
|
||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_VENDOR_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_tagged_unsigned(&apdu[0], Device_Vendor_Identifier());
|
||||
break;
|
||||
case PROP_MODEL_NAME:
|
||||
characterstring_init_ansi(&char_string, (char *) "GNU");
|
||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_FIRMWARE_REVISION:
|
||||
characterstring_init_ansi(&char_string, (char *) "1.0");
|
||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_APPLICATION_SOFTWARE_VERSION:
|
||||
characterstring_init_ansi(&char_string, (char *) "1.0");
|
||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_PROTOCOL_VERSION:
|
||||
apdu_len =
|
||||
encode_tagged_unsigned(&apdu[0], Device_Protocol_Version());
|
||||
break;
|
||||
case PROP_PROTOCOL_REVISION:
|
||||
apdu_len =
|
||||
encode_tagged_unsigned(&apdu[0], Device_Protocol_Revision());
|
||||
break;
|
||||
/* BACnet Legacy Support */
|
||||
case PROP_PROTOCOL_CONFORMANCE_CLASS:
|
||||
apdu_len = encode_tagged_unsigned(&apdu[0], 1);
|
||||
break;
|
||||
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
||||
/* Note: list of services that are executed, not initiated. */
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* automatic lookup based on handlers set */
|
||||
bitstring_set_bit(&bit_string, (uint8_t) i,
|
||||
apdu_service_supported(i));
|
||||
}
|
||||
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
|
||||
/* Note: this is the list of objects that can be in this device,
|
||||
not a list of objects that this device can access */
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
|
||||
/* initialize all the object types to not-supported */
|
||||
bitstring_set_bit(&bit_string, (uint8_t) i, false);
|
||||
}
|
||||
/* FIXME: indicate the objects that YOU support */
|
||||
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
||||
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
/* Array element zero is the number of objects in the list */
|
||||
if (array_index == 0)
|
||||
apdu_len = encode_tagged_unsigned(&apdu[0], count);
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. Note that more than likely you will have */
|
||||
/* to return an error if the number of encoded objects exceeds */
|
||||
/* your maximum APDU size. */
|
||||
else if (array_index == BACNET_ARRAY_ALL) {
|
||||
for (i = 1; i <= count; i++) {
|
||||
if (Device_Object_List_Identifier(i, &object_type,
|
||||
&instance)) {
|
||||
len =
|
||||
encode_tagged_object_id(&apdu[apdu_len],
|
||||
object_type, instance);
|
||||
apdu_len += len;
|
||||
/* assume next one is the same size as this one */
|
||||
/* can we all fit into the APDU? */
|
||||
if ((apdu_len + len) >= MAX_APDU) {
|
||||
apdu_len = -2;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* error: internal error? */
|
||||
*error_class = ERROR_CLASS_SERVICES;
|
||||
*error_code = ERROR_CODE_OTHER;
|
||||
apdu_len = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Device_Object_List_Identifier(array_index, &object_type,
|
||||
&instance))
|
||||
apdu_len =
|
||||
encode_tagged_object_id(&apdu[0], object_type,
|
||||
instance);
|
||||
else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_MAX_APDU_LENGTH_ACCEPTED:
|
||||
apdu_len = encode_tagged_unsigned(&apdu[0],
|
||||
Device_Max_APDU_Length_Accepted());
|
||||
break;
|
||||
case PROP_SEGMENTATION_SUPPORTED:
|
||||
apdu_len = encode_tagged_enumerated(&apdu[0],
|
||||
Device_Segmentation_Supported());
|
||||
break;
|
||||
case PROP_APDU_TIMEOUT:
|
||||
apdu_len = encode_tagged_unsigned(&apdu[0], APDU_Timeout);
|
||||
break;
|
||||
case PROP_NUMBER_OF_APDU_RETRIES:
|
||||
apdu_len =
|
||||
encode_tagged_unsigned(&apdu[0],
|
||||
Device_Number_Of_APDU_Retries());
|
||||
break;
|
||||
case PROP_DEVICE_ADDRESS_BINDING:
|
||||
/* FIXME: encode the list here, if it exists */
|
||||
break;
|
||||
case PROP_DATABASE_REVISION:
|
||||
apdu_len =
|
||||
encode_tagged_unsigned(&apdu[0], Device_Database_Revision());
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "ctest.h"
|
||||
|
||||
void testDevice(Test * pTest)
|
||||
{
|
||||
bool status = false;
|
||||
const char *name = "Patricia";
|
||||
|
||||
status = Device_Set_Object_Instance_Number(0);
|
||||
ct_test(pTest, Device_Object_Instance_Number() == 0);
|
||||
ct_test(pTest, status == true);
|
||||
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||
ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE);
|
||||
ct_test(pTest, status == true);
|
||||
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2);
|
||||
ct_test(pTest,
|
||||
Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2));
|
||||
ct_test(pTest, status == true);
|
||||
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1);
|
||||
ct_test(pTest,
|
||||
Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1));
|
||||
ct_test(pTest, status == false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TEST_DEVICE
|
||||
/* stubs to dependencies to keep unit test simple */
|
||||
char *Analog_Input_Name(uint32_t object_instance)
|
||||
{
|
||||
(void) object_instance;
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned Analog_Input_Count(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Analog_Input_Index_To_Instance(unsigned index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
char *Analog_Output_Name(uint32_t object_instance)
|
||||
{
|
||||
(void) object_instance;
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned Analog_Output_Count(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Analog_Output_Index_To_Instance(unsigned index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
|
||||
pTest = ct_create("BACnet Tiny Device", NULL);
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testDevice);
|
||||
assert(rc);
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void) ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* TEST_DEVICE */
|
||||
#endif /* TEST */
|
||||
@@ -1,328 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#if PRINT_ENABLED
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include "bacdef.h"
|
||||
#include "mstp.h"
|
||||
#include "dlmstp.h"
|
||||
#include "rs485.h"
|
||||
#include "npdu.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
/* Number of MS/TP Packets Rx/Tx
|
||||
*/
|
||||
uint16_t MSTP_Packets = 0;
|
||||
|
||||
/* receive buffer */
|
||||
#pragma udata MSTP_RxData
|
||||
static DLMSTP_PACKET Receive_Buffer;
|
||||
/* temp buffer for NPDU insertion */
|
||||
/* local MS/TP port data - shared with RS-485 */
|
||||
#pragma udata MSTP_PortData
|
||||
volatile struct mstp_port_struct_t MSTP_Port;
|
||||
#pragma udata
|
||||
|
||||
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
|
||||
|
||||
/* This defines the number of edit fields for this module
|
||||
*/
|
||||
#define MAX_EDIT_FIELD 1
|
||||
static uint8_t EditField = 0;
|
||||
/* *************************************************************************
|
||||
DESCRIPTION: This function handles incrementing or decrementing our
|
||||
EditField
|
||||
RETURN: none
|
||||
ALGORITHM: none
|
||||
NOTES: Pass a #>0 to increment #<0 to decrement
|
||||
*************************************************************************** */
|
||||
void dlmstp_SetEditField(signed char state)
|
||||
{ /* direction our editfield is moving */
|
||||
if (state > 0) {
|
||||
if (++EditField > MAX_EDIT_FIELD)
|
||||
EditField = 0;
|
||||
} else if (state < 0) {
|
||||
if (EditField)
|
||||
EditField--;
|
||||
else
|
||||
EditField = MAX_EDIT_FIELD;
|
||||
} else
|
||||
EditField = 0;
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
DESCRIPTION: Gets the current edit field for this module
|
||||
RETURN: the current edit field
|
||||
ALGORITHM: none
|
||||
NOTES: none
|
||||
*************************************************************************** */
|
||||
uint8_t dlmstp_GetEditField(void)
|
||||
{
|
||||
return (EditField);
|
||||
}
|
||||
|
||||
void dlmstp_millisecond_timer(void)
|
||||
{
|
||||
INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer);
|
||||
}
|
||||
|
||||
void dlmstp_reinit(void)
|
||||
{
|
||||
RS485_Reinit();
|
||||
dlmstp_set_my_address(DEFAULT_MAC_ADDRESS);
|
||||
dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES);
|
||||
dlmstp_set_max_master(DEFAULT_MAX_MASTER);
|
||||
}
|
||||
|
||||
void dlmstp_init(void)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
/* initialize buffer */
|
||||
Receive_Buffer.ready = false;
|
||||
Receive_Buffer.pdu_len = 0;
|
||||
/* initialize hardware */
|
||||
RS485_Initialize();
|
||||
MSTP_Port.InputBuffer = &Receive_Buffer.pdu[0];
|
||||
MSTP_Init(&MSTP_Port);
|
||||
data = I2C_Read_Byte(EEPROM_DEVICE_ADDRESS, EEPROM_MSTP_MAC_ADDR);
|
||||
if (data <= 127)
|
||||
MSTP_Port.This_Station = data;
|
||||
else
|
||||
dlmstp_set_my_address(DEFAULT_MAC_ADDRESS);
|
||||
data = I2C_Read_Byte(EEPROM_DEVICE_ADDRESS,
|
||||
EEPROM_MSTP_MAX_MASTER_ADDR);
|
||||
if (data <= 127)
|
||||
MSTP_Port.Nmax_master = data;
|
||||
else
|
||||
dlmstp_set_max_master(DEFAULT_MAX_MASTER);
|
||||
MSTP_Port.Nmax_info_frames =
|
||||
I2C_Read_Byte(EEPROM_DEVICE_ADDRESS,
|
||||
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR);
|
||||
}
|
||||
|
||||
void dlmstp_cleanup(void)
|
||||
{
|
||||
/* nothing to do for static buffers */
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, zero on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
BACNET_NPDU_DATA * npdu_data, /* network information */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
{ /* number of bytes of data */
|
||||
int bytes_sent = 0;
|
||||
unsigned npdu_len = 0;
|
||||
uint8_t frame_type = 0;
|
||||
uint8_t destination = 0; /* destination address */
|
||||
BACNET_ADDRESS src;
|
||||
unsigned i = 0; /* loop counter */
|
||||
|
||||
if (MSTP_Port.TxReady == false) {
|
||||
if (npdu_data->data_expecting_reply)
|
||||
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
|
||||
else
|
||||
MSTP_Port.TxFrameType =
|
||||
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
||||
|
||||
/* load destination MAC address */
|
||||
if (dest && dest->mac_len == 1) {
|
||||
destination = dest->mac[0];
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
dlmstp_get_my_address(&src);
|
||||
if ((8 /* header len */ + pdu_len) > MAX_MPDU) {
|
||||
return -4;
|
||||
}
|
||||
bytes_sent = MSTP_Create_Frame(
|
||||
(uint8_t *) & MSTP_Port.TxBuffer[0],
|
||||
sizeof(MSTP_Port.TxBuffer),
|
||||
MSTP_Port.TxFrameType,
|
||||
destination, MSTP_Port.This_Station, pdu, pdu_len);
|
||||
MSTP_Port.TxLength = bytes_sent;
|
||||
MSTP_Port.TxReady = true;
|
||||
MSTP_Packets++;
|
||||
}
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
void dlmstp_task(void)
|
||||
{
|
||||
uint8_t bytes_remaining;
|
||||
bool received_frame;
|
||||
|
||||
/* only do receive state machine while we don't have a frame */
|
||||
if ((MSTP_Port.ReceivedValidFrame == false) &&
|
||||
(MSTP_Port.ReceivedInvalidFrame == false)) {
|
||||
do {
|
||||
bytes_remaining = RS485_Check_UART_Data(&MSTP_Port);
|
||||
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
||||
received_frame = MSTP_Port.ReceivedValidFrame ||
|
||||
MSTP_Port.ReceivedInvalidFrame;
|
||||
if (received_frame)
|
||||
break;
|
||||
} while (bytes_remaining);
|
||||
}
|
||||
/* only do master state machine while rx is idle */
|
||||
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) {
|
||||
while (MSTP_Master_Node_FSM(&MSTP_Port)) {
|
||||
};
|
||||
/*MSTP_Master_Node_FSM(&MSTP_Port);
|
||||
*/
|
||||
}
|
||||
/* see if there is a packet available, and a place
|
||||
to put the reply (if necessary) and process it */
|
||||
if (Receive_Buffer.ready && !MSTP_Port.TxReady) {
|
||||
if (Receive_Buffer.pdu_len) {
|
||||
MSTP_Packets++;
|
||||
npdu_handler(&Receive_Buffer.address,
|
||||
&Receive_Buffer.pdu[0], Receive_Buffer.pdu_len);
|
||||
}
|
||||
Receive_Buffer.ready = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_fill_bacnet_address(BACNET_ADDRESS * src, uint8_t mstp_address)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (mstp_address == MSTP_BROADCAST_ADDRESS) {
|
||||
/* mac_len = 0 if broadcast address */
|
||||
src->mac_len = 0;
|
||||
src->mac[0] = 0;
|
||||
} else {
|
||||
src->mac_len = 1;
|
||||
src->mac[0] = mstp_address;
|
||||
}
|
||||
/* fill with 0's starting with index 1; index 0 filled above */
|
||||
for (i = 1; i < MAX_MAC_LEN; i++) {
|
||||
src->mac[i] = 0;
|
||||
}
|
||||
src->net = 0;
|
||||
src->len = 0;
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
src->adr[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* for the MS/TP state machine to use for putting received data */
|
||||
uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t pdu_len)
|
||||
{ /* amount of PDU data */
|
||||
/* PDU is already in the Receive_Buffer */
|
||||
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
|
||||
Receive_Buffer.pdu_len = pdu_len;
|
||||
Receive_Buffer.ready = true;
|
||||
}
|
||||
|
||||
void dlmstp_set_my_address(uint8_t mac_address)
|
||||
{
|
||||
/* Master Nodes can only have address 0-127 */
|
||||
if (mac_address <= 127)
|
||||
MSTP_Port.This_Station = mac_address;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t dlmstp_my_address(void)
|
||||
{
|
||||
return MSTP_Port.This_Station;
|
||||
}
|
||||
|
||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||
/* maximum number of information frames the node may send before it must */
|
||||
/* pass the token. Max_Info_Frames may have different values on different */
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
void dlmstp_set_max_info_frames(unsigned max_info_frames)
|
||||
{
|
||||
MSTP_Port.Nmax_info_frames = max_info_frames;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned dlmstp_max_info_frames(void)
|
||||
{
|
||||
return MSTP_Port.Nmax_info_frames;
|
||||
}
|
||||
|
||||
/* This parameter represents the value of the Max_Master property of the */
|
||||
/* node's Device object. The value of Max_Master specifies the highest */
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
void dlmstp_set_max_master(uint8_t max_master)
|
||||
{
|
||||
if (max_master <= 127)
|
||||
MSTP_Port.Nmax_master = max_master;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t dlmstp_max_master(void)
|
||||
{
|
||||
return MSTP_Port.Nmax_master;
|
||||
}
|
||||
|
||||
void dlmstp_get_my_address(BACNET_ADDRESS * my_address)
|
||||
{
|
||||
int i = 0; /* counter */
|
||||
|
||||
my_address->mac_len = 1;
|
||||
my_address->mac[0] = MSTP_Port.This_Station;
|
||||
my_address->net = 0; /* local only, no routing */
|
||||
my_address->len = 0;
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
my_address->adr[i] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest)
|
||||
{ /* destination address */
|
||||
int i = 0; /* counter */
|
||||
|
||||
if (dest) {
|
||||
dest->mac_len = 1;
|
||||
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
|
||||
dest->net = BACNET_BROADCAST_NETWORK;
|
||||
dest->len = 0; /* len=0 denotes broadcast address */
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
dest->adr[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Mark Norton and Steve Karg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Functional
|
||||
* Description: Defines the hardware implementation for the Microchip
|
||||
* microprocessor used in the Synergy lighting control project.
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef HARDWARE_H
|
||||
#define HARDWARE_H
|
||||
|
||||
#include <p18F452.h>
|
||||
#include <portb.h>
|
||||
#include <timers.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Card IO *
|
||||
****************************************************************************/
|
||||
/*
|
||||
TRIS masks are:
|
||||
0 = OUTPUT
|
||||
1 = INPUT
|
||||
|
||||
The IO on this card is as follows:
|
||||
RA0 - SDA - SEEPROM (input)
|
||||
RA1 - SCL - SEEPROM (input)
|
||||
RA2 - not used (input)
|
||||
RA3 - not used (input)
|
||||
RA4 - LK2a - jumper (input)
|
||||
RA5 - LK2b - jumper (input)
|
||||
|
||||
TRISA - 0011 1111 - 3Fh
|
||||
|
||||
RB0 - INT - Zero Cross Interrupt (input)
|
||||
RB1 - LED - I2C Bus Indication (output)
|
||||
RB2 - LED - Labeled 'DATA' (output)
|
||||
RB3 - not used (input)
|
||||
RB4 - CTS input for RS-232 (not used unless LT1180A chip is there)
|
||||
RB5 - RTS output for RS-232 (not used unless LT1180A chip is there)
|
||||
RB6 - PGC - in circuit programming (input)
|
||||
RB7 - PGD - in circuit programming (input)
|
||||
|
||||
TRISB - 1101 1001 - D9h
|
||||
|
||||
RC0 - QH of 74165 shift register (input)
|
||||
RC1 - SHIFTREG_CKL of 74165 shift register (output)
|
||||
RC2 - SHIFTREG_LOAD of 74165 shift register (output)
|
||||
RC3 - SCL for I2C bus (input)
|
||||
RC4 - SDA for I2C bus (input)
|
||||
RC5 - RS-485 TXEN (or RS232) (output)
|
||||
RC6 - RS-485 TXD (or RS232) (output)
|
||||
RC7 - RS-485 RXD (or RS232) (input)
|
||||
|
||||
TRISC - 1001 1001 - 99h
|
||||
|
||||
*/
|
||||
|
||||
#define PORT_A_TRIS_MASK 0x3F
|
||||
#define PORT_B_TRIS_MASK 0xD9
|
||||
#define PORT_C_TRIS_MASK 0x99
|
||||
|
||||
/* hardware mapping of functionality */
|
||||
#define DATA_LED_ON() PORTBbits.RB2=0
|
||||
#define DATA_LED_OFF() PORTBbits.RB2=1
|
||||
|
||||
#define ABUS_LED_ON() PORTBbits.RB1=0
|
||||
#define ABUS_LED_OFF() PORTBbits.RB1=1
|
||||
|
||||
#define RS485_TRANSMIT_DISABLE() PORTCbits.RC5=0
|
||||
#define RS485_TRANSMIT_ENABLE() PORTCbits.RC5=1
|
||||
|
||||
/* note: board is inverted logic */
|
||||
#define JUMPER_LK2_TOP_OFF() PORTAbits.RA4
|
||||
#define JUMPER_LK2_TOP_ON() (!PORTAbits.RA4)
|
||||
#define JUMPER_LK2_BOTTOM_OFF() PORTAbits.RA5
|
||||
#define JUMPER_LK2_BOTTOM_ON() (!PORTAbits.RA5)
|
||||
|
||||
#define ZERO_CROSS PORTBbits.RB0
|
||||
|
||||
#define I2C_CLK_LATCH LATCbits.LATC3
|
||||
#define I2C_DATA_LATCH LATCbits.LATC4
|
||||
#define I2C_CLK PORTCbits.RC3
|
||||
#define I2C_DATA PORTCbits.RC4
|
||||
#define I2C_CLK_HI_Z TRISCbits.TRISC3
|
||||
#define I2C_SDA_HI_Z TRISCbits.TRISC4
|
||||
|
||||
#define EEPROM_DATA_LATCH LATAbits.LATA0
|
||||
#define EEPROM_CLK_LATCH LATAbits.LATA1
|
||||
#define EEPROM_SDA PORTAbits.RA0
|
||||
#define EEPROM_CLK PORTAbits.RA1
|
||||
#define EEPROM_SDA_HI_Z TRISAbits.TRISA0
|
||||
#define EEPROM_CLK_HI_Z TRISAbits.TRISA1
|
||||
|
||||
#define SHIFTREG_LOAD PORTCbits.RC2
|
||||
#define SHIFTREG_CLK PORTCbits.RC1
|
||||
#define SHIFTREG_DATA PORTCbits.RC0
|
||||
|
||||
#define NO_ANALOGS 0x06 /* None */
|
||||
#define ALL_ANALOG 0x00 /* RA0 RA1 RA2 RA3 RA5 RE0 RE1 RE2 Ref=Vdd */
|
||||
#define ANALOG_RA3_REF 0x01 /* RA0 RA1 RA2 RA5 RE0 RE1 RE2 Ref=RA3 */
|
||||
#define A_ANALOG 0x02 /* RA0 RA1 RA2 RA3 RA5 Ref=Vdd */
|
||||
#define A_ANALOG_RA3_REF 0x03 /* RA0 RA1 RA2 RA5 Ref=RA3 */
|
||||
#define RA0_RA1_RA3_ANALOG 0x04 /* RA0 RA1 RA3 Ref=Vdd */
|
||||
#define RA0_RA1_ANALOG_RA3_REF 0x05 /* RA0 RA1 Ref=RA3 */
|
||||
|
||||
#define ANALOG_RA3_RA2_REF 0x08
|
||||
#define ANALOG_NOT_RE1_RE2 0x09
|
||||
#define ANALOG_NOT_RE1_RE2_REF_RA3 0x0A
|
||||
#define ANALOG_NOT_RE1_RE2_REF_RA3_RA2 0x0B
|
||||
#define A_ANALOG_RA3_RA2_REF 0x0C
|
||||
#define RA0_RA1_ANALOG_RA3_RA2_REF 0x0D
|
||||
#define RA0_ANALOG 0x0E
|
||||
#define RA0_ANALOG_RA3_RA2_REF 0x0F
|
||||
|
||||
/* Constants used for SETUP_ADC() are: */
|
||||
#define ADC_OFF 0
|
||||
#define ADC_START 4
|
||||
#define ADC_CLOCK_DIV_2 1
|
||||
#define ADC_CLOCK_DIV_4 0x101
|
||||
#define ADC_CLOCK_DIV_8 0x41
|
||||
#define ADC_CLOCK_DIV_16 0x141
|
||||
#define ADC_CLOCK_DIV_32 0x81
|
||||
#define ADC_CLOCK_DIV_64 0x181
|
||||
#define ADC_CLOCK_INTERNAL 0xc1
|
||||
#define ADC_DONE_MASK 0x04
|
||||
|
||||
#define SET_ADC_CHAN(x) ADCON0 = (ADC_CLOCK_DIV_32 | ((x) << 3))
|
||||
|
||||
#define T1_DISABLED 0
|
||||
#define T1_INTERNAL 0x85
|
||||
#define T1_EXTERNAL 0x87
|
||||
#define T1_EXTERNAL_SYNC 0x83
|
||||
|
||||
#define T1_CLK_OUT 8
|
||||
|
||||
#define T1_DIV_BY_1 0
|
||||
#define T1_DIV_BY_2 0x10
|
||||
#define T1_DIV_BY_4 0x20
|
||||
#define T1_DIV_BY_8 0x30
|
||||
#define SETUP_TIMER1(mode) T1CON = (mode)
|
||||
|
||||
#define T2_DISABLED 0
|
||||
#define T2_DIV_BY_1 4
|
||||
#define T2_DIV_BY_4 5
|
||||
#define T2_DIV_BY_16 6
|
||||
#define SETUP_TIMER2(mode, period, postscale) \
|
||||
{ \
|
||||
T2CON = ((mode) | ((postscale)-1)<<3); \
|
||||
PR2 = (period); \
|
||||
}
|
||||
|
||||
#define T3_DISABLED 0
|
||||
#define T3_INTERNAL 0x85
|
||||
#define T3_EXTERNAL 0x87
|
||||
#define T3_EXTERNAL_SYNC 0x83
|
||||
|
||||
#define T3_DIV_BY_1 0
|
||||
#define T3_DIV_BY_2 0x10
|
||||
#define T3_DIV_BY_4 0x20
|
||||
#define T3_DIV_BY_8 0x30
|
||||
#define SETUP_TIMER3(mode) T3CON = (mode)
|
||||
|
||||
#define CCP_OFF 0
|
||||
#define CCP_CAPTURE_FE 4
|
||||
#define CCP_CAPTURE_RE 5
|
||||
#define CCP_CAPTURE_DIV_4 6
|
||||
#define CCP_CAPTURE_DIV_16 7
|
||||
#define CCP_COMPARE_SET_ON_MATCH 8
|
||||
#define CCP_COMPARE_CLR_ON_MATCH 9
|
||||
#define CCP_COMPARE_INT 0xA
|
||||
#define CCP_COMPARE_RESET_TIMER 0xB
|
||||
#define CCP_PWM 0xC
|
||||
#define CCP_PWM_PLUS_1 0x1c
|
||||
#define CCP_PWM_PLUS_2 0x2c
|
||||
#define CCP_PWM_PLUS_3 0x3c
|
||||
#define SETUP_CCP1(mode) CCP1CON = (mode)
|
||||
#define SETUP_CCP2(mode) CCP2CON = (mode)
|
||||
|
||||
#define WATCHDOG_TIMER() \
|
||||
{ \
|
||||
_asm \
|
||||
CLRWDT \
|
||||
_endasm \
|
||||
}
|
||||
|
||||
#define GLOBAL_INT_ENABLE() INTCONbits.GIE = 1
|
||||
#define GLOBAL_INT_DISABLE() INTCONbits.GIE = 0
|
||||
|
||||
#define PERIPHERAL_INT_ENABLE() INTCONbits.PEIE = 1
|
||||
#define PERIPHERAL_INT_DISABLE() INTCONbits.PEIE = 0
|
||||
|
||||
#define TIMER0_INT_ENABLE() INTCONbits.TMR0IE = 1
|
||||
#define TIMER0_INT_DISABLE() INTCONbits.TMR0IE = 0
|
||||
|
||||
#define TIMER2_INT_ENABLE() PIE1bits.TMR2IE = 1
|
||||
#define TIMER2_INT_DISABLE() PIE1bits.TMR2IE = 0
|
||||
|
||||
#define CCP2_INT_ENABLE() PIE2bits.CCP2IE = 1
|
||||
#define CCP2_INT_DISABLE() PIE2bits.CCP2IE = 0
|
||||
|
||||
#define CCP1_INT_ENABLE() PIE1bits.CCP1IE = 1
|
||||
#define CCP1_INT_DISABLE() PIE1bits.CCP1IE = 0
|
||||
|
||||
#define ABUS_INT_ENABLE() PIE1bits.SSPIE = 1
|
||||
#define ABUS_INT_DISABLE() PIE1bits.SSPIE = 0
|
||||
#define ABUS_INT_FLAG_CLEAR() PIR1bits.SSPIF = 0
|
||||
|
||||
#define USART_RX_INT_DISABLE() PIE1bits.RCIE = 0
|
||||
#define USART_RX_INT_ENABLE() PIE1bits.RCIE = 1
|
||||
|
||||
#define USART_TX_INTERRUPT() PIE1bits.TXIE
|
||||
#define USART_TX_INT_DISABLE() PIE1bits.TXIE = 0
|
||||
#define USART_TX_INT_ENABLE() PIE1bits.TXIE = 1
|
||||
#define USART_TX_ENABLE() TXSTAbits.TXEN = 1
|
||||
#define USART_TX_INT_FLAG_CLEAR() PIR1bits.TXIF = 0
|
||||
#define USART_TX_EMPTY() TXSTAbits.TRMT
|
||||
#define USART_CONTINUOUS_RX_ENABLE() RCSTAbits.CREN = 1
|
||||
#define USART_CONTINUOUS_RX_DISABLE() RCSTAbits.CREN = 0
|
||||
#define USART_RX_COMPLETE() PIR1bits.RCIF
|
||||
#define USART_RX_STATUS() RCSTAbits
|
||||
#define USART_RX_STATUS() RCSTAbits
|
||||
#define USART_TRANSMIT(x) TXREG = (x)
|
||||
#define USART_RECEIVE() RCREG
|
||||
#define USART_RX_FRAME_ERROR() rcstabits.FERR
|
||||
/* combine the sequence correctly */
|
||||
#define USART_RX_SETUP() PIE1bits.RCIE = 1; RCSTAbits.CREN = 1
|
||||
#define USART_TX_SETUP() PIE1bits.TXIE = 1; TXSTAbits.TXEN = 1
|
||||
|
||||
|
||||
#endif /* HARDWARE_H */
|
||||
@@ -1,130 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Mark Norton
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Functional
|
||||
* Description: Handles the init code for the Microchip microprocessor
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
|
||||
/* define this to enable ICD */
|
||||
/*#define USE_ICD */
|
||||
|
||||
/* Configuration Bits */
|
||||
#pragma config OSC = HS
|
||||
#pragma config PWRT = ON
|
||||
#pragma config BOR = ON, BORV = 42
|
||||
#pragma config CCP2MUX = ON
|
||||
#pragma config STVR = ON
|
||||
#pragma config LVP = OFF
|
||||
#pragma config CP0 = OFF
|
||||
#pragma config CP1 = OFF
|
||||
#pragma config CP2 = OFF
|
||||
#pragma config CP3 = OFF
|
||||
#pragma config CPB = OFF
|
||||
#pragma config CPD = OFF
|
||||
#pragma config WRT0 = OFF
|
||||
#pragma config WRT1 = OFF
|
||||
#pragma config WRT2 = OFF
|
||||
#pragma config WRT3 = OFF
|
||||
#pragma config WRTB = OFF
|
||||
#pragma config WRTC = OFF
|
||||
#pragma config WRTD = OFF
|
||||
#pragma config EBTR0 = OFF
|
||||
#pragma config EBTR1 = OFF
|
||||
#pragma config EBTR2 = OFF
|
||||
#pragma config EBTR3 = OFF
|
||||
#pragma config EBTRB = OFF
|
||||
|
||||
#ifdef USE_ICD
|
||||
#pragma config WDT = OFF, WDTPS = 128
|
||||
#pragma config DEBUG = ON
|
||||
#else
|
||||
#pragma config WDT = ON, WDTPS = 128
|
||||
#pragma config DEBUG = OFF
|
||||
#endif /* USE_ICD */
|
||||
|
||||
#pragma romdata
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Initializes the PIC, its timers, WDT, etc.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void init_hardware(void)
|
||||
{
|
||||
/* If the processor gets a power on reset then we can do something. */
|
||||
/* We should not get a reset unless there has been */
|
||||
/* some kind of power line disturbance. */
|
||||
if (RCONbits.POR) {
|
||||
/*do something special! */
|
||||
}
|
||||
|
||||
GLOBAL_INT_DISABLE();
|
||||
|
||||
/* Setup PORT A */
|
||||
TRISA = PORT_A_TRIS_MASK;
|
||||
|
||||
/* PORT A can have analog inputs or digital IO */
|
||||
ADCON1 = NO_ANALOGS;
|
||||
|
||||
/* Setup PORT B */
|
||||
TRISB = PORT_B_TRIS_MASK;
|
||||
|
||||
/* Setup PORT C */
|
||||
TRISC = PORT_C_TRIS_MASK;
|
||||
|
||||
/* setup zero cross interrupt to trigger on a low to high edge */
|
||||
INTCON2bits.INTEDG0 = 1;
|
||||
|
||||
/* setup ABUS */
|
||||
/*ABUS_LED_OFF(); */
|
||||
/*SSPADD = ABUS_DEFAULT_ADDR; */
|
||||
/*SSPCON1 = (ABUS_SLAVE_MASK | ABUS_CLK_ENABLE | ABUS_MODE_SETUP); */
|
||||
/*ABUS_Clear_SSPBUF(); */
|
||||
|
||||
/* setup timer2 to reset every 1ms */
|
||||
CloseTimer2();
|
||||
PR2 = 250;
|
||||
OpenTimer2(T2_PS_1_4 & T2_POST_1_5 & 0x7F);
|
||||
|
||||
/* Setup our interrupt priorities ---------> all low priority */
|
||||
RCONbits.IPEN = 1;
|
||||
IPR1 = 0;
|
||||
IPR2 = 0;
|
||||
INTCON2bits.TMR0IP = 0;
|
||||
INTCON2bits.RBIP = 0;
|
||||
INTCON3 = 0;
|
||||
|
||||
/* Enable interrupts */
|
||||
TIMER2_INT_ENABLE();
|
||||
PERIPHERAL_INT_ENABLE();
|
||||
GLOBAL_INT_ENABLE();
|
||||
|
||||
/* Turn on the Zero cross interrupt */
|
||||
INTCONbits.INT0F = 0;
|
||||
INTCONbits.INT0E = 1;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef INIT_H
|
||||
#define INIT_H
|
||||
|
||||
void init_hardware(void);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,165 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Mark Norton and Steve Karg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Functional
|
||||
* Description: Defines the interrupt service routines (ISR) for the
|
||||
* Microchip microprocessor used in the Synergy lighting
|
||||
* control project.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* interrupt service routines */
|
||||
extern void RS485_Receive_Interrupt(void);
|
||||
extern void RS485_Transmit_Interrupt(void);
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: High priority interrupt routine
|
||||
* PARAMETERS: none
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
#pragma interruptlow InterruptHandlerLow save=PROD, section(".tmpdata")
|
||||
void InterruptHandlerLow(void)
|
||||
{
|
||||
/* check for timer0 interrupt */
|
||||
if ((INTCONbits.TMR0IF) && (INTCONbits.TMR0IE)) {
|
||||
/* clear interrupt flag */
|
||||
INTCONbits.TMR0IF = 0;
|
||||
/* call interrupt handler */
|
||||
}
|
||||
/*check for timer1 interrupt */
|
||||
if ((PIR1bits.TMR1IF) && (PIE1bits.TMR1IE)) {
|
||||
PIR1bits.TMR1IF = 0;
|
||||
/* call interrupt handler */
|
||||
}
|
||||
/*check for timer2 interrupt */
|
||||
if ((PIR1bits.TMR2IF) && (PIE1bits.TMR2IE)) {
|
||||
PIR1bits.TMR2IF = 0;
|
||||
Timer_Millisecond_Interrupt();
|
||||
}
|
||||
/*check for timer3 interrupt */
|
||||
if ((PIR2bits.TMR3IF) && (PIE2bits.TMR3IE)) {
|
||||
PIR2bits.TMR3IF = 0;
|
||||
/* call interrupt handler */
|
||||
}
|
||||
/*check for compare 1 int */
|
||||
if ((PIR1bits.CCP1IF) && (PIE1bits.CCP1IE)) {
|
||||
PIR1bits.CCP1IF = 0;
|
||||
/* call interrupt handler */
|
||||
}
|
||||
/*check for compare 2 int */
|
||||
if ((PIR2bits.CCP2IF) && (PIE2bits.CCP2IE)) {
|
||||
PIR2bits.CCP2IF = 0;
|
||||
/* call interrupt handler */
|
||||
}
|
||||
/*check for USART Rx int */
|
||||
if ((PIR2bits.EEIF) && (PIE2bits.EEIE)) {
|
||||
PIR2bits.EEIF = 0; /*clear interrupt flag */
|
||||
EECON1bits.WREN = 0; /* disable writes */
|
||||
/* call interrupt handler */
|
||||
}
|
||||
/*check for USART Tx int */
|
||||
if ((PIR1bits.TXIF) && (PIE1bits.TXIE)) {
|
||||
/* call interrupt handler */
|
||||
RS485_Transmit_Interrupt();
|
||||
}
|
||||
/*check for USART Rx int */
|
||||
if ((PIR1bits.RCIF) && (PIE1bits.RCIE)) {
|
||||
/* call interrupt handler */
|
||||
RS485_Receive_Interrupt();
|
||||
}
|
||||
/*check for AD int */
|
||||
if ((PIR1bits.ADIF) && (PIE1bits.ADIE)) {
|
||||
/* call interrupt handler */
|
||||
PIR1bits.ADIF = 0;
|
||||
}
|
||||
/*check for I2C receive int (MSSP int) */
|
||||
if ((PIR1bits.SSPIF) && (PIE1bits.SSPIE)) {
|
||||
PIR1bits.SSPIF = 0;
|
||||
/* call interrupt handler */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: High priority interrupt routine
|
||||
* PARAMETERS: none
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: don't call functions from this function because registers are
|
||||
* not saved, and saving registers is slower.
|
||||
*****************************************************************************/
|
||||
#pragma interrupt InterruptHandlerHigh
|
||||
void InterruptHandlerHigh(void)
|
||||
{
|
||||
/*check for external int */
|
||||
if ((INTCONbits.INT0IF) && (INTCONbits.INT0IE)) {
|
||||
/* Test to ensure that we are not getting a false trigger on the
|
||||
falling edge. Only trigger on Rising edge. */
|
||||
if (ZERO_CROSS) {
|
||||
/* timer used to determine when power is gone (no zero crosses) */
|
||||
/* Power_Timeout = 30; */
|
||||
/* if (ABUS_Current_Status.Zerox_Fail) */
|
||||
/* { */
|
||||
/* ABUS_Flags.SendStatus = TRUE; */
|
||||
/* ABUS_Current_Status.Zerox_Fail = FALSE; */
|
||||
/* } */
|
||||
/* if we get here it means power is good */
|
||||
/* System_Flags.PowerFail = FALSE; */
|
||||
}
|
||||
INTCONbits.INT0IF = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: High priority interrupt vector
|
||||
* PARAMETERS: none
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: ISRs not here because we would only have 0x10 bytes for code
|
||||
*****************************************************************************/
|
||||
#pragma code InterruptVectorHigh = 0x08
|
||||
void InterruptVectorHigh(void)
|
||||
{
|
||||
_asm goto InterruptHandlerHigh /*jump to interrupt routine */
|
||||
_endasm}
|
||||
#pragma code
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Low priority interrupt vector
|
||||
* PARAMETERS: none
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
#pragma code InterruptVectorLow = 0x18
|
||||
void InterruptVectorLow(void)
|
||||
{
|
||||
_asm goto InterruptHandlerLow /*jump to interrupt routine */
|
||||
_endasm}
|
||||
#pragma code
|
||||
@@ -1,192 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "mstp.h"
|
||||
#include "bytes.h"
|
||||
#include "crc.h"
|
||||
#include "rs485.h"
|
||||
#include "init.h"
|
||||
#include "timer.h"
|
||||
#include "datalink.h"
|
||||
#include "handlers.h"
|
||||
#include "device.h"
|
||||
#include "hardware.h"
|
||||
#include "iam.h"
|
||||
/* for readproperty handler */
|
||||
#include "config.h"
|
||||
#include "txbuf.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacerror.h"
|
||||
#include "apdu.h"
|
||||
#include "npdu.h"
|
||||
#include "abort.h"
|
||||
#include "rp.h"
|
||||
|
||||
/* buffer used for encoding RP apdu */
|
||||
static uint8_t Temp_Buf[MAX_APDU];
|
||||
/* buffer used for receiving */
|
||||
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||
|
||||
/* address where message came from */
|
||||
static BACNET_ADDRESS src;
|
||||
/* address used to send */
|
||||
static BACNET_ADDRESS my_address;
|
||||
|
||||
/* see demo/handler/h_rp.c for a more complete example */
|
||||
void My_Read_Property_Handler(uint8_t * service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||
{
|
||||
BACNET_READ_PROPERTY_DATA data;
|
||||
int len = 0;
|
||||
int pdu_len = 0;
|
||||
bool send = false;
|
||||
bool error = false;
|
||||
int bytes_sent = 0;
|
||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
BACNET_ADDRESS my_address;
|
||||
|
||||
len = rp_decode_service_request(service_request, service_len, &data);
|
||||
/* encode the NPDU portion of the packet */
|
||||
datalink_get_my_address(&my_address);
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src,
|
||||
&my_address, &npdu_data);
|
||||
/* bad decoding - send an abort */
|
||||
if (len < 0) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
} else if (service_data->segmented_message) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
} else {
|
||||
switch (data.object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
/* FIXME: probably need a length limitation sent with encode */
|
||||
if (data.object_instance == Device_Object_Instance_Number()) {
|
||||
len = Device_Encode_Property_APDU(&Temp_Buf[0],
|
||||
data.object_property,
|
||||
data.array_index, &error_class, &error_code);
|
||||
if (len >= 0) {
|
||||
/* encode the APDU portion of the packet */
|
||||
data.application_data = &Temp_Buf[0];
|
||||
data.application_data_len = len;
|
||||
/* FIXME: probably need a length limitation sent with encode */
|
||||
len =
|
||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer
|
||||
[pdu_len], service_data->invoke_id, &data);
|
||||
} else
|
||||
error = true;
|
||||
} else
|
||||
error = true;
|
||||
break;
|
||||
default:
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
||||
}
|
||||
pdu_len += len;
|
||||
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||
&Handler_Transmit_Buffer[0], pdu_len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Handles our calling our module level milisecond counters
|
||||
* PARAMETERS: none
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
static void Check_Timer_Milliseconds(void)
|
||||
{
|
||||
/* We might have missed some so keep doing it until we have got them all */
|
||||
while (Milliseconds) {
|
||||
dlmstp_millisecond_timer();
|
||||
Milliseconds--;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
unsigned timeout = 100; /* milliseconds */
|
||||
uint16_t pdu_len = 0;
|
||||
|
||||
|
||||
/* we need to handle who-is
|
||||
to support dynamic device binding to us */
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
|
||||
handler_who_is);
|
||||
/* set the handler for all the services we don't implement
|
||||
It is required to send the proper reject message... */
|
||||
apdu_set_unrecognized_service_handler_handler
|
||||
(handler_unrecognized_service);
|
||||
/* we must implement read property - it's required! */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
My_Read_Property_Handler);
|
||||
/* handle communication so we can shutup when asked */
|
||||
apdu_set_confirmed_handler
|
||||
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
|
||||
Device_Set_Object_Instance_Number(5);
|
||||
dlmstp_set_my_address(0x05);
|
||||
dlmstp_init();
|
||||
|
||||
init_hardware();
|
||||
|
||||
/* broadcast an I-Am on startup */
|
||||
iam_send(&Handler_Transmit_Buffer[0]);
|
||||
/* loop forever */
|
||||
for (;;) {
|
||||
WATCHDOG_TIMER();
|
||||
|
||||
/* input */
|
||||
Check_Timer_Milliseconds();
|
||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||
/* process */
|
||||
if (pdu_len) {
|
||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||
}
|
||||
|
||||
/* output */
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,246 +0,0 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2004 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307
|
||||
USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
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
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
|
||||
#ifndef MSTP_H
|
||||
#define MSTP_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "bacdef.h"
|
||||
#include "dlmstp.h"
|
||||
|
||||
/* The value 255 is used to denote broadcast when used as a */
|
||||
/* destination address but is not allowed as a value for a station. */
|
||||
/* Station addresses for master nodes can be 0-127. */
|
||||
/* Station addresses for slave nodes can be 127-254. */
|
||||
#define MSTP_BROADCAST_ADDRESS 255
|
||||
|
||||
/* MS/TP Frame Type */
|
||||
/* Frame Types 8 through 127 are reserved by ASHRAE. */
|
||||
#define FRAME_TYPE_TOKEN 0
|
||||
#define FRAME_TYPE_POLL_FOR_MASTER 1
|
||||
#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2
|
||||
#define FRAME_TYPE_TEST_REQUEST 3
|
||||
#define FRAME_TYPE_TEST_RESPONSE 4
|
||||
#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5
|
||||
#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6
|
||||
#define FRAME_TYPE_REPLY_POSTPONED 7
|
||||
/* Frame Types 128 through 255: Proprietary Frames */
|
||||
/* These frames are available to vendors as proprietary (non-BACnet) frames. */
|
||||
/* The first two octets of the Data field shall specify the unique vendor */
|
||||
/* identification code, most significant octet first, for the type of */
|
||||
/* vendor-proprietary frame to be conveyed. The length of the data portion */
|
||||
/* of a Proprietary frame shall be in the range of 2 to 501 octets. */
|
||||
#define FRAME_TYPE_PROPRIETARY_MIN 128
|
||||
#define FRAME_TYPE_PROPRIETARY_MAX 255
|
||||
/* The initial CRC16 checksum value */
|
||||
#define CRC16_INITIAL_VALUE (0xFFFF)
|
||||
|
||||
|
||||
/* receive FSM states */
|
||||
typedef enum {
|
||||
MSTP_RECEIVE_STATE_IDLE = 0,
|
||||
MSTP_RECEIVE_STATE_PREAMBLE = 1,
|
||||
MSTP_RECEIVE_STATE_HEADER = 2,
|
||||
MSTP_RECEIVE_STATE_HEADER_CRC = 3,
|
||||
MSTP_RECEIVE_STATE_DATA = 4
|
||||
} MSTP_RECEIVE_STATE;
|
||||
|
||||
/* master node FSM states */
|
||||
typedef enum {
|
||||
MSTP_MASTER_STATE_INITIALIZE = 0,
|
||||
MSTP_MASTER_STATE_IDLE = 1,
|
||||
MSTP_MASTER_STATE_USE_TOKEN = 2,
|
||||
MSTP_MASTER_STATE_WAIT_FOR_REPLY = 3,
|
||||
MSTP_MASTER_STATE_DONE_WITH_TOKEN = 4,
|
||||
MSTP_MASTER_STATE_PASS_TOKEN = 5,
|
||||
MSTP_MASTER_STATE_NO_TOKEN = 6,
|
||||
MSTP_MASTER_STATE_POLL_FOR_MASTER = 7,
|
||||
MSTP_MASTER_STATE_ANSWER_DATA_REQUEST = 8
|
||||
} MSTP_MASTER_STATE;
|
||||
|
||||
struct mstp_port_struct_t {
|
||||
MSTP_RECEIVE_STATE receive_state;
|
||||
/* When a master node is powered up or reset, */
|
||||
/* it shall unconditionally enter the INITIALIZE state. */
|
||||
MSTP_MASTER_STATE master_state;
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if an error is detected during the reception of a frame. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceiveError:1;
|
||||
/* There is data in the buffer */
|
||||
unsigned DataAvailable:1;
|
||||
unsigned ReceivedInvalidFrame:1;
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if a valid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedValidFrame:1;
|
||||
/* A Boolean flag set to TRUE by the master machine if this node is the */
|
||||
/* only known master node. */
|
||||
unsigned SoleMaster:1;
|
||||
/* stores the latest received data */
|
||||
uint8_t DataRegister;
|
||||
/* Used to accumulate the CRC on the data field of a frame. */
|
||||
uint16_t DataCRC;
|
||||
/* Used to store the data length of a received frame. */
|
||||
unsigned DataLength;
|
||||
/* Used to store the destination address of a received frame. */
|
||||
uint8_t DestinationAddress;
|
||||
/* Used to count the number of received octets or errors. */
|
||||
/* This is used in the detection of link activity. */
|
||||
/* Compared to Nmin_octets */
|
||||
uint8_t EventCount;
|
||||
/* Used to store the frame type of a received frame. */
|
||||
uint8_t FrameType;
|
||||
/* The number of frames sent by this node during a single token hold. */
|
||||
/* When this counter reaches the value Nmax_info_frames, the node must */
|
||||
/* pass the token. */
|
||||
unsigned FrameCount;
|
||||
/* Used to accumulate the CRC on the header of a frame. */
|
||||
uint8_t HeaderCRC;
|
||||
/* Used as an index by the Receive State Machine, up to a maximum value of */
|
||||
/* InputBufferSize. */
|
||||
unsigned Index;
|
||||
/* An array of octets, used to store octets as they are received. */
|
||||
/* InputBuffer is indexed from 0 to InputBufferSize-1. */
|
||||
/* The maximum size of a frame is 501 octets. */
|
||||
uint8_t *InputBuffer;
|
||||
/* "Next Station," the MAC address of the node to which This Station passes */
|
||||
/* the token. If the Next_Station is unknown, Next_Station shall be equal to */
|
||||
/* This_Station. */
|
||||
uint8_t Next_Station;
|
||||
/* "Poll Station," the MAC address of the node to which This Station last */
|
||||
/* sent a Poll For Master. This is used during token maintenance. */
|
||||
uint8_t Poll_Station;
|
||||
/* A counter of transmission retries used for Token and Poll For Master */
|
||||
/* transmission. */
|
||||
unsigned RetryCount;
|
||||
/* A timer with nominal 5 millisecond resolution used to measure and */
|
||||
/* generate silence on the medium between octets. It is incremented by a */
|
||||
/* timer process and is cleared by the Receive State Machine when activity */
|
||||
/* is detected and by the SendFrame procedure as each octet is transmitted. */
|
||||
/* Since the timer resolution is limited and the timer is not necessarily */
|
||||
/* synchronized to other machine events, a timer value of N will actually */
|
||||
/* denote intervals between N-1 and N */
|
||||
uint16_t SilenceTimer;
|
||||
|
||||
/* A timer used to measure and generate Reply Postponed frames. It is */
|
||||
/* incremented by a timer process and is cleared by the Master Node State */
|
||||
/* Machine when a Data Expecting Reply Answer activity is completed. */
|
||||
/* note: we always send a reply postponed since a message other than
|
||||
the reply may be in the transmit queue */
|
||||
/* uint16_t ReplyPostponedTimer; */
|
||||
|
||||
/* Used to store the Source Address of a received frame. */
|
||||
uint8_t SourceAddress;
|
||||
|
||||
/* The number of tokens received by this node. When this counter reaches the */
|
||||
/* value Npoll, the node polls the address range between TS and NS for */
|
||||
/* additional master nodes. TokenCount is set to zero at the end of the */
|
||||
/* polling process. */
|
||||
unsigned TokenCount;
|
||||
|
||||
/* "This Station," the MAC address of this node. TS is generally read from a */
|
||||
/* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */
|
||||
/* 0 to 254. The value 255 is used to denote broadcast when used as a */
|
||||
/* destination address but is not allowed as a value for TS. */
|
||||
uint8_t This_Station;
|
||||
|
||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||
/* maximum number of information frames the node may send before it must */
|
||||
/* pass the token. Max_Info_Frames may have different values on different */
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
unsigned Nmax_info_frames;
|
||||
|
||||
/* This parameter represents the value of the Max_Master property of the */
|
||||
/* node's Device object. The value of Max_Master specifies the highest */
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
unsigned Nmax_master;
|
||||
|
||||
/* An array of octets, used to store PDU octets prior to being transmitted. */
|
||||
/* This array is only used for APDU messages */
|
||||
uint8_t TxBuffer[MAX_MPDU];
|
||||
unsigned TxLength;
|
||||
bool TxReady; /* true if ready to be sent or received */
|
||||
uint8_t TxFrameType; /* type of message - needed by MS/TP */
|
||||
};
|
||||
|
||||
#define DEFAULT_MAX_INFO_FRAMES 1
|
||||
#define DEFAULT_MAX_MASTER 127
|
||||
#define DEFAULT_MAC_ADDRESS 127
|
||||
|
||||
/* 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. */
|
||||
/* 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 38400 baud, 40 bit times would be about 1.041 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 115200 baud, 40 bit times would be about 0.347 milliseconds */
|
||||
/* 40 bits is 4 octets including a start and stop bit with each octet */
|
||||
#define Tturnaround 40
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port);
|
||||
void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t
|
||||
*mstp_port);
|
||||
bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t
|
||||
*mstp_port);
|
||||
|
||||
/* returns true if line is active */
|
||||
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port);
|
||||
|
||||
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||
unsigned buffer_len, /* amount of space available */
|
||||
uint8_t frame_type, /* type of frame to send - see defines */
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t source, /* source address */
|
||||
uint8_t * data, /* any data to be sent - may be null */
|
||||
unsigned data_len); /* number of bytes of data (up to 501) */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
BACnet Stack - SourceForge.net
|
||||
Build for MPLAB IDE
|
||||
|
||||
These are some settings that are important when building
|
||||
the BACnet Stack using MPLAB IDE and MCC18 Compiler,
|
||||
|
||||
1. Add the files to the project that you need:
|
||||
abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c,
|
||||
bacstr.c, crc.c, datetime.c, dcc.c, iam.c,
|
||||
npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c
|
||||
|
||||
From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c
|
||||
|
||||
From demo/object/: device.c or dev_tiny.c
|
||||
objects as needed: ai.c, ao.c, etc.
|
||||
|
||||
From demo/handler/: txbuf.c, h_dcc.c, h_rd.c, h_rp.c or h_rp_tiny.c
|
||||
Additional handlers as needed: h_wp.c
|
||||
|
||||
2. Project->Options->Project
|
||||
|
||||
General Tab: Include Path:
|
||||
C:\code\bacnet-stack\;C:\code\bacnet-stack\demo\handler\;C:\code\bacnet-stack\demo\object\;C:\code\bacnet-stack\ports\pic18\
|
||||
|
||||
MPLAB C18 Tab: Memory Model:
|
||||
Code: Large Code Model
|
||||
Data: Large Data Model
|
||||
Stack: Multi-bank Model
|
||||
|
||||
MPLAB C18 Tab: General: Macro Definitions:
|
||||
PRINT_ENABLED=0
|
||||
BACDL_MSTP=1
|
||||
TSM_ENABLED=0
|
||||
BIG_ENDIAN=0
|
||||
|
||||
3. The linker script must reserve some extra stack space.
|
||||
|
||||
//DATABANK NAME=gpr12 START=0xC00 END=0xCFF
|
||||
//DATABANK NAME=gpr13 START=0xD00 END=0xDFF
|
||||
DATABANK NAME=stackreg START=0xC00 END=0xDFF PROTECTED
|
||||
|
||||
//STACK SIZE=0x100 RAM=gpr13
|
||||
STACK SIZE=0x200 RAM=stackreg
|
||||
|
||||
@@ -1,365 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* The module handles sending data out the RS-485 port */
|
||||
/* and handles receiving data from the RS-485 port. */
|
||||
/* Customize this file for your specific hardware */
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "hardware.h"
|
||||
#include "mstp.h"
|
||||
#include "comm.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
/* public port info */
|
||||
extern volatile struct mstp_port_struct_t MSTP_Port;
|
||||
|
||||
/* the baud rate is adjustable */
|
||||
uint32_t RS485_Baud_Rate = 9600;
|
||||
|
||||
/* the ISR and other use this for status and control */
|
||||
COMSTAT RS485_Comstat;
|
||||
|
||||
/*#pragma udata MSTPPortData */
|
||||
/* the buffer for receiving characters */
|
||||
volatile uint8_t RS485_Rx_Buffer[MAX_MPDU];
|
||||
|
||||
/* UART transmission buffer and index */
|
||||
volatile uint8_t RS485_Tx_Buffer[MAX_MPDU];
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Transmits a frame using the UART
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
uint16_t i = 0; /* loop counter */
|
||||
uint8_t turnaround_time;
|
||||
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
/* bounds check */
|
||||
if (nbytes >= sizeof(RS485_Tx_Buffer))
|
||||
return;
|
||||
|
||||
/* buffer is full. Wait for ISR to transmit. */
|
||||
while (RS485_Comstat.Tx_Bytes) {
|
||||
};
|
||||
|
||||
/* wait 40 bit times since reception */
|
||||
if (RS485_Baud_Rate == 9600)
|
||||
turnaround_time = 4;
|
||||
else if (RS485_Baud_Rate == 19200)
|
||||
turnaround_time = 2;
|
||||
else
|
||||
turnaround_time = 1;
|
||||
|
||||
while (mstp_port->SilenceTimer < turnaround_time) {
|
||||
};
|
||||
|
||||
RS485_Comstat.TxHead = 0;
|
||||
memcpy((void *) &RS485_Tx_Buffer[0], (void *) buffer, nbytes);
|
||||
|
||||
/*for (i = 0; i < nbytes; i++) { */
|
||||
/* /* put the data into the buffer */ */
|
||||
/* RS485_Tx_Buffer[i] = *buffer; */
|
||||
/* buffer++; */
|
||||
/*} */
|
||||
RS485_Comstat.Tx_Bytes = nbytes;
|
||||
/* disable the receiver */
|
||||
PIE3bits.RC2IE = 0;
|
||||
RCSTA2bits.CREN = 0;
|
||||
/* enable the transceiver */
|
||||
RS485_TX_ENABLE = 1;
|
||||
RS485_RX_DISABLE = 1;
|
||||
/* enable the transmitter */
|
||||
TXSTA2bits.TXEN = 1;
|
||||
PIE3bits.TX2IE = 1;
|
||||
/* per MSTP spec, sort of */
|
||||
mstp_port->SilenceTimer = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Checks for data on the receive UART, and handles errors
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *
|
||||
mstp_port)
|
||||
{
|
||||
/* check for data */
|
||||
if (RS485_Comstat.Rx_Bytes) {
|
||||
mstp_port->DataRegister = RS485_Rx_Buffer[RS485_Comstat.RxTail];
|
||||
if (RS485_Comstat.RxTail >= (sizeof(RS485_Rx_Buffer) - 1))
|
||||
RS485_Comstat.RxTail = 0;
|
||||
else
|
||||
RS485_Comstat.RxTail++;
|
||||
RS485_Comstat.Rx_Bytes--;
|
||||
/* errors? let the state machine know */
|
||||
if (RS485_Comstat.Rx_Bufferoverrun) {
|
||||
RS485_Comstat.Rx_Bufferoverrun = FALSE;
|
||||
mstp_port->ReceiveError = TRUE;
|
||||
}
|
||||
/* We read a good byte */
|
||||
else
|
||||
mstp_port->DataAvailable = TRUE;
|
||||
}
|
||||
|
||||
return RS485_Comstat.Rx_Bytes;
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
DESCRIPTION: Receives RS485 data stream
|
||||
|
||||
RETURN: none
|
||||
|
||||
ALGORITHM: none
|
||||
|
||||
NOTES: none
|
||||
*************************************************************************** */
|
||||
void RS485_Interrupt_Rx(void)
|
||||
{
|
||||
char dummy;
|
||||
|
||||
if ((RCSTA2bits.FERR) || (RCSTA2bits.OERR)) {
|
||||
/* Clear the error */
|
||||
RCSTA2bits.CREN = 0;
|
||||
RCSTA2bits.CREN = 1;
|
||||
RS485_Comstat.Rx_Bufferoverrun = TRUE;
|
||||
dummy = RCREG2;
|
||||
} else if (RS485_Comstat.Rx_Bytes < sizeof(RS485_Rx_Buffer)) {
|
||||
RS485_Rx_Buffer[RS485_Comstat.RxHead] = RCREG2;
|
||||
if (RS485_Comstat.RxHead >= (sizeof(RS485_Rx_Buffer) - 1))
|
||||
RS485_Comstat.RxHead = 0;
|
||||
else
|
||||
RS485_Comstat.RxHead++;
|
||||
RS485_Comstat.Rx_Bytes++;
|
||||
} else {
|
||||
RS485_Comstat.Rx_Bufferoverrun = TRUE;
|
||||
dummy = RCREG2;
|
||||
(void) dummy;
|
||||
}
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
DESCRIPTION: Transmits a byte using the UART out the RS485 port
|
||||
|
||||
RETURN: none
|
||||
|
||||
ALGORITHM: none
|
||||
|
||||
NOTES: none
|
||||
*************************************************************************** */
|
||||
void RS485_Interrupt_Tx(void)
|
||||
{
|
||||
if (RS485_Comstat.Tx_Bytes) {
|
||||
/* Get the data byte */
|
||||
TXREG2 = RS485_Tx_Buffer[RS485_Comstat.TxHead];
|
||||
/* point to the next byte */
|
||||
RS485_Comstat.TxHead++;
|
||||
/* reduce the buffer size */
|
||||
RS485_Comstat.Tx_Bytes--;
|
||||
} else {
|
||||
/* wait for the USART to be empty */
|
||||
while (!TXSTA2bits.TRMT);
|
||||
/* disable this interrupt */
|
||||
PIE3bits.TX2IE = 0;
|
||||
/* enable the receiver */
|
||||
RS485_TX_ENABLE = 0;
|
||||
RS485_RX_DISABLE = 0;
|
||||
/* FIXME: might not be necessary */
|
||||
PIE3bits.RC2IE = 1;
|
||||
RCSTA2bits.CREN = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Returns the baud rate that we are currently running at
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
uint32_t RS485_Get_Baud_Rate(void)
|
||||
{
|
||||
return RS485_Baud_Rate;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Sets the baud rate for the chip USART
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Set_Baud_Rate(uint32_t baud)
|
||||
{
|
||||
if (baud < 19200)
|
||||
RS485_Baud_Rate = 9600;
|
||||
else if (baud < 38400)
|
||||
RS485_Baud_Rate = 19200;
|
||||
else if (baud < 57600)
|
||||
RS485_Baud_Rate = 38400;
|
||||
else if (baud < 57600)
|
||||
RS485_Baud_Rate = 57600;
|
||||
else if (baud < 115200)
|
||||
RS485_Baud_Rate = 76800;
|
||||
else
|
||||
RS485_Baud_Rate = 115200;
|
||||
|
||||
I2C_Write_Block(EEPROM_DEVICE_ADDRESS,
|
||||
(char *) &RS485_Baud_Rate,
|
||||
sizeof(RS485_Baud_Rate), EEPROM_MSTP_BAUD_RATE_ADDR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
|
||||
* receive mode.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Initialize_Port(void)
|
||||
{
|
||||
|
||||
/* Reset USART registers to POR state */
|
||||
TXSTA2 = 0;
|
||||
RCSTA2 = 0;
|
||||
/* configure USART for receiving */
|
||||
/* since the TX will handle setting up for transmit */
|
||||
RCSTA2bits.CREN = 1;
|
||||
/* Interrupt on receipt */
|
||||
PIE3bits.RC2IE = 1;
|
||||
/* enable the transmitter, disable its interrupt */
|
||||
TXSTA2bits.TXEN = 1;
|
||||
PIE3bits.TX2IE = 0;
|
||||
/* setup USART Baud Rate Generator */
|
||||
/* see BAUD RATES FOR ASYNCHRONOUS MODE in Data Book */
|
||||
/* Fosc=20MHz
|
||||
BRGH=1 BRGH=0
|
||||
Rate SPBRG Rate SPBRG
|
||||
------- ----- ------- -----
|
||||
9615 129 9469 32
|
||||
19230 64 19530 15
|
||||
37878 32 78130 3
|
||||
56818 21 104200 2
|
||||
113630 10 312500 0
|
||||
250000 4
|
||||
625000 1
|
||||
1250000 0
|
||||
*/
|
||||
switch (RS485_Baud_Rate) {
|
||||
case 19200:
|
||||
SPBRG2 = 64;
|
||||
TXSTA2bits.BRGH = 1;
|
||||
break;
|
||||
case 38400:
|
||||
SPBRG2 = 32;
|
||||
TXSTA2bits.BRGH = 1;
|
||||
break;
|
||||
case 57600:
|
||||
SPBRG2 = 21;
|
||||
TXSTA2bits.BRGH = 1;
|
||||
break;
|
||||
case 76800:
|
||||
SPBRG2 = 3;
|
||||
TXSTA2bits.BRGH = 0;
|
||||
break;
|
||||
case 115200:
|
||||
SPBRG2 = 10;
|
||||
TXSTA2bits.BRGH = 1;
|
||||
break;
|
||||
case 9600:
|
||||
SPBRG2 = 129;
|
||||
TXSTA2bits.BRGH = 1;
|
||||
break;
|
||||
default:
|
||||
SPBRG2 = 129;
|
||||
TXSTA2bits.BRGH = 1;
|
||||
RS485_Set_Baud_Rate(9600);
|
||||
break;
|
||||
}
|
||||
/* select async mode */
|
||||
TXSTA2bits.SYNC = 0;
|
||||
/* enable transmitter */
|
||||
TXSTA2bits.TXEN = 1;
|
||||
/* serial port enable */
|
||||
RCSTA2bits.SPEN = 1;
|
||||
/* since we are using RS485,
|
||||
we need to explicitly say
|
||||
transmit enable or not */
|
||||
RS485_RX_DISABLE = 0;
|
||||
RS485_TX_ENABLE = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Disables the RS485 hardware
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Disable_Port(void)
|
||||
{
|
||||
RCSTA2 &= 0x4F; /* Disable the receiver */
|
||||
TXSTA2bits.TXEN = 0; /* and transmitter */
|
||||
PIE3 &= 0xCF; /* Disable both interrupts */
|
||||
}
|
||||
|
||||
void RS485_Reinit(void)
|
||||
{
|
||||
RS485_Set_Baud_Rate(9600);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Initializes the data and the port
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Initialize(void)
|
||||
{
|
||||
/* Init the Rs485 buffers */
|
||||
RS485_Comstat.RxHead = 0;
|
||||
RS485_Comstat.RxTail = 0;
|
||||
RS485_Comstat.Rx_Bytes = 0;
|
||||
RS485_Comstat.Rx_Bufferoverrun = FALSE;
|
||||
RS485_Comstat.TxHead = 0;
|
||||
RS485_Comstat.TxTail = 0;
|
||||
RS485_Comstat.Tx_Bytes = 0;
|
||||
|
||||
I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
||||
(char *) &RS485_Baud_Rate,
|
||||
sizeof(RS485_Baud_Rate), EEPROM_MSTP_BAUD_RATE_ADDR);
|
||||
|
||||
RS485_Initialize_Port();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2004 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307
|
||||
USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
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
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
|
||||
#ifndef RS485_H
|
||||
#define RS485_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mstp.h"
|
||||
#include "comm.h"
|
||||
|
||||
extern COMSTAT RS485_Comstat;
|
||||
extern volatile uint8_t RS485_Rx_Buffer[MAX_MPDU];
|
||||
extern volatile uint8_t RS485_Tx_Buffer[MAX_MPDU];
|
||||
extern uint32_t RS485_Baud_Rate;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void RS485_Reinit(void);
|
||||
void RS485_Initialize(void);
|
||||
|
||||
void RS485_Disable(void);
|
||||
|
||||
void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
||||
|
||||
uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port); /* port specific data */
|
||||
|
||||
void RS485_Interrupt_Rx(void);
|
||||
|
||||
void RS485_Interrupt_Tx(void);
|
||||
|
||||
uint32_t RS485_Get_Baud_Rate(void);
|
||||
void RS485_Set_Baud_Rate(uint32_t baud);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef STDBOOL_H
|
||||
#define STDBOOL_H
|
||||
|
||||
/* C99 Boolean types for compilers without C99 support */
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef char _Bool;
|
||||
#ifndef bool
|
||||
#define bool _Bool
|
||||
#endif
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
#define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Defines the standard integer types that are used in code */
|
||||
|
||||
#ifndef STDINT_H
|
||||
#define STDINT_H 1
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
|
||||
typedef signed char int8_t; /* 1 byte -127 to 127 */
|
||||
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
|
||||
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
|
||||
/*typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 */
|
||||
typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */
|
||||
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
|
||||
/* typedef signed long long int64_t; */
|
||||
/* typedef unsigned long long uint64_t; */
|
||||
|
||||
#endif /* STDINT_H */
|
||||
@@ -1,45 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
volatile uint8_t Milliseconds; /* used for timing stuff - counts up to 0xFF. */
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Timer is set to go off every 1ms. We increment the counter,
|
||||
* and the main task will decrement the counter.
|
||||
* PARAMETERS: none
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void Timer_Millisecond_Interrupt(void)
|
||||
{
|
||||
/* Global Milisecond timer */
|
||||
if (Milliseconds < 0xFF)
|
||||
Milliseconds++;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
/* used for timing stuff - counts up to 0xFF. */
|
||||
extern volatile uint8_t Milliseconds;
|
||||
|
||||
void Timer_Millisecond_Interrupt(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user