[ST_MICRO]/STM32H72018. 12. 1. 04:54

STM32H7 FMC - TFT LCD 출력하기 (STM32F7 FMC와 다른점)

STM32H7 FMC - TFT LCD 출력하기 (STM32F7 FMC와 다른점)




STM32H7 EVM 보드에는 FMC를 이용하여 기존에 제작 해 두었던 TFT LCD 모듈을 연결할 수 있도록 구성하였다. STM32H7에서 FMC로 TFC LCD 테스트를 진행 해 볼 수 있다.







STM32H7 의 FMC는  Data(16), WR, RD, CS, A16 핀을 할당 할 수 있다.

메모리 맵핑은 기존 STM32 시리즈와 동일하게 0x6000 0000 에 가능하다.






STM32CubeMX에서 FMC 설정을 LCD Interface 타입으로 설정하여 코드 생성 한다.








STM32H7 FMC 기본 동작 테스트

FMC 제어를 위해 STM32CubeMx의 HAL 라이브러리가 제공된다.


uint8_t BSP_SRAM_WriteData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize)
{
  if(HAL_SRAM_Write_16b(&hsram1, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
  {
    return SRAM_ERROR;
  }
  else
  {
    return SRAM_OK;
  }

}



스코프 확인식 신호가 정상 적으로 출력 되는것을 확이 할 수 있다.


  MX_FMC_Init();

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
         data ^= 0x55;
         addr ^= 1;
         if(addr)
         {
                //BSP_SRAM_WriteData(LCD_BANK_ADDR, &data, 1);
                _LCD_DATA(0) ^= data ;
         }
         else
         {
                //BSP_SRAM_WriteData(LCD_BANK_ADDR+(1<<16), &data, 1);
                _LCD_DATA((1<<16)) ^= data ;
         }
      
        GPIOD->ODR ^= GPIO_PIN_13;
        HAL_Delay(100);

  }





이제 실제 TFT LCD모듈을 연결하여 테스트 해 보자





TFT LCD가 정상 동작을 하지 않는다.


스코프 확인 해 보니 Address, Data Write 구간에 CS핀이 4번 정도 High가 되는 현상이 있다.





너무 고속이라 그런가?

STM32H7에서 FMC에서 달라진 점은 속도 이다. 최대 180Mhz 까지 가능하다.





열심히 구글링 결과  STM32H7 vs STM32F7 GPIO 속도 테스트2 와 같이 STM32H7의 버스 메트릭스 구조가 달라져서 그1사이클에 4번의 전환이 발생 한다고 한다. H7으로 코드 전환이 쉽지가 않네...


Memory Type을 바꾸어 보니 그런 현상이 없어 졌다.

 hsram1.Init.MemoryType = FMC_MEMORY_TYPE_NOR;




/* FMC initialization function */
static void MX_FMC_Init(void)
{
  /* USER CODE BEGIN FMC_Init 0 */
  /* USER CODE END FMC_Init 0 */
  FMC_NORSRAM_TimingTypeDef Timing = {0};
  /* USER CODE BEGIN FMC_Init 1 */
  /* USER CODE END FMC_Init 1 */
  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  //hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_NOR;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 30;
  Timing.AddressHoldTime = 30;
  Timing.DataSetupTime = 25;
  Timing.BusTurnAroundDuration =50;
  Timing.CLKDivision = 0;
  Timing.DataLatency = 0;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */
  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }
  /* USER CODE BEGIN FMC_Init 2 */
  /* USER CODE END FMC_Init 2 */

}





SD카드 연결하고 BMP 이미지 출력하니 TFT LCD에 BMP이미지가 정상적으로 출력된다.

















Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32F72018. 5. 15. 04:34

STM32F7 EVM FMC 테스트 - TFT LCD 제어 (STM32F7 에서 FMC출력 문제발생)

STM32F7 EVM FMC 테스트 - TFT LCD 제어 (STM32F7 에서 FMC출력 문제발생)




STM32F7 EVM 보드는 100핀 페키지의 STM32F767이 실장되어 있다. 100핀 페키지에서는 FMC Data/Address 16, RD, WR, NE 을 사용할 수 있어 버스 방식의 LCD 제어에 적합하다.

기존에 제작한 LCD 모듈중 버스제어 방식의 LCD모듈을 표준 핀맵으로 제작해 두었기 때문에 이 모듈로 STM32F7의 FMC를 이용한 TFT LCD를 테스트 해 보았다.




STM32F7 EVM보드의 TFT LCD는 CS -> NE1, RS->A16에 연결에 되어 있다.









STM32F7 FMC 테스트 코드 작성

STM32CubeMX 에서 FMC를 아래와 같이 핀맵에 맞게 설정 하면 된다.





STM32CubeMX에서 코드 생성을 하면 아래와 같이 기본 초기화 코드가 생성된다.



static void MX_FMC_Init(void)
{
  /* USER CODE BEGIN FMC_Init 0 */
  /* USER CODE END FMC_Init 0 */
  FMC_NORSRAM_TimingTypeDef Timing = {0};
  /* USER CODE BEGIN FMC_Init 1 */
  /* USER CODE END FMC_Init 1 */
  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 25;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 50;//50;//255;
  Timing.BusTurnAroundDuration = 1;//2;//15;
  Timing.CLKDivision = 2;
  Timing.DataLatency = 2;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */
  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }
  /* USER CODE BEGIN FMC_Init 2 */
  /* USER CODE END FMC_Init 2 */
}





기존 STM32F439 FMC테스트 예제와 동일한 코드를 구동 시켰는데...

동작을 하지 않는다.


뭔가 이상하다. STM32F7에서 뭐가 달라졌나?



일단 LCD기본 테스트 코드로 파형이 정상적으로 출력이 되는지 확인 해 보자


CMD출력 할때 RS(A16)가 low가 되는것을 확인 할 수 있다.


       while(1)
       {
              Lcd_Cmd(0x0200);Lcd_Data(0x0000);        //Horizontal Address Set
              Lcd_Cmd(0x0201);Lcd_Data(0x0000);        //Vertical Address Set
              Delay(delay_time);
       }



하지만 4번의 출력이 있어야 하는 WR신호가 2번 밖에 출력되지 않는다.




타이밍 이슈 인가? 하지만 타이밍을 짧게 해도 2번 밖에 출력이 되지 않는다.






FMC 출력 할 때 딜레이를 좀 주면 어떻게 될까?


#define _LCD_TIME_DELAY                                60
#define Lcd_Cmd(reg)                    _LCD_DATA(0x0000) = reg;Delay_ns(_LCD_TIME_DELAY);

#define Lcd_Data(dat)                   _LCD_DATA(0x10000) = dat;Delay_ns(_LCD_TIME_DELAY);



정상 동작은 하지만 속도가 STM32F4에 비해 4배 이상 느리다.

딜레이 타임을 줄이면 정상 동작을 하지 않는다.







STM32F7 FMC HAL 코드를 사용해 보면 어떨까?


void Lcd_Cmd(unsigned int reg)

{
       uint16_t buf = reg;
       HAL_SRAM_Write_16b(&hsram1, (uint32_t*)(LCD_BANK_ADDR+0), &buf, 1);
}

void Lcd_Data(unsigned int reg)
{
       uint16_t buf = reg;
       HAL_SRAM_Write_16b(&hsram1, (uint32_t*)(LCD_BANK_ADDR+0x20000), &buf, 1);

}




하지만 HAL코드를 이용하면 동작은 하지만 속도가 너무 느리다.

타이밍을 짧게 해도 1프래임 출력 시간이 44ms나 소요된다.



결론적으로 보면 출력 후 바로 출력 하는것에는 문제가 있는것 같다.

무시 해 버리는듯..


속도는 느리지만 SD카드의 BMP출력하면 STM32F7에서 TFT-LCD에 이미지 출력은 되고 있다. 

하지만 속도 문제는 해결해야 할것 같다.









Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32F42015. 6. 29. 14:14

[STM32F4_ZE_NET] FSMC 테스트 - TFT LCD 출력 테스트


[STM32F4_ZE_NET] FSMC 테스트 - TFT LCD 출력 테스트





STM32F4의 FSMC를 이용하면 TFT-LCD를 버스 방식으로 제어 가능하다.


STM32F4의 FSMC는 4개의 64MB로 할당 가능하다.






STM32F405 FSMC 블록도





STM32F405 FSMC 테스트 초기화 코드


초기화 코드

#define LCD_BANK_ADDR                   ((uint32_t)0x6C000000)
#define _LCD_CMD_OUT(Data)              (*(uint16_t *) (LCD_BANK_ADDR) = Data)
#define _LCD_DAT_OUT(Data)              (*(uint16_t *) (LCD_BANK_ADDR) = Data)
#define _LCD_DATA(p)                    (*(volatile uint16_t*) (LCD_BANK_ADDR + (p<<1)))

#define Lcd_Cmd(reg)                    _LCD_DATA(0x0000) = reg;

#define Lcd_Data(dat)                   _LCD_DATA(0x0002) = dat;




테스트 코로 테스트 해 보면 CMD출력 할때 RS(A1)가 low가 되는것을 확인 할 수 있다.

       while(1)
       {
              Lcd_Cmd(0x0200);Lcd_Data(0x0000);
              Lcd_Cmd(0x0201);Lcd_Data(0x0000);
              Delay(delay_time);
       }







/CS와 /WR 신호를 확인 해 보면 4개의 /CS,/RS가 출력 되는것을 확인 할 수 있다.

타이밍을 최적화 해 보면 300ns 내에 4개의 명령이 수행 되는것을 확인 할 수 있다.

  /* Timing */
  Timing.AddressSetupTime = 4;
  Timing.AddressHoldTime = 4;
  Timing.DataSetupTime = 8;
  Timing.BusTurnAroundDuration = 6;
  Timing.CLKDivision = 2;
  Timing.DataLatency = 2;




LCD에 이미지 한장 출력하는데 7.5ms 정도 소요된다.






TFT-LCD에 BMP 파일 출력 해보면 정상 적으로 잘 출력 되는것을 확인 할 수 있다.








Posted by nexp

댓글을 달아 주세요

[FreeScale]/KINETIS2013. 11. 10. 23:30

K20 EVM - Kinetis Cortex-M4 TFT LCD 테스트

K20 EVM - Kinetis Cortex-M4 TFT LCD 테스트



Cortex-M4 코어를 가진 K20 EVM보를 이용하여 TFT-LCD 출력 테스트를 했다.

50Mhz에서 400x320 픽셀의 TFT LCD에 1프레임 출력하는데 18ms정도 소요된다.



[NET-EVB SM] 확장 테스트 보드를 이용하여 SD Card의 BMP이미지를 출력하도록 했다.









K20 EVM TFT LCD 출력 테스트 동영상




K20 TFT LCD 드라이버 소스코드정리
//-----------------------------------------------------------------------------
#define _SPI0_IO_INIT() PORTD_PCR0 = PORT_PCR_MUX(0x2);\
PORTD_PCR1 = PORT_PCR_MUX(0x2);\
PORTD_PCR2 = PORT_PCR_MUX(0x2);\
PORTD_PCR3 = PORT_PCR_MUX(0x2);
                                        
                                        
                                        

#define TFT_DRV_HD66791                 0
#define TFT_DRV_COM44                   1

#define LCD_LAT_BIT BIT16
#define LCD_LAT_PORT GPIOB
#define LCD_LAT_ON() sbi(LCD_LAT_PORT, LCD_LAT_BIT) 
#define LCD_LAT_OFF() cbi(LCD_LAT_PORT, LCD_LAT_BIT) 
#define LCD_DATA_LATCH() LCD_LAT_ON();LCD_LAT_OFF();

#define LCD_EN_BIT BIT17
#define LCD_EN_PORT GPIOB
#define LCD_ENABLE() cbi(LCD_EN_PORT, LCD_EN_BIT) 
#define LCD_DISABLE() sbi(LCD_EN_PORT, LCD_EN_BIT) 

#define LCD_RST_BIT //BIT8
#define LCD_RST_PORT //PORTB
#define LCD_RST_ON() //Sbi(LCD_RST_PORT, LCD_RST_BIT) 
#define LCD_RST_OFF() //Cbi(LCD_RST_PORT, LCD_RST_BIT) 

#define LCD_RS_BIT BIT0
#define LCD_RS_PORT GPIOA
#define LCD_RS_OFF() cbi(LCD_RS_PORT, LCD_RS_BIT) 
#define LCD_RS_ON() sbi(LCD_RS_PORT, LCD_RS_BIT)

#define LCD_WR_BIT BIT3
#define LCD_WR_PORT GPIOA
#define LCD_WR_OFF() cbi(LCD_WR_PORT, LCD_WR_BIT) 
#define LCD_WR_ON() sbi(LCD_WR_PORT, LCD_WR_BIT)

#define LCD_RD_BIT ///BIT9
#define LCD_RD_PORT //PORTB
#define LCD_RD_OFF() //Cbi(LCD_RD_PORT, LCD_RD_BIT) 
#define LCD_RD_ON() //Sbi(LCD_RD_PORT, LCD_RD_BIT)

#define LCD_BL_BIT BIT3
#define LCD_BL_PORT GPIOC
#define LCD_BL_OFF() cbi(LCD_BL_PORT, LCD_BL_BIT) 
#define LCD_BL_ON() sbi(LCD_BL_PORT, LCD_BL_BIT)

#define _LCD_DAT_OUT(Data) PORTD = (Data>>8);\
                                    LCD_DATA_LATCH();\
                                    PORTD = (Data&0xFF);

#define TFTGpioInit() SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;\
                                        SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;\
                                        SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;\
                                        SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;\
                                        PORTA_PCR0 = PORT_PCR_MUX(1);\
                                        PORTA_PCR3 = PORT_PCR_MUX(1);\
PORTB_PCR16 = PORT_PCR_MUX(1);\
                                        PORTB_PCR17 = PORT_PCR_MUX(1);\
                                        PORTC_PCR3 = PORT_PCR_MUX(1);\
                                        PORTD_PCR0 = PORT_PCR_MUX(1);\
                                        PORTD_PCR1 = PORT_PCR_MUX(1);\
                                        PORTD_PCR2 = PORT_PCR_MUX(1);\
                                        PORTD_PCR3 = PORT_PCR_MUX(1);\
                                        PORTD_PCR4 = PORT_PCR_MUX(1);\
                                        PORTD_PCR5 = PORT_PCR_MUX(1);\
                                        PORTD_PCR6 = PORT_PCR_MUX(1);\
                                        PORTD_PCR7 = PORT_PCR_MUX(1);\
                                        Sbi(GPIOA_PDDR, (BIT0|BIT3));\
                                        Sbi(GPIOB_PDDR, (BIT16|BIT17));\
                                        Sbi(GPIOD_PDDR, 0xFF);



Posted by nexp

댓글을 달아 주세요

[MCU]/adStar2013. 3. 24. 00:52

adStar - SD Card 이용한 7" TFT LCD 테스트

adStar - SD Card 이용한 7" TFT LCD 테스트

 

 

adStar의 자장 큰 장점으로 MCU내에 TFT LCD 컨트롤러가 내장되어 있는 것이다. 때문에 7" TFT LCD도 쉽고 저렴하게 제어 할 수 있다.

 

 

adStar TFT LCD제어 초기화 코드

PORT6, PORT7, PORT8 이 TFT LCD데이터 포트 이므로 기능 설정 레지스터를 LCD 로 설정해 주면된다.

주의 사항으로 JTAG핀과 공통으로 사용하므로 개발할때 불편함이 있다. MUX칩으로 스위칭 할수 있도록 하면 좀더 쉽게 개발할수 있다.

void InitLcd()
{
 Cbi(*R_PAF5, 0xFFC0);//VSYNC,HSYNC,DISP_EN,CRTC_CLK_OUT
 BCKLIGHT_IO_INIT();
 BCKLIGHT_OFF();

 

 *R_PAF6 = 0; //LCD R
 *R_PAF7 = 0; //LCD G
 *R_PAF8 = 0; //LCD B
 
 crtc_clock_init(); 
}

 

 

LCD 종류에 따라 모드 설정이 필요한데 setscreen() 함수에서 설정 가능하다.

초기에 정상동작을 하지 않아 약간의 수정을 해 주니 잘 동작한다.

void setscreen(SCREENRES res,U32 scmode)
{
 switch(res)
 {
 case SCREEN_480x272:
  setscreenex(480,272,scmode,0x0000020D,0x0002002B,0x002D020D ,0x0000011E ,0x0002000C ,0x000E011E );
  break;
 case SCREEN_640x480:
  setscreenex(640,480,scmode,0x00000320,0x00130073,0x00A00320 ,0x0000020D ,0x0007000D ,0x002B020B );
  break;
 case SCREEN_800x480:
  //setscreenex(800,480,scmode,1000,(3<<16)|0,(24<<16)|1000 ,530 ,(23<<16)|2 ,(13<<16)|530 );
  break;
 case SCREEN_800x600:
  setscreenex(800,600,scmode,0x00000420,0x002300b0,0x01000420 ,0x00000274 ,0x0004000a ,0x001a0272 );
  break;
 default:
  debugstring("invalid screen size\r\n");
  return;
 }
}


void setscreenex(U32 width,U32 height,U32 scmode,U32 ht,U32 hs, U32 ha, U32 vt, U32 vs, U32 va)
{
 *R_CRTHT  = ht; //Horizontal Active와 Blank구간을 포함한 Horizontal Total Scan Value
 *R_CRTHS  = hs; //Horizontal Sync 구간의 Start(End) value
 *R_CRTHA  = ha; //Horizontal Active 구간의 Start(End) value
 *R_CRTVT  = vt; //Vertical Active와 blank 구간을 포함한 Vertical Total scan value
 *R_CRTVS  = vs; //Vertical Sync 구간의 Start(End) value
 *R_CRTVA  = va; //Vertical Active구간의 Start(End) value
 screen_w= width;
 screen_h = height;
 
 U32 conval=0;
 debugprintf(" CRTC %d x %d Setting Done\r\n",width,height);
 if(scmode&SCREENMODE_RGB888)
 {
  debugstring("RGB888 Mode\r\n");
  screen_bpp = 32;
  conval |= (1<<13);
 }
 else
 {
  debugstring("RGB565 Mode\r\n");
  screen_bpp = 16;
  conval |= (1<<12);
 }
 conval |= (1<<4);//line pitch not align 512,1024
 *R_CRTWIDTH = screen_w;
 *R_CRTCON = conval;
 drawsetclipwindow(0,0,screen_w,screen_h);
 set_interrupt(INTNUM_FRAMESYNC,framesync_isr);
 enable_interrupt(INTNUM_FRAMESYNC,FALSE);
}

 

 

 

asStar 7" TFT LCD 테스트 동영상

sdCard를 이용하여 7" TFT LCD에 BMP영상을 출력핟록 하고 있다. jpg파일도 가능하지만 JPG->BMP 변환 속도가 느려 BMP보다는 출력속도가 느린것 같다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by nexp

댓글을 달아 주세요