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