RE: MCF5329 LCD controller not working

"Bystrianyk, Roman" <[email protected]> Fri, 23 May 2008 08:37:20 -0400
Newsgroups gmane.comp.hardware.motorola.microcontrollers.coldfire
Message-ID <[email protected]>
Hi Nicolas,

 

We're using the LCD/5329 and it's working great - take a look at this
portion of our driver and see if it is of any help.  Good luck!

 

Roman

 

void DragonFireScreen::ConfigureController(void)

{

    PEGULONG *pLongReg;

    PEGULONG lVal;

    PEGUSHORT HalfVal;

    LCD_REGS *pRegs = (LCD_REGS *) LCD_REG_BASE;

 

   #if defined(PANEL_QVGA10)

    pRegs->ContrastControl = 0x00008000;

   #endif

 

    // first configure GPIO for LCD control:

 

    // PAR_LCDDATA- page 13-31

    PEGUBYTE *pByteReg = (PEGUBYTE *) 0xfc0a405d;   

    *pByteReg = 0xff;

 

    // PAR_LCDCTRL- page 13-32

    PEGUSHORT *pHalfReg = (PEGUSHORT *) 0xfc0a405e; 

   

   #if defined(PANEL_QVGA10)

    *pHalfReg = 0x01ff;        

   #else

    *pHalfReg = 0x1f0;      

   #endif

 

    // Port data direction regs, page 13-17

    pByteReg = (PEGUBYTE *) 0xfc0a4021;     // PDDR_LCDDATAM

    *pByteReg++ = 0xff;                     // all outputs

 

    pByteReg = (PEGUBYTE *) 0xfc0a4022;     // PDDR_LCDDATAL

    *pByteReg++ = 0xff;                     // all outputs

 

    pByteReg = (PEGUBYTE *) 0xfc0a4025;     // PDDR_LCDCTLL

    *pByteReg++ = 0xff;                     // all outputs

 

    // Drive Strength Control, LCD (DSCR_LCD), page 13-35

 

    pByteReg = (PEGUBYTE *) 0xfc0a406f;

    *pByteReg = 0x01;   // max drive strength?

 

    // Master privelege register 1, page 11-4

 

    pLongReg = (PEGULONG *) 0xec000000;

    lVal = *pLongReg;

    lVal |= 0x00007000;

    *pLongReg = lVal;

 

    // 

    // Peripheral access control register F, page 11-5

 

    pLongReg = (PEGULONG *) 0xfc000044;     // PACRF

    lVal = *pLongReg;

    lVal &= 0xfff0ffff;

    *pLongReg = lVal;

 

    // LCD HCLK disable (MISCCR). Page 9-5

 

    pHalfReg = (PEGUSHORT *) 0xfc0a0010;

    HalfVal = *pHalfReg;

    HalfVal &= ~(1 << 8);

    *pHalfReg = HalfVal;

 

 

    pRegs->ScreenStartAddr = (PEGULONG) mpVidMemBase;

    pRegs->Size = ((PEG_VIRTUAL_XSIZE / 16) << 20) | PEG_VIRTUAL_YSIZE;

    pRegs->VirtualPageWidth = PEG_VIRTUAL_XSIZE / 4;    // 4 pixels /
longword

    pRegs->CursorPos = 0;

    pRegs->CursorSizeBlink = 0;

    pRegs->PanelConfig = 

        (LCD_PANEL_TYPE << 31)  |

        (LCD_COLOR << 30)       |

        (LCD_BUS_WIDTH << 28)   |

        (LCD_BITS_PIX << 25)    |

        (LCD_PIX_POL  << 24)    |

        (LCD_FLM_POL  << 23)    |

        (LCD_LP_POL   << 22)    |

        (LCD_CLK_POL  << 21)    |

        (LCD_OE_POL   << 20)    |

        (LCD_SCLK_IDLE << 19)   |

        (LCD_ENDIAN   << 18)    |

        (LCD_SWAP_SEL << 17)    |

        (LCD_REV_VS   << 16)    |

        (LCD_ACD_SEL  << 15)    |

        (LCD_ACD << 8)          |

        (LCD_SCLK_SEL << 7)     |

        (LCD_SHARP << 6)        |

        (LCD_PCD);

 

    pRegs->HorzConfig = (LCD_HSYNC_WIDTH << 26) |

                        (LCD_HWAIT1 << 8)       |

                        (LCD_HWAIT2);

 

 

    pRegs->VerticalConfig = (LCD_VSYNC_WIDTH << 26) |

                            (LCD_VWAIT1 << 8)       |

                            (LCD_VWAIT2);

 

    pRegs->PanOffset = 0;

 

   #if defined(PANEL_QVGA10)

    pRegs->SharpConfig = 0x04000000;

   #else

    pRegs->SharpConfig = 0;

   #endif

 

    pRegs->DMAControl = (LCD_BURST << 31)   |

                        (LCD_HI_MARK << 16) |

                        (LCD_LO_MARK);

 

    pRegs->InterruptConfig = 0; // interrupt on loading last data end of
frame

    pRegs->InterruptEnable = 0;

 

   #if defined(ENABLE_GRAPHICS_PLANE) || defined(HARDWARE_CURSOR)

 

    pRegs->GraphicWindowStart = (PEGULONG)
mpGraphicsContext->pBaseAddress;

    pRegs->GraphicWindowSize = ((mpGraphicsContext->Width / 16) << 20) |

                               mpGraphicsContext->Height;

 

    pRegs->GraphicWindowVirtualPageWidth = mpGraphicsContext->Width / 4;

 

    pRegs->GraphicWindowPanOffset = 0;

    pRegs->GraphicWindowPos = 0;

    pRegs->GraphicWindowControl = 0x0000    |        // transparent  

                                  (1 << 22) |       // enable

                                  (1 << 23) |       // color key enable

                                  GRAPHIC_COLOR_KEY;          // color
key

   #else

 

    pRegs->GraphicWindowStart = 0;

    pRegs->GraphicWindowSize = 0;

    pRegs->GraphicWindowVirtualPageWidth = 0;

    pRegs->GraphicWindowPanOffset = 0;

    pRegs->GraphicWindowPos = 0;

    pRegs->GraphicWindowControl = 0;

 

   #endif       // GRAPHICS plane enabled?

 

    pRegs->GraphicWindowDMAControl = (LCD_BURST << 31)   |

                        (LCD_HI_MARK << 16) |

                        (LCD_LO_MARK);

 

    // configure DMA channel if used:

 

   #if defined(LCD_DMA_CHANNEL)

 

    mpWaitChannel = NULL;

 

    // configure registers that don't change:

 

    pLongReg = (PEGULONG *) eDMA_CONTROL;

    *pLongReg = 0x04;       // round robbin arbitration

 

    // clear enable error interrupt:

 

    pByteReg = (PEGUBYTE *) eDMA_CLR_ENABLE_ERROR_INT;

    *pByteReg = LCD_DMA_CHANNEL;    // no error ints from this channel

    *pByteReg = LCD_DMA_CHANNEL + 1;

 

    // clear errors

 

    pByteReg = (PEGUBYTE *) eDMA_CLEAR_ERROR;

    *pByteReg = LCD_DMA_CHANNEL;

    *pByteReg = LCD_DMA_CHANNEL + 1;

 

    // clear the done bit:

 

    pByteReg = (PEGUBYTE *) eDMA_CLEAR_DONE;

    *pByteReg = LCD_DMA_CHANNEL;

    *pByteReg = LCD_DMA_CHANNEL + 1;

 

    DMA_TCD *pTcd = (DMA_TCD *)

        (eDMA_TCD_BASE + (LCD_DMA_CHANNEL * eDMA_TCD_SIZE));

    DMA_TCD *pChannel2 = (DMA_TCD *)

        (eDMA_TCD_BASE + ((LCD_DMA_CHANNEL + 1) * eDMA_TCD_SIZE));

 

 

    pTcd->Attribs = 0x0202;     // 32-bit xfers, no modulo

    pTcd->SourceOffset = 4;

    pTcd->DestOffset = 4;

 

    pChannel2->LastSourceAdjust = 0;

    pChannel2->LastDestAdjust = 0;

    pChannel2->SourceOffset = 0;

    pChannel2->DestOffset = 0;

    pChannel2->MinorByteCount = 1;

 

    // we copy from one TCD field to another, just to give channel2

    // something to do:

 

    pChannel2->SourceAddr = (PEGULONG) &PegDmaDummy[0];

    pChannel2->DestAddr = (PEGULONG) &PegDmaDummy[1];

 

    pChannel2->Attribs = 0x0000;     // 8-bit xfer, no modulo

    pTcd->Attribs = 0x0202;

 

    // Peripheral power management register hi- page 8-6

 

    pLongReg = (PEGULONG *) 0xfc040034;

    lVal = *pLongReg;

    lVal &= ~(1 << 17);           // enable eDMA clock block

    *pLongReg = lVal;

 

   #endif       // LCD_DMA_CHANNEL

 

 

    // Peripheral power management register low- page 8-5

 

    pLongReg = (PEGULONG *) 0xfc040030;

    lVal = *pLongReg;

    lVal &= ~(1 << 11);           // enable LCD clock block

    *pLongReg = lVal;

 

   #if defined(PANEL_QVGA10)

        pRegs->ContrastControl = 0x00a9038f;

   #endif

 

    // Crossbar Switch prorities. We program the LCDC (M4) to second

    // highest priority (after the core) to prevent underflows with
large

    // displays when the eDMA is in use:

 

    pLongReg = (PEGULONG *) 0xfc004100; // slave 1 (SRAM) priority reg

    //*pLongReg = 0x76510320;     // LCDC = 1, FEC = 3, eDMA = 2, core =
0

    *pLongReg =   0x76510230;     // LCDC = 1, FEC = 2, eDMA = 3, core =
0

 

    pLongReg = (PEGULONG *) 0xfc004110; // slave 1 (SRAM) control reg

    *pLongReg = 0x00000004;     // fixed priority, park on LCDC

 

 

    // turn on the backlight (LogicPD eval kits only)

    // The SMX RTOS continuously updates the LEDs by

    // updating a "latch shadow" register. The external

    // latch register cannot be read by software, so they

    // keep a shadow.

 

   #if defined(PEGSTANDALONE)

   // Can't do this unless CS has been configured, leave for the RTOS
for now:

   // pByteReg = (PEGUBYTE *) 0x10080000;

   // *pByteReg = 0x10;

   #elif defined(PEGSMX)

    m5329evb_latch_shadow |= 0x10;  // enable the backlight

    pByteReg = (PEGUBYTE *) 0x10080000;

    *pByteReg = m5329evb_latch_shadow;

    count(100, ticks, INF);

   #endif

 

    // fill screen with black

 

    memset(mpVidMemBase, 0, FRAME_BUFFERS_SIZE);

 

    // LCD HCLK enable (MISCCR). Page 9-5

 

    pHalfReg = (PEGUSHORT *) 0xfc0a0010;

    HalfVal = *pHalfReg;

    HalfVal |= (1 << 8);

    *pHalfReg = HalfVal;

}

 

________________________________

From: [email protected] [mailto:[email protected]]
On Behalf Of Nicolas Pinault
Sent: Friday, May 23, 2008 5:37 AM
To: Bystrianyk, Roman
Subject: [ColdFire] MCF5329 LCD controller not working

 

Hi all,

I'm trying to use MCF5329 LCD controller but no signals are output from
the chip. No clk, no sync, no data.
My LCD panel is a 640x480 color TFT panel.

Here is an excerpt of my code :

    MCF_GPIO_PAR_LCDDATA = MCF_GPIO_PAR_LCDDATA_PAR_LD7_0(3)  | // LCD
                           MCF_GPIO_PAR_LCDDATA_PAR_LD15_8(3) | // LCD
                           MCF_GPIO_PAR_LCDDATA_PAR_LD16(3)   | // LCD
                           MCF_GPIO_PAR_LCDDATA_PAR_LD17(3);    // LCD
    
    MCF_GPIO_PAR_LCDCTL = //MCF_GPIO_PAR_LCDCTL_PAR_CLS       |   // LCD
                          //MCF_GPIO_PAR_LCDCTL_PAR_PS        |   // LCD
                          //MCF_GPIO_PAR_LCDCTL_PAR_REV       |   // LCD
                          //MCF_GPIO_PAR_LCDCTL_PAR_SPL_SPR   |   // LCD
                          MCF_GPIO_PAR_LCDCTL_PAR_CONTRAST  |   // LCD
                          MCF_GPIO_PAR_LCDCTL_PAR_LSCLK     |   // LCD
                          MCF_GPIO_PAR_LCDCTL_PAR_LP_HSYNC  |   // LCD
                          MCF_GPIO_PAR_LCDCTL_PAR_FLM_VSYNC |   // LCD
                          MCF_GPIO_PAR_LCDCTL_PAR_ACD_OE;       // LCD
        
    MCF_GPIO_PDDR_LCDCTLH  = 0x01;  // Tout en sortie
    MCF_GPIO_PDDR_LCDCTLL  = 0xFF;  // Tout en sortie
    MCF_GPIO_PDDR_LCDDATAH = 0x03;  // Tout en sortie
    MCF_GPIO_PDDR_LCDDATAM = 0xFF;  // Tout en sortie
    MCF_GPIO_PDDR_LCDDATAL = 0xFF;  // Tout en sortie
    
    MCF_GPIO_DSCR_LCD = MCF_GPIO_DSCR_LCD_LCD_DSE(3);   // Maximum drive
strength

    // Bursting
    MCF_SCM_BCR = MCF_SCM_BCR_GBR |
                  MCF_SCM_BCR_GBW |
                  0xFF;

    // Panel configuration
    MCF_LCDC_LPCR = MCF_LCDC_LPCR_PCD(4) |      // TODO : 2 ?
                    //MCF_LCDC_LPCR_SHARP |
                    MCF_LCDC_LPCR_SCLKSEL |
                    MCF_LCDC_LPCR_ACD(0) |
                    MCF_LCDC_LPCR_ACDSEL |
                    //MCF_LCDC_LPCR_REV_VS |
                    MCF_LCDC_LPCR_SWAP_SEL |
                    MCF_LCDC_LPCR_ENDSEL |
                    MCF_LCDC_LPCR_SCLKIDLE |
                    MCF_LCDC_LPCR_OEPOL |
                    MCF_LCDC_LPCR_CLKPOL |
                    MCF_LCDC_LPCR_LPPOL |
                    MCF_LCDC_LPCR_FLM |
                    //MCF_LCDC_LPCR_PIXPOL |
                    MCF_LCDC_LPCR_BPIX_18bpp |
                    MCF_LCDC_LPCR_PBSIZ_8 |
                    MCF_LCDC_LPCR_COLOR |
                    MCF_LCDC_LPCR_TFT;
    
    // Horizontal configuration
    MCF_LCDC_LHCR = MCF_LCDC_LHCR_H_WAIT_2(78-3) |    // tHBP
                    MCF_LCDC_LHCR_H_WAIT_1(88-1) |    // tHFP
                    MCF_LCDC_LHCR_H_WIDTH(2-1);
    
    // Vertical configuration
    MCF_LCDC_LVCR = MCF_LCDC_LVCR_V_WAIT_2(1) |
                    MCF_LCDC_LVCR_V_WAIT_1(6) |
                    MCF_LCDC_LVCR_V_WIDTH(1);
    
    // Start Address
    MCF_LCDC_LSSAR = MCF_LCDC_LSSAR_SSA((INT32U)BackgroundPlane);
    
    // Width and Height
    MCF_LCDC_LSR = MCF_LCDC_LSR_XMAX(480/16) | 
                   MCF_LCDC_LSR_YMAX(640);
    
    // Virtual width
    MCF_LCDC_LVPWR = MCF_LCDC_LVPWR_VPW(480);
    
    // Cursor
    MCF_LCDC_LCPR = MCF_LCDC_LCPR_CXP(100) |
                    MCF_LCDC_LCPR_CYP(100) |
                    MCF_LCDC_LCPR_CC_XOR |
                    MCF_LCDC_LCPR_OP_ON;
    
    // Cursor Width Height and Blink
    MCF_LCDC_LCWHBR = MCF_LCDC_LCWHBR_BD(32) |
                      MCF_LCDC_LCWHBR_CH(10) |
                      MCF_LCDC_LCWHBR_CW(20) |
                      MCF_LCDC_LCWHBR_BK_EN_ON;
    
    // Color cursor mapping
    MCF_LCDC_LCCMR = MCF_LCDC_LCCMR_CUR_COL_R(0x30) |   // midscale
                     MCF_LCDC_LCCMR_CUR_COL_G(0x30) |
                     MCF_LCDC_LCCMR_CUR_COL_B(0x30);
    
    
    // Panning offset
    MCF_LCDC_LPOR = MCF_LCDC_LPOR_POS(0);
    
    // Dma control
    MCF_LCDC_LDCR = MCF_LCDC_LDCR_TM(4) |
                    MCF_LCDC_LDCR_HM(8) |
                    MCF_LCDC_LDCR_BURST;
    
    // Refresh mode
    MCF_LCDC_LRMCR = MCF_LCDC_LRMCR_SEL_REF;
    
    // Interrupt configuration
    MCF_LCDC_LICR = 0;
    
    // Interrupt enable
    MCF_LCDC_LIER = 0;
    
//    // Graphic window start address
//    MCF_LCDC_LGWSAR = MCF_LCDC_LGWSAR_GWSA((INT32U)GraphicPlane);
//    
//    // Graphic window size
////    MCF_LCDC_LGWSR = MCF_LCDC_LGWSR_GWH(640) |
////                     MCF_LCDC_LGWSR_GWW(480/16);
//    MCF_LCDC_LGWSR = MCF_LCDC_LGWSR_GWH(1) |
//                     MCF_LCDC_LGWSR_GWW(1);
//    
//    // Graphic window virtual page width
//    MCF_LCDC_LGWVPWR = MCF_LCDC_LGWVPWR_GWVPW(480);
//    
//    // Graphic window panning offset
//    MCF_LCDC_LGWPOR = MCF_LCDC_LGWPOR_GWPO(0);
//    
//    // Graphic window position
//    MCF_LCDC_LGWPR = MCF_LCDC_LGWPR_GWYP(0) |
//                     MCF_LCDC_LGWPR_GWXP(0);
    
    // Graphic window control
    MCF_LCDC_LGWCR = MCF_LCDC_LGWCR_GWCKB(0x3F) |
                     MCF_LCDC_LGWCR_GWCKG(0x3F) |
                     MCF_LCDC_LGWCR_GWCKR(0x3F) |
                     //MCF_LCDC_LGWCR_GW_RVS  |
                     //MCF_LCDC_LGWCR_GWE |
                     //MCF_LCDC_LGWCR_GWCKE |
                     MCF_LCDC_LGWCR_GWAV(0);
    
    // Graphic window DMA control
    MCF_LCDC_LGWDCR = MCF_LCDC_LGWDCR_GWTM(4) |
                      MCF_LCDC_LGWDCR_GWHM(8) |
                      MCF_LCDC_LGWDCR_GWBT;
    
    // Mapping RAM registers
    
    
    // Enable LCD controller
    MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LCD_CHEN;

I am obviously missing something but what ?
Any help would be appreciated.

Best regards,
Nicolas Pinault

[email protected] Send a post to the list.
[email protected] Join the list. [email protected]
Join the list in digest mode. [email protected] Leave the
list.


                        LEGAL NOTICE:
Unless expressly stated otherwise, this message is confidential 
and may be privileged. It is intended for the addressee(s) 
only. Access to this e-mail by anyone else is unauthorized. If 
you are not an addressee, any disclosure or copying of the 
contents or any action taken (or not taken) in reliance on it 
is unauthorized and may be unlawful. If you are not an 
addressee, please inform the sender immediately.