|
STM32H743. Тайминги FMC, Тактирование FMC |
|
|
|
Jul 21 2018, 13:42
|

Местный
  
Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126

|
Обнаружил интересную проблему и способ её решения. Отладочная плата Nucleo-H743. Процессор STM32H743. Частота ядра 400 МГц. Частота шины FMC выставлена 200 МГц (максимум). Тактирование заведено от HCLK3. На FMC висит дисплей с настроенными времянками. Инит дисплея проходит успешно, его ID производителя успешно определяется. Далее в дисплей начинаю сыпать, сыпать, сыпать данные.... Через DMA. Только данные. Ножка A16 всегда =1 при этом. Возникает проблема: дисплей перестаёт отображать данные. Либо он "зависает" (картинка не обновляется), либо он уходит в стэндбай - и весь экран становится белым. При этом процессор и остальная периферия работают. И с каждым сбросом CPU проблема повторяется. Но стоило выбрать другой источник тактирования FMC - PLL1Q, а частоту тактирования FMC сделать в 2 раза ниже: 100 МГц, дисплей работает как часы и передача данных не срывается. Времянки при этом перерасчитаны (тоесть в масштабах времени они одинаковы, меняется число клоков) - использую Mode A - там только Address Setup и Data Setup. Пробовал сильно укорачивать времянки - всёравно работает. Картинка не перекручивается - пиксели не пропускаются, и нужного цвета. Но стоит поднять частоту FMC чуть выше 100 МГц, то проблема снова появляется, даже если времянки поставить очень длинные. Я вот о чем подумал - в Mode A у FMC есть "хвостик" после Data Setup - его длина ВСЕГДА ФИКСИРОВАНА и равна 1 такту шины FMC. Картинка ниже. Вопрос вот в чём, насколько существенна длительность этого "хвоста" для работы с периферией на FMC? Ведь по сути нет никаких способов влиять программно на этот "хвост", кроме как занижать частоту FMC. А значит стабильную работу с данным LCD можно получить только, выставив минимально допустимую длину "хвоста", понизив частоту FMC и выставив остальные параметры времянок. Пробовал другие дисплеи(модели другие!) подключать, таких проблем не было. Только один конкретный дисплей так ведёт себя. В чем может быть ещё проблема? Дисплеи на "макаронах" до 10 см., это не критично для обмена на частоте данных 20-30 МГц.
Сообщение отредактировал __inline__ - Jul 22 2018, 02:32
|
|
|
|
|
 |
Ответов
|
Jul 23 2018, 11:04
|

Местный
  
Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126

|
Цитата(mantech @ Jul 23 2018, 11:18)  Сорри за оффтоп, с оллвиннером уже наигрались, раз на стм перешли? Что не понравилось? Олвиннер пока отложил временно, не успеваю. Но один момент успел не понравиться. Я раскопал это в Linux BSP. Работа с TCON в режиме i8080: Код s32 tcon0_cpu_wr_24b_data(u32 sel, u32 data) { u32 count = 0; while((tcon0_cpu_busy(sel)) && (count < 50)) { count ++; disp_delay_us(100); } lcd_dev[sel]->tcon0_cpu_ctl.bits.ca = 1; //tcon0_cpu_if_reg_t lcd_dev[sel]->tcon0_cpu_wr.bits.data_wr = data; //tcon0_cpu_wr_reg_t return 0; } Видите костыль? Вот он: Цитата u32 count = 0; while((tcon0_cpu_busy(sel)) && (count < 50)) { count ++; disp_delay_us(100); Меня как аппаратчика, разочаровывают эти строки. Пока временно отложил. Ну и в связи с последними событиями - появление STM на 400 МГц занялся пока изучением Cortex-M7.
|
|
|
|
|
Jul 23 2018, 11:31
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(__inline__ @ Jul 23 2018, 14:04)  Пока временно отложил. Ну и в связи с последними событиями - появление STM на 400 МГц занялся пока изучением Cortex-M7. Понятно, жаль, думал, может УСБшку вскладчину подняли бы, одному как-то тяжко с ней Меня б 400МГц тоже устроили бы, но СДРАМ и только внешняя - это уже прошлый век, для дисплейчиков 320х240 или чуть выше может оно и нормально, но для хороших разрешений совсем не айс  Цитата(__inline__ @ Jul 23 2018, 14:04)  Но один момент успел не понравиться. Я раскопал это в Linux BSP. Работа с TCON в режиме i8080: Дак это можно понять - этот режим у них очень опциональный и скорее всего никто его не использовал...
Сообщение отредактировал mantech - Jul 23 2018, 11:33
|
|
|
|
|
Jul 23 2018, 14:12
|

Местный
  
Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126

|
Цитата(mantech @ Jul 23 2018, 12:31)  Понятно, жаль, думал, может УСБшку вскладчину подняли бы, одному как-то тяжко с ней  Скажу по секрету, с USB на микроконтроллерах никогда не работал. Только на компе и только через FT232/245. Цитата(mantech @ Jul 23 2018, 12:31)  Меня б 400МГц тоже устроили бы, но СДРАМ и только внешняя - это уже прошлый век, для дисплейчиков 320х240 или чуть выше может оно и нормально, но для хороших разрешений совсем не айс  C v3s вопрос о памяти снимается автоматически - 64 biultin  А на отладках с A13 что есть там уже напаяна DDR. (Olinuxino и SOM) Цитата(mantech @ Jul 23 2018, 12:31)  Дак это можно понять - этот режим у них очень опциональный и скорее всего никто его не использовал... На счёт дисплеев. Пересмотрел все даташиты все LCD, которые использовал и оказалось, что у них всех HOLD после DATA SETUP от 0 до 7 нс. Становится понятным, почему ранее при подключении их к FMC проблем не было. Попался дисплей с обалденно хорошим качеством картинки с SE K800i оригинал (контроллер Toshiba). Но у него HOLD от 15 нс, что нереализуемо на частотах FMC выше 66 Мгц. Пришлось FMC в режим NAND загонять, чтобы выставить нужный HOLD без снижения тактовой частоты FMC (иначе остальные времянки прийдётся загрублять в большую сторону). Но до того как это понял и докопаться до сути - понаставил костыли: 1) Резистор около 2 кОм на !CS 2) Постоянно посыл команды Write Data , перед отправкой фреймбуфера 3) Костыль в алгоритме инициализации Теперь все костыли ушли в небытиё! Дисплей стабильно работает и рисует непрерывно кадр через DMA бе опорных команд (позиция по X,Y; write data) и ничего не съезжает. FMC в режиме NAND рулит! Правда, на смежном форуме меня пытались убедить, что через NAND мол, можно к дисплею обращаться как к массиву. Но в STM32 адрес NAND Flash задаётся через запись в регистр, также как и данные. Так что смещения относительно базового адреса NAND не вышло. А было бы очень изящно: все регистры дисплея - элементы массива(или структуры), вместо раздельных посылок: адреса и данных.
|
|
|
|
|
Jul 23 2018, 17:16
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(__inline__ @ Jul 23 2018, 20:12)  Правда, на смежном форуме меня пытались убедить, что через NAND мол, можно к дисплею обращаться как к массиву. Я и здесь могу это повторить - можно и нужно. Более того - код будет более простым и нативным по сравнению с явным указанием адреса команд и данных. Обращаться к области памяти как к массиву, да почти так. Без адреса, через имя структуры, и линейно от начала до конца окна. Дело в том что у всех дисплеев счётчик адреса данных щёлкает автоматически с каждым чтением/записи данных. А для новых дисплеев это свойство распространяется на всю периферию (наверное забыли отключить).
|
|
|
|
|
Jul 24 2018, 01:40
|

Местный
  
Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126

|
Цитата(AVI-crak @ Jul 23 2018, 17:16)  Я и здесь могу это повторить - можно и нужно. Более того - код будет более простым и нативным по сравнению с явным указанием адреса команд и данных. Обращаться к области памяти как к массиву, да почти так. Без адреса, через имя структуры, и линейно от начала до конца окна. Дело в том что у всех дисплеев счётчик адреса данных щёлкает автоматически с каждым чтением/записи данных. А для новых дисплеев это свойство распространяется на всю периферию (наверное забыли отключить). Ой, да ладно!  Мечтать оно не вредно, но реалии намного скромнее. В HAL идёт обращение к NAND как к регистрам: выставляем байты адреса(Addr section), байт команды(Cmd section), затем только читем/пишем(Data section). Нет тут обращения как к массиву даже и близко: Код HAL_NAND_Read_Page_8b(...) { //........
//Записывается адрес в несколько байт *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00; __DSB(); *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress); __DSB(); *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress); __DSB();
//далее ждем.......
//Read Page CMD *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U); __DSB();
//Читаем данные for(; index < size; index++) { *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress; }
//.............. } У меня делается обращение к дисплею всего 2 записями (CMD_AREA - это A16. =0 - регистр, =1 - данные.): Код *(__IO uint16_t *)((uint32_t)(deviceAddress )) = ((uint16_t)LCD_REGISTER_N); *(__IO uint16_t *)((uint32_t)(deviceAddress| CMD_AREA )) = ((uint16_t)LCD_DATA); Принцип тот же. А вы предлагаете сделать так (полагая, что если записать смещение в адрес, то оно упадёт на шину): Код *(__IO uint16_t *)((uint32_t)(deviceAddress | ADDR_AREA | LCD_REGISTER_N)) = ((uint16_t)LCD_DATA); Но этого не будет. Потому что либо товарищ AVI-crak никогда не работал с FMC в режиме NAND, либо он - циничный тролль и издевается надо мной. В мануале на H743 чётко прописан алгоритм взаимодействия FMC c NAND-flash. Что адрес выставляется записью значения в регистр, а не идёт в смещение относительно базы:
AVI-crak, Вы бы Бога побоялись что-ли... Ну нельзя ж так издеваться!  И перестаньте вводить в заблуждение!
Сообщение отредактировал __inline__ - Jul 24 2018, 01:50
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|