MementoMori 4 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 2 minutes ago, aaarrr said: Можно вывести на пин частоту после делителя А что вы хотите вывести? Тактирование FMC? Самое близкое к нему, что выводится на MCO, это PLLCLK. После него до FMC всего два делителя. Логика понятна, но у меня есть функция HAL_Delay - она выдает правильные задержки, пропорциональные SYSCLK. Так что тут все ровно. ЕДинственное - что - посмотрите на тактирование Я не могу сделать по человечески - поделить HSE на 25 и дальше плясать от 1 МГЦ - у меня в этом случае почему-то не заводится пиксельклок, хотя куб показывает допустимые значения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба На MCO2 можно SYSCLK вывести. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 2 minutes ago, aaarrr said: На MCO2 можно SYSCLK вывести. Куб ругается, если она меньше 25 МГЦ. У меня идея..... сейчас приду... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба Я поделил SYSCLK на 512, должен был получить HLCK 0.39 МГЦ Но на SD_CLK получил такую осциллограмму Этим осциллографом, в силу его примитивности, я ловлю максимум 100 кГц. Более высокие частоты у меня просто сглаживаются в линию на уровне 2-2.5 вольт. Но, судя по картинке, его пропускной способности хватает, и сигнал именно 15 кГц, Это показывает счетчик, и измерение ручками по 10 импульсам. Частота клока на SDRAM - 15,6 КГц. То есть, когда я ее не делю - она по факту 8 МГц. (У меня уже мозги плывут, вчера до 3 ночи сидел, и сегодня весь день. Не исключаю, что мог элементарно ошибиться) А должна быть равна HCLK/2, так ведь? Что посоветуете сделать, чтобы понять, кто своровал мегагерцы? Повторюсь, программный код до включения деления на 512 выдавал правильные задержки через функцию HAL_Delay. То есть в SYSCLK и в HCLK я могу быть уверен, а вот что происходит дальше по цепочке.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба Тихо сам с собою... Прочитал отладчиком состояние регистра FMC SDCR1 - получил 2, что соответствует HCLK/2. А вот в SDCR2 - 0 - отключено. У меня задействован SDRAM_bank2, то есть SDCKE1 и SDNE1. То есть у меня тактирование отключено? А откуда тогда клок на SDRAM? Сначала я решил что в коде от куба ошибка - SDCLockPeriod для банка 2 в нем неправильно настраивается. В даташите написано SDCLK[1:0]: SDRAM clock configuration These bits define the SDRAM clock period for both SDRAM banks and allow disabling the clock before changing the frequency. In this case the SDRAM must be re-initialized. Это как понимать? То есть SDCLK для банка 2 устанавливать не нужно - он один общий и читается из регистра настройки первого банка что ли? Судя по коду так и есть else /* FMC_Bank2_SDRAM */ { tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; /* Clear SDCLK, RBURST, and RPIPE bits */ tmpr1 &= ((uint32_t)~(FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); tmpr1 |= (uint32_t)(Init->SDClockPeriod |\ Init->ReadBurst |\ Init->ReadPipeDelay); tmpr2 = Device->SDCR[FMC_SDRAM_BANK2]; /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ tmpr2 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); tmpr2 |= (uint32_t)(Init->ColumnBitsNumber |\ Init->RowBitsNumber |\ Init->MemoryDataWidth |\ Init->InternalBankNumber |\ Init->CASLatency |\ Init->WriteProtection ); Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; Device->SDCR[FMC_SDRAM_BANK2] = tmpr2; } Да и попытка при отладке в Кейле изменить SDCLK банка в регистре FMC SDCR2 ни к чему не приводит... Я перенастроил SDRAM на банк 1, проверил клок - он все также при делении на 512 равен 15 кГц. А что еще тогда в FMC отвечает за тактирование SDRAM? Я не нашел ничего.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба Стадия RTFM в полный рост настала, кмк, уже когда до 3 ночи возился ;-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба Just now, Obam said: Стадия RTFM в полный рост настала, кмк, уже когда до 3 ночи возился ;-) Когда начинаешь понимать, где загвоздка, RTFM - весьма приятное занятие. Но вчера бы мне это не помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба ...... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба Проверяйте тактирование с самого начала. Только не по картинкам, а по коду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба Начну для начала с картинки для наглядности Вот как это выглядит в коде RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /** 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_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLN = 400; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 2; 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(); } Хочу я к примеру, понять - соответствует ли HCLK истинному. От него тактируется FMC и core. Поскольку HAL_Delay(1000) дает правильную задержку в 1 секунду, считаю, что ядро тактируется правильно. Смущает только то, что если настроить HCLK на 100 МГц, то библиотека не пересчитывает это и имею задержку в 2 секунды. От 200 МГц core тактируется правильно. Но вот SDRAM_CLK, который настроен на половину HCLK, получается меньше 10 МГц. Захожу с другой стороны. Настраиваю таймер TIM4. Он тактируется от APB1, 100МГц. Настраиваю его переполнение на 100 мсек htim4.Instance = TIM4; htim4.Init.Prescaler = 10000; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 1000; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim4) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } Я правильно указал Prescaler и Period? Тогда должно быть 100000000/10000/1000 = 10 переполнений в секунду. А по факту - переполнение ровно за 5 секунд. Как бы APB1 не имеет никакого отношения к FMC, но сам факт неправильной работы таймера беспокоит. В чем подвох? Чем еще можно проверить HCLK? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 5 hours ago, MementoMori said: Вот как это выглядит в коде Это не код, а заполнение портянок HAL'а. Почему бы не попробовать сделать то же самое руками, самым простым способом: //************************************** //* CLK //* //* SYSCLK = 200MHz (over-drive) //* AHB = 200MHz, APB2 = 100MHz, APB1 = 50MHz //* #define HSE_CLK_MHZ 25 static void clk_setup(void) { /* Enable ART accelerator, Prefetch Buffer and set Flash Latency */ FLASH->ACR = FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_7WS; /* Enable HSE */ RCC->CR |= RCC_CR_HSEON; while(!(RCC->CR & RCC_CR_HSERDY)); /* SYSCLK = HSE * AHB = SYSCLK * APB1 = AHB / 4 * APB2 = AHB / 2 * RTC = HSE / HSE_CLK_MHZ = 1MHz * MCO2 = SYSCLK / 4 */ RCC->CFGR = RCC_CFGR_MCO2PRE_2 | RCC_CFGR_MCO2PRE_1 | HSE_CLK_MHZ << RCC_CFGR_RTCPRE_Pos | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_HSE; /* PLLM = HSE / HSE_CLK_MHZ = 1MHz * PLLN = 400 * PLLP = 2 (SYSCLK = 400 / 2 = 200MHz) * PLL source = HSE * PLLQ = 8 (PLL48 = 400 / 8 = 50MHz) */ RCC->PLLCFGR = 8 << RCC_PLLCFGR_PLLQ_Pos | RCC_PLLCFGR_PLLSRC_HSE | 400 << RCC_PLLCFGR_PLLN_Pos | HSE_CLK_MHZ; /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Enable over-drive */ PWR->CR1 |= PWR_CR1_ODEN; while(!(PWR->CSR1 & PWR_CSR1_ODRDY)); PWR->CR1 |= PWR_CR1_ODSWEN; while(!(PWR->CSR1 & PWR_CSR1_ODSWRDY)); /* Wait till PLL is ready */ while(!(RCC->CR & RCC_CR_PLLRDY)); /* Select PLL as MCO2 and system clock source */ RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_MCO2_Msk | RCC_CFGR_SW_Msk)) | RCC_CFGR_MCO2_1 | RCC_CFGR_MCO2_0 | RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 27 января, 2020 Опубликовано 27 января, 2020 (изменено) · Жалоба Мысли... процессор уже давно вышел, ошибки в кубовской настойке тактирования для него маловероятны. Топикствртеру предлагаю контролировать правильность настройки ввводом в компорт текста. Изменено 27 января, 2020 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 1 hour ago, GenaSPB said: Топикствртеру предлагаю контролировать правильность настройки ввводом в компорт текста. Не совсем понял, о чем вы... 1 hour ago, GenaSPB said: Мысли... процессор уже давно вышел, ошибки в кубовской настойке тактирования для него маловероятны. Ну тот факт, что если поставить делитель HSE на величину,равную частоте кварца, то какими бы ни были остальные множители, ltdc clock перестает работать (то ли не генерируется, то ли частота не подходящая)уже говорит о том что ошибки есть. Лично я в прошлом году нашел ошибку в одной из версий, благодаря которой не настраивались cs на qspi, написал в ST, думал, что я дурак, а они ответили, мол, ошибка, исправим Но с вами согласен, такая вещь, как тактирование - давно бы уже нашли ошибку, если б она там была. Лично мне кажется подозрительно странным соотношение должной частоты клока (100 мгц) и реальной (8 мгц). Это как 200 и 16 и напоминает ситуацию, когда срабатывает CSS. Вернусь домой и если код, предложенный выше, не сработает, то попробую посмотреть на прерывания от css. Еще есть мысль - оказывается tim11 можно подключить к HSE в режиме input capture. То есть хотя бы это звено проверить. И кстати... я изначально видел проблему так - проект куба под дискавери и touchgfx работает из коробки, куб сам настраивает периферию, узнав что у меня дискавери, мой же проект, сделанный ручками, не работает. И я потратил уйму времени, пытаясь найти разницу между двумя проектами. По факту же, на дискавери, на настройках, предлагаемых кубом, та же самая проблема. Там скорость SDRAM еще меньше. Но на разрешении 480х272 и пиксельклоке 9.6 мгц, проблем с буфером не возникает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 52 minutes ago, MementoMori said: И я потратил уйму времени, пытаясь найти разницу между двумя проектами. Есть простое решение, нужно снять дамп регистров периферии после всех операций инициализации. Для этого пригодится макрос преобразования имени переменной в строку. Просто печать в отладку, с сохранением в файл, и уже потом проверка. Решение не годится для поиска различий в реализации алгоритмов, но позволяет выявить место косяка, что значительно сокращает время на решение проблемы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 5 hours ago, aaarrr said: Это не код, а заполнение портянок HAL'а. Почему бы не попробовать сделать то же самое руками, самым простым способом: Не знаю даже что и сказать. Ваш код виснет на последней строке приведенного ниже фрагмента /* Enable HSE */ RCC->CR |= RCC_CR_HSEON; while(!(RCC->CR & RCC_CR_HSERDY)); Наверное все-таки мое предположение верно - не работает HSE, система переключается на HSI 16 МГц- как раз получающиеся частоты этому и соответствуют: 1. SDRAM - HCLK/2 =16/2=8 МГц 2. В 12,5 раз медленнее работает таймер 3. Systick выдает правильные интервалы. Осталось проверить, так ли это... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться