cancel
Showing results for 
Search instead for 
Did you mean: 

SSD1963 and DMA with FMC

davide
Associate II
Posted on May 10, 2015 at 01:14

The original post was too long to process during our migration. Please click on the attachment to read the original post.
14 REPLIES 14
jj2
Associate II
Posted on May 10, 2015 at 10:37

Feel your pain!     And while post ''is'' long - does that not beat the, ''does not work'' alternative?

I've not used that MCU - in that DMA manner - so will suggest only a, ''method of attack.''

You identify both a ''legal'' and ''illegal'' RGB data range.     And you have complete control over the, ''when/where'' (in your data transfer) those illegal data values may appear - have you not?    (i.e. suspect that you can create a small, test frame - and ''seed it'' (strategically) with an illegal data value.)    Then - cannot you capture each/every: ''data, address & control signal bit'' value/level - which arrive (at the exact moment) of that illegal data?

At minimum - such test should indicate whether the issue exists:

a) between the MCU & SSD

b) internal to the SSD - (although others have achieved B-W levels beyond which you state)

Might it be that your ''illegal'' data values ''exceed'' the 565 data range capability - thus confounding the SSD.

The fact that such occurs (only) under DMA may suggest ''data or control line'' mangling somewhere w/in the DMA process.     Earlier suggested ''data grab'' may prove a good means to ''freeze that event in time'' such that the troubled part (more notably) reveals...
davide
Associate II
Posted on May 10, 2015 at 16:00

Thank you for your reply,

without the DMA i haven't any issue, i use same addresses that should be used by the DMA (0x60000000data/0x60020000cmd for SSD, 0xD0000000 for SDRAM) in order to read the frame from the buffer and send it to the SSD. In this ''manual'' condition I fill the SDRAM buffer with 565 colors (full range-TestPattern, something like the old televisions one) and start the manual transfer, which ends up correctly with no pain.

When i take the same TestPattern (filled in the same manner) and send it over DMA (that should do the same things i do manually: Read 16b from SDRAM >> in SDRAM Addr+=2 >> send the 16b to the SSD >> repeat 800*480 times) the problem shows up. 

Using ad Hoc test patterns i've managed to spot the Legal Range: 0x0C0C0C -> 0xF2F2F2.

Every time i add only only one pixel outside this legal region i got garbage.

Can you be a little more specific on how to freeze the data transfer when i come to the illegal pixel? You're method seems to be the correct one to frame the problem!

I really thank you so much for your help here!

jj2
Associate II
Posted on May 11, 2015 at 05:53

Large clue appears in this (past) sentence, ''And you have complete control over the, ''when/where'' (in your data transfer stream) those illegal data values may appear!''

 

I was suggesting that you create a fixed pattern w/in your frame buffer - and place just a single ''illegal'' data value - say 10 lines (down) - w/in that buffer.   By this means - you know exactly when/where the illegal value will appear - and can take a ''snapshot'' of the data, address & control signals - as they appear - at that moment in time.    You may want to place your ''illegal'' at a frame buffer address which is easy to monitor (i.e. 2 or 3 ''high address bits'' go high in unison - and use that as your, ''snapshot'' trigger!)

It's of interest to me (perhaps to you as well) if the occurrence of just one single ''illegal'' data value will ''wreck'' your frame load.    If I had to guess - I'd suspect that 1 or more critical bits

''got hammered'' due to the illegal - and drove the SSD into disarray.

My suspicion is that the DMA - for some (as of yet unexplained) reason - is altering either your data, address or control signals.     (clearly data tops that list - control's distant 3rd)

We note that your ''base'' data values are contained w/in a 24 bit field - and that these must be constrained to 16 bits - for presentation to the SSD IC.    It is here that the DMA may ''break'' down - it would appear.

Our tech firm has (past) used that SSD device - and thru luck or skill - we'd not been so plagued.
davide
Associate II
Posted on May 12, 2015 at 00:38

I've done a lot of testing today, still doesn't work properly, but I see things more clearly:

  • Following what you have suggested me, i've builded the test frame, basically an array full of ''legal'' values and only one (0x0000, 565 color) ''illegal''. With the exact same FMC/DMA settings. When i hit the illegal value i didn't see any strange behaviour on the Control/Address/Data Lines but, what change is the interpretation of those by the SSD or something else i still didn't have figured out. Result: all of the next data passed to the SSD will fall randomly to registers, data or lost. After two or three refreshes of the test frame I end up with a completely randomly initialised SSD that obviously doesn't work anymore.
  • In order to recreate such situation also during ''Manual'' transfer i have changed the function that read from SDRAM and send data to the SSD:

 

void

 mySSD_fromSDRAM(

void

){

uint32_t j=

0

;

mySSD_SetPos(

0

,

799

,

0

,

479

);

for

(j=

0

; j<

768000

;j+=

2

){

   *(uint16_t*) (

0x60020000

) = *(uint16_t*) (

0xD0000000

 + j);

}

}

the function i use to set the write window on the SSD i that one:

void

 mySSD_SetPos(uint16_t xs, uint16_t xe, uint16_t ys, uint16_t ye){

//SET COLUMN ADDRESS

mySSD_Write_cmd(

0x2A

);

mySSD_Write_data((xs>>

8

)&

0x00FF

);

//Highest byte SC

mySSD_Write_data(xs & 

0x00FF

);

//Lowest byte SC, Start Column

mySSD_Write_data((xe>>

8

)&

0x00FF

);

//Highest byte EC

mySSD_Write_data(xe & 

0x00FF

);

//Lowest byte EC, End Column

//SET COLUMN ADDRESS

mySSD_Write_cmd(

0x2B

);

mySSD_Write_data((ys>>

8

)&

0x00FF

);

//Highest byte SP

mySSD_Write_data(ys & 

0x00FF

);

//Lowest byte SP, Start Page

mySSD_Write_data((ye>>

8

)&

0x00FF

);

//Highest byte EP

mySSD_Write_data(ye & 

0x00FF

);

//Lowest byte EP, End Page

//WRITE MEMORY START

mySSD_Write_cmd(

0x2C

); } 

Now this function copy an entire frame in just 54ms (measured with a timer), so it's fast, and when i transfer the Test Frame I got nearly the same result: When the Illegal value is reach, the frame stops loading itself in the SSD, all the next values (although they are correctly sent) won't shows up, but at least the initialisation of the SSD remains consistent and, if the following new frame has only ''legal'' values things start working again.

  • From now, all i can think of is that, when i transfer a lot of bytes all together, some transfer are messing up timings. I guess that this result in a no more synced transmission that makes SSD to go by it's own way. So my guess is that maybe i messed up something with the FMC init code. I post i here, maybe someone will see something very wrong:

/* Afer Slow Init and SSD Init, Fast Init must be called for high FPS */

uint8_t myFMC_SSD_FAST_Init(

void

){

FMC_NORSRAMInitTypeDef  FMC_NORSRAMInitDef;

FMC_NORSRAMTimingInitTypeDef  FMC_NORSRAMTimingInitDef;

/* Enable FMC clock */

RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);

/* FMC SSD1963 as a NORSRAM device initialization sequence ---*/

/* Step 1 ----------------------------------------------------------*/

/* Timing configuration for 84 Mhz of SD clock frequency (168Mhz/2) */

FMC_NORSRAMTimingInitDef.FMC_AddressSetupTime = 

0

;

FMC_NORSRAMTimingInitDef.FMC_AddressHoldTime = 

0

;

FMC_NORSRAMTimingInitDef.FMC_DataSetupTime = 

4

;

FMC_NORSRAMTimingInitDef.FMC_BusTurnAroundDuration   = 

0

;

FMC_NORSRAMTimingInitDef.FMC_CLKDivision     = 

0

;

FMC_NORSRAMTimingInitDef.FMC_DataLatency            = 

0

;

FMC_NORSRAMTimingInitDef.FMC_AccessMode              = FMC_AccessMode_B;

/* FMC SDRAM control configuration */

FMC_NORSRAMInitDef.FMC_Bank  = FMC_Bank1_NORSRAM1;

    FMC_NORSRAMInitDef.FMC_DataAddressMux  = FMC_DataAddressMux_Disable;

FMC_NORSRAMInitDef.FMC_MemoryType  = FMC_MemoryType_NOR;

FMC_NORSRAMInitDef.FMC_MemoryDataWidth  = FMC_NORSRAM_MemoryDataWidth_16b;

FMC_NORSRAMInitDef.FMC_BurstAccessMode  = FMC_BurstAccessMode_Disable;

FMC_NORSRAMInitDef.FMC_AsynchronousWait = FMC_AsynchronousWait_Disable;

FMC_NORSRAMInitDef.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low;

FMC_NORSRAMInitDef.FMC_WrapMode  = FMC_WrapMode_Disable;

FMC_NORSRAMInitDef.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState;

FMC_NORSRAMInitDef.FMC_WriteOperation  = FMC_WriteOperation_Enable;

FMC_NORSRAMInitDef.FMC_WaitSignal  = FMC_WaitSignal_Disable;

FMC_NORSRAMInitDef.FMC_ExtendedMode  = FMC_ExtendedMode_Disable;

FMC_NORSRAMInitDef.FMC_WriteBurst  = FMC_WriteBurst_Disable;

FMC_NORSRAMInitDef.FMC_ContinousClock  = FMC_CClock_SyncOnly;

FMC_NORSRAMInitDef.FMC_ReadWriteTimingStruct = &FMC_NORSRAMTimingInitDef;

FMC_NORSRAMInitDef.FMC_WriteTimingStruct = &FMC_NORSRAMTimingInitDef;

/* DISABLING THE NORSRAM BANK WHILE CHANGING SPEED */

FMC_NORSRAMCmd(FMC_Bank1_NORSRAM1, DISABLE);

/* FMC NORSRAM bank initialization */

FMC_NORSRAMInit(&FMC_NORSRAMInitDef);

/* FMC NORSRAM bank enable */

FMC_NORSRAMCmd(FMC_Bank1_NORSRAM1, ENABLE);

return

1

;

}

Thank you again jj.sprague for you're help, when this mess is solved i'm already planning to release a library for this, maybe i will solve lot of problems to other people.

jj2
Associate II
Posted on May 12, 2015 at 23:27

Davide, ''When I hit the illegal value I didn't see any strange behaviour on the Control/Address/Data Lines but, what change is the interpretation of those by the SSD or something else...''

 

I'm glad that you've made some progress - yet I don't believe that the ''SSD'' chip would (suddenly) ''misinterpret'' data - which it (earlier) recognized/responded to correctly!    That's not very likely - trust you'll agree.

More likely is the occurrence of some signal glitch - or power disturbance - which (most likely) impacts one or more of the SSD's control signal inputs.   Such is far more likely to cause the SSD ''disorder'' which you note.

Have you (really) monitored these control signals - @ the SSD - during the occurrence of the ''illegal'' data word?    I'd wager tall stack of chips - ''that'' is where your issue lies.

Unknown & undescribed is ''how'' you monitored these control signals during that critical ''illegal'' data transmission.    Logic analyzer proves ideal here - fast FPGA monitoring & storing results is a ''poor man's'' substitute - and can ''go places'' where a ''good'' scope cannot.
matthew2
Associate II
Posted on May 14, 2015 at 16:01

I am also having a possible similar / related problem.  For testing I'm drawing a square onto a plain background in a frame buffer, then transferring the buffer to the screen though the FMC (not using dma).  If the colour of the square is white, then the SSD1963 chip stops listening to the transfer partway though the update as show here:

0690X000006031fQAA.jpg

My logic analyser shows that 76800 writes (320x240) are happening on the 8080 bus, its just that the SSD stops listening.

If I change the colour of the box to another colour, say yellow, then the whole screen updates successfully.

0690X000006031LQAQ.jpg

Once again, the logic analyser shows 76800 writes from the FMC, yet this time the whole screen is refreshed correctly.

I can get the white square to draw correctly by lowing the HCLK speed of the micro (by using /8 in pll-p).  If I use 84MHz (PLL-P = /4) I can get the white square to draw correctly by putting a 1K pullup between the NWE line and +V.

The pullup doesn't work when HCLK is 168MHz, the only way I can get this to work is to enable the 'extended mode' on the FMC controller, though the screen refreshes are very slow when I do this, even though I'm using the same timing structure for both normal and extended mode.

The problem seems to exist if regardless of if I use external or internal SDRAM for the frame buffer. Most of the time I'm using an internal buffer because it allows me to analyse the FMC port easier with the logic analyser.

I'm not sure if a port isn't set up correctly or some other timing isn't correct, but if you find anything out I would be interested to know.

davide
Associate II
Posted on May 15, 2015 at 03:01

Sorry jj.sprague for the delay in the answer,

and thank you again for your help, as i think you already know, i'm moving my first steps in the stm32f4 mcu. 

Back to the topic, i'm now waiting (just purchased) for a ''real'' LA, right now i'm using another stm32f429 that reads a whole GPIO port and store some micro-s of data transfer inside stm32f4 internal memory... when transition is done it send all to the usart in an excel friendly format and from it i read what's happened in 16 channels. I know it's a real real poor's man solution... and for sure that wont let me see if glitch are happening.

I only hope the shipment won't take so much time, so i can show you some ''trustable'' results, right now i think they're just not relevant....

My configuration for these tests is ''simple''  SSD1963 (8080 parallel 565 color) <-> STM32F429 discovery (lcd removed) <-> SDRAM     +   SDCARD over SDIO (but it's not used nor init while LA, the frame is composed directly in sdram by the stm32f4).

Here I leave a short video to show what's happening right now (as soon as I have a real LA I will put also the ''formal'' results): 

https://youtu.be/Be25GTwIVss

Matt suggested pull-up on NWE, i think i will try during the weekend. 

I Really appreciate all the support and help, i'll keep you updated!

jj2
Associate II
Posted on May 15, 2015 at 03:47

Thanks to poster Matt for sharing his findings.   It's been several years since we last used SSD1963 - yet I do not recall having such color limitations or having to use a pull-up on the signal as mentioned.

We did pay full attention the SSD's timing chart - and carefully scoped each/every signal - to insure compliance.    Sometimes you can, ''bend the rules'' but usually ''not'' when it comes to timing charts!

As Matt reports the issue w/''white'' - may we ask that he repeat his test - but this time w/black - to better duplicate Davide's earlier test/report.

Suspect that Matt's logging his address, data & control signals - both before - during - and then after the ''illegal'' white's arrival - may prove useful.    If not a ''glitched'' control signal line -

 then I lean to an incorrect SSD ''set-up/config.''

I'd bet that Matt's TFT is a 2.4 - 3.5'' in QVGA format.    These place less burden upon the MCU and the SSD during screen update than the more pixel intense (7'') screen used by Davide.

Displays are one of the most ''fun'' devices to troubleshoot (provided you can get (some) pixels to display) as the impact of your changes becomes immediately visible.

Good luck to you both...

matthew2
Associate II
Posted on May 15, 2015 at 15:32

Managed to get a little more time to play around today.  Heres what I've found out.  I suspect the pull-up is a bit of a red-herring.  I'm guessing its just skewing a clock edge a little.

With the AHB bus at 42MHz (pll-p=/2, AHB=/4, APB1=/2, APB2=/1) I can use Data-Setup-time=4 on the FMC controller and the SSD will update correctly.  Using this setting I can get 29 full screen updates per second (320x240), this is good!

When I move to a faster speed where the AHB bus is at 84MHz (AHB=/2) then I can only get the SSD to respond by setting data-setup-time to 160 for the FMC.  This works, but the update rate becomes very slow and I can only get 7 full screen updates per second.  If I set the Data-setup-time any lower, either the display doesn't respond or or corrupts with bad data.

I assume its something to do with the 1HCLK cycle after the write pulse (pg 1601 of the reference manual) being too fast for the SSD.  The max command rate for the SSD is half the clock.  I have my SSD clock set to 120MHz which give a maximum speed of 60MHz, hence why 42MHz works and 84Mhz doesn't.

It seems a shame to have to run the AHB at 42MHz to get this working, there must be a better way to adjust the timings on the FMC that I'm just not seeing.

Edit:

This is running from a frame buffer in the INTERNAL SDRAM.  If I switch to the EXTERNAL SDRAM, I once again get corruption caused by various colours (primarily white).  Might have to stick with internal frame buffer for the time being, fortunately I can do this with the 320x240 screen.