PRU Uart read using Rx interrupt

I have modified my earlier read program to use interrupts from the PRU Uart to the PRU.

See the Code at:https://github.com/jstampfl/PruUart_Int

The program for the PRU depends on the C program to do some of the initialization of the PRU interrupts. The PRU code initializes the Uart Rx interrupt which is System Event 6. The System Event 6 is mapped to channel 0 which is mapped to Host Interrupt 0 which appears on r31.t30 of the PRU.

.setcallreg r2.w0  //  Just out of habit.
.origin 0
.entrypoint TB
TB:
       ldi r20,0
       ldi r21,0
       ldi r22,0
       mov r0,0
       sbbo r0,r20,r21,4
       zero &r0,64             //zero 16 registers
TB05:
       sbbo r0,r20,r21,64      //zero some of pru0 local memory
       add r21,r21,64          // for linux string functions
       add r22,r22,1
       qbgt TB05,r22,20

       jmp ISET                //this is the routine to setup
                               //interrupts

TB1:
// See section 8.2.1 in the AM335x PRU-ICSS Reference Guide
//    for formula to compute the Uart divisor
       ldi r3,4               //Uart divisor  =1250 = 0x04E2
       sbco r3,c7,0x24,4      // 9600 at 16x
       ldi r3,0xE2            //in DLL & DLH
       sbco r3,c7,0x20,4

       ldi r3,1
       sbco r3,c7,4,4        // turn on receiver interupts
       lbco r3,c7,8,4        //read IIR to clear

       ldi r3,0x3             //LCR = 3, 8 none & 1
       sbco r3,c7,0x0C,4      //

       mov r3,0x6001          //Power &
       sbco r3,c7,0x30,4      // = tx on, rx on & Free to enable
       mov r5,0xFFFFFF
       ldi r4,0
       
       ldi r4,0              //zero some registers
       ldi r5,0
       ldi r3,0
       ldi r20,0
       ldi r21,0
       mov r9,276
       ldi r11,0

       ldi r24,0
       call RSET             // routine to clear & enable interrupts
                             //  and  get a character.

TB2:
       qbbc TB2,r31.t30     // spin here for interrupt

       call RSET            // clear, enable & read

       sbbo r3,r5,r4,1        // and put in buffer
       add r4,r4,1

       qbne TB2,r3,0xA        // do until nl received
       sbbo r20,r5,r4,1       // put null to terminate
       ldi r4,0               // zero buffer pointer
       mov r31.b0,35          // signal linux
       jmp TB2

TB9:    // an exit point used in debugging.  Not used here
       ldi r18,332            // offset to write errno
       sbbo r23,r18,0,4       // used for debugging
       HALT

ISET: //  This section is to initialize the interrupts
       mov r19,336            //point to printf in mem
       lbco r13,c4,4,4        //enable OCP master port
       clr r13,r13,4
       sbco r13,c4,4,4

       lbco r13,c4,0x2C,4        //disable MII_RT Events
       ldi r13,0                 // MII_RT Register in Pru cfg
       sbco r13,c4,0x2C,4

       mov  r15,0x10            //Turn off global interrupts
       lbco r14,c0,r15,4
       clr r14,r14,0
       sbco r14,c0,r15,4

       mov r15,0x400            //set up Channel map
       mov r14,0x09090909       // first map all unused events to
       sbco r14,c0,r15,4        //  Channel 9
       mov r15,0x408
       sbco r14,c0,r15,4
       mov r15,0x40C            // skiping offsets 410 & 414, they
       sbco r14,c0,r15,4        // were set by the C program via prussdrv
       mov r18,0x43C
       mov r15,0x414
TB43:
       add r15,r15,4
       sbco r14,c0,r15,4
       qbgt TB43,r15,r18
       mov r14,0x00000909
       mov r15,0x400            // now do offset 400
       sbco r14,c0,r15,4        // only allow events 2 & 3
       mov r14,0x09000000
       mov r15,0x404            // now do 404, which has the
       sbco r14,c0,r15,4        // entries for 4,5,6 the Uart interrupts

       ldi r15, 0x24             //clear all events
       call ALLEVT

       mov  r15,0x10
       ldi r14,0x1
       sbco r14,c0,r15,4

       ldi r15,0x28              // enable all events
       call ALLEVT
       jmp TB1

RSET:  // Routine to clear & enalbe system events, also host interrupts
       //  and read IIR in the Uart registers to clear the interrupt from
       // the Uart.  Also gets the character from the Uart buffer.
       mov r24,r2           // Save return address
                            // so can call ALLEVT
       mov r15,0x24         //  to clear system event
       call ALLEVT
       mov r15,0x28         //  to enable system event
       call ALLEVT
       lbco r3,c7,8,4        //read IIR to clear
       lbco r3,c7,0,4         //data is ready, get from RBR
       ldi r17,1
       sbco r17,c7,4,4        // turn on receive interupts
       mov r15,0x34          //HIEISR  to enable host interrupt
       ldi r14,0
       sbco r14,c0,r15,4
       mov r15,0x34          //HIEISR  to enable host interrupt
       ldi r14,2
       sbco r14,c0,r15,4
       mov r15,0x34          //HIEISR  to enable host interrupt
       ldi r14,3
       sbco r14,c0,r15,4
       mov r2,r24            // restore return address
       ret
       
ALLEVT:  //Insert the system envent in the proper resiger
         // register r15 must have the register offset
         // will only work with registers that take the event number
         // if you want to handle multiple events, just add 
         //   ldi r14,"sys event no."
         //   sbco r14, c0 ,r15,4

       ldi r14,0x6
       sbco r14, c0 ,r15,4
       ret