AnsweredAssumed Answered

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

Question asked by delauratfrançois on Aug 21, 2015
Latest reply on Oct 2, 2015 by delauratfrançois

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);

}

Outcomes