USART2 with ISRRX

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
Coccoliso
Posts: 152
Joined: Mon Feb 17, 2014 10:34 am

USART2 with ISRRX

Post by Coccoliso » Mon May 04, 2015 9:03 am

I want to use the ISRRX on second USART on a 46K22 and I rebuilt a ISSRX for the second USART renaming it UartBuffer2.bas
I still have not the MPU so I rely only on compilation and I noticed that in the USART2.BAS module there is a specific reference to 18F26K22 (which is exactly the same family of 18F46K22) and refers to TRISB instead of TRISG.

1) I can safely add the 18F46K22 to this verification?
2) Do you think that attachment source (ISRRX> UsartBuffer2) is correct?

It derives from a module of David John Barker wrote for Firewing ( with RunTo, LookFor very useful functions ) which I tried to apply what has already been written in ISRRX.BAS standard module.
I ask this with regard to overrun and RX2Priority setting for which are quite uncertain :(

Code: Select all

Module UARTBuffer2

// import USART library...
Include "USART2.bas"

// set interrupt priority level...
#if IsOption(RX2_PRIORITY) And Not (RX2_PRIORITY in (ipLow, ipHigh))
   #error RX2_PRIORITY, "Invalid option. Priority must be ipHigh or ipLow."
#endif
#option RX2_PRIORITY = ipHigh
Const PriorityLevel = RX2_PRIORITY

// size of the RX buffer...
#if IsOption(RX2_BUFFER_SIZE) And Not (RX2_BUFFER_SIZE in (1 to 1024))
   #error RX2_BUFFER_SIZE, "Invalid option. Buffer size must be between 1 and 256 (bytes)."
#endif
#option RX2_BUFFER_SIZE = 64      
Public Const BufferSize = RX2_BUFFER_SIZE


// local variables and aliases...
Dim 
   FBuffer(BufferSize) As Byte,
   FIndexIn As Byte,
   FIndexOut As Byte,
   FByteRead As Byte,
   FProcessByte As Boolean,
   FMaybeOverrun As Boolean
 
// public variables and aliases...   
Public Dim   
   USARTOverrun As USART2.Overrun,
   BufferOverrun As Boolean,
   DataByte As FByteRead,
   DataChar As FByteRead.AsChar,
   ProcessByte As FProcessByte

{
****************************************************************************
* Name    : OnRX (PRIVATE)                                                 *
* Purpose : Interrupt Service Routine (ISR) to buffer incoming data        *
****************************************************************************
}
Interrupt OnRX(PriorityLevel)
   Dim FSRSave As Word
   FSRSave = FSR0
   BufferOverrun = FMaybeOverrun
   If Not USART2.Overrun Then
      FByteRead = USART2.RCRegister
      If Not BufferOverrun Then
         FProcessByte = true
         
         // execute handler...
         
         If FProcessByte Then
            FBuffer(FIndexIn) = FByteRead
            Inc(FIndexIn)
	        If FIndexIn > Bound(FBuffer) Then
               FIndexIn = 0
            EndIf
            FMaybeOverrun = (FIndexIn = FIndexOut) 
         EndIf   
      EndIf
   EndIf	     
   FSR0 = FSRSave
End Interrupt
{
****************************************************************************
* Name    : Initialize                                                     *
* Purpose : Initialize buffering - with optional OnData event handler      *
****************************************************************************
}
Public Sub Initialize()
   FIndexIn = 0
   FIndexOut = 0
   FMaybeOverrun = false
   BufferOverrun = false
   USART2.ClearOverrun
   #if RX2_PRIORITY = ipLow
   USART2.RCIPHigh = false
   #endif
   USART2.RCIEnable = true
   Enable(OnRX)
End Sub
{
****************************************************************************
* Name    : Reset                                                          *
* Purpose : Reset module                                                   *
****************************************************************************
}
Public Sub Reset()
   Disable(OnRX)
   Initialize()
End Sub	  
{
****************************************************************************
* Name    : Start                                                          *
* Purpose : Start interrupt handling                                       *
****************************************************************************
}
Public Sub Start()
   Enable(OnRX)
End Sub
{
****************************************************************************
* Name    : Stop                                                           *
* Purpose : Stop interrupt handling                                        *
****************************************************************************
}
Public Sub Stop()
   Disable(OnRX)
End Sub
{
****************************************************************************
* Name    : DataAvailable                                                  *
* Purpose : Check to see if there is data in the buffer                    *
****************************************************************************
}
Public Function DataAvailable() As Boolean
'   Disable(OnRX)
   Result = FIndexIn <> FIndexOut
'   Enable(OnRX)
End Function
{
****************************************************************************
* Name    : Overrun                                                        *
* Purpose : Returns true if RC register or buffer has overrun, false       *
*         : otherwise                                                      *
****************************************************************************
}
Public Function Overrun() As Boolean
   Result = USART2.Overrun Or BufferOverrun
End Function
{
****************************************************************************
* Name    : GetByte (PRIVATE)                                              *
* Purpose : Get a single byte from the buffer                              *
****************************************************************************
}
Function GetByte() As Byte
   FMaybeOverrun = false
   Result = FBuffer(FIndexOut)
   Inc(FIndexOut)
   If FIndexOut > Bound(FBuffer) Then
      FIndexOut = 0
   EndIf   
End Function
{
****************************************************************************
* Name    : ReadByte                                                       *
* Purpose : Read a single byte from the buffer                             *
****************************************************************************
}
Public Function ReadByte() As Byte
   Disable(OnRX)
   Result = GetByte
   Enable(OnRX)
End Function
{
****************************************************************************
* Name    : ReadWord                                                       *
* Purpose : Read a word from the buffer                                    *
****************************************************************************
}
Public Function ReadWord() As Word
   Disable(OnRX)
   Result.Bytes(0) = GetByte
   Result.Bytes(1) = GetByte
   Enable(OnRX)
End Function
{
****************************************************************************
* Name    : ReadLongWord                                                   *
* Purpose : Read a long word from the buffer                               *
****************************************************************************
}
Public Function ReadLongWord() As LongWord
   Disable(OnRX)
   Result.Bytes(0) = GetByte
   Result.Bytes(1) = GetByte
   Result.Bytes(2) = GetByte
   Result.Bytes(3) = GetByte
   Enable(OnRX)
End Function
{
****************************************************************************
* Name    : ReadFloat                                                      *
* Purpose : Read a floating point number from the buffer                   *
****************************************************************************
}
Public Function ReadFloat() As Float
   Disable(OnRX)
   Result.Bytes(0) = GetByte
   Result.Bytes(1) = GetByte
   Result.Bytes(2) = GetByte
   Result.Bytes(3) = GetByte
   Enable(OnRX)
End Function
{
****************************************************************************
* Name    : ReadStr                                                        *
* Purpose : Read a string from the buffer. Optional parameter pTerminator  *
*         : to specify the input string terminator character. The function *
*         : returns the number of characters read                          *
****************************************************************************
}
Public Function ReadStr(ByRef pText As String, pTerminator As Char = null) As Byte
   Dim Ch As Char
   Dim Text As POSTINC0
   
   Disable(OnRX)
   FSR0 = AddressOf(pText)
   Result = 0
   Repeat
      Ch = GetByte
      If Ch <> pTerminator Then
         Text = Ch
         Inc(Result)
      EndIf   
   Until Ch = pTerminator
   Text = 0
   Enable(OnRX)
End Function

'****************************************************************************
'* Name    : LookFor                                                        *
'* Purpose : Look for a string - but will not eat input bytes               *
'****************************************************************************
Public Function LookFor(str As String) As Boolean
   Dim indexIn As Word 
   Dim indexOut As Word
   Dim index As Byte
   Dim data As Byte 
   indexIn = FIndexIn
   indexOut = FIndexOut 
   index = 0
   Result = False
   While (indexIn <> indexOut) And Not Result
      data = FBuffer(indexOut)
      Inc(indexOut)
      If indexOut > Bound(FBuffer) Then 
        indexOut = 0
      End If
      If str(index) = Char(data) Then
         Inc(index)
      Else
         index = 0
      End If  
      If str(index) = Char(0) Then
         Result = True
      Else
         Result = False
      End If
   End While  
End Function

'****************************************************************************
'* Name    : RunTo                                                          *
'* Purpose : Look for a string - eats input bytes                           *
'****************************************************************************
Public Function RunTo(str As String) As Boolean
   Dim index As Byte
   Dim data As Byte
   Index = 0
   Result = False
   While DataAvailable And Not Result
      data = ReadByte()
      If str(index) = Char(data) Then
         Inc(index)
      Else
         index = 0
      End If  
      If str(index) = Char(0) Then
        Result = True
      Else
        Result = False
      EndIf
   End While  
End Function

FIndexOut = 0
FIndexIn = 0

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: USART2 with ISRRX

Post by Jerry Messina » Mon May 04, 2015 11:27 am

With regard to the pins you can change the mapping, but it's very device specific.

Code: Select all

 #if _device in (18F26K22)
   RCInput As TRISB.Booleans(7),   //    as TRISG (2)
   TXInput As TRISB.Booleans(6)    //    as TRISG (1)   
 #elseif _device in (18F46K22)
   RCInput As TRISD.Booleans(7),   //    as TRISD (2)
   TXInput As TRISD.Booleans(6)    //    as TRISD (1)   
 #else
   RCInput As TRISG.Booleans(2),   //    as TRISG (2)
   TXInput As TRISG.Booleans(1)    //    as TRISG (1)
 #endif
The rest of the code looks like it would be ok. Just remember to set the priorities to different levels if you're using both USART and USART2.

User avatar
Coccoliso
Posts: 152
Joined: Mon Feb 17, 2014 10:34 am

Re: USART2 with ISRRX

Post by Coccoliso » Mon May 04, 2015 11:55 am

Thanks Jerry :wink:

Post Reply