CCS PCH C Compiler, Version 4.095, 48896 09-Sep-10 18:37 Filename: main.lst ROM used: 17352 bytes (35%) Largest free fragment is 31796 RAM used: 300 (9%) at main() level 345 (10%) worst case Stack: 10 worst case (8 in main + 2 for interrupts) * 0000: GOTO 42F0 * 0008: MOVWF 05 000A: MOVFF FD8,06 000E: MOVFF FE0,07 0012: MOVLB 0 0014: MOVFF FE9,0D 0018: MOVFF FEA,08 001C: MOVFF FE1,09 0020: MOVFF FE2,0A 0024: MOVFF FD9,0B 0028: MOVFF FDA,0C 002C: MOVFF FF3,14 0030: MOVFF FF4,15 0034: MOVFF FFA,16 0038: MOVFF 00,0F 003C: MOVFF 01,10 0040: MOVFF 02,11 0044: MOVFF 03,12 0048: MOVFF 04,13 004C: BTFSS F9D.5 004E: GOTO 0058 0052: BTFSC F9E.5 0054: GOTO 0440 0058: MOVFF 0F,00 005C: MOVFF 10,01 0060: MOVFF 11,02 0064: MOVFF 12,03 0068: MOVFF 13,04 006C: MOVFF 0D,FE9 0070: MOVFF 08,FEA 0074: BSF 08.7 0076: MOVFF 09,FE1 007A: MOVFF 0A,FE2 007E: MOVFF 0B,FD9 0082: MOVFF 0C,FDA 0086: MOVFF 14,FF3 008A: MOVFF 15,FF4 008E: MOVFF 16,FFA 0092: MOVF 05,W 0094: MOVFF 07,FE0 0098: MOVFF 06,FD8 009C: RETFIE 0 .................... #include<18F4585.h> .................... //////// Standard Header file for the PIC18F4585 device //////////////// .................... #device PIC18F4585 .................... #list .................... .................... .................... #device ADC=10 .................... #use delay(clock=20000000) * 04E6: MOVLW 01 04E8: MOVWF FEA 04EA: MOVLW 2E 04EC: MOVWF FE9 04EE: MOVF FEF,W 04F0: BZ 050C 04F2: MOVLW 06 04F4: MOVWF 01 04F6: CLRF 00 04F8: DECFSZ 00,F 04FA: BRA 04F8 04FC: DECFSZ 01,F 04FE: BRA 04F6 0500: MOVLW 7B 0502: MOVWF 00 0504: DECFSZ 00,F 0506: BRA 0504 0508: DECFSZ FEF,F 050A: BRA 04F2 050C: RETLW 00 .................... #use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7, parity=N, bits=8, stop=2) * 1D5E: BTFSS F9E.4 1D60: BRA 1D5E 1D62: MOVLB 1 1D64: MOVF x2C,W 1D66: MOVWF FAD 1D68: BTFSS FAC.1 1D6A: BRA 1D68 1D6C: MOVLW AD 1D6E: MOVWF 00 1D70: DECFSZ 00,F 1D72: BRA 1D70 1D74: MOVLB 0 1D76: RETLW 00 .................... #use spi(MASTER, DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3, LOAD=PIN_B0, BITS=8, MODE=0) * 0C34: MOVLB 1 0C36: MOVF x32,W 0C38: SUBLW 08 0C3A: BZ 0C44 0C3C: MOVWF x33 0C3E: RLCF x31,F 0C40: DECFSZ x33,F 0C42: BRA 0C3E 0C44: BSF F94.4 0C46: BCF F94.5 0C48: BCF F94.3 0C4A: BCF F8B.3 0C4C: BCF F93.0 0C4E: BCF F8A.0 0C50: MOVFF 132,133 0C54: BTFSS x31.7 0C56: BCF F8B.5 0C58: BTFSC x31.7 0C5A: BSF F8B.5 0C5C: RLCF x31,F 0C5E: BSF F8B.3 0C60: RLCF 01,F 0C62: BTFSS F82.4 0C64: BCF 01.0 0C66: BTFSC F82.4 0C68: BSF 01.0 0C6A: BCF F8B.3 0C6C: DECFSZ x33,F 0C6E: BRA 0C54 0C70: BSF F8A.0 0C72: BCF F8A.0 0C74: MOVLB 0 0C76: GOTO 0DDA (RETURN) .................... //#fuses HS,NOPUT,NOBROWNOUT,NOWRT,NOWDT,NOLVP .................... #fuses HS,NOPUT,BROWNOUT,NOWRT,NOWDT,NOLVP // from original omurs file--edit by jam .................... // HighSpeedcrystal, NO PowerUpTimer, NOBROWNOUTdetector, .................... // enableeepromWRiTe, NOWatchDogTimer, NOLowVoltageProgramming .................... #include "RB.c" .................... /********************* .................... * RB.c .................... * Robotics Bus .................... **********************/ .................... .................... /* ----- revision history: .................... .................... 2006-08-05, Jimmy Sastra: Today I started this revision history. .................... - Included actualPos (servo position) in every heartbeat. .................... - Blink LED at every heartbeat on PIN_B0 .................... - Turn LED on/off every 30 TxPM and RxPM on Pin B1 and B4 respectively .................... .................... */ .................... .................... #include "RB.h" // defines and prototypes needed by RBapp.c and RB.c .................... // RB.h .................... .................... // Constants and Global Variables used by Universal Robotics Bus. .................... .................... /* ----- revision history: .................... .................... 2004-04-03, DGI: Today I started this revision history. .................... The things that need work are: the ERROR constants. These are not very .................... well thought out. Also, perhaps some more guidance for user on how to set up .................... the object dictionary. The master version of this file should be .................... downloaded from: www.grasp.upenn.edu/destudio/CAN/code .................... .................... 2004-09-10, EAS: Added object_dictionary_entry type, added an object type .................... and changed the numbering of the data types to bring them more in line with .................... the CANopen specification. .................... .................... 2005-01-10 DGI: changed the od_entry type to explicitly include a permissions .................... byte. Eliminated the "object" type because the word "object" is too vague. .................... Added "MEDIA" const and uint8 RB_NODEID variable, and changed many of the .................... names from URB_* to RB_*. Robotics Bus web site is now: .................... www.grasp.upenn.edu/destudio/RB .................... .................... */ .................... .................... /************************************************************************** .................... ROBOTICS BUS TYPE DEFINITIONS .................... ***************************************************************************/ .................... .................... typedef int8 bool; .................... typedef signed int8 sint8; .................... typedef signed int16 sint16; .................... typedef signed int32 sint32; .................... typedef unsigned int8 uint8; .................... typedef unsigned int16 uint16; .................... typedef unsigned int32 uint32; .................... .................... /************************************************************************** .................... CONSTANTS .................... ***************************************************************************/ .................... .................... // this is what they do in the microcanopen2.00 .................... #define URB_HEARTBEAT_NORMAL 0x05 .................... #define URB_HEARTBEAT_STOPPED 0x04 .................... .................... // heartbeat interval of 1 Hz .................... // this const changes with clock/crystal .................... #define URB_HEARTBEAT_INTERVAL 0x4C47 .................... .................... #define URB_ERROR_OK 0x00 .................... #define URB_ERROR_RX_INVALID_MSG 0x10 .................... #define URB_ERROR_RX_XTD_FRAME 0x20 .................... #define URB_ERROR_RX_RTR_FRAME 0x40 .................... .................... #define URB_RX_IN_PROCESS 0x34 .................... .................... #define URB_ERROR_SDO_REPLY_SENT 0x22 .................... #define URB_ERROR_SDO_IN_PROCESS 0x33 .................... #define URB_ERROR_SDO_MALFORMED 0xA9 .................... #define URB_ERROR_SDO_UNKNOWN_TYPE 0xAA .................... #define URB_ERROR_SDO_NOT_FOUND 0xAB .................... #define URB_ERROR_SDO_TYPE_MISMATCH 0xAC .................... #define URB_ERROR_WAITING_FOR_TXBUF 0xAD .................... #define URB_ERROR_SDO_UNKNOWN_COMMAND 0xAE .................... #define URB_ERROR_SDO_PERMISSIONS 0xAF .................... .................... #define URB_ERROR_NMT_UNKNOWN_COMMAND 0xCC .................... #define URB_ERROR_NMT_NOT_ADDRESSED 0xCD .................... #define URB_ERROR_NMT_INVALID_LENGTH 0xCE .................... .................... #define URB_ERROR_PM_NO_MAP 0xD0 .................... #define URB_ERROR_MAPPING_IN_PROCESS 0xD1 .................... #define URB_ERROR_READ_IN_PROCESS 0xD2 .................... .................... // CAN identifiers .................... #define RB_MSG_DICT_READ 0x40 .................... #define RB_MSG_DICT_WRITE 0x20 .................... .................... /************************************************************************** .................... TYPE SPECIFIERS .................... ***************************************************************************/ .................... .................... // The MEDIA bit specifies whether the variable .................... // is stored in RAM or EEPROM .................... #define RB_MEDIA_BIT 0b10000000 .................... #define RB_MEDIA_NONV 0b10000000 .................... #define RB_MEDIA_RAM 0b00000000 .................... #define RB_MEDIA_ROM 0b00000000 // this one isn't used .................... .................... // access definitions -- permissions .................... // occupy the first byte of subindex zero. .................... #define RB_PERM_BITS 0b00000011 .................... #define RB_PERM_READ_BIT 0b00000001 .................... #define RB_PERM_READONLY 0b00000001 .................... #define RB_PERM_READWRITE 0b00000011 .................... #define RB_PERM_WRITE_BIT 0b00000010 .................... #define RB_PERM_WRITEONLY 0b00000010 .................... .................... // data type definitions .................... #define RB_TYPE_BOOLEAN 0x41 .................... #define RB_TYPE_SINT8 0x42 .................... #define RB_TYPE_SINT16 0x43 .................... #define RB_TYPE_SINT32 0x44 .................... #define RB_TYPE_UINT8 0x45 .................... #define RB_TYPE_UINT16 0x46 .................... #define RB_TYPE_UINT32 0x47 .................... #define RB_TYPE_FLOAT 0x48 .................... #define RB_TYPE_PM_CONFIG 0x60 .................... #define RB_TYPE_PM_MAPPING 0x61 .................... #define RB_TYPE_IDENTITY 0x63 .................... .................... // end-of-dictionary marker is a zero-index object .................... #define RB_END_OF_DICTIONARY {0x0000,0,0,0,0} .................... .................... #define RB_NULL 0 .................... #define RB_UNUSED_MAP {{0,0,0}} .................... .................... /************************************************************************** .................... DATA STRUCTURES .................... ***************************************************************************/ .................... .................... typedef struct .................... { .................... int16 ID; .................... byte len; .................... byte buf[8]; .................... } CAN_MSG; .................... .................... // the main dictionary .................... typedef struct .................... { .................... uint16 index; .................... uint8 permissions; .................... uint8 data_type; .................... char* address; .................... char name[33]; .................... byte padding; .................... } od_entry; .................... .................... // used in a process message mapping - RAM only .................... typedef struct .................... { .................... int16 index; .................... uint8 data_type; .................... char* address; .................... } pm_map; .................... .................... /************************************************************************** .................... GLOBAL RAM VARIABLES .................... ***************************************************************************/ .................... .................... CAN_MSG IRt; .................... CAN_MSG IRr; .................... CAN_MSG RBtPM[4]; // caches the TPDOs before they are sent. .................... bool RBtPMready[4]; // flag to indicate ready to transmit. .................... CAN_MSG RBrPM[4]; // caches the RPDOs when they are received. is this necessary? .................... CAN_MSG URBhb; // heartbeat message buffer .................... CAN_MSG URBStackRcv; // buffer used for incoming messages. .................... CAN_MSG URBTxSDO; // buffer used for responding to an SDO request .................... byte URBErrorCode; // returns the exit code when something unexpected happens. .................... byte URBRecvOverflowCounter; .................... byte URBRecvCounter; .................... uint8 RB_NODEID=0; .................... uint8 RB_IRID=0; .................... .................... /************************************************************************** .................... EEPROM MAP .................... ***************************************************************************/ .................... .................... // addresses below 0x7F may be used by application .................... // addresses above 0x80 are allocated here. .................... .................... #define RB_EEPROM_NODEID 0x80 // single byte stores the Node ID (can be 1-127) .................... #define RB_EEPROM_IRID 0x81 // single byte stores the Node ID (can be 1-127) .................... .................... /************************************************************************** .................... FUNCTION PROTOTYPES .................... ***************************************************************************/ .................... .................... // prototypes are necessary to make things compile .................... void RB_PM_SetDefaults(void); .................... void RB_Handle_Mapping_Request(int16 index, int8 subindex); .................... bool OD_lookup(int16 index, int8& num); .................... void RB_Set_tPM_Identifiers(void); .................... .................... // these two functions are "callback functions" which must be implemented by the application in "main.c" .................... .................... void RB_App_ResetApp(void); .................... void RB_App_SetFactoryDefaults(void); .................... .................... .................... #define CAN_MASK_ELEVEN_BITS 0x07FF .................... #define CAN_MASK_RB_MESG 0x0700 .................... .................... #define RB_NMT 0x0000 .................... #define RB_COMMAND 0x0100 .................... #define RB_SENSOR 0x0200 .................... #define RB_USART 0x0300 .................... #define RB_NEIGHBOR 0x0400 .................... #define RB_DICT_RESP 0x0500 .................... #define RB_DICT_REQ 0x0600 .................... #define RB_HEARTBEAT 0x0700 .................... .................... #define RB_ALL 0x0700 .................... #define RB_NODE_RESET 129 .................... #define NUM_MASK 2 .................... #define NUM_FILTER 6 .................... .................... uint16 RB_RXCONFIG_0; .................... uint16 RB_RXCONFIG_1; .................... uint16 RB_RXCONFIG_2; .................... uint16 RB_RXCONFIG_3; .................... uint16 RB_TXCONFIG_0; .................... uint16 RB_TXCONFIG_1; .................... uint16 RB_TXCONFIG_2; .................... uint16 RB_TXCONFIG_3; .................... .................... void RB_reset_from_eeprom(void); .................... void RB_setup_CAN(void); .................... .................... #include "RBapp.h" // defines the application-specific Bus Objects. .................... // RBapp.h : Application-specific code for an application built .................... // on the Robotics Bus. .................... // .................... // To customize this template for your application, .................... // make a list of all the network-accessible variables used by the application, .................... // and place them in three places below. .................... // .................... // 1: Allocate space in EEPROM for any nonvolatile parameters. .................... // .................... // 2: Declare global variables in the RAM map, using RB_TYPEs UINT8, FLOAT, etc. .................... // .................... // 3: Populate the Object Dictionary with the index, permissions, .................... // and type of each variable. (perms are or'd with a media specifier). .................... // .................... // 4: In the dictionary, enter a pointer to each variable. .................... // This will be a simple constant for EEPROM, or a &myVar pointer to RAM. .................... // .................... // 5: Enter a text string to identify each object. Text labels can be 32 .................... // characters long and should be entered inside quotes inside the .................... // dictionary table. The text string will be used by configuration utility .................... // program to create a friendly user interface for configuration. .................... // .................... // 6: Assign descriptive strings to any Process Messages you use. .................... // .................... // 7: In the Process Message Mapping table, include a default identifier, .................... // and the number of mappings, followed by a list of all mapped objects. .................... .................... /* ----- revision history: .................... 2006-08-05, Jimmy Sastra: Today I started this revision history. .................... Took out process messages for actualPos. The bluetooth module could not keep up. .................... .................... 2006-08-07, Mike Park: Reinstated process messages for actualPos. Frequency is set to a .................... low default and a variable in EEPROM allows user to modify frequency. .................... .................... 2007-02-13, Mike Park: 1 Hz neighbor information (piggybacked off of the heartbeat function) .................... toggled with object dictionary variable. .................... */ .................... .................... /************************************************************************* .................... // DEFAULT NODE ID .................... ***************************************************************************/ .................... .................... // *** DONT REMOVE, OK TO CHANGE *** .................... // NID to use when ROM is wiped clean. .................... // This can be changed and replaced in nonvolatile memory during operation. .................... .................... #define RB_NODEID_DEFAULT 0x22 .................... #define RB_IRID_DEFAULT 0x00 .................... .................... // WARNING: If this is 0 or > 253 RB_factory initialize will be .................... //called repetetively and no changes in eeprom will be saved .................... // this condition is because of the condition as set in RB_reset_from_eeprom() .................... .................... /************************************************************************** .................... // EEPROM MAP .................... ***************************************************************************/ .................... .................... // Assign addresses 0x00-0x7F (0-127) for variables stored in EEPROM, .................... // and be sure they are consistent with the Object Dictionary below. .................... // NOTE!! Addresses above 0x7F are used internally by the Robotics Bus (see RB.h). .................... .................... #define SERVO_CAL_CMD_CENTER 2 .................... #define SERVO_CAL_CMD_AMPLITUDE 4 .................... //#define SERVO_KP 8 .................... //#define SERVO_KD 10 .................... #define SERVO_SPEED 12 .................... #define SERVO_START_POS 14 .................... #define FEEDBACK 8 .................... .................... .................... /************************************************************************** .................... // RAM MAP .................... ***************************************************************************/ .................... .................... // Global RAM variables used by application. .................... uint16 feed_freq; .................... sint16 actualPos; .................... sint16 servoPosCommand=0; .................... uint8 servoSpeed; .................... bool calMode; .................... uint16 feed_mult=1; .................... uint16 feed_int=0; .................... uint16 raw_adc =0; .................... uint8 currentSense=0; .................... uint8 temp_nodeid = 0x00; .................... .................... /*************************************** .................... PROCESS MESSAGE MAPPINGS .................... .................... if used, they must be named: .................... RB_RXMAPPING_0 - RB_RXMAPPING_3 .................... RB_TXMAPPING_0 - RB_TXMAPPING_3 .................... .................... ****************************************/ .................... .................... CONST UINT8 RB_RXMAPPING_0_LENGTH = 1; .................... CONST UINT16 RB_RXMAPPING_0_DEFAULT = RB_COMMAND + RB_NODEID_DEFAULT; .................... CONST pm_map RB_RXMAPPING_0[] = .................... { .................... {0x1050, RB_TYPE_SINT16, &servoPosCommand}, .................... {0x1052, RB_TYPE_UINT8, &servoSpeed}, .................... }; .................... .................... CONST UINT8 RB_RXMAPPING_1_LENGTH = 0; .................... CONST UINT16 RB_RXMAPPING_1_DEFAULT = RB_NULL; .................... CONST pm_map RB_RXMAPPING_1[] = RB_UNUSED_MAP; .................... .................... CONST UINT8 RB_RXMAPPING_2_LENGTH = 0; .................... CONST UINT16 RB_RXMAPPING_2_DEFAULT = RB_NULL; .................... CONST pm_map RB_RXMAPPING_2[] = RB_UNUSED_MAP; .................... .................... CONST UINT8 RB_RXMAPPING_3_LENGTH = 0; .................... CONST UINT16 RB_RXMAPPING_3_DEFAULT = RB_NULL; .................... CONST pm_map RB_RXMAPPING_3[] = RB_UNUSED_MAP; .................... .................... CONST UINT8 RB_TXMAPPING_0_LENGTH = 1; .................... CONST UINT16 RB_TXMAPPING_0_DEFAULT = RB_SENSOR + RB_NODEID_DEFAULT; .................... CONST pm_map RB_TXMAPPING_0[] = .................... { .................... {0x1051, RB_TYPE_SINT16, &actualPos} .................... }; .................... .................... CONST UINT8 RB_TXMAPPING_1_LENGTH = 0; .................... CONST UINT16 RB_TXMAPPING_1_DEFAULT = RB_NULL; .................... CONST pm_map RB_TXMAPPING_1[] = RB_UNUSED_MAP; .................... .................... CONST UINT8 RB_TXMAPPING_2_LENGTH = 0; .................... CONST UINT16 RB_TXMAPPING_2_DEFAULT = RB_NULL; .................... CONST pm_map RB_TXMAPPING_2[] = RB_UNUSED_MAP; .................... .................... CONST UINT8 RB_TXMAPPING_3_LENGTH = 0; .................... CONST UINT16 RB_TXMAPPING_3_DEFAULT = RB_NULL; .................... CONST pm_map RB_TXMAPPING_3[] = RB_UNUSED_MAP; .................... .................... /*************************************** .................... OBJECT DICTIONARY .................... ****************************************/ .................... .................... CONST od_entry objectDictionary[] = .................... { // "|<------ 32 char string ------>|" .................... { 0x1000, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_IDENTITY, RB_EEPROM_NODEID, "V1.5"}, // name of device goes here .................... { 0x1001, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_UINT16, FEEDBACK, "Feedback in Hz"}, .................... { 0x1002, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_UINT8, RB_EEPROM_IRID, "Default Node ID for IR"}, // name of device goes here .................... { 0x1003, RB_MEDIA_RAM | RB_PERM_READWRITE, RB_TYPE_UINT8, &temp_nodeid, "Temp Node ID for IR"}, .................... { 0x1050, RB_MEDIA_RAM | RB_PERM_READWRITE, RB_TYPE_SINT16, &servoPosCommand, "poscomm"}, .................... { 0x1051, RB_MEDIA_RAM | RB_PERM_READONLY, RB_TYPE_SINT16, &actualPos, "Actual Pos"}, .................... { 0x1052, RB_MEDIA_RAM | RB_PERM_READWRITE, RB_TYPE_UINT8, &ServoSpeed, "Current speed"}, .................... .................... { 0x1014, RB_MEDIA_RAM | RB_PERM_READONLY, RB_TYPE_UINT16, &raw_adc, "rawADC"}, .................... { 0x1015, RB_MEDIA_RAM | RB_PERM_READONLY, RB_TYPE_UINT8, ¤tSense, "current Sense"}, .................... { 0x1020, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_SINT16, SERVO_CAL_CMD_CENTER, "calccent"}, .................... { 0x1021, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_UINT16, SERVO_CAL_CMD_AMPLITUDE,"calcamp"}, .................... .................... //{ 0x1024, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_UINT16, SERVO_KP,"KP for position control"}, .................... //{ 0x1025, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_UINT16, SERVO_KD,"KD for position control"}, .................... { 0x1026, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_UINT16, SERVO_SPEED,"Initial Speed at startup"}, .................... { 0x1027, RB_MEDIA_NONV | RB_PERM_READWRITE, RB_TYPE_SINT16, SERVO_START_POS,"Initial Position"}, .................... .................... { 0x1060, RB_MEDIA_RAM | RB_PERM_READWRITE, RB_TYPE_BOOLEAN, &calMode, "calMode"}, .................... .................... { 0x1800, RB_MEDIA_ROM | RB_PERM_READONLY, RB_TYPE_PM_CONFIG, &RB_TXCONFIG_0, "posfeed"} // Tx PM Config .................... { 0x1A00, RB_MEDIA_ROM | RB_PERM_READONLY, RB_TYPE_PM_MAPPING, RB_NULL, RB_NULL}, // Tx Mapping .................... .................... { 0x1400, RB_MEDIA_ROM | RB_PERM_READONLY, RB_TYPE_PM_CONFIG, &RB_RXCONFIG_0, "poscomm PMID"}, // Rx PM Config .................... { 0x1600, RB_MEDIA_ROM | RB_PERM_READONLY, RB_TYPE_PM_MAPPING, RB_NULL, RB_NULL}, // Rx Mapping .................... RB_END_OF_DICTIONARY // end of dictionary marker .................... }; .................... .................... //eof .................... .................... #include "canfunctions.c" // Our entrypoint to CAN hardware- CANInit, CANSend, etc. .................... /*************************************************************** .................... * CANFunctions * .................... **************************************************************** .................... * Created: 10/11/2002 (dd/mm/yyyy) * .................... **************************************************************** .................... * Created by: Jose Sanchez and Ben Fine * .................... * email: joseos@okstate.edu * .................... * Telephone: 405 744 4669 * .................... * This program is property of Jose Sanchez and Ben Fine * .................... * The code contained in this file could be distribuited and * .................... * used freely with the proper acreditation. * .................... .................... dgi 2003 12 03: .................... .................... I get a "Constant out of the valid range" error .................... on the ptr=TXB0D0; assignment. Appears that CCS does not accept .................... pointers to memory over FFh. Fix is to eliminate use of ptr, like .................... this: *(TXB0D0+i) = Data[i]; .................... .................... Also changed the ranges of the baud rate registers to BRP--, .................... to match the comments. .................... .................... Added RXERRCNT and IsTxReady, IsRxReady to canfunctions.h. .................... .................... Fixed overflow enable: .................... if (config & CAN_CONFIG_DBL_BUFFER_BIT) .................... RXB0CON_RXB0DBEN = 1; .................... .................... dgi 2004 01 01: .................... .................... Removed fn "RegsToCANID" because it was dropping .................... the top three bits for some reason. .................... .................... Changed CANSetMask param "val" to type "int32" to match calls. .................... .................... Changed id type to int16 in Send and Recieve fns. .................... (No Extended IDs possible.) .................... .................... dgi 2004 04 26: .................... .................... Added code in CANInitialize to set the ENDRHI bit, to avoid floating output. .................... Deleted CAN ISRs- all CAN functions handled without interrupts. .................... .................... dgi 2004 06 14 .................... .................... added code to initialize PIN_B2 to output and B3 to input - needed to make CAN work. .................... .................... .................... ****************************************************************/ .................... .................... #include "canfunctions.h" .................... /*************************************************************** .................... * CANFunctions * .................... **************************************************************** .................... * Created: 10/11/2002 (dd/mm/yyyy) * .................... **************************************************************** .................... * Created by: Jose Sanchez and Ben Fine * .................... * email: joseos@okstate.edu * .................... * Telephone: 405 744 4669 * .................... * This program is property of Jose Sanchez and Ben Fine * .................... * The code contained in this file could be distribuited and * .................... * used freely with the proper acreditation. * .................... ****************************************************************/ .................... .................... #ifndef CANFUNCTIONS_H .................... #define CANFUNCTIONS_H .................... .................... #RESERVE 0x051:0x05D // don't use this RAM. See Microchip errata 80161 rev F. --dgi 28jan2005 .................... .................... /*Defines needed by my project*/ .................... .................... #BYTE CANCON=0xF6F .................... #BYTE CANSTAT=0xF6E .................... #BYTE COMSTAT=0xF74 .................... .................... /*Transmit registers*/ .................... .................... #BYTE TXB0CON= 0xF40 .................... #BIT TXB0CON_TXREQ=0xF40.3 .................... .................... #BYTE TXB1CON= 0xF30 .................... #BIT TXB1CON_TXREQ=0xF30.3 .................... .................... #BYTE TXB2CON= 0xF20 .................... #BIT TXB2CON_TXREQ=0xF20.3 .................... .................... #BYTE TXB0SIDH= 0xF41 .................... #BYTE TXB1SIDH= 0xF31 .................... #BYTE TXB2SIDH= 0xF21 .................... .................... #BYTE TXB0SIDL= 0xF42 .................... #BYTE TXB1SIDL= 0xF32 .................... #BYTE TXB2SIDL= 0xF22 .................... .................... #BYTE TXB0EIDH= 0xF43 .................... #BYTE TXB1EIDH= 0xF33 .................... #BYTE TXB2EIDH= 0xF23 .................... .................... #BYTE TXB0EIDL= 0xF44 .................... #BYTE TXB1EIDL= 0xF34 .................... #BYTE TXB2EIDL= 0xF24 .................... .................... #define TXB0D0 0xF46 .................... #define TXB0D1 0xF47 .................... #define TXB0D2 0xF48 .................... #define TXB0D3 0xF49 .................... #define TXB0D4 0xF4A .................... #define TXB0D5 0xF4B .................... #define TXB0D6 0xF4C .................... #define TXB0D7 0xF4D .................... .................... #define TXB1D0 0xF36 .................... #define TXB1D1 0xF37 .................... #define TXB1D2 0xF38 .................... #define TXB1D3 0xF39 .................... #define TXB1D4 0xF3A .................... #define TXB1D5 0xF3B .................... #define TXB1D6 0xF3C .................... #define TXB1D7 0xF3D .................... .................... #define TXB2D0 0xF26 .................... #define TXB2D1 0xF27 .................... #define TXB2D2 0xF28 .................... #define TXB2D3 0xF29 .................... #define TXB2D4 0xF2A .................... #define TXB2D5 0xF2B .................... #define TXB2D6 0xF2C .................... #define TXB2D7 0xF2D .................... .................... #BYTE TXB0DLC= 0xF45 .................... #BYTE TXB1DLC= 0xF35 .................... #BYTE TXB2DLC= 0xF25 .................... .................... #BYTE TXERRCNT= 0xF76 .................... .................... /*CAN BAUD RATE REGISTERS*/ .................... .................... #BYTE BRGCON1= 0xF70 .................... #BYTE BRGCON2= 0xF71 .................... /*Special bit from this register*/ .................... #BIT BRGCON2_SAM=0xF71.6 .................... #BIT BRGCON2_SEG2PHTS=0xF71.7 .................... .................... #BYTE BRGCON3= 0xF72 .................... /*Special bit from this register*/ .................... #BIT BRGCON3_WAKFIL=0xF72.6 .................... .................... #BYTE CIOCON = 0xF73 .................... #BIT ENDRHI = 0xF73.5 .................... .................... #BYTE PIR3= 0xFA4 .................... #BIT PIR3_RXB0IF= 0xFA4.0 .................... #BIT PIR3_RXB1IF= 0xFA4.1 .................... #BIT PIR3_TXB0IF= 0xFA4.2 .................... #BIT PIR3_TXB1IF= 0xFA4.3 .................... #BIT PIR3_TXB2IF= 0xFA4.4 .................... #BIT PIR3_IRXIF=0xFA4.7 .................... .................... #BYTE PIE3= 0xFA3 .................... #BIT TXB0IE = 0xFA3.2 .................... .................... #BYTE IPR3= 0xFA5 .................... .................... /*Receive Registers*/ .................... .................... #BYTE RXERRCNT= 0xF75 .................... .................... #define RXB0CON 0xF60 .................... #BIT RXB0CON_RXFUL= 0xF60.7 .................... #BIT RXB0CON_RXB0DBEN= 0xF60.2 .................... .................... #BIT RXB1IE= 0xFA3.1 .................... #define RXB1CON 0xF50 .................... #BIT RXB1CON_RXFUL= 0xF50.7 .................... .................... #BIT COMSTAT_RXB0OVFL= 0xF74.7 .................... #BIT COMSTAT_RXB1OVFL= 0xF74.6 .................... .................... #define RXB0DLC 0xF65 .................... #BIT RXB0DLC_RXRTR= 0xF65.6 .................... .................... #define RXM0SIDH 0xF18 .................... #define RXM0SIDL 0xF19 .................... #define RXM0EIDH 0xF1A .................... #define RXM0EIDL 0xF1B .................... .................... #define RXM1SIDH 0xF1C .................... #define RXM1SIDL 0xF1D .................... #define RXM1EIDH 0xF1E .................... #define RXM1EIDL 0xF1F .................... .................... .................... #define RXF0SIDH 0xF00 .................... #define RXF0SIDL 0xF01 .................... #define RXF0EIDH 0xF02 .................... #define RXF0EIDL 0xF03 .................... .................... #define RXF1SIDH 0xF04 .................... #define RXF1SIDL 0xF05 .................... #define RXF1EIDH 0xF06 .................... #define RXF1EIDL 0xF07 .................... .................... #define RXF2SIDH 0xF08 .................... #define RXF2SIDL 0xF09 .................... #define RXF2EIDH 0xF0A .................... #define RXF2EIDL 0xF0B .................... .................... #define RXF3SIDH 0xF0C .................... #define RXF3SIDL 0xF0D .................... #define RXF3EIDH 0xF0E .................... #define RXF3EIDL 0xF0F .................... .................... #define RXF4SIDH 0xF10 .................... #define RXF4SIDL 0xF11 .................... #define RXF4EIDH 0xF12 .................... #define RXF4EIDL 0xF13 .................... .................... #define RXF5SIDH 0xF14 .................... #define RXF5SIDL 0xF15 .................... #define RXF5EIDH 0xF16 .................... #define RXF5EIDL 0xF17 .................... .................... /*definitions receive buffer 0*/ .................... #define RXB0SIDH 0xF61 .................... #define RXB0SIDL 0xF62 .................... #define RXB0EIDH 0xF63 .................... #define RXB0EIDL 0xF64 .................... #BIT RXB0SIDL_EXID=0xF62.3 .................... .................... #define RXB0D0 0xF66 .................... #define RXB0D1 0xF67 .................... #define RXB0D2 0xF68 .................... #define RXB0D3 0xF69 .................... #define RXB0D4 0xF6A .................... #define RXB0D5 0xF6B .................... #define RXB0D6 0xF6C .................... #define RXB0D7 0xF6D .................... .................... /*definitions receive buffer 1*/ .................... #define RXB1DLC 0xF55 .................... #BIT RXB1DLC_RXRTR= 0xF55.6 .................... .................... #define RXB1SIDL 0xF52 .................... #BIT RXB1SIDL_EXID=0xF52.3 .................... .................... #define RXB1SIDH 0xF51 .................... #define RXB1EIDH 0xF53 .................... #define RXB1EIDL 0xF54 .................... .................... #define RXB1D0 0xF56 .................... #define RXB1D1 0xF57 .................... #define RXB1D2 0xF58 .................... #define RXB1D3 0xF59 .................... #define RXB1D4 0xF5A .................... #define RXB1D5 0xF5B .................... #define RXB1D6 0xF5C .................... #define RXB1D7 0xF5D .................... .................... // tristate register must set B2 to output and B3 to input. .................... .................... #BYTE TRISB_REG=0xF93 .................... .................... /********************************************************************* .................... * .................... * enum CAN_TX_MSG_FLAGS .................... * .................... * This enumeration values define flags related to transmission of a .................... * CAN message. There could be more than one this flag .................... * ANDed together to form multiple flags. .................... * .................... *********************************************************************/ .................... enum CAN_TX_MSG_FLAGS .................... { .................... CAN_TX_PRIORITY_BITS= 0b00000011, .................... CAN_TX_PRIORITY_0 = 0b11111100, // XXXXXX00 .................... CAN_TX_PRIORITY_1 = 0b11111101, // XXXXXX01 .................... CAN_TX_PRIORITY_2 = 0b11111110, // XXXXXX10 .................... CAN_TX_PRIORITY_3 = 0b11111111, // XXXXXX11 .................... .................... CAN_TX_FRAME_BIT = 0b00001000, .................... CAN_TX_STD_FRAME = 0b11111111, // XXXXX1XX .................... CAN_TX_XTD_FRAME = 0b11110111, // XXXXX0XX .................... .................... CAN_TX_RTR_BIT = 0b01000000, .................... CAN_TX_NO_RTR_FRAME = 0b11111111, // X1XXXXXX .................... CAN_TX_RTR_FRAME = 0b10111111 // X0XXXXXX .................... }; .................... .................... /********************************************************************* .................... * .................... * enum CAN_OP_MODE .................... * .................... * This enumeration values define codes related to CAN module .................... * operation mode. CANSetOperationMode() routine requires this code. .................... * These values must be used by itself .................... * i.e. it cannot be ANDed to form * multiple values. .................... * .................... ********************************************************************/ .................... enum CAN_OP_MODE .................... { .................... CAN_OP_MODE_BITS = 0b11100000, // Use this to access opmode .................... // bits .................... CAN_OP_MODE_NORMAL = 0b00000000, .................... CAN_OP_MODE_SLEEP = 0b00100000, .................... CAN_OP_MODE_LOOP = 0b01000000, .................... CAN_OP_MODE_LISTEN = 0b01100000, .................... CAN_OP_MODE_CONFIG = 0b10000000 .................... }; .................... .................... /********************************************************************* .................... * .................... * enum CAN_CONFIG_FLAGS .................... * .................... * This enumeration values define flags related to configuring CAN .................... * module. Routines CANInitialize() and CANSetBaudRate() use these .................... * codes. One or more these values may be ANDed to form multiple .................... * flags. .................... * .................... ********************************************************************/ .................... enum CAN_CONFIG_FLAGS .................... { .................... CAN_CONFIG_DEFAULT = 0b11111111, // 11111111 .................... .................... CAN_CONFIG_PHSEG2_PRG_BIT = 0b00000001, .................... CAN_CONFIG_PHSEG2_PRG_ON = 0b11111111, // XXXXXXX1 .................... CAN_CONFIG_PHSEG2_PRG_OFF = 0b11111110, // XXXXXXX0 .................... .................... CAN_CONFIG_LINE_FILTER_BIT = 0b00000010, .................... CAN_CONFIG_LINE_FILTER_ON = 0b11111111, // XXXXXX1X .................... CAN_CONFIG_LINE_FILTER_OFF = 0b11111101, // XXXXXX0X .................... .................... CAN_CONFIG_SAMPLE_BIT = 0b00000100, .................... CAN_CONFIG_SAMPLE_ONCE = 0b11111111, // XXXXX1XX .................... CAN_CONFIG_SAMPLE_THRICE = 0b11111011, // XXXXX0XX .................... .................... CAN_CONFIG_MSG_TYPE_BIT = 0b00001000, .................... CAN_CONFIG_STD_MSG = 0b11111111, // XXXX1XXX .................... CAN_CONFIG_XTD_MSG = 0b11110111, // XXXX0XXX .................... .................... CAN_CONFIG_DBL_BUFFER_BIT = 0b00010000, .................... CAN_CONFIG_DBL_BUFFER_ON = 0b11111111, // XXX1XXXX .................... CAN_CONFIG_DBL_BUFFER_OFF = 0b11101111, // XXX0XXXX .................... .................... CAN_CONFIG_MSG_BITS = 0b01100000, .................... CAN_CONFIG_ALL_MSG = 0b11111111, // X11XXXXX .................... CAN_CONFIG_VALID_XTD_MSG = 0b11011111, // X10XXXXX .................... CAN_CONFIG_VALID_STD_MSG = 0b10111111, // X01XXXXX .................... CAN_CONFIG_ALL_VALID_MSG = 0b10011111 // X00XXXXX .................... }; .................... .................... ////////////////////////////////////////////////////////////////////// .................... /********************************************************************* .................... * .................... * enum CAN_MASK .................... * .................... * This enumeration values define mask codes. Routine CANSetMask() .................... * requires this code as one of its arguments. These enumerations .................... * must be used by itself i.e. it cannot be ANDed to form multiple .................... * values. .................... * .................... ********************************************************************/ .................... enum CAN_MASK .................... { .................... CAN_MASK_B1, .................... CAN_MASK_B2 .................... }; .................... .................... /********************************************************************* .................... * .................... * enum CAN_FILTER .................... * .................... * This enumeration values define filter codes. Routine CANSetFilter .................... * requires this code as one of its arguments. These enumerations .................... * must be used by itself .................... * i.e. it cannot be ANDed to form multiple values. .................... * .................... ********************************************************************/ .................... enum CAN_FILTER .................... { .................... CAN_FILTER_B1_F1, .................... CAN_FILTER_B1_F2, .................... CAN_FILTER_B2_F1, .................... CAN_FILTER_B2_F2, .................... CAN_FILTER_B2_F3, .................... CAN_FILTER_B2_F4 .................... }; .................... .................... /********************************************************************* .................... * .................... * enum CAN_RX_MSG_FLAGS .................... * .................... * This enumeration values define flags related to reception of a CAN .................... * message. There could be more than one this flag .................... * ANDed together to form multiple flags. .................... * If a particular bit is set, corresponding meaning is TRUE or else .................... * it will be FALSE. .................... * .................... * e.g. .................... * if (MsgFlag & CAN_RX_OVERFLOW) .................... * { .................... * // Receiver overflow has occured. We have lost previous .................... * // message. .................... * ... .................... * } .................... * .................... ********************************************************************/ .................... enum CAN_RX_MSG_FLAGS .................... { .................... CAN_RX_FILTER_BITS = 0b00000111, // Use this to access filter .................... // bits .................... CAN_RX_FILTER_1 = 0b00000000, .................... CAN_RX_FILTER_2 = 0b00000001, .................... CAN_RX_FILTER_3 = 0b00000010, .................... CAN_RX_FILTER_4 = 0b00000011, .................... CAN_RX_FILTER_5 = 0b00000100, .................... CAN_RX_FILTER_6 = 0b00000101, .................... .................... CAN_RX_OVERFLOW = 0b00001000, // Set if Overflowed else .................... // cleared .................... .................... CAN_RX_INVALID_MSG = 0b00010000, // Set if invalid else .................... // cleared .................... .................... CAN_RX_XTD_FRAME = 0b00100000, // Set if XTD message else .................... // cleared .................... .................... CAN_RX_RTR_FRAME = 0b01000000, // Set if RTR message else .................... // cleared .................... .................... CAN_RX_DBL_BUFFERED = 0b10000000 // Set if this message was .................... // hardware double-buffered .................... }; .................... .................... /********************************************************************* .................... * Macro: BOOL CANIsRxReady() .................... * .................... * PreCondition: None .................... * .................... * Input: None .................... * .................... * Output: TRUE if at least one of the CAN receive buffer is .................... * full FALSE if none receive buffers are full. .................... * .................... * Side Effects: None .................... * .................... * Errata: This was incorrectly documented above as "empty" .................... * instead of "full." -dgi 24oct2003 .................... * .................... ********************************************************************/ .................... #define CANIsRxReady() (RXB0CON_RXFUL | RXB1CON_RXFUL) .................... .................... /********************************************************************* .................... * Macro: BOOL CANIsTxReady() .................... * .................... * PreCondition: None .................... * .................... * Input: None .................... * .................... * Output: TRUE if at least one CAN transmit buffer is empty .................... * FALSE if all CAN transmit buffers are full .................... * .................... * Side Effects: None .................... * .................... ********************************************************************/ .................... #define CANIsTxReady() (!TXB0CON_TXREQ || \ .................... !TXB1CON_TXREQ || \ .................... !TXB2CON_TXREQ ) .................... .................... #define CANIsTx0Ready() (!TXB0CON_TXREQ) .................... #define CANIsTx1Ready() (!TXB1CON_TXREQ) .................... #define CANIsTx2Ready() (!TXB2CON_TXREQ) .................... .................... void CANSetBaudRate(int SJW,int BRP,int PHSEG1,int PHSEG2,int PROPSEG,CAN_CONFIG_FLAGS flags); .................... void CANSetOperationMode(CAN_OP_MODE mode); .................... void CANInitialize(int SJW,int BRP,int PHSEG1,int PHSEG2,int PROPSEG,CAN_CONFIG_FLAGS config); .................... BOOLEAN CANSendMessage(int16 val,int8 buffSelect,BYTE* Data,BYTE DataLen,CAN_TX_MSG_FLAGS MsgFlags); .................... void CANSetMask(CAN_MASK code, int32 val, CAN_CONFIG_FLAGS type); .................... void CANIDToRegs(int *regaddress,int32 val,CAN_CONFIG_FLAGS type); .................... void RegsToCANID(int *regaddress,int32 *val,CAN_CONFIG_FLAGS type); .................... BOOLEAN CANReceiveMessage(int16 *id, BYTE *Data, BYTE *DataLen, CAN_RX_MSG_FLAGS *MsgFlags); .................... void CANSetFilter(CAN_FILTER code,int32 val,CAN_CONFIG_FLAGS type); .................... #endif .................... .................... .................... /////////////////////////////////////////////////////////////////////// .................... /********************************************************************* .................... * Function: void CANSetBaudRate(BYTE SJW, .................... * BYTE BRP, .................... * BYTE PHSEG1, .................... * BYTE PHSEG2, .................... * BYTE PROPSEG, .................... * enum CAN_CONFIG_FLAGS flags) .................... * .................... * PreCondition: MCU must be in Configuration mode or else these .................... * values will be ignored. .................... * .................... * Input: SJW - SJW value as defined in 18CXX8 datasheet .................... * (Must be between 1 thru 4) .................... * BRP - BRP value as defined in 18CXX8 datasheet .................... * (Must be between 1 thru 64) .................... * PHSEG1 - PHSEG1 value as defined in 18CXX8 .................... * datasheet .................... * (Must be between 1 thru 8) .................... * PHSEG2 - PHSEG2 value as defined in 18CXX8 .................... * datasheet .................... * (Must be between 1 thru 8) .................... * PROPSEG - PROPSEG value as defined in 18CXX8 .................... * datasheet .................... * (Must be between 1 thru 8) .................... * flags - Value of type enum CAN_CONFIG_FLAGS .................... * .................... * Output: CAN bit rate is set as per given values. .................... * .................... * Side Effects: None .................... * .................... * Overview: Given values are bit adjusted to fit in 18CXX8 .................... * BRGCONx registers and copied. .................... * .................... ********************************************************************/ .................... .................... void CANSetBaudRate(int SJW,int BRP,int PHSEG1,int PHSEG2,int PROPSEG,CAN_CONFIG_FLAGS flags) .................... { .................... // Decrement these valuse to fit in registers. .................... // The register values are offset from the Tq periods. .................... SJW--; * 15F4: MOVLB 1 15F6: DECF x35,F .................... BRP--; 15F8: DECF x36,F .................... PHSEG1--; 15FA: DECF x37,F .................... PHSEG2--; 15FC: DECF x38,F .................... PROPSEG--; 15FE: DECF x39,F .................... .................... // Bit adjust given values into their appropriate registers. .................... BRGCON1 = SJW << 6; 1600: SWAPF x35,W 1602: MOVWF F70 1604: RLCF F70,F 1606: RLCF F70,F 1608: MOVLW C0 160A: ANDWF F70,F .................... BRGCON1 |= BRP; 160C: MOVF x36,W 160E: IORWF F70,F .................... .................... BRGCON2 = PHSEG1 << 3; 1610: RLCF x37,W 1612: MOVWF F71 1614: RLCF F71,F 1616: RLCF F71,F 1618: MOVLW F8 161A: ANDWF F71,F .................... BRGCON2 |= PROPSEG; 161C: MOVF x39,W 161E: IORWF F71,F .................... .................... if ( !(flags & CAN_CONFIG_SAMPLE_BIT) ) 1620: BTFSC x3A.2 1622: BRA 1626 .................... BRGCON2_SAM = 1; 1624: BSF F71.6 .................... .................... if ( flags & CAN_CONFIG_PHSEG2_PRG_BIT ) 1626: BTFSS x3A.0 1628: BRA 162C .................... BRGCON2_SEG2PHTS = 1; 162A: BSF F71.7 .................... .................... .................... BRGCON3 = PHSEG2; 162C: MOVFF 138,F72 .................... //if ( flags & CAN_CONFIG_LINE_FILTER_BIT ) .................... BRGCON3_WAKFIL = 1; 1630: BSF F72.6 .................... } 1632: MOVLB 0 1634: GOTO 1720 (RETURN) .................... //////////////////////////////////////////////////////////////////////// .................... /********************************************************************* .................... * Function: void CANSetOperationMode(CAN_OP_MODE mode) .................... * .................... * PreCondition: None .................... * .................... * Input: mode - Operation mode code .................... * must be of type enum CAN_OP_MODES .................... * .................... * Output: MCU is set to requested mode .................... * .................... * Side Effects: None .................... * .................... * Overview: Given mode byte is copied to CANSTAT and made .................... * sure that requested mode is set. .................... * .................... * Note: This is a blocking call. It will not return until .................... * requested mode is set. .................... ********************************************************************/ .................... void CANSetOperationMode(CAN_OP_MODE mode) .................... { .................... // Request desired mode. .................... CANCON = mode; * 15DC: MOVFF 135,F6F .................... .................... // Wait till desired mode is set. .................... .................... while( (CANSTAT & CAN_OP_MODE_BITS) != mode ); 15E0: MOVF F6E,W 15E2: ANDLW E0 15E4: MOVLB 1 15E6: SUBWF x35,W 15E8: BTFSC FD8.2 15EA: BRA 15F0 15EC: MOVLB 0 15EE: BRA 15E0 .................... } 15F0: MOVLB 0 15F2: RETLW 00 .................... .................... ////////////////////////////////////////////////////////////////////// .................... /********************************************************************* .................... * Function: void CANInitialize(BYTE SJW, .................... * BYTE BRP, .................... * BYTE PHSEG1, .................... * BYTE PHSEG2, .................... * BYTE PROPSEG, .................... * enum CAN_CONFIG_FLAGS flags) .................... * .................... * PreCondition: MCU must be in Configuration mode or else these .................... * values will be ignored. .................... * .................... * Input: SJW - SJW value as defined in 18CXX8 datasheet .................... * (Must be between 1 thru 4) .................... * BRP - BRP value as defined in 18CXX8 datasheet .................... * (Must be between 1 thru 64) .................... * PHSEG1 - PHSEG1 value as defined in 18CXX8 .................... * datasheet .................... * (Must be between 1 thru 8) .................... * PHSEG2 - PHSEG2 value as defined in 18CXX8 .................... * datasheet .................... * (Must be between 1 thru 8) .................... * PROPSEG - PROPSEG value as defined in 18CXX8 .................... * datasheet .................... * (Must be between 1 thru 8) .................... * flags - Value of type enum CAN_CONFIG_FLAGS .................... * .................... * Output: CAN bit rate is set. All masks registers are set .................... * '0' to allow all messages. .................... * Filter registers are set according to flag value. .................... * If (config & CAN_CONFIG_VALID_XTD_MSG) .................... * Set all filters to XTD_MSG .................... * Else if (config & CONFIG_VALID_STD_MSG) .................... * Set all filters to STD_MSG .................... * Else .................... * Set half of the filters to STD while rests to .................... * XTD_MSG. .................... * .................... * Side Effects: All pending transmissions are aborted. .................... * .................... ********************************************************************/ .................... void CANInitialize(int SJW,int BRP,int PHSEG1,int PHSEG2,int PROPSEG,CAN_CONFIG_FLAGS config) .................... { .................... int FilterConfig1; .................... int FilterConfig2; .................... .................... // set tristate register to allow CAN to use B2, B3: .................... // B2 output, B3 input .................... // Doing it this way does not disturb any other pins. .................... TRISB_REG = (TRISB_REG & 0xFB) | 0x08; * 16F4: MOVF F93,W 16F6: ANDLW FB 16F8: IORLW 08 16FA: MOVWF F93 .................... .................... // In order to setup necessary config parameters of CAN module, .................... // it must be in CONFIG mode. .................... CANSetOperationMode(CAN_OP_MODE_CONFIG); 16FC: MOVLW 80 16FE: MOVLB 1 1700: MOVWF x35 1702: MOVLB 0 1704: RCALL 15DC .................... .................... // Now set the baud rate. .................... CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2,PROPSEG,config); 1706: MOVFF 12D,135 170A: MOVFF 12E,136 170E: MOVFF 12F,137 1712: MOVFF 130,138 1716: MOVFF 131,139 171A: MOVFF 132,13A 171E: BRA 15F4 .................... .................... *RXB0CON = config & CAN_CONFIG_MSG_BITS; //dgi changed 1720: MOVLB 1 1722: MOVF x32,W 1724: ANDLW 60 1726: MOVWF F60 .................... if (config & CAN_CONFIG_DBL_BUFFER_BIT) 1728: BTFSS x32.4 172A: BRA 172E .................... RXB0CON_RXB0DBEN = 1; 172C: BSF F60.2 .................... .................... *RXB1CON = *RXB0CON; 172E: MOVFF F60,F50 .................... .................... // Set ENDRHI to drive CANTX output high when recessive. .................... // Otherwise it is floated when recessive. .................... // This is the appropriate setting when using a .................... // transceiver without a pullup on CANTX. .................... // Alternatively, set ENDRHI = 0, and use a pullup. .................... // Then you can communicate non-differentially .................... // without a transciever. .................... ENDRHI = 1; 1732: BSF F73.5 .................... .................... // Set default filter and mask registers for all receive buffers. .................... // Default is to accept all messages .................... CANSetMask(CAN_MASK_B1, 0x00000000, CAN_CONFIG_STD_MSG); 1734: CLRF x35 1736: CLRF x39 1738: CLRF x38 173A: CLRF x37 173C: CLRF x36 173E: MOVLW FF 1740: MOVWF x3A 1742: MOVLB 0 1744: RCALL 1638 .................... CANSetMask(CAN_MASK_B2, 0x00000000, CAN_CONFIG_STD_MSG); 1746: MOVLW 01 1748: MOVLB 1 174A: MOVWF x35 174C: CLRF x39 174E: CLRF x38 1750: CLRF x37 1752: CLRF x36 1754: MOVLW FF 1756: MOVWF x3A 1758: MOVLB 0 175A: RCALL 1638 .................... .................... switch( (config & CAN_CONFIG_MSG_BITS) | ~CAN_CONFIG_MSG_BITS ) .................... { 175C: MOVLB 1 175E: MOVF x32,W 1760: ANDLW 60 1762: IORLW 9F 1764: XORLW DF 1766: MOVLB 0 1768: BZ 1770 176A: XORLW 60 176C: BZ 177A 176E: BRA 1784 .................... case CAN_CONFIG_VALID_XTD_MSG: .................... FilterConfig1 = CAN_CONFIG_XTD_MSG; 1770: MOVLW F7 1772: MOVLB 1 1774: MOVWF x33 .................... FilterConfig2 = CAN_CONFIG_XTD_MSG; 1776: MOVWF x34 .................... break; 1778: BRA 1790 .................... .................... case CAN_CONFIG_VALID_STD_MSG: .................... FilterConfig1 = CAN_CONFIG_STD_MSG; 177A: MOVLW FF 177C: MOVLB 1 177E: MOVWF x33 .................... FilterConfig2 = CAN_CONFIG_STD_MSG; 1780: MOVWF x34 .................... break; 1782: BRA 1790 .................... default: .................... FilterConfig1 = CAN_CONFIG_STD_MSG; 1784: MOVLW FF 1786: MOVLB 1 1788: MOVWF x33 .................... FilterConfig2 = CAN_CONFIG_XTD_MSG; 178A: MOVLW F7 178C: MOVWF x34 .................... break; 178E: BRA 1790 .................... } .................... .................... // By default, there will be no mask on any receive filters, .................... // hence filter value of '0' will be ignored. .................... CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1); 1790: CLRF x35 1792: CLRF x39 1794: CLRF x38 1796: CLRF x37 1798: CLRF x36 179A: MOVFF 133,13A 179E: MOVLB 0 17A0: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1); 17A2: MOVLW 01 17A4: MOVLB 1 17A6: MOVWF x35 17A8: CLRF x39 17AA: CLRF x38 17AC: CLRF x37 17AE: CLRF x36 17B0: MOVFF 133,13A 17B4: MOVLB 0 17B6: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2); 17B8: MOVLW 02 17BA: MOVLB 1 17BC: MOVWF x35 17BE: CLRF x39 17C0: CLRF x38 17C2: CLRF x37 17C4: CLRF x36 17C6: MOVFF 134,13A 17CA: MOVLB 0 17CC: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2); 17CE: MOVLW 03 17D0: MOVLB 1 17D2: MOVWF x35 17D4: CLRF x39 17D6: CLRF x38 17D8: CLRF x37 17DA: CLRF x36 17DC: MOVFF 134,13A 17E0: MOVLB 0 17E2: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2); 17E4: MOVLW 04 17E6: MOVLB 1 17E8: MOVWF x35 17EA: CLRF x39 17EC: CLRF x38 17EE: CLRF x37 17F0: CLRF x36 17F2: MOVFF 134,13A 17F6: MOVLB 0 17F8: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2); 17FA: MOVLW 05 17FC: MOVLB 1 17FE: MOVWF x35 1800: CLRF x39 1802: CLRF x38 1804: CLRF x37 1806: CLRF x36 1808: MOVFF 134,13A 180C: MOVLB 0 180E: RCALL 1672 .................... .................... // Restore to Normal mode. .................... CANSetOperationMode(CAN_OP_MODE_NORMAL); 1810: MOVLB 1 1812: CLRF x35 1814: MOVLB 0 1816: RCALL 15DC .................... } 1818: GOTO 1838 (RETURN) .................... .................... /********************************************************************* .................... * Function: BOOL CANSendMessage(int16 id, .................... * BYTE *Data, .................... * BYTE DataLen, .................... * enum CAN_TX_MSG_FLAGS MsgFlags) .................... * .................... * PreCondition: None .................... * .................... * Input: id - CAN message identifier. .................... * Range: 0x0000 - 0x07FF .................... * .................... * buffSelect - select Tx buff 0, 1, or 2. .................... * Data - Data bytes of upto 8 bytes in length .................... * DataLen - Data length from 1 thru 8. .................... * MsgFlags - One or CAN_TX_MSG_FLAGS values ANDed .................... * together .................... * .................... * Output: If at least one empty transmit buffer is found, .................... * given message is queued to be transmitted. If none .................... * found FALSE value is returned. .................... * .................... * Side Effects: None .................... * .................... ********************************************************************/ .................... // This is not "#inline" !! Do not call CANSendMessage from interrupt! .................... BOOLEAN CANSendMessage(int16 val, int8 buffSelect, BYTE* Data, BYTE DataLen, CAN_TX_MSG_FLAGS MsgFlags) .................... { .................... BYTE i; .................... .................... // use Buffer 0? .................... if ( TXB0CON_TXREQ == 0 && buffSelect ==0 ) * 1068: MOVLB F 106A: BTFSC x40.3 106C: BRA 111C 106E: MOVLB 1 1070: MOVF x40,F 1072: BTFSC FD8.2 1074: BRA 107A 1076: MOVLB F 1078: BRA 111C .................... { .................... // Select which of the CAN buffers to switch into the access bank area .................... CANCON &= 0b11110000;//0b11110001; 107A: MOVLW F0 107C: ANDWF F6F,F .................... CANCON |= 0b00001000; 107E: BSF F6F.3 .................... // Set transmit priority. .................... TXB0CON |= MsgFlags & CAN_TX_PRIORITY_BITS; 1080: MOVF x44,W 1082: ANDLW 03 1084: MOVLB F 1086: IORWF x40,F .................... // Populate Extended identifier information only if it is .................... // desired. .................... .................... if ( !(MsgFlags & CAN_TX_FRAME_BIT) ) 1088: MOVLB 1 108A: BTFSC x44.3 108C: BRA 10AE .................... CANIDToRegs(&TXB0SIDH,val,CAN_CONFIG_XTD_MSG); 108E: MOVLW 0F 1090: MOVWF x47 1092: MOVLW 41 1094: MOVWF x46 1096: CLRF x4B 1098: CLRF x4A 109A: MOVFF 13F,149 109E: MOVFF 13E,148 10A2: MOVLW F7 10A4: MOVWF x4C 10A6: MOVLB 0 10A8: RCALL 0F50 .................... else 10AA: BRA 10CA 10AC: MOVLB 1 .................... CANIDToRegs(&TXB0SIDH,val,CAN_CONFIG_STD_MSG); 10AE: MOVLW 0F 10B0: MOVWF x47 10B2: MOVLW 41 10B4: MOVWF x46 10B6: CLRF x4B 10B8: CLRF x4A 10BA: MOVFF 13F,149 10BE: MOVFF 13E,148 10C2: MOVLW FF 10C4: MOVWF x4C 10C6: MOVLB 0 10C8: RCALL 0F50 .................... .................... TXB0DLC = DataLen; 10CA: MOVFF 143,F45 .................... .................... if ( !(MsgFlags & CAN_TX_RTR_BIT) ) 10CE: MOVLB 1 10D0: BTFSC x44.6 10D2: BRA 10DA .................... TXB0DLC |= 0b01000000; 10D4: MOVLB F 10D6: BSF x45.6 10D8: MOVLB 1 .................... .................... // Populate data values. .................... for (i=0;i>3); .................... *(&TXB0SIDH)=temp; .................... temp=(int)(RBSendMsgID&0x7); .................... *(&TXB0SIDH+1)=(temp<<5); .................... .................... TXB0DLC = 2; // length of data .................... if ( !(localMsgFlags & CAN_TX_RTR_BIT) ) .................... TXB0DLC |= 0b01000000; .................... .................... // Populate data values. .................... for (i=0;i<2;i++) .................... *(TXB0D0+i) = Data[i]; .................... .................... TXB0CON_TXREQ=1; //enable transmission .................... .................... // CANCON=CAN_OP_MODE_NORMAL; .................... .................... return; .................... } .................... .................... */ .................... .................... /********************************************************************* .................... * Function: void CANIDToRegs(BYTE* ptr, .................... * int32 val, .................... * enum CAN_CONFIG_FLAGS type) .................... * .................... * PreCondition: None .................... * .................... * Input: ptr - Starting address of a buffer to be updated .................... * val - 32-bit value to be converted .................... * type - Type of message - either .................... * CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG .................... * .................... * Output: Given CAN id value 'val' is bit adjusted and copied .................... * into corresponding PIC18CXX8 CAN registers .................... * .................... * Side Effects: None .................... * .................... * Overview: If given id is of type standard identifier, .................... * only SIDH and SIDL are updated .................... * If given id is of type extended identifier, .................... * bits val<17:0> is copied to EIDH, EIDL and SIDH<1:0> .................... * bits val<28:18> is copied to SIDH and SIDL .................... * .................... ********************************************************************/ .................... void CANIDToRegs(int *regaddress, int32 val, CAN_CONFIG_FLAGS type) .................... { .................... byte temp; .................... if (type == CAN_TX_STD_FRAME) * 0F50: MOVLB 1 0F52: INCFSZ x4C,W 0F54: BRA 0FB0 .................... { .................... // Standard Identifier .................... temp=(int)(val>>3); 0F56: RRCF x4B,W 0F58: MOVWF 03 0F5A: RRCF x4A,W 0F5C: MOVWF 02 0F5E: RRCF x49,W 0F60: MOVWF 01 0F62: RRCF x48,W 0F64: MOVWF 00 0F66: RRCF 03,F 0F68: RRCF 02,F 0F6A: RRCF 01,F 0F6C: RRCF 00,F 0F6E: RRCF 03,F 0F70: RRCF 02,F 0F72: RRCF 01,F 0F74: RRCF 00,F 0F76: MOVLW 1F 0F78: ANDWF 03,F 0F7A: MOVFF 00,14D .................... *regaddress=temp; 0F7E: MOVFF 146,FE9 0F82: MOVFF 147,FEA 0F86: MOVFF 14D,FEF .................... temp=(int)(val&0x7); 0F8A: MOVF x48,W 0F8C: ANDLW 07 0F8E: MOVWF x4D .................... *(regaddress+1)=(temp<<5); 0F90: MOVLW 01 0F92: ADDWF x46,W 0F94: MOVWF 01 0F96: MOVLW 00 0F98: ADDWFC x47,W 0F9A: MOVFF 01,FE9 0F9E: MOVWF FEA 0FA0: SWAPF x4D,W 0FA2: MOVWF 00 0FA4: RLCF 00,F 0FA6: MOVLW E0 0FA8: ANDWF 00,F 0FAA: MOVFF 00,FEF .................... } .................... else 0FAE: BRA 1064 .................... { .................... // Extended Identifier .................... *regaddress=val>>21; 0FB0: MOVFF 147,03 0FB4: MOVFF 146,FE9 0FB8: MOVFF 147,FEA 0FBC: RRCF x4B,W 0FBE: MOVWF 01 0FC0: RRCF x4A,W 0FC2: MOVWF 00 0FC4: RRCF 01,F 0FC6: RRCF 00,F 0FC8: RRCF 01,F 0FCA: RRCF 00,F 0FCC: RRCF 01,F 0FCE: RRCF 00,F 0FD0: RRCF 01,F 0FD2: RRCF 00,F 0FD4: MOVLW 07 0FD6: ANDWF 01,F 0FD8: MOVFF 00,FEF .................... *(regaddress+1)=((val>>13)&0xE0); 0FDC: MOVLW 01 0FDE: ADDWF x46,W 0FE0: MOVWF 01 0FE2: MOVLW 00 0FE4: ADDWFC x47,W 0FE6: MOVWF 03 0FE8: MOVFF 01,FE9 0FEC: MOVWF FEA 0FEE: RRCF x4B,W 0FF0: MOVWF x53 0FF2: RRCF x4A,W 0FF4: MOVWF x52 0FF6: RRCF x49,W 0FF8: MOVWF x51 0FFA: RRCF x53,F 0FFC: RRCF x52,F 0FFE: RRCF x51,F 1000: RRCF x53,F 1002: RRCF x52,F 1004: RRCF x51,F 1006: RRCF x53,F 1008: RRCF x52,F 100A: RRCF x51,F 100C: RRCF x53,F 100E: RRCF x52,F 1010: RRCF x51,F 1012: MOVLW 07 1014: ANDWF x53,F 1016: MOVF x51,W 1018: ANDLW E0 101A: MOVWF FEF .................... *(regaddress+1)|=((val>>16)&0x3); 101C: MOVLW 01 101E: ADDWF x46,W 1020: MOVWF 01 1022: MOVLW 00 1024: ADDWFC x47,W 1026: MOVWF 03 1028: MOVFF 01,FE9 102C: MOVWF FEA 102E: MOVF x4A,W 1030: ANDLW 03 1032: MOVWF 00 1034: MOVF 00,W 1036: IORWF FEF,W 1038: MOVWF FEF .................... *(regaddress+2)=val>>8; 103A: MOVLW 02 103C: ADDWF x46,W 103E: MOVWF 01 1040: MOVLW 00 1042: ADDWFC x47,W 1044: MOVWF 03 1046: MOVFF 01,FE9 104A: MOVWF FEA 104C: MOVFF 149,FEF .................... *(regaddress+3)=(int)val; 1050: MOVLW 03 1052: ADDWF x46,W 1054: MOVWF 01 1056: MOVLW 00 1058: ADDWFC x47,W 105A: MOVFF 01,FE9 105E: MOVWF FEA 1060: MOVFF 148,FEF .................... } .................... } 1064: MOVLB 0 1066: RETLW 00 .................... .................... ////////////////////////////////////////////////////////////////////// .................... /********************************************************************* .................... * Function: void CANSetMask(enum CAN_MASK code, .................... * unsigned long val, .................... * enum CAN_CONFIG_FLAGS type) .................... * .................... * PreCondition: MCU must be in Configuration mode. If not, all .................... * values will be ignored. .................... * .................... * Input: code - One of CAN_MASK value .................... * val - Actual mask register value. .................... * type - Type of message to filter either .................... * CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG .................... * .................... * Output: Given value is bit adjusted to appropriate buffer .................... * mask registers. .................... * .................... * Side Effects: None .................... * .................... ********************************************************************/ .................... void CANSetMask(CAN_MASK code, int32 val,CAN_CONFIG_FLAGS type) .................... { .................... int16 ptr; .................... .................... // Select appropriate starting address based on given CAN_MASK .................... // value. .................... if ( code == CAN_MASK_B1 ) * 1638: MOVLB 1 163A: MOVF x35,F 163C: BNZ 1648 .................... ptr = RXM0SIDH; 163E: MOVLW 0F 1640: MOVWF x3C 1642: MOVLW 18 1644: MOVWF x3B .................... else 1646: BRA 1650 .................... ptr = RXM1SIDH; 1648: MOVLW 0F 164A: MOVWF x3C 164C: MOVLW 1C 164E: MOVWF x3B .................... .................... // Convert given 32-bit id value into corresponding register values. .................... CANIDToRegs(ptr, val, type); 1650: MOVFF 13C,147 1654: MOVFF 13B,146 1658: MOVFF 139,14B 165C: MOVFF 138,14A 1660: MOVFF 137,149 1664: MOVFF 136,148 1668: MOVFF 13A,14C 166C: MOVLB 0 166E: RCALL 0F50 .................... } 1670: RETLW 00 .................... .................... /********************************************************************* .................... * Function: void CANSetFilter(enum CAN_FILTER code, .................... * unsigned long val, .................... * enum CAN_CONFIG type) .................... * .................... * PreCondition: MCU must be in Configuration mode. If not, all .................... * values will be ignored. .................... * .................... * .................... Input: code - One of CAN_FILTER value .................... * val - Actual filter register value. .................... * type - Type of message to filter either .................... * CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG .................... * .................... * Output: Given value is bit adjusted to appropriate buffer .................... * filter registers. .................... * .................... * Side Effects: None .................... ********************************************************************/ .................... void CANSetFilter(CAN_FILTER code,int32 val,CAN_CONFIG_FLAGS type) .................... { .................... int16 ptr; .................... .................... // Select appropriate starting address based on given CAN_FILTER .................... // code. .................... switch(code) .................... { 1672: MOVLB 1 1674: MOVF x35,W 1676: MOVLB 0 1678: BZ 168C 167A: XORLW 01 167C: BZ 1696 167E: XORLW 03 1680: BZ 16A2 1682: XORLW 01 1684: BZ 16AE 1686: XORLW 07 1688: BZ 16BA 168A: BRA 16C6 .................... case CAN_FILTER_B1_F1: .................... ptr = RXF0SIDH; 168C: MOVLW 0F 168E: MOVLB 1 1690: MOVWF x3C 1692: CLRF x3B .................... break; 1694: BRA 16D2 .................... .................... case CAN_FILTER_B1_F2: .................... ptr = RXF1SIDH; 1696: MOVLW 0F 1698: MOVLB 1 169A: MOVWF x3C 169C: MOVLW 04 169E: MOVWF x3B .................... break; 16A0: BRA 16D2 .................... .................... case CAN_FILTER_B2_F1: .................... ptr = RXF2SIDH; 16A2: MOVLW 0F 16A4: MOVLB 1 16A6: MOVWF x3C 16A8: MOVLW 08 16AA: MOVWF x3B .................... break; 16AC: BRA 16D2 .................... .................... case CAN_FILTER_B2_F2: .................... ptr = RXF3SIDH; 16AE: MOVLW 0F 16B0: MOVLB 1 16B2: MOVWF x3C 16B4: MOVLW 0C 16B6: MOVWF x3B .................... break; 16B8: BRA 16D2 .................... .................... case CAN_FILTER_B2_F3: .................... ptr = RXF4SIDH; 16BA: MOVLW 0F 16BC: MOVLB 1 16BE: MOVWF x3C 16C0: MOVLW 10 16C2: MOVWF x3B .................... break; 16C4: BRA 16D2 .................... .................... default: .................... ptr = RXF5SIDH; 16C6: MOVLW 0F 16C8: MOVLB 1 16CA: MOVWF x3C 16CC: MOVLW 14 16CE: MOVWF x3B .................... break; 16D0: BRA 16D2 .................... } .................... .................... // Convert 32-bit value into register values. .................... CANIDToRegs(ptr, val, type); 16D2: MOVFF 13C,147 16D6: MOVFF 13B,146 16DA: MOVFF 139,14B 16DE: MOVFF 138,14A 16E2: MOVFF 137,149 16E6: MOVFF 136,148 16EA: MOVFF 13A,14C 16EE: MOVLB 0 16F0: RCALL 0F50 .................... } 16F2: RETLW 00 .................... .................... ////////////////////////////////////////////////////////////////////// .................... /********************************************************************* .................... * Function: BOOL CANReceiveMessage(int16 *id, .................... * BYTE *Data, .................... * BYTE DataLen, .................... * enum CAN_RX_MSG_FLAGS MsgFlags) .................... * .................... * PreCondition: None .................... * .................... * Input: None .................... * .................... * Output: id - CAN message identifier. .................... * Data - Data bytes of upto 8 bytes in length .................... * DataLen - Data length from 1 thru 8. .................... * MsgFlags - One or CAN_RX_MSG_FLAGS values ANDed .................... * together .................... * .................... * Output: If at least one full receive buffer is found, .................... * it is extrated and returned. .................... * If none found FALSE value is returned. .................... * .................... * Side Effects: None .................... * .................... ********************************************************************/ .................... .................... BOOLEAN CANReceiveMessage(int16 *id, BYTE *Data, BYTE *DataLen, CAN_RX_MSG_FLAGS *MsgFlags) .................... { .................... BYTE i; .................... BOOLEAN lbIsItBuffer0; .................... .................... // Start with no error or flags set. .................... *MsgFlags = 0x0; * 2466: MOVLB 1 2468: MOVFF 132,FE9 246C: MOVFF 133,FEA 2470: CLRF FEF .................... .................... // Find which buffer is ready. .................... if ( RXB0CON_RXFUL ) 2472: BTFSS F60.7 2474: BRA 25C0 .................... { .................... // RXBuffer0 is full. .................... CANCON &= 0b11110000; // clear Window Address bits (see sec 19.2.1) 2476: MOVLW F0 2478: ANDWF F6F,F .................... // dgi doesn't know if this is necessary? 2004-01-01 .................... .................... lbIsItBuffer0 = TRUE; 247A: BSF x35.0 .................... .................... // Clear the received flag. .................... PIR3_RXB0IF = 0; 247C: BCF FA4.0 .................... .................... // Record and forget any previous overflow .................... if ( COMSTAT_RXB0OVFL ) 247E: BTFSS F74.7 2480: BRA 2492 .................... { .................... *MsgFlags |= CAN_RX_OVERFLOW; 2482: MOVFF 132,FE9 2486: MOVFF 133,FEA 248A: MOVF FEF,W 248C: IORLW 08 248E: MOVWF FEF .................... COMSTAT_RXB0OVFL = 0; 2490: BCF F74.7 .................... } .................... .................... if ( RXB0CON_RXB0DBEN ) 2492: BTFSS F60.2 2494: BRA 24B8 .................... { .................... *MsgFlags |= RXB0CON & CAN_RX_FILTER_BITS; 2496: MOVFF 133,03 249A: MOVFF 132,FE9 249E: MOVFF 133,FEA 24A2: MOVFF FEF,00 24A6: MOVFF 00,FEF .................... *MsgFlags &= 0x01; 24AA: MOVFF 132,FE9 24AE: MOVFF 133,FEA 24B2: MOVF FEF,W 24B4: ANDLW 01 24B6: MOVWF FEF .................... } .................... .................... // Retrieve message length. .................... .................... *DataLen = *RXB0DLC & 0b00001111; 24B8: MOVFF 130,FE9 24BC: MOVFF 131,FEA 24C0: MOVF F65,W 24C2: ANDLW 0F 24C4: MOVWF FEF .................... .................... .................... // Determine whether this was RTR or not. .................... if ( RXB0DLC_RXRTR ) 24C6: BTFSS F65.6 24C8: BRA 24D8 .................... *MsgFlags |= CAN_RX_RTR_FRAME; 24CA: MOVFF 132,FE9 24CE: MOVFF 133,FEA 24D2: MOVF FEF,W 24D4: IORLW 40 24D6: MOVWF FEF .................... .................... // Retrieve EIDX bytes only if this is extended message .................... if ( RXB0SIDL_EXID ) 24D8: BTFSS F62.3 24DA: BRA 24EC .................... { .................... *MsgFlags |= CAN_RX_XTD_FRAME; 24DC: MOVFF 132,FE9 24E0: MOVFF 133,FEA 24E4: MOVF FEF,W 24E6: IORLW 20 24E8: MOVWF FEF .................... } .................... else { 24EA: BRA 2556 .................... *id =((int32)(*RXB0SIDH)) * 8; 24EC: MOVFF 12C,FE9 24F0: MOVFF 12D,FEA 24F4: CLRF x3B 24F6: CLRF x3A 24F8: CLRF x39 24FA: RLCF F61,W 24FC: MOVWF 00 24FE: RLCF x39,W 2500: MOVWF 01 2502: RLCF x3A,W 2504: MOVWF 02 2506: RLCF x3B,W 2508: MOVWF 03 250A: RLCF 00,F 250C: RLCF 01,F 250E: RLCF 02,F 2510: RLCF 03,F 2512: RLCF 00,F 2514: RLCF 01,F 2516: RLCF 02,F 2518: RLCF 03,F 251A: MOVLW F8 251C: ANDWF 00,F 251E: MOVFF 00,FEF 2522: MOVFF 01,FEC .................... *id |= (int32)(((*RXB0SIDL) & 0xE0)>>5); 2526: MOVFF 12D,03 252A: MOVFF 12C,FE9 252E: MOVFF 12D,FEA 2532: MOVF F62,W 2534: ANDLW E0 2536: MOVWF 00 2538: SWAPF 00,F 253A: RRCF 00,F 253C: MOVLW 07 253E: ANDWF 00,F 2540: MOVF 00,W 2542: CLRF 01 2544: MOVF 00,W 2546: IORWF FEF,W 2548: MOVWF 00 254A: MOVF 01,W 254C: IORWF FEC,W 254E: MOVF FED,F 2550: MOVFF 00,FEF 2554: MOVWF FEC .................... } .................... .................... for ( i = 0; i < *DataLen; i++ ) 2556: CLRF x34 2558: MOVFF 131,03 255C: MOVFF 130,FE9 2560: MOVFF 131,FEA 2564: MOVF FEF,W 2566: SUBWF x34,W 2568: BC 25A8 .................... Data[i] = *(RXB0D0+i); 256A: CLRF 03 256C: MOVF x34,W 256E: ADDWF x2E,W 2570: MOVWF 01 2572: MOVF x2F,W 2574: ADDWFC 03,F 2576: MOVFF 01,136 257A: MOVFF 03,137 257E: MOVLW 66 2580: ADDWF x34,W 2582: MOVWF 01 2584: MOVLW 0F 2586: MOVWF 03 2588: BTFSC FD8.0 258A: INCF 03,F 258C: MOVFF 01,FE9 2590: MOVFF 03,FEA 2594: MOVFF FEF,138 2598: MOVFF 137,FEA 259C: MOVFF 136,FE9 25A0: MOVFF 138,FEF 25A4: INCF x34,F 25A6: BRA 2558 .................... .................... CANCON=CAN_OP_MODE_NORMAL; 25A8: CLRF F6F .................... .................... // Record and Clear any previous invalid message bit flag. .................... if ( PIR3_IRXIF ) 25AA: BTFSS FA4.7 25AC: BRA 25BE .................... { .................... *MsgFlags |= CAN_RX_INVALID_MSG; 25AE: MOVFF 132,FE9 25B2: MOVFF 133,FEA 25B6: MOVF FEF,W 25B8: IORLW 10 25BA: MOVWF FEF .................... PIR3_IRXIF = 0; 25BC: BCF FA4.7 .................... } .................... } .................... else if ( RXB1CON_RXFUL ) 25BE: BRA 2744 25C0: MOVLB F 25C2: BTFSS x50.7 25C4: BRA 273C .................... { .................... // RXBuffer1 is full .................... CANCON &= 0b11110000; // clear Window Address bits (see sec 19.2.1) 25C6: MOVLW F0 25C8: ANDWF F6F,F .................... CANCON |= 0b00001010; // select RXBuff1 25CA: MOVLW 0A 25CC: IORWF F6F,F .................... .................... lbIsItBuffer0 = FALSE; 25CE: MOVLB 1 25D0: BCF x35.0 .................... .................... // Clear the received flag. .................... PIR3_RXB1IF = 0; 25D2: BCF FA4.1 .................... .................... // Record and forget any previous overflow .................... if ( COMSTAT_RXB1OVFL ) 25D4: BTFSS F74.6 25D6: BRA 25E8 .................... { .................... *MsgFlags |= CAN_RX_OVERFLOW; 25D8: MOVFF 132,FE9 25DC: MOVFF 133,FEA 25E0: MOVF FEF,W 25E2: IORLW 08 25E4: MOVWF FEF .................... COMSTAT_RXB1OVFL = 0; 25E6: BCF F74.6 .................... } .................... .................... *MsgFlags |= RXB1CON & CAN_RX_FILTER_BITS; 25E8: MOVFF 133,03 25EC: MOVFF 132,FE9 25F0: MOVFF 133,FEA 25F4: MOVFF FEF,00 25F8: MOVFF 00,FEF .................... if ( *MsgFlags < 0x02 ) 25FC: MOVFF 133,03 2600: MOVFF 132,FE9 2604: MOVFF 133,FEA 2608: MOVF FEF,W 260A: SUBLW 01 260C: BNC 261C .................... *MsgFlags |= CAN_RX_DBL_BUFFERED; 260E: MOVFF 132,FE9 2612: MOVFF 133,FEA 2616: MOVF FEF,W 2618: IORLW 80 261A: MOVWF FEF .................... .................... .................... // Retrieve message length. .................... *DataLen = *RXB1DLC & 0b00001111; 261C: MOVFF 130,FE9 2620: MOVFF 131,FEA 2624: MOVLB F 2626: MOVF x55,W 2628: ANDLW 0F 262A: MOVWF FEF .................... .................... // Determine whether this was RTR or not. .................... if ( RXB1DLC_RXRTR ) 262C: BTFSS x55.6 262E: BRA 2642 .................... *MsgFlags |= CAN_RX_RTR_FRAME; 2630: MOVLB 1 2632: MOVFF 132,FE9 2636: MOVFF 133,FEA 263A: MOVF FEF,W 263C: IORLW 40 263E: MOVWF FEF 2640: MOVLB F .................... .................... // Retrieve EIDX bytes only if this is extended message .................... if ( RXB1SIDL_EXID ) { 2642: BTFSS x52.3 2644: BRA 265A .................... *MsgFlags |= CAN_RX_XTD_FRAME; 2646: MOVLB 1 2648: MOVFF 132,FE9 264C: MOVFF 133,FEA 2650: MOVF FEF,W 2652: IORLW 20 2654: MOVWF FEF .................... } .................... else { 2656: BRA 26CE 2658: MOVLB F .................... *id =((int32)(*RXB1SIDH)) * 8; 265A: MOVLB 1 265C: MOVFF 12C,FE9 2660: MOVFF 12D,FEA 2664: CLRF x3B 2666: CLRF x3A 2668: CLRF x39 266A: MOVFF F51,138 266E: RLCF x38,W 2670: MOVWF 00 2672: RLCF x39,W 2674: MOVWF 01 2676: RLCF x3A,W 2678: MOVWF 02 267A: RLCF x3B,W 267C: MOVWF 03 267E: RLCF 00,F 2680: RLCF 01,F 2682: RLCF 02,F 2684: RLCF 03,F 2686: RLCF 00,F 2688: RLCF 01,F 268A: RLCF 02,F 268C: RLCF 03,F 268E: MOVLW F8 2690: ANDWF 00,F 2692: MOVFF 00,FEF 2696: MOVFF 01,FEC .................... *id |= (int32)(((*RXB1SIDL) & 0xE0)>>5); 269A: MOVFF 12D,03 269E: MOVFF 12C,FE9 26A2: MOVFF 12D,FEA 26A6: MOVLB F 26A8: MOVF x52,W 26AA: ANDLW E0 26AC: MOVWF 00 26AE: SWAPF 00,F 26B0: RRCF 00,F 26B2: MOVLW 07 26B4: ANDWF 00,F 26B6: MOVF 00,W 26B8: CLRF 01 26BA: MOVF 00,W 26BC: IORWF FEF,W 26BE: MOVWF 00 26C0: MOVF 01,W 26C2: IORWF FEC,W 26C4: MOVF FED,F 26C6: MOVFF 00,FEF 26CA: MOVWF FEC 26CC: MOVLB 1 .................... } .................... .................... // Get message data itself .................... //ptr = RXB1D0; .................... for ( i = 0; i < *DataLen; i++ ) 26CE: CLRF x34 26D0: MOVFF 131,03 26D4: MOVFF 130,FE9 26D8: MOVFF 131,FEA 26DC: MOVF FEF,W 26DE: SUBWF x34,W 26E0: BC 2720 .................... Data[i] = *(RXB1D0+i); 26E2: CLRF 03 26E4: MOVF x34,W 26E6: ADDWF x2E,W 26E8: MOVWF 01 26EA: MOVF x2F,W 26EC: ADDWFC 03,F 26EE: MOVFF 01,136 26F2: MOVFF 03,137 26F6: MOVLW 56 26F8: ADDWF x34,W 26FA: MOVWF 01 26FC: MOVLW 0F 26FE: MOVWF 03 2700: BTFSC FD8.0 2702: INCF 03,F 2704: MOVFF 01,FE9 2708: MOVFF 03,FEA 270C: MOVFF FEF,138 2710: MOVFF 137,FEA 2714: MOVFF 136,FE9 2718: MOVFF 138,FEF 271C: INCF x34,F 271E: BRA 26D0 .................... .................... // Restore default RXB0 mapping. .................... //CANCON &= 0b11110000;//0b11110001; .................... CANCON=CAN_OP_MODE_NORMAL; 2720: CLRF F6F .................... // Record and Clear any previous invalid message bit flag. .................... if ( PIR3_IRXIF ) 2722: BTFSS FA4.7 2724: BRA 2736 .................... { .................... *MsgFlags |= CAN_RX_INVALID_MSG; 2726: MOVFF 132,FE9 272A: MOVFF 133,FEA 272E: MOVF FEF,W 2730: IORLW 10 2732: MOVWF FEF .................... PIR3_IRXIF = 0; 2734: BCF FA4.7 .................... } .................... RXB1CON_RXFUL = 0; 2736: MOVLB F 2738: BCF x50.7 .................... } .................... else 273A: BRA 2742 .................... return FALSE; 273C: MOVLW 00 273E: MOVWF 01 2740: BRA 2758 2742: MOVLB 1 .................... .................... if ( lbIsItBuffer0 ) 2744: BTFSS x35.0 2746: BRA 274C .................... RXB0CON_RXFUL = 0; 2748: BCF F60.7 .................... else 274A: BRA 2752 .................... RXB1CON_RXFUL = 0; 274C: MOVLB F 274E: BCF x50.7 2750: MOVLB 1 .................... .................... return TRUE; 2752: MOVLW 01 2754: MOVWF 01 2756: MOVLB F .................... } 2758: MOVLB 0 275A: GOTO 3D08 (RETURN) .................... .................... #include "ODaccess.c" // object dictionary access functions .................... /************************************************************************** .................... OBJECT DICTIONARY ACCESS .................... ************************************************************************** .................... .................... A set of functions for accessing information in the object dictionary. .................... .................... Authors and Contributors: .................... Ethan Stump .................... GRASP Lab, University of Pennsylvania .................... .................... Daniel Gomez-Ibanez .................... .................... Ethan, I changed two lines here because I was getting a compile error, .................... "identifier must be a pointer" See "char* source;" declaration. .................... **************************************************************************/ .................... .................... // read and write to EEPROM .................... .................... void RBSetEEPROM(int *data, byte addr, int len) .................... { .................... int i; .................... for (i=0; ican, can->spi passing functions .................... /* .................... ir_ports.c .................... .................... The functions in this file are used for communication between the host->pic CANbus .................... and the pic->atxmega SPI. .................... */ .................... .................... #include "ir_ports.h" .................... /* .................... ir_ports.h .................... */ .................... .................... //#ifndef IR_PORTS_H .................... //#define IR_PORTS_H .................... .................... #define LED1 PIN_D5 .................... #define LED2 PIN_D6 .................... #define LED3 PIN_D7 .................... #define SS_PIC PIN_A5 .................... #define LED_ON(x) output_high(x) .................... #define LED_OFF(x) output_low(x) .................... #define SPI_NUM_BYTES 10 .................... #define SPI_START_TOKEN 0b10110000 .................... #define SPI_END_TOKEN 0x44 .................... .................... typedef struct spi_struct { .................... int rx_flag; .................... int tx_flag; .................... int rx_numBytes; .................... int tx_numBytes; .................... int rx_counter; .................... int tx_counter; .................... int rx_byte; .................... int tx_byte; .................... int rx_len; .................... int tx_len; .................... int rx_buffer[SPI_NUM_BYTES]; .................... int tx_buffer[SPI_NUM_BYTES]; .................... .................... } spi_struct_t; .................... .................... void init_ir_ports(void); .................... void process_ir_ports(void); .................... void write_can_to_spi_transmit(void); .................... void update_atx_id(void); .................... void reset_atx_id(void); .................... .................... .................... //#endif .................... .................... .................... spi_struct_t spi_temp, *spi = &spi_temp; .................... /* .................... void init_ir_ports(void){ .................... .................... set_tris_A(0b00100000); .................... spi->tx_byte = 0x45; .................... for (spi->i=0;spi->i<16;spi->i++){ .................... spi->tx_buffer[spi->i] = 0x45; .................... } .................... } .................... */ .................... void process_ir_ports(void){ .................... /* .................... This processes the spi communications between the pic and atx. .................... - Values are returned to the spi struct .................... - Success of the 'Transmit' and 'Receive' is order dependent, .................... so don't change the order of the logic .................... */ .................... uint8 send_byte = 0x00; * 0C7A: MOVLB 1 0C7C: CLRF x2F .................... uint8 receive_byte = 0x00; 0C7E: CLRF x30 .................... .................... /* Transmit */ .................... /* ------------------------------------------------------ */ .................... if (spi->tx_flag == 0){ 0C80: MOVLW 01 0C82: MOVLB 0 0C84: ADDWF xFB,W 0C86: MOVWF FE9 0C88: MOVLW 00 0C8A: ADDWFC xFC,W 0C8C: MOVWF FEA 0C8E: MOVF FEF,F 0C90: BNZ 0CA8 .................... spi->tx_counter = 0; 0C92: MOVLW 05 0C94: ADDWF xFB,W 0C96: MOVWF FE9 0C98: MOVLW 00 0C9A: ADDWFC xFC,W 0C9C: MOVWF FEA 0C9E: CLRF FEF .................... send_byte = 0x00; 0CA0: MOVLB 1 0CA2: CLRF x2F .................... }else{ 0CA4: BRA 0DCE 0CA6: MOVLB 0 .................... if (spi->tx_counter == (spi->tx_len+4)){ 0CA8: MOVLW 05 0CAA: ADDWF xFB,W 0CAC: MOVWF FE9 0CAE: MOVLW 00 0CB0: ADDWFC xFC,W 0CB2: MOVWF FEA 0CB4: MOVFF FEF,131 0CB8: MOVLW 09 0CBA: ADDWF xFB,W 0CBC: MOVWF FE9 0CBE: MOVLW 00 0CC0: ADDWFC xFC,W 0CC2: MOVWF FEA 0CC4: MOVLW 04 0CC6: ADDWF FEF,W 0CC8: MOVLB 1 0CCA: SUBWF x31,W 0CCC: BNZ 0CDE .................... spi->tx_counter = 0; 0CCE: MOVLW 05 0CD0: MOVLB 0 0CD2: ADDWF xFB,W 0CD4: MOVWF FE9 0CD6: MOVLW 00 0CD8: ADDWFC xFC,W 0CDA: MOVWF FEA 0CDC: CLRF FEF .................... } .................... if (spi->tx_counter == (spi->tx_len+3)){ 0CDE: MOVLW 05 0CE0: MOVLB 0 0CE2: ADDWF xFB,W 0CE4: MOVWF FE9 0CE6: MOVLW 00 0CE8: ADDWFC xFC,W 0CEA: MOVWF FEA 0CEC: MOVFF FEF,131 0CF0: MOVLW 09 0CF2: ADDWF xFB,W 0CF4: MOVWF FE9 0CF6: MOVLW 00 0CF8: ADDWFC xFC,W 0CFA: MOVWF FEA 0CFC: MOVLW 03 0CFE: ADDWF FEF,W 0D00: MOVLB 1 0D02: SUBWF x31,W 0D04: BNZ 0D1A .................... send_byte = SPI_END_TOKEN; 0D06: MOVLW 44 0D08: MOVWF x2F .................... spi->tx_flag = 0; 0D0A: MOVLW 01 0D0C: MOVLB 0 0D0E: ADDWF xFB,W 0D10: MOVWF FE9 0D12: MOVLW 00 0D14: ADDWFC xFC,W 0D16: MOVWF FEA 0D18: CLRF FEF .................... } .................... if (spi->tx_counter<(spi->tx_len+3) && spi->tx_counter>0){ 0D1A: MOVLW 05 0D1C: MOVLB 0 0D1E: ADDWF xFB,W 0D20: MOVWF FE9 0D22: MOVLW 00 0D24: ADDWFC xFC,W 0D26: MOVWF FEA 0D28: MOVFF FEF,131 0D2C: MOVLW 09 0D2E: ADDWF xFB,W 0D30: MOVWF FE9 0D32: MOVLW 00 0D34: ADDWFC xFC,W 0D36: MOVWF FEA 0D38: MOVLW 03 0D3A: ADDWF FEF,W 0D3C: MOVLB 1 0D3E: SUBWF x31,W 0D40: BC 0D96 0D42: MOVLW 05 0D44: MOVLB 0 0D46: ADDWF xFB,W 0D48: MOVWF FE9 0D4A: MOVLW 00 0D4C: ADDWFC xFC,W 0D4E: MOVWF FEA 0D50: MOVF FEF,F 0D52: BTFSS FD8.2 0D54: BRA 0D5A 0D56: MOVLB 1 0D58: BRA 0D96 .................... send_byte = spi->tx_buffer[(spi->tx_counter)-1]; 0D5A: MOVLW 05 0D5C: ADDWF xFB,W 0D5E: MOVWF FE9 0D60: MOVLW 00 0D62: ADDWFC xFC,W 0D64: MOVWF FEA 0D66: MOVLW 01 0D68: SUBWF FEF,W 0D6A: CLRF 03 0D6C: ADDLW 14 0D6E: MOVWF 01 0D70: MOVLW 00 0D72: ADDWFC 03,F 0D74: MOVF 01,W 0D76: ADDWF xFB,W 0D78: MOVWF FE9 0D7A: MOVF xFC,W 0D7C: ADDWFC 03,W 0D7E: MOVWF FEA 0D80: MOVFF FEF,12F 0D84: MOVLB 1 .................... spi->tx_counter++; 0D86: MOVLW 05 0D88: MOVLB 0 0D8A: ADDWF xFB,W 0D8C: MOVWF FE9 0D8E: MOVLW 00 0D90: ADDWFC xFC,W 0D92: MOVWF FEA 0D94: INCF FEF,F .................... } .................... if (spi->tx_counter == 0){ 0D96: MOVLW 05 0D98: MOVLB 0 0D9A: ADDWF xFB,W 0D9C: MOVWF FE9 0D9E: MOVLW 00 0DA0: ADDWFC xFC,W 0DA2: MOVWF FEA 0DA4: MOVF FEF,F 0DA6: BNZ 0DCC .................... send_byte = SPI_START_TOKEN | spi->tx_len; 0DA8: MOVLW 09 0DAA: ADDWF xFB,W 0DAC: MOVWF FE9 0DAE: MOVLW 00 0DB0: ADDWFC xFC,W 0DB2: MOVWF FEA 0DB4: MOVF FEF,W 0DB6: IORLW B0 0DB8: MOVLB 1 0DBA: MOVWF x2F .................... spi->tx_counter++; 0DBC: MOVLW 05 0DBE: MOVLB 0 0DC0: ADDWF xFB,W 0DC2: MOVWF FE9 0DC4: MOVLW 00 0DC6: ADDWFC xFC,W 0DC8: MOVWF FEA 0DCA: INCF FEF,F 0DCC: MOVLB 1 .................... } .................... } .................... /* ------------------------------------------------------ */ .................... /* For PIC */ .................... receive_byte = spi_xfer(send_byte); 0DCE: MOVFF 12F,131 0DD2: MOVLW 08 0DD4: MOVWF x32 0DD6: MOVLB 0 0DD8: BRA 0C34 0DDA: MOVF 01,W 0DDC: MOVFF 01,130 .................... .................... /* For atxmega */ .................... /*SPI_SlaveWriteByte(&spiSlaveC, send_byte); .................... receive_byte = SPI_SlaveReadByte(&spiSlaveC); */ .................... /* ------------------------------------------------------ */ .................... /* Receive */ .................... spi->rx_flag = 0; 0DE0: MOVFF FB,FE9 0DE4: MOVFF FC,FEA 0DE8: CLRF FEF .................... if (spi->rx_counter == (spi->rx_len+4)){ 0DEA: MOVLW 04 0DEC: ADDWF xFB,W 0DEE: MOVWF FE9 0DF0: MOVLW 00 0DF2: ADDWFC xFC,W 0DF4: MOVWF FEA 0DF6: MOVFF FEF,131 0DFA: MOVLW 08 0DFC: ADDWF xFB,W 0DFE: MOVWF FE9 0E00: MOVLW 00 0E02: ADDWFC xFC,W 0E04: MOVWF FEA 0E06: MOVLW 04 0E08: ADDWF FEF,W 0E0A: MOVLB 1 0E0C: SUBWF x31,W 0E0E: BNZ 0E20 .................... spi->rx_counter = 0; 0E10: MOVLW 04 0E12: MOVLB 0 0E14: ADDWF xFB,W 0E16: MOVWF FE9 0E18: MOVLW 00 0E1A: ADDWFC xFC,W 0E1C: MOVWF FEA 0E1E: CLRF FEF .................... } .................... if (spi->rx_counter == (spi->rx_len+3)){ 0E20: MOVLW 04 0E22: MOVLB 0 0E24: ADDWF xFB,W 0E26: MOVWF FE9 0E28: MOVLW 00 0E2A: ADDWFC xFC,W 0E2C: MOVWF FEA 0E2E: MOVFF FEF,131 0E32: MOVLW 08 0E34: ADDWF xFB,W 0E36: MOVWF FE9 0E38: MOVLW 00 0E3A: ADDWFC xFC,W 0E3C: MOVWF FEA 0E3E: MOVLW 03 0E40: ADDWF FEF,W 0E42: MOVLB 1 0E44: SUBWF x31,W 0E46: BNZ 0E7E .................... if (receive_byte == SPI_END_TOKEN){ 0E48: MOVF x30,W 0E4A: SUBLW 44 0E4C: BNZ 0E6E .................... spi->rx_flag = 1; 0E4E: MOVLB 0 0E50: MOVFF FB,FE9 0E54: MOVFF FC,FEA 0E58: MOVLW 01 0E5A: MOVWF FEF .................... spi->rx_counter++; 0E5C: MOVLW 04 0E5E: ADDWF xFB,W 0E60: MOVWF FE9 0E62: MOVLW 00 0E64: ADDWFC xFC,W 0E66: MOVWF FEA 0E68: INCF FEF,F .................... }else{ 0E6A: BRA 0E7E 0E6C: MOVLB 1 .................... spi->rx_counter = 0; 0E6E: MOVLW 04 0E70: MOVLB 0 0E72: ADDWF xFB,W 0E74: MOVWF FE9 0E76: MOVLW 00 0E78: ADDWFC xFC,W 0E7A: MOVWF FEA 0E7C: CLRF FEF .................... } .................... } .................... if (spi->rx_counter<(spi->rx_len+3) && spi->rx_counter>0){ 0E7E: MOVLW 04 0E80: MOVLB 0 0E82: ADDWF xFB,W 0E84: MOVWF FE9 0E86: MOVLW 00 0E88: ADDWFC xFC,W 0E8A: MOVWF FEA 0E8C: MOVFF FEF,131 0E90: MOVLW 08 0E92: ADDWF xFB,W 0E94: MOVWF FE9 0E96: MOVLW 00 0E98: ADDWFC xFC,W 0E9A: MOVWF FEA 0E9C: MOVLW 03 0E9E: ADDWF FEF,W 0EA0: MOVLB 1 0EA2: SUBWF x31,W 0EA4: BC 0EF6 0EA6: MOVLW 04 0EA8: MOVLB 0 0EAA: ADDWF xFB,W 0EAC: MOVWF FE9 0EAE: MOVLW 00 0EB0: ADDWFC xFC,W 0EB2: MOVWF FEA 0EB4: MOVF FEF,F 0EB6: BTFSS FD8.2 0EB8: BRA 0EBE 0EBA: MOVLB 1 0EBC: BRA 0EF6 .................... spi->rx_buffer[(spi->rx_counter)-1] = receive_byte; 0EBE: MOVLW 04 0EC0: ADDWF xFB,W 0EC2: MOVWF FE9 0EC4: MOVLW 00 0EC6: ADDWFC xFC,W 0EC8: MOVWF FEA 0ECA: MOVLW 01 0ECC: SUBWF FEF,W 0ECE: CLRF 03 0ED0: ADDLW 0A 0ED2: MOVWF 01 0ED4: MOVLW 00 0ED6: ADDWFC 03,F 0ED8: MOVF 01,W 0EDA: ADDWF xFB,W 0EDC: MOVWF FE9 0EDE: MOVF xFC,W 0EE0: ADDWFC 03,W 0EE2: MOVWF FEA 0EE4: MOVFF 130,FEF .................... spi->rx_counter++; 0EE8: MOVLW 04 0EEA: ADDWF xFB,W 0EEC: MOVWF FE9 0EEE: MOVLW 00 0EF0: ADDWFC xFC,W 0EF2: MOVWF FEA 0EF4: INCF FEF,F .................... } .................... if (spi->rx_counter == 0){ 0EF6: MOVLW 04 0EF8: MOVLB 0 0EFA: ADDWF xFB,W 0EFC: MOVWF FE9 0EFE: MOVLW 00 0F00: ADDWFC xFC,W 0F02: MOVWF FEA 0F04: MOVF FEF,F 0F06: BNZ 0F4C .................... if ((receive_byte & 0b11110000) == SPI_START_TOKEN){ 0F08: MOVLB 1 0F0A: MOVF x30,W 0F0C: ANDLW F0 0F0E: SUBLW B0 0F10: BNZ 0F3C .................... spi->rx_len = (receive_byte & 0b00001111); 0F12: MOVLW 08 0F14: MOVLB 0 0F16: ADDWF xFB,W 0F18: MOVWF FE9 0F1A: MOVLW 00 0F1C: ADDWFC xFC,W 0F1E: MOVWF FEA 0F20: MOVLB 1 0F22: MOVF x30,W 0F24: ANDLW 0F 0F26: MOVWF FEF .................... spi->rx_counter++; 0F28: MOVLW 04 0F2A: MOVLB 0 0F2C: ADDWF xFB,W 0F2E: MOVWF FE9 0F30: MOVLW 00 0F32: ADDWFC xFC,W 0F34: MOVWF FEA 0F36: INCF FEF,F .................... }else{ 0F38: BRA 0F4C 0F3A: MOVLB 1 .................... spi->rx_counter = 0; 0F3C: MOVLW 04 0F3E: MOVLB 0 0F40: ADDWF xFB,W 0F42: MOVWF FE9 0F44: MOVLW 00 0F46: ADDWFC xFC,W 0F48: MOVWF FEA 0F4A: CLRF FEF .................... } .................... } .................... /* ------------------------------------------------------ */ .................... return; .................... } 0F4C: GOTO 129C (RETURN) .................... .................... .................... .................... .................... // Design Rationale: .................... // .................... // This code takes care of the Robotics Bus. The Robotics Bus is a modular .................... // system that facilitates interoperation of many devices in a mobile robot. .................... // .................... // Because bus communication is never going to be instantaneous, this code .................... // does not use interrupts. It is assumed that the application may use .................... // interrupts to perform its work. This code will not interfere with those .................... // interrupts. .................... // .................... // This bus does its work when URB_Process_Stack() is called from main(). .................... // URB_Process_Stack() should be called at least every millisecond. .................... // .................... // Timers .................... // .................... // The Robotics Bus system controls Timer0. At least one timer is needed for .................... // generating a regular heartbeat. The other timers are available for use by .................... // the application. .................... // .................... // CAN Buffers. .................... // .................... // The PIC CAN controller has two recieve buffers and three transmit buffers. .................... .................... // Macro for inquiring the operational state of the node. true=running. false=stopped. .................... #define URBOperational() (URBhb.buf[0] == URB_HEARTBEAT_NORMAL) .................... .................... .................... .................... .................... // Initialize. called by RB_App_ResetApp from main(). .................... // Also may be called by the main loop (RB_ProcessStack). .................... // Initializes the CAN hardware and RB variables. .................... .................... void RB_Initialize() { .................... .................... // Set up a heartbeat timer. .................... // Read config info from EEPROM. If NID=0 then set "factory defaults." .................... // Set up heartbeat message in URBhb buffer. .................... // Initialize the CAN controller. .................... // Set up filters. .................... // Set Process Message Identifiers. .................... // Initialize the counters. .................... .................... setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); * 19A4: MOVLW 87 19A6: MOVWF FD5 .................... .................... RB_setup_CAN(); 19A8: BRA 181C .................... .................... //enable_interrupts(GLOBAL); // start the application running .................... .................... } // end of URBInitialize 19AA: GOTO 1D24 (RETURN) .................... .................... .................... // Get default identifiers out of the object dictionary, .................... // put them into the EEPROM for future use/modification. .................... // if a PM is not used, set its identifier to zero, so that .................... // its mask/filter is set harmlessly to zero. .................... // NOTE: THIS IS ONLY RUN ONCE AFTER WIPING THE ROM ! .................... // routine initialization is handled in RB_initialize() .................... void RB_PM_SetDefaults(void) { .................... int8 entry_num; .................... int16 tmpIdent = 0; * 0530: MOVLB 1 0532: CLRF x2D 0534: CLRF x2E .................... .................... // RX PROCESS MESSAGES .................... .................... if (OD_lookup(0x1600, entry_num)) // if the PM exists, 0536: MOVLW 16 0538: MOVWF x39 053A: CLRF x38 * 05DE: MOVF 01,F 05E0: BZ 05EC .................... tmpIdent = RB_RXMAPPING_0_DEFAULT; 05E2: MOVLW 01 05E4: MOVWF x2E 05E6: MOVLW 22 05E8: MOVWF x2D .................... else 05EA: BRA 05F0 .................... tmpIdent=0; 05EC: CLRF x2E 05EE: CLRF x2D .................... RB_RXCONFIG_0 = tmpIdent; 05F0: MOVFF 12E,4E 05F4: MOVFF 12D,4D .................... .................... if (OD_lookup(0x1601, entry_num)) // if the PM exists, 05F8: MOVLW 16 05FA: MOVWF x39 05FC: MOVLW 01 05FE: MOVWF x38 * 06A2: MOVF 01,F 06A4: BZ 06AC .................... tmpIdent = RB_RXMAPPING_1_DEFAULT; 06A6: CLRF x2E 06A8: CLRF x2D .................... else 06AA: BRA 06B0 .................... tmpIdent=0; 06AC: CLRF x2E 06AE: CLRF x2D .................... RB_RXCONFIG_1 = tmpIdent; 06B0: MOVFF 12E,50 06B4: MOVFF 12D,4F .................... .................... if (OD_lookup(0x1602, entry_num)) // if the PM exists, 06B8: MOVLW 16 06BA: MOVWF x39 06BC: MOVLW 02 06BE: MOVWF x38 * 0762: MOVF 01,F 0764: BZ 076C .................... tmpIdent = RB_RXMAPPING_2_DEFAULT; 0766: CLRF x2E 0768: CLRF x2D .................... else 076A: BRA 0770 .................... tmpIdent=0; 076C: CLRF x2E 076E: CLRF x2D .................... RB_RXCONFIG_2 = tmpIdent; 0770: MOVFF 12E,C2 0774: MOVFF 12D,C1 .................... .................... if (OD_lookup(0x1603, entry_num)) // if the PM exists, 0778: MOVLW 16 077A: MOVWF x39 077C: MOVLW 03 077E: MOVWF x38 * 0822: MOVF 01,F 0824: BZ 082C .................... tmpIdent = RB_RXMAPPING_3_DEFAULT; 0826: CLRF x2E 0828: CLRF x2D .................... else 082A: BRA 0830 .................... tmpIdent=0; 082C: CLRF x2E 082E: CLRF x2D .................... RB_RXCONFIG_3 = tmpIdent; 0830: MOVFF 12E,C4 0834: MOVFF 12D,C3 .................... .................... // TX PROCESS MESSAGES .................... .................... if (OD_lookup(0x1A00, entry_num)) 0838: MOVLW 1A 083A: MOVWF x39 083C: CLRF x38 * 08E0: MOVF 01,F 08E2: BZ 08EE .................... tmpIdent = RB_TXMAPPING_0_DEFAULT; 08E4: MOVLW 02 08E6: MOVWF x2E 08E8: MOVLW 22 08EA: MOVWF x2D .................... else 08EC: BRA 08F2 .................... tmpIdent=0; 08EE: CLRF x2E 08F0: CLRF x2D .................... RB_TXCONFIG_0 = tmpIdent; 08F2: MOVFF 12E,C6 08F6: MOVFF 12D,C5 .................... .................... if (OD_lookup(0x1A01, entry_num)) 08FA: MOVLW 1A 08FC: MOVWF x39 08FE: MOVLW 01 0900: MOVWF x38 * 09A8: MOVF 01,F 09AA: BZ 09B2 .................... tmpIdent = RB_TXMAPPING_1_DEFAULT; 09AC: CLRF x2E 09AE: CLRF x2D .................... else 09B0: BRA 09B6 .................... tmpIdent=0; 09B2: CLRF x2E 09B4: CLRF x2D .................... RB_TXCONFIG_1 = tmpIdent; 09B6: MOVFF 12E,C8 09BA: MOVFF 12D,C7 .................... .................... if (OD_lookup(0x1A02, entry_num)) 09BE: MOVLW 1A 09C0: MOVWF x39 09C2: MOVLW 02 09C4: MOVWF x38 * 0A6C: MOVF 01,F 0A6E: BZ 0A76 .................... tmpIdent = RB_TXMAPPING_2_DEFAULT; 0A70: CLRF x2E 0A72: CLRF x2D .................... else 0A74: BRA 0A7A .................... tmpIdent=0; 0A76: CLRF x2E 0A78: CLRF x2D .................... RB_TXCONFIG_2 = tmpIdent; 0A7A: MOVFF 12E,CA 0A7E: MOVFF 12D,C9 .................... .................... if (OD_lookup(0x1A03, entry_num)) 0A82: MOVLW 1A 0A84: MOVWF x39 0A86: MOVLW 03 0A88: MOVWF x38 * 0B30: MOVF 01,F 0B32: BZ 0B3A .................... tmpIdent = RB_TXMAPPING_3_DEFAULT; 0B34: CLRF x2E 0B36: CLRF x2D .................... else 0B38: BRA 0B3E .................... tmpIdent=0; 0B3A: CLRF x2E 0B3C: CLRF x2D .................... RB_TXCONFIG_3 = tmpIdent; 0B3E: MOVFF 12E,CC 0B42: MOVFF 12D,CB .................... // need to automate this and do it for all four Tx/Rx .................... } 0B46: MOVLB 0 0B48: GOTO 152A (RETURN) .................... .................... .................... void RB_Send_PM(byte myBufNum) .................... { .................... if (URBOperational()) // send TPDO only if the node is operational * 2094: MOVF 35,W 2096: SUBLW 05 2098: BTFSS FD8.2 209A: BRA 2420 .................... { .................... uint8 numMappings, mapCount, type; .................... .................... numMappings = RB_Get_Tx_Mapping_Length(myBufNum); 209C: MOVFF 12A,13E 20A0: RCALL 1E1A 20A2: MOVFF 01,12B .................... RBtPM[myBufNum].len=0; 20A6: MOVLB 1 20A8: MOVF x2A,W 20AA: MULLW 0B 20AC: MOVF FF3,W 20AE: CLRF x2F 20B0: MOVWF x2E 20B2: MOVLW 02 20B4: ADDWF x2E,W 20B6: MOVWF 01 20B8: MOVLW 00 20BA: ADDWFC x2F,W 20BC: MOVWF 03 20BE: MOVF 01,W 20C0: ADDLW 5E 20C2: MOVWF FE9 20C4: MOVLW 00 20C6: ADDWFC 03,W 20C8: MOVWF FEA 20CA: CLRF FEF .................... .................... for (mapCount=0; mapCount=0xF7) // send label string 2EA0: BRA 3204 2EA2: MOVLB 1 2EA4: MOVF x33,W 2EA6: SUBLW F6 2EA8: BC 2F38 .................... { .................... int i; .................... int s; .................... // handle label string read as a special case. .................... URBTxSDO.len = 8; // use all four data bytes for chars 2EAA: MOVLW 08 2EAC: MOVLB 0 2EAE: MOVWF xB8 .................... s = 4*(subindex-0xF7); 2EB0: MOVLW F7 2EB2: MOVLB 1 2EB4: SUBWF x33,W 2EB6: MULLW 04 2EB8: MOVFF FF3,137 .................... // load the string characters into the outgoing message .................... for (i=4;i<8;i++) 2EBC: MOVLW 04 2EBE: MOVWF x36 2EC0: MOVF x36,W 2EC2: SUBLW 07 2EC4: BNC 2F2E .................... { .................... URBTxSDO.buf[i] = objectDictionary[entry_num].name[s]; 2EC6: CLRF 03 2EC8: MOVF x36,W 2ECA: ADDLW 03 2ECC: MOVWF 01 2ECE: MOVLW 00 2ED0: ADDWFC 03,F 2ED2: MOVF 01,W 2ED4: ADDLW B6 2ED6: MOVWF FE9 2ED8: MOVLW 00 2EDA: ADDWFC 03,W 2EDC: MOVWF FEA 2EDE: CLRF x43 2EE0: MOVFF 12E,142 2EE4: CLRF x45 2EE6: MOVLW 28 2EE8: MOVWF x44 2EEA: MOVLB 0 2EEC: CALL 050E 2EF0: MOVFF 02,13B 2EF4: MOVFF 01,13A 2EF8: MOVLW 06 2EFA: MOVLB 1 2EFC: ADDWF x3A,F 2EFE: MOVLW 00 2F00: ADDWFC x3B,F 2F02: MOVF x37,W 2F04: ADDWF x3A,W 2F06: MOVWF 01 2F08: MOVLW 00 2F0A: ADDWFC x3B,W 2F0C: MOVWF 03 2F0E: MOVF 01,W 2F10: MOVFF FF2,13A 2F14: BCF FF2.7 2F16: MOVFF 03,FF7 2F1A: MOVLB 0 2F1C: CALL 0102 2F20: MOVLB 1 2F22: BTFSC x3A.7 2F24: BSF FF2.7 2F26: MOVWF FEF .................... s++; 2F28: INCF x37,F .................... } 2F2A: INCF x36,F 2F2C: BRA 2EC0 .................... URB_Send_SDO_Reply(); 2F2E: MOVLB 0 2F30: RCALL 275E .................... URBErrorCode = URB_ERROR_OK; 2F32: CLRF 48 .................... } .................... else if ((subindex == 1) && (permissions & RB_PERM_READ_BIT)) 2F34: BRA 3204 2F36: MOVLB 1 2F38: DECFSZ x33,W 2F3A: BRA 31FE 2F3C: BTFSS x32.0 2F3E: BRA 31FE .................... { .................... OD_read_data(&URBTxSDO.buf[4],entry_num,type); 2F40: CLRF x39 2F42: MOVLW BD 2F44: MOVWF x38 2F46: MOVFF 12E,13A 2F4A: MOVFF 12F,13B .................... URBTxSDO.len = 4+len; * 31EC: MOVLW 04 31EE: ADDWF x30,W 31F0: MOVLB 0 31F2: MOVWF xB8 .................... .................... URB_Send_SDO_Reply(); 31F4: CALL 275E .................... URBErrorCode = URB_ERROR_OK; 31F8: CLRF 48 .................... } .................... else 31FA: BRA 3204 31FC: MOVLB 1 .................... { .................... // else read not allowed .................... URBErrorCode = URB_ERROR_SDO_PERMISSIONS; 31FE: MOVLW AF 3200: MOVWF 48 3202: MOVLB 0 .................... } .................... } // end read command .................... else if (cmd == RB_MSG_DICT_WRITE) 3204: BRA 36CA 3206: MOVLB 1 3208: MOVF x31,W 320A: SUBLW 20 320C: BTFSS FD8.2 320E: BRA 36C4 .................... { .................... // writes are not allowed for subindices besides "1" .................... if ((permissions & RB_PERM_WRITE_BIT) && (subindex == 1)) 3210: BTFSS x32.1 3212: BRA 36BA 3214: DECFSZ x33,W 3216: BRA 36BA .................... { .................... // write allowed, so we write the value and then .................... // read it back for verification. .................... .................... // now write the data .................... OD_write_data(&data[4],entry_num,type); 3218: MOVLW 04 321A: ADDWF x2C,W 321C: MOVWF x38 321E: MOVLW 00 3220: ADDWFC x2D,W 3222: MOVWF x39 3224: MOVFF 139,13B 3228: MOVFF 138,13A 322C: MOVFF 12E,13C 3230: MOVFF 12F,13D .................... .................... // read it back to confirm .................... OD_read_data(&URBTxSDO.buf[4],entry_num,type); * 33FA: MOVLB 1 33FC: CLRF x39 33FE: MOVLW BD 3400: MOVWF x38 3402: MOVFF 12E,13A 3406: MOVFF 12F,13B .................... .................... URBTxSDO.len = 4+len; * 36A8: MOVLW 04 36AA: ADDWF x30,W 36AC: MOVLB 0 36AE: MOVWF xB8 .................... .................... URB_Send_SDO_Reply(); 36B0: CALL 275E .................... URBErrorCode = URB_ERROR_OK; 36B4: CLRF 48 .................... } .................... else 36B6: BRA 36C0 36B8: MOVLB 1 .................... { .................... // else, write not allowed .................... URBErrorCode = URB_ERROR_SDO_PERMISSIONS; 36BA: MOVLW AF 36BC: MOVWF 48 36BE: MOVLB 0 .................... } .................... } // end write command .................... else 36C0: BRA 36CA 36C2: MOVLB 1 .................... { .................... URBErrorCode = URB_ERROR_SDO_UNKNOWN_COMMAND; 36C4: MOVLW AE 36C6: MOVWF 48 36C8: MOVLB 0 .................... } // end default .................... } // end valid data length .................... } // end found index .................... else 36CA: BRA 36D2 36CC: MOVLB 1 .................... { .................... #ifdef DEBUGGING .................... printf("Index Not Found...\r\n"); .................... #endif .................... URBErrorCode = URB_ERROR_SDO_NOT_FOUND; // index not found in object dictionary 36CE: MOVLW AB 36D0: MOVWF 48 36D2: MOVLB 0 .................... } // end not found index .................... .................... } // sdoRequest 36D4: GOTO 3DAA (RETURN) .................... .................... .................... .................... // check timer, send heartbeat. return 1 if sent, else 0. .................... bool URBMaintainHeartbeat() { .................... // this way, we don't need to use interrupts, which can be used by application. .................... .................... if ( get_timer0() > URB_HEARTBEAT_INTERVAL) { * 3B88: MOVF FD6,W 3B8A: MOVFF FD7,03 3B8E: MOVLB 1 3B90: MOVWF x2C 3B92: MOVF FD7,W 3B94: MOVWF x2D 3B96: SUBLW 4B 3B98: BC 3BFE 3B9A: XORLW FF 3B9C: BNZ 3BA4 3B9E: MOVF x2C,W 3BA0: SUBLW 47 3BA2: BC 3BFE .................... output_toggle(PIN_D6); 3BA4: BCF F95.6 3BA6: BTG F8C.6 .................... // if timer0 goes past one second, .................... // send heartbeat .................... URBhb.buf[1] = TXERRCNT; 3BA8: MOVFF F76,36 .................... URBhb.buf[2] = RXERRCNT; 3BAC: MOVFF F75,37 .................... URBhb.buf[3] = URBErrorCode; 3BB0: MOVFF 48,38 .................... memcpy(&URBhb.buf[4], &actualPos,2); // include actual position 3BB4: CLRF FEA 3BB6: MOVLW 39 3BB8: MOVWF FE9 3BBA: CLRF FE2 3BBC: MOVLW CF 3BBE: MOVWF FE1 3BC0: MOVLW 02 3BC2: MOVWF 01 3BC4: MOVFF FE6,FEE 3BC8: DECFSZ 01,F 3BCA: BRA 3BC4 .................... // use lowest priority, this message is not critical, do an unconfirmed send. .................... CANSendMessage(URBhb.ID,2,URBhb.buf,URBhb.len, CAN_TX_PRIORITY_0 & CAN_TX_STD_FRAME); 3BCC: MOVFF 33,13F 3BD0: MOVFF 32,13E 3BD4: MOVLW 02 3BD6: MOVWF x40 3BD8: CLRF x42 3BDA: MOVLW 35 3BDC: MOVWF x41 3BDE: MOVFF 34,143 3BE2: MOVLW FC 3BE4: MOVWF x44 3BE6: MOVLB 0 3BE8: CALL 1068 .................... .................... // prepare for next heartbeat .................... feed_mult=1; 3BEC: CLRF xD6 3BEE: MOVLW 01 3BF0: MOVWF xD5 .................... set_timer0(0); // heartbeat interval is half of the longest period of the timer0. 3BF2: CLRF FD7 3BF4: CLRF FD6 .................... return TRUE; 3BF6: MOVWF 01 3BF8: BRA 3C06 .................... } .................... else 3BFA: BRA 3C06 3BFC: MOVLB 1 .................... return FALSE; 3BFE: MOVLW 00 3C00: MOVWF 01 3C02: MOVLB 0 3C04: BRA 3C06 .................... }// end heartbeat 3C06: GOTO 3E2A (RETURN) .................... .................... bool RB_Process_Outgoing_PM() { .................... int i; .................... for (i=0; i<4; i++) 3C0A: MOVLB 1 3C0C: CLRF x2C 3C0E: MOVF x2C,W 3C10: SUBLW 03 3C12: BNC 3CDA .................... .................... if (RBtPMready[i]) 3C14: CLRF 03 3C16: MOVF x2C,W 3C18: ADDLW 2E 3C1A: MOVWF FE9 3C1C: MOVLW 00 3C1E: ADDWFC 03,W 3C20: MOVWF FEA 3C22: MOVF FEF,F 3C24: BZ 3CD2 .................... if (CANSendMessage(RBtPM[i].ID,(i % 2),RBtPM[i].buf,RBtPM[i].len, .................... CAN_TX_PRIORITY_0 & CAN_TX_STD_FRAME & CAN_TX_NO_RTR_FRAME)) 3C26: MOVF x2C,W 3C28: MULLW 0B 3C2A: MOVF FF3,W 3C2C: CLRF x2E 3C2E: MOVWF x2D 3C30: MOVLW 5E 3C32: ADDWF x2D,W 3C34: MOVWF FE9 3C36: MOVLW 00 3C38: ADDWFC x2E,W 3C3A: MOVWF FEA 3C3C: MOVFF FEC,12E 3C40: MOVF FED,F 3C42: MOVFF FEF,12D 3C46: MOVF x2C,W 3C48: ANDLW 01 3C4A: MOVWF x2F 3C4C: MOVF x2C,W 3C4E: MULLW 0B 3C50: MOVF FF3,W 3C52: CLRF x31 3C54: MOVWF x30 3C56: MOVLW 03 3C58: ADDWF x30,W 3C5A: MOVWF 01 3C5C: MOVLW 00 3C5E: ADDWFC x31,W 3C60: MOVWF 03 3C62: MOVF 01,W 3C64: ADDLW 5E 3C66: MOVWF 01 3C68: MOVLW 00 3C6A: ADDWFC 03,F 3C6C: MOVFF 01,130 3C70: MOVFF 03,131 3C74: MOVF x2C,W 3C76: MULLW 0B 3C78: MOVF FF3,W 3C7A: CLRF x33 3C7C: MOVWF x32 3C7E: MOVLW 02 3C80: ADDWF x32,W 3C82: MOVWF 01 3C84: MOVLW 00 3C86: ADDWFC x33,W 3C88: MOVWF 03 3C8A: MOVF 01,W 3C8C: ADDLW 5E 3C8E: MOVWF FE9 3C90: MOVLW 00 3C92: ADDWFC 03,W 3C94: MOVWF FEA 3C96: MOVFF FEF,132 3C9A: MOVFF 12E,13F 3C9E: MOVFF 12D,13E 3CA2: MOVFF 12F,140 3CA6: MOVFF 131,142 3CAA: MOVFF 130,141 3CAE: MOVFF 132,143 3CB2: MOVLW FC 3CB4: MOVWF x44 3CB6: MOVLB 0 3CB8: CALL 1068 3CBC: MOVF 01,F 3CBE: BZ 3CD4 .................... // There are three tx buffers. we use buffer # (myBufNum % 2) to .................... // "randomly" select buff 1 or 0, to balance the tx load between the two. .................... // (Buff 2 is used for heartbeats and dictionary responses.) .................... RBtPMready[i] = FALSE; 3CC0: CLRF 03 3CC2: MOVLB 1 3CC4: MOVF x2C,W 3CC6: ADDLW 2E 3CC8: MOVWF FE9 3CCA: MOVLW 00 3CCC: ADDWFC 03,W 3CCE: MOVWF FEA 3CD0: CLRF FEF 3CD2: MOVLB 0 3CD4: MOVLB 1 3CD6: INCF x2C,F 3CD8: BRA 3C0E .................... .................... return 0; 3CDA: MOVLW 00 3CDC: MOVWF 01 .................... }//outgoingPM 3CDE: MOVLB 0 3CE0: GOTO 3E34 (RETURN) .................... .................... .................... /***** .................... * URB Handle Receive Process Data Object .................... * .................... * the main program has already found a match between RPDO[index] .................... * and this incoming message. All left to do is copy the bytes into the .................... * mapped objects. .................... * .................... *******/ .................... .................... void URB_Handle_rPDO(byte *data, byte myBuf) .................... { .................... CAN_MSG myMSG; .................... uint8 numMappings, mapCount, bufCount, type, index; .................... .................... numMappings = RB_Get_Rx_Mapping_Length(myBuf); * 3914: MOVFF 12E,13F 3918: CALL 278E 391C: MOVFF 01,13A .................... .................... bufCount=0; 3920: MOVLB 1 3922: CLRF x3C .................... .................... for (mapCount=0; mapCount 253)) 14EE: MOVF 4B,F 14F0: BZ 14F8 14F2: MOVF 4B,W 14F4: SUBLW FD 14F6: BC 1530 .................... { .................... write_eeprom( RB_EEPROM_NODEID, RB_NODEID_DEFAULT); 14F8: CLRF FAA 14FA: MOVLW 80 14FC: MOVWF FA9 14FE: MOVLW 22 1500: MOVWF FA8 1502: BCF FA6.6 1504: BCF FA6.7 1506: BSF FA6.2 1508: MOVFF FF2,00 150C: BCF FF2.7 150E: MOVLB F 1510: MOVLW 55 1512: MOVWF FA7 1514: MOVLW AA 1516: MOVWF FA7 1518: BSF FA6.1 151A: BTFSC FA6.1 151C: BRA 151A 151E: BCF FA6.2 1520: MOVF 00,W 1522: IORWF FF2,F .................... RB_PM_SetDefaults(); // set identifiers on Process Messages 1524: MOVLB 0 1526: GOTO 0530 .................... RB_App_SetFactoryDefaults(); 152A: GOTO 0BA4 152E: MOVLB 1 .................... } .................... RB_NODEID = read_eeprom(RB_EEPROM_NODEID); 1530: MOVFF FF2,12C 1534: BCF FF2.7 1536: CLRF FAA 1538: MOVLW 80 153A: MOVWF FA9 153C: BCF FA6.6 153E: BCF FA6.7 1540: BSF FA6.0 1542: MOVF FA8,W 1544: BTFSC x2C.7 1546: BSF FF2.7 1548: MOVWF 4B .................... .................... /* .................... Rewrite IR node ID with new value if that exists and .................... is valid. .................... */ .................... RB_IRID = read_eeprom(RB_EEPROM_IRID); 154A: MOVFF FF2,12C 154E: BCF FF2.7 1550: CLRF FAA 1552: MOVLW 81 1554: MOVWF FA9 1556: BCF FA6.6 1558: BCF FA6.7 155A: BSF FA6.0 155C: MOVF FA8,W 155E: BTFSC x2C.7 1560: BSF FF2.7 1562: MOVWF 4C .................... if ((RB_IRID == 0x00)|| (RB_IRID > 253)){ 1564: MOVF 4C,F 1566: BZ 156E 1568: MOVF 4C,W 156A: SUBLW FD 156C: BC 15A6 .................... write_eeprom(RB_EEPROM_IRID, RB_IRID_DEFAULT); 156E: CLRF FAA 1570: MOVLW 81 1572: MOVWF FA9 1574: CLRF FA8 1576: BCF FA6.6 1578: BCF FA6.7 157A: BSF FA6.2 157C: MOVFF FF2,00 1580: BCF FF2.7 1582: MOVLB F 1584: MOVLW 55 1586: MOVWF FA7 1588: MOVLW AA 158A: MOVWF FA7 158C: BSF FA6.1 158E: BTFSC FA6.1 1590: BRA 158E 1592: BCF FA6.2 1594: MOVF 00,W 1596: IORWF FF2,F .................... delay_ms(200); 1598: MOVLW C8 159A: MOVLB 1 159C: MOVWF x2E 159E: MOVLB 0 15A0: CALL 04E6 15A4: MOVLB 1 .................... } .................... RB_IRID = read_eeprom(RB_EEPROM_IRID); 15A6: MOVFF FF2,12C 15AA: BCF FF2.7 15AC: CLRF FAA 15AE: MOVLW 81 15B0: MOVWF FA9 15B2: BCF FA6.6 15B4: BCF FA6.7 15B6: BSF FA6.0 15B8: MOVF FA8,W 15BA: BTFSC x2C.7 15BC: BSF FF2.7 15BE: MOVWF 4C .................... /* Send a message to tell the atx to update its ID */ .................... update_atx_id(); 15C0: MOVLB 0 15C2: BRA 141E .................... .................... // heartbeat setup .................... URBhb.ID = RB_HEARTBEAT + (int16) RB_NODEID; 15C4: CLRF 03 15C6: MOVFF 4B,32 15CA: MOVLW 07 15CC: ADDWF 03,W 15CE: MOVWF 33 .................... URBhb.len = 6; 15D0: MOVLW 06 15D2: MOVWF 34 .................... URBhb.buf[0] = URB_HEARTBEAT_NORMAL; 15D4: MOVLW 05 15D6: MOVWF 35 .................... .................... } 15D8: GOTO 1D22 (RETURN) .................... .................... .................... void RB_setup_CAN() .................... { .................... uint8 i; .................... .................... // SJW, BRP, PHSEG1, PHSEG2, PROPSEG .................... CANInitialize(1,2,6,6,7,CAN_CONFIG_VALID_STD_MSG & CAN_CONFIG_DBL_BUFFER_ON); //works for 250kbps for 20Mhz * 181C: MOVLW 01 181E: MOVLB 1 1820: MOVWF x2D 1822: MOVLW 02 1824: MOVWF x2E 1826: MOVLW 06 1828: MOVWF x2F 182A: MOVWF x30 182C: MOVLW 07 182E: MOVWF x31 1830: MOVLW BF 1832: MOVWF x32 1834: MOVLB 0 1836: BRA 16F4 .................... // 11557 for 500kbps / 18 Mhz .................... // 12557 for 250kbps / 18 Mhz .................... // 14557 for 125kbps / 18 Mhz .................... // 15557 for 100kbps / 18 Mhz .................... // 1,10,557 for 50 kbps / 18 Mhz .................... // 1,25,557 for 20 / 18 Mhz .................... .................... // Filters will be set up with rollover from Buff0 to Buff1 enabled (the default). .................... // Receive Buffer 1, ("B1") the higher priority buffer because it can rollover to B2, .................... // will be set up to recieve only NMT messages with Node ID 0, .................... // and Dictionary Request messages addressed directly to this node. .................... // .................... // Receive Buffer 2 ("B2"), however, will catch Process Messages .................... // which have one of several Process Message IDs- which are read from EEPROM and put into the .................... // broadcast by other nodes. Because this filter can't roll over into B1, .................... // it is considered lower priority and PMs may occasionally be lost. .................... .................... CANSetOperationMode(CAN_OP_MODE_CONFIG); // must be in config mode to change masks/filters 1838: MOVLW 80 183A: MOVLB 1 183C: MOVWF x35 183E: MOVLB 0 1840: RCALL 15DC .................... .................... // Set Up B1 .................... CANSetMask(CAN_MASK_B1,CAN_MASK_ELEVEN_BITS , CAN_CONFIG_STD_MSG); // screen on the basis of all CAN-ID bits 1842: MOVLB 1 1844: CLRF x35 1846: CLRF x39 1848: CLRF x38 184A: MOVLW 07 184C: MOVWF x37 184E: MOVLW FF 1850: MOVWF x36 1852: MOVWF x3A 1854: MOVLB 0 1856: RCALL 1638 .................... CANSetFilter(CAN_FILTER_B1_F1, RB_DICT_REQ + RB_NODEID, CAN_CONFIG_STD_MSG); // allow SDO messages for own node 1858: MOVFF 4B,12D 185C: MOVLB 1 185E: MOVLW 06 1860: CLRF x35 1862: CLRF x39 1864: CLRF x38 1866: MOVWF x37 1868: MOVFF 4B,136 186C: MOVLW FF 186E: MOVWF x3A 1870: MOVLB 0 1872: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B1_F2, RB_NMT, CAN_CONFIG_STD_MSG); // also allow NMT msg with NodeID 0 (master node). 1874: MOVLW 01 1876: MOVLB 1 1878: MOVWF x35 187A: CLRF x39 187C: CLRF x38 187E: CLRF x37 1880: CLRF x36 1882: MOVLW FF 1884: MOVWF x3A 1886: MOVLB 0 1888: RCALL 1672 .................... .................... /* Check this out ... the repitition of F1 may lead to populate() errors */ .................... //CANSetFilter(CAN_FILTER_B1_F1, RB_DICT_REQ + RB_IRID, CAN_CONFIG_STD_MSG); // allow SDO messages for IR node .................... .................... .................... // Set up B2 - for incoming Rx PMs .................... CANSetMask(CAN_MASK_B2, CAN_MASK_ELEVEN_BITS, CAN_CONFIG_STD_MSG); // screen on the basis of all 11 bits 188A: MOVLW 01 188C: MOVLB 1 188E: MOVWF x35 1890: CLRF x39 1892: CLRF x38 1894: MOVLW 07 1896: MOVWF x37 1898: MOVLW FF 189A: MOVWF x36 189C: MOVWF x3A 189E: MOVLB 0 18A0: RCALL 1638 .................... // Set up B2 F2 - for incoming messages to the IR .................... .................... // Add up to four different identifiers. .................... // The number of incoming PMs is limited by the number of filters .................... // in the particular CAN controller - in this case four. .................... RB_RXCONFIG_0 = RB_NODEID + RB_COMMAND; 18A2: MOVFF 4B,4D 18A6: MOVLW 01 18A8: MOVWF 4E .................... RB_RXCONFIG_1 = RB_NODEID + RB_USART; 18AA: MOVFF 4B,4F 18AE: MOVLW 03 18B0: MOVWF 50 .................... RB_RXCONFIG_2 = RB_NULL; 18B2: CLRF xC2 18B4: CLRF xC1 .................... //RB_RXCONFIG_3 = RB_NULL; .................... .................... RBrPM[0].ID = RB_RXCONFIG_0; 18B6: MOVFF 4E,8B 18BA: MOVFF 4D,8A .................... RBrPM[1].ID = RB_RXCONFIG_1; 18BE: MOVFF 50,96 18C2: MOVFF 4F,95 .................... RBrPM[2].ID = RB_RXCONFIG_2; 18C6: MOVFF C2,A1 18CA: MOVFF C1,A0 .................... //RBrPM[3].ID = RB_RXCONFIG_3; .................... CANSetFilter(CAN_FILTER_B2_F1,RB_RXCONFIG_0, CAN_CONFIG_STD_MSG); 18CE: MOVLW 02 18D0: MOVLB 1 18D2: MOVWF x35 18D4: CLRF x39 18D6: CLRF x38 18D8: MOVFF 4E,137 18DC: MOVFF 4D,136 18E0: MOVLW FF 18E2: MOVWF x3A 18E4: MOVLB 0 18E6: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B2_F2,RB_RXCONFIG_1, CAN_CONFIG_STD_MSG); 18E8: MOVLW 03 18EA: MOVLB 1 18EC: MOVWF x35 18EE: CLRF x39 18F0: CLRF x38 18F2: MOVFF 50,137 18F6: MOVFF 4F,136 18FA: MOVLW FF 18FC: MOVWF x3A 18FE: MOVLB 0 1900: RCALL 1672 .................... CANSetFilter(CAN_FILTER_B2_F3,RB_RXCONFIG_2, CAN_CONFIG_STD_MSG); 1902: MOVLW 04 1904: MOVLB 1 1906: MOVWF x35 1908: CLRF x39 190A: CLRF x38 190C: MOVFF C2,137 1910: MOVFF C1,136 1914: MOVLW FF 1916: MOVWF x3A 1918: MOVLB 0 191A: RCALL 1672 .................... //CANSetFilter(CAN_FILTER_B2_F4,RB_RXCONFIG_3, CAN_CONFIG_STD_MSG); .................... CANSetFilter(CAN_FILTER_B2_F4, RB_DICT_REQ + RB_IRID, CAN_CONFIG_STD_MSG); // allow rx messages for IR node 191C: MOVFF 4C,12D 1920: MOVLB 1 1922: MOVLW 06 1924: MOVWF x2E 1926: MOVLW 05 1928: MOVWF x35 192A: CLRF x39 192C: CLRF x38 192E: MOVFF 12E,137 1932: MOVFF 4C,136 1936: MOVLW FF 1938: MOVWF x3A 193A: MOVLB 0 193C: RCALL 1672 .................... .................... .................... // set tPM identifiers .................... RB_TXCONFIG_0 = RB_NODEID + RB_SENSOR; 193E: MOVFF 4B,C5 1942: MOVLW 02 1944: MOVWF xC6 .................... RB_TXCONFIG_1 = 0; 1946: CLRF xC8 1948: CLRF xC7 .................... RB_TXCONFIG_2 = 0; 194A: CLRF xCA 194C: CLRF xC9 .................... RB_TXCONFIG_3 = 0; 194E: CLRF xCC 1950: CLRF xCB .................... RBtPM[0].ID = RB_TXCONFIG_0; 1952: MOVFF C6,5F 1956: MOVFF C5,5E .................... RBtPM[1].ID = RB_TXCONFIG_1; 195A: MOVFF C8,6A 195E: MOVFF C7,69 .................... RBtPM[2].ID = RB_TXCONFIG_2; 1962: MOVFF CA,75 1966: MOVFF C9,74 .................... RBtPM[3].ID = RB_TXCONFIG_3; 196A: MOVFF CC,80 196E: MOVFF CB,7F .................... CANSetOperationMode(CAN_OP_MODE_NORMAL); // turn the CAN back on after setting filters. 1972: MOVLB 1 1974: CLRF x35 1976: MOVLB 0 1978: RCALL 15DC .................... .................... for (i=0; i<4; i++) 197A: MOVLB 1 197C: CLRF x2C 197E: MOVF x2C,W 1980: SUBLW 03 1982: BNC 1998 .................... { .................... RBtPMready[i] = FALSE; // no data ready to send 1984: CLRF 03 1986: MOVF x2C,W 1988: ADDLW 2E 198A: MOVWF FE9 198C: MOVLW 00 198E: ADDWFC 03,W 1990: MOVWF FEA 1992: CLRF FEF .................... } 1994: INCF x2C,F 1996: BRA 197E .................... .................... URBRecvCounter = 0; 1998: CLRF 4A .................... URBRecvOverflowCounter = 0; 199A: CLRF 49 .................... URBErrorCode = URB_ERROR_OK; 199C: CLRF 48 .................... } 199E: MOVLB 0 19A0: GOTO 19AA (RETURN) .................... .................... .................... /***** .................... * URB Process Stack: .................... * .................... * this function should be called at least once every 1-2 msec. .................... * .................... * - generate heartbeat message .................... * .................... * - respond to NMT requests to Stop/Start .................... * .................... * - respond to SDO requests to get/set values .................... * .................... * - respond to RPDO by setting the appropriate variables. .................... * .................... *******/ .................... .................... byte RB_ProcessStack() { .................... byte ret_val = 0; // will return 1 if a message is received or sent * 3CE4: MOVLB 1 3CE6: CLRF x2A .................... byte RcvMessageFlags; .................... .................... // first, process incoming messages .................... if (CANReceiveMessage (&URBStackRcv.ID, URBStackRcv.buf,&URBStackRcv.len,&RcvMessageFlags)) 3CE8: CLRF x2D 3CEA: MOVLW 3D 3CEC: MOVWF x2C 3CEE: CLRF x2F 3CF0: MOVLW 40 3CF2: MOVWF x2E 3CF4: CLRF x31 3CF6: MOVLW 3F 3CF8: MOVWF x30 3CFA: MOVLW 01 3CFC: MOVWF x33 3CFE: MOVLW 2B 3D00: MOVWF x32 3D02: MOVLB 0 3D04: GOTO 2466 3D08: MOVF 01,F 3D0A: BTFSC FD8.2 3D0C: BRA 3E24 .................... { .................... ret_val = 1; 3D0E: MOVLW 01 3D10: MOVLB 1 3D12: MOVWF x2A .................... URBRecvCounter++; 3D14: INCF 4A,F .................... if (RcvMessageFlags & (CAN_RX_XTD_FRAME | CAN_RX_RTR_FRAME)) { // don't accept these strange things. uriah note: <- here is the error 3D16: MOVF x2B,W 3D18: ANDLW 60 3D1A: BZ 3D24 .................... URBErrorCode = (RcvMessageFlags & 0x60); // see URB.h for error codes. 3D1C: MOVF x2B,W 3D1E: ANDLW 60 3D20: MOVWF 48 .................... } .................... else { 3D22: BRA 3E26 .................... if (RcvMessageFlags & CAN_RX_OVERFLOW) { // it's not clear what this flag means, but count it. 3D24: BTFSS x2B.3 3D26: BRA 3D2A .................... URBRecvOverflowCounter++; 3D28: INCF 49,F .................... } .................... // NOW PROCESS INCOMING MESSAGE! .................... URBErrorCode = URB_RX_IN_PROCESS; 3D2A: MOVLW 34 3D2C: MOVWF 48 .................... .................... if (URBStackRcv.ID == 0) { // high-priority NMT (start/stop) message 3D2E: MOVF 3D,F 3D30: BNZ 3D78 3D32: MOVF 3E,F 3D34: BNZ 3D78 .................... if ((URBStackRcv.buf[1] == RB_NODEID) || (URBStackRcv.buf[1] == 0)) { 3D36: MOVF 4B,W 3D38: SUBWF 41,W 3D3A: BZ 3D40 3D3C: MOVF 41,F 3D3E: BNZ 3D6E .................... //if (URBStackRcv.len != 2) URBErrorCode = URB_ERROR_NMT_INVALID_LENGTH; else .................... switch (URBStackRcv.buf[0]) { 3D40: MOVF 40,W 3D42: XORLW 01 3D44: MOVLB 0 3D46: BZ 3D52 3D48: XORLW 03 3D4A: BZ 3D58 3D4C: XORLW 83 3D4E: BZ 3D5E 3D50: BRA 3D64 .................... case 1: .................... URBhb.buf[0] = URB_HEARTBEAT_NORMAL; 3D52: MOVLW 05 3D54: MOVWF 35 .................... break; // start the node running 3D56: BRA 3D6A .................... case 2: .................... URBhb.buf[0] = URB_HEARTBEAT_STOPPED; 3D58: MOVLW 04 3D5A: MOVWF 35 .................... break; // stop the node. 3D5C: BRA 3D6A .................... // preoperational state not implemented .................... case RB_NODE_RESET: .................... RB_App_ResetApp(); 3D5E: CALL 1D0A .................... break; // reset the application. 3D62: BRA 3D6A .................... default: .................... URBErrorCode = URB_ERROR_NMT_UNKNOWN_COMMAND; 3D64: MOVLW CC 3D66: MOVWF 48 .................... break; // unknown NMT command, not implemented 3D68: BRA 3D6A .................... } // end switch .................... } // end addressed to us .................... else URBErrorCode = URB_ERROR_NMT_NOT_ADDRESSED; 3D6A: BRA 3D74 3D6C: MOVLB 1 3D6E: MOVLW CD 3D70: MOVWF 48 3D72: MOVLB 0 .................... } // end NMT .................... .................... else if (URBStackRcv.ID == RB_DICT_REQ + RB_NODEID) // is it an SDO request? 3D74: BRA 3E24 3D76: MOVLB 1 3D78: MOVFF 4B,01 3D7C: MOVLW 06 3D7E: MOVWF 03 3D80: MOVF 4B,W 3D82: SUBWF 3D,W 3D84: BNZ 3DAE 3D86: MOVF 03,W 3D88: SUBWF 3E,W 3D8A: BNZ 3DAE .................... { .................... if (URBStackRcv.len > 3) 3D8C: MOVF 3F,W 3D8E: SUBLW 03 3D90: BC 3DA4 .................... URB_Handle_SDO_Request(URBStackRcv.buf); 3D92: CLRF x2D 3D94: MOVLW 40 3D96: MOVWF x2C 3D98: MOVLB 0 3D9A: GOTO 2BAA .................... else 3D9E: MOVLB 0 3DA0: BRA 3DAA 3DA2: MOVLB 1 .................... URBErrorCode = URB_ERROR_SDO_MALFORMED; 3DA4: MOVLW A9 3DA6: MOVWF 48 3DA8: MOVLB 0 .................... }//sdo .................... //start rpdo .................... else if (URBOperational()) { // if node is operational, handle PMs 3DAA: BRA 3E24 3DAC: MOVLB 1 3DAE: MOVF 35,W 3DB0: SUBLW 05 3DB2: BNZ 3E26 .................... if (URBStackRcv.ID == RBrPM[0].ID) 3DB4: MOVLB 0 3DB6: MOVF x8A,W 3DB8: SUBWF 3D,W 3DBA: BNZ 3DD2 3DBC: MOVF x8B,W 3DBE: SUBWF 3E,W 3DC0: BNZ 3DD2 .................... URB_Handle_rPDO(URBStackRcv.buf, 0); // copy bytes to rpdo 0 3DC2: MOVLB 1 3DC4: CLRF x2D 3DC6: MOVLW 40 3DC8: MOVWF x2C 3DCA: CLRF x2E 3DCC: MOVLB 0 3DCE: RCALL 3914 .................... .................... else if (URBStackRcv.ID == RBrPM[1].ID) 3DD0: BRA 3E24 3DD2: MOVF x95,W 3DD4: SUBWF 3D,W 3DD6: BNZ 3DF0 3DD8: MOVF x96,W 3DDA: SUBWF 3E,W 3DDC: BNZ 3DF0 .................... URB_Handle_rPDO(URBStackRcv.buf, 1); // copy bytes to rpdo 1 3DDE: MOVLB 1 3DE0: CLRF x2D 3DE2: MOVLW 40 3DE4: MOVWF x2C 3DE6: MOVLW 01 3DE8: MOVWF x2E 3DEA: MOVLB 0 3DEC: RCALL 3914 .................... .................... else if (URBStackRcv.ID == RBrPM[2].ID) 3DEE: BRA 3E24 3DF0: MOVF xA0,W 3DF2: SUBWF 3D,W 3DF4: BNZ 3E0E 3DF6: MOVF xA1,W 3DF8: SUBWF 3E,W 3DFA: BNZ 3E0E .................... URB_Handle_rPDO(URBStackRcv.buf, 2); // copy bytes to rpdo 2 3DFC: MOVLB 1 3DFE: CLRF x2D 3E00: MOVLW 40 3E02: MOVWF x2C 3E04: MOVLW 02 3E06: MOVWF x2E 3E08: MOVLB 0 3E0A: RCALL 3914 .................... .................... /* .................... Note: This is logic bloc replaces the RBrPM[3] logic bloc. .................... One may not have both RBrPM[3] and the IR receive since .................... the PIC is using CAN mode 0 which only provides 6 filters .................... .................... This forwards a message from PIC CAN receive to PIC SPI transmit, .................... providing that the atxmega's ID is present. .................... */ .................... else if ((URBStackRcv.ID & 0x00FF) == RB_IRID) { 3E0C: BRA 3E24 3E0E: MOVFF 3D,12C 3E12: MOVLB 1 3E14: CLRF x2D 3E16: MOVF 4C,W 3E18: SUBWF 3D,W 3E1A: BNZ 3E26 3E1C: MOVF x2D,F 3E1E: BNZ 3E26 .................... // note!!!: remember to send entire CAN message received over to SPI .................... /* Write Can message and ID into spi transmit buffer */ .................... write_can_to_spi_transmit(); 3E20: MOVLB 0 3E22: BRA 3AD0 3E24: MOVLB 1 .................... } .................... .................... /* else if (URBStackRcv.ID == RBrPM[3].ID) .................... URB_Handle_rPDO(URBStackRcv.buf, 3); // copy bytes to rpdo 3 */ .................... } // node operational, handle PMs .................... .................... } // end message is valid .................... } // end recv message .................... .................... // generate the heartbeat message (if it's time) but don't block on it .................... ret_val |= URBMaintainHeartbeat(); 3E26: MOVLB 0 3E28: BRA 3B88 3E2A: MOVF 01,W 3E2C: MOVLB 1 3E2E: IORWF x2A,F .................... .................... // check to see if there are any Process Messages queued to send. .................... ret_val |= RB_Process_Outgoing_PM(); 3E30: MOVLB 0 3E32: BRA 3C0A 3E34: MOVF 01,W 3E36: MOVLB 1 3E38: IORWF x2A,F .................... .................... return ret_val; 3E3A: MOVFF 12A,01 .................... } // end URBProcessStack 3E3E: MOVLB 0 3E40: GOTO 43C6 (RETURN) .................... .................... .................... /* Initialize communication with the atxmega */ .................... void init_ir_ports(void){ .................... int i; .................... set_tris_A(0b00100000); * 0486: MOVLW 20 0488: MOVWF F92 .................... /* Initialize Default spi tx_buffer at 0x00 */ .................... for (i=0;i<9;i++){ 048A: MOVLB 1 048C: CLRF x2A 048E: MOVF x2A,W 0490: SUBLW 08 0492: BNC 04B6 .................... spi->tx_buffer[i] = 0x00; 0494: CLRF 03 0496: MOVF x2A,W 0498: ADDLW 14 049A: MOVWF 01 049C: MOVLW 00 049E: ADDWFC 03,F 04A0: MOVF 01,W 04A2: MOVLB 0 04A4: ADDWF xFB,W 04A6: MOVWF FE9 04A8: MOVF xFC,W 04AA: ADDWFC 03,W 04AC: MOVWF FEA 04AE: CLRF FEF .................... } 04B0: MOVLB 1 04B2: INCF x2A,F 04B4: BRA 048E .................... .................... IRt.len = 8; 04B6: MOVLW 08 04B8: MOVWF 1A .................... IRr.len = 8; 04BA: MOVWF 25 .................... IRt.ID = 0; 04BC: CLRF 19 04BE: CLRF 18 .................... IRr.ID = 0; 04C0: CLRF 24 04C2: CLRF 23 .................... spi->rx_counter = 0; 04C4: MOVLW 04 04C6: MOVLB 0 04C8: ADDWF xFB,W 04CA: MOVWF FE9 04CC: MOVLW 00 04CE: ADDWFC xFC,W 04D0: MOVWF FEA 04D2: CLRF FEF .................... spi->tx_counter = 0; 04D4: MOVLW 05 04D6: ADDWF xFB,W 04D8: MOVWF FE9 04DA: MOVLW 00 04DC: ADDWFC xFC,W 04DE: MOVWF FEA 04E0: CLRF FEF .................... .................... } 04E2: GOTO 4364 (RETURN) .................... .................... .................... /* Transmit and Receive from the atxmega */ .................... void transmit_ir_to_can(void){ .................... uint8 i = 0; * 1294: MOVLB 1 1296: CLRF x2E .................... .................... /*memcpy(&IRt.buf[4], &actualPos,2); */ // include actual position .................... // use lowest priority, this message is not critical, do an unconfirmed send. .................... process_ir_ports(); 1298: MOVLB 0 129A: BRA 0C7A .................... /* update full buffer once full array is received */ .................... if (spi->rx_flag == 1){ 129C: MOVFF FB,FE9 12A0: MOVFF FC,FEA 12A4: DECFSZ FEF,W 12A6: BRA 139C .................... if (spi->rx_buffer[1] != 0x00){ 12A8: MOVLW 0B 12AA: ADDWF xFB,W 12AC: MOVWF FE9 12AE: MOVLW 00 12B0: ADDWFC xFC,W 12B2: MOVWF FEA 12B4: MOVF FEF,F 12B6: BZ 139C .................... IRt.ID = ((((int16)(spi->rx_buffer[0]))<<8) | ((int16)(spi->rx_buffer[1]))); 12B8: MOVLW 0A 12BA: ADDWF xFB,W 12BC: MOVWF FE9 12BE: MOVLW 00 12C0: ADDWFC xFC,W 12C2: MOVWF FEA 12C4: MOVF FEF,W 12C6: MOVLB 1 12C8: CLRF x30 12CA: MOVWF x2F 12CC: MOVWF x30 12CE: CLRF x2F 12D0: MOVLW 0B 12D2: MOVLB 0 12D4: ADDWF xFB,W 12D6: MOVWF FE9 12D8: MOVLW 00 12DA: ADDWFC xFC,W 12DC: MOVWF FEA 12DE: MOVF FEF,W 12E0: CLRF 03 12E2: MOVLB 1 12E4: IORWF x2F,W 12E6: MOVWF 18 12E8: MOVF 03,W 12EA: IORWF x30,W 12EC: MOVWF 19 .................... RB_IRID = spi->rx_buffer[1]; 12EE: MOVLW 0B 12F0: MOVLB 0 12F2: ADDWF xFB,W 12F4: MOVWF FE9 12F6: MOVLW 00 12F8: ADDWFC xFC,W 12FA: MOVWF FEA 12FC: MOVFF FEF,4C .................... IRt.len = spi->rx_len; 1300: MOVLW 08 1302: ADDWF xFB,W 1304: MOVWF FE9 1306: MOVLW 00 1308: ADDWFC xFC,W 130A: MOVWF FEA 130C: MOVFF FEF,1A .................... for(i=2;i<(spi->rx_len+2);i++){ 1310: MOVLW 02 1312: MOVLB 1 1314: MOVWF x2E 1316: MOVLW 08 1318: MOVLB 0 131A: ADDWF xFB,W 131C: MOVWF FE9 131E: MOVLW 00 1320: ADDWFC xFC,W 1322: MOVWF FEA 1324: MOVLW 02 1326: ADDWF FEF,W 1328: MOVLB 1 132A: SUBWF x2E,W 132C: BC 137E .................... IRt.buf[i-2] = spi->rx_buffer[i]; 132E: MOVLW 02 1330: SUBWF x2E,W 1332: CLRF 03 1334: ADDLW 03 1336: MOVWF 01 1338: MOVLW 00 133A: ADDWFC 03,F 133C: MOVF 01,W 133E: ADDLW 18 1340: MOVWF 01 1342: MOVLW 00 1344: ADDWFC 03,F 1346: MOVFF 01,12F 134A: MOVFF 03,130 134E: CLRF 03 1350: MOVF x2E,W 1352: ADDLW 0A 1354: MOVWF 01 1356: MOVLW 00 1358: ADDWFC 03,F 135A: MOVF 01,W 135C: MOVLB 0 135E: ADDWF xFB,W 1360: MOVWF FE9 1362: MOVF xFC,W 1364: ADDWFC 03,W 1366: MOVWF FEA 1368: MOVFF FEF,131 136C: MOVLB 1 136E: MOVFF 130,FEA 1372: MOVFF 12F,FE9 1376: MOVFF 131,FEF .................... } 137A: INCF x2E,F 137C: BRA 1316 .................... CANSendMessage(IRt.ID,2,IRt.buf,IRt.len, CAN_TX_PRIORITY_0 & CAN_TX_STD_FRAME); 137E: MOVFF 19,13F 1382: MOVFF 18,13E 1386: MOVLW 02 1388: MOVWF x40 138A: CLRF x42 138C: MOVLW 1B 138E: MOVWF x41 1390: MOVFF 1A,143 1394: MOVLW FC 1396: MOVWF x44 1398: MOVLB 0 139A: RCALL 1068 .................... } .................... } .................... } 139C: RETLW 00 .................... .................... .................... /* Write Can message and ID into spi transmit buffer */ .................... void write_can_to_spi_transmit(void){ .................... uint8 i; .................... /* Toggle LED for debugging coolness */ .................... output_toggle(PIN_D5); * 3AD0: BCF F95.5 3AD2: BTG F8C.5 .................... spi->tx_buffer[0] = URBStackRcv.ID>>8; 3AD4: MOVLW 14 3AD6: ADDWF xFB,W 3AD8: MOVWF FE9 3ADA: MOVLW 00 3ADC: ADDWFC xFC,W 3ADE: MOVWF FEA 3AE0: MOVF 3E,W 3AE2: MOVWF FEF .................... spi->tx_buffer[1] =(URBStackRcv.ID & 0x00FF); 3AE4: MOVLW 15 3AE6: ADDWF xFB,W 3AE8: MOVWF FE9 3AEA: MOVLW 00 3AEC: ADDWFC xFC,W 3AEE: MOVWF FEA 3AF0: MOVFF 3D,FEF .................... spi->tx_len = URBStackRcv.len; 3AF4: MOVLW 09 3AF6: ADDWF xFB,W 3AF8: MOVWF FE9 3AFA: MOVLW 00 3AFC: ADDWFC xFC,W 3AFE: MOVWF FEA 3B00: MOVFF 3F,FEF .................... for(i=2;i<(spi->tx_len+2);i++){ 3B04: MOVLW 02 3B06: MOVLB 1 3B08: MOVWF x2C 3B0A: MOVLW 09 3B0C: MOVLB 0 3B0E: ADDWF xFB,W 3B10: MOVWF FE9 3B12: MOVLW 00 3B14: ADDWFC xFC,W 3B16: MOVWF FEA 3B18: MOVLW 02 3B1A: ADDWF FEF,W 3B1C: MOVLB 1 3B1E: SUBWF x2C,W 3B20: BC 3B72 .................... spi->tx_buffer[i] = URBStackRcv.buf[i-2]; 3B22: CLRF 03 3B24: MOVF x2C,W 3B26: ADDLW 14 3B28: MOVWF 01 3B2A: MOVLW 00 3B2C: ADDWFC 03,F 3B2E: MOVF 01,W 3B30: MOVLB 0 3B32: ADDWF xFB,W 3B34: MOVWF 01 3B36: MOVF xFC,W 3B38: ADDWFC 03,F 3B3A: MOVFF 01,12D 3B3E: MOVLB 1 3B40: MOVFF 03,12E 3B44: MOVLW 02 3B46: SUBWF x2C,W 3B48: CLRF 03 3B4A: ADDLW 03 3B4C: MOVWF 01 3B4E: MOVLW 00 3B50: ADDWFC 03,F 3B52: MOVF 01,W 3B54: ADDLW 3D 3B56: MOVWF FE9 3B58: MOVLW 00 3B5A: ADDWFC 03,W 3B5C: MOVWF FEA 3B5E: MOVFF FEF,12F 3B62: MOVFF 12E,FEA 3B66: MOVFF 12D,FE9 3B6A: MOVFF 12F,FEF .................... } 3B6E: INCF x2C,F 3B70: BRA 3B0A .................... spi->tx_flag = 1; 3B72: MOVLW 01 3B74: MOVLB 0 3B76: ADDWF xFB,W 3B78: MOVWF FE9 3B7A: MOVLW 00 3B7C: ADDWFC xFC,W 3B7E: MOVWF FEA 3B80: MOVLW 01 3B82: MOVWF FEF .................... } 3B84: GOTO 3E24 (RETURN) .................... .................... /* Send a message to the atx telling it to update its ID */ .................... .................... void update_atx_id(void){ .................... uint8 i; .................... spi->tx_buffer[0] = 0x06; * 141E: MOVLW 14 1420: ADDWF xFB,W 1422: MOVWF FE9 1424: MOVLW 00 1426: ADDWFC xFC,W 1428: MOVWF FEA 142A: MOVLW 06 142C: MOVWF FEF .................... spi->tx_buffer[1] = 0x00; 142E: MOVLW 15 1430: ADDWF xFB,W 1432: MOVWF FE9 1434: MOVLW 00 1436: ADDWFC xFC,W 1438: MOVWF FEA 143A: CLRF FEF .................... spi->tx_len = 5; 143C: MOVLW 09 143E: ADDWF xFB,W 1440: MOVWF FE9 1442: MOVLW 00 1444: ADDWFC xFC,W 1446: MOVWF FEA 1448: MOVLW 05 144A: MOVWF FEF .................... spi->tx_buffer[2] = RB_MSG_DICT_WRITE; 144C: MOVLW 16 144E: ADDWF xFB,W 1450: MOVWF FE9 1452: MOVLW 00 1454: ADDWFC xFC,W 1456: MOVWF FEA 1458: MOVLW 20 145A: MOVWF FEF .................... spi->tx_buffer[3] = 0x01; 145C: MOVLW 17 145E: ADDWF xFB,W 1460: MOVWF FE9 1462: MOVLW 00 1464: ADDWFC xFC,W 1466: MOVWF FEA 1468: MOVLW 01 146A: MOVWF FEF .................... spi->tx_buffer[4] = 0x00; 146C: MOVLW 18 146E: ADDWF xFB,W 1470: MOVWF FE9 1472: MOVLW 00 1474: ADDWFC xFC,W 1476: MOVWF FEA 1478: CLRF FEF .................... spi->tx_buffer[5] = 0x10; 147A: MOVLW 19 147C: ADDWF xFB,W 147E: MOVWF FE9 1480: MOVLW 00 1482: ADDWFC xFC,W 1484: MOVWF FEA 1486: MOVLW 10 1488: MOVWF FEF .................... spi->tx_buffer[6] = RB_IRID; 148A: MOVLW 1A 148C: ADDWF xFB,W 148E: MOVWF FE9 1490: MOVLW 00 1492: ADDWFC xFC,W 1494: MOVWF FEA 1496: MOVFF 4C,FEF .................... spi->tx_flag = 1; 149A: MOVLW 01 149C: ADDWF xFB,W 149E: MOVWF FE9 14A0: MOVLW 00 14A2: ADDWFC xFC,W 14A4: MOVWF FEA 14A6: MOVLW 01 14A8: MOVWF FEF .................... .................... for (i=0; i<20; i++){ 14AA: MOVLB 1 14AC: CLRF x2C 14AE: MOVF x2C,W 14B0: SUBLW 13 14B2: BNC 14CA .................... transmit_ir_to_can(); 14B4: MOVLB 0 14B6: RCALL 1294 .................... delay_ms(20); 14B8: MOVLW 14 14BA: MOVLB 1 14BC: MOVWF x2E 14BE: MOVLB 0 14C0: CALL 04E6 .................... } 14C4: MOVLB 1 14C6: INCF x2C,F 14C8: BRA 14AE .................... reset_atx_id(); 14CA: MOVLB 0 14CC: BRA 139E .................... } 14CE: GOTO 15C4 (RETURN) .................... void reset_atx_id(void){ .................... uint8 i; .................... spi->tx_buffer[0] = 0x00; * 139E: MOVLW 14 13A0: ADDWF xFB,W 13A2: MOVWF FE9 13A4: MOVLW 00 13A6: ADDWFC xFC,W 13A8: MOVWF FEA 13AA: CLRF FEF .................... spi->tx_buffer[1] = 0x00; 13AC: MOVLW 15 13AE: ADDWF xFB,W 13B0: MOVWF FE9 13B2: MOVLW 00 13B4: ADDWFC xFC,W 13B6: MOVWF FEA 13B8: CLRF FEF .................... spi->tx_len = 2; 13BA: MOVLW 09 13BC: ADDWF xFB,W 13BE: MOVWF FE9 13C0: MOVLW 00 13C2: ADDWFC xFC,W 13C4: MOVWF FEA 13C6: MOVLW 02 13C8: MOVWF FEF .................... spi->tx_buffer[2] = 0x81; 13CA: MOVLW 16 13CC: ADDWF xFB,W 13CE: MOVWF FE9 13D0: MOVLW 00 13D2: ADDWFC xFC,W 13D4: MOVWF FEA 13D6: MOVLW 81 13D8: MOVWF FEF .................... spi->tx_buffer[3] = 0x00; 13DA: MOVLW 17 13DC: ADDWF xFB,W 13DE: MOVWF FE9 13E0: MOVLW 00 13E2: ADDWFC xFC,W 13E4: MOVWF FEA 13E6: CLRF FEF .................... spi->tx_flag = 1; 13E8: MOVLW 01 13EA: ADDWF xFB,W 13EC: MOVWF FE9 13EE: MOVLW 00 13F0: ADDWFC xFC,W 13F2: MOVWF FEA 13F4: MOVLW 01 13F6: MOVWF FEF .................... for (i=0; i<20; i++){ 13F8: MOVLB 1 13FA: CLRF x2D 13FC: MOVF x2D,W 13FE: SUBLW 13 1400: BNC 1418 .................... transmit_ir_to_can(); 1402: MOVLB 0 1404: RCALL 1294 .................... delay_ms(20); 1406: MOVLW 14 1408: MOVLB 1 140A: MOVWF x2E 140C: MOVLB 0 140E: CALL 04E6 .................... } 1412: MOVLB 1 1414: INCF x2D,F 1416: BRA 13FC .................... } 1418: MOVLB 0 141A: GOTO 14CE (RETURN) .................... .................... .................... .................... #include "hsr_serial.c" .................... // Functions related to HSR Servos .................... .................... //To use these functions properly, you need to copy and paste the code below .................... //to your "main.c" .................... /*//////////////////////////////////////// .................... .................... #include "hsr_serial.c" .................... .................... #int_rda .................... void serial_isr() .................... { .................... if(kbhit()) .................... { .................... RxData[RxCounter]=getc(); .................... RxCounter++; .................... RxCounter%=3; .................... if (RxCounter==0) .................... { .................... RxLastData[0]=RxData[0]; .................... RxLastData[1]=RxData[1]; .................... RxComplete=1; .................... } .................... else .................... { .................... RxComplete=0; .................... } .................... } .................... } .................... .................... .................... *///////////////////////////////////////// .................... #include // Special Register Locations .................... .................... .................... //register location // power-up value .................... .................... #byte PCL = 0xFF9 .................... #byte FSR0H = 0xFEA // 0x00 .................... #byte FSR0L = 0xFE9 // 0x00 .................... .................... #byte INTCON = 0xFF2 // 0x00 .................... #byte INTCON2= 0xFF1 // 0xF5 .................... #byte INTCON3= 0xFF0 // 0xC0 .................... #byte FSR0H = 0xFEA // 0x00 .................... .................... #byte STATUS = 0xFD8 // 0x00 .................... .................... #byte TMR0H = 0xFD7 // 0x00 .................... #byte TMR0L = 0xFD6 // 0x00 .................... #byte T0CON = 0xFD5 // 0xFF .................... .................... #byte TMR1H = 0xFCF // 0x00 .................... #byte TMR1L = 0xFCE // 0x00 .................... #byte T1CON = 0xFCD // 0x00 .................... .................... #byte TMR2 = 0xFCC // 0x00 .................... #byte PR2 = 0xFCB // 0xff .................... #byte T2CON = 0xFCA // 0x00 .................... .................... #byte SSPADD = 0xFC8 // 0x00 .................... #byte SSPSTAT= 0xFC7 // 0x00 .................... .................... #byte SSPCON1= 0xFC6 // 0x00 .................... #byte SSPCON2= 0xFC5 // 0x00 .................... .................... #byte TMR3H = 0xFB3 // 0x00 .................... #byte TMR3L = 0xFB2 // 0x00 .................... #byte T3CON = 0xFB1 // 0x00 .................... .................... #byte SPBRG = 0xFAF // 0x00 .................... #byte RCREG = 0xFAE // 0x00 .................... #byte TXREG = 0xFAD // 0x00 .................... #byte TXSTA = 0xFAC // 0x02 .................... #byte RCSTA = 0xFAB // 0x00 .................... .................... #byte PIR2 = 0xFA1 // 0x00 .................... #byte PIR1 = 0xF9E // 0x00 .................... #byte PIE1 = 0xF9D // 0x00 .................... .................... #byte TRISC = 0xF94 // 0xff .................... #byte TRISB = 0xF93 // 0xff .................... #byte TRISA = 0xF92 // 0x3f .................... .................... #byte PORTC = 0xF82 // 0x00 .................... #byte PORTB = 0xF81 // 0x00 .................... #byte PORTA = 0xF80 // 0x00 .................... .................... #byte SPBRG2 = 0xF6F .................... #byte RCREG2 = 0xF6E .................... #byte TXREG2 = 0xF6D .................... #byte TXSTA2 = 0xF6C .................... #byte RCSTA2 = 0xF6B .................... .................... #byte IPR1 = 0xF9F //Interrupt Priority Register .................... .................... #byte ADCON0 = 0xFC2 .................... #byte ADCON1 = 0xFC1 .................... .................... #byte BAUDCON = 0xFB8 .................... .................... // .................... //Important Register Bits .................... // .................... .................... //Interrupt Enable and Priority Bits .................... #bit GIE = INTCON.7 // global interrupt enable .................... #bit PIE = INTCON.6 // periperial interrupt enable .................... .................... .................... #bit RCIE = PIE1.5 // USART receive interrupt .................... #bit TXIE = PIE1.4 // USART transmit interrupt .................... .................... .................... #bit TXIP = IPR1.4 // Transmit Interrupt Priority Bit .................... #bit RCIP = IPR1.5 // Receive Interrupt Priority Bit .................... .................... .................... // Important USART Bits .................... #bit SPEN = RCSTA.7 // serial port enable .................... #bit SREN = RCSTA.5 // single receive enable .................... #bit CREN = RCSTA.4 // continuous receive enable .................... #bit ADDEN = RCSTA.3 // address detection .................... #bit OERR = RCSTA.1 //overrun error bit .................... .................... #bit TRMT = TXSTA.1 // Transmit Shift Status Register Bit .................... #bit BRGH = TXSTA.2 // High Baud Rate Select Bit .................... #bit TXEN = TXSTA.5 // Transmit Enable Bit .................... .................... #bit RCIF = PIR1.5 // Receive Interrupt Flag .................... #bit TXIF = PIR1.4 // Transmit Interrupt Flag .................... .................... #bit RCIDL = BAUDCON.6 //Receive Idle Status .................... .................... .................... #bit RCON_IPEN = 0xFD0.7 .................... .................... #include // Special commands and memory locations for HSR servos .................... //HSR Serial Communication .................... //Commands and Memory Locations .................... .................... #include .................... // General Project Conventions .................... /************************************************************************** .................... ROBOTICS BUS TYPE DEFINITIONS .................... ***************************************************************************/ .................... /* .................... typedef int8 bool; .................... typedef signed int8 sint8; .................... typedef signed int16 sint16; .................... typedef signed int32 sint32; .................... typedef unsigned int8 uint8; .................... typedef unsigned int16 uint16; .................... typedef unsigned int32 uint32; .................... */ .................... .................... //Commands .................... #define _HSR_ComStart 0x80 //Communication start byte .................... #define _HSR_ReadEPPROM 0xE1 // Read a specific location from EEPROM .................... #define _HSR_WriteEPPROM 0xE2 // Write a specific location from EEPROM .................... #define _HSR_ReadMemory 0xE3 // Read a specific location from memory .................... #define _HSR_WriteMemory 0xE4 // Write a specific location from memory .................... #define _HSR_ReadPosition 0xE5 // Read current servo position .................... #define _HSR_SetPosition 0xE6 // Set target position .................... #define _HSR_ReadVerID 0xE7 // Read servo version and ID .................... #define _HSR_ReadPWM 0xE8 // Read pulsewidth and Voltage .................... #define _HSR_SetSpeed 0xE9 // Set servo speed and read position .................... #define _HSR_SelectControl 0xEA // Select control parameter set .................... #define _HSR_SetGoStop 0xEB // Set go/stop .................... #define _HSR_Release 0xEF // Release .................... .................... .................... //Servo Related Variables .................... .................... uint8 _ServoID; // Servo ID .................... uint8 _ServoVersion; // Servo version .................... uint8 _ServoPosH; // Servo position high .................... uint8 _ServoPosL; // Servo position low .................... /*uint8 _ServoMinPosH; // Minimum servo position - High Byte .................... uint8 _ServoMinPosL; // Minimum servo position - Low Byte .................... uint16 _ServoMinPos = 550; // Minimum Servo Position .................... uint8 _ServoMaxPosH; // Maximum servo position - High Byte .................... uint8 _ServoMaxPosL; // Maximum servo position - Low Byte .................... uint16 _ServoMaxPos = 2350; // Maximum Servo Position .................... uint8 _ServoMidPosH; // Center servo position - High Byte .................... uint8 _ServoMidPosL; // Center servo position - Low Byte .................... uint16 _ServoMidPos = 1500; // Center Servo Position .................... uint8 _ServoSpeed; // Servo speed .................... uint8 _temp=0; // */ .................... char _RxData[3]; // Incoming data from servo .................... char _RxLastData[2]; // Last Received Complete Data .................... uint8 _RxCounter=0; // Counter for incoming data .................... short _RxComplete=0; // Incomming data is ready .................... uint8 _CheckSum; // It is used for error checking .................... uint8 _ServoPW; // Pulsewidth of PWM signal .................... uint8 _ServoVoltage; // Voltage of PWM signal .................... uint16 _Start_time; .................... uint16 _Reset_interval= URB_HEARTBEAT_INTERVAL/60; .................... .................... //Important EPPROM Locations .................... #define _HSR_EPPROM_P1H 0x00 // High byte of Proportional gain for parameter set 1 .................... #define _HSR_EPPROM_P1L 0x01 // Low byte of Proportional gain for parameter set 1 .................... #define _HSR_EPPROM_DZ1 0x02 // Dead zone for parameter set 1 .................... #define _HSR_EPPROM_P1D 0x03 // Derivative gain for parameter set 1 .................... #define _HSR_EPPROM_P2H 0x1F // High byte of Proportional gain for parameter set 1 .................... #define _HSR_EPPROM_P2L 0x20 // Low byte of Proportional gain for parameter set 1 .................... #define _HSR_EPPROM_DZ2 0x21 // Dead zone for parameter set 1 .................... #define _HSR_EPPROM_P2D 0x22 // Derivative gain for parameter set 1 .................... #define _HSR_EPPROM_P3H 0x24 // High byte of Proportional gain for parameter set 1 .................... #define _HSR_EPPROM_P3L 0x25 // Low byte of Proportional gain for parameter set 1 .................... #define _HSR_EPPROM_DZ3 0x26 // Dead zone for parameter set 1 .................... #define _HSR_EPPROM_P3D 0x27 // Derivative gain for parameter set 1 .................... #define _HSR_EPPROM_Speed 0x06 // EEPROM address for speed .................... #define _HSR_EPPROM_ID 0x29 // Servo ID .................... #define _HSR_EPPROM_MinPosH 0x09 // High byte of minimum servo position .................... #define _HSR_EPPROM_MinPosL 0x0A // Low byte of minimum servo positon .................... #define _HSR_EPPROM_MaxPosH 0x0B // High byte of maximum servo position .................... #define _HSR_EPPROM_MaxPosL 0x0C // Low byte of maximum servo positon .................... #define _HSR_EPPROM_MidPosH 0x11 // High byte of center servo position .................... #define _HSR_EPPROM_MidPosL 0x12 // Low byte of center servo positon .................... .................... //Important Memory Locations .................... //Some of them are loaded from EPPROM at power-on .................... #define _HSR_MEM_CurTargetPosL 0x06 // Low byte of current target set position .................... #define _HSR_MEM_CurTargetPosH 0x07 // High byte of current target set position .................... #define _HSR_MEM_TargetPosH 0xA5 // High byte of target position .................... #define _HSR_MEM_TargetPosL 0xA6 // Low byte of target position .................... #define _HSR_MEM_ActualPosH 0xA7 // High byte of actual position .................... #define _HSR_MEM_ActualPosL 0xA8 // Low byte of actual position .................... #define _HSR_MEM_PosErrorH 0xA9 // High byte of position error (Target Position - Actual Position) .................... #define _HSR_MEM_PosErrorL 0xAA // Low byte of position error (Target Position - Actual Position) .................... #define _HSR_MEM_GoStop 0xC9 // Go/Stop .................... #define _HSR_MEM_P1H 0x80 // High byte of Proportional gain for parameter set 1 .................... #define _HSR_MEM_P1L 0x81 // Low byte of Proportional gain for parameter set 1 .................... #define _HSR_MEM_DZ1 0x82 // Dead zone for parameter set 1 .................... #define _HSR_MEM_P1D 0x83 // Derivative gain for parameter set 1 .................... #define _HSR_MEM_Speed 0x86 // Memory address for speed .................... #define _HSR_MEM_CurSpeed 0xC3 // Current Speed setting and sometimes updated from HSR_MEM_Speed .................... #define _HSR_MEM_MinPosH 0x89 // High byte of minimum servo position .................... #define _HSR_MEM_MinPosL 0x8A // Low byte of minimum servo positon .................... #define _HSR_MEM_MaxPosH 0x8B // High byte of maximum servo position .................... #define _HSR_MEM_MaxPosL 0x8C // Low byte of maximum servo positon .................... #define _HSR_MEM_MidPosH 0x91 // High byte of center servo position .................... #define _HSR_MEM_MidPosL 0x92 // Low byte of center servo positon .................... .................... // Function Prototypes .................... void HSR_SerialInitialization(void); // Initial Serial Configuration for HSR communication .................... void HSR_Release(void); // Release Servo .................... void HSR_Release_v2(void); // Release Servo .................... uint16 HSR_ReadPosition(void); // Read Servo Position .................... void HSR_ReadPosition_v2(void); // Read Servo Position .................... short IsRxDataReady(void); // Is incoming data ready .................... void WaitRxDataReady(void); // Wait until incoming data is ready. .................... uint8 HSR_ReadEPPROM(uint8 addr); //Read a Specific EPPROM location .................... void HSR_ReadEPPROM_v2(uint8 addr); //Read a Specific EPPROM location .................... void HSR_WriteEPPROM(uint8 addr, uint8 data); //Write one byte data to the EPPROM .................... void HSR_WriteEPPROM_v2(uint8 addr, uint8 data); //Write one byte data to the EPPROM .................... uint8 HSR_ReadMemory(uint8 addr); //Read a specific memory location .................... void HSR_ReadMemory_v2(uint8 addr); //Read a specific memory location .................... void HSR_WriteMemory(uint8 addr, uint8 data); //Write Memory .................... void HSR_WriteMemory_v2(uint8 addr, uint8 data); //Write Memory .................... void HSR_SetPosition(uint8 PosH, uint8 PosL); //Set target position .................... void HSR_SetPosition(uint8 ServoID, uint8 PosH, uint8 PosL); // Set target position of a specific servo. Overloaded version .................... void HSR_SetInitialPosition(uint8 PosH, uint8 PosL); // Smooth Startup .................... void HSR_ReadVerID(void); // Read servo version and id .................... void HSR_ReadVerID_v2(void); // Read servo version and id .................... void HSR_ReadPWM(void); // Read pulsewidth and voltage .................... void HSR_ReadPWM_v2(void); // Read pulsewidth and voltage .................... void HSR_SetSpeed(uint8 ServoID, uint8 ServoSpeed);// Set the peed of a single servo using its ID and read its current position .................... void HSR_SetSpeed_v2(uint8 ServoID, uint8 ServoSpeed);// Set the peed of a single servo using its ID and read its current position .................... void HSR_SelectControl(uint8 ControlSet); // Select control parameter set .................... void HSR_SelectControl_v2(uint8 ControlSet); // Select control parameter set .................... void HSR_SetGoStop(uint8 GoStop); // Set Go/Stop .................... void HSR_SetGoStop_v2(uint8 GoStop); // Set Go/Stop .................... void HSR_SetAction(sint16 TargetAngle, uint16 ActionTime); //Set Action .................... void HSR_SetAction_v2(sint16 TargetAngle, uint16 ActionTime); //Set Action .................... uint32 HSR_SetAction_v3(sint16 TargetAngle, uint16 ActionTime);//Set Action and estimaate time of motion .................... .................... void HSR_SerialInitialization(void) .................... { .................... //Disable Transmission and Receive .................... CREN=0; * 1CFA: BCF FAB.4 .................... TXEN=0; 1CFC: BCF FAC.5 .................... .................... //Configure both transmission and receive pins as input .................... TRISC |=0b11000000; 1CFE: MOVLW C0 1D00: IORWF F94,F .................... .................... enable_interrupts(int_rda); 1D02: BSF F9D.5 .................... enable_interrupts(global); 1D04: IORWF FF2,F .................... .................... } 1D06: GOTO 1D40 (RETURN) .................... .................... //Release Servo .................... void HSR_Release(void) .................... { .................... _RxComplete=0; //The data is not available .................... .................... _CheckSum=_HSR_ComStart+_HSR_Release; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_Release,0x00,0x00,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); .................... .................... .................... } .................... .................... //Release Servo .................... void HSR_Release_v2(void) .................... { .................... .................... _CheckSum=_HSR_ComStart+_HSR_Release; * 3F60: MOVLW 6F 3F62: MOVLB 1 3F64: MOVWF x08 .................... _CheckSum=(~_CheckSum)+1; 3F66: MOVF x08,W 3F68: XORLW FF 3F6A: ADDLW 01 3F6C: MOVWF x08 .................... TXEN=1; 3F6E: BSF FAC.5 .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_Release,0x00,0x00,_CheckSum); 3F70: MOVLW 80 3F72: MOVWF x2C 3F74: MOVLB 0 3F76: CALL 1D5E 3F7A: MOVLW EF 3F7C: MOVLB 1 3F7E: MOVWF x2C 3F80: MOVLB 0 3F82: CALL 1D5E 3F86: MOVLB 1 3F88: CLRF x2C 3F8A: MOVLB 0 3F8C: CALL 1D5E 3F90: MOVLB 1 3F92: CLRF x2C 3F94: MOVLB 0 3F96: CALL 1D5E 3F9A: MOVFF 108,12C 3F9E: CALL 1D5E .................... TXEN=0; 3FA2: BCF FAC.5 .................... .................... } 3FA4: GOTO 421A (RETURN) .................... .................... //This function reads the servo position .................... uint16 HSR_ReadPosition(void) .................... { .................... _RxComplete=0; //The data is not available * 1DBE: MOVLB 1 1DC0: BCF x07.0 .................... _CheckSum=_HSR_ComStart+_HSR_ReadPosition; 1DC2: MOVLW 65 1DC4: MOVWF x08 .................... _CheckSum=(~_CheckSum)+1; 1DC6: MOVF x08,W 1DC8: XORLW FF 1DCA: ADDLW 01 1DCC: MOVWF x08 .................... .................... CREN=0; 1DCE: BCF FAB.4 .................... TXEN=1; 1DD0: BSF FAC.5 .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadPosition,0x00,0x00,_CheckSum); 1DD2: MOVLW 80 1DD4: MOVWF x2C 1DD6: MOVLB 0 1DD8: RCALL 1D5E 1DDA: MOVLW E5 1DDC: MOVLB 1 1DDE: MOVWF x2C 1DE0: MOVLB 0 1DE2: RCALL 1D5E 1DE4: MOVLB 1 1DE6: CLRF x2C 1DE8: MOVLB 0 1DEA: RCALL 1D5E 1DEC: MOVLB 1 1DEE: CLRF x2C 1DF0: MOVLB 0 1DF2: RCALL 1D5E 1DF4: MOVFF 108,12C 1DF8: RCALL 1D5E .................... CREN=1; 1DFA: BSF FAB.4 .................... TXEN=0; 1DFC: BCF FAC.5 .................... .................... WaitRxDataReady(); 1DFE: BRA 1D78 .................... _ServoPosH = _RxLastData[0]; 1E00: MOVFF 104,FF .................... _ServoPosL = _RxLastData[1]; 1E04: MOVFF 105,100 .................... .................... return(make16(_RxLastData[0],_RxLastData[1])); 1E08: MOVFF 104,03 1E0C: MOVLB 1 1E0E: MOVFF 105,01 1E12: MOVFF 104,02 .................... .................... } 1E16: MOVLB 0 1E18: RETLW 00 .................... .................... //This function only starts to reading current position of servo. .................... //User need to be check if the data is ready using variable _RxComplete .................... void HSR_ReadPosition_v2(void) .................... { .................... _RxComplete=0; //The data is not available .................... _CheckSum=_HSR_ComStart+_HSR_ReadPosition; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN=0; .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadPosition,0x00,0x00,_CheckSum); .................... CREN=1; .................... TXEN=0; .................... } .................... .................... //This function returns if incoming data is ready (1), or not (0). .................... short IsRxDataReady(void) .................... { .................... return(_RxComplete); .................... } .................... .................... //This function waits until incoming data is ready. .................... .................... void WaitRxDataReady(void) .................... { .................... _Start_time =get_timer0(); * 1D78: MOVF FD6,W 1D7A: MOVLB 1 1D7C: MOVWF x0B 1D7E: MOVFF FD7,10C .................... while(!_RxComplete) .................... { if (get_timer0()-_Start_time >_Reset_interval) 1D82: BTFSC x07.0 1D84: BRA 1DB8 1D86: MOVF FD6,W 1D88: MOVFF FD7,03 1D8C: MOVWF x2A 1D8E: MOVFF FD7,12B 1D92: MOVF x0B,W 1D94: SUBWF x2A,F 1D96: MOVF x0C,W 1D98: SUBWFB x2B,F 1D9A: MOVF x0E,W 1D9C: SUBWF x2B,W 1D9E: BNC 1DB6 1DA0: BNZ 1DA8 1DA2: MOVF x2A,W 1DA4: SUBWF x0D,W 1DA6: BC 1DB6 .................... { .................... output_low(Pin_D5); 1DA8: BCF F95.5 1DAA: BCF F8C.5 .................... output_low(Pin_D6); 1DAC: BCF F95.6 1DAE: BCF F8C.6 .................... output_low(Pin_D7); 1DB0: BCF F95.7 1DB2: BCF F8C.7 .................... break; 1DB4: BRA 1DB8 .................... } .................... } 1DB6: BRA 1D82 .................... } 1DB8: MOVLB 0 1DBA: GOTO 1E00 (RETURN) .................... .................... //Read a Specific EPPROM location .................... uint8 HSR_ReadEPPROM(uint8 addr) .................... { .................... _RxComplete=0; //The data is not available .................... _CheckSum=_HSR_ComStart+_HSR_ReadEPPROM+addr; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN=0; .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadEPPROM,addr,0x00,_CheckSum); .................... CREN=1; .................... TXEN=0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... return(_RxLastData[0]); .................... } .................... .................... //This function only starts to reading from EPPROM. .................... //User need to be check if the data is ready using variable _RxComplete .................... void HSR_ReadEPPROM_v2(uint8 addr) .................... { .................... _RxComplete=0; //The data is not available .................... _CheckSum=_HSR_ComStart+_HSR_ReadEPPROM+addr; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadEPPROM,addr,0x00,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... } .................... .................... //Write EPPROM .................... void HSR_WriteEPPROM(uint8 addr, uint8 data) .................... { .................... _RxComplete=0; //The data is not available .................... .................... _CheckSum = _HSR_ComStart + _HSR_WriteEPPROM + addr + data; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_WriteEPPROM,addr,data,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); .................... .................... } .................... .................... //Write EPPROM .................... void HSR_WriteEPPROM_v2(uint8 addr, uint8 data) .................... { .................... .................... _CheckSum = _HSR_ComStart + _HSR_WriteEPPROM + addr + data; .................... _CheckSum = (~_CheckSum) + 1; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_WriteEPPROM,addr,data,_CheckSum); .................... TXEN = 0; .................... .................... } .................... .................... //Read a Specific Memory location .................... uint8 HSR_ReadMemory(uint8 addr) .................... { .................... _RxComplete=0; //The data is not available .................... _CheckSum=_HSR_ComStart+_HSR_ReadMemory+addr; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN=0; .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadMemory,addr,0x00,_CheckSum); .................... CREN=1; .................... TXEN=0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... return(_RxLastData[0]); .................... } .................... .................... //This function only starts to reading memory. .................... //User need to be check if the data is ready using variable _RxComplete .................... void HSR_ReadMemory_v2(uint8 addr) .................... { .................... _RxComplete=0; //The data is not available .................... _CheckSum=_HSR_ComStart+_HSR_ReadMemory+addr; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN=0; .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadMemory,addr,0x00,_CheckSum); .................... CREN=1; .................... TXEN=0; .................... .................... } .................... .................... //Write Memory .................... void HSR_WriteMemory(uint8 addr, uint8 data) .................... { .................... _RxComplete=0; //The data is not available .................... .................... _CheckSum=_HSR_ComStart+_HSR_WriteMemory+addr+data; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN=0; .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_WriteMemory,addr,data,_CheckSum); .................... CREN=1; .................... TXEN=0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... .................... } .................... .................... //Write Memory .................... void HSR_WriteMemory_v2(uint8 addr, uint8 data) .................... { .................... _CheckSum=_HSR_ComStart+_HSR_WriteMemory+addr+data; * 3EBC: MOVLW 64 3EBE: MOVLB 1 3EC0: ADDWF x2A,W 3EC2: MOVWF x2C 3EC4: MOVLW 01 3EC6: MOVWF x2D 3EC8: BTFSC FD8.0 3ECA: INCF x2D,F 3ECC: MOVF x2B,W 3ECE: ADDWF x2C,W 3ED0: MOVWF x08 .................... _CheckSum=(~_CheckSum)+1; 3ED2: MOVF x08,W 3ED4: XORLW FF 3ED6: ADDLW 01 3ED8: MOVWF x08 .................... .................... TXEN=1; 3EDA: BSF FAC.5 .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_WriteMemory,addr,data,_CheckSum); 3EDC: MOVLW 80 3EDE: MOVWF x2C 3EE0: MOVLB 0 3EE2: CALL 1D5E 3EE6: MOVLW E4 3EE8: MOVLB 1 3EEA: MOVWF x2C 3EEC: MOVLB 0 3EEE: CALL 1D5E 3EF2: MOVFF 12A,12C 3EF6: CALL 1D5E 3EFA: MOVFF 12B,12C 3EFE: CALL 1D5E 3F02: MOVFF 108,12C 3F06: CALL 1D5E .................... TXEN=0; 3F0A: BCF FAC.5 .................... .................... } 3F0C: RETLW 00 .................... .................... //Set target position .................... void HSR_SetPosition(uint8 PosH, uint8 PosL) .................... { .................... .................... _CheckSum = _HSR_ComStart + _HSR_SetPosition + PosH + PosL; 3F0E: MOVLW 66 3F10: MOVLB 1 3F12: ADDWF x2A,W 3F14: MOVWF x2C 3F16: MOVLW 01 3F18: MOVWF x2D 3F1A: BTFSC FD8.0 3F1C: INCF x2D,F 3F1E: MOVF x2B,W 3F20: ADDWF x2C,W 3F22: MOVWF x08 .................... _CheckSum=(~_CheckSum)+1; 3F24: MOVF x08,W 3F26: XORLW FF 3F28: ADDLW 01 3F2A: MOVWF x08 .................... .................... TXEN=1; 3F2C: BSF FAC.5 .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SetPosition,PosH,PosL,_CheckSum); 3F2E: MOVLW 80 3F30: MOVWF x2C 3F32: MOVLB 0 3F34: CALL 1D5E 3F38: MOVLW E6 3F3A: MOVLB 1 3F3C: MOVWF x2C 3F3E: MOVLB 0 3F40: CALL 1D5E 3F44: MOVFF 12A,12C 3F48: CALL 1D5E 3F4C: MOVFF 12B,12C 3F50: CALL 1D5E 3F54: MOVFF 108,12C 3F58: CALL 1D5E .................... TXEN=0; 3F5C: BCF FAC.5 .................... .................... } 3F5E: RETLW 00 .................... .................... .................... //Overloaded Function .................... //Set target position .................... void HSR_SetPosition(uint8 ServoID, uint8 PosH, uint8 PosL) .................... { .................... .................... _CheckSum = _HSR_ComStart + ServoID + PosH + PosL; .................... _CheckSum=(~_CheckSum)+1; .................... .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,ServoID,PosH,PosL,_CheckSum); .................... TXEN=0; .................... .................... } .................... .................... //This function is used to smoothly go to a target position .................... //from limp position .................... void HSR_SetInitialPosition(uint8 PosH, uint8 PosL) .................... { .................... .................... HSR_ReadPosition_v2();//Read Current Position .................... WaitRxDataReady(); // Wait until data is receieved .................... HSR_WriteMemory(_HSR_MEM_CurTargetPosL, _ServoPosL); .................... HSR_WriteMemory(_HSR_MEM_CurTargetPosH, _ServoPosH); .................... HSR_SetPosition(PosH, PosL); .................... .................... } .................... .................... //Read Servo Version and ID .................... void HSR_ReadVerID(void) .................... { .................... .................... _RxComplete=0; //The data is not available .................... .................... _CheckSum=_HSR_ComStart+_HSR_ReadVerID; .................... _CheckSum=(~_CheckSum)+1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadVerID,0x00,0x00,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... _ServoID = _RxLastData[0]; .................... _ServoVersion = _RxLastData[1]; .................... .................... } .................... .................... //Read Servo Version and ID. .................... //The servo version and id will be available as the first and .................... //second elements of _RxLastData at the end of communication. .................... void HSR_ReadVerID_v2(void) .................... { .................... .................... _CheckSum=_HSR_ComStart+_HSR_ReadVerID; .................... _CheckSum=(~_CheckSum)+1; .................... .................... TXEN=1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadVerID,0x00,0x00,_CheckSum); .................... TXEN=0; .................... .................... } .................... .................... //Read pulsewidth and voltage .................... void HSR_ReadPWM(void) .................... { .................... .................... _RxComplete = 0; //The data is not available .................... .................... _CheckSum = _HSR_ComStart + _HSR_ReadPWM; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadPWM,0x00,0x00,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... _ServoPW = _RxLastData[0]; .................... _ServoVoltage = _RxLastData[1]; .................... .................... } .................... .................... //Read pulsewidth and voltage .................... //At te end of communication, pulsewidth and voltage will be .................... //available as the first and second elements of _RxLastData, .................... //respectively. .................... void HSR_ReadPWM_v2(void) .................... { .................... .................... _CheckSum = _HSR_ComStart + _HSR_ReadPWM; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_ReadPWM,0x00,0x00,_CheckSum); .................... TXEN = 0; .................... .................... } .................... .................... //Set the speed of a single servo using its ID .................... //and read its current position .................... void HSR_SetSpeed(uint8 ServoID, uint8 ServoSpeed) .................... { .................... .................... _RxComplete = 0; //The data is not available .................... .................... _CheckSum = _HSR_ComStart + _HSR_SetSpeed + ServoID + ServoSpeed; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SetSpeed,ServoID,ServoSpeed,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... _ServoPosH = _RxLastData[0]; .................... _ServoPosL = _RxLastData[1]; .................... .................... } .................... .................... //Set the speed of a single servo using its ID .................... //and read its current position. .................... //This function only starts the communication, .................... //you need to wait communication to end successfully. .................... //Current position will be available as _RxLastData .................... void HSR_SetSpeed_v2(uint8 ServoID, uint8 ServoSpeed) .................... { .................... .................... _CheckSum = _HSR_ComStart + _HSR_SetSpeed + ServoID + ServoSpeed; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SetSpeed,ServoID,ServoSpeed,_CheckSum); .................... TXEN = 0; .................... .................... } .................... .................... //Select Control Parameter Set .................... void HSR_SelectControl(uint8 ControlSet) .................... { .................... // Note: ControlSet must be 1-3, otherwise it will be processed as 3. .................... .................... _RxComplete = 0; //The data is not available .................... .................... _CheckSum = _HSR_ComStart + _HSR_SelectControl + ControlSet; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SelectControl,0x00,ControlSet,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... .................... } .................... .................... //Select Control Parameter Set .................... //This function only starts to communication. .................... //To make sure that communication ends succesfully, .................... //wait 3ms or call WaitRxDataReady(); .................... void HSR_SelectControl_v2(uint8 ControlSet) .................... { .................... // Note: ControlSet must be 1-3, otherwise it will be processed as 3. .................... .................... .................... _CheckSum = _HSR_ComStart + _HSR_SelectControl + ControlSet; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SelectControl,0x00,ControlSet,_CheckSum); .................... TXEN = 0; .................... .................... } .................... .................... //Set Go/Stop .................... void HSR_SetGoStop(uint8 GoStop) .................... { .................... .................... _RxComplete = 0; //The data is not available .................... .................... _CheckSum = _HSR_ComStart + _HSR_SetGoStop + GoStop; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... CREN = 0; .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SetGoStop,GoStop,0x00,_CheckSum); .................... CREN = 1; .................... TXEN = 0; .................... .................... WaitRxDataReady(); // Wait until receive is completed. .................... .................... } .................... .................... //Set Go/Stop .................... //This function only starts to communication. .................... //To make sure that communication ends succesfully, .................... //wait 3ms or call WaitRxDataReady(); .................... void HSR_SetGoStop_v2(uint8 GoStop) .................... { .................... .................... _CheckSum = _HSR_ComStart + _HSR_SetGoStop + GoStop; .................... _CheckSum = (~_CheckSum) + 1; .................... .................... TXEN = 1; .................... printf("%c%c%c%c%c",_HSR_ComStart,_HSR_SetGoStop,GoStop,0x00,_CheckSum); .................... TXEN = 0; .................... .................... } .................... .................... //Set Action .................... void HSR_SetAction(sint16 TargetAngle, uint16 ActionTime) .................... { .................... uint16 CurServoPos; .................... uint16 TargetPos; .................... uint8 TargetPosH; .................... uint8 TargetPosL; .................... uint16 ActionSpeed; .................... uint8 ActionSpeedByte; .................... CurServoPos = HSR_ReadPosition(); .................... TargetPos = TargetAngle+14500; .................... TargetPos = TargetPos/10; .................... TargetPosH = make8(TargetPos,1); .................... TargetPosL = make8(TargetPos,0); .................... ActionTime=ActionTime/10; .................... .................... if (TargetPos>CurServoPos) .................... { .................... ActionSpeed = (TargetPos-CurServoPos)/10; .................... ActionSpeed*=39; .................... ActionSpeed/=ActionTime; .................... } .................... else .................... { .................... ActionSpeed = (CurServoPos-TargetPos)/10; .................... ActionSpeed*=39; .................... ActionSpeed/=ActionTime; .................... } .................... ActionSpeedByte=make8(ActionSpeed,0); .................... output_b(ActionSpeedByte); .................... HSR_WriteMemory(_HSR_MEM_Speed, ActionSpeedByte); .................... HSR_WriteMemory(_HSR_MEM_CurSpeed, ActionSpeedByte); .................... HSR_SetPosition(TargetPosH,TargetPosL); .................... .................... } .................... .................... //Set Action .................... void HSR_SetAction_v2(sint16 TargetAngle, uint16 ActionTime) .................... { .................... uint16 CurServoPos; .................... uint16 TargetPos; .................... uint8 TargetPosH; .................... uint8 TargetPosL; .................... uint32 ActionSpeed; .................... uint8 ActionSpeedByte; .................... CurServoPos = HSR_ReadPosition(); .................... TargetPos = TargetAngle+14500; .................... TargetPos = TargetPos/10; .................... TargetPosH = make8(TargetPos,1); .................... TargetPosL = make8(TargetPos,0); .................... .................... if (TargetPos>CurServoPos) .................... { .................... ActionSpeed = (TargetPos-CurServoPos); .................... ActionSpeed*=2000; .................... ActionSpeed/=ActionTime; .................... ActionSpeed/=79; .................... } .................... else .................... { .................... ActionSpeed = (CurServoPos-TargetPos); .................... ActionSpeed*= 2000; .................... ActionSpeed/=ActionTime; .................... ActionSpeed/=79; .................... } .................... ActionSpeedByte=make8(ActionSpeed,0); .................... output_b(ActionSpeedByte); .................... HSR_WriteMemory(_HSR_MEM_Speed, ActionSpeedByte); .................... HSR_WriteMemory(_HSR_MEM_CurSpeed, ActionSpeedByte); .................... HSR_SetPosition(TargetPosH,TargetPosL); .................... .................... } .................... .................... //Set Action and estimaate time of motion .................... uint32 HSR_SetAction_v3(sint16 TargetAngle, uint16 ActionTime) .................... { .................... uint16 CurServoPos; .................... uint16 TargetPos; .................... uint8 TargetPosH; .................... uint8 TargetPosL; .................... uint32 ActionSpeed; .................... uint32 EstimatedTime; .................... uint8 ActionSpeedByte; .................... CurServoPos = HSR_ReadPosition(); .................... TargetPos = TargetAngle+14500; .................... TargetPos = TargetPos/10; .................... TargetPosH = make8(TargetPos,1); .................... TargetPosL = make8(TargetPos,0); .................... .................... if (TargetPos>CurServoPos) .................... { .................... ActionSpeed = (TargetPos-CurServoPos); .................... ActionSpeed*=2000; .................... ActionSpeed/=79; .................... EstimatedTime=ActionSpeed; .................... ActionSpeed/=ActionTime; .................... .................... } .................... else .................... { .................... ActionSpeed = (CurServoPos-TargetPos); .................... ActionSpeed*= 2000; .................... ActionSpeed/=79; .................... EstimatedTime=ActionSpeed; .................... ActionSpeed/=ActionTime; .................... } .................... ActionSpeedByte=make8(ActionSpeed,0); .................... EstimatedTime/=ActionSpeedByte; .................... output_b(ActionSpeedByte); .................... HSR_WriteMemory(_HSR_MEM_Speed, ActionSpeedByte); .................... HSR_WriteMemory(_HSR_MEM_CurSpeed, ActionSpeedByte); .................... HSR_SetPosition(TargetPosH,TargetPosL); .................... return(EstimatedTime); .................... .................... } .................... .................... .................... .................... .................... #include "RCservo.c" .................... // a set of subroutines that generates PWM signals to control RC/hobby servos. .................... .................... /* ----- revision history: .................... .................... this file has been modified and tailored for Superbot - calibration, etc. .................... we use timer3 interrupt to start the pulse, .................... and timer1 for timing the pulse duration and ending the pulse. .................... port C is where all the servo lines are output. .................... .................... 2006-08-05, Jimmy Sastra: Today I started this revision history. .................... - turned off sending PM for servo position. .................... .................... 2006-08-07, Mike Park: .................... - turned PM for servo back on. User can modulate frequency in ConfigTool or GaitComposer .................... */ .................... .................... #use FAST_IO(C) .................... .................... // FAST_IO prevents the compiler from inserting extra instructions to set TRISC. .................... // to avoid slow EEPROM reads, keep a copy of these values in RAM: .................... // to avoid needless computation, calculate these values on reset only once. .................... .................... float commandScaleFactor; .................... sint16 commandCenter, tmpAmplitude, tmps; .................... uint16 tmp; .................... uint8 s; .................... .................... void RCservo_init() { .................... /* Ignoring all servo communications .................... uint16 D16,P; .................... uint8 D,PL,PH; .................... .................... PL=HSR_ReadMemory(_HSR_MEM_P1L); .................... PH=HSR_ReadMemory(_HSR_MEM_P1H); .................... P=make16(PH,PL); .................... D=HSR_ReadMemory(_HSR_MEM_P1D); .................... D16=make16(0,D); .................... RBReadEEPROM(&tmp,SERVO_KP,2); .................... if ( tmp!=0 ) .................... {HSR_WriteMemory(_HSR_MEM_P1H,make8(tmp,1)); .................... HSR_WriteMemory(_HSR_MEM_P1L,make8(tmp,0)); .................... HSR_SelectControl(1); .................... } .................... else .................... {RBSetEEPROM(&P,SERVO_KP, 2); .................... HSR_SelectControl(3);} .................... .................... RBReadEEPROM(&tmp,SERVO_KD,2); .................... if ( tmp!=0 ) .................... {HSR_WriteMemory(_HSR_MEM_P1D,make8(tmp,0)); .................... HSR_SelectControl(1); .................... } .................... else .................... {RBSetEEPROM(&D16,SERVO_KD, 2); .................... HSR_SelectControl(3);} .................... */ .................... calMode = 0; // set normal mode * 1BE6: CLRF xD4 .................... RBReadEEPROM(&tmp,SERVO_SPEED,2); 1BE8: MOVLW 01 1BEA: MOVLB 1 1BEC: MOVWF x42 1BEE: MOVLW 19 1BF0: MOVWF x41 1BF2: MOVLW 0C 1BF4: MOVWF x43 1BF6: MOVLW 02 1BF8: MOVWF x44 1BFA: MOVLB 0 1BFC: RCALL 19AE .................... s=make8(tmp,0); 1BFE: MOVLB 1 1C00: MOVFF 119,11B .................... ServoSpeed=s; 1C04: MOVFF 11B,D3 .................... RBReadEEPROM(&commandCenter, SERVO_CAL_CMD_CENTER, 2); 1C08: MOVLW 01 1C0A: MOVWF x42 1C0C: MOVLW 13 1C0E: MOVWF x41 1C10: MOVLW 02 1C12: MOVWF x43 1C14: MOVWF x44 1C16: MOVLB 0 1C18: RCALL 19AE .................... RBReadEEPROM(&tmpAmplitude, SERVO_CAL_CMD_AMPLITUDE, 2); 1C1A: MOVLW 01 1C1C: MOVLB 1 1C1E: MOVWF x42 1C20: MOVLW 15 1C22: MOVWF x41 1C24: MOVLW 04 1C26: MOVWF x43 1C28: MOVLW 02 1C2A: MOVWF x44 1C2C: MOVLB 0 1C2E: RCALL 19AE .................... commandScaleFactor = ((float) tmpAmplitude) / ((float) 9000); 1C30: MOVFF 116,12D 1C34: MOVFF 115,12C 1C38: RCALL 19EE 1C3A: MOVFF 00,12C 1C3E: MOVFF 01,12D 1C42: MOVFF 02,12E 1C46: MOVFF 03,12F 1C4A: MOVFF 03,133 1C4E: MOVFF 02,132 1C52: MOVFF 01,131 1C56: MOVFF 00,130 1C5A: MOVLB 1 1C5C: CLRF x37 1C5E: MOVLW A0 1C60: MOVWF x36 1C62: MOVLW 0C 1C64: MOVWF x35 1C66: MOVLW 8C 1C68: MOVWF x34 1C6A: MOVLB 0 1C6C: BRA 1A3E 1C6E: MOVFF 03,112 1C72: MOVFF 02,111 1C76: MOVFF 01,110 1C7A: MOVFF 00,10F .................... RBReadEEPROM(&tmps,SERVO_START_POS, 2); 1C7E: MOVLW 01 1C80: MOVLB 1 1C82: MOVWF x42 1C84: MOVLW 17 1C86: MOVWF x41 1C88: MOVLW 0E 1C8A: MOVWF x43 1C8C: MOVLW 02 1C8E: MOVWF x44 1C90: MOVLB 0 1C92: RCALL 19AE .................... servoPosCommand=tmps; 1C94: MOVFF 118,D2 1C98: MOVFF 117,D1 .................... .................... RBReadEEPROM(&feed_freq,FEEDBACK, 2); 1C9C: MOVLB 1 1C9E: CLRF x42 1CA0: MOVLW CD 1CA2: MOVWF x41 1CA4: MOVLW 08 1CA6: MOVWF x43 1CA8: MOVLW 02 1CAA: MOVWF x44 1CAC: MOVLB 0 1CAE: RCALL 19AE .................... if ( feed_freq>0 ) 1CB0: MOVF xCD,F 1CB2: BNZ 1CB8 1CB4: MOVF xCE,F 1CB6: BZ 1CD6 .................... feed_int = URB_HEARTBEAT_INTERVAL/feed_freq; 1CB8: MOVLW 4C 1CBA: MOVLB 1 1CBC: MOVWF x2D 1CBE: MOVLW 47 1CC0: MOVWF x2C 1CC2: MOVFF CE,12F 1CC6: MOVFF CD,12E 1CCA: MOVLB 0 1CCC: BRA 1B9E 1CCE: MOVFF 02,D8 1CD2: MOVFF 01,D7 .................... .................... setup_adc_ports(AN0); 1CD6: MOVF FC1,W 1CD8: ANDLW C0 1CDA: IORLW 0E 1CDC: MOVWF FC1 .................... setup_adc(ADC_CLOCK_INTERNAL); 1CDE: MOVF FC0,W 1CE0: ANDLW C0 1CE2: IORLW 07 1CE4: MOVWF FC0 1CE6: BSF FC0.7 1CE8: BSF FC2.0 .................... set_adc_channel(0); 1CEA: MOVLW 00 1CEC: MOVWF 01 1CEE: MOVF FC2,W 1CF0: ANDLW C3 1CF2: IORWF 01,W 1CF4: MOVWF FC2 .................... } 1CF6: GOTO 1D26 (RETURN) .................... .................... .................... static sint16 TAngle = 0; //Target Position -9000 -- 9000 .................... static sint16 CAngle = 0; //Callibration Target Position -9000 -- 9000 .................... sint16 TargetPos; .................... uint8 TargetPosH; .................... uint8 TargetPosL; .................... sint16 TargetAngle; .................... uint16 Timer_100 = ((int)URB_HEARTBEAT_INTERVAL)/100; // Timer count for 60 Hz .................... .................... void initiate_pulse() { .................... .................... if (calMode) * 40DE: MOVF xD4,F 40E0: BTFSC FD8.2 40E2: BRA 41D4 .................... { .................... if (CAngle!=servoPosCommand) 40E4: MOVF xD1,W 40E6: MOVLB 1 40E8: SUBWF x1E,W 40EA: BNZ 40F6 40EC: MOVLB 0 40EE: MOVF xD2,W 40F0: MOVLB 1 40F2: SUBWF x1F,W 40F4: BZ 4186 .................... {CAngle=servoPosCommand; 40F6: MOVFF D2,11F 40FA: MOVFF D1,11E .................... if ( !( (servoPosCommand > 9000)||(servoPosCommand < -9000)) ) 40FE: MOVLB 0 4100: BTFSC xD2.7 4102: BRA 4114 4104: MOVF xD2,W 4106: SUBLW 22 4108: BC 4114 410A: XORLW FF 410C: BNZ 4184 410E: MOVF xD1,W 4110: SUBLW 28 4112: BNC 4184 4114: BTFSS xD2.7 4116: BRA 4126 4118: MOVF xD2,W 411A: SUBLW DC 411C: BNC 4126 411E: BNZ 4184 4120: MOVF xD1,W 4122: SUBLW D7 4124: BC 4184 .................... { .................... TargetAngle=servoPosCommand; 4126: MOVFF D2,125 412A: MOVFF D1,124 .................... TargetPos = TargetAngle+14500; 412E: MOVLW A4 4130: MOVLB 1 4132: ADDWF x24,W 4134: MOVWF x20 4136: MOVLW 38 4138: ADDWFC x25,W 413A: MOVWF x21 .................... TargetPos = TargetPos/10; 413C: MOVFF 121,12B 4140: MOVFF 120,12A 4144: CLRF x2D 4146: MOVLW 0A 4148: MOVWF x2C 414A: MOVLB 0 414C: RCALL 3E44 414E: MOVFF 02,121 4152: MOVFF 01,120 .................... TargetPosH = make8(TargetPos,1); 4156: MOVLB 1 4158: MOVFF 121,122 .................... TargetPosL = make8(TargetPos,0); 415C: MOVFF 120,123 .................... HSR_WriteMemory_v2(_HSR_MEM_Speed,ServoSpeed); 4160: MOVLW 86 4162: MOVWF x2A 4164: MOVFF D3,12B 4168: MOVLB 0 416A: RCALL 3EBC .................... HSR_WriteMemory_v2(_HSR_MEM_CurSpeed, ServoSpeed); 416C: MOVLW C3 416E: MOVLB 1 4170: MOVWF x2A 4172: MOVFF D3,12B 4176: MOVLB 0 4178: RCALL 3EBC .................... HSR_SetPosition(TargetPosH,TargetPosL); 417A: MOVFF 122,12A 417E: MOVFF 123,12B 4182: RCALL 3F0E 4184: MOVLB 1 .................... } .................... } .................... if(get_timer0() >= Timer_100*feed_mult) 4186: MOVF FD6,W 4188: MOVFF FD7,03 418C: MOVWF x2A 418E: MOVFF FD7,12B 4192: MOVFF 127,143 4196: MOVFF 126,142 419A: MOVFF D6,145 419E: MOVFF D5,144 41A2: MOVLB 0 41A4: CALL 050E 41A8: MOVF 02,W 41AA: MOVWF 03 41AC: MOVLB 1 41AE: SUBWF x2B,W 41B0: BNC 41D0 41B2: BNZ 41BA 41B4: MOVF 01,W 41B6: SUBWF x2A,W 41B8: BNC 41D0 .................... { raw_adc = HSR_ReadPosition(); 41BA: MOVLB 0 41BC: CALL 1DBE 41C0: MOVFF 02,DA 41C4: MOVFF 01,D9 .................... //output_toggle(PIN_D5); .................... feed_mult++; 41C8: INCF xD5,F 41CA: BTFSC FD8.2 41CC: INCF xD6,F 41CE: MOVLB 1 .................... } .................... } .................... else 41D0: BRA 42E0 41D2: MOVLB 0 .................... { .................... if (TAngle!=servoPosCommand) 41D4: MOVF xD1,W 41D6: MOVLB 1 41D8: SUBWF x1C,W 41DA: BNZ 41E8 41DC: MOVLB 0 41DE: MOVF xD2,W 41E0: MOVLB 1 41E2: SUBWF x1D,W 41E4: BTFSC FD8.2 41E6: BRA 42E0 .................... {TAngle=servoPosCommand; 41E8: MOVFF D2,11D 41EC: MOVFF D1,11C .................... if( (servoPosCommand > 9000)||(servoPosCommand < -9000)) { 41F0: MOVLB 0 41F2: BTFSC xD2.7 41F4: BRA 4206 41F6: MOVF xD2,W 41F8: SUBLW 22 41FA: BC 4206 41FC: XORLW FF 41FE: BNZ 4218 4200: MOVF xD1,W 4202: SUBLW 28 4204: BNC 4218 4206: BTFSS xD2.7 4208: BRA 4228 420A: MOVF xD2,W 420C: SUBLW DC 420E: BNC 4228 4210: BNZ 4218 4212: MOVF xD1,W 4214: SUBLW D7 4216: BNC 4228 .................... HSR_Release_v2(); //Go Limp 4218: BRA 3F60 .................... delay_ms(20); //WARNING: Removing this will make the command unreliable 421A: MOVLW 14 421C: MOVLB 1 421E: MOVWF x2E 4220: MOVLB 0 4222: CALL 04E6 .................... } .................... else { 4226: BRA 42DE .................... TargetAngle = commandCenter + (sint16)(((float) servoPosCommand) * commandScaleFactor); 4228: MOVFF D2,12D 422C: MOVFF D1,12C 4230: CALL 19EE 4234: MOVFF 00,12A 4238: MOVFF 01,12B 423C: MOVFF 02,12C 4240: MOVFF 03,12D 4244: MOVFF 03,131 4248: MOVFF 02,130 424C: MOVFF 01,12F 4250: MOVFF 00,12E 4254: MOVFF 112,135 4258: MOVFF 111,134 425C: MOVFF 110,133 4260: MOVFF 10F,132 4264: BRA 3FA8 4266: MOVFF 03,12D 426A: MOVFF 02,12C 426E: MOVFF 01,12B 4272: MOVFF 00,12A 4276: BRA 40A0 4278: MOVF 01,W 427A: MOVLB 1 427C: ADDWF x13,W 427E: MOVWF x24 4280: MOVF 02,W 4282: ADDWFC x14,W 4284: MOVWF x25 .................... TargetPos = TargetAngle+14500; 4286: MOVLW A4 4288: ADDWF x24,W 428A: MOVWF x20 428C: MOVLW 38 428E: ADDWFC x25,W 4290: MOVWF x21 .................... TargetPos = TargetPos/10; 4292: MOVFF 121,12B 4296: MOVFF 120,12A 429A: CLRF x2D 429C: MOVLW 0A 429E: MOVWF x2C 42A0: MOVLB 0 42A2: RCALL 3E44 42A4: MOVFF 02,121 42A8: MOVFF 01,120 .................... TargetPosH = make8(TargetPos,1); 42AC: MOVLB 1 42AE: MOVFF 121,122 .................... TargetPosL = make8(TargetPos,0); 42B2: MOVFF 120,123 .................... HSR_WriteMemory_v2(_HSR_MEM_Speed,ServoSpeed); 42B6: MOVLW 86 42B8: MOVWF x2A 42BA: MOVFF D3,12B 42BE: MOVLB 0 42C0: RCALL 3EBC .................... HSR_WriteMemory_v2(_HSR_MEM_CurSpeed, ServoSpeed); 42C2: MOVLW C3 42C4: MOVLB 1 42C6: MOVWF x2A 42C8: MOVFF D3,12B 42CC: MOVLB 0 42CE: RCALL 3EBC .................... HSR_SetPosition(TargetPosH,TargetPosL); 42D0: MOVFF 122,12A 42D4: MOVFF 123,12B 42D8: RCALL 3F0E .................... output_toggle(Pin_D7); 42DA: BCF F95.7 42DC: BTG F8C.7 42DE: MOVLB 1 .................... } .................... } .................... } .................... currentSense = read_adc(); 42E0: BSF FC2.1 42E2: BTFSC FC2.1 42E4: BRA 42E2 42E6: MOVFF FC3,DB 42EA: MOVLB 0 .................... .................... } 42EC: GOTO 43C8 (RETURN) .................... .................... .................... #int_rda .................... void serial_isr() .................... { .................... if(kbhit()) * 0440: BTFSS F9E.5 0442: BRA 0480 .................... { .................... _RxData[_RxCounter]=getc(); 0444: CLRF 03 0446: MOVLB 1 0448: MOVF x06,W 044A: ADDLW 01 044C: MOVWF FE9 044E: MOVLW 01 0450: ADDWFC 03,W 0452: MOVWF FEA 0454: BTFSS F9E.5 0456: BRA 0454 0458: MOVFF FAE,FEF .................... _RxCounter++; 045C: INCF x06,F .................... _RxCounter%=3; 045E: MOVFF 106,156 0462: MOVLW 03 0464: MOVWF x57 0466: MOVLB 0 0468: BRA 0412 046A: MOVFF 00,106 .................... if (_RxCounter==0) 046E: MOVLB 1 0470: MOVF x06,F 0472: BNZ 047E .................... { .................... _RxLastData[0]=_RxData[0]; 0474: MOVFF 101,104 .................... _RxLastData[1]=_RxData[1]; 0478: MOVFF 102,105 .................... _RxComplete=1; 047C: BSF x07.0 047E: MOVLB 0 .................... } .................... } .................... } .................... .................... // TIMER GUIDELINES .................... // Timer0 is used by RB Stack, leaving Timers 1,2 and 3 for Application. .................... .................... // ResetApp is a callback function: .................... // it is called on startup from main(), and in addition, .................... // it can be called at any time by RB_ProcessStack(); .................... // RB_App_SetFactoryDefaults is a callback, and is called only once, .................... // by RB_Initialize, on first power up after wiping the ROM. .................... 0480: BCF F9E.5 0482: GOTO 0058 .................... void RB_App_SetFactoryDefaults() .................... { .................... .................... uint16 tmp; .................... sint16 tmps; .................... tmps = 9001;//starts limp * 0BA4: MOVLW 23 0BA6: MOVLB 1 0BA8: MOVWF x2F 0BAA: MOVLW 29 0BAC: MOVWF x2E .................... RBSetEEPROM(&tmps,SERVO_START_POS,2); 0BAE: MOVLW 01 0BB0: MOVWF x44 0BB2: MOVLW 2E 0BB4: MOVWF x43 0BB6: MOVLW 0E 0BB8: MOVWF x45 0BBA: MOVLW 02 0BBC: MOVWF x46 0BBE: MOVLB 0 0BC0: RCALL 0B4C .................... /*tmp = 0; .................... RBSetEEPROM(&tmp,SERVO_KP, 2); .................... tmp = 0; .................... RBSetEEPROM(&tmp,SERVO_KD,2); .................... */ .................... tmp=255; 0BC2: MOVLB 1 0BC4: CLRF x2D 0BC6: MOVLW FF 0BC8: MOVWF x2C .................... RBSetEEPROM(&tmp,SERVO_SPEED,2); 0BCA: MOVLW 01 0BCC: MOVWF x44 0BCE: MOVLW 2C 0BD0: MOVWF x43 0BD2: MOVLW 0C 0BD4: MOVWF x45 0BD6: MOVLW 02 0BD8: MOVWF x46 0BDA: MOVLB 0 0BDC: RCALL 0B4C .................... tmp=10; 0BDE: MOVLB 1 0BE0: CLRF x2D 0BE2: MOVLW 0A 0BE4: MOVWF x2C .................... RBSetEEPROM(&tmp,FEEDBACK,2); 0BE6: MOVLW 01 0BE8: MOVWF x44 0BEA: MOVLW 2C 0BEC: MOVWF x43 0BEE: MOVLW 08 0BF0: MOVWF x45 0BF2: MOVLW 02 0BF4: MOVWF x46 0BF6: MOVLB 0 0BF8: RCALL 0B4C .................... tmps=0; 0BFA: MOVLB 1 0BFC: CLRF x2F 0BFE: CLRF x2E .................... RBSetEEPROM(&tmp,SERVO_CAL_CMD_CENTER,2); 0C00: MOVLW 01 0C02: MOVWF x44 0C04: MOVLW 2C 0C06: MOVWF x43 0C08: MOVLW 02 0C0A: MOVWF x45 0C0C: MOVWF x46 0C0E: MOVLB 0 0C10: RCALL 0B4C .................... tmps=9000; 0C12: MOVLW 23 0C14: MOVLB 1 0C16: MOVWF x2F 0C18: MOVLW 28 0C1A: MOVWF x2E .................... RBSetEEPROM(&tmps,SERVO_CAL_CMD_AMPLITUDE,2); 0C1C: MOVLW 01 0C1E: MOVWF x44 0C20: MOVLW 2E 0C22: MOVWF x43 0C24: MOVLW 04 0C26: MOVWF x45 0C28: MOVLW 02 0C2A: MOVWF x46 0C2C: MOVLB 0 0C2E: RCALL 0B4C .................... .................... .................... } 0C30: GOTO 152E (RETURN) .................... void RB_App_ResetApp() .................... { .................... //setup_spi(FALSE); // not using this peripheral .................... //setup_wdt(WDT_OFF); // no watchdog timer .................... disable_interrupts(GLOBAL); // to prevent data from corrupting * 1D0A: BCF FF2.6 1D0C: BCF FF2.7 1D0E: BTFSC FF2.7 1D10: BRA 1D0C .................... delay_ms(100); 1D12: MOVLW 64 1D14: MOVLB 1 1D16: MOVWF x2E 1D18: MOVLB 0 1D1A: CALL 04E6 .................... RB_reset_from_eeprom();// reads node id from eeprom and resets variables associated with it 1D1E: GOTO 14D2 .................... RB_Initialize(); 1D22: BRA 19A4 .................... RCservo_init(); // sets up servo default values 1D24: BRA 1BE6 .................... delay_ms(2000); // WARNING: DONOT REMOVE WILL CAUSE SERVO TO FREEZE 1D26: MOVLW 08 1D28: MOVLB 1 1D2A: MOVWF x2C 1D2C: MOVLW FA 1D2E: MOVWF x2E 1D30: MOVLB 0 1D32: CALL 04E6 1D36: MOVLB 1 1D38: DECFSZ x2C,F 1D3A: BRA 1D2C .................... HSR_SerialInitialization(); // Initial Serial Configuration for HSR communication 1D3C: MOVLB 0 1D3E: BRA 1CFA .................... delay_ms(2000); // WARNING: DONOT REMOVE WILL CAUSE SERVO TO FREEZE 1D40: MOVLW 08 1D42: MOVLB 1 1D44: MOVWF x2C 1D46: MOVLW FA 1D48: MOVWF x2E 1D4A: MOVLB 0 1D4C: CALL 04E6 1D50: MOVLB 1 1D52: DECFSZ x2C,F 1D54: BRA 1D46 .................... output_toggle(Pin_D7); 1D56: BCF F95.7 1D58: BTG F8C.7 .................... } 1D5A: MOVLB 0 1D5C: RETLW 00 .................... // URBProcessStack uses all idle processor cycles. .................... // Application processing is done inside interrupts. .................... .................... void ReadPos() .................... { // feed_freq has to be less than 4C47 i.e. the URB_HEARTBEAT_INTERVAL .................... raw_adc = HSR_ReadPosition(); * 2426: RCALL 1DBE 2428: MOVFF 02,DA 242C: MOVFF 01,D9 .................... //actualPos=(sint16)(((float)( raw_adc - commandCenter))/ commandScaleFactor); .................... actualPos=( raw_adc*10 - 14500 ); 2430: MOVFF DA,143 2434: MOVFF D9,142 2438: MOVLB 1 243A: CLRF x45 243C: MOVLW 0A 243E: MOVWF x44 2440: MOVLB 0 2442: CALL 050E 2446: MOVLW A4 2448: MOVLB 1 244A: SUBWF 01,W 244C: MOVWF 00 244E: MOVLW 38 2450: SUBWFB 02,W 2452: MOVFF 00,CF 2456: MOVLB 0 2458: MOVWF xD0 .................... RB_Send_PM(0); 245A: MOVLB 1 245C: CLRF x2A 245E: MOVLB 0 2460: BRA 2094 .................... //output_toggle(PIN_D5); .................... } 2462: GOTO 43BC (RETURN) .................... .................... void main() .................... { * 42F0: CLRF FF8 42F2: BCF FD0.7 42F4: BSF 08.7 42F6: CLRF FEA 42F8: CLRF FE9 42FA: BCF FB8.3 42FC: MOVLW 40 42FE: MOVWF FAF 4300: MOVLW A6 4302: MOVWF FAC 4304: MOVLW 90 4306: MOVWF FAB 4308: BSF F94.4 430A: BCF F94.5 430C: BCF F94.3 430E: BCF F8B.3 4310: BCF F93.0 4312: BSF F8A.0 4314: MOVF FC1,W 4316: ANDLW C0 4318: IORLW 0F 431A: MOVWF FC1 431C: MOVLW 07 431E: MOVWF FB4 4320: CLRF 4B 4322: CLRF 4C 4324: CLRF xD1 4326: CLRF xD2 4328: MOVLW 01 432A: MOVWF xD5 432C: CLRF xD6 432E: CLRF xD7 4330: CLRF xD8 4332: CLRF xD9 4334: CLRF xDA 4336: CLRF xDB 4338: CLRF xDC 433A: CLRF xFC 433C: MOVLW DD 433E: MOVWF xFB 4340: MOVLB 1 4342: CLRF x06 4344: BCF x07.0 4346: MOVLW 45 4348: MOVWF x0D 434A: MOVLW 01 434C: MOVWF x0E 434E: CLRF x1C 4350: CLRF x1D 4352: CLRF x1E 4354: CLRF x1F 4356: CLRF x26 4358: CLRF x27 .................... int counter; .................... int spiFreqCounter; .................... output_low(Pin_D7); 435A: BCF F95.7 435C: BCF F8C.7 .................... init_ir_ports(); 435E: MOVLB 0 4360: GOTO 0486 .................... RB_App_ResetApp(); 4364: CALL 1D0A .................... while(1){ .................... /*if (spiFreqCounter>2){ .................... spiFreqCounter = 0; .................... transmit_ir_to_can(); .................... }else{ .................... spiFreqCounter++; .................... }*/ .................... transmit_ir_to_can(); 4368: CALL 1294 .................... if(get_timer0() >= feed_int*feed_mult && feed_freq != 0){ 436C: MOVF FD6,W 436E: MOVFF FD7,03 4372: MOVLB 1 4374: MOVWF x2A 4376: MOVFF FD7,12B 437A: MOVFF D8,143 437E: MOVFF D7,142 4382: MOVFF D6,145 4386: MOVFF D5,144 438A: MOVLB 0 438C: CALL 050E 4390: MOVF 02,W 4392: MOVWF 03 4394: MOVLB 1 4396: SUBWF x2B,W 4398: BNC 43C2 439A: BNZ 43A2 439C: MOVF 01,W 439E: SUBWF x2A,W 43A0: BNC 43C2 43A2: MOVLB 0 43A4: MOVF xCD,F 43A6: BNZ 43B2 43A8: MOVF xCE,F 43AA: BTFSS FD8.2 43AC: BRA 43B2 43AE: MOVLB 1 43B0: BRA 43C2 .................... _RxCounter=0; 43B2: MOVLB 1 43B4: CLRF x06 .................... //transmit_ir_to_can(); .................... ReadPos(); 43B6: MOVLB 0 43B8: GOTO 2426 .................... feed_mult++; 43BC: INCF xD5,F 43BE: BTFSC FD8.2 43C0: INCF xD6,F .................... } .................... RB_ProcessStack(); 43C2: MOVLB 0 43C4: BRA 3CE4 .................... initiate_pulse(); 43C6: BRA 40DE .................... } 43C8: BRA 4368 .................... } .................... // end main 43CA: SLEEP Configuration Fuses: Word 1: 0200 HS NOIESO NOFCMEN Word 2: 1E1F BROWNOUT NOWDT BORV21 NOPUT WDT32768 Word 3: 8200 PBADEN NOLPT1OSC MCLR Word 4: 0081 STVREN NODEBUG NOLVP BBSIZ1K NOXINST Word 5: C00F NOPROTECT NOCPD NOCPB Word 6: E007 NOWRT NOWRTD NOWRTC NOWRTB Word 7: 4007 NOEBTR NOEBTRB