Using the PRU is a round about way to get regular sampling. The ADC can be 
configured to sample at a regular rate and place samples in a FIFO and 
interrupt as the FIFO fills. The PRU isn't needed. See the TRM.

On Thursday, February 05, 2015 12:10:38 celso maia wrote:
> I got one error, and I don't know how to solve this.
> 
> "ERROR: Sampling period is required by second"
> 
> Anyone can help me?
> 
> Em terça-feira, 8 de abril de 2014 07:15:31 UTC-3, Youngtae Jo escreveu:
> > I've tried to find some example of ADC reading by PRU for my project, but
> > I couldn't find it.
> > And I made that of source code and attach here for some people who have
> > the same problem with me.
> > I hope it will be helpful.
> > 
> > [ AM335x ARM-CORE PRU ADC Example ]
> > 
> >  - Sequence of example
> >  1. Install compiling environment of PRU
> >  2. Enable PRU
> >  3. Enable ADC
> >  4. Example source
> >  
> >     - This example source collects ADC data from AIN0 pin with 16khz
> > 
> > sampling rate.
> > - The collected data are saved into "Results.txt" file.
> > - The example source are "Makefile", "ADCCollector.c", "ADCCollector.p",
> > "ADCCollector.hp"
> > 
> > [ Install compile environment ]
> > 
> >  1. Get a copy of the am335x_pru_package ->
> > 
> > https://github.com/beagleboard/am335x_pru_package
> > 
> >     You also can download the am335x_pru_package here ->
> > 
> > https://github.com/beagleboard/am335x_pru_package/archive/master.zip
> > 
> >  2. If you downloaded the archive, unpack it somewhere under your home
> > 
> > directory.
> > 
> >  3. Make a new directory /usr/include/pruss/ and copy the files prussdrv.h
> >  
> >     and pruss_intc_mapping.h into it (from
> > 
> > am335x_pru_package-master/pru_sw/app_loader/include).
> > Check the permissions; if you used the .zip file, these headers will
> > likely have the execute bits on.
> > It doesn't really hurt anything, but is certainly not what you want.
> > 
> >  4. Change directory to
> > 
> > am335x_pru_package-master/pru_sw/app_loader/interface
> > 
> >     then run: CROSS_COMPILE= make (note the space between the = and the
> > 
> > command).
> > 
> >  5. The previous step should have created four files in
> > 
> > am335x_pru_package-master/pru_sw/app_loader/lib: libprussdrv.a,
> > libprussdrvd.a, libprussdrvd.so and libprussdrv.so.
> > 
> >     Copy these all to /usr/lib then run ldconfig.
> >  
> >  6. Change directory to am335x_pru_package-master/pru_sw/utils/pasm_source
> >  
> >     then run source linuxbuild to create a pasm executable one directory
> > 
> > level up.
> > 
> >  - If linuxbuild doesn't have permission to execution, give the permission
> > 
> > by run this
> > 
> >    : chmod +x linuxbuild
> > 
> > Copy it to /usr/bin and make sure you can run it.
> > If you invoke it with no arguments, you should get a usage statement.
> > 
> > [ Enable PRU ]
> > 
> >  Before using PRU, we need to enable the PRU core, you can do it as shown
> > 
> > below
> > 
> >  # echo BB-BONE-PRU-01 > /sys/devices/bone_capemgr.8/slots
> > 
> > [ Enable ADC ]
> > 
> >  Before using ADC, we also need to enable ADC, you can do it as shown
> >  below
> >  # echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots
> > 
> > [ ADC Example - Makefile]
> > CFLAGS+=-Wall -Werror
> > LDLIBS+= -lpthread -lprussdrv
> > 
> > all: ADCCollector.bin ADCCollector
> > 
> > clean:
> > rm -f ADCCollector *.o *.bin
> > 
> > ADCCollector.bin: ADCCollector.p
> > pasm -b $^
> > 
> > ADCCollector: ADCCollector.o
> > 
> > [ ADC Example - ADCCollector.p]
> > // Developed by Youngtae Jo in Kangwon National University (April-2014)
> > 
> > // This program collects ADC from AIN0 with certain sampling rate.
> > // The collected data are stored into PRU shared memory(buffer) first.
> > // The host program(ADCCollector.c) will read the stored ADC data
> > // This program uses double buffering technique.
> > // The host program can recognize the buffer status by buffer status
> > variable
> > // 0 means empty, 1 means first buffer is ready, 2 means second buffer is
> > ready.
> > // When each buffer is ready, host program read ADC data from the buffer.
> > 
> > 
> > .origin 0 // offset of the start of the code in PRU memory
> > .entrypoint START // program entry point, used by debugger only
> > 
> > #include "ADCCollector.hp"
> > 
> > #define BUFF_SIZE 0x00000FA0 //Total buff size: 4kbyte(Each buffer has
> > 2kbyte: 500 piece of data)
> > #define HALF_SIZE BUFF_SIZE / 2
> > 
> > #define SAMPLING_RATE 16000 //Sampling rate(16khz)
> > #define DELAY_MICRO_SECONDS (1000000 / SAMPLING_RATE) //Delay by sampling
> > rate
> > #define CLOCK 200000000 // PRU is always clocked at 200MHz
> > #define CLOCKS_PER_LOOP 2 // loop contains two instructions, one clock
> > each
> > #define DELAYCOUNT DELAY_MICRO_SECONDS * CLOCK / CLOCKS_PER_LOOP / 1000 /
> > 1000 * 3
> > 
> > .macro DELAY
> > 
> >     MOV r10, DELAYCOUNT
> >     
> >     DELAY:
> >         SUB r10, r10, 1
> >         QBNE DELAY, r10, 0
> > 
> > .endm
> > 
> > .macro READADC
> > 
> >     //Initialize buffer status (0: empty, 1: first buffer is ready, 2:
> > second buffer is ready)
> > 
> >     MOV r2, 0
> >     SBCO r2, CONST_PRUSHAREDRAM, 0, 4
> >     
> >     INITV:
> >         MOV r5, 0 //Shared RAM address of ADC Saving position
> >         MOV r6, BUFF_SIZE  //Counting variable
> >     
> >     READ:
> >         //Read ADC from FIFO0DATA
> >         MOV r2, 0x44E0D100
> >         LBBO r3, r2, 0, 4
> >         //Add address counting
> >         ADD r5, r5, 4
> >         //Write ADC to PRU Shared RAM
> >         SBCO r3, CONST_PRUSHAREDRAM, r5, 4
> >         
> >         DELAY
> >         
> >         SUB r6, r6, 4
> >         MOV r2, HALF_SIZE
> >         QBEQ CHBUFFSTATUS1, r6, r2 //If first buffer is ready
> >         QBEQ CHBUFFSTATUS2, r6, 0 //If second buffer is ready
> >         QBA READ
> >     
> >     //Change buffer status to 1
> >     
> >     CHBUFFSTATUS1:
> >         MOV r2, 1
> >         SBCO r2, CONST_PRUSHAREDRAM, 0, 4
> >         QBA READ
> >     
> >     //Change buffer status to 2
> >     
> >     CHBUFFSTATUS2:
> >         MOV r2, 2
> >         SBCO r2, CONST_PRUSHAREDRAM, 0, 4
> >         QBA INITV
> >     
> >     //Send event to host program
> >     MOV r31.b0, PRU0_ARM_INTERRUPT+16
> >     HALT
> > 
> > .endm
> > 
> > // Starting point
> > 
> > START:
> >     // Enable OCP master port
> >     LBCO r0, CONST_PRUCFG, 4, 4
> >     CLR r0, r0, 4
> >     SBCO r0, CONST_PRUCFG, 4, 4
> >     
> >     //C28 will point to 0x00012000 (PRU shared RAM)
> >     MOV r0, 0x00000120
> >     MOV r1, CTPPR_0
> >     ST32 r0, r1
> >     
> >     //Init ADC CTRL register
> >     MOV r2, 0x44E0D040
> >     MOV r3, 0x00000005
> >     SBBO r3, r2, 0, 4
> >     
> >     //Enable ADC STEPCONFIG 1
> >     MOV r2, 0x44E0D054
> >     MOV r3, 0x00000002
> >     SBBO r3, r2, 0, 4
> >     
> >     //Init ADC STEPCONFIG 1
> >     MOV r2, 0x44E0D064
> >     MOV r3, 0x00000001 //continuous mode
> >     SBBO r3, r2, 0, 4
> >     
> >     //Read ADC and FIFOCOUNT
> >     READADC
> > 
> > [ ADC Example - ADCCollector.c]
> > 
> > 
> > /*************************************************************************
> > ***** * Include Files
> > 
> >     *
> > 
> > **************************************************************************
> > ****/ // Standard header files
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <sys/mman.h>
> > #include <fcntl.h>
> > #include <errno.h>
> > #include <unistd.h>
> > #include <string.h>
> > #include <time.h>
> > 
> > // Driver header file
> > #include <pruss/prussdrv.h>
> > #include <pruss/pruss_intc_mapping.h>
> > 
> > 
> > /*************************************************************************
> > ***** * Local Macro Declarations
> > 
> >    *
> > 
> > **************************************************************************
> > ****/ #define PRU_NUM  0
> > #define OFFSET_SHAREDRAM 2048 //equivalent with 0x00002000
> > 
> > #define PRUSS0_SHARED_DATARAM    4
> > #define SAMPLING_RATE 16000 //16khz
> > #define BUFF_LENGTH SAMPLING_RATE
> > #define PRU_SHARED_BUFF_SIZE 500
> > #define CNT_ONE_SEC SAMPLING_RATE / PRU_SHARED_BUFF_SIZE
> > 
> > 
> > /*************************************************************************
> > ***** * Functions declarations
> > 
> >    *
> > 
> > **************************************************************************
> > ****/ static void Enable_ADC();
> > static void Enable_PRU();
> > static unsigned int ProcessingADC1(unsigned int value);
> > 
> > 
> > /*************************************************************************
> > ***** * Global variable Declarations
> > 
> >    *
> > 
> > **************************************************************************
> > ****/ static void *sharedMem;
> > static unsigned int *sharedMem_int;
> > 
> > 
> > /*************************************************************************
> > ***** * Main
> > 
> >    *
> > 
> > **************************************************************************
> > ****/ int main (int argc, char* argv[])
> > {
> > FILE *fp_out;
> > 
> >     unsigned int ret;
> >     tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
> > 
> > int i = 0, cnt = 0, total_cnt = 0;
> > int target_buff = 1;
> > int sampling_period = 0;
> > 
> > if(argc != 2){
> > printf("\tERROR: Sampling period is required by second\n");
> > printf("\t       %s [sampling period]\n", argv[0]);
> > return 0;
> > }
> > sampling_period = atoi(argv[1]);
> > 
> > /* Enable PRU */
> > Enable_PRU();
> > /* Enable ADC */
> > Enable_ADC();
> > /* Initializing PRU */
> > 
> >     prussdrv_init();
> >     ret = prussdrv_open(PRU_EVTOUT_0);
> >     if (ret){
> >     
> >         printf("\tERROR: prussdrv_open open failed\n");
> >         return (ret);
> >     
> >     }
> >     prussdrv_pruintc_init(&pruss_intc_initdata);
> >     printf("\tINFO: Initializing.\r\n");
> >     prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, &sharedMem);
> >     sharedMem_int = (unsigned int*) sharedMem;
> >  
> >  /* Open save file */
> > 
> > fp_out = fopen("Results.txt", "w");
> > if(fp_out == NULL){
> > printf("\tERROR: file open failed\n");
> > return 0;
> > }
> > 
> > /* Executing PRU. */
> > printf("\tINFO: Sampling is started for %d seconds\n", sampling_period);
> > 
> >     printf("\tINFO: Collecting");
> >     prussdrv_exec_program (PRU_NUM, "./ADCCollector.bin");
> > 
> > /* Read ADC */
> > while(1){
> > while(1){
> > if(sharedMem_int[OFFSET_SHAREDRAM] == 1 && target_buff == 1){ // First
> > buffer is ready
> > for(i=0; i<PRU_SHARED_BUFF_SIZE; i++){
> > fprintf(fp_out, "%d\n", ProcessingADC1(sharedMem_int[OFFSET_SHAREDRAM + 1
> > + i]));
> > }
> > target_buff = 2;
> > break;
> > }else if(sharedMem_int[OFFSET_SHAREDRAM] == 2 && target_buff == 2){ //
> > Second buffer is ready
> > for(i=0; i<PRU_SHARED_BUFF_SIZE; i++){
> > fprintf(fp_out, "%d\n", ProcessingADC1(sharedMem_int[OFFSET_SHAREDRAM +
> > PRU_SHARED_BUFF_SIZE + 1 + i]));
> > }
> > target_buff = 1;
> > break;
> > }
> > }
> > 
> > if(++cnt == CNT_ONE_SEC){
> > printf(".");
> > total_cnt += cnt;
> > cnt = 0;
> > }
> > 
> > if(total_cnt == CNT_ONE_SEC * sampling_period){
> > printf("\n\tINFO: Sampling completed ...\n");
> > break;
> > }
> > }
> > 
> > fclose(fp_out);
> > 
> >     printf("\tINFO: PRU completed transfer.\r\n");
> >     prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
> >     
> >     /* Disable PRU*/
> >     prussdrv_pru_disable(PRU_NUM);
> >     prussdrv_exit();
> >     
> >     return(0);
> > 
> > }
> > 
> > 
> > /*************************************************************************
> > **** * Local Function Definitions
> > 
> >   *
> > 
> > **************************************************************************
> > ***/ /* Enable ADC */
> > static int Enable_ADC()
> > {
> > FILE *ain;
> > 
> > ain = fopen("/sys/devices/bone_capemgr.8/slots", "w");
> > if(!ain){
> > printf("\tERROR: /sys/devices/bone_capemgr.8/slots open failed\n");
> > return -1;
> > }
> > fseek(ain, 0, SEEK_SET);
> > fprintf(ain, "cape-bone-iio");
> > fflush(ain);
> > return 0;
> > }
> > 
> > /* Enable PRU */
> > static int Enable_PRU()
> > {
> > FILE *ain;
> > 
> > ain = fopen("/sys/devices/bone_capemgr.8/slots", "w");
> > if(!ain){
> > printf("\tERROR: /sys/devices/bone_capemgr.8/slots open failed\n");
> > return -1;
> > }
> > fseek(ain, 0, SEEK_SET);
> > fprintf(ain, "BB-BONE-PRU-01");
> > fflush(ain);
> > return 0;
> > }
> > 
> > /*
> > 
> >  * FIFO0DATA register includes both ADC and channelID
> >  * so we need to remove the channelID
> >  */
> > 
> > static unsigned int ProcessingADC1(unsigned int value)
> > {
> > unsigned int result = 0;
> > 
> > result = value << 20;
> > result = result >> 20;
> > 
> > return result;
> > }
> > 
> > 
> > 
> > [ ADC Example - ADCCollector.hp]
> > //
> > **************************************************************************
> > ***/ // file:   PRU_memAccess_DDR_PRUsharedRAM.hp
> > //
> > // brief:  PRU_memAccess_DDR_PRUsharedRAM assembly constants.
> > //
> > //
> > //  (C) Copyright 2012, Texas Instruments, Inc
> > //
> > //  author     M. Watkins
> > //
> > **************************************************************************
> > ***/
> > 
> > 
> > #ifndef _PRU_memAccess_DDR_PRUsharedRAM_HP_
> > #define _PRU_memAccess_DDR_PRUsharedRAM_HP_
> > 
> > 
> > // ***************************************
> > // *      Global Macro definitions       *
> > // ***************************************
> > 
> > // Refer to this mapping in the file -
> > \prussdrv\include\pruss_intc_mapping.h
> > #define PRU0_PRU1_INTERRUPT     17
> > #define PRU1_PRU0_INTERRUPT     18
> > #define PRU0_ARM_INTERRUPT      19
> > #define PRU1_ARM_INTERRUPT      20
> > #define ARM_PRU0_INTERRUPT      21
> > #define ARM_PRU1_INTERRUPT      22
> > 
> > #define CONST_PRUCFG     C4
> > #define CONST_PRUDRAM        C24
> > #define CONST_PRUSHAREDRAM   C28
> > #define CONST_DDR            C31
> > 
> > // Address for the Constant table Block Index Register (CTBIR)
> > #define CTBIR          0x22020
> > 
> > // Address for the Constant table Programmable Pointer Register 0(CTPPR_0)
> > #define CTPPR_0         0x22028
> > 
> > // Address for the Constant table Programmable Pointer Register 1(CTPPR_1)
> > #define CTPPR_1         0x2202C
> > 
> > 
> > .macro  LD32
> > .mparam dst,src
> > 
> >     LBBO    dst,src,#0x00,4
> > 
> > .endm
> > 
> > .macro  LD16
> > .mparam dst,src
> > 
> >     LBBO    dst,src,#0x00,2
> > 
> > .endm
> > 
> > .macro  LD8
> > .mparam dst,src
> > 
> >     LBBO    dst,src,#0x00,1
> > 
> > .endm
> > 
> > .macro ST32
> > .mparam src,dst
> > 
> >     SBBO    src,dst,#0x00,4
> > 
> > .endm
> > 
> > .macro ST16
> > .mparam src,dst
> > 
> >     SBBO    src,dst,#0x00,2
> > 
> > .endm
> > 
> > .macro ST8
> > .mparam src,dst
> > 
> >     SBBO    src,dst,#0x00,1
> > 
> > .endm
> > 
> > 
> > // ***************************************
> > // *    Global Structure Definitions     *
> > // ***************************************
> > 
> > .struct Global
> > 
> >     .u32 regPointer
> >     .u32 regVal
> > 
> > .ends
> > 
> > 
> > // ***************************************
> > // *     Global Register Assignments     *
> > // ***************************************
> > 
> > .assign Global, r2, *, global
> > 
> > #endif //_PRU_memAccess_DDR_PRUsharedRAM_

--
Hunyue Yau
http://www.hy-research.com/

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to