2011-08-24 12:52:24     Problem with PPI and continuous data

Document created by Aaronwu Employee on Aug 27, 2013
Version 1Show Document
  • View in full screen mode

2011-08-24 12:52:24     Problem with PPI and continuous data

Lapo Pieri (ITALY)

Message: 103113   

 

Hi Forum,

I'm a newby in bfin and dsp... I would build an application that read

a 3ch adc at 400kS/s for each channel, make some iir/fir filtering and

some other slow calculation, than output very slow data (<100S/s).

 

I've a BF537-STAMP and I'm in the trouble with PPI: I plan to use PPI

for ADC i/f and to get practice with PPI under uClinux I've build a

simple board with a counter ('HC393) who's output data is connected

with the first 8 bit of PPI and clock came from timer3 which drive

PPI_CLK too. I've attached the schematic.

 

So I've written a simple test program (ppi-1.c) that read some raw

data, store in memory and print on the screen: it's easy to see 256

value counted by counter, so it seems to me that everithing is working

properly.

 

ppi-1.c

=======

 

int main(void){

  int fdppi, i, fdtmr;

  unsigned char buff[512];

  unsigned long count=2500; /* timer period in nanosec */

 

  /* open timer3 */

  fdtmr=open("/dev/timer3", O_RDWR);

  if(fdtmr==-1){

    fprintf(stderr,"unable to open /dev/timer3");

    return 1;

  }

 

  /* configure timer3 for 50% duty-cycle output */

  ioctl(fdtmr, BFIN_PWM_SET_PERIOD, count);

  count = count >>1;

  ioctl(fdtmr, BFIN_PWM_SET_DUTY, count);

 

  /* open raw ppi */

  fdppi=open("/dev/ppi0", O_RDWR,0);

  if (fdppi==-1){

    printf(" error opening /dev/ppi0\n");

    return 1;

  }

 

  /* configure ppi */

  ioctl(fdppi, CMD_PPI_PORT_DIRECTION, CFG_PPI_PORT_DIR_RX);

  ioctl(fdppi, CMD_PPI_XFR_TYPE, CFG_PPI_XFR_TYPE_NON646);

  ioctl(fdppi, CMD_PPI_PACKING, CFG_PPI_PACK_DISABLE);

  ioctl(fdppi, CMD_PPI_SKIPPING, CFG_PPI_SKIP_DISABLE);

  ioctl(fdppi, CMD_PPI_DATALEN, CFG_PPI_DATALEN_8);

  ioctl(fdppi, CMD_PPI_CLK_EDGE, CFG_PPI_CLK_EDGE_RISE);

 

  /* start clock source */

  ioctl(fdtmr, BFIN_PWM_TIMER_START);

 

  /* get data */

  read(fdppi, buff, 256);

 

  /* stop clock source */

  ioctl(fdtmr, BFIN_PWM_TIMER_STOP);

 

 

  for(i=0; i<256; i++)

    printf("%02x  ", buff[i]);

  printf("\n");

 

  close(fdtmr); close(fdppi);

  return 0;

}

 

 

But I've to make a continuous operation, i.e. the ADC must get

continuosly data and store it in the memory, so, since speed is not so

high I tought to make two subsequent read() as in following ppi-4.c.

 

 

ppi-4.c

=======

 

#define BUFFERLEN 512

 

int main(void){

  int fdppi, i, fdtmr, rv1, rv2;

  unsigned char buff[BUFFERLEN];

  unsigned long count=2500; /* timer period in nanosec */

 

 

  /* open timer3 */

  fdtmr=open("/dev/timer3", O_RDWR | O_NONBLOCK );

  /* O_NONBLOCK is suggested for device on which only ioctl() are done */

  if(fdtmr==-1){

    fprintf(stderr,"unable to open /dev/timer3");

    return 1;

  }

 

  /* configure timer3 for 50% duty-cycle output */

  ioctl(fdtmr, BFIN_PWM_SET_PERIOD, count);

  count = count >>1;

  ioctl(fdtmr, BFIN_PWM_SET_DUTY, count);

 

  /* open raw ppi */

  fdppi=open("/dev/ppi0", O_RDWR);

  if (fdppi==-1){

    printf(" error opening /dev/ppi0\n");

    return 1;

  }

 

  /* configure ppi */

  ioctl(fdppi, CMD_PPI_PORT_DIRECTION, CFG_PPI_PORT_DIR_RX);

  ioctl(fdppi, CMD_PPI_XFR_TYPE, CFG_PPI_XFR_TYPE_NON646);

  ioctl(fdppi, CMD_PPI_PACKING, CFG_PPI_PACK_DISABLE);

  ioctl(fdppi, CMD_PPI_SKIPPING, CFG_PPI_SKIP_DISABLE);

  ioctl(fdppi, CMD_PPI_DATALEN, CFG_PPI_DATALEN_8);

  ioctl(fdppi, CMD_PPI_CLK_EDGE, CFG_PPI_CLK_EDGE_RISE);

  ioctl(fdppi, CMD_PPI_SET_DIMS, CFG_PPI_DIMS_1D);

  ioctl(fdppi, CMD_PPI_DELAY, 0);

  /* ioctl(fdppi, CMD_PPI_SETGPIO); */

 

  /* start clock source */

  ioctl(fdtmr, BFIN_PWM_TIMER_START);

 

  /* get data */

  rv1=read(fdppi, buff, BUFFERLEN/2);

  rv2=read(fdppi, buff+BUFFERLEN/2, BUFFERLEN/2);

 

  /* stop clock source */

  ioctl(fdtmr, BFIN_PWM_TIMER_STOP);

 

  for(i=1; i<BUFFERLEN; i++)

    if(((buff[i-1]+1)&0xff)!=buff[i])

      printf("%d: %d ---> %d (%d)\n", i, buff[i-1], buff[i],

         buff[i]-buff[i-1]>0?buff[i]-buff[i-1]:buff[i]-buff[i-1]+256);

 

  close(fdtmr); close(fdppi);

  return 0;

}

 

 

The problem is that between the two block of data some counts are

missed; the number of missed counts vary with clock frequency but also

with only 4kHz clock I loose 4-5 count.

 

Indeed with 400kHz clock I got:

 

       root:/usr> ./ppi4

       256: 4 ---> 21 (17)

 

and with 4kHz clock:

 

       root:/usr> ./ppi4

       256: 32 ---> 35 (3)

 

DMA seems to lose something when is reinitialized on every ppi_read()

call.. I've take a look at bfin_ppi.c but it's quit hard to me to

understand and modify...

 

I use 2.6.34.7-ADI-2010R1 and application are compiled with last

available toolchain (bfin-uclinux-gcc (debian

blackfin-toolchain-uclinux ver. 2010R1-rc4).

 

Could someone point me out where I am wrong?

 

Many thanks in advance.

 

Lapo

 

 

ppi_counter-1.0.pdf

TranslateQuoteReplyEditDelete

 

 

2011-08-25 22:33:06     Re: Problem with PPI and continuous data

Scott Jiang (CHINA)

Message: 103124   

 

ppi overrun, ppi only has 16bits x 16 fifo. bfin_ppi driver can't support continuous data.

 

If you want to support continuous data, you must modify driver to queue/dequeue model and use ping-pong buffer.

QuoteReplyEditDelete

 

 

2011-08-26 03:06:12     Re: Problem with PPI and continuous data

Lapo Pieri (ITALY)

Message: 103127   

 

ppi overrun, ppi only has 16bits x 16 fifo. bfin_ppi driver can't support continuous data.

 

If you want to support continuous data, you must modify driver to queue/dequeue model and use ping-pong buffer.

 

---

 

 

 

Thank you Scott!

 

Ok, I'll try to modify bfin_ppi.c, I've to study how dma works and several other stuff, kernelspace is not my space... I'll try to do it.

 

Many thanks

 

 

 

Lapo

TranslateQuoteReplyEditDelete

 

 

2011-09-01 09:17:45     Re: Problem with PPI and continuous data

Martin Strubel (SWITZERLAND)

Message: 103251   

 

Hi Lapo,

 

we've got a driver for just that, it's running in various streaming applications where data loss is 'no go'. Default usage is actually with the realtime extensions, but v4l2 is an option, too (main purpose being cameras). You might want to check   section5.ch/vkit for more details.

 

Greetings,

 

- Martin

QuoteReplyEditDelete

 

 

2011-09-03 15:03:39     Re: Problem with PPI and continuous data

Lapo Pieri (ITALY)

Message: 103266   

 

Thank you Martin,

 

I'm just taking a look, I'm working on bfin_ppi_cd (cd is for continuous data) but it's an hard job for me...

 

Thank you!

 

Lapo

Attachments

Outcomes