here is a rx ring buffer example I worked on with someone on one of the pbp forums some years back.
its limited to 256 bytes max buffer size.
Code:
INCLUDE "DT_INTS-18.bas"
'INCLUDE "ReEnterPBP-18.bas"
ASM ;
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX1_INT, myint, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
TRISB.7=0 ;DEBUG
LATB.7=1 ;DEBUG
index_in VAR BYTE bank0 ' Pointer - next empty location in buffer
index_out VAR BYTE bank0 ' Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 ' Error flag
UartFlag VAR errflag.0
BufferFlag VAR errflag.1
buffer_size CON 256 ' Sets the size of the ring buffer
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
BufChar VAR BYTE ' Stores the character retrieved from the buffer
' trisC.6=0 ;tx1
RCSTA1 = $90 ' Enable serial port & continuous receive
' TXSTA1 = $24 ' Enable transmit, BRGH = 1
SPBRG1 = 56 ' 38400 Baud @ 48MHz, -0.16%
SPBRGH1 = 1
BAUDCON1.3 = 1 ' Enable 16 bit baudrate generator
GoTo start ' Skip around interrupt handler
Asm
myint
; Check for hardware overrun error
btfsc RCSTA1,OERR ; Check for usart overrun
bra usart_err ; jump to assembly error routine
; Test for buffer overrun
incf _index_in,W ; Increment index_in to W
subwf _index_out,W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
bra buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it's outside the ring buffer
incf _index_in,F ; Increment index_in to index_in
movf _index_in,W ; Move new index_in to W
sublw _buffer_size-1; Subtract index_in from buffer_size-1
btfss STATUS, C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw High _buffer ;Store the High byte of buffer to FSR0H
movwf FSR0H
movlw Low _buffer ; Get the Low byte of buffer[0]
addwf _index_in,W ; Add index_in to point to next empty slot
movwf FSR0L ; Store Low byte of pointer in FSR0
; Read and store the character from the USART
movf RCREG1,W ; Read the received character
movwf INDF0 ; Put the received character in FSR0 location
BTFSC PIR1,TX1IF ;ANY MORE ?
BRA myint
finished
RST?RP
INT_RETURN
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
bsf _errflag,0 ; Set the USART flag
movf RCREG1, W ; Trash the received character
bra finished ; Restore state and return to program
EndAsm
start:
PAUSE 3000 ' Let ME CONNECT PICKIT UART MODULE
Debug "Start",13 ,13
index_in = 0 ' Initialize ringbuffer variables
index_out = 0
GOSUB error ;CLR AND RESET EUART
@ INT_ENABLE RX_INT ; Enable USART RX Interrupts
Main:
DEBUG "Main", 13 ,13
MainLoop:
display: ' dump the buffer to the terminal
IF errflag Then GOSUB error ' Goto error routine if needed
IF index_in = index_out Then mainloop ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
debug bufchar ' Send the character to terminal
GoTo display ' Check for more characters in buffer
' Get a character from the buffer
getbuf: ' Move the next character in buffer to bufchar
intcon = 0 ' Disable interrupts while reading buffer
index_out = index_out + 1 ' Increment index_out pointer (0 to 63)
IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
bufchar = buffer[index_out] ' Read buffer location(index_out)
INTCON = %11000000 ' Enable interrupts
Return
' Display an error
error: ' Display error message
INTCON = 0 ' Disable interrupts while in the error routine
IF errflag.1 Then ' Determine the error
debug "B!",13,13 ' Display buffer error on line-2
Else
debug "U!",13,13 ' Display usart error on line_2
EndIF
PIR1.4=0
errflag = 0 ' Reset the error flag
RCSTA1.4=0 'CREN = 0 Disable continuous receive to clear hardware error
RCSTA1.4=1 'CREN = 1 Enable continuous receive
INTCON = %11000000 ' Enable interrupts
GoTo RETURN ' repeat
;clear any rcsta error
Bookmarks