Перейти к содержанию
    

STM32F745 FMC + LCD 16-bit i8080 mode

Условия:

Плата с 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);
}

Так все заработало

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Условия:

Плата с STM32F745VET (100 pin)

Схема спроектирована с помощью CubeMX и им же сделан базовый код.

 

Проблема:

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

 

Анализ:

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

 

Безуспешные попытки:

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

 

Всё прям как у меня :)

 

После инита FMC сделать:

HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM);

 

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

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

О, снова знакомая тема вылезла.

Где-то ранее я уже с этми же бился и даже победил.

 

И ровно та же ситуация. Ремаппинг памяти и ВСЕ проблемы сразу же ушли.

Изменено пользователем AlanDrakes

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот и вопрос к STM, почему бы в очередной редакции мануала не давать контекстно ссылки на пункты errata и appnotes-заплаты.

Хотя их консультанты, очевидно, получают премии за кол-во запросов-ответов по e-mail.

:)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот и вопрос к STM, почему бы в очередной редакции мануала не давать контекстно ссылки на пункты errata и appnotes-заплаты.

Хотя их консультанты, очевидно, получают премии за кол-во запросов-ответов по e-mail.

:)

 

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

 

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

 

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

 

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

:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот в AT91RM9200 был полноценный MMU - с поддержкой виртуальных адресов. А в STM32H7 нет, и это меня огорчает.

Если бы у бабушки был @#$, то она была бы дедушкой © наше всё

Может в M8 и станет, а? :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если бы у бабушки был @#$, то она была бы дедушкой © наше всё

Может в M8 и станет, а? :rolleyes:

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

 

А вот в -A7, -A8 лучше не лезть. Пускай они для линуксоидов, андроидов, питонов и прочей нечисти:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот в -A7, -A8 лучше не лезть. Пускай они для линуксоидов, андроидов, питонов и прочей нечисти:)

Почему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему?

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.

 

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

 

Всё мощно! :rolleyes:

 

Получилось работать с 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 - нет. Почему?

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...