2014-09-25 1 views
1

AM335X Cortex A8 프로세서에서 실행되는 비글 본 블랙 세계에 다소 새로운 것이므로 빠른 아날로그 읽기에 PRU를 사용하고 싶습니다. 가능한 최대 샘플링 속도.비글 본 블랙 용 PRU와 호스트 C 프로그램을 사용하여 7 개의 입력에서 모두 아날로그로 읽음

내가 좋아하는 루프 형태로 모두 7 개 입력을 읽고 싶습니다

while(n*7 < sampling_rate){ //initial value for n = 0 
    read(AIN0); //and store it in shared memory(7*n + 0) 
    read(AIN1); //and store it in shared memory(7*n + 1) 
    read(AIN2); //and store it in shared memory(7*n + 2) 
    read(AIN3); //and store it in shared memory(7*n + 3) 
    read(AIN4); //and store it in shared memory(7*n + 4) 
    read(AIN5); //and store it in shared memory(7*n + 5) 
    read(AIN6); //and store it in shared memory(7*n + 6) 
    n++; 
} 

을 내가 메인 프로세서에서 실행되는 호스트 프로그램에서 읽을 수있다. 어떻게 그렇게 생각하십니까? AM335x_pru_package라는 패키지에서 ADCCollector.c라는 준비된 코드를 사용해 보았지만 사용 된 레지스터의 모든 주소와 값을 얻는 방법을 알 수 없습니다.

내가 수정하려고했던 코드 (ADCCollector.p)입니다 :

.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 1 //Sampling rate(16khz) //***//16000 
#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 //if sampling rate = 98000 --> = 3061.224 

.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  //#define CONST_PRUCFG  C4  taken from ADCCollector.hp 
    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 

또 다른 질문은 : 나는 단지에서 200000 아래 다른 번호 16000에서 #DEFINE sampling_rate의 변경거나 같은 경우 (.p) 파일에서 샘플링 속도를 얻을 수 있습니까? 아니면 다른 것을 바꿔야합니까?

미리 감사드립니다.

답변

0

나는 libpruio에서 C 래퍼를 사용 : http://www.freebasic.net/forum/viewtopic.php?f=14&t=22501

을 다음 내 모든 ADC 값을 얻기 위해이 코드를 사용 : 당신은 그러므로 IO 모드 (동기)과의 libpruio를 사용하여 예에서

#include "stdio.h" 
#include "c_wrapper/pruio.h" // include header 
#include "sys/time.h" 

//! The main function. 
int main(int argc, char **argv) { 
    struct timeval start, now; 
    long mtime, seconds, useconds;  
    gettimeofday(&start, NULL); 
    int i,x; 
    pruIo *io = pruio_new(PRUIO_DEF_ACTIVE, 0x98, 0, 1); //! create new driver structure 
    if (pruio_config(io, 1, 0x1FE, 0, 4)){ // upload (default) settings, start IO mode 
     printf("config failed (%s)\n", io->Errr);} 
    else { 

     do { 
      gettimeofday(&now, NULL); 
      seconds = now.tv_sec - start.tv_sec; 
      useconds = now.tv_usec - start.tv_usec; 
      mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5; 
      printf("%lu",mtime); 
      for(i = 1; i < 9; i++) { 
       printf(",%d", io->Adc->Value[i]); //0-66504 for 0-1.8v 
      } 
      printf("\n"); 

      x++; 
     }while (mtime < 100); 

     printf("count: %d \n", x); 

     pruio_destroy(io);  /* destroy driver structure */ 
    } 
    return 0; 
} 
0

을 호스트 CPU가 실시간으로 작동하지 않기 때문에 사용자는 샘플링 속도를 제어 할 수 없습니다.

최대 샘플링 속도 (OP에서 언급 한 바와 같이)를 얻으려면 RB 또는 MM 모드를 사용해야합니다. 이러한 모드에서 libpruio는 샘플을 메모리에 버퍼링하고 호스트는 비동기 적으로 샘플에 액세스 할 수 있습니다. libpruio 패키지의 예제 rb_file.c (또는 triggers.bas)를 참조하십시오.

관련 문제