2011-06-15 03:47:39     BF561 PPI

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

2011-06-15 03:47:39     BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101276   




I was trying to use both ppi busses on my BF561 at the same time, but I hit the following error:


PPIdev: Unable to attach BlackFin PPI Error Interrupt


Looking further in this problem I found in ' char/bfin_ppi.c ' that ' ppi_devices[0].irq_error = IRQ_PPI_ERROR; ' actually refers to the same IRQ line as  ' ppi_devices[1].irq_error = IRQ_PPI1_ERROR; ' because of the following declaration in ' match-bf561/include/match/irq.h ':




#define IRQ_PPI1_ERROR (IVG_BASE + 4) /* PPI1   Error Interrupt   */

#define IRQ_PPI_ERROR IRQ_PPI1_ERROR /* PPI1   Error Interrupt   */

#define IRQ_PPI2_ERROR (IVG_BASE + 5) /* PPI2   Error Interrupt   */


I suspect this is incorrect behaviour and it should be like this ' ppi_devices[1].irq_error = IRQ_PPI2_ERROR; '. Am I right? I haven't tested it yet, but I just might later this week.


Hopefully this solves the problems I've been experiencing.


Kind regards,






2011-06-15 04:18:31     Re: BF561 PPI

Aaron Wu (CHINA)

Message: 101280   


Thanks, you are probably right, welcome to have  a try and share us the feedback




2011-06-16 07:51:13     Re: BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101321   


It works, I changed the 'arch/blackfin/mach-bf561/include/mach/irq.h' file as follows:




#define IRQ_PPI_ERROR (IVG_BASE + 4) /* PPI1   Error Interrupt   */

#define IRQ_PPI1_ERROR (IVG_BASE + 5) /* PPI2   Error Interrupt   */


Now I'm getting ' PPI Error: PPI Status = 0x1000 ' occasionally on one or both busses, but that is a hardware related problem I think, isn't it?


Kind regards,





2011-06-16 08:07:42     Re: BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101323   


Since I can't edit my previous posts: I'm using uClinux 2010R1 branch and BlueTechnix CM-BF561 by the way.




2011-06-16 10:11:37     Re: BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101325   


The above problem already seems to be solved by enabling DMA packing. Last time I tried this (with 2009R1), DMA packing was disabled for the BF561 in ' bfin_ppi.c ', but it seems to be enabled again since 2010R1.




2011-06-16 23:14:40     Re: BF561 PPI

Mike Frysinger (UNITED STATES)

Message: 101328   


ive committed a fix for this to trunk:





2011-06-21 07:53:25     Re: BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101512   


It seems enabling DMA32 is not available via the bfin_ppi char driver. Is it possible this will be supported in the future?




2011-06-21 12:00:16     Re: BF561 PPI

Mike Frysinger (UNITED STATES)

Message: 101524   


we arent actively developing the bfin_ppi driver.  if there's functionality missing that you desire, please open an item under the Features Request tracker so we know what people want and we can assign/schedule/implement it.




2011-06-21 14:11:49     Re: BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101527   


I have already implemented and tested DMA32 functionality in the char driver. I will clean up and post the changes here later, because I am still pretty novice so someone else can decide what to do with it.


In the mean time, when trying to capture multiple sequential frames (3) on both camera's the PPI FIFO Overrun (0x1000) reappears for the second and third capture (remember I solved this for 1 stereo frame capture with the PACK_EN option). When also using the DMA32 option the PPI FIFO Overrun only occurs for the third capture. I basically do < open - ioctl - read - close > x 3 for both camera's in separate threads. Perhaps < open - ioctl - read - read -read - close > is better, but still I don't understand why the PPI FIFO Overrun occurs since DMA should be disabled and freed after the read call completes. As far as I can see this is correct in the char driver. Does anyone have an idea? When I wait a small amount of time between stereo frame captures it works again, so it seems the DMA isn't free directly after reading finished.


Thanks for helping!






2011-06-22 04:17:05     Re: BF561 PPI

Steven Mattheussen (BELGIUM)

Message: 101561   


Here are the changes I made to the bfin_ppi char driver to make DMA32 work. I tested it on my CM-BF561 module and it seems to work.

Changes to ' drivers/char/bfin_ppi.h ' from 2010R1 branch:

Added the following defines:


#define CMD_PPI_DMA32 41




Changes to ' drivers/char/bfin_ppi.c ' from 2010R1 branch:

Changed the ppi_config struct to support dma32:


struct ppi_config {

unsigned char opened;

unsigned char data_len;

unsigned char pack_mode;

unsigned char dma32;

unsigned char fs23;

unsigned char timers;

unsigned char trigger_edge;

unsigned char dimensions;

unsigned short delay;

unsigned short access_mode;

unsigned short done;

unsigned short dma_config;

unsigned short line_len;

unsigned short num_lines;

unsigned short fs1_blanking;

unsigned short ppi_control;

#if defined(EPPI0_CONTROL) || defined(EPPI1_CONTROL) /* EPPI */

unsigned short v_delay;

unsigned short v_count;



Addapted the following ioctl to allow packing for datalengths > 8bits when DMA32 is enabled:




pr_debug("ppi_ioctl: CMD_PPI_PACKING\n");

regdata= dev->regs->ppi_control;

if (arg) {

#if defined(PPI_CONTROL) || defined(PPI0_CONTROL)


* The PACK_EN bit only has meaning when the PPI port width (selected by

* DLEN[2:0]) is 8 bits or when DMA32 is enabled and DLEN[2:0] > 16 bits


if ((conf->data_len > CFG_PPI_DATALEN_8 && !conf->dma32) || conf->data_len > CFG_PPI_DATALEN_16) {


"Invalid data length for packing\n");

goto err_inval;


regdata |= PACK_EN;

pr_debug("ppi_ioctl: CMD_PPI_PACKING packing enable\n");


} else {

regdata &= ~PACK_EN;

pr_debug("ppi_ioctl: CMD_PPI_PACKING packing disable\n");


conf->ppi_control = regdata;

conf->pack_mode = !!arg;

dev->regs->ppi_control = regdata;



Added the following ioctl for enabling DMA32:


#if defined(DMA32)

case CMD_PPI_DMA32:


pr_debug("ppi_ioctl: CMD_PPI_DMA32\n");

regdata = dev->regs->ppi_control;

if (arg) {

regdata |= DMA32;

pr_debug("ppi_ioctl: CMD_PPI_DMA32 enable\n");

} else {

regdata &= ~DMA32;

pr_debug("ppi_ioctl: CCMD_PPI_DMA32 disable\n");


conf->ppi_control = regdata;

conf->dma32 = !!arg;

dev->regs->ppi_control = regdata;




For both functions ppi_read and ppi_write I changed the following:


if (conf->pack_mode && conf->dma32 && conf->data_len == CFG_PPI_DATALEN_8)

step_size = 4;

else if ((conf->data_len > CFG_PPI_DATALEN_8) || conf->pack_mode)

step_size = 2;


step_size = 1;



if (conf->pack_mode && conf->dma32 && conf->data_len == CFG_PPI_DATALEN_8)

x_count = conf->line_len / 4;

else if (conf->pack_mode)

x_count = conf->line_len / 2;


x_count = conf->line_len;

and perhaps in the section where the line length is calculated according to count if the first is not configured the if condition is not needed:


if (conf->data_len > CFG_PPI_DATALEN_8)

conf->line_len = count / step_size;


I hope this is helpfull and an experienced programmer can verify this.




2011-06-23 04:20:18     Re: BF561 PPI

Scott Jiang (CHINA)

Message: 101605   


Hi Steven,


Take care of the timing. This error came out because dma was't started immediately after ppi finished the last transfer.


You use multiple threads to do this, but application can't do this real time work well.


The bfin_ppi.c driver is only for simple use, not for video capture.


I am working on v4l2 driver for blackfin, vs6624 on bf537 has been finished. adv7183 on bf561 is under debugging.


Please subscribe linux-kernel-commits list if you are interested in this.




2011-06-27 05:40:05     Re: BF561 PPI

Martin Strubel (SWITZERLAND)

Message: 101708   




we have a v4l2 buffer queue driver (ppivideo) that's running under all recent and new kernels (sensor/acquisition independent). There are plans to put it into upstream opensource, if we can make sure, it will cost us no more support. It's part of a bigger framework, more info at   www.section5.ch/vkit. If you want to evaluate the driver, let me know.




- Martin