Page 1 of 1

USART2 with ISRRX

Posted: Mon May 04, 2015 9:03 am
by Coccoliso
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

Re: USART2 with ISRRX

Posted: Mon May 04, 2015 11:27 am
by Jerry Messina
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.

Re: USART2 with ISRRX

Posted: Mon May 04, 2015 11:55 am
by Coccoliso
Thanks Jerry :wink: