Problem (K7O controller LCD) to disable LCDSTART in SIM_MCR register

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem (K7O controller LCD) to disable LCDSTART in SIM_MCR register

1,257 Views
delauratfrançoi
Contributor II

Hello my name is françois, I work on Kinetis K70 and I have a problem with LCDC module.

My problem is when I enable or disable the graphic window, the micro crashes and all its registers (R0..R15) are equal to zero. This bug occurs very rarely.

I enable or disable the graphic window when “the end of frame event” occurs. My steps in ISR to enable or disable the graphic window:

1 To set zero the LCDSTART bit in SIM_MCR register.

2 If I want to enable the graphic window to set one the GWE bit in LCDC_LGWCR register

else To disable the graphic window to set zero the GWE bit in LCDC_LGWCR register.

3 To set one the LCDSTART bit in SIM_MCR register.

After a few days of work I understood that the problem occurred just after to disable LCDSTART (to set zero LCDSTART bit in SIM_MCR register). I also noticed that if I used the graphic window end of frame event (GW_EOF) instead of the end of frame event to enable or disable the graphic window, the problem occurred quickly.

I do not know my problem solving

Can you help me please.

Thank you in advance for your reply

My configuration:

- K70 clock 18.4 MHz

- MCG is BLPE.

- LCD clock 6.13

- LCD 340x280

- LCD tft

- LCD 4bpp

- the frame buffer is in the sram

- the window frame buffer is in the sram

- address frame buffer : 0x1fff1800

- address window frame buffer: 0x1fff0400

init pin lcd function

/*--------------------------------------------

| Name:        k70f120m_lcd_gpio

| Description:

| Parameters:  none

| Return Type: none

| Comments:

| See:

----------------------------------------------*/

static void k70f120m_lcd_gpio (dev_panel_info_t* p_panel_info)

{

  char NBPinData=0;

volatile unsigned int reg_val = 0;

  int i;

//mettre la pin du reset en sortie

  PinConf(LCD_RESET,LCD_RESET_PIN,1);

//mettre l'ecarn en reset n'activer le reset

  k70f120m_lcd_reset_on();

//mettre la pin du baclight en sortie

  PinConf(LCD_BLK,LCD_BKL_PIN,1);

//allumer le backlight

  k70f120m_lcd_backlight_off();

//initiliser les pin pour la luminosite

//initialiser les pin du lcd

//HSYNC VSYNC DE ET DCLK

  hal_set_pin_function(LCD_HSYNC);

  hal_set_pin_function(LCD_VSYNC);

  hal_set_pin_function(LCD_DCLK);

  hal_set_pin_function(LCD_DE);

//init des data

//selon la represenation le nombre de pin à initilise n'est pas le même

  switch(p_panel_info->vl_bpix)

  {

  case BPP_4:

  NBPinData=18;

  break;

  case BPP_8:

  NBPinData=18;

  break;

  case BPP_18:

  NBPinData=18;

  break;

  case BPP_24:

  NBPinData=24;

  break;

default://mode de representation encore non traite

  NBPinData=0;

  break;

  }//switch nombre pin active par réprensation

//pour les data de 0 à 11 et 17 à 23 compri mux = 7

//pour les pin de 12 à 16 mux =5

  for(i=LCD_DATA0_PIN;i<(LCD_DATA0_PIN+NBPinData);i++)

  {

  if((i>LCD_DATA11_PIN) &&  (i<LCD_DATA17_PIN))

  {

  hal_set_pin_function(LCD_DATAX(i,5));

  }

  else

  {

  hal_set_pin_function(LCD_DATAX(i,7));

  }

  }

//le lcd utilise la clock bus

  HAL_READ_UINT32(REG_SIM_SOPT2_ADDR, reg_val);

  reg_val &=~REG_SIM_SOPT2_LCDCSRC_MASK;

  HAL_WRITE_UINT32(REG_SIM_SOPT2_ADDR, reg_val);

//activer les clock des differnt peripherique et port concerné

//clock port F

  HAL_READ_UINT32(REG_SIM_SCGC5_ADDR, reg_val);

  reg_val |= REG_SIM_SCGC5_PORTF_MASK;

  HAL_WRITE_UINT32(REG_SIM_SCGC5_ADDR, reg_val);

//clock LCD

  HAL_READ_UINT32(REG_SIM_SCGC3_ADDR, reg_val);

  reg_val |= REG_SIM_SCGC3_LCDC_MASK;

  HAL_WRITE_UINT32(REG_SIM_SCGC3_ADDR, reg_val);

//initialisation du dac de controle de la luminosite

  DACx_Init(&DAC_Luminosity_LCD);

//mettre à 100% la luminosity

  k70f120m_lcd_set_luminosity(100);

}

Init lcd function:

/*--------------------------------------------

| Name:        k70f120m_lcd_ctrl_init

| Description:

| Parameters:  none

| Return Type: none

| Comments:

| See:

----------------------------------------------*/

int k70f120m_lcd_ctrl_init (dev_panel_info_t* p_panel_info)

{

    unsigned int NbBitPerPixelRegistre;

    volatile unsigned int reg_val = 0;

    float CoefFreq;

    int CoefFreqEntier;

    if(!p_panel_info)

          return -1;

    g_panel_info=p_panel_info;

    //init pin

    k70f120m_lcd_gpio(g_panel_info);

    //verifier existence d'un premier frame buffer

    if(!g_panel_info->TabFrameBuffer[0])

    return -1;

    // set LCD Screen Start Address pour l'instant

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LSSAR, ((uint32_t)g_panel_info->TabFrameBuffer[0]));

    //initialise les variables k70f120m_current_frame_buffer et k70f120m_shadow_frame_buffer

    k70f120m_current_frame_buffer=0;

    k70f120m_shadow_frame_buffer=1;

    //set size screen

    //Attention la largeur doit etre prealablement divise par 16

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LSR,(LCDC_LSR_XMAX(g_panel_info->vl_col/16)|LCDC_LSR_YMAX(g_panel_info->vl_row)));

    // set LCD virtual page width

    //explication de ce registre donne dans la doc

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LVPWR,LCDC_LVPWR_VPW(40));//(g_panel_info->vl_col*g_panel_info->vl_bpix)/32

    //mettre a zero les registre curseur car on utilise

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LCPR,0);

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LCCMR,0);

    //validation de la valeur du nombre de bit par pixel pour le registre

    switch(g_panel_info->vl_bpix)

    {

    case BPP_4:

    NbBitPerPixelRegistre=2;

    break;

    case BPP_8:

    NbBitPerPixelRegistre=3;

    break;

    case BPP_18:

    NbBitPerPixelRegistre=6;

    break;

    case BPP_24:

    NbBitPerPixelRegistre=7;

    break;

    default://cas non gerer

    NbBitPerPixelRegistre=0;

    break;

    }

    CoefFreq=((float)CYGNUM_HAL_CORTEXM_KINETIS_MCG_FLL_PLL_REF_FREQ/(float)g_panel_info->vl_pixclock)+0.5;

    CoefFreqEntier=(int)CoefFreq;

    //registre de configuration du lcd

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LPCR,

    (LCDC_LPCR_TFT_MASK | //validation du TFT

    LCDC_LPCR_COLOR_MASK | //validation de la couleur

    LCDC_LPCR_BPIX(NbBitPerPixelRegistre) |  //bbp par pixel 4 ici

    LCDC_LPCR_PIXPOL(g_panel_info->vl_dp) | //polarite des data

    LCDC_LPCR_FLMPOL(g_panel_info->vl_vsp) | //polarite de vsync

    LCDC_LPCR_LPPOL(g_panel_info->vl_hsp) | //polarite de hsync

    LCDC_LPCR_CLKPOL(g_panel_info->vl_clkp) | //polarite de clock

    LCDC_LPCR_OEPOL(g_panel_info->vl_oep) | //polarite de oep

    //LCDC_LPCR_SCLKIDLE_MASK | //valide la clock lorsque VSync en idle attention voir si utile

    //LCDC_LPCR_END_SEL_MASK  | //Use big-endian mode (0xFFAA5500 means R=AA,G=55,B=00). ATTENTION depant de l'ecran

    //LCDC_LPCR_REV_VS_MASK |

    LCDC_LPCR_SWAP_SEL_MASK |       //Set if needed for LCD data lines match up correctly with the LCD

    LCDC_LPCR_SCLKSEL_MASK  |       //Always enable clock à voir si vraiment utile pour la conso

    LCDC_LPCR_PCD(CoefFreqEntier-1)));             //Clock micro / par clock lcd -1

    //ATTENTION WAIT 2 est HB voir doc micro page 2233

    //HSYNC configuration

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LHCR,

    (LCDC_LHCR_H_WIDTH(g_panel_info->vl_hpw-1)| //largeur de la pulse HSYNC -1 en clock lcd

     LCDC_LHCR_H_WAIT_2(g_panel_info->vl_blw-3)| // nombre de clk lcd entre OE et le debut de hsync -1

     LCDC_LHCR_H_WAIT_1(g_panel_info->vl_elw-1) )); // nombre de clk lcd entre la fin d'une ligne et OE – 3

    //MEME CHOSE POUR VSYNC

    //VSYNC Configuration

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LVCR,

    (LCDC_LHCR_H_WIDTH(g_panel_info->vl_vpw)| //largeur de la pulse VSYNC en clock lcd

     LCDC_LHCR_H_WAIT_2(g_panel_info->vl_bfw)| // nombre de clk lcd entre OE et le debut debut d'une image

     LCDC_LHCR_H_WAIT_1(g_panel_info->vl_efw))); // nombre de clk lcd entre la fin d'une image et OE

    //le panning n'est pas utilise le mettre à zero

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LPOR,0);

    //deconnecter tout les interrupt

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LICR,LCDC_LICR_INTSYN_MASK);

    //deconnecter le mode graphique window peut etre utile pour un double frame buffer

  //  HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWCR,0);

    //init la pallette

    if((g_panel_info->vl_bpix==BPP_4)||(g_panel_info->vl_bpix==BPP_8))

    k70f120m_lcd_set_lut((const PALETTEENTRY *)g_panel_info->palette,0,(1<<g_panel_info->vl_bpix));

    //init du DMA mettre le DMA pour le background en mode burst mode dynamic

    HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LDCR,reg_val);

    reg_val&=~LCDC_LDCR_BURST_MASK;

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LDCR, reg_val);

    //init buffer window

    //initialisation par defaut

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWSAR, ((uint32_t)g_panel_info->TabFrameBuffer[1]));

    //set size screen

    //Attention la largeur doit etre prealablement divise par 16

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWSR,(LCDC_LGWSR_GWW(WIDHT_MAX_SCREEN_WINDOW/16)|LCDC_LGWSR_GWH(HEIGHT_MAX_SCREEN_WINDOW)));

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWVPWR,LCDC_LGWVPWR_GWVPW(8));

    //position window buffer en 0 par defaut

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWPR,LCDC_LGWPR_GWXP(0)|LCDC_LGWPR_GWYP(0));

    // set LCD window configuration

    // not enable the lcd window

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWCR,LCDC_LGWCR_GWAV_MASK);//(g_panel_info->vl_col*g_panel_info->vl_bpix)/32

    //init du DMA mettre le DMA pour le background en mode burst mode dynamic

    HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LGWDCR,reg_val);

    reg_val&=~LCDC_LGWDCR_GWBT_MASK;

    HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWDCR, reg_val);

    //creation it

    cyg_interrupt_create((cyg_vector_t)KINETIS_LCD_IRQ_NO,

                        KINETIS_LCD_IRQ_PRIORITY,

                        (cyg_addrword_t)&StateWindowFrameBuffer,

                         _kinetis_lcd_isr,

                         _kinetis_lcd_dsr,

                         &irq_handle_lcd,

                         &irq_it_lcd);

    cyg_interrupt_attach(irq_handle_lcd);

    cyg_interrupt_mask(KINETIS_LCD_IRQ_NO);

    //start le lcd

    HAL_READ_UINT32(REG_SIM_MCR,reg_val);

    reg_val=SIM_MCR_LCDSTART_MASK;

    HAL_WRITE_UINT32(REG_SIM_MCR,reg_val);

    //desactiver le reset du lcd

//mettre l'ecarn en reset n'activer le reset

  k70f120m_lcd_reset_off();

    return 0;

}

isr function

cyg_uint32 _kinetis_lcd_isr(cyg_vector_t vector, cyg_addrword_t data) {

   cyg_interrupt_mask(vector);

   cyg_interrupt_acknowledge(vector);

   volatile unsigned int reg_val = 0;

   HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LISR,reg_val);

   //dasactive les it

   HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LIER,0);

//init du DMA mettre le DMA pour le background en mode burst mode dynamic

//HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LGWDCR,reg_val);

//reg_val|=LCDC_LGWDCR_GWBT_MASK;

//HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWDCR, reg_val);

  HAL_READ_UINT32(REG_SIM_MCR,reg_val);

    reg_val&=~SIM_MCR_LCDSTART_MASK;

  HAL_WRITE_UINT32(REG_SIM_MCR,reg_val);

   if(StateWindowFrameBuffer)

   {

       //start window le lcd

       HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LGWCR,reg_val);

       reg_val|=(LCDC_LGWCR_GWE_MASK);

       //reg_val|=LCDC_LGWCR_GWAV_MASK;

       HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWCR,reg_val);

       debugfd=40;

   }

   else

   {

       HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LGWCR,reg_val);

       reg_val&=~LCDC_LGWCR_GWE_MASK;

       //

       //reg_val&= ~LCDC_LGWCR_GWAV_MASK;

       //reg_val|=(LCDC_LGWCR_GWE_MASK|LCDC_LGWCR_GWAV(0x00));

       HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWCR,reg_val);

   }

 

//init du DMA mettre le DMA pour le background en mode burst mode dynamic

//HAL_READ_UINT32(LCDC_BASE_PTR + LCDC_LGWDCR,reg_val);

//reg_val&=~LCDC_LGWDCR_GWBT_MASK;

//HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LGWDCR, reg_val);

  HAL_READ_UINT32(REG_SIM_MCR,reg_val);

  reg_val|=SIM_MCR_LCDSTART_MASK;

  HAL_WRITE_UINT32(REG_SIM_MCR,reg_val);

   HAL_WRITE_UINT32(LCDC_BASE_PTR + LCDC_LRMCR, 0);

   return(CYG_ISR_HANDLED | CYG_ISR_CALL_DSR);

}

0 Kudos
9 Replies

771 Views
delauratfrançoi
Contributor II

Hello Earl

When you say that you enable the Graphic Window and a parasite window appears, isn't it the Graphic Window?

Yes,it is. The parasite window appears for one seconde after there is not the parasite window so the register LCDC_LGWSR  is correctly configured. The parasite window is previous image. But I'll check  if the register LCDC_LGWSR is correctly configured.

Else have you got an other idea to eliminate the parasite window.

Thank you in advance for your reply

Best regards,

François.

0 Kudos

771 Views
EarlOrlando
Senior Contributor II

Hello François,

Could you please test the code which is inside of the ISR but out of the ISR? This is to ensure sure that the problem is because of the LCDSTART bit or because a problem with the ISR.

Also, could you please put some dummy code at the end of the ISR? Is still the problem happening when you turn the LCDSTART bit off (i.e. in the same line)?

Best regards,

Earl Orlando.

0 Kudos

771 Views
delauratfrançoi
Contributor II

Hello Earl.

I test out of of the ISR and there is always the bug. I think that I have not right to switch off the LCD with LCDSTART bit at any time.

I try to modify the ISR timing with the LCDC_LICR. Currently I have the configuration INTSYN=1 and INTCOn =0 if I program INTSYN= 0 and INTCON=0, the problem occurred quickly.

I think that I have little  window time to switch off the lcd in the ISR and  rarely when the micro is overloaded  I think I am outside of window time.

But I would like to know when I am outside of window time with a register.

Can you help me please.

Thank you in advance for your reply

0 Kudos

771 Views
EarlOrlando
Senior Contributor II

Hello Francois,

Could you please share your entire project to recreate the scenario in my own board and look for a solution?

Best regards,

Earl.

0 Kudos

771 Views
delauratfrançoi
Contributor II

Hello Earl

I can not send all my project but I send all lcd device.

There are 5 files.

The k70f120m_lcd (.c an d.h) files are low level device.

I have questions about SIM_MCR register.

Can we stop the LCD at any time it?

Thank you in advance for your reply

Best regards,

François.

0 Kudos

771 Views
EarlOrlando
Senior Contributor II

Hello Francois,

I've been reviewing your code but I can't find what is wrong. However, The LCDC module does not need to be disabled to clear/set the LCDC_LGWCR[GWE] bit. Please try to enable/disable the Graphic Window without disable the LCDC module. Please confirm if this works.

Besides to enable/disable the Graphic Window, do you need to enable/disable the LCDC module?

Also, I compared your code with the demo provided in the Kinetis 120MHz bare metal sample code package which can be downloaded from Kinetis K70 120 MHz Tower System Module|Freescale. I think that this demo could be useful for you even if another problem arises.

pastedImage_8.png

Best regards,

Earl.

0 Kudos

771 Views
delauratfrançoi
Contributor II

Hello Earl

Excuse me for this late response

I did lots of tests. I tried to enable/disable the Graphic Window without disable the LCDC module. It works only if I do not change the LCDC_LGWSR register. If I change the LCDC_LGWSR register before to enable Graphic Window. So when I enable Graphic Window, I see a stray window, It is the old window

0 Kudos

771 Views
delauratfrançoi
Contributor II

Hello Earl

Excuse me for this late response

I did lots of tests. I tried to enable/disable the Graphic Window without disable the LCDC module. It works only if I do not change the LCDC_LGWSR register. If I change the LCDC_LGWSR register before to enable Graphic Window. So when I enable Graphic Window, I see a parasite window, It is the old window.

Have you got an idea to eliminate the parasite window.

Thank you in advance for your reply

Best regards,

François.

0 Kudos

771 Views
EarlOrlando
Senior Contributor II

Hello Francois,

When you say that you enable the Graphic Window and a parasite window appears, isn't it the Graphic Window? If you enable that window it will appears on the screen. Maybe you see a wrong Graphic Window because the register LCDC_LGWSR is configured wrong. Please be sure that you are writing the correct configurations (the field GWW is the graphic window width divided by 16!).

Best regards,

Earl.

0 Kudos