Merhaba,
Stm32f750n8 ile MT48LC8M16A2TG-6A:LTR kullanarak yapılmış bir kartım var.
SDRAM ile ilgili ilk çalışmam. Bu yüzden temel şeyleri kaçırmadan ilerlemek istiyorum.
Kodda timing ile ilgili dikkat etmem gereken hususlar nelerdir? RAMden baştan sona veri yazıp okuma yapmak istiyorum. Böylece test etmiş olacağımı düşünüyorum. Yanılıyor muyum?
SDRAM datasheet te dikkat etmem gereken değerler nelerdir?
Cubemx'te yapmam gereken ayarlar nelerdir?
SDRAM1 bank 1 e bağlı.
(https://ibb.co/nbrgcwg)
Resimdeki alanları datasheet üzerinde bulmam gerekiyor.
SDRAMtiming in memory clock cycles olarak belirtilen alanı 16 seçtim. Ancak bu konuda datasheet te bir karışıklık var gibi geldi.Bu değeri datasheet içinde ne diye aramam gerekiyor?
SDRAM ayarlarını STM32F750N Discovery kiti örnek uygulamadan referans alarak testlere başladım.
main fonksiyon örnekte şöyle (amaç sdram test etmek)
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/* Enable the CPU Cache */
CPU_CACHE_Enable();
/* STM32F7xx HAL library initialization:
- Configure the Flash prefetch
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock to 200 MHz */
SystemClock_Config();
/* Configure LED1 */
BSP_LED_Init(LED1);
/*##-1- Configure the SDRAM device #########################################*/
/* SDRAM device configuration */
hsdram.Instance = FMC_SDRAM_DEVICE;
SDRAM_Timing.LoadToActiveDelay = 2;
SDRAM_Timing.ExitSelfRefreshDelay = 6;
SDRAM_Timing.SelfRefreshTime = 4;
SDRAM_Timing.RowCycleDelay = 6;
SDRAM_Timing.WriteRecoveryTime = 2;
SDRAM_Timing.RPDelay = 2;
SDRAM_Timing.RCDDelay = 2;
hsdram.Init.SDBank = FMC_SDRAM_BANK1;
hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram.Init.SDClockPeriod = SDCLOCK_PERIOD;
hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* Initialize the SDRAM controller */
if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Program the SDRAM external device */
BSP_SDRAM_Initialization_Sequence(&hsdram, &command);
/*##-2- SDRAM memory read/write access #####################################*/
/* Fill the buffer to write */
Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xA244250F);
/* Write data to the SDRAM memory */
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
*(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = aTxBuffer[uwIndex];
}
/* Read back data from the SDRAM memory */
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
aRxBuffer[uwIndex] = *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
}
/*##-3- Checking data integrity ############################################*/
for (uwIndex = 0; (uwIndex < BUFFER_SIZE) && (uwWriteReadStatus == 0); uwIndex++)
{
if (aRxBuffer[uwIndex] != aTxBuffer[uwIndex])
{
uwWriteReadStatus++;
}
}
if (uwWriteReadStatus != PASSED)
{
while(1)
{
/* KO, Toggle LED1 with a period of 200 ms */
BSP_LED_Toggle(LED1);
HAL_Delay(200);
}
}
else
{
/* OK, turn on LED1 */
BSP_LED_On(LED1);
}
/* Infinite loop */
while (1)
{
}
}
Benim main fonksiyon ise;
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
// MX_ADC1_Init();
// MX_CRC_Init();
// MX_I2C1_Init();
// MX_I2C2_Init();
// MX_QUADSPI_Init();
// MX_RTC_Init();
// MX_SDMMC1_SD_Init();
// MX_SPI2_Init();
// MX_TIM10_Init();
// MX_USART1_UART_Init();
// MX_DMA2D_Init();
MX_FMC_Init();
// MX_LTDC_Init();
// MX_TIM6_Init();
/* USER CODE BEGIN 2 */
/* Program the SDRAM external device */
BSP_SDRAM_Initialization_Sequence(&hsdram1, &command);
/*##-2- SDRAM memory read/write access #####################################*/
/* Fill the buffer to write */
Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xaa55aa55/*0xA244250F*/);
/* Write data to the SDRAM memory */
uint32_t p;
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
*(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex) = aTxBuffer[uwIndex];
}
/* Read back data from the SDRAM memory */
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
aRxBuffer[uwIndex] = *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex);
}
/*##-3- Checking data integrity ############################################*/
for (uwIndex = 0; (uwIndex < BUFFER_SIZE) /*&& (uwWriteReadStatus == 0)*/; uwIndex++)
{
if (aRxBuffer[uwIndex] != aTxBuffer[uwIndex])
{
uwWriteReadStatus++;
__BKPT(0);
}
}
if (uwWriteReadStatus != PASSED)
{
while(1)
{
/* KO, Toggle LED1 with a period of 200 ms */
// BSP_LED_Toggle(LED1);
HAL_Delay(200);
}
}
else
{
/* OK, turn on LED1 */
// BSP_LED_On(LED1);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Ayrıca FMC_Init fonksiyonu;
/* FMC initialization function */
static void MX_FMC_Init(void)
{
/* USER CODE BEGIN FMC_Init 0 */
/* USER CODE END FMC_Init 0 */
FMC_SDRAM_TimingTypeDef SdramTiming = {0};
/* USER CODE BEGIN FMC_Init 1 */
/* USER CODE END FMC_Init 1 */
/** Perform the SDRAM1 memory initialization sequence
*/
hsdram1.Instance = FMC_SDRAM_DEVICE;
/* hsdram1.Init */
hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* SdramTiming */
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 6;
SdramTiming.SelfRefreshTime = 4;
SdramTiming.RowCycleDelay = 6;
SdramTiming.WriteRecoveryTime = 2;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;
if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
{
Error_Handler( );
}
/* USER CODE BEGIN FMC_Init 2 */
/* USER CODE END FMC_Init 2 */
}
Yardımcı fonksiyonlar ise şöyle;
/**
* @brief Perform the SDRAM external memory initialization sequence
* @param hsdram: SDRAM handle
* @param Command: Pointer to SDRAM command structure
* @retval None
*/
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 4: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 8: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));
}
/**
* @brief Fills buffer with user predefined data.
* @param pBuffer: pointer on the buffer to fill
* @param uwBufferLenght: size of the buffer to fill
* @param uwOffset: first value to fill on the buffer
* @retval None
*/
static void Fill_Buffer(uint32_t *pBuffer, uint32_t uwBufferLenght, uint32_t uwOffset)
{
uint32_t tmpIndex = 0;
/* Put in global buffer different values */
for (tmpIndex = 0; tmpIndex < uwBufferLenght; tmpIndex++ )
{
pBuffer[tmpIndex] = tmpIndex + uwOffset;
}
}
Değişkenler ve macrolar ise şöyle;
typedef enum {PASSED = 0, FAILED = !PASSED} TestStatus_t;
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
#define SDRAM_BANK_ADDR ((uint32_t)0xC0000000)
/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
#define BUFFER_SIZE ((uint32_t)0x1000)
#define WRITE_READ_ADDR ((uint32_t)0x0000)
//#define WRITE_READ_ADDR ((uint32_t)0x0800)
/* Read/Write Buffers */
uint32_t aTxBuffer[BUFFER_SIZE];
uint32_t aRxBuffer[BUFFER_SIZE];
/* Status variables */
__IO uint32_t uwWriteReadStatus = 0;
/* Counter index */
uint32_t uwIndex = 0;
FMC_SDRAM_CommandTypeDef command;
Sorun ise şu;
Yazdığım değerlerin aynısını okuyamıyorum. örnekteki kodda 0xA244250F değerini yazıyor. Başlangıç adresi de 0x0800. Bu şartlarda 0. adresten itibaren 0xA244250F yerine 0xA244210F olarak okuyor. Yazdığım değeri 0 olarak değiştirdim. Bu kez 1024. adresten itibaren 0 a dönüp arttığını görüyorum. Bu tarz bir sorunun sebebi ne olabilir?
Derdim bütün pinlerin sağlıklı şekilde bağlandığından emin olmak. MCU bga kılıf.
SDRAM başka nasıl test edilir? Nelerden emin olmam gerekiyor?
Datasheeti iyi oku derim. ;) Soyle yuzeysel baktigimda ayarlarin yanlis gibi duruyor. Ben iki hata buldum mesela. CAS 2 write recovery 1 olmali 8-)
Tekrar merhaba,
Uzun zamandır yazamadım yoğunluktan.
SDRAM ile ilgili ayarları tamamladım. Yararlandığım kaynak burada. (http://microelk.azurewebsites.net/STM32_STEmWin/STM32_STEmWin)
hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* SdramTiming */
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 7;
SdramTiming.SelfRefreshTime = 4;
SdramTiming.RowCycleDelay = 6;
SdramTiming.WriteRecoveryTime = 2;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;
Test ettim ve herhangi bir sorun ile karşılaşmadım. Test yöntemi ise oldukça basit. RAM kapasitesi kadar alana bildiğim bir değeri yazıp o değeri okuyorum. Değer doğru ise sorun yoktur diyorum.
//#define BUFFER_SIZE ((uint32_t)0x8000)
#define BUFFER_SIZE ((uint32_t)0x400000)
#define WRITE_READ_ADDR ((uint32_t)0x0000)
#define WRITE_VALUE ((uint32_t)0xA244250F)
//#define SDRAM_TEST
/* Status variables */
__IO uint32_t uwWriteReadStatus = 0;
/* Counter index */
uint32_t uwIndex = 0;
FMC_SDRAM_CommandTypeDef command;
#if defined(SDRAM_TEST)
/**
* @brief Perform the SDRAM external memory initialization sequence
* @param hsdram: SDRAM handle
* @param Command: Pointer to SDRAM command structure
* @retval None
*/
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd = 0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 4: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 8: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
hsdram->Instance->SDRTR |= ((uint32_t)((1292) << 1));
}
//
#endif
#if defined(SDRAM_TEST)
/* Program the SDRAM external device */
BSP_SDRAM_Initialization_Sequence(&hsdram1, &command);
/*##-2- SDRAM memory read/write access #####################################*/
/* Write data to the SDRAM memory */
for(uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
*(__IO uint32_t *)(SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex) = WRITE_VALUE;
}
/*##-3- Checking data integrity ############################################*/
for(uwIndex = 0; (uwIndex < BUFFER_SIZE) /*&& (uwWriteReadStatus == 0)*/; uwIndex++)
{
uint32_t value = *(__IO uint32_t *)(SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex);
if(value != WRITE_VALUE)
{
uwWriteReadStatus++;
__BKPT(0);
}
}
if(uwWriteReadStatus != PASSED)
{
while(1)
{
HAL_Delay(200);
}
}
#endif
Debug ile kontrol ettiğimde yazdığım bütün alanı aynı değer ile okuyabiliyorum. Yazma ve okuma işlerini 32 bit olarak yapıyorum. Bir de byte olarak yapmam gerekir mi?
Şimdilerde LTDC donanımı ile biraz sıkıntı yaşıyorum. Kullandığım LCD kontrolcüsü şu. (https://www.buydisplay.com/download/ic/HX8264.pdf)
İlgili ayarları şu şekilde yaptım:
(https://ibb.co/phF8f11)
hltdc.Instance = LTDC;
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc.Init.HorizontalSync = 0;
hltdc.Init.VerticalSync = 2;
hltdc.Init.AccumulatedHBP = 46;
hltdc.Init.AccumulatedVBP = 25;
hltdc.Init.AccumulatedActiveW = 846;
hltdc.Init.AccumulatedActiveH = 505;
hltdc.Init.TotalWidth = 1056;
hltdc.Init.TotalHeigh = 527;
hltdc.Init.Backcolor.Blue = 0;
hltdc.Init.Backcolor.Green = 255;
hltdc.Init.Backcolor.Red = 0;
if(HAL_LTDC_Init(&hltdc) != HAL_OK)
{
Error_Handler();
}
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 800;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 480;
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
pLayerCfg.Alpha = 255;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
pLayerCfg.FBStartAdress = 0;
pLayerCfg.ImageWidth = 800;
pLayerCfg.ImageHeight = 480;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 255;
pLayerCfg.Backcolor.Red = 0;
if(HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
{
Error_Handler();
}
Aslında şuan herhangi bir layer ayarı yapmak istemiyorum. Yalnızca ekrana mavi, yeşil, kırmızı herhangi birini bastırsam şuan yeterli. Ekranın çalıştığını görmek istiyorum.
LTDC ayarlarını yaparken referans aldığım doküman ise AN4861 (https://www.st.com/content/ccc/resource/technical/document/application_note/group0/25/ca/f9/b4/ae/fc/4e/1e/DM00287603/files/DM00287603.pdf/jcr:content/translations/en.DM00287603.pdf)
Aşağıda ekranın durumu var.
(https://ibb.co/gPdBNB4)
Referans aldığım dokümana göre;
PCLK (Pixel Clock) [Hz] = Total Heigh x Total Width x Refresh Rate
PCLK = 527 * 1056 * 60 = 33 390 720 Hz = 33,39072 MHz.
Bu değerlere göre PCL değerini hem 33,5 MHz olarak hem de 33,3333 MHz olarak ayarladım. Hatta denemek amacıyla 50 MHz olarak da denedim. Sonuç resimdeki gibi. Hiçbir değişiklik yok.
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 200;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 8;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if(HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_RTC
| RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1
| RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_SDMMC1
| RCC_PERIPHCLK_CLK48;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 200;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 3;
PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2;
PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV2;
PeriphClkInitStruct.PLLSAIDivQ = 1;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
PeriphClkInitStruct.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_CLK48;
if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
Bu arada Interrupt açmıştım ve durumu debug ile denediğimde 2 kez isr içine girdiğini gördüm. Callback ile baktığımda,
/**
* @brief Error LTDC callback.
* @param hltdc pointer to a LTDC_HandleTypeDef structure that contains
* the configuration information for the LTDC.
* @retval None
*/
void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hltdc);
__BKPT(0);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_LTDC_ErrorCallback could be implemented in the user file
*/
}
//
/**
* @brief Line Event callback.
* @param hltdc pointer to a LTDC_HandleTypeDef structure that contains
* the configuration information for the LTDC.
* @retval None
*/
void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hltdc);
__BKPT(0);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_LTDC_LineEventCallback could be implemented in the user file
*/
}
//
/**
* @brief Reload Event callback.
* @param hltdc pointer to a LTDC_HandleTypeDef structure that contains
* the configuration information for the LTDC.
* @retval None
*/
void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hltdc);
__BKPT(0);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_LTDC_ReloadEvenCallback could be implemented in the user file
*/
}
//
HAL_LTDC_ERROR_TE /*!< LTDC Transfer error */
HAL_LTDC_ERROR_FU /*!< LTDC FIFO Underrun */
birer kez oluştuğunu gördüm.HAL_LTDC_ErrorCallback
2 kez çağırıldığını gördüm ve yukarıdakilerden kaynaklandığını gördüm.
Sonuç olarak lcd yi sağlıklı bir şekilde nasıl çalıştırabilirim? Nerede hata yapıyorum acaba?
32 bit uygun fakat RAM testi o kadar basit degil ;)
Tam anlamyila test etmek istiyorsan assagidaki gibi olmali. Buradan aldigin hatalari yorumlayarak nerede sorun oldugunu bulabilirsin.
- Sabit sayi ile hafizayi doldurmak (bu senin yaptigin)
- Artan ve azalan sayi ile hafizayi doldurmak
- Yuruyen 1 ve 0 lar ile hafizayi doldurmak
Bu testlerden sag salim cikmasi lazim. ::ok
@yldzelektronik kullandığınız LCD nedir??
RAM testi için Memtest86 programını örnek alabilirsiniz.
Alıntı yapılan: serdararikan - 15 Ağustos 2019, 21:11:05@yldzelektronik kullandığınız LCD nedir??
Hocam kontrolcü için link vermiştim. https://www.buydisplay.com/download/ic/HX8264.pdf
Ancak lcd paneli soruyarsanız o da şu: https://www.buydisplay.com/default/4-3-800x480-ips-tft-lcd-module-all-viewing-optl-touchscreen-display
@OptimusPrime @MC_Skywalker aslında ram testindeki gayem bga kılıf doğru dürüst lehimlenmiş mi ondan emin olmak :)
Memtest86 ya çok kısa baktım. Baya detaylı imiş. Öyle bir test gerekli mi bilmiyorum ama fena olmaz sanki.
@OptimusPrime ın bahsettiği yöntemi ileride uygulayabilirim. Şimdilik kalsın diyorum.
Şuan önceliğim LTDC ve QSPI ile ilgili sıkıntıları çözmek.
O zaman en azindan yuruyen 1 denemelisin. ::ok
Alıntı yapılan: OptimusPrime - 16 Ağustos 2019, 16:32:16O zaman en azindan yuruyen 1 denemelisin. ::ok
Yürüyen derken hocam? Biraz açar mısınız?
adres = 0x0000_0000, patern = 0x0000_0001
adres = 0x0000_0004, patern = 0x0000_0010
adres = 0x0000_0008, patern = 0x0000_0100
adres = 0x0000_000C, patern = 0x0000_1000
adres = 0x0000_0010, patern = 0x0001_0000
adres = 0x0000_0014, patern = 0x0010_0000
adres = 0x0000_001C, patern = 0x0100_0000
adres = 0x0000_0020, patern = 0x1000_0000
gibi. Herbir baglantiyi ayri ayri test etmis olursun. Bunun aynisini adres bitlerinede uygulayabilirsin.
LCD ile ilgili sorunum halen devam etmekte.Şöyle bir gelişme var:
STM32F7508-DISCO LTDC_PicturesFromSDCard örneğini kendi kartıma uyarladım. SD carddan resim okuyup yazmayı deniyorum. Ancak başarılı olamıyorum. SD card okunuyor. Sorun yok.
Ekranda gördüğüm ise: https://www.youtube.com/watch?v=cxayA_-Zh34
LCD Init kodları:
/**
* @brief Initializes the LTDC MSP.
* @param hltdc: LTDC handle
* @param Params
* @retval None
*/
__weak void BSP_LCD_MspInit(LTDC_HandleTypeDef *hltdc, void *Params)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable the LTDC and DMA2D clocks */
__HAL_RCC_LTDC_CLK_ENABLE();
__HAL_RCC_DMA2D_CLK_ENABLE();
/* Enable GPIOs clock */
BSP_GPIOCLK_Enable();
LCD_DISP_GPIO_CLK_ENABLE();
LCD_BL_CTRL_GPIO_CLK_ENABLE();
/*** LTDC Pins configuration ***/
/**LTDC GPIO Configuration
PG11 ------> LTDC_B3
PJ13 ------> LTDC_B1
PJ12 ------> LTDC_B0
PK7 ------> LTDC_DE
PK6 ------> LTDC_B7
PK5 ------> LTDC_B6
PG12 ------> LTDC_B4
PJ14 ------> LTDC_B2
PI10 ------> LTDC_HSYNC
PK4 ------> LTDC_B5
PI9 ------> LTDC_VSYNC
PK1 ------> LTDC_G6
PK2 ------> LTDC_G7
PI15 ------> LTDC_R0
PJ11 ------> LTDC_G4
PK0 ------> LTDC_G5
PI14 ------> LTDC_CLK
PJ8 ------> LTDC_G1
PJ10 ------> LTDC_G3
PJ7 ------> LTDC_G0
PJ9 ------> LTDC_G2
PJ6 ------> LTDC_R7
PJ4 ------> LTDC_R5
PJ5 ------> LTDC_R6
PJ3 ------> LTDC_R4
PJ2 ------> LTDC_R3
PJ0 ------> LTDC_R1
PJ1 ------> LTDC_R2
*/
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_12 | GPIO_PIN_14 |GPIO_PIN_11 |
GPIO_PIN_8 | GPIO_PIN_10 | GPIO_PIN_7 |GPIO_PIN_9 |
GPIO_PIN_6 | GPIO_PIN_4 | GPIO_PIN_5 |GPIO_PIN_3 |
GPIO_PIN_2 | GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4 |
GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_0;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOK, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF9_LTDC;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_9 | GPIO_PIN_15 | GPIO_PIN_14;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
/* LCD_DISP GPIO configuration */
GPIO_InitStruct.Pin = LCD_DISP_PIN; /* LCD_DISP pin has to be manually controlled */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(LCD_DISP_GPIO_PORT, &GPIO_InitStruct);
/** TIM10 GPIO Configuration PF6 ------> TIM10_CH1 */
GPIO_InitStruct.Pin = LCD_BL_CTL_Pin;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF3_TIM10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(LCD_BL_CTL_GPIO_Port, &GPIO_InitStruct);
}
//
uint8_t BSP_LCD_Init(void)
{
/* Select the used LCD */
/* The HX8264 LCD 800x480 is selected */
/* Timing Configuration */
hLtdcHandler.Init.HorizontalSync = (HX8264_HSYNC - 1);
hLtdcHandler.Init.VerticalSync = (HX8264_VSYNC - 1);
hLtdcHandler.Init.AccumulatedHBP = (HX8264_HSYNC + HX8264_HBP - 1);
hLtdcHandler.Init.AccumulatedVBP = (HX8264_VSYNC + HX8264_VBP - 1);
hLtdcHandler.Init.AccumulatedActiveW = (HX8264_WIDTH + HX8264_HSYNC + HX8264_HBP - 1);
hLtdcHandler.Init.AccumulatedActiveH = (HX8264_HEIGHT + HX8264_VSYNC + HX8264_VBP - 1);
hLtdcHandler.Init.TotalHeigh = (HX8264_HEIGHT + HX8264_VSYNC + HX8264_VBP + HX8264_VFP - 1);
hLtdcHandler.Init.TotalWidth = (HX8264_WIDTH + HX8264_HSYNC + HX8264_HBP + HX8264_HFP - 1);
/* LCD clock configuration */
BSP_LCD_ClockConfig(&hLtdcHandler, NULL);
/* Initialize the LCD pixel width and pixel height */
hLtdcHandler.LayerCfg->ImageWidth = HX8264_WIDTH;
hLtdcHandler.LayerCfg->ImageHeight = HX8264_HEIGHT;
/* Background value */
hLtdcHandler.Init.Backcolor.Blue = 0;
hLtdcHandler.Init.Backcolor.Green = 0;
hLtdcHandler.Init.Backcolor.Red = 0;
/* Polarity */
hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hLtdcHandler.Instance = LTDC;
if(HAL_LTDC_GetState(&hLtdcHandler) == HAL_LTDC_STATE_RESET)
{
/* Initialize the LCD Msp: this __weak function can be rewritten by the application */
BSP_LCD_MspInit(&hLtdcHandler, NULL);
}
HAL_LTDC_Init(&hLtdcHandler);
/* Assert display enable LCD_DISP pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET);
/* Assert backlight LCD_BL_CTRL pin */
Init_BacklightPWM();
#if !defined(DATA_IN_ExtSDRAM)
/* Initialize the SDRAM */
BSP_SDRAM_Init();
#endif
/* Initialize the font */
BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
return LCD_OK;
}
Sorunun rgb ayarlarıyla ilgili olduğunu sanıyorum. Mesela ekranın ortasına yazı yazdırmak istediğimde ekranın ortasında bir kargaşa oluştuğunu görüyorum. Ama renkler birbirine girmiş.
Nasıl çözebilirim?
Hocam temel olarak ilk önce rgb datası ile test etmek gerekir. Ben olsaydım ilk olarak ram alanını 32bit ARGB Değerleri ile doldurup ekranda RGB testi yapardım. Bu çok önemli eğer bu aşamayı geçemiyorsanız resim basmaya felan uğraşma. Bence sen bunu düzgün yapamıyorsun.
LTDC yi bende çok iyi bilmiyorum. O yüzden net birşey diyemiyorum.
Sonuca bakarak birsey demek zor. Sanki yatay pixel i fazla veriyorsun gibide duruyor. Ama olmayadabilir. En güzeli özellikle vsync hsync i scope ile gozleyip bilinen bir data göndermen. Bu sana nerede hata olduğuna dair fikir verecektir.
Edit: lcd config fonksiyonunu aşağıdaki şekilde düzenlediğimde ekranda istediğim formatta (rgb565, rgb888, argb8888) renk basabiliyorum. Demek ki lcd ile ilgili bir sorun yok. Peki hafıza kartından okuyup yazarken neden sorun oluyor?
LTDC_LayerCfgTypeDef pLayerCfg;
/* LCD Initialization */
BSP_LCD_Init();
/* Layer1 Configuration ------------------------------------------------------*/
/* Windowing configuration */
/* In this case all the active display area is used to display a picture then :
Horizontal start = horizontal synchronization + Horizontal back porch = 43
Vertical start = vertical synchronization + vertical back porch = 12
Horizontal stop = Horizontal start + window width -1 = 43 + 480 -1
Vertical stop = Vertical start + window height -1 = 12 + 272 -1 */
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 800;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 480;
/* Pixel Format configuration*/
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
/* Start Address configuration : frame buffer is located at FLASH memory */
pLayerCfg.FBStartAdress = (uint32_t)LCD_FB_START_ADDRESS;
/* Alpha constant (255 == totally opaque) */
pLayerCfg.Alpha = 255;
/* Default Color configuration (configure A,R,G,B component values) : no background color */
pLayerCfg.Alpha0 = 0; /* fully transparent */
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
/* Configure blending factors */
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
/* Configure the number of lines and number of pixels per line */
pLayerCfg.ImageWidth = 800;
pLayerCfg.ImageHeight = 480;
extern LTDC_HandleTypeDef hLtdcHandler;
/* Configure the Layer*/
if(HAL_LTDC_ConfigLayer(&hLtdcHandler, &pLayerCfg, 1) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
uint32_t Color = 0;
uint64_t size = BSP_LCD_GetXSize() * BSP_LCD_GetYSize() * 4;
while(1)
for(uint64_t i = 0; i < size; i++)
{
*(__IO uint32_t*)(LCD_FB_START_ADDRESS + (4 * i)) = Color;
}
Sorun halen devam ediyor. Konuyla ilgili bilgisi olan var mı?
Konu hakkinda bir bilgim/tecrubem yok. Sadece bi el atayim dedim 8-) ::ok
Bence ilk once SD den frame buffer a nasil data aktarildigini goz onunde bulundurmalisin. LCD de bir sorun olmadigina gore SD den LCD ye olan data zincirinde bir kopukluk olsa gerek.
Alıntı yapılan: OptimusPrime - 19 Ağustos 2019, 08:15:50Sonuca bakarak birsey demek zor. Sanki yatay pixel i fazla veriyorsun gibide duruyor. Ama olmayadabilir. En güzeli özellikle vsync hsync i scope ile gozleyip bilinen bir data göndermen. Bu sana nerede hata olduğuna dair fikir verecektir.
Hocam haklısınız. Fazla pclk verildiği içinmiş. Sorun çözüldü. Teşekkürler.
@Mucit23 teşekkürler.
Şimdi fark ettiğim bir durum var.
ST diyor ki PCLK = toplam genişlik x toplam uzunluk x yenileme hızı
Ben de diyorum ki PCLK = 1056 x 527 x 60 = 33.390.720 Hz. Buna göre 33,5 MHz yaparsam karınca tv yayına başlıyor.
Ancak 21 MHz yaparsam resim sorunsuz görünürken yazı yazdırmak istediğimde ekrana yine karıncalanma oluyor.
PCLK yı 17 MHz yapınca da resim yenilenmeleri belli oluyor. Hiç hoş olmuyor.
Bu işin kuralı nedir?
ekran 800x480 degilmiydi? 1056 x 527 nasil yapiyorsun?
@OptimusPrimeSanırım hesap yapılırken kullanılabilir aktif alana göre değil, Back Porch, Front Porch gibi değerlerle birlikte Toplam genişlik ve yükselik hesaplanıyor.
Dogrudur. ::ok
Sd den okunan resimlerin lcd boyutunda olmasini bekliyordum garip rakamlar cikti. Aslinda bu rakamlar nerden geliyor onu merak ettim. Sistemde kamera da yok diye biliyorum.
@OptimusPrime @Mucit23 ün dediği gibi toplam alan.
Camera yok sistemde.
@Mucit23 un verdigi sekilde gorunen zamanlamalari sen ne olarak girdiysen yazsana bi buraya.
Hicbir zaman senkron calismiyor sanki cihaz. Sadece Vsync ve Hsync i ani anda gorunce bi aska geliyor sonra yine sapitiyor gibi.
Elindeki xtal degerlerinide yaz. ;)
Alıntı yapılan: OptimusPrime - 11 Eylül 2019, 19:02:16@Mucit23 un verdigi sekilde gorunen zamanlamalari sen ne olarak girdiysen yazsana bi buraya.
Hicbir zaman senkron calismiyor sanki cihaz. Sadece Vsync ve Hsync i ani anda gorunce bi aska geliyor sonra yine sapitiyor gibi.
Elindeki xtal degerlerinide yaz. ;)
Hocam selam. Baya geç bir cevap oldu. Kusura bakma.
Kullandığım ekrandaki değerler şöyle;
(https://ibb.co/y0JH9kT)
Bu değerlere göre ben lcd clk değerini 33,5 MHz olarak belirliyorum. Bu durumda kaymalar oluyor.
Değerleri şu şekilde ayarladığımda;
/**
* @brief HX8264 frequency divider
*/
#define HX8264_FREQUENCY_DIVIDER 4 /* LCD Frequency divider */
/* HX8264 LCD clock configuration */
/* PLLSAI_VCO Input = HSI_VALUE / PLL_M = 2 Mhz */
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 138 Mhz */
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 168 / 4 = 42 Mhz */
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 42 / 2 = 21Mhz */
periph_clk_init_struct.PLLSAI.PLLSAIN = 84;
periph_clk_init_struct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
periph_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
periph_clk_init_struct.PLLSAI.PLLSAIR = HX8264_FREQUENCY_DIVIDER;
HAL_RCCEx_PeriphCLKConfig(&periph_clk_init_struct);
Sorun düzeliyor. Kaymalar bitiyor.
Edit: tag
@taydin
Yani? cozdun mu? ::)
Alıntı yapılan: OptimusPrime - 15 Ekim 2019, 19:34:12Yani? cozdun mu? ::)
Abi touchgfx ile yaptığımda herhangi bir titreme gözükmüyor. Bakalım biraz daha test edeyim de anlarız. :)
Tekrar merhaba,
SDRAM test ile ilgili şöyle bir test programı hazırladım.
uint32_t memTestDataBus(volatile uint32_t * address)
{
uint32_t pattern;
/* Perform a walking 1's test at the given address. */
for (pattern = 1; pattern != 0; pattern <<= 1)
{
/* Write the test pattern. */
*address = pattern;
/* Read it back (immediately is okay for this test). */
if (*address != pattern)
{
return (pattern);
}
}
return (0);
}
//
uint32_t *memTestAddressBus(volatile uint32_t * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long testOffset;
unsigned long addressMask = (nBytes / sizeof(datum) - 1);
datum pattern = (uint32_t ) 0xAAAAAAAA;
datum antipattern = (uint32_t ) 0x55555555;
/* Write the default pattern at each of the power-of-two offsets. */
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
baseAddress[offset] = pattern;
}
/* Check for address bits stuck high. */
testOffset = 0;
baseAddress[testOffset] = antipattern;
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if (baseAddress[offset] != pattern)
{
return ((datum *) &baseAddress[offset]);
}
}
baseAddress[testOffset] = pattern;
/* Check for address bits stuck low or shorted. */
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
{
baseAddress[testOffset] = antipattern;
if (baseAddress[0] != pattern)
{
return ((datum *) &baseAddress[testOffset]);
}
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if ((baseAddress[offset] != pattern) && (offset != testOffset))
{
return ((datum *) &baseAddress[testOffset]);
}
}
baseAddress[testOffset] = pattern;
}
return (NULL);
}
//
uint32_t *memTestDevice(volatile uint32_t * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long nWords = nBytes / sizeof(datum);
uint32_t pattern;
uint32_t antipattern;
/* Fill memory with a known pattern. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
baseAddress[offset] = pattern;
}
/* Check each location and invert it for the second pass. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
if (baseAddress[offset] != pattern)
{
return ((uint32_t *) &baseAddress[offset]);
}
antipattern = ~pattern;
baseAddress[offset] = antipattern;
}
/* Check each location for the inverted pattern and zero it. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
antipattern = ~pattern;
if (baseAddress[offset] != antipattern)
{
return ((uint32_t *) &baseAddress[offset]);
}
}
return (NULL);
}
//
Bu kod ile sdrami test ettiğimde herhangi bir sorunla karşılaşmıyorum. Ancak resimleri ekrana aldığımda aşağıdaki gibi sorunla karşılaşıyorum.
Hem görsel olması gerektiği gibi değil, anlamsız beyaz noktalar, olmaması gereken beyaz çizgiler, dikkatli bakıldığında fark edilen hareketli pixeller.
Bunun yanında butonlara dokunulduğunda algılanmayan touch eylemi. Aslında touch ic algılıyor. Bunu debug yaparken görebiliyorum. Konumları falan alabiliyorum. Ama gel gelelim buton touch event oluşmuyor. Zaten video da fark edilebilen anlamsız dokunuşlar, dokunulduğunda ekranda oluşan değişimler görülüyor.
Bu sorunun sebebi nedir?
Geliştirme ortamı Keil, TouchGFX.
Şöyle bir şey oldu az evvel;
Test kodunu çalıştırdığımda test yaklaşık 29 saniye falan sürüyor. Eğer bu testi yaparak boot olursa, ekrandaki kötü pixeller görünmüyor.
Ancak o kısmı es geçersem sorun devam ediyor. Main şöyle;
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* enable gpio clock */
BSP_GPIOCLK_Enable();
/* init sdram */
if(BSP_SDRAM_Init() != SDRAM_OK)
SDRAM_Error = true;
/* init qspi init */
if(BSP_QSPI_Init() != QSPI_OK)
QSPIFlash_Error = true;
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
/* get qspi flash id */
if(BSP_QSPI_ReadID(&QSPI_ID) != QSPI_OK)
QSPIFlash_Error = true;
/* get qspi flash device id */
if(BSP_QSPI_ReadDeviceID(&QSPI_DevID) != QSPI_OK)
QSPIFlash_Error = true;
/* enable memory map mode */
if(BSP_QSPI_EnableMemoryMappedMode(true) != QSPI_OK)
QSPIFlash_Error = true;
/* test SDRAM */
uint32_t *address;
for(address = (uint32_t*)SDRAM_DEVICE_ADDR; address < (uint32_t *)(SDRAM_DEVICE_ADDR + SDRAM_DEVICE_SIZE); address++)
{
if(memTestDataBus((datum *)address) != 0)
{
SDRAM_Error = true;
break;
}
}
if(memTestAddressBus((datum*)SDRAM_DEVICE_ADDR, SDRAM_DEVICE_SIZE) != 0)
SDRAM_Error = true;
if(memTestDevice((datum*)SDRAM_DEVICE_ADDR, SDRAM_DEVICE_SIZE) != 0)
SDRAM_Error = true;
/* test TFT LCD Touch Panel IC */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* check if there is any bootloader application? */
if(QSPIFlash_Error == false && checkforapplication(BOOTLOADER1_ADDRESS))
{
/* there is a bootloader in the external flash */
/* deinit usb */
USBD_DeInit(&hUsbDeviceFS);
/* deinit sdram */
BSP_SDRAM_DeInit();
SysTick->CTRL = 0;
SCB->VTOR = BOOTLOADER1_ADDRESS; /* Vector Table Relocation in Internal FLASH */
/* Initialize user application's Stack Pointer & Jump to user application */
JumpToApplication = (pFunction) (*(__IO uint32_t*) (BOOTLOADER1_ADDRESS + 4));
__set_MSP(*(__IO uint32_t*) BOOTLOADER1_ADDRESS);
JumpToApplication();
}
}
}
}
Test kodu dedigin ram testi mi?
Alıntı yapılan: OptimusPrime - 24 Ekim 2019, 02:10:04Test kodu dedigin ram testi mi?
Evet.
Şimdi başka bir şey daha oldu. RAMi temizleyip içine 0 doldurursam (ram testi kapalı) pixel sorunu ortadan kalkıyor. Ama neden?
0 yerine FF yaparsan geri geliyor mu?
Alıntı yapılan: OptimusPrime - 24 Ekim 2019, 02:40:160 yerine FF yaparsan geri geliyor mu?
Hocam tekrar selam.
Kusura bakma geç oldu. 3 gündür yeni CubeMX ile uğraşıyorum. TouchGFX ve CubeMX güncellenmiş. Ancak proje oluştururken CubeMX garip garip hatalar veriyordu. 5.3 e geri döndüm. Ancak çözdüm sorunu.
Hocam 0x00 veya 0xFF yaparsam sorun düzeliyor. Ancak herhangi bir şey yazmazsam görüntü videodaki gibi bulanık oluyor.
Ben sorunun SDRAM ayarlarıyla ilgili olduğunu düşünüyorum. Ancak bütün değerleri SDRAM datasheetten aldım.
Ayrıca tek renk (turkuaz gibi) arka plan resmi ile denediğimde böyle bir durum olmuyor. Resmi gayet düzgün şekilde gösteriyor. Ancak o durumda sadece tek bir resim oluyor. Ancak videodaki proje tam haliyle. Acaba diyorum TouchGFX bir şekilde bütün resimleri SDRAM'e kopyalayıp o şekilde mi ekranı yeniliyor?
Cok acayip seylerden bahsediyorsun. Bazen senin devre cinlenmis bi okuttur diyesim geliyor :D
:du:
Ram testi icin cetrefilli birseyden bahsetmistim. Onu bi uygula derim. En azindan ram ile ilgili suphelerin ortadan kalkar.
Bu arada derleyiciye bu alana dokunma dedin mi?
Alıntı yapılan: OptimusPrime - 27 Ekim 2019, 08:33:20Cok acayip seylerden bahsediyorsun. Bazen senin devre cinlenmis bi okuttur diyesim geliyor :D
...
Evet. Genelde benim işlerde bu tip şeyler bolca oluyor ;D ;D
Alıntı yapılan: OptimusPrime - 27 Ekim 2019, 08:33:20...
Ram testi icin cetrefilli birseyden bahsetmistim. Onu bi uygula derim. En azindan ram ile ilgili suphelerin ortadan kalkar.
Aşağıdaki konudan bahsediyorsan;
Alıntı yapılan: OptimusPrime - 15 Ağustos 2019, 19:53:0232 bit uygun fakat RAM testi o kadar basit degil ;)
Tam anlamyila test etmek istiyorsan assagidaki gibi olmali. Buradan aldigin hatalari yorumlayarak nerede sorun oldugunu bulabilirsin.
- Sabit sayi ile hafizayi doldurmak (bu senin yaptigin)
- Artan ve azalan sayi ile hafizayi doldurmak
- Yuruyen 1 ve 0 lar ile hafizayi doldurmak
Bu testlerden sag salim cikmasi lazim. ::ok
Evet. Bu iş için bir test programı var ve buradan gerçekten sağ salim çıktı.
uint32_t memTestDataBus(volatile uint32_t * address)
{
uint32_t pattern;
/* Perform a walking 1's test at the given address. */
for (pattern = 1; pattern != 0; pattern <<= 1)
{
/* Write the test pattern. */
*address = pattern;
/* Read it back (immediately is okay for this test). */
if (*address != pattern)
{
return (pattern);
}
}
return (0);
}
//
uint32_t *memTestAddressBus(volatile uint32_t * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long testOffset;
unsigned long addressMask = (nBytes / sizeof(datum) - 1);
datum pattern = (uint32_t ) 0xAAAAAAAA;
datum antipattern = (uint32_t ) 0x55555555;
/* Write the default pattern at each of the power-of-two offsets. */
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
baseAddress[offset] = pattern;
}
/* Check for address bits stuck high. */
testOffset = 0;
baseAddress[testOffset] = antipattern;
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if (baseAddress[offset] != pattern)
{
return ((datum *) &baseAddress[offset]);
}
}
baseAddress[testOffset] = pattern;
/* Check for address bits stuck low or shorted. */
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
{
baseAddress[testOffset] = antipattern;
if (baseAddress[0] != pattern)
{
return ((datum *) &baseAddress[testOffset]);
}
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if ((baseAddress[offset] != pattern) && (offset != testOffset))
{
return ((datum *) &baseAddress[testOffset]);
}
}
baseAddress[testOffset] = pattern;
}
return (NULL);
}
//
uint32_t *memTestDevice(volatile uint32_t * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long nWords = nBytes / sizeof(datum);
uint32_t pattern;
uint32_t antipattern;
/* Fill memory with a known pattern. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
baseAddress[offset] = pattern;
}
/* Check each location and invert it for the second pass. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
if (baseAddress[offset] != pattern)
{
return ((uint32_t *) &baseAddress[offset]);
}
antipattern = ~pattern;
baseAddress[offset] = antipattern;
}
/* Check each location for the inverted pattern and zero it. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
antipattern = ~pattern;
if (baseAddress[offset] != antipattern)
{
return ((uint32_t *) &baseAddress[offset]);
}
}
return (NULL);
}
//
Diğer taraftan;
Alıntı yapılan: OptimusPrime - 27 Ekim 2019, 08:44:22Bu arada derleyiciye bu alana dokunma dedin mi?
Ben öyle bir tanımlama yapmadım. Bu alan harici ramde. Yani derleyicinin oraya bir şey koyacağını pek zannetmiyorum. Nasıl diyeceğim derleyiciye karışma bu alana?
Konu SDRAM timing ile ilgili olabilir mi?
Daha önce başıma geldi kritik değişkenler kesinlikle volatile olarak tanımlanmalı.. Bende anlam veremiyorum.
Cihaz 2 aşamalı çalışıyor. İlk aşamada bir yazılım sdram init ediliyor. Burada flashta yazılım varsa deinit yapılıp user app external flashtan çalıştırılıyor.
Bootloader da Sdram init etmesem ve temizlemesem yine aynı bozukluklar oluyor. Debug ile (user app ta) 0xC0000000 adresine baktığımda gerçekten sürekli değerlerin değiştiğini görüyorum. User app te hiçbir değişiklik yok.
Sadece bootloaderda sdram temizlenmezse sdrame sürekli bir şeyler yazılıyor. Bu arada sdram e 0x00, 0xFF, 0xAA55 gibi değerler yazarak boot etmeyi denediğimde her seferinde ekran sorunsuz çalışıyor. Demek ki mutlaka bir şeyler yazıp öyle boot olmak gerekiyor diye düşünüyorum.
Peki timing değerlerim yanlış mı acaba? Bu durum neden olur?
Alıntı yapılan: yldzelektronik - 27 Ekim 2019, 13:48:14Bootloader da Sdram init etmesem ve temizlemesem yine aynı bozukluklar oluyor. Debug ile (user app ta) 0xC0000000 adresine baktığımda gerçekten sürekli değerlerin değiştiğini görüyorum. User app te hiçbir değişiklik yok.
Peki timing değerlerim yanlış mı acaba? Bu durum neden olur?
Programinizda hatali code olabilir, sifir adresine birseyler yazmak NULL pointer kullanimini gosteriyor olabilir. Statik kod inceleyen PC Lint veya benzeri ile kodunuzu analiz ediniz.
Alıntı yapılan: mufitsozen - 27 Ekim 2019, 16:56:09Programinizda hatali code olabilir, sifir adresine birseyler yazmak NULL pointer kullanimini gosteriyor olabilir. Statik kod inceleyen PC Lint veya benzeri ile kodunuzu analiz ediniz.
Abi sıfır adresine bir şeyler yazmıyorum. Neden öyle düşündün? Yanlış anladığım bir şey mi var?
Alıntı yapılan: yldzelektronik - 27 Ekim 2019, 17:22:14Abi sıfır adresine bir şeyler yazmıyorum. Neden öyle düşündün? Yanlış anladığım bir şey mi var?
Kullandiginiz bir pointer programlama hatasi yada hata kontrolunun eksikliginden dolayi NULL kaliyor olabilir.
Pc-lint gibi statik analyzer programlari bu cesit problemleri ortaya cikarabilir.
Bu programın indirme linkini bir türlü bulamıyorum. Ben mi kaçırıyorum acaba?
Alıntı yapılan: yldzelektronik - 28 Ekim 2019, 15:38:09Bu programın indirme linkini bir türlü bulamıyorum. Ben mi kaçırıyorum acaba?
Asagidaki linkdeki formu doldur, evaluation version indirme linkini yollasinlar.
evaluate PC-Lint Plus (https://www.gimpel.com/evaluate.html)
Bu arada map dosyasina bakiver senin frame buffer in disinda bu alani kullanan var mi diye. ::ok
Alıntı yapılan: OptimusPrime - 28 Ekim 2019, 17:29:54Bu arada map dosyasina bakiver senin frame buffer in disinda bu alani kullanan var mi diye. ::ok
Bunu yaptım. Aslında o alanı kullanan hiç kimse yok. Bu da ayrı bir soru işareti. Sanırım 0xC000 0000 adresine erişim sadece DMA2D üzerinden yapılıyor.
Edit:
Alıntı yapılan: mufitsozen - 28 Ekim 2019, 17:06:53Asagidaki linkdeki formu doldur, evaluation version indirme linkini yollasinlar.
evaluate PC-Lint Plus (https://www.gimpel.com/evaluate.html)
Bunu da yaptım.
Sen bu ram testini yaparken ne flush cache diyorsun nede invalidate cache diyorsun. Emin misin bu datanin ram a yazildigindan? Ram bolgesi icin cache kapali mi?
Veya sadece deneme amacli cache contoller a, 0xC000 0000 (sanirim frame buffer bu adreste ikamet ediyor :) ) adresi dahil olmak uzere frame buffer boyunca cache islemi yapma de.
Veya programin en basinda cache controller i kapat gitsin. Bakalim ne degisecek.
Alıntı yapılan: OptimusPrime - 28 Ekim 2019, 22:07:07Sen bu ram testini yaparken ne flush cache diyorsun nede invalidate cache diyorsun. Emin misin bu datanin ram a yazildigindan? Ram bolgesi icin cache kapali mi?
Hocam bu testi yaparken/bu olayı yaşarken durum şöyle;
/* USER CODE BEGIN 2 */
MPU_Region_InitTypeDef MPU_InitStruct;
/* Configure unused area of QSPI region as strongly ordered.
* This is *important* to avoid unintentional fetches from illegal
* addresses due to cache/speculation which would halt the MCU.
*/
HAL_MPU_Disable();
/* Enable D-cache on SDRAM (Write-through) */
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
SCB_InvalidateICache();
/* Enable branch prediction */
SCB->CCR |= (1 << 18);
__DSB();
SCB_InvalidateICache();
SCB_EnableICache();
SCB_InvalidateDCache();
SCB_EnableDCache();
/* USER CODE END 2 */
/* Initialise the graphical hardware */
GRAPHICS_HW_Init();
/* Initialise the graphical stack engine */
GRAPHICS_Init();
Sdram icin cache acik gorunuyor. Disable edip tekrar dene derim. Disable ettiginde eger hala garip pixeller gorunuyorsa bu sekilde birde ram testi yap derim. Eger gorunmuyorsa DMA ile cache senkronizasyonunu bir yerlerde atliyorsun demektir. Bu teorim yanlis da olabilir. Fakat denemekte fayda var. ::ok
Birde sistem nasil calisiyor (ozelliklede DMA olan kismi) bunu da anlativer :) Kullanici seviyesinden frame buffera resim nasil tasiyorsun onu merak ediyorum. ::)
Denediğim senaryolar şöyle;
Chache kapalı, mpu kapalı, temizlik yapmıyorum sorun var, yapıyorum sorun yok.
Chache açık, mpu kapalı, temizlik yapmıyorum sorun var, yapıyorum sorun yok.
Chache kapalı, mpu açık, temizlik yapmıyorum sorun var, yapıyorum sorun yok.
Chache açık, mpu açık, temizlik yapmıyorum sorun var, yapıyorum sorun yok.
RAM testi yaptığımda chache ve mpu kapalı.
DMA erişimi kısmı biraz kapalı. TouchGFX kendi hallediyor onu. Ama elle erişmek istersen, önce bir framebuffer alanı belirleyip, o alanı dma2d ye göstermen ve taşıma işlemini elle başlatmak zorundasın.
Hicbir sey degismiyor kisaca :du:
Cache kapatilinca en azindan sistemde yavaslama olmali bunu gozlemleyebiliyor musun?
Su temizlikle ilgili kodu da eklersen bakalim.
Olmadi bi hocaya okutturacaz gibi duruyor :D
Alıntı yapılan: yldzelektronik - 27 Ekim 2019, 12:31:51Evet. Genelde benim işlerde bu tip şeyler bolca oluyor ;D ;D Aşağıdaki konudan bahsediyorsan;
Evet. Bu iş için bir test programı var ve buradan gerçekten sağ salim çıktı.
uint32_t memTestDataBus(volatile uint32_t * address)
{
uint32_t pattern;
/* Perform a walking 1's test at the given address. */
for (pattern = 1; pattern != 0; pattern <<= 1)
{
/* Write the test pattern. */
*address = pattern;
/* Read it back (immediately is okay for this test). */
if (*address != pattern)
{
return (pattern);
}
}
return (0);
}
//
uint32_t *memTestAddressBus(volatile uint32_t * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long testOffset;
unsigned long addressMask = (nBytes / sizeof(datum) - 1);
datum pattern = (uint32_t ) 0xAAAAAAAA;
datum antipattern = (uint32_t ) 0x55555555;
/* Write the default pattern at each of the power-of-two offsets. */
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
baseAddress[offset] = pattern;
}
/* Check for address bits stuck high. */
testOffset = 0;
baseAddress[testOffset] = antipattern;
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if (baseAddress[offset] != pattern)
{
return ((datum *) &baseAddress[offset]);
}
}
baseAddress[testOffset] = pattern;
/* Check for address bits stuck low or shorted. */
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
{
baseAddress[testOffset] = antipattern;
if (baseAddress[0] != pattern)
{
return ((datum *) &baseAddress[testOffset]);
}
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if ((baseAddress[offset] != pattern) && (offset != testOffset))
{
return ((datum *) &baseAddress[testOffset]);
}
}
baseAddress[testOffset] = pattern;
}
return (NULL);
}
//
uint32_t *memTestDevice(volatile uint32_t * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long nWords = nBytes / sizeof(datum);
uint32_t pattern;
uint32_t antipattern;
/* Fill memory with a known pattern. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
baseAddress[offset] = pattern;
}
/* Check each location and invert it for the second pass. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
if (baseAddress[offset] != pattern)
{
return ((uint32_t *) &baseAddress[offset]);
}
antipattern = ~pattern;
baseAddress[offset] = antipattern;
}
/* Check each location for the inverted pattern and zero it. */
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
antipattern = ~pattern;
if (baseAddress[offset] != antipattern)
{
return ((uint32_t *) &baseAddress[offset]);
}
}
return (NULL);
}
//
Diğer taraftan;
Ben öyle bir tanımlama yapmadım. Bu alan harici ramde. Yani derleyicinin oraya bir şey koyacağını pek zannetmiyorum. Nasıl diyeceğim derleyiciye karışma bu alana?
Konu SDRAM timing ile ilgili olabilir mi?
Test kodu burada.
Cinli minli işler hep beni bulur da, onların pek bu tür şeyleri sevdiğini sanmıyorum. Bu işin içinde bir bit yeniği var gibi. Ama hocaya da hayır demem hani :) :)
Ekleme: Yavaşlama derken? Zaten durağan bir ekran var. Performans takibi yapmadım açıkçası. Bence benim kodlarda bir yerde bir hata var. Ama şöyle tuhaf bir durum var. Bütün işi zaten TouchGFX yapıyor.
Galiba benim bootloader ile ilgili bir durum var.
:du:
Su temizlik yapiyorum soyle oluyor, yapmiyorum boyle oluyor dedigin kodlari sanirim acip kapatiyorsun. O kismi kopyalar misin? Gidisatta nasil bir degisiklik oluyor bide ona bakalim.
Sdram ve cache ile ilgili suphelerim vardi ama anlattiklarina gore bunlarda da sorun yok gibi.
Bu arada TouchGFX ne isler ceviriyor bilemiyorum. Hic kullanmadim. TouchGFX ile ekranda nesneleri olustururken nesneleri birbirine bagliyor musun? Veya gorunen nesneleri TouchGFX de nasil tanimliyorsun?