[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]/STM32F42017. 1. 12. 00:46

[STM32F4_ZE_NET] FSMC 테스트 - W5300 이더넷 전송 속도 테스트

[STM32F4_ZE_NET] FSMC 테스트 - W5300 이더넷 전송 속도 테스트





[STM32F4_ZE_EVM] 보드는 FSMC에 Hardwired TCP/IP 칩인 W5300 모듈을 연결할 수 있다.

STM32F405도 MII(RMII) 이더넷 인터페이스가 있긴하지만 이더넷 전송속를 높일 수 있는 W5300을 이용하여 TCP/IP 전송율을 테스트 해 보자


[STM32F4_ZE_EVM] 보드에 STM32F405 FSMC NE2(PG9)에 CS가 연결되어 있고 Data Bus는 16bit 모드 이다.





기본 설정을 이용하여 STM32F405에서 W5300 TCP 루프백 전송율을 테스트 해본 결과 5Mbps 정도 측정이 된다.

이때 CS 타임이 1.6us 정도 이다.


/CS time -> 1.6us


  SRAM_Timing.AddressSetupTime       = 15;

  SRAM_Timing.AddressHoldTime        = 15;

  SRAM_Timing.DataSetupTime          = 255;

  SRAM_Timing.BusTurnAroundDuration  = 15;

  SRAM_Timing.CLKDivision            = 16;

  SRAM_Timing.DataLatency            = 17;





타이미을 최대한 짧게 설정하여 테스트 해보자.

동작하는 범위에서 최대로 짧게 설정하니 40ns 정도 되고 TCP 루프백 전송율은 90Mbps 정도로 출력된다.


다른 MCU에서 W5300 TCP전송율 테스트 결과와 비교해 보면 100M 이더넷에서 거의 최대 치로 출력되는것 같다.



/CS time -> 40ns


  SRAM_Timing.AddressSetupTime       = 2;

  SRAM_Timing.AddressHoldTime        = 2;

  SRAM_Timing.DataSetupTime          = 4;

  SRAM_Timing.BusTurnAroundDuration  = 3;

  SRAM_Timing.CLKDivision            = 2;

  SRAM_Timing.DataLatency            = 2;





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

댓글을 달아 주세요