?? can18xx8.c
字號:
/*********************************************************************
*
* PIC18CXX8 CAN C Library Source Code
*
*********************************************************************
* FileName: CAN18CXX8.C
* Dependencies: CAN18CXX8.h
* Date: 09/06/00
* Processor: PIC18CXX8
* Complier: MPLAB 5.11.00
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the 揅ompany? for its PICmicro?Microcontroller is intended and
* supplied to you, the Company抯 customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN 揂S IS?CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Nilesh Rajbharti 9/6/00 Original (Rev 1.0)
* Nilesh Rajbharti 12/1/00 Fixed bugs.
* (CANRegsToID, CANReceiveMessage,
* CANSetMask + Added
* CAN_CONFIG_DBL_BUFFER_ON/OFF option)
* Nilesh Rajbharti 6/8/01 Renamed CAN_CONFIG_DBL_BUFFERED to
* CAN_RX_DBL_BUFFERED
* Nilesh Rajbharti 10/11/01 Added support for HITECH compiler
* Modified CAN_MESSAGE_ID def to be
* compatible with HITECH Compiler
* (Rev 1.1)
* Nilesh Rajbharti 6/5/02 Modified RXB0DLC_RTR def to fix compiler
* missing def problem.
* Fixed CANIDToRegs() where "static"
* mode would not compile. (Rev 1.2)
*
********************************************************************/
#include "can18xx8.h"
#if defined(MCHP_C18)
#include <p18f8680.h> // p18cxxx.h must have current processor
// defined.
#endif
#if defined(HITECH_C18)
#include <pic18.h>
#endif
#if defined(MCHP_C18)
#define RXB0CON_RX0DBEN RXB0CONbits.RXB0DBEN
#define BRGCON2_SAM BRGCON2bits.SAM
#define BRGCON2_SEG2PHTS BRGCON2bits.SEG2PHTS
#define BRGCON3_WAKFIL BRGCON3bits.WAKFIL
#define PIR3_RXB0IF PIR3bits.RXB0IF
#define COMSTAT_RX0OVFL COMSTATbits.RXB0OVFL
#define PIR3_RXB1IF PIR3bits.RXB1IF
#define COMSTAT_RX1OVFL COMSTATbits.RXB1OVFL
#define RXB0DLC_RTR (RXB0DLC & 0x40) // RXB0DLCbits.RTR
#define RXB0SIDL_EXID RXB0SIDLbits.EXID
#define PIR3_IRXIF PIR3bits.IRXIF
#endif
#if defined(HITECH_C18)
#define RXB0CON_RX0DBEN RXB0DBEN
#define BRGCON2_SAM SAM
#define BRGCON2_SEG2PHTS SEG2PHTS
#define BRGCON3_WAKFIL WAKFIL
#define PIR3_RXB0IF RXB0IF
#define COMSTAT_RX0OVFL RXB0OVFL
#define PIR3_RXB1IF RXB1IF
#define COMSTAT_RX1OVFL RXB1OVFL
#define RXB0DLC_RTR RXB0RXRTR
#define RXB0SIDL_EXID RXB0EXID
#define PIR3_IRXIF IRXIF
#endif
/*
* Private helper functions to convert 32-bit CAN ID value into
* corresponding PIC18CXX8 registers and vice-versa.
*/
static void CANIDToRegs(BYTE* ptr,
unsigned long val,
enum CAN_CONFIG_FLAGS type);
static void RegsToCANID(BYTE* ptr,
unsigned long *val,
enum CAN_CONFIG_FLAGS type);
/*********************************************************************
* 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(BYTE SJW,
BYTE BRP,
BYTE PHSEG1,
BYTE PHSEG2,
BYTE PROPSEG,
enum CAN_CONFIG_FLAGS config)
{
BYTE FilterConfig1;
BYTE FilterConfig2;
// In order to setup necessary config parameters of CAN module,
// it must be in CONFIG mode.
CANSetOperationMode(CAN_OP_MODE_CONFIG);
// Now set the baud rate.
CANSetBaudRate(SJW,
BRP,
PHSEG1,
PHSEG2,
PROPSEG,
config);
RXB0CON = config & CAN_CONFIG_MSG_BITS;
if ( (config & CAN_CONFIG_DBL_BUFFER_BIT)
== CAN_CONFIG_DBL_BUFFER_ON )
RXB0CON_RX0DBEN = 1;
RXB1CON = RXB0CON;
// Set default filter and mask registers for all receive buffers.
CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG);
CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG);
switch( (config & CAN_CONFIG_MSG_BITS) | ~CAN_CONFIG_MSG_BITS )
{
case CAN_CONFIG_VALID_XTD_MSG:
FilterConfig1 = CAN_CONFIG_XTD_MSG;
FilterConfig2 = CAN_CONFIG_XTD_MSG;
break;
case CAN_CONFIG_VALID_STD_MSG:
FilterConfig1 = CAN_CONFIG_STD_MSG;
FilterConfig2 = CAN_CONFIG_STD_MSG;
break;
default:
FilterConfig1 = CAN_CONFIG_STD_MSG;
FilterConfig2 = CAN_CONFIG_XTD_MSG;
break;
}
// 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);
CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1);
CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2);
CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2);
CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2);
CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2);
// Restore to Normal mode.
CANSetOperationMode(CAN_OP_MODE_NORMAL);
}
//////////////////////////////////////////////////////////////////////
/*********************************************************************
* 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(enum CAN_OP_MODE mode)
{
// Request desired mode.
CANCON = mode;
// Wait till desired mode is set.
while( ( CANSTAT & CAN_OP_MODE_BITS) != mode );
}
//////////////////////////////////////////////////////////////////////
/*********************************************************************
* 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(BYTE SJW,
BYTE BRP,
BYTE PHSEG1,
BYTE PHSEG2,
BYTE PROPSEG,
enum CAN_CONFIG_FLAGS flags)
{
// Actual values are offset '0'.
// Hence map given values from offset '1' to offset '0'
SJW--;
BRP--;
PHSEG1--;
PHSEG2--;
PROPSEG--;
// Bit adjust given values into their appropriate registers.
BRGCON1 = SJW << 6;
BRGCON1 |= BRP;
BRGCON2 = PHSEG1 << 3;
BRGCON2 |= PROPSEG;
if ( !(flags & CAN_CONFIG_SAMPLE_BIT) )
BRGCON2_SAM = 1;
if ( flags & CAN_CONFIG_PHSEG2_PRG_BIT )
BRGCON2_SEG2PHTS = 1;
BRGCON3 = PHSEG2;
if ( flags & CAN_CONFIG_LINE_FILTER_BIT )
BRGCON3_WAKFIL = 1;
}
//////////////////////////////////////////////////////////////////////
/*********************************************************************
* Function: void CANIDToRegs(BYTE* ptr,
* unsigned long 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
*
********************************************************************/
static void CANIDToRegs(BYTE* ptr,
unsigned long val,
enum CAN_CONFIG_FLAGS type)
{
CAN_MESSAGE_ID *Value;
Value = (CAN_MESSAGE_ID*)&val;
if ( type & CAN_CONFIG_MSG_TYPE_BIT )
{
// Standard Identifier
*ptr = Value->BYTES.BYTE_1 >> 3; // Copy SID<7:3> to SIDH<4:0>
*ptr |= (Value->BYTES.BYTE_2 << 5); // Copy SID<10:8> to SIDH<7:5>
ptr++; // Point to SIDL
*ptr = Value->BYTES.BYTE_1 << 5; // Copy SID<2:0> to SIDL<7:5>
}
else
{
// Extended Identifier
*ptr = Value->BYTES.BYTE_3 >> 5; // Copy EID<23:21> to SIDH<2:0>
*ptr |= Value->BYTES.BYTE_4 << 3; // Copy EID<28:24> to SIDH<7:3>
ptr++; // Point to SIDL
*ptr = (Value->BYTES.BYTE_3 << 3) & 0xE0; // Copy EID<20:18> to SIDL<7:5>
// mask out EID<17:16> bits
*ptr |= 0b00001000; // Set EXIDEN bit to SIDL<3>
*ptr |= Value->BYTES.BYTE_3 & 0x03; // Copy EID<17:16> to SIDL<1:0>
ptr++; // Point to EIDH
*ptr = Value->BYTES.BYTE_2; // Copy EID<15:8> to EIDH<7:0>
ptr++; // Point to EIDL
*ptr = Value->BYTES.BYTE_1; // Copy EID<7:0> to EIDL<7:0>
}
}
//////////////////////////////////////////////////////////////////////
/*********************************************************************
* Function: void RegsToCANID(BYTE *ptr,
* unsigned long *val,
* enum CAN_CONFIG_FLAGS type)
*
* PreCondition: None
*
* Input: ptr - Starting address of a buffer to be updated
* val - 32-bit buffer to hold value
* type - Type of message - either
* CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -