Re: MCF5329 LCD controller not working

Nicolas Pinault <[email protected]> Mon, 26 May 2008 17:46:01 +0200
Newsgroups gmane.comp.hardware.motorola.microcontrollers.coldfire
Organization AATON
Message-ID <[email protected]>
Well, forget my previous message. It still does not work.
I have HCLK, VSync and HSync running. But OE and Data lines are stuck to 
ground.

Nicolas


Nicolas Pinault a écrit :
> Hi Roman,
>
> Thank you for your answer.
> My problem was a big error in my code. The following two lines were at 
> the end of my init function instead at the begining :
>
> // Enable LCD controller
>     MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LCD_CHEN;
>
> I put them at the right place (at the beginning of the init function). 
> Now, it works correctly.
>
> Regards,
> Nicolas
>
>
> Bystrianyk, Roman a écrit :
>>
>> 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
>>
>>                         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.
>>
>>
>>   
>> [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. [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. 
> [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.