Hello. I've been trying (for almost 2 months) to set the LCDC module of the TWR K70 board with no succes. I need to display a number in a plain VGA PC monitor connecting the VGA DB-15. connector in a board.
I am trying first to get the signals out of the k70 but nothing... I don't even see the Hsync or Vsync signals.
This is my program, it is just configuration to turn on the LCDC but nothing, what is wrong? Programm is full of comments since I am learning and reading the data sheet and getting the elements I need to complete the project I am working for, so I am sorry because it is quite messy but Looks like I am very near of the goal.
Here is my set up, the board, getting out the H & V signals to the oscilloscope of the elevator connector but nothing.
HELP PLEASE!!!
#include "derivative.h" /* include peripheral declarations */
#define XMAX 800
#define YMAX 600
#define ALT7 0x00000700
int arreglo [4000]={0xaaaaaaaa};
int *ptr;
int main(void)
{
int counter = 0;
ptr = (void *)&arreglo;
SIM_SCGC5 = (1<<14) | (1<<9); //activate PORTA and PORTF
PORTA_PCR10 = 0x00000120; //config LEDs of twr K70
PORTA_PCR11 = 0x00000120;
PORTA_PCR28 = 0x00000120;
PORTA_PCR29 = 0x00000120;
//GPIO pag 2147
GPIOA_PDOR = 0x30000C00; //field descriptions
GPIOA_PDDR = 0x30000C00;
// PORTF_PCR2 = 0x00000120;
// PORTF_PCR3 = 0x00000120;
GPIOF_PDOR = 0x0000000C; //field descriptions
GPIOF_PDDR = 0x0000000C;
//señal de horizontal GLCD_HFS que es PTF2 que es pin N16 está en D27 de J7B LCD_HSYNC
//señal de vertical GLCD_VFS que es PTF3 que es pin M16 está en D28 de J7B LCD_VSYNC
//señal de horizontal GLCD_HFS que es PTD14 que es pin E5 está en D27 de J7B LCD_HSYNC
//señal de vertical GLCD_VFS que es PTD15 que es pin E4 está en D28 de J7B LCD_VSYNC
//GPIOF_PDOR = 0x0000000C;
//GPIOF_PSOR =
//GPIOF_PCOR =
//GPIOF_PTOR =
//GPIOF_PDIR =
//GPIOF_PDDR = 0x0000000C;
//lo referente al LCDC pag 193
//SYSTEM MEMORY MAP
//CLOCK DISTRIBUTION pag 229
//diagrama del clock en pag 214 y 636
MCG_C5 = 0b11000000; //seleccionamos 0SC1 como fuente de clock bit 7 (0 osc1 de 12Mhz y 1 osc0 de 50Mhz)
//y habilitamos MCGPLL0CLK MCG Control 5 Register pag 643
MCG_C6 = 0b00000000; //MCG Control 6 Register (MCG_C6) pag 644
//MCG_C11 = 0b //MCG Control 11 Register
//pag 214 Bus clock, MCGPLL0CLK, MCGPLL1CLK, OSC0ERCLK son fuentes de clock del LCDC
//detalles de clock , 221, 217,
SIM_SOPT2 = 1<<26 | 0<<14; //selecciona la fuente de clock
//[LCDC_LCDCSRC] bits 27 y 26, 0 Bus clock, 1 MCGPLL0CLK, 2 MCGPLL1CLK, 3 OSC0ERCLK
//[LCDC_CLKSEL] bit 14 pag 324 0 Clock divider LCDC pixel clock, 1 EXTAL1 clock.
SIM_CLKDIV3 = 1<<16 | 1<<8; // pag355
//LCDC Clock divider fraction bits 16 al 27
//This field sets the fraction multiply value for the fractional clock divider used as a source for LCDC pixel
//clock. The source clock for the fractional clock divider is set by the SOPT2 LCDCSRC[1:0] register bit.
//Divider output clock = Divider input clock*((LCDCFRAC+1)/(LCDCDIV+1))
//LCDCFRAC bits 8 al 15
SIM_SCGC3 = 1<<22; //pag 338 LCDC clock gate control, 1 Clock is enabled.
//POWER MANAGEMENT
//SIGNAL MULTIPLEXING
//Chip configuration pag 81
//The Memory Protection Unit must be configured to allow the LCDC to access the DRAM.
//pines del micro y nombres pag 297
//crossbar switch pag 100
//Master module LCDC graphic window Master port number 5
//Master module LCDC background plane Master port number 4
//LCDC explicación de cómo funciona el LCDC pag 2215
//signals Multiplexing module pag 273
PORTF_PCR2 = 0x00000700; //alt7 GLCD_HFS pag 280
PORTF_PCR3 = 0x00000700; //alt7 GLCD_VFS pag 280
//PORTF_PCR0 = ALT7; // Graphic LCD PCLK, Schematic PTF0
//PORTF_PCR1 = ALT7; // Graphic LCD DE, Schematic PTF1
//PORTF_PCR2 = ALT7; // Graphic LCD HSYNC, Schematic PTF2
//PORTF_PCR3 = ALT7; // Graphic LCD VSYNC, Schematic PTF3
PORTF_PCR4 = ALT7; // Graphic LCD D[0], Schematic PTF4
PORTF_PCR5 = ALT7; // Graphic LCD D[1], Schematic PTF5
PORTF_PCR6 = ALT7; // Graphic LCD D[2], Schematic PTF6
PORTF_PCR7 = ALT7; // Graphic LCD D[3], Schematic PTF7
//configuración de gráficos: LCDC (Liquid Cristal Display Controller) Pag 2183
//LCDC_LSSAR = (void *)&ptr; //LCDC screen start address register
LCDC_LSSAR = ((int)ptr)<<1; //LCDC screen start address register
LCDC_LSR = XMAX<<20 | YMAX; //LCDC size register XMAX y YMAX ** Aguas con XMAX si es o no dividido por 16
LCDC_LVPWR = XMAX; //LCDC virtual page width register representa la dirección de inicio de una línea desplegada
LCDC_LCPR = 0; //LCDC cursor position register tipo de cursor, e inicio en X,Y del cursor
LCDC_LCWHB = 0; //LCDC cursor width, height, and blink register
LCDC_LCCMR = 0; //LCDC color cursor mapping register
//pag 2194 - LCDC_LPCR
//LCDC_LPCR = 0b 1100 0100 1100 1010 1000 0000 1000 0001; //configura algo de tiempos LCDC panel configuration register 2194 his register defines all properties of the LCD screen.
LCDC_LPCR = 0b11000100110010101000000010000001;
LCDC_LHCR = 10<<26|10<<8|50; //LCDC horizontal configuration register
LCDC_LVCR = 15<<26|15<<8|15; //LCDC vertical configuration register
LCDC_LPOR = 0; //LCDC panning offset register
LCDC_LPCCR = 1<<7; //LCDC PWM contrast control register
LCDC_LDCR = 1<<31; //LCDC DMA control register
LCDC_LRMCR = 1; //LCDC refresh mode control register 0 Disable self-refresh
LCDC_LICR = 0; //LCDC interrupt configuration register
//If an EOF interrupt is desired, then set INTCON=0 and LIER[EOF_EN]=1.
//If a BOF interrupt is desired, then set INTCON=1 and LIER[BOF_EN]=1.
LCDC_LIER = 0; //LCDC interrupt enable register
LCDC_LISR = 0; //LCDC interrupt status register
LCDC_LGWSAR = 0; //LCDC graphic window start address register 2207
LCDC_LGWSR = 800<<20 | 600; //LCDC graphic window size register
LCDC_LGWVPWR = 4; //LCDC graphic window virtual page width register
LCDC_LGWPOR = 1; //LCDC graphic window panning offset register
LCDC_LGWPR = 0; //LCDC graphic window position register
LCDC_LGWCR = 0x0f<<24|1<<23|1<<22|4<<12|4<<6|4; //LCDC graphic window control register
LCDC_LGWDCR = 1<<31; //LCDC graphic window DMA control register
LCDC_LAUSCR = 0; //LCDC AUS mode control register
LCDC_LAUSCCR = 0; //LCDC AUS mode cursor control register
SIM_MCR = 1<<16; //LCDSTART bit 16 // pag 357
for(;;)
{
for(counter=500000; counter > 0; counter--)
{
}
GPIOA_PTOR = 0x30000C00;
// GPIOF_PTOR = 0x0000000C;
}
return 0;
}
Hello Oliver,
You can check in the SC code, the example for the TWR-K70 (lcdc project)
KINETIS_120MHZ_SC : Kinetis 120MHz bare metal sample code.
Size (K): 17844 Format: zip Rev #: 1.4 Modified: 12/19/2013
By default the MPU is enabled and the LCDC can’t access to the DDR (frame buffer). You need to disable it completely or configure the MPU registers. For testing add:
/* Disable MPU */
MPU_CESR &= ~MPU_CESR_VLD_MASK;
But review the SC code project just in case you are missing other configuration.
Best Regards,
Luis
Hello Luis.
I downloaded the SC code, I changed to a new version and I've been trying to make the LCDC module to work and it is still the same, no Vsync or Hsync signals out of the ports...
This is my new code, it is practically the same provided by the SC and it is not working. What can I do? Who can help me with this?
/*
* main implementation: use this 'C' sample to create your own application
*
*/
#include "derivative.h" /* include peripheral declarations */
//#include "common.h"
//#include "lcdc.h"
//#include "lptmr.h"
//#include "sdram.h"
#define SCREEN_XSIZE 480
#define SCREEN_YSIZE 272
#define GW_XSIZE (SCREEN_XSIZE/2)
#define GW_YSIZE (SCREEN_YSIZE/2)
#define FRAME_START_ADDRESS 0x80400000 //Screen in DDR
#define GW_START_ADDRESS 0x80200000
#define FRAME_BUFFER_SIZE (SCREEN_XSIZE * SCREEN_YSIZE * 4) //4 bytes per pixel for 24bpp
#define GW_BUFFER_SIZE (GW_XSIZE * GW_YSIZE * 4) //4 bytes per pixel for 24bpp
int main(void)
{
int counter = 0;
// printf("LCD Controller Example\n");
//Enable Port clocks
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
/* Enable LCDC and DDR Modules */
SIM_SCGC3 |= SIM_SCGC3_LCDC_MASK;
/* Disable MPU */
MPU_CESR &= ~MPU_CESR_VLD_MASK;
/* LCDC configuration for TWR-LCD-RGB */
lcdc_init_screen();
lcdc_color_demo();
for(;;) {
counter++;
}
return 0;
}
void lcdc_color_demo()
{
color_demo_data(); //Create the frame buffer data for background plane and graphic window
color_demo_gw_setup(); //Initialize the graphic window registers for this demo
// set LCD Screen Start Address
LCDC_LSSAR = FRAME_START_ADDRESS;
// set LCD graphic window start address
LCDC_LGWSAR = GW_START_ADDRESS;
SIM_MCR|=SIM_MCR_LCDSTART_MASK; //Start LCDC
// printf("Hit any key to turn on/off the graphic window\n");
while(1)
{
// in_char(); //Wait for input
// LCDC_LGWCR&=~LCDC_LGWCR_GWE_MASK; //Turn off graphic window
// in_char(); //Wait for input
LCDC_LGWCR|=LCDC_LGWCR_GWE_MASK; //Turn on graphic window
}
}
void color_demo_data(void)
{
int *pointer32;
int i,n;
/*
* Create the frame buffer so that the screen will be divided into 4 quadrants
* of a different color:
* RG
* BW
*/
pointer32=(int *)FRAME_START_ADDRESS;
//Loop through top half of screen
for(i=0;i<SCREEN_YSIZE/2;i++)
{
//One half will be red
for(n=0;n<SCREEN_XSIZE/2;n++)
{
*pointer32=0x00FF0000; //Red
pointer32++;
}
//One half will be green
for(n=0;n<SCREEN_XSIZE/2;n++)
{
*pointer32=0x0000FF00; //Green
pointer32++;
}
}
//Loop through bottom half of screen
for(i=0;i<SCREEN_YSIZE/2;i++)
{
//One half will be blue
for(n=0;n<SCREEN_XSIZE/2;n++)
{
*pointer32=0x000000FF; //Blue
pointer32++;
}
//One half will be white
for(n=0;n<SCREEN_XSIZE/2;n++)
{
*pointer32=0x00FFFFFF; //White
pointer32++;
}
}
/* Create a graphic window filled with the color black*/
pointer32=(int *)GW_START_ADDRESS;
for(i=0;i<GW_BUFFER_SIZE/4;i++)
{
*pointer32=0x00000000; //Black
pointer32++;
}
}
void color_demo_gw_setup(void)
{
// set LCD graphic window size
LCDC_LGWSR =
LCDC_LGWSR_GWW(GW_XSIZE/16) |
LCDC_LGWSR_GWH(GW_YSIZE);
// set LCD graphic window virtual page width
LCDC_LGWVPWR = GW_XSIZE;
// set LCD graphic window panning offset (not used in 24bpp mode)
LCDC_LGWPOR = 0;
// set LCD graphic window position so that the GW will cover up the middle of screen
LCDC_LGWPR =
LCDC_LGWPR_GWXP(SCREEN_XSIZE/4) |
LCDC_LGWPR_GWYP(SCREEN_YSIZE/4);
// set LCD graphic window control
LCDC_LGWCR =
LCDC_LGWCR_GWAV(0xff) | // alpha-transparent value (0xFF is opaque)
LCDC_LGWCR_GWE_MASK;
}
void lcdc_init_pins()
{
#define ALT2 (0|PORT_PCR_MUX(2)|PORT_PCR_DSE_MASK)
#define ALT5 (0|PORT_PCR_MUX(5)|PORT_PCR_DSE_MASK)
#define ALT7 (0|PORT_PCR_MUX(7)|PORT_PCR_DSE_MASK)
PORTF_PCR4 =ALT7; // Graphic LCD D[0], Schematic PTF4
PORTF_PCR5 =ALT7; // Graphic LCD D[1], Schematic PTF5
PORTF_PCR6 =ALT7; // Graphic LCD D[2], Schematic PTF6
PORTF_PCR7 =ALT7; // Graphic LCD D[3], Schematic PTF7
PORTF_PCR8 =ALT7; // Graphic LCD D[4], Schematic PTF8
PORTF_PCR9 =ALT7; // Graphic LCD D[5], Schematic PTF9
PORTF_PCR10=ALT7; // Graphic LCD D[6], Schematic PTF10
PORTF_PCR11=ALT7; // Graphic LCD D[7], Schematic PTF11
PORTF_PCR12=ALT7; // Graphic LCD D[8], Schematic PTF12
PORTF_PCR13=ALT7; // Graphic LCD D[9], Schematic PTF13
PORTF_PCR14=ALT7; // Graphic LCD D[10], Schematic PTF14
PORTF_PCR15=ALT7; // Graphic LCD D[11], Schematic PTF15
PORTF_PCR16=ALT5; // Graphic LCD D[12], Schematic PTF16
PORTF_PCR17=ALT5; // Graphic LCD D[13], Schematic PTF17
PORTF_PCR18=ALT5; // Graphic LCD D[14], Schematic PTF18
PORTF_PCR19=ALT5; // Graphic LCD D[15], Schematic PTF19
PORTF_PCR20=ALT5; // Graphic LCD D[16], Schematic PTF20
PORTF_PCR21=ALT7; // Graphic LCD D[17], Schematic PTF21
PORTF_PCR22=ALT7; // Graphic LCD D[18], Schematic PTF22
PORTF_PCR23=ALT7; // Graphic LCD D[19], Schematic PTF23
PORTF_PCR24=ALT7; // Graphic LCD D[20], Schematic PTF24
PORTF_PCR25=ALT7; // Graphic LCD D[21], Schematic PTF25
PORTF_PCR26=ALT7; // Graphic LCD D[22], Schematic PTF26
PORTF_PCR27=ALT7; // Graphic LCD D[23], Schematic PTF27
PORTF_PCR0=ALT7; // Graphic LCD PCLK, Schematic PTF0
PORTF_PCR1=ALT7; // Graphic LCD DE, Schematic PTF1
PORTF_PCR2=ALT7; // Graphic LCD HSYNC, Schematic PTF2
PORTF_PCR3=ALT7; // Graphic LCD VSYNC, Schematic PTF3
// set LCD_CONTRAST
//PORTB_PCR4=ALT2; // Graphic LCD CONTRAST, Schematic PTB4
}
void lcdc_init_screen()
{
// set LCD Screen Start Address
LCDC_LSSAR = FRAME_START_ADDRESS;
// set LCD Size. The XMAX bitfield is the screen x-size/16.
LCDC_LSR = LCDC_LSR_XMAX( (SCREEN_XSIZE / 16) ) | LCDC_LSR_YMAX( SCREEN_YSIZE );
// set LCD virtual page width
LCDC_LVPWR = LCDC_LVPWR_VPW( SCREEN_XSIZE );
// set LCD cursor positon & settings (turn off)
LCDC_LCPR = 0;
LCDC_LCWHB = 0;
// set LCD panel configuration. Use endianess to work with TWR-LCD-RGB lines.
LCDC_LPCR =
LCDC_LPCR_TFT_MASK | //TFT Screen
LCDC_LPCR_COLOR_MASK | //Color
LCDC_LPCR_BPIX(0x2) | //4 bpp
LCDC_LPCR_FLMPOL_MASK | //first line marker active low (VSYNC)
LCDC_LPCR_LPPOL_MASK | //line pulse active low (HSYNC)
LCDC_LPCR_END_SEL_MASK | //Use big-endian mode (0xFFAA5500 means R=AA,G=55,B=00).
//LCDC_LPCR_SWAP_SEL_MASK | //Set if needed for LCD data lines match up correctly with the LCD
LCDC_LPCR_SCLKIDLE_MASK | //Enalbe LSCLK when vsync is idle
LCDC_LPCR_SCLKSEL_MASK | //Always enable clock
LCDC_LPCR_PCD(11); //Divide 120 PLL0 clock (default clock) by (11+1)=12 to get 10MHz clock
//If RevE or later TWR-LCD-RGB, need to adjust clock settings
#ifdef REVE
LCDC_LPCR |= LCDC_LPCR_CLKPOL_MASK; //In TFT mode, active on negative edge of LSCLK.
// set LCD horizontal configuration based on panel data (Figure 3-3 in Seiko datasheet)
LCDC_LHCR =
LCDC_LHCR_H_WIDTH(41) | //(41+1)=42 SCLK period for HSYNC activated
LCDC_LHCR_H_WAIT_1(1) | //(1+1)=2 SCLK period between end of OE and beginning of HSYNC
LCDC_LHCR_H_WAIT_2(0); //(0+3)=3 SCLK periods between end of HSYNC and beginning of OE
// set LCD vertical configuration based on panel data (Figure 3-3 in Seiko datasheet)
LCDC_LVCR =
LCDC_LVCR_V_WIDTH(2) | //2 lines period for VSYNC activated
LCDC_LVCR_V_WAIT_1(1) | //1 line period between end of OE and beginning of VSYNC
LCDC_LVCR_V_WAIT_2(1); //1 line periods between end of VSYNC and beginning of OE
//Earlier TWR-LCD-RGB versions (B, C, and D)
#else
LCDC_LHCR =
LCDC_LHCR_H_WIDTH(40) | //(40+1)=41 SCLK period for HSYNC activated
LCDC_LHCR_H_WAIT_1(1) | //(1+1)=2 SCLK period between end of OE and beginning of HSYNC
LCDC_LHCR_H_WAIT_2(0); //(0+3)=3 SCLK periods between end of HSYNC and beginning of OE
// set LCD vertical configuration based on panel data (Figure 3-3 in Seiko datasheet)
LCDC_LVCR =
LCDC_LVCR_V_WIDTH(10) | //10 lines period for VSYNC activated
LCDC_LVCR_V_WAIT_1(2) | //2 line period between end of OE and beginning of VSYNC
LCDC_LVCR_V_WAIT_2(2); //2 line periods between end of VSYNC and beginning of OE
#endif
// set the LCD panning offset (not used in 24bpp mode)
LCDC_LPOR = 0;
// set LCD interrupt configuration register
LCDC_LICR = 0;
//Disable LCDC interrupts
LCDC_LIER = 0;
//Disable the graphic window. See the "color" and "fsl" demos for examples of
// using the graphic window feature
LCDC_LGWCR &=~LCDC_LGWCR_GWE_MASK;
//Set background plane DMA to burst mode
LCDC_LDCR&=~LCDC_LDCR_BURST_MASK;
//Set graphic window DMA to burst mode
LCDC_LGWDCR&=~LCDC_LGWDCR_GWBT_MASK;
}
Hi Oliver,
I found a number of issues with your code.....
1. What clock mode are you using? Looks like you have disabled the PLL or at least zeroed out the dividers. Was that intentional? The SIM_SOPT2[LCDCSRC] configuration you have is trying to use the MCGPLL0CLK as the source, so you either need to have a valid PLL0 configuration or change the LCDCSRC setting. Right now you don't have a valid clock input to the LCD.
2. What memory location are you using to store the graphic buffer? For the screen size (800x600) and configuration you are using (4bpp), you need 240KB of memory to store the image. This is larger than the on-chip RAM, so you'll need to have some external memory configured and accessible for the image. The LSR and LVPWR settings you are using are also incorrect. The LSR should be 0x03200258 for an 800x600 screen (yes, you should be dividing the XSIZE by 16. The LVPWR should be 100 for your configuration (800 pixels with 4bpp, means you need 100 32-bit values to store a line of data).
3. The LPCR[PCD] should be 2 or larger for a TFT configuration. Minimum valid divide is 3 for TFT mode. You should still be able to get signals with the incorrect divider, but you should still address this problem.
4. The LRMCR value you have is enabling self refresh mode. You don't really want that on.
5. You have the graphic window enabled (LGWCR[GWE] set). It doesn't look like you actually have an image for the graphic window (LGWSAR = 0), and you don't have the data lines on at this point anyway. You should probably disable the graphic window. Basically you can just skip writing any of the LGWxx registers. The graphic window is disabled by default.
I hope this helps to get you up and running.
Regards,
Melissa