CanBus

SwordfishUser.CanBus History

Show minor edits - Show changes to output

Added line 77:
Deleted line 5:
Changed lines 76-79 from:
For initialization you can choice between Sensirion_Init or Sensirion_Init_

You can download source code from :
[[http://www.microelemente.ro/Swordfish/Sensirion.zip]]
to:
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.

Changed lines 81-94 from:
Device = 18F8520
to:
{
*****************************************************************************
*
  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
Changed lines 98-159 from:
// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3

// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"

Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer

ADCON0 = 0
CMCON  = $07                    // turn off comparators
ADCON1 = $0F                    // turn off analog inputs
MEMCON.7 = 1                    // disable external memory bus

Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2) 
                                          // Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
                                          // Data an Clock Pin must be at the same Port
                                          // This is a wrong configuration :
                                          // Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1)    // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
    NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
    If NoError Then
        buf = temperature * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C  ")
        buf = humidity * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," %  ")
        dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)     
    Else
        LCD.WriteAt(1,1, " Error detected ")
        LCD.WriteAt(2,1, " Error detected ")       
    End If
    DelayMS(2000)
Wend
=]
!!!Module Code
=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

to:
Include "CAN_lib"
Include "usart"
Changed lines 102-115 from:
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
to:
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
Changed lines 108-127 from:
  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,
to:
  ADCON1 = %11000110      // AD off
  CMCON = $07            // Comparator off
  WDTCON = 1
Changed lines 112-188 from:
  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),
to:
  ClrWDT
  SetBaudrate(br115200)
Changed lines 115-134 from:
  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)
to:
  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
Changed lines 142-143 from:
  Wend            // Wait till desired mode is set.
End Sub
to:
   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
=code [=
Changed lines 166-181 from:
****************************************************************************
* 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                            *

****************************************************************************
to:
*****************************************************************************
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                                   *
*****************************************************************************
Changed lines 177-197 from:
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
to:
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)

Changed lines 307-312 from:
* 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
                  *
to:
* Name    : CANSetOperationMode                                            *
* Purpose : Given mode byte is copied to CANCON
                           *
*
          and made sure that requested mode is set.                    *
Changed lines 312-326 from:
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
to:
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.
Changed lines 320-325 from:
* 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>                  *
to:
* 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       
                  *
Changed lines 336-352 from:
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
to:
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
Changed lines 359-361 from:
* Name    : CANSetMask                                                     *
* Purpose : Given value is bit adjusted to appropriate buffer              *
*
          mask registers.                                               *
to:
* 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
                  *
Deleted lines 365-382:
}
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.                                              *
****************************************************************************
Changed lines 367-386 from:
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
to:
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
Changed lines 385-397 from:
* 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       
                  *
to:
* 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>                  *
Changed lines 393-395 from:
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dim FilterConfig1 As Byte,
    FilterConfig2 As Byte
to:
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
Changed lines 420-437 from:
  #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
to:
  If mask = CAN_MASK_B1 Then // Select appropriate starting address based on given CAN_MASK value.
    buf = AddressOf(RXM0SIDH)
  Else
    buf = AddressOf(RXM1SIDH)
Changed lines 425-445 from:
  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.
to:
  CANIDToRegs(buf, value, flags)
Changed lines 430-433 from:
* 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.
                        *
to:
* Name    : CANSetFilter                                                  *
* Purpose : Given value is bit adjusted to appropriate buffer              *
*
          filter registers.                                           *
Changed lines 434-436 from:
}
Public Function CANSendMessage
(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
Dim i As Byte 
to:
}
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Changed lines 438-448 from:
  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
to:
  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)
Changed lines 450-482 from:
     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
to:
     buf = AddressOf(RXF5SIDH)
  End Select
  CANIDToRegs(buf, value, flags)
Changed line 454 from:
End Function
to:
End Sub
Changed lines 457-460 from:
* Name    : CANReceiveMessage                                              *
* Purpose : If at least one full receive buffer is found
,                 *
*
          it is extrated and returned.                                 *
*
          If none found FALSE value is returned.                        *
to:
* 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 
                        *
Changed lines 471-474 from:
}
Public Function CANReceiveMessage
(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
Dim i
, buf As Byte,
    lbIsItBuffer0 As Boolean 
to:
}
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dim FilterConfig1 As Byte,
   FilterConfig2 As Byte
Changed lines 476-506 from:
  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
to:
  #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
Changed lines 506-516 from:
     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)
to:
     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
Changed lines 535-536 from:
   id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_STD_MSG)
  End If 
to:
   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
Changed lines 563-566 from:
  buf = DataLen                    // Get message data itself
  FSR1 = AddressOf(RXB0D0)
  FSR2 = AddressOf(Data)
  While i < buf
to:
  FSR2 = AddressOf(RXB0D0)            // Populate data values.
  FSR1 = AddressOf(Data)
  While i < DataLen
Changed lines 568-580 from:
  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
to:
  Wend
  ASM
    bsf RXB0CON, 3
  End ASM
  CANCON = CANCON And %11110001
Changed lines 578-579 from:
* Name    : String2ID                                                     *
* Purpose : Transform 3 Char String into LongWord id
                      *
to:
* Name    : CANReceiveMessage                                              *
* Purpose : If at least one full receive buffer is found,                  *
*          it is extrated and returned.                                  *
*          If none found FALSE value is returned. 
                      *
Added lines 583-661:
}
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                      *
****************************************************************************
Changed lines 50-74 from:
to:
{
****************************************************************************
* 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
Changed lines 136-147 from:
******************************************************************************
*  Name    : Sensirion.BAS                                                  *
*  Author  : Medrea Florin Andrei                                           *
*  Notice  : Copyright (c) 2007 -YO2LIO-                                    *
*          : All Rights Reserved                                             *
*  Date    : 9/26/2007                                                      *
                                                                         *
*
  Copyright Notice                                                         *
*
                                                                           *
*  This library For the SHT temperature And humidity sensors is based on the *
*  application datasheet Sample Code humidity sensor SHTxx from Sensirion.  *
*
*****************************************************************************
to:
*****************************************************************************
*  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                                    *
*****************************************************************************
Changed lines 147-168 from:
Module Sensirion

Include "math"
Include "system"

Const NoACK As Byte = 1,
      ACK As Byte = 0,
      CMD_STATUS_REG_W As Byte = $06,
      CMD_STATUS_REG_R As Byte = $07,
      CMD_TEMP As Byte = $03,
      CMD_HUMIDITY As Byte = $05,
     CMD_RESET As Byte = $1E
     
Structure TPin
  Pin As Byte
   PinMask As Byte
End Structure

Structure TPort
  AddrPort As Word
  AddrTRIS As Word
End Structure
to:
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
Changed lines 166-170 from:
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte

Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
to:
  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)
Changed lines 286-299 from:
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pData)      // get pin address
    SPort
.AddrTRIS = SPort.AddrPort + 18    // get pin TRIS address
    SData.Pin = BitOf(pData)                // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = BitOf(pClock)              // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
to:
  Wend            // Wait till desired mode is set.
Changed lines 288-304 from:

Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pPort)      // get port address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get port TRIS address
    SData.Pin = 1 << pData                  // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = 1 << pClock                // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
to:
{
****************************************************************************
* 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 
Changed lines 327-343 from:

Sub Sensirion_Start()
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask
        // clear pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SClock.Pin             // set pin SClock
 
  DelayUS(1)   
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    DelayUS(1)
   INDF2 = INDF2 And SClock.PinMask      // clear pin SClock   
to:
{
****************************************************************************
* 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
Changed lines 353-376 from:

Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
    buf = 0
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        If (INDF2 And SData.Pin) > 0 Then
            buf = buf Or 1
        End If
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then buf = buf << 1 End If
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort
    If ack_ = 0 Then
        INDF2 = INDF2 And SData.PinMask    // clear pin SData
to:
{
****************************************************************************
* 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)
Changed lines 420-476 from:
       INDF2 = INDF2 Or SData.Pin         // Set pin SData           
    End If   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)      
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1) 
   result = buf
End Function

Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
    result = false
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        If (data And 128) > 0 Then
 
        INDF2 = INDF2 Or SData.Pin      // Set pin SData
        Else
            INDF2 = INDF2 And SData.PinMask // clear pin SData   
        End If
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
 
      DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
      DelayUS(1)
   
    Inc(i)
        If i < 8 Then data = data << 1 End If       
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)
       
    If (INDF2 And SData.Pin) = 0 Then
        result = true
    End If
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
 
  DelayUS(1)
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
End Function
                     
Sub Sensirion_Reset()
Dim i As Byte
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin             // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
   i = 0
    While i < 9
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)   
   
 
     INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
 
      DelayUS(1)
        Inc(i)
    Wend   
    Sensirion_Start
to:
     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
Changed lines 488-491 from:

Function Sensirion_Soft_Reset() As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_RESET)
to:
{
****************************************************************************
* 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
Changed lines 546-551 from:
 
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
    sensirion_status = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
to:
{
****************************************************************************
* 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
Deleted lines 626-797:

Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
    Sensirion_Reset
    result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
    result = result1 And Sensirion_Put_Byte(data)
End Function

Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
    result = false
    Sensirion_Reset
    Select data
        Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
        Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
    Else Exit
    End Select
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    Repeat
        ClrWDT       
        If (INDF2 And SData.Pin) = 0 Then
            Break
        End If
        Inc(i)
        DelayMS(1)       
    Until i > 500
    If i > 500 Then
        result = false
        Exit
    End If   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    result_h = Sensirion_Get_Byte(ACK)
    result_l = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
      T2 As Float = 0.00008,
      C1 As Float = -4.0,
      C2 As Float = 0.0405,
      C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
    result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
    buf.Byte0 = data_l
    buf.Byte1 = data_h   
    tx = (buf * 0.01) - 40.0
    result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
    If result = false Then
        temp = 0
        hum = 0
        Exit
    End If
    buf.Byte0 = data_l
    buf.Byte1 = data_h     
    rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
    rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
    If rh_true > 99.9 Then rh_true = 99.9 End If
    If rh_true < 0.0 Then rh_true = 0.0 End If
    temp = tx + 0.00001
    hum = rh_true
End Function

Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
      C2d As LongInt = 405,
      C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
  result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
  temp_d.Byte0 = data_l
  temp_d.Byte1 = data_h
  temp_d = temp_d - 4000
  result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
  If result = false Then
    temp_d = 0
    hum_d = 0
    Exit
  End If
  buf.Byte0 = data_l
  buf.Byte1 = data_h
  rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
  rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
  If rh_true > 9999 Then rh_true = 9999 End If
  If rh_true < 0 Then rh_true = 0 End If
  hum_d = Integer(rh_true)
End Function

Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
    k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
    result = (243.12 * k) / (17.62 - k)
End Function
=]  : 2 Home Made, MCU PIC18F458, MCP2515 CAN transceiver.

'''Available functions'''

=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]

For initialization you can choice between Sensirion_Init or Sensirion_Init_

You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]

!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL

// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3

// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"

Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer

ADCON0 = 0
CMCON  = $07                    // turn off comparators
ADCON1 = $0F                    // turn off analog inputs
MEMCON.7 = 1                    // disable external memory bus

Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2) 
                                          // Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
                                          // Data an Clock Pin must be at the same Port
                                          // This is a wrong configuration :
                                          // Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1)    // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
    NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
    If NoError Then
        buf = temperature * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C  ")
        buf = humidity * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," %  ")
        dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)     
    Else
        LCD.WriteAt(1,1, " Error detected ")
        LCD.WriteAt(2,1, " Error detected ")       
    End If
    DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
Changed lines 628-639 from:
******************************************************************************
Name    : Sensirion.BAS                                                  *
*
  Author  : Medrea Florin Andrei                                         *
*  Notice  : Copyright (c) 2007 -YO2LIO-                                    *
*          : All Rights Reserved                                            *
*  Date    : 9/26/2007                                                      *
*                                                                            *
*  Copyright Notice                                                          *
*                                                                            *
*  This library For the SHT temperature And humidity sensors is based on the *
*  application datasheet Sample Code humidity sensor SHTxx from Sensirion.  *
**
****************************************************************************
to:
****************************************************************************
* Name    : String2ID                                                     *
* Purpose : Transform 3 Char String into LongWord id
                      *
****************************************************************************
Changed lines 633-909 from:
Module Sensirion

Include "math"
Include "system"

Const NoACK As Byte = 1,
      ACK As Byte = 0,
      CMD_STATUS_REG_W As Byte = $06,
      CMD_STATUS_REG_R As Byte = $07,
      CMD_TEMP As Byte = $03,
      CMD_HUMIDITY As Byte = $05,
      CMD_RESET As Byte = $1E
     
Structure TPin
  Pin As Byte
  PinMask As Byte
End Structure

Structure TPort
  AddrPort As Word
  AddrTRIS As Word
End Structure
 
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte

Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pData)      // get pin address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get pin TRIS address
    SData.Pin = BitOf(pData)                // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = BitOf(pClock)              // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
End Sub

Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pPort)      // get port address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get port TRIS address
    SData.Pin = 1 << pData                  // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = 1 << pClock                // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
End Sub

Sub Sensirion_Start()
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock   
End Sub

Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
    buf = 0
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        If (INDF2 And SData.Pin) > 0 Then
            buf = buf Or 1
        End If
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then buf = buf << 1 End If
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort
    If ack_ = 0 Then
        INDF2 = INDF2 And SData.PinMask    // clear pin SData
    Else
        INDF2 = INDF2 Or SData.Pin          // Set pin SData           
    End If   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)       
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1) 
    result = buf
End Function

Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
    result = false
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        If (data And 128) > 0 Then
            INDF2 = INDF2 Or SData.Pin      // Set pin SData
        Else
            INDF2 = INDF2 And SData.PinMask // clear pin SData   
        End If
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then data = data << 1 End If       
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)       
    If (INDF2 And SData.Pin) = 0 Then
        result = true
    End If
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
End Function
                     
Sub Sensirion_Reset()
Dim i As Byte
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    i = 0
    While i < 9
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
    Wend   
    Sensirion_Start
End Sub

Function Sensirion_Soft_Reset() As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_RESET)
End Function
 
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
    sensirion_status = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
    Sensirion_Reset
    result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
    result = result1 And Sensirion_Put_Byte(data)
End Function

Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
    result = false
    Sensirion_Reset
    Select data
        Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
        Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
    Else Exit
    End Select
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    Repeat
        ClrWDT       
        If (INDF2 And SData.Pin) = 0 Then
            Break
        End If
        Inc(i)
        DelayMS(1)       
    Until i > 500
    If i > 500 Then
        result = false
        Exit
    End If   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    result_h = Sensirion_Get_Byte(ACK)
    result_l = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
      T2 As Float = 0.00008,
      C1 As Float = -4.0,
      C2 As Float = 0.0405,
      C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
    result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
    buf.Byte0 = data_l
    buf.Byte1 = data_h   
    tx = (buf * 0.01) - 40.0
    result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
    If result = false Then
        temp = 0
        hum = 0
        Exit
    End If
    buf.Byte0 = data_l
    buf.Byte1 = data_h     
    rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
    rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
    If rh_true > 99.9 Then rh_true = 99.9 End If
    If rh_true < 0.0 Then rh_true = 0.0 End If
    temp = tx + 0.00001
    hum = rh_true
End Function

Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
      C2d As LongInt = 405,
      C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
  result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
  temp_d.Byte0 = data_l
  temp_d.Byte1 = data_h
  temp_d = temp_d - 4000
  result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
  If result = false Then
    temp_d = 0
    hum_d = 0
    Exit
  End If
  buf.Byte0 = data_l
  buf.Byte1 = data_h
  rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
  rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
  If rh_true > 9999 Then rh_true = 9999 End If
  If rh_true < 0 Then rh_true = 0 End If
  hum_d = Integer(rh_true)
End Function

Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
    k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
    result = (243.12 * k) / (17.62 - k)
End Function
to:
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
Changed lines 8-12 from:
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
to:
{
****************************************************************************
* 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)

Added lines 1-725:
CAN BUS module available for Swordfish.

Test equipment : 2 Home Made boards, MCU PIC18F458, MCP2551 CAN transceiver.

'''Available functions'''

=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]

For initialization you can choice between Sensirion_Init or Sensirion_Init_

You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]

!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL

// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3

// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"

Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer

ADCON0 = 0
CMCON  = $07                    // turn off comparators
ADCON1 = $0F                    // turn off analog inputs
MEMCON.7 = 1                    // disable external memory bus

Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2) 
                                          // Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
                                          // Data an Clock Pin must be at the same Port
                                          // This is a wrong configuration :
                                          // Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1)    // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
    NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
    If NoError Then
        buf = temperature * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C  ")
        buf = humidity * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," %  ")
        dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)     
    Else
        LCD.WriteAt(1,1, " Error detected ")
        LCD.WriteAt(2,1, " Error detected ")       
    End If
    DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
******************************************************************************
*  Name    : Sensirion.BAS                                                  *
*  Author  : Medrea Florin Andrei                                            *
*  Notice  : Copyright (c) 2007 -YO2LIO-                                    *
*          : All Rights Reserved                                            *
*  Date    : 9/26/2007                                                      *
*                                                                            *
*  Copyright Notice                                                          *
*                                                                            *
*  This library For the SHT temperature And humidity sensors is based on the *
*  application datasheet Sample Code humidity sensor SHTxx from Sensirion.  *
******************************************************************************
}
Module Sensirion

Include "math"
Include "system"

Const NoACK As Byte = 1,
      ACK As Byte = 0,
      CMD_STATUS_REG_W As Byte = $06,
      CMD_STATUS_REG_R As Byte = $07,
      CMD_TEMP As Byte = $03,
      CMD_HUMIDITY As Byte = $05,
      CMD_RESET As Byte = $1E
     
Structure TPin
  Pin As Byte
  PinMask As Byte
End Structure

Structure TPort
  AddrPort As Word
  AddrTRIS As Word
End Structure
 
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte

Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pData)      // get pin address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get pin TRIS address
    SData.Pin = BitOf(pData)                // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = BitOf(pClock)              // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
End Sub

Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pPort)      // get port address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get port TRIS address
    SData.Pin = 1 << pData                  // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = 1 << pClock                // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
End Sub

Sub Sensirion_Start()
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock   
End Sub

Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
    buf = 0
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        If (INDF2 And SData.Pin) > 0 Then
            buf = buf Or 1
        End If
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then buf = buf << 1 End If
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort
    If ack_ = 0 Then
        INDF2 = INDF2 And SData.PinMask    // clear pin SData
    Else
        INDF2 = INDF2 Or SData.Pin          // Set pin SData           
    End If   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)       
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1) 
    result = buf
End Function

Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
    result = false
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        If (data And 128) > 0 Then
            INDF2 = INDF2 Or SData.Pin      // Set pin SData
        Else
            INDF2 = INDF2 And SData.PinMask // clear pin SData   
        End If
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then data = data << 1 End If       
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)       
    If (INDF2 And SData.Pin) = 0 Then
        result = true
    End If
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
End Function
                     
Sub Sensirion_Reset()
Dim i As Byte
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    i = 0
    While i < 9
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
    Wend   
    Sensirion_Start
End Sub

Function Sensirion_Soft_Reset() As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_RESET)
End Function
 
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
    sensirion_status = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
    Sensirion_Reset
    result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
    result = result1 And Sensirion_Put_Byte(data)
End Function

Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
    result = false
    Sensirion_Reset
    Select data
        Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
        Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
    Else Exit
    End Select
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    Repeat
        ClrWDT       
        If (INDF2 And SData.Pin) = 0 Then
            Break
        End If
        Inc(i)
        DelayMS(1)       
    Until i > 500
    If i > 500 Then
        result = false
        Exit
    End If   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    result_h = Sensirion_Get_Byte(ACK)
    result_l = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
      T2 As Float = 0.00008,
      C1 As Float = -4.0,
      C2 As Float = 0.0405,
      C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
    result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
    buf.Byte0 = data_l
    buf.Byte1 = data_h   
    tx = (buf * 0.01) - 40.0
    result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
    If result = false Then
        temp = 0
        hum = 0
        Exit
    End If
    buf.Byte0 = data_l
    buf.Byte1 = data_h     
    rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
    rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
    If rh_true > 99.9 Then rh_true = 99.9 End If
    If rh_true < 0.0 Then rh_true = 0.0 End If
    temp = tx + 0.00001
    hum = rh_true
End Function

Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
      C2d As LongInt = 405,
      C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
  result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
  temp_d.Byte0 = data_l
  temp_d.Byte1 = data_h
  temp_d = temp_d - 4000
  result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
  If result = false Then
    temp_d = 0
    hum_d = 0
    Exit
  End If
  buf.Byte0 = data_l
  buf.Byte1 = data_h
  rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
  rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
  If rh_true > 9999 Then rh_true = 9999 End If
  If rh_true < 0 Then rh_true = 0 End If
  hum_d = Integer(rh_true)
End Function

Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
    k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
    result = (243.12 * k) / (17.62 - k)
End Function
=]  : 2 Home Made, MCU PIC18F458, MCP2515 CAN transceiver.

'''Available functions'''

=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]

For initialization you can choice between Sensirion_Init or Sensirion_Init_

You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]

!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL

// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3

// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"

Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer

ADCON0 = 0
CMCON  = $07                    // turn off comparators
ADCON1 = $0F                    // turn off analog inputs
MEMCON.7 = 1                    // disable external memory bus

Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2) 
                                          // Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
                                          // Data an Clock Pin must be at the same Port
                                          // This is a wrong configuration :
                                          // Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1)    // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
    NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
    If NoError Then
        buf = temperature * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C  ")
        buf = humidity * 100
        TempA = buf / 100
        TempB = buf Mod 100
        LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," %  ")
        dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)     
    Else
        LCD.WriteAt(1,1, " Error detected ")
        LCD.WriteAt(2,1, " Error detected ")       
    End If
    DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
******************************************************************************
*  Name    : Sensirion.BAS                                                  *
*  Author  : Medrea Florin Andrei                                            *
*  Notice  : Copyright (c) 2007 -YO2LIO-                                    *
*          : All Rights Reserved                                            *
*  Date    : 9/26/2007                                                      *
*                                                                            *
*  Copyright Notice                                                          *
*                                                                            *
*  This library For the SHT temperature And humidity sensors is based on the *
*  application datasheet Sample Code humidity sensor SHTxx from Sensirion.  *
******************************************************************************
}
Module Sensirion

Include "math"
Include "system"

Const NoACK As Byte = 1,
      ACK As Byte = 0,
      CMD_STATUS_REG_W As Byte = $06,
      CMD_STATUS_REG_R As Byte = $07,
      CMD_TEMP As Byte = $03,
      CMD_HUMIDITY As Byte = $05,
      CMD_RESET As Byte = $1E
     
Structure TPin
  Pin As Byte
  PinMask As Byte
End Structure

Structure TPort
  AddrPort As Word
  AddrTRIS As Word
End Structure
 
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte

Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pData)      // get pin address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get pin TRIS address
    SData.Pin = BitOf(pData)                // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = BitOf(pClock)              // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
End Sub

Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
    ClrWDT
    DelayMS(100)
    ClrWDT
    SPort.AddrPort = AddressOf(pPort)      // get port address
    SPort.AddrTRIS = SPort.AddrPort + 18    // get port TRIS address
    SData.Pin = 1 << pData                  // get pin number
    SData.PinMask = Not SData.Pin          // create pin number mask
    SClock.Pin = 1 << pClock                // get pin number
    SClock.PinMask = Not SClock.Pin        // create pin number mask 
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin
    INDF2 = INDF2 And SClock.PinMask        // clear pin   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    INDF2 = INDF2 And SClock.PinMask        // make output SClock
End Sub

Sub Sensirion_Start()
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)   
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    DelayUS(1)
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock   
End Sub

Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
    buf = 0
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        If (INDF2 And SData.Pin) > 0 Then
            buf = buf Or 1
        End If
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then buf = buf << 1 End If
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort
    If ack_ = 0 Then
        INDF2 = INDF2 And SData.PinMask    // clear pin SData
    Else
        INDF2 = INDF2 Or SData.Pin          // Set pin SData           
    End If   
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)       
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1) 
    result = buf
End Function

Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
    result = false
    FSR2 = SPort.AddrPort
    i = 0
    While i < 8
        If (data And 128) > 0 Then
            INDF2 = INDF2 Or SData.Pin      // Set pin SData
        Else
            INDF2 = INDF2 And SData.PinMask // clear pin SData   
        End If
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
        If i < 8 Then data = data << 1 End If       
    Wend
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SClock.Pin            // set pin SClock
    DelayUS(1)       
    If (INDF2 And SData.Pin) = 0 Then
        result = true
    End If
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    DelayUS(1)
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
End Function
                     
Sub Sensirion_Reset()
Dim i As Byte
    FSR2 = SPort.AddrPort
    INDF2 = INDF2 Or SData.Pin              // set pin SData
    INDF2 = INDF2 And SClock.PinMask        // clear pin SClock
    i = 0
    While i < 9
        INDF2 = INDF2 Or SClock.Pin        // set pin SClock
        DelayUS(1)       
        INDF2 = INDF2 And SClock.PinMask    // clear pin SClock
        DelayUS(1)
        Inc(i)
    Wend   
    Sensirion_Start
End Sub

Function Sensirion_Soft_Reset() As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_RESET)
End Function
 
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
    Sensirion_Reset
    result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
    sensirion_status = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
    Sensirion_Reset
    result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
    result = result1 And Sensirion_Put_Byte(data)
End Function

Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
    result = false
    Sensirion_Reset
    Select data
        Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
        Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
    Else Exit
    End Select
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 Or SData.Pin              // make input SData
    FSR2 = SPort.AddrPort
    i = 0
    Repeat
        ClrWDT       
        If (INDF2 And SData.Pin) = 0 Then
            Break
        End If
        Inc(i)
        DelayMS(1)       
    Until i > 500
    If i > 500 Then
        result = false
        Exit
    End If   
    FSR2 = SPort.AddrTRIS
    INDF2 = INDF2 And SData.PinMask        // make output SData
    FSR2 = SPort.AddrPort 
    INDF2 = INDF2 And SData.PinMask        // clear pin SData
    result_h = Sensirion_Get_Byte(ACK)
    result_l = Sensirion_Get_Byte(ACK)
    sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function

Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
      T2 As Float = 0.00008,
      C1 As Float = -4.0,
      C2 As Float = 0.0405,
      C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
    result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
    buf.Byte0 = data_l
    buf.Byte1 = data_h   
    tx = (buf * 0.01) - 40.0
    result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
    If result = false Then
        temp = 0
        hum = 0
        Exit
    End If
    buf.Byte0 = data_l
    buf.Byte1 = data_h     
    rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
    rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
    If rh_true > 99.9 Then rh_true = 99.9 End If
    If rh_true < 0.0 Then rh_true = 0.0 End If
    temp = tx + 0.00001
    hum = rh_true
End Function

Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
      C2d As LongInt = 405,
      C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
  result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
  temp_d.Byte0 = data_l
  temp_d.Byte1 = data_h
  temp_d = temp_d - 4000
  result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
  If result = false Then
    temp_d = 0
    hum_d = 0
    Exit
  End If
  buf.Byte0 = data_l
  buf.Byte1 = data_h
  rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
  rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
  If rh_true > 9999 Then rh_true = 9999 End If
  If rh_true < 0 Then rh_true = 0 End If
  hum_d = Integer(rh_true)
End Function

Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
    k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
    result = (243.12 * k) / (17.62 - k)
End Function
=]