Jump to content

    

__inline__

Участник
  • Content Count

    791
  • Joined

Everything posted by __inline__


  1. Сейчас набегут гуру ядра 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))); :)
  2. STM342F4 и FSMC

    2 байта на пиксел. 16bpp. 320x240x2=150 кБ два буфера - уже 300 кБ < 192 кБ в stm32f407 :biggrin:
  3. Всё прям как у меня :) После инита FMC сделать: HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM); и обращаться к дисплею по адресам 0xC0000000 и 0xC0020000.
  4. Это просто капец... Эта память жестко специализирована: DTCM - может быть стеком, данными и DMA AXI - тоже самое SRAM1,2,3 - только данными. Никакого ДМА и стека SRAM4 - данные, стек. Никакого ДМА Итого: DTCM и AXI - универсальная память. SRAM 1..4 - нет
  5. STM342F4 и FSMC

    Там где 24 Гц - это на STM32F407. У него 128+64 кБ памяти, хватает только на один буфер 320x240x2 и то, он реализован кусками! Двойная буферизация в STM32H743. Но там 63 FPS.
  6. Память SRAM1,2,3 сидит в регионах 0x30000000...0x30047FFF. Тактирование включил. При попытке туда записать или считать с помощью CPU ни к чему не приводит. Эта память доступна вообще для процессора или нет? Читал манул, так и не понял.
  7. STM342F4 и FSMC

    24 FPS - это общий FPS: рендеринг картинки в буфер + перекидывание буфера на дисплей, а не чисто-перекидывание на дисплей Если перекидывание буфера на экран через SPI даст 24 FPS, то общий FPS программы упадёт до 10 и меньше.
  8. Как оказалось, что сабжевый вариант вполне работоспособный: компиляция, прошивка -всё работает. Правда дебаг недоступен. В целом девелопать можно. Только при запуске выскакивет такое сообщение (игнорировать):
  9. STM342F4 и FSMC

    Всё просто замечательно! :rolleyes: Подключил дисплей к FMC, настроил времянки. Задействовал кеширование. Вышло 41 FPS. Потом сделал двойную буферизацию, задействовал ДМА память-память. В итоге пока процессор рендерит один кадр, ДМА отправляет на LCD готовый кадр. Путём таких ухищрений удалось выжать 63 FPS. Видео (по сравнению с видео выше с STM32F407, скорость намного выше 63 vs. 24 FPS): http://www.youtube.com/watch?v=4VpX5UfkmWA Исходники для STM32H743 Ниже. Просьба не ругаться(за кало-Куб), нужно было оценить отладочную плату и процессор STM32H743. Tunnel_STM32H743_DMA.rar
  10. STM342F4 и FSMC

    Вопрос по поводу кеша возник не случайно. Так как раньше было отображение регистров периферии в адресное пространство типа "память", то при включенном кеше данных устройство работало некорректно. Сейчас же при отображении регистров устройства в адресное пространство типа "Device" кеш данных не мешает. Вот инфа, которая расставляет все точки над "I": http://microsin.net/programming/arm/an4838...unit-stm32.html http://microsin.net/programming/arm/an4839...he-stm32f7.html И всё-же я помню, что в AT91RM9200 аттрибут в MMU "Buferable" ускорял работу с периферией. А "Cacheable" приводил к артефактам. Есть ли подобное в H743 ? И почему ж никто не подсказал, что для внешних устройств надо было ремэпнуть банки, так как дефолтные установки ставят тип "память", а не "device"? Про адреса явно же писал. не верю, что с FMC никто не работал.
  11. STM342F4 и FSMC

    В данном случае калокуб тут не причем. Подосрала сама STM electronix. Ошибка кривая и аппаратная. Проблему решил, работает по крайней мере на внешней SRAM: https://electronix.ru/forum/index.php?s=&am...t&p=1571320 Сейчас осталось вернуться LCD и раскочегарить 3D-туннель на 400 МГц при включенных кешах. Нужно ли включать кеширование кода и данных, если программа выполняется во встроенной Flash контроллера? Как запретить кешировать регион памяти для LCD, но оставить буферизацию? В AT91RM9200 делал это с помощью MMU, а тут как? P.S. Я - не сторонник кало-куба, пока его использую, так как только начал знакомиться с STM32H743. И очень жаль, что SPL нет, как это было в F407 :( Прийдется распиливать HAL и разбавлять с даташитами :) И почему тогда в сети куча примеров под кало-куб, а на регистрах нет нигде примеров?
  12. Отремапил банки, как там было написано. Заработало!!! :yeah: Теперь уровень логической "1" на линиях данных D0..D7 около 3V, что верно. Подсоединил SRAM на 32 кБ (старшие адреса посадил на GND, младший A0 => на A16 контроллера) , прогнал тест - всё успешно. Причём, если во время работы хотя бы 1 бит отсоединить, то тест проваливается, что логично. Времянки подобрал самые быстрые, при чтении времянка чуть длинее, что логично. Если сделать ещё короче, что ниже, то тест проваливается (что тоже логично). Так что проблема с FMC решена. Но STM подосрала конкретно ))) 2 дня убил. :smile3009: Тестилка SRAM 32 kB UT62256CPC-70LL: #include <stdlib.h> #define LCD_COM8 (*(volatile unsigned char*) 0xC0000000) #define LCD_DAT8 (*(volatile unsigned char*) 0xC0010000) volatile unsigned char t1,t2; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_FMC_Init(); HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM); //=======================> ЭТО ВАЖНО !!! HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET); while(1) { t1=rand(); t2=rand(); LCD_COM8=t1; LCD_DAT8=t2; if((LCD_COM8!=t1)||(LCD_DAT8!=t2)) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); while(1); } } } Настройки времянок (частота FMC и CPU 168 МГц !): /* READ */ Timing.AddressSetupTime =0; //0.. 15 Timing.AddressHoldTime =1; //1.. 15 Timing.DataSetupTime =5; //1..255 Timing.BusTurnAroundDuration=0; //0.. 15 Timing.CLKDivision =2; //2.. 16 Timing.DataLatency =2; //2.. 17 Timing.AccessMode =FMC_ACCESS_MODE_D; /* WRITE */ ExtTiming.AddressSetupTime =0; //0.. 15 ExtTiming.AddressHoldTime =1; //1.. 15 ExtTiming.DataSetupTime =3; //1..255 ExtTiming.BusTurnAroundDuration=0; //0.. 15 ExtTiming.CLKDivision =2; //2.. 16 ExtTiming.DataLatency =2; //2.. 17 ExtTiming.AccessMode =FMC_ACCESS_MODE_D; HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming);
  13. Проблема (возможно и её решение) здесь: https://community.st.com/thread/49249-stm32...spurious-writes
  14. STM342F4 и FSMC

    Обнаружил, что я не одинок, глюк присутствует ещё у одного товарища: https://community.st.com/thread/49249-stm32...spurious-writes Вот первый блин комом как говорится. :santa2:
  15. STM342F4 и FSMC

    Что удалось обнаружить. Напряжение логической "1" на линиях D[0..7] = 0.38V. Логический "0" =0V. На линиях A[0], !RD, !WR, !CS напряжения логической "1" и "0" соответственно 2.8V и 0V -что норма. Теперь стало понятно, почему ID дисплея читался верно - потому что нулевой регистр. Был бы ненулевым, не прочлось бы. На чтение FMC работает. Уровни на линиях D[0..7] распознаются. Теперь осталось понять, почему же уровень напряжения логической "1" на линиях D[0..7] 0.38V, вместо 2...3.2V ...
  16. Эта же программа на STM32F4Discovery (stm32f407) даёт провал теста, если памяти на шине нет. так уж и быть: заволатайлил переменные i,test1, test2. Ничего не изменилось на H743. Попробовал сделать задержку 1 мс и тест стал валиться, что верно, когда SRAM не подключена к FMC. Зато когда подключена, то ни одна из времянок не дала положительного исхода теста - чтение из SRAM происходит некорректно. Я уже начинаю побаиваться: камень свежий вдруг там с FMC напороли глюков? Ну не работает он вообще - с 70-нс SRAM типа UT62256CPC-70LL чтение неверно. Ещё глянул HAL, там зачем-то объявлены функции чтения-записи из внешней памяти. Зачем? Это также глупо, как и писать функцию чтения-записи массива. Главное GPIO работают, прерывание таймера и задержки работают, с FMC не хочет(точнее, не происходит корректное чтение). Сигналы на всех линиях присутствуют (проверял тестером, делая вечный цикл чтения или записи по определенному адресу, взводя по одному биту в данных: 0x01 , 0x02, 4,8,16,32,.. 128)
  17. Пытаюсь завести контроллер внешней шины(FMC) на отладочной плате Nucleo-144 STM32H743. Прицепил SRAM на 32 кБ, адресные биты посадил на GND, кроме самого младшего A0, который заведён на A16 микроконтроллера. Делаю такой нехитрый тест: int main(void) { // SCB_EnableICache(); // SCB_EnableDCache(); HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_FMC_Init(); // __disable_irq(); #define STATUS_REG (*(volatile unsigned char*) 0x60000000) #define DATA_REG (*(volatile unsigned char*) 0x60010000) u8 test1,test2,i=0; while(1) { test1=i*i; test2=(i+25)*(i+25); i++; STATUS_REG=test1; DATA_REG=test2; if((STATUS_REG!=test1)||(DATA_REG!=test2)) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); while(1); } else { HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14); delay_ms(1); } } } Если данные в двух ячейках не совпадают, то светодиод должен потухнуть и в вечный цикл. Если тест ОК, то светодиод быстро мерцает. Так вот, при полностью исключенной SRAM тест успешен! Верны ли вообще адреса для FMC : ? (*(volatile unsigned char*) 0x60000000 и (*(volatile unsigned char*) 0x60010000 ? Складывается впечатление, что там другая периферия. На всякий случай код инита GPIO и FMC (сгенерирован кубом и подправлен): /* FMC initialization function */ void MX_FMC_Init(void) { FMC_NORSRAM_TimingTypeDef Timing; /** Perform the SRAM1 memory initialization sequence */ hsram1.Instance = FMC_NORSRAM_DEVICE; hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE; /* hsram1.Init */ hsram1.Init.NSBank = FMC_NORSRAM_BANK1; hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8; hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE; hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY; hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE; hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE; /* Timing */ Timing.AddressSetupTime = 0; //15; Timing.AddressHoldTime = 0; //15; Timing.DataSetupTime = 6; //255; Timing.BusTurnAroundDuration = 0; //15; Timing.CLKDivision = 0; //16; Timing.DataLatency = 0; //17; Timing.AccessMode = FMC_ACCESS_MODE_A; /* ExtTiming */ if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } static uint32_t FMC_Initialized = 0; static void HAL_FMC_MspInit(void){ /* USER CODE BEGIN FMC_MspInit 0 */ /* USER CODE END FMC_MspInit 0 */ GPIO_InitTypeDef GPIO_InitStruct; if (FMC_Initialized) { return; } FMC_Initialized = 1; /* Peripheral clock enable */ __HAL_RCC_FMC_CLK_ENABLE(); /** FMC GPIO Configuration PE7 ------> FMC_D4 PE8 ------> FMC_D5 PE9 ------> FMC_D6 PE10 ------> FMC_D7 PD11 ------> FMC_A16 PD14 ------> FMC_D0 PD15 ------> FMC_D1 PC7 ------> FMC_NE1 PD0 ------> FMC_D2 PD1 ------> FMC_D3 PD4 ------> FMC_NOE PD5 ------> FMC_NWE */ /* GPIO_InitStruct */ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* GPIO_InitStruct */ GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0 |GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* GPIO_InitStruct */ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF9_FMC; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* USER CODE BEGIN FMC_MspInit 1 */ /* USER CODE END FMC_MspInit 1 */ }
  18. STM342F4 и FSMC

    Обнаружил более глобальную проблему. FMC на отладочной плате Nucleo-H743ZI не работает как надо. Не читаются правильные значения регистров. Вместо дисплея подсоединял другую периферию - тоже не работает. Использую Кало-КУБ + Хал для генерации инит-кода. Вижу в нём настройку GPIO, FSMC и разрешение тактирования на FMC и GPIO. Этого достаточно? Есть ли подводные камни ? Лампочки мигают, кнопки тоже считываются, миллисекундные задержки работают. А FMC с инитом куба -не хочет. Вызванивал все сигналы (зацикливал в программе чтение-запись по адресам, по отдельным битам данных): D0..D7, A16, WR, RD, CS - всё на месте.
  19. STM342F4 и FSMC

    Подключил дисплей к Nucleo-144 STM32H743. Перестал показывать. Чтением регистра возвращается правильный ID, но не инитится. Кеширование кода/данных выключено. Вернул дисплей назад к STM32F4Discovery - всё работает. Обнаружил, что касание ножки ~CS дисплея пинцетом во время работы сносит крышу дисплею. Касание к остальным выводам не ведёт к сбоям. Если притянуть вывод ~CS к минусу через резистор 2 кОм, то касание пинцетом не влияет. Но на STM32H743 дисплей не хочет включаться (нет развёртки, но ID читается верно). Ставил растактовки такиеже при частоте 168 МГц и потом пересчитывал для 400 МГц. Один фиг - дисплей не инитится. Питание на дискавери 2.8V, на нуклее 3.2V. Может из-за этого? Куда копать?
  20. STM342F4 и FSMC

    Дисплей активно работает по FSMC, сбоев не замечено. Накидал программу с 3D графикой. На разогнанном STM32F407 до 252 МГц вышло 24 FPS. Использовал софтварный текстурный мэппер, в SIMD не влазил, только VFP. Вот что вышло: http://www.youtube.com/watch?v=mIBVAke6A80 Исходники приложил ниже: Tunnel.rar В проекте применено копирование в память дисплея с помощью блоков по 128 байт (s0..s31 VFP)
  21. STM342F4 и FSMC

    Разобрался с быстрым копированием по 128 байт за раз: ASM: memcpy128 PROC EXPORT memcpy128 vpush {s16 - s31} ; 17 z vldm.32 r1!, {s0 - s31} ; 33 vstm.32 r0!, {s0 - s31} ; 33 subs.n r2, #1 ; 1 bne.n z ; ~3 (taken) vpop {s16 - s31} ; 17 bx lr ; 1-3?? ENDP C: void memcpy128(void *destination,const void *source,int num); А как подобным образом реализовать заливку константой (memset) блоками выше, чем 4 байта? (какими ассемблерными инструкциями?)
  22. STM342F4 и FSMC

    Скиньте плиз свой инит FSMC, интересно глянуть его на предмет бурстов.
  23. STM342F4 и FSMC

    Ещё проделал эксперимент. Устройство на шине одно, на CS подал логический "0", просто присоединив его к GND. Дисплей не запустился. Выходит, что STM32 на шину FSMC может давать мусор в моменты когда NE(он же и CS) =1 ? Тоесть самодельный дешифратор генерации CS1, CS2.. CSn на несколько устройств не выйдет? Хотел на STM32F407 повешать 2 устройства на FSMC, а тут видать облом - только NE1 есть и всё. Остальные NE2-4 только в BGA :(
  24. STM342F4 и FSMC

    Я так и сделал. Всё работает! Определил шину 8 битовой, но посылаю по 16 бит для команд и и по 32 бит -данные. Вопрос был в том, насколько 16/32 битные пересылки будут быстрее, чем 8-битные - в случае когда шина физически 8 бит. И как дергается строб !CS - каждый байт или 1 раз за всю 16/32-битную пересылку?
  25. STM342F4 и FSMC

    Ещё интересный вопрос возник по сигналам FSMC. Допустим мы настроили FSMC в режиме 8 бит (дисплей). Общение идёт через 2 порта: #define LCD_COM16 (*(volatile unsigned short int*) 0x60000000) #define LCD_DAT16 (*(volatile unsigned short int*) 0x60010000) Несмотря на 8 битную шину, я объявил их 16-битными. Потому что контроллер дисплея просит 16-битные команды, а делать 2 раза по 8 не хочется(как это делают обычно: шлют старший, затем младший байты. Обнаружил, что можно полу-слово отправить, развернув байты предварительно, даже если шина физически 8 бит, а не 16) Как будет FSMC дёргать стробами CS и WR ? После каждого байта или после полу-слова? Адрес при этом будет увеличиваться? Или 4 байта сразу так: #define LCD_DAT32 (*(volatile unsigned long int*) 0x60010000) Тоже работает. Что происходит с CS, WR, A ? Я полагаю на шине адреса будет инкремент адреса на +1 с каждым байтом, а стробы CS,WR будут дергаться с каждым байтом. Увеличение адреса нас не трогает, потому что размер банка больше, чем количество слов, которое надо переслать. А дисплею всёравно - у него регистр видеопамяти один, адрес автоинкрементируется внутри него. Верно или нет? Верно ли моё предположение, что для быстрой пересылки лучше писать в 32-битный регистр, а не 4 раза по 8 бит в случае если шина 8 битная? Процессор считает одну инструкцию вместо 4-х получится экономия времени: Иными словами так быстрее: void LCD_Transfer(void) { register u32 i=(320*240)>>1; register u32 *v=(u32*)VideoBuffer; while(i--)LCD_DAT32=rev16(*v++); } Чем: void LCD_Transfer(void) { register u32 i=(320*240); register u16 *v=(u16*)VideoBuffer; while(i--)LCD_DAT16=rev16(*v++); } и тем более чем: void LCD_Transfer(void) { register u32 i=(320*240)<<1; register u8 *v=(u8*)VideoBuffer; while(i--)LCD_DAT8=*v++; } Правда, прийдётся байты разворачивать. Или в случае 8-битной шины выигрыша не даст?