Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F745 FMC + LCD 16-bit i8080 mode
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Мусатов Константин
Условия:
Плата с STM32F745VET (100 pin)
Схема спроектирована с помощью CubeMX и им же сделан базовый код.

Проблема:
Не работает дисплей

Анализ:
Исследования с помощью многоканального осциллоскопа показало белиберду в управляющих сигналах.

Безуспешные попытки:
Пробовал изменять режимы работы FMC, тайминги, настройки. Ничего принципиально не помогает. Если код исполнять пошагово, то работает, если непрерывно - не работает. Промежуточным решением оказалось вставить после каждого обращения к LCD задержку на 400-500 нс. Но скорость записи сильно страдает.

Решение:
Похоже, в FMC, в отличие от FSMC есть логика кеширования. Запись в дисплей ведется по двум адресам ((__IO uint16_t*)0x60000000) и ((__IO uint16_t*)0x60020000). Данные потоком пишутся по второму адресу и FMC начинает пропускать циклы записи, оставляя последний. Отключение FIFO не помогает. Решением оказалось инкрементирование адреса в рамках до A16, которым проводится разделение команда-данные.
Код
void LCD_CMD( uint16_t cmd )
{
  static volatile uint16_t *Cmd = ((__IO uint16_t*)0x60000000);
  *(Cmd++) = cmd;
  if( Cmd >= ((__IO uint16_t*)0x6000FFF) ) Cmd = ((__IO uint16_t*)0x60000000);
}
void LCD_DATA( uint16_t data )
{
  static volatile uint16_t *Data = ((__IO uint16_t*)0x60020000);
  *(Data++) = data;
  if( Data >= ((__IO uint16_t*)0x6002FFFF)) Data = ((__IO uint16_t*)0x60020000);
}

Так все заработало
VladislavS
Оно? STM32H743II FMC + 8080 LCD spurious writes
__inline__
Цитата(Мусатов Константин @ Jul 6 2018, 11:45) *
Условия:
Плата с STM32F745VET (100 pin)
Схема спроектирована с помощью CubeMX и им же сделан базовый код.

Проблема:
Не работает дисплей

Анализ:
Исследования с помощью многоканального осциллоскопа показало белиберду в управляющих сигналах.

Безуспешные попытки:
Пробовал изменять режимы работы FMC, тайминги, настройки. Ничего принципиально не помогает. Если код исполнять пошагово, то работает, если непрерывно - не работает. Промежуточным решением оказалось вставить после каждого обращения к LCD задержку на 400-500 нс. Но скорость записи сильно страдает.


Всё прям как у меня sm.gif

После инита FMC сделать:
Код
HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM);


и обращаться к дисплею по адресам 0xC0000000 и 0xC0020000.


AlanDrakes
О, снова знакомая тема вылезла.
Где-то ранее я уже с этми же бился и даже победил.

И ровно та же ситуация. Ремаппинг памяти и ВСЕ проблемы сразу же ушли.
Мусатов Константин
Спасибо про ремапинг. Но вот и еще один вариант sm.gif
k155la3
Вот и вопрос к STM, почему бы в очередной редакции мануала не давать контекстно ссылки на пункты errata и appnotes-заплаты.
Хотя их консультанты, очевидно, получают премии за кол-во запросов-ответов по e-mail.
sm.gif
__inline__
Цитата(k155la3 @ Jul 6 2018, 19:18) *
Вот и вопрос к STM, почему бы в очередной редакции мануала не давать контекстно ссылки на пункты errata и appnotes-заплаты.
Хотя их консультанты, очевидно, получают премии за кол-во запросов-ответов по e-mail.
sm.gif


Сейчас набегут гуру ядра ARM-а и закидают шапками, что мол надо спецификации на Cortex-M7 ядро почитать, так как эта фишка (разграничение регионов адресов на "Device" и "Memory") заложена в самом ядре и К ЭТОМУ НАДО БЫЛО УЖЕ БЫТЬ ГОТОВЫМ! Так что это не глюк, а просто дефолтная установка.

Попробую MPU настроить чтобы всё-же классический адрес 0x60000000 работал как "Device" (отключить кеширование этой области, возможно отключить буферизацию и включить shareable).

А вот в AT91RM9200 был полноценный MMU - с поддержкой виртуальных адресов. А в STM32H7 нет, и это меня огорчает. Свершилась бы мечта идиота программиста - фрагментированную на куски SRAM сделать одним непрерывным большим массивом данных sm.gif А так прийдётся писать нечто вроде:

Код
u16 VideoBuffer[n] __attribute__((at(0x20000000)));
u8 SoundBuffer[n] __attribute__((at(0x24000000)));

sm.gif
jcxz
Цитата(__inline__ @ Jul 7 2018, 07:16) *
А вот в AT91RM9200 был полноценный MMU - с поддержкой виртуальных адресов. А в STM32H7 нет, и это меня огорчает.

Если бы у бабушки был @#$, то она была бы дедушкой © наше всё
Может в M8 и станет, а? rolleyes.gif
__inline__
Цитата(jcxz @ Jul 7 2018, 07:28) *
Если бы у бабушки был @#$, то она была бы дедушкой © наше всё
Может в M8 и станет, а? rolleyes.gif

А я и не жду sm.gif ждать - это вообще очень дорогое для меня удовольствие... Потому что время. Поэтому стараемся использовать всё что есть и выкручиваться.

А вот в -A7, -A8 лучше не лезть. Пускай они для линуксоидов, андроидов, питонов и прочей нечистиsm.gif
jcxz
Цитата(__inline__ @ Jul 7 2018, 09:50) *
А вот в -A7, -A8 лучше не лезть. Пускай они для линуксоидов, андроидов, питонов и прочей нечистиsm.gif

Почему?
__inline__
Цитата(jcxz @ Jul 7 2018, 07:51) *
Почему?

1) нет внятных доков по его программированию. Хотя бы на уровне reference manual-ов как у STM

2) нет практических примеров использования (на уровне микроконтроллеров)

3) Application-ориентирование, а не Microcontroller. Это значит - Only for Linux, Only for Android, under Linux, Under Android.

4) Слишком сложное внутреннее устройство (без 1) -реверс черного ящика). В Linux BSP освещены не все моменты. Хотя бы банально - работы с TCON0 через i8080 bus я не нашёл. В частности, как расставлять времянки по сигналам D, A, CS, WR, RD, WAIT.

Цитата(__inline__ @ Jul 7 2018, 05:16) *
Попробую MPU настроить чтобы всё-же классический адрес 0x60000000 работал как "Device" (отключить кеширование этой области, возможно отключить буферизацию и включить shareable).


Всё мощно! rolleyes.gif

Получилось работать с FMC + LCD и через адреса с 0x60000000. С помощью MPU запрещаем кеширование данного адресного региона и работаем:
Код
static void MPU_Conf(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
HAL_MPU_Disable();
MPU_InitStruct.Enable=MPU_REGION_ENABLE;

MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB; //256KB если линия A16 и 16-битная шина данных. 128KB если линия A16 и 8-битная шина данных

MPU_InitStruct.AccessPermission=MPU_REGION_FULL_ACCESS;

MPU_InitStruct.TypeExtField=MPU_TEX_LEVEL0;
MPU_InitStruct.IsCacheable=MPU_ACCESS_NOT_CACHEABLE; //для портов ввода-вывода обязательно!
MPU_InitStruct.IsBufferable=MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsShareable=MPU_ACCESS_SHAREABLE;

MPU_InitStruct.Number=MPU_REGION_NUMBER0;
MPU_InitStruct.SubRegionDisable=0x00;
MPU_InitStruct.DisableExec=MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);

HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

int main(void)
{
MPU_Conf();

SCB_EnableICache();
SCB_EnableDCache();

HAL_Init();
..................


Убрать HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM); , если оно было.
И использовать:
Код
#define LCD_COM16 (*(volatile unsigned short int*) 0x60000000)
#define LCD_DAT16 (*(volatile unsigned short int*) 0x60020000)


У меня работает через DMA и через CPU.

Единственно, остался невыясненным момент в этих вещах:
Код
MPU_InitStruct.IsBufferable=MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsShareable=MPU_ACCESS_SHAREABLE;


Какие бы не ставил значения - все 4 комбинации работают. И прироста/замедления в скорости не заметил.
Играют ли они роль в контексте LCD по FMC или нет?

Ещё по DMA бурстам вопрос.
hdma_memtomem_dma1_stream0.Init.MemBurst = DMA_MBURST_SINGLE; //DMA_MBURST_INC4;
hdma_memtomem_dma1_stream0.Init.PeriphBurst = DMA_PBURST_SINGLE; //DMA_PBURST_INC4;

SINGLE и INC4 работает DMA + FMC LCD. С бурстами INC8, INC16 - нет. Почему?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.