Hello sir, I have some question regarding your code please.

What is the maximum sampling rate that I can get using this code and what 
should I change to get that sampling rate?
If I want to read from all 7 analog pins, how can I do that?

Thank you for your help and your effort.

On Tuesday, April 8, 2014 1:15:31 PM UTC+3, Youngtae Jo wrote:
>
> 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_
>
>

-- 
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 beagleboard+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to