CanBus
CAN BUS module available for Swordfish.
Test equipment : 2 Home Made boards, MCU PIC18F458, MCP2551 CAN transceiver.
Available functions
{ **************************************************************************** * Name : CANInitialize * * Purpose : Initialize CAN module, Filters, Mask * * 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 CAN_CONFIG_FLAGS * **************************************************************************** } Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte) { **************************************************************************** * Name : CANSetFilter * * Purpose : Given value is bit adjusted to appropriate buffer * * filter registers. * **************************************************************************** } Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte) { **************************************************************************** * Name : CANSetMask * * Purpose : Given value is bit adjusted to appropriate buffer * * mask registers. * **************************************************************************** } Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte) { **************************************************************************** * Name : CANSetOperationMode * * Purpose : Given mode byte is copied to CANCON * * and made sure that requested mode is set. * **************************************************************************** } Public Sub CANSetOperationMode(mode As Byte) { **************************************************************************** * Name : CANSendMessage * * Purpose : If at least one empty transmit buffer is found, * * given message is queued to be transmitted. * * If none found FALSE value is returned. * **************************************************************************** } Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean { **************************************************************************** * Name : CANReceiveMessage * * Purpose : If at least one full receive buffer is found, * * it is extrated and returned. * * If none found FALSE value is returned. * **************************************************************************** } Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean { **************************************************************************** * Name : String2ID * * Purpose : Transform 3 Char String into LongWord id * **************************************************************************** } Public Function String2ID(str_in As String) As LongWord
You can download source code from : http://www.microelemente.ro/Swordfish/CAN.zip
In ZIP file, you have 4 examples and additional SYS_lib module.
Example Code
{ ***************************************************************************** * Name : CAN_Echo.BAS * * Author : Florin Andrei Medrea * * Notice : Copyright (c) 2007 - YO2LIO - * * : All Rights Reserved * * Date : 10/26/2007 * * Version : 1.0 * * Notes : Receive CAN message for XTD id "S01", * * : send message back to sender with XTD id "S01" * * : and send message to Usart * ***************************************************************************** } Device = 18F458 Clock = 40 Config OSC = HSPLL Include "CAN_lib" Include "usart" Include "SYS_lib" Dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags, Rx_Data_Len, i As Byte, RxTx_Data(8) As Byte, Tx_ID, Rx_ID As LongWord, Msg_Rcvd, Msg_Sent As Boolean ADCON1 = %11000110 // AD off CMCON = $07 // Comparator off WDTCON = 1 ClrWDT SetBaudrate(br115200) Can_Init_Flags = 0 Can_Send_Flags = 0 Can_Rcv_Flags = 0 Can_Send_Flags = CAN_TX_PRIORITY_0 And // Form value to be used CAN_TX_XTD_FRAME And // with CANSendMessage CAN_TX_NO_RTR_FRAME Can_Init_Flags = CAN_CONFIG_SAMPLE_THRICE And // Form value to be used CAN_CONFIG_PHSEG2_PRG_ON And // with CANInitialize CAN_CONFIG_XTD_MSG And CAN_CONFIG_DBL_BUFFER_ON And CAN_CONFIG_ALL_VALID_MSG CANInitialize(1, 10, 7, 6, 2, Can_Init_Flags) // initialize CAN at 250 Kbps CANSetOperationMode(CAN_OP_MODE_CONFIG) // set CONFIGURATION mode Rx_ID = $FFFFFFFF CANSetMask(CAN_MASK_B1, Rx_ID, CAN_CONFIG_XTD_MSG) // set all mask1 bits to ones CANSetMask(CAN_MASK_B2, Rx_ID, CAN_CONFIG_XTD_MSG) // set all mask2 bits to ones Rx_ID = String2ID("S01") Tx_ID = String2ID("S01") CANSetFilter(CAN_FILTER_B1_F1, Rx_ID, CAN_CONFIG_XTD_MSG) // set id of filter B1_F1 to "S01" CANSetOperationMode(CAN_OP_MODE_NORMAL) // set NORMAL mode While true ClrWDT Msg_Rcvd = CANReceiveMessage(Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags) If Msg_Rcvd Then WriteByte(Rx_ID.Byte2) WriteByte(Rx_ID.Byte1) WriteByte(Rx_ID.Byte0) WriteByte(" ") i = 0 While i < Rx_Data_Len WriteByte(RxTx_Data(i)) Inc(i) Wend Write($0D, $0A) Msg_Sent = CANSendMessage(Tx_ID, RxTx_Data, Rx_Data_Len, Can_Send_Flags) // send data back If Msg_Sent Then Write("CANSendMessage Success", $0D, $0A) Else Write("CANSendMessage Error", $0D, $0A) End If End If Wend
Module Code
{ ***************************************************************************** * Name : CAN_lib.BAS * * Author : Florin Andrei Medrea * * Notice : Copyright (c) 2007 - YO2LIO - * * : All Rights Reserved * * Date : 10/26/2007 * * Version : 1.0 * * Notes : This module is based on Microchip sample * * : CAN Application Note AN738 * ***************************************************************************** } Module CAN_lib Include "SYS_lib" Public Const CAN_TX_PRIORITY_BITS= %00000011, CAN_TX_PRIORITY_0 = %11111100, // XXXXXX00 CAN_TX_PRIORITY_1 = %11111101, // XXXXXX01 CAN_TX_PRIORITY_2 = %11111110, // XXXXXX10 CAN_TX_PRIORITY_3 = %11111111, // XXXXXX11 CAN_TX_FRAME_BIT = %00001000, CAN_TX_STD_FRAME = %11111111, // XXXXX1XX CAN_TX_XTD_FRAME = %11110111, // XXXXX0XX CAN_TX_RTR_BIT = %01000000, CAN_TX_NO_RTR_FRAME = %11111111, // X1XXXXXX CAN_TX_RTR_FRAME = %10111111, // X0XXXXXX CAN_RX_FILTER_BITS = %00000111, CAN_RX_FILTER_1 = %00000000, CAN_RX_FILTER_2 = %00000001, CAN_RX_FILTER_3 = %00000010, CAN_RX_FILTER_4 = %00000011, CAN_RX_FILTER_5 = %00000100, CAN_RX_FILTER_6 = %00000101, CAN_RX_OVERFLOW = %00001000, // Set if Overflowed else cleared CAN_RX_INVALID_MSG = %00010000, // Set if invalid else cleared CAN_RX_XTD_FRAME = %00100000, // Set if XTD message else cleared CAN_RX_RTR_FRAME = %01000000, // Set if RTR message else cleared CAN_RX_DBL_BUFFERED = %10000000, // Set if this message was hardware double-buffered CAN_OP_MODE_BITS = %11100000, CAN_OP_MODE_NORMAL = %00000000, CAN_OP_MODE_SLEEP = %00100000, CAN_OP_MODE_LOOP = %01000000, CAN_OP_MODE_LISTEN = %01100000, CAN_OP_MODE_CONFIG = %10000000, CAN_CONFIG_DEFAULT = %11111111, // 11111111 CAN_CONFIG_PHSEG2_PRG_BIT = %00000001, CAN_CONFIG_PHSEG2_PRG_ON = %11111111, // XXXXXXX1 CAN_CONFIG_PHSEG2_PRG_OFF = %11111110, // XXXXXXX0 CAN_CONFIG_LINE_FILTER_BIT = %00000010, CAN_CONFIG_LINE_FILTER_ON = %11111111, // XXXXXX1X CAN_CONFIG_LINE_FILTER_OFF = %11111101, // XXXXXX0X CAN_CONFIG_SAMPLE_BIT = %00000100, CAN_CONFIG_SAMPLE_ONCE = %11111111, // XXXXX1XX CAN_CONFIG_SAMPLE_THRICE = %11111011, // XXXXX0XX CAN_CONFIG_MSG_TYPE_BIT = %00001000, CAN_CONFIG_STD_MSG = %11111111, // XXXX1XXX CAN_CONFIG_XTD_MSG = %11110111, // XXXX0XXX CAN_CONFIG_DBL_BUFFER_BIT = %00010000, CAN_CONFIG_DBL_BUFFER_ON = %11111111, // XXX1XXXX CAN_CONFIG_DBL_BUFFER_OFF = %11101111, // XXX0XXXX CAN_CONFIG_MSG_BITS = %01100000, CAN_CONFIG_ALL_MSG = %11111111, // X11XXXXX CAN_CONFIG_VALID_XTD_MSG = %11011111, // X10XXXXX CAN_CONFIG_VALID_STD_MSG = %10111111, // X01XXXXX CAN_CONFIG_ALL_VALID_MSG = %10011111, // X00XXXXX CAN_MASK_B1 = 1, CAN_MASK_B2 = 2, CAN_FILTER_B1_F1 = 1, CAN_FILTER_B1_F2 = 2, CAN_FILTER_B2_F1 = 3, CAN_FILTER_B2_F2 = 4, CAN_FILTER_B2_F3 = 5, CAN_FILTER_B2_F4 = 6 Const // BRGCON3 WAKFIL = 6, // BRGCON2 SEG2PHTS = 7, SAM = 6, // COMSTAT RX1OVFL = 7, RXB0OVFL = 7, TXBO = 5, TXBP = 4, RXBP = 3, // PIR3 IRXIF = 7, RXB1IF = 1, RXB0IF = 0, // CANCON ABAT = 4, // RXBnCON RXFUL = 7, RXB0DBEN = 2, // RXBnDLC RXRTR = 6, // RXBnSIDL EXID = 3, // TXBnCON TXREQ = 3 Dim RXB0CON_RX0DBEN As RXB0CON.Bits(RXB0DBEN), BRGCON2_SAM As BRGCON2.Bits(SAM), BRGCON2_SEG2PHTS As BRGCON2.Bits(SEG2PHTS), BRGCON3_WAKFIL As BRGCON3.Bits(WAKFIL), PIR3_RXB0IF As PIR3.Bits(RXB0IF), COMSTAT_RX0OVFL As COMSTAT.Bits(RXB0OVFL), PIR3_RXB1IF As PIR3.Bits(RXB1IF), COMSTAT_RX1OVFL As COMSTAT.Bits(RX1OVFL), RXB0DLC_RTR As RXB0DLC.Bits(RXRTR), RXB0SIDL_EXID As RXB0SIDL.Bits(EXID), PIR3_IRXIF As PIR3.Bits(IRXIF), COMSTAT_TXB0 As COMSTAT.Bits(TXBO), COMSTAT_TXBP As COMSTAT.Bits(TXBP), COMSTAT_RXBP As COMSTAT.Bits(RXBP), CANCON_ABAT As CANCON.Bits(ABAT), RXB0CON_RXFUL As RXB0CON.Bits(RXFUL) // RXB1CON_RXFUL As RXB1CON.Bits(RXFUL), // TXB0CON_TXREQ As TXB0CON.Bits(TXREQ), // TXB1CON_TXREQ As TXB1CON.Bits(TXREQ), // TXB2CON_TXREQ As TXB2CON.Bits(TXREQ) { **************************************************************************** * Name : CANSetOperationMode * * Purpose : Given mode byte is copied to CANCON * * and made sure that requested mode is set. * **************************************************************************** } Public Sub CANSetOperationMode(mode As Byte) CANCON = mode // Request desired mode. While((CANSTAT And CAN_OP_MODE_BITS) <> mode) ClrWDT Wend // Wait till desired mode is set. End Sub { **************************************************************************** * Name : CANSetBaudRate * * Purpose : Given values are bit adjusted to fit in 18CXX8 * * BRGCONx registers and copied. * * 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 CAN_CONFIG_FLAGS * **************************************************************************** } Sub CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte) Dec(SJW) Dec(BRP) Dec(PHSEG1) Dec(PHSEG2) Dec(PROPSEG) BRGCON1 = SJW << 6 BRGCON1 = BRGCON1 Or BRP BRGCON2 = PHSEG1 << 3 BRGCON2 = BRGCON2 Or PROPSEG If (flags And CAN_CONFIG_SAMPLE_BIT) = 0 Then BRGCON2_SAM = 1 End If If (flags And CAN_CONFIG_PHSEG2_PRG_BIT) <> 0 Then BRGCON2_SEG2PHTS = 1 End If BRGCON3 = PHSEG2 If (flags And CAN_CONFIG_LINE_FILTER_BIT) <> 0 Then BRGCON3_WAKFIL = 1 End If End Sub { **************************************************************************** * Name : CANIDToRegs * * Purpose : If given id is standard identifier, * * only SIDH and SIDL are updated * * If given id is extended identifier, * * bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> * * bits value<28:18> is copied to SIDH and SIDL * **************************************************************************** } Sub CANIDToRegs(CANreg As Word, value As LongWord, flags As Byte) FSR2 = CANreg If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier INDF2 = value.Byte0 >> 3 // Copy SID<7:3> to SIDH<4:0> POSTINC2 = INDF2 Or (value.Byte1 << 5) // Copy SID<10:8> to SIDH<7:5> INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5> Else // Extended Identifier INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0> POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3> INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5> INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3> POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0> POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0> INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0> End If End Sub { **************************************************************************** * Name : RegsToCANID * * Purpose : If given id is standard identifier, * * only SIDH and SIDL are used * * If given id is extended identifier, * * EIDH, EIDL And SIDH<1:0> is copied To bits value<17:0> * * SIDH And SIDL is copied To bits value<28:18> * **************************************************************************** } Function RegsToCANID(CANreg As Word, flags As Byte) As LongWord FSR2 = CANreg If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier result.Byte0 = INDF2 << 3 // Copy SIDH<4:0> to SID<7:3> result.Byte1 = POSTINC2 >> 5 // Copy SIDH<7:5> to SID<10:8> result.Byte0 = result.Byte0 Or (INDF2 >> 5) // Copy SIDL<7:6> to SID<2:0> result.Byte2 = $00 result.Byte3 = $00 Else // Extended Identifier result.Byte2 = INDF2 << 5 // Copy SIDH<2:0> to EID<23:21> result.Byte3 = POSTINC2 >> 3 // Copy SIDH<7:3> to EID<29:25> result.Byte2 = result.Byte2 Or (INDF2 And $03) // Copy SIDH<1:0> to EID<17:16> result.Byte2 = result.Byte2 Or ((POSTINC2 And $E0) >> 3) // Copy SIDL<7:6> to EID<20:18> result.Byte1 = POSTINC2 // Copy EIDH<15:8> to EID<15:8> result.Byte0 = INDF2 // Copy EIDH<7:0> to EID<7:0> End If End Function { **************************************************************************** * Name : CANSetMask * * Purpose : Given value is bit adjusted to appropriate buffer * * mask registers. * **************************************************************************** } Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte) Dim buf As Word Save(FSR1, FSR2) If mask = CAN_MASK_B1 Then // Select appropriate starting address based on given CAN_MASK value. buf = AddressOf(RXM0SIDH) Else buf = AddressOf(RXM1SIDH) End If CANIDToRegs(buf, value, flags) Restore End Sub { **************************************************************************** * Name : CANSetFilter * * Purpose : Given value is bit adjusted to appropriate buffer * * filter registers. * **************************************************************************** } Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte) Dim buf As Word Save(FSR1, FSR2) Select filter Case CAN_FILTER_B1_F1 buf = AddressOf(RXF0SIDH) Case CAN_FILTER_B1_F2 buf = AddressOf(RXF1SIDH) Case CAN_FILTER_B2_F1 buf = AddressOf(RXF2SIDH) Case CAN_FILTER_B2_F2 buf = AddressOf(RXF3SIDH) Case CAN_FILTER_B2_F3 buf = AddressOf(RXF4SIDH) Else buf = AddressOf(RXF5SIDH) End Select CANIDToRegs(buf, value, flags) Restore End Sub { **************************************************************************** * Name : CANInitialize * * Purpose : Initialize CAN module, Filters, Mask * * 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 CAN_CONFIG_FLAGS * **************************************************************************** } Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte) Dim FilterConfig1 As Byte, FilterConfig2 As Byte Save(FSR1, FSR2) #if _device in (18F248, 18F258, 18F448, 18F458, 18F2480, 18F2580, 18F4480, 18F4580, 18F2682, 18F2685, 18F4682, 18F4685) TRISB.2 = 0 'TX CAN TRISB.3 = 1 'RX CAN #else TRISG.0 = 0 'TX CAN TRISG.2 = 1 'RX CAN #endif CIOCON = 0 CANSetOperationMode(CAN_OP_MODE_CONFIG) // In order to setup necessary config parameters of CAN module, it must be in Config mode. #if _device in (18F248, 18F258, 18F448, 18F458) Nop #else ECANCON = ECANCON And %00111111 #endif CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags) // Now set the baud rate. RXB0CON = flags And CAN_CONFIG_MSG_BITS If (flags And CAN_CONFIG_DBL_BUFFER_BIT) = CAN_CONFIG_DBL_BUFFER_ON Then RXB0CON_RX0DBEN = 1 End If RXB1CON = RXB0CON CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG) // Set default filter and mask registers for all receive buffers. CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG) Select ((flags And CAN_CONFIG_MSG_BITS) Or (Not(CAN_CONFIG_MSG_BITS))) Case CAN_CONFIG_VALID_XTD_MSG FilterConfig1 = CAN_CONFIG_XTD_MSG FilterConfig2 = CAN_CONFIG_XTD_MSG Case CAN_CONFIG_VALID_STD_MSG FilterConfig1 = CAN_CONFIG_STD_MSG FilterConfig2 = CAN_CONFIG_STD_MSG Else FilterConfig1 = CAN_CONFIG_STD_MSG FilterConfig2 = CAN_CONFIG_XTD_MSG End Select CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1) // By default, there will be no mask on any receive filters, hence filter value of '0' will be ignored. 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) CANSetOperationMode(CAN_OP_MODE_NORMAL) // Restore to Normal mode. Restore End Sub { **************************************************************************** * Name : CANSendMessage * * Purpose : If at least one empty transmit buffer is found, * * given message is queued to be transmitted. * * If none found FALSE value is returned. * **************************************************************************** } Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean Dim i As Byte Save(FSR1, FSR2) FSR2 = AddressOf(TXB0CON) // For compatibility with SwordfishSE If INDF2.bits(TXREQ) = 0 Then // Find the first empty transmitter. // If TXB0CON_TXREQ = 0 Then CANCON = CANCON And %11110001 // TxBuffer0 is empty. Set WIN bits to point to TXB0 CANCON = CANCON Or %00001000 Else FSR2 = AddressOf(TXB1CON) // For compatibility with SwordfishSE If INDF2.bits(TXREQ) = 0 Then // If TXB1CON_TXREQ = 0 Then CANCON = CANCON And %11110001 // TxBuffer1 is empty. Set WIN bits to point to TXB1 CANCON = CANCON Or %00000110 Else FSR2 = AddressOf(TXB2CON) // For compatibility with SwordfishSE If INDF2.bits(TXREQ) = 0 Then // If TXB2CON_TXREQ = 0 Then CANCON = CANCON And %11110001 // TxBuffer2 is empty. Set WIN bits to point to TXB2 CANCON = CANCON Or %00000100 Else result = false // None of the transmit buffers were empty. Exit End If End If End If RXB0CON = flags And CAN_TX_PRIORITY_BITS // Set transmit priority. If (flags And CAN_TX_FRAME_BIT) = 0 Then // Populate Extended identifier information only if it is desired. CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_XTD_MSG) Else CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_STD_MSG) End If RXB0DLC = DataLen If (flags And CAN_TX_RTR_BIT) = 0 Then RXB0DLC = RXB0DLC Or %01000000 End If i = 0 FSR2 = AddressOf(RXB0D0) // Populate data values. FSR1 = AddressOf(Data) While i < DataLen POSTINC2 = POSTINC1 Inc(i) Wend ASM bsf RXB0CON, 3 End ASM CANCON = CANCON And %11110001 result = true Restore End Function { **************************************************************************** * Name : CANReceiveMessage * * Purpose : If at least one full receive buffer is found, * * it is extrated and returned. * * If none found FALSE value is returned. * **************************************************************************** } Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean Dim i, buf As Byte, lbIsItBuffer0 As Boolean Save(FSR1, FSR2) flags = 0 // Start with no error or flags set. If RXB0CON_RXFUL = 1 Then // Find which buffer is ready. CANCON = CANCON And %11110001 // RXBuffer0 is full. lbIsItBuffer0 = true PIR3_RXB0IF = 0 // Clear the received flag. If COMSTAT_RX0OVFL = 1 Then // Record and forget any previous overflow flags = flags Or CAN_RX_OVERFLOW COMSTAT_RX0OVFL = 0 End If If RXB0CON_RX0DBEN = 1 Then flags = (flags Or RXB0CON) And CAN_RX_FILTER_BITS flags = flags And $01 End If Else FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE If INDF2.bits(RXFUL) = 1 Then // If RXB1CON_RXFUL = 1 Then CANCON = CANCON And %11110001 // RXBuffer1 is full CANCON = CANCON Or %00001010 lbIsItBuffer0 = false PIR3_RXB1IF = 0 // Clear the received flag. If COMSTAT_RX1OVFL = 1 Then // Record and forget any previous overflow flags = flags Or CAN_RX_OVERFLOW COMSTAT_RX1OVFL = 0 End If FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE flags = (flags Or INDF2) And CAN_RX_FILTER_BITS // flags = (flags Or RXB1CON) And CAN_RX_FILTER_BITS If flags < $02 Then flags = flags Or CAN_RX_DBL_BUFFERED End If Else result = false Exit End If End If DataLen = RXB0DLC And %00001111 // Retrieve message length. If RXB0DLC_RTR = 1 Then // Determine whether this was RTR or not. flags = flags Or CAN_RX_RTR_FRAME End If If RXB0SIDL_EXID = 1 Then // Retrieve EIDX bytes only if this is extended message flags = flags Or CAN_RX_XTD_FRAME id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_XTD_MSG) Else id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_STD_MSG) End If i = 0 buf = DataLen // Get message data itself FSR1 = AddressOf(RXB0D0) FSR2 = AddressOf(Data) While i < buf POSTINC2 = POSTINC1 Inc(i) Wend CANCON = CANCON And %11110001 // Restore default RXB0 mapping. If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag. flags = flags Or CAN_RX_INVALID_MSG PIR3_IRXIF = 0 End If If lbIsItBuffer0 = true Then RXB0CON_RXFUL = 0 Else FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE INDF2.bits(RXFUL) = 0 // RXB1CON_RXFUL = 0 End If result = true Restore End Function { **************************************************************************** * Name : String2ID * * Purpose : Transform 3 Char String into LongWord id * **************************************************************************** } Public Function String2ID(str_in As String) As LongWord Save(FSR2) FSR2 = AddressOf(str_in) result.Byte3 = 0 result.Byte2 = POSTINC2 result.Byte1 = POSTINC2 result.Byte0 = INDF2 Restore End Function