2009-07-14 13:36:33     PPI FB error

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

2009-07-14 13:36:33     PPI FB error

Adam Dershowitz (UNITED STATES)

Message: 77254   

 

I have a frame buffer driver that I wrote to control the PPI.  I am trying to output 16 bit 2-D data (essentially it is analogous to a video frame).

 

The driver is working, but I am only getting data output every other frame.  In other words, if I look at a single bit on a scope and also look at FS2, the data bit is active every other time that FS2 transitions low, instead of every time.  If I increase my Timer1 period by a bunch I can get data on every cycle, but then there is also a bunch of dead time (ie I am sending data maybe 75% of the time, and waiting the rest).  In other words it seems that I need to have a much longer Timer1 then I need actually need to get all the data out.

 

I have tried decreasing my PPI clock frequency a bunch and everything just scales directly so I am pretty sure that it is not an issue of memory access time and such.  For testing purposes I am now running at 1 MHz, and getting the identical duty cycle as I get at 15 MHz.

 

My code is based heavily on the bfin-t350mcqb-fb.c sample that is included with uclinux.  I am using all 16 bits of the PPI.

 

I am trying to get continuous data out, and I am completely baffled by why I can only get data at 75% duty cycle, or it drops to 50%.  I think that it relates to how the PPI, DMA or timers are configured, but I have tried all different types of combinations of timing and such with no luck at all.

 

Any suggestions or guidance where to look would be much appreciated.

 

Thanks,

 

 

 

--Adam

QuoteReplyEditDelete

 

 

2009-07-14 14:11:29     PPI FB error

Michael Hennerich (GERMANY)

Message: 77255    Adam,

 

I have no glue on what you are trying to explain.

But if you're looking for a 16-bit PPI driver example you should have better started with the bfin-lq035q1-fb.c. The one you modified uses PPI Packing.

 

https://blackfin.uclinux.org/gf/project/linux-kernel/scmsvn/?action=browse&path=%2Ftrunk%2Fdrivers%2Fvideo%2Fbfin-lq035q1-fb.c&view=log

 

A view words -

The PPI start on simul. assertion of FS1 (Line Sync) and FS2 (Frame Sync).

Later it only looks at FS1. The Timers in PWM out mode control the timings for FS1 and FS2. Please have a look at the Blackfin Peripheral Hardware Reference Manual. Interesting chapters: PPI, Timers, DMA.

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-14 14:44:15     Re: PPI FB error

Adam Dershowitz (UNITED STATES)

Message: 77257   

 

Sorry if my email really wasn't clear.

 

I already have my driver almost working, but lq035, might offer me some clues.  I did try to switch stuff over to 16 bit without packing, but I am going to dig through that code some to try to figure out if I missed something.

 

Let me try to explain a little better what I am doing and seeing.  What I am seeing is that I am just getting data out with every other FS2.  So, I see data the first time that FS2 goes low, but not the next one.  The amount of data that I am seeing looks like it is what I expect.  So it is as though, for some reason, it is not ready to send again the next time that FS2 goes low.

 

Here is some background:

 

I have a buffer that is 2880 cols (PACKET_SIZE) and 253 rows (NUM_PACKETS) that contains the data that I want to send out my PPI port, 16 bits at a time.  So H_PERIOD  (horizontal period) is 2880/2 and V_PERIOD is H_PERIOD * 253.

 

Then I set up my timers like this:

 

    set_gptimer_period(TIMER0_id, H_PERIOD );

    set_gptimer_pwidth(TIMER0_id, H_PULSE);

    set_gptimer_config(TIMER0_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT |

                      TIMER_TIN_SEL | TIMER_CLK_SEL|

                      TIMER_EMU_RUN);

 

    set_gptimer_period(TIMER1_id, V_PERIOD);

    set_gptimer_pwidth(TIMER1_id, V_PULSE);

    set_gptimer_config(TIMER1_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT |

                      TIMER_TIN_SEL | TIMER_CLK_SEL |

                      TIMER_EMU_RUN);

 

 

And my DMA like this:

 

 

 

    set_dma_config(CH_PPI,

               set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO,

                       INTR_DISABLE, DIMENSION_2D,

                       DATA_SIZE_16,

                       DMA_NOSYNC_KEEP_DMA_BUF));

    set_dma_x_count(CH_PPI, PACKET_SIZE);

    set_dma_x_modify(CH_PPI, DMA_BUS_SIZE / 8);

    set_dma_y_count(CH_PPI, NUM_PACKETS);

    set_dma_y_modify(CH_PPI, DMA_BUS_SIZE / 8);

 

 

and my PPI like this:

 

 

 

    bfin_write_PPI_DELAY(0);

    bfin_write_PPI_COUNT(PACKET_SIZE/2 -1);

    bfin_write_PPI_FRAME(NUM_PACKETS);

 

    bfin_write_PPI_CONTROL(PPI_TX_MODE |       /* output mode , PORT_DIR */

                PPI_XFER_TYPE_11 | /* sync mode XFR_TYPE */

                PPI_PORT_CFG_01 |  /* two frame sync PORT_CFG */

                PPI_DLEN_16 |        /*Set to 16 bits of data*/

                PPI_POLS_1);       /* faling edge syncs POLS */

 

 

 

Finally, what I was trying to explain, but didn't make clear before.  If I change my FS2 timer to be big enough like this:

 

set_gptimer_period(TIMER1_id, V_PERIOD + 103 * H_PERIOD);

 

then it behaves as expect.  So I get data every time that FS2 goes low, but of course there is a period (of 103 H_PERIOD) with no data at all.

 

Does this explaination make more sense?

 

Thanks,

 

--Adam

QuoteReplyEditDelete

 

 

2009-07-14 17:20:16     Re: PPI FB error

Adam Dershowitz (UNITED STATES)

Message: 77262   

 

Maybe I can ask a bit more specific question about something that is just not clear to me in the documentation about the PPI.  When I am using 16 bits of DMA and 16 bits of PPI it is not always clear which counters and stuff are in bytes and which are in "ticks" (meaning 2 bytes in this case).

 

Can you confirm the following for me:

 

set_gptimer_period() is in ticks.  Thus, since I am moving 2880 bytes (PACKET_SIZE) in groups of 16 bits, it should take 1440 ticks to move a row and 1440 times the number of rows (NUM_PACKETS) to move a whole frame.

 

set_dma_x_count() is going to be the width of a row in bytes, not ticks.  So it should be 2880 in this case, while the increment (modify) should be 2 (since I am going 16 bits per read).

 

set_dma_y_count() should be the number of actual rows of data, 253 in my case.  and modify for y should again be 2.

 

bfin_write_PPI_DELAY(0); should be fine since I don't want to wait at all.

bfin_write_PPI_COUNT(PACKET_SIZE/2 -1);  This is essentially in "ticks" since I put out 16 bits at a time.  Since packet_size is 2880, this should be correct to dump a whole row.

bfin_write_PPI_FRAME(NUM_PACKETS);  This is just the number of rows, again 253 in my case.

 

 

Thanks,

 

--Adam

QuoteReplyEditDelete

 

 

2009-07-15 05:23:27     Re: PPI FB error

Michael Hennerich (GERMANY)

Message: 77326    >Can you confirm the following for me:

 

>set_gptimer_period() is in ticks. Thus, since I am moving 2880 bytes (PACKET_SIZE) in groups of 16

>bits, it should take 1440 ticks to move a row and 1440 times the number of rows (NUM_PACKETS) to move

>a whole frame.

 

Yes - Timers use clocks - one clock with a 16-bit PPI moves to bytes.

 

 

>set_dma_x_count() is going to be the width of a row in bytes, not ticks. So it should be 2880 in

>this case, while the increment (modify) should be 2 (since I am going 16 bits per read).

 

No - In 2D DMA mode x_count relates to the number of elements.

So program to the number of words (16-bit) transferred.

Right - x_modify should be 2

 

 

>set_dma_y_count() should be the number of actual rows of data, 253 in my case. and modify for y

>should again be 2.

 

Yes

 

 

>bfin_write_PPI_DELAY(0); should be fine since I don't want to wait at all.

 

Ok

 

>bfin_write_PPI_COUNT(PACKET_SIZE/2 -1); This is essentially in "ticks" since I put out 16 bits at a

 

Yes

 

>time. Since packet_size is 2880, this should be correct to dump a whole row.

> bfin_write_PPI_FRAME(NUM_PACKETS); This is just the number of rows, again 253 in my case.

 

 

Yes

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-16 18:15:00     Re: PPI FB error

Adam Dershowitz (UNITED STATES)

Message: 77486   

 

Is there any way to get to the error register from the command line?  In other words, if I just want to find out if I am having DMA, or PPI, errors, while the code is running, is there a way to do that? Or do I have to read that register in my code, and then print it out.

 

Also, another possible hint.  I have played around with bfin_write_PPI_FRAME as a test going from 0 to large values, and it doesn't seem to change anything for my issue.  Shouldn't going to small, or two large cause an error or failed data writes?

 

Thanks,

 

--Adam

QuoteReplyEditDelete

 

 

2009-07-16 18:17:05     Re: PPI FB error

Mike Frysinger (UNITED STATES)

Message: 77487   

 

https://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:debug

QuoteReplyEditDelete

 

 

2009-07-16 18:25:22     Re: PPI FB error

Michael Hennerich (GERMANY)

Message: 77488    You should see PPI_STATUS errors (Frame Tracking) in case FS2 reasserts before the numbers of Lines (FS1 assertions) exceeded.

 

Request IRQ_PPI_ERROR and listen to what it is telling you.

 

-Michael

QuoteReplyEditDelete

 

 

2009-07-16 20:23:15     Re: PPI FB error

Adam Dershowitz (UNITED STATES)

Message: 77491   

 

Accordig to the 52x Harware reference FT_ERR is "valid for RX modes only".  So, I don't expect that it would do anything for TX mode, like I am using.  But, it does appear to actually be valid.

 

 

 

However, I did request IRQ_PPI_ERROR and now I see that I am getting 0x800 for the status, which is a FT_ERR.  That was a useful clue to figure out the problem, which seems that it was a timing/counting issue.

Attachments

    Outcomes