Skip to content

Commit

Permalink
added example ipes
Browse files Browse the repository at this point in the history
  • Loading branch information
jstampfl committed Jul 25, 2014
1 parent 0fe94b7 commit 023e1d0
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 4 deletions.
6 changes: 5 additions & 1 deletion README.md
@@ -1,4 +1,4 @@
PruIEP_Int 2 examples
PruIEP_Int 3 examples
========
Examples of using the PRUSS IEP timer interrupt on the BEAGLEBONE to toggle a pin.

Expand All @@ -13,3 +13,7 @@ prujts1-00A0.dts - The device tree overlay to enable the PRUSS and set P9.31 for
iep2.c - Initialize the Pruss, initializes the interrupt system, waits for the pru to finish executionjj

iep2.p - The PRUSS initializes the IEP interrupt for CMP0 (compare register 0). and CMP1 On CMP1 interrupt clear the pin, on CMP0 set the pin and reset the counter.

ieps.c - Initialize the Pruss, waits 30 seconds and exits. Does not initialize the PRUSS INTC

ieps.c - Initialize the PRUSS INTC interrupt system. Initializes the IEP interrupts for CMP0 & CMP1. Toggles P9.31 using interrupts form CMP0 & CMP1.
132 changes: 132 additions & 0 deletions ieps.c
@@ -0,0 +1,132 @@
/*ieps.c - PRUSS IEP, 2 interrupts
*
* The C-code is derived from:
* PRU_memAccessPRUDataRam.c
*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/*
* ============================================================================
* Copyright (c) Texas Instruments Inc 2010-12
*
* Use of this software is controlled by the terms and conditions found in the
* license agreement under which this software has been supplied or provided.
* ============================================================================
*/

/*****************************************************************************
* Copyright (c) John Stampfl 2014
* This code is provided for your reading pleasure.
* anyother use is at your own risk.
*
*pu.c uses the PRUSS to read data from
*pu.c the ADAFRUIT Ultimate GPS
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <prussdrv.h>
#include <pruss_intc_mapping.h>

#define PRU_NUM 0
#define AM33XX

static int LOCAL_exampleInit ( unsigned short pruNum );
static void *pruDataMem;
static unsigned int *pruDataMem_int;
static char *pdata;

int main (void)
{
int ret1,i,cnt;
int fd,len,msig,messno;
short ret2;

unsigned int ret,value,en = 0;
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;


printf("\nINFO: Starting %s example.\r\n", "pt - SR04");

/* Initialize the PRU */
prussdrv_init ();

/* Open PRU Interrupt */
ret = prussdrv_open(PRU_EVTOUT_0);
if (ret)
{
printf("prussdrv_open open failed\n");
return (ret);
}

/* Get the interrupt initialized */
//prussdrv_pruintc_init(&pruss_intc_initdata);

/* Initialize example */
printf("\tINFO: Initializing example.\r\n");
LOCAL_exampleInit(PRU_NUM);

/* Execute example on PRU */
printf("\tINFO: Executing example.\r\n");
prussdrv_exec_program (PRU_NUM, "./ieps.bin");
pruDataMem_int[66] = 0;
printf("\tINFO: Waiting for \r\n");
sleep(30);
prussdrv_pru_disable (PRU_NUM);
prussdrv_exit ();
return(0);

}

static int LOCAL_exampleInit ( unsigned short pruNum )
{
//Initialize pointer to PRU data memory
if (pruNum == 0)
{
prussdrv_map_prumem (PRUSS0_PRU0_DATARAM, &pruDataMem);
}
else if (pruNum == 1)
{
prussdrv_map_prumem (PRUSS0_PRU1_DATARAM, &pruDataMem);
}

pdata=(char*) pruDataMem;
pruDataMem_int = (unsigned int*) pruDataMem;
return(0);
}

138 changes: 138 additions & 0 deletions ieps.p
@@ -0,0 +1,138 @@
//ieps.p - setup PRU INTC without help of Linux Prussdrv
// All the setup is done by the pru. Still does the same
// as iepx.p, Initalizes CMP0 and toggle the pin on interrupt
// and on CMP1 hitting compare value.
// toggles pin p9.31 - attached to r30.t0 - mode 5 output
//
// Changed the loop time to 1 second.
//
.setcallreg r2.w0 // Going to use r30
.origin 0
.entrypoint TB
TB:
set r30,r30, 0 //turn on
jmp ASET //this is the routine to setup

TB1:
ldi r17,0 // init loop counter
call RSET // routine to clear & enable interrupts

TB2:
qbbc TB2,r31.t30 // spin here for interrupt
lbco r3,c26,0x44,4 //get status, which interrupt
qbbs TB5,r3.t0 // check for CMP0
TB3:
clr r30,r30,0 // CMP1 interrupt
TB4:
call RSET // clear, enable
add r17,r17,1 //loop counter
qblt TB9,r17,50 //loop 50 times
jmp TB2

TB5:
set r30,r30,0 // CMP0 interrupt
jmp TB4

TB9: // exit point
clr r30,r30,0
HALT

ASET: // This section is to initialize the interrupts

// INITIALIZE` THE PRU INTC

mov r15,0xD00 //offset for SIPR0
mov r14,0xFFFFFFFF // must be oll bits = one
sbco r14,c0,r15,4
mov r15,0xD04 //offset for SIPR1
sbco r14,c0,r15,4

mov r15,0xD80 //offset for SITR0
mov r14,0 // must be zero
sbco r14,c0,r15,4
mov r15,0xD84 //offset for SITR1
sbco r14,c0,r15,4

// INITIALIZE IEP INTERRUPTS

mov r14,0x0BEBC200 //For CMP0, compare trigger
sbco r14,c26,0x48,4
mov r14,0x05F5E100 //For CMP1, compare trigger
sbco r14,c26,0x4c,4
mov r14,0x7 // enable CMP0 & CPM1, and enable
sbco r14,c26,0x40,4 // counter reset on event
mov r14,0x3
sbco r14,c26,0x44,4 // clear status for CMP0 & CMP1
lbco r14,c26,0x4,4
sbco r14,c26,0x4,4 // clear GLOBAL status, overflow
mov r14,0x111 // enable IEP counter, inc 1
sbco r14,c26,0,4

// DONE WITH IEP SETUP

// SETUP CHANNEL MAP
// map SysEvent to Channel 0, leave 16 - 23 alone set by Linux
mov r18,0x43C
mov r15,0x3FC //set up Channel map
TB43:
mov r14,0x09090909 // first map all events to
add r15,r15,4 // to channel 9
sbco r14,c0,r15,4
qbgt TB43,r15,r18
mov r14,0x00090909 // map SysEvt 7 to channel 0
mov r15,0x404 // now do 404, which has the
sbco r14,c0,r15,4 // entries for 4,5,6,7

// Done with Channel Map, Host Interrupt Map now
// Host Interrupt 0 - 3 were setup by Linux

mov r14,0x09090900 // map channels 1,2,3 to Host Int 9
// and channel 0 to host 0
mov r15,0x800
sbco r14,c0,r15,4
mov r14,0x09090909 // map channels 4,5,6,7 to Host Int 9
mov r15,0x804
sbco r14,c0,r15,4
mov r14,0x00000909 // map channel 8 & 9 to Host Int 9
mov r15,0x808
sbco r14,c0,r15,4

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

ldi r15,0x28 // enable all events
call ALLEVT
ldi r14,1
ldi r15,0x10
sbco r14,c0,r15,4 //turn on global interrupts
ldi r14,0xF
ldi r15,0x1500
sbco r14,c0,r15,4 //turn on interrupts
jmp TB1

RSET: // Routine to clear & enable system events, also host interrupts
mov r24,r2 // Save return address
// so can call ALLEVT
lbco r14,c26,0x4,4 // clear GLOBAL_STATUS
sbco r14,c26,0x4,4
lbco r14,c26,0x44,4 // clear CMP_STATUS
sbco r14,c26,0x44,4
lbco r14,c26,0x44,4
mov r15,0x24 // to clear system event
call ALLEVT
mov r15,0x28 // to enable system event
call ALLEVT

mov r2,r24 // restore return address
ret

ALLEVT: //Insert the system envent in the proper INTC register
// 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,0x7
sbco r14, c0 ,r15,4
ret
30 changes: 27 additions & 3 deletions notes
@@ -1,4 +1,4 @@
Notes for PruIEP_Int
Notes for PruIEP_Int - Three examples

Hardware:
========================================================================
Expand All @@ -24,13 +24,37 @@ Devicetree:
========================================================================
prujts1-00A0.dts - enables the PRUSS and configures P9.31 (offset 0x190) for PRU input.

Program:
Program for example1
========================================================================
iepx.c - initializes the PRU and PRU INTC for Linux interrupt 0. Waits for Host Interrupt to signal PRU program
completion

iepx.p - Initializes the PRU IEP counter and cmp0 with interrupt on cmp0 match. Toggles P9.31 on IEP interrupt.
iepx.p - Initializes the PRU IEP counter and CMP0 with interrupt on CMP0 match. Toggles P9.31 on IEP interrupt.


The PRU program iep2.p depends on the Linux program iepx.c to initialize the PRU INTC system. Then adds initialization
for the IEP interrupt.

Program for example2
========================================================================
iep2.c - initializes the PRU and PRU INTC for Linux interrupt 0. Waits for Host Interrupt to signal PRU program
completion

iep2.p - Initializes the PRU IEP counter,CMP0 with interrupt on CMP0 match and on CMP1 match. Toggles P9.31. CMP0 match puts high value to the pin and resets the counter. CMP1 match puts low value to the pin. The values set
means CMP0 interrupts every 4 seconds, and CMP1 interrupts 2 seconds after the counter is reset. Each loop is wait for interrrupt, if CMP1 clear the value and wait for interrupt, if CMP0 set the value and reset the counter and wait for interrupt.


The PRU program iepx.p depends on the Linux program iepx.c to initialize the PRU INTC system. Then adds initialization
for the IEP interrupt.

Program for example3
========================================================================
ieps.c - Starts the PRUSS & Waits 30 seconds.


ieps.p - Initializes the PRUSS INTC interrupt system. Initializes the PRU IEP counter,CMP0 with interrupt on CMP0 match and on CMP1 match. Toggles P9.31. CMP0 match puts high value to the pin and resets the counter. CMP1 match puts low value to the pin. The values set means CMP0 interrupts every 1 seconds, and CMP1 interrupts .5 seconds after the counter is reset. Each loop is: wait for interrrupt, if CMP1, clear the value and wait for interrupt, if CMP0, set the value and reset the counter and wait for interrupt.


The PRU program initializes the PRU INTC system and initializes the IEP interrupt.

This is the same program as iep2.ps above with the loop time changed and initializing the PRU INTC instead of depending on Linux & PRUSSDRV.

0 comments on commit 023e1d0

Please sign in to comment.