Stm32f746g disco как выводить изображение
Перейти к содержимому

Stm32f746g disco как выводить изображение

  • автор:

STM32F746 Discovery

По умолчанию Arduino IDE настроена только на AVR-платы. Для работы с платформой «STM32F746 Discovery» — добавьте в менеджере плат поддержку платформ «STM32».

Элементы платы

Принципиальная схема

Распиновка

Характеристики

Начинка микроконтроллера

Микроконтроллер: STM32F746NGH6 c 32-битный ARM Cortex M7
Корпус: BGA216
Тактовая частота: 216 МГц
Объём Flash-памяти: 1 МБ
Объём SRAM-памяти: 320 КБ
Портов ввода-вывода всего: 168
Портов толерантных к 5 В: 166
АЦП: 3× 12 битный на 24 канала
ЦАП: 2× 12 битный
Таймеры ШИМ: 18
Аппаратные интерфейсы: 6× SPI, 4× I²C, 4× UART, 2× CAN, 1× SPDIFRX
LCD параллельный интерфейс 8080/6800
Номинальное рабочее напряжение: 3,3 В
Максимальный ток с пина или на пин: 25 мА

Особенности платы

Встроенный внутрисхемный отладчик/программатор ST-LINK/V2-1
4.3” дюймовый ёмкостной цветной LCD-TFT дисплей с разрешением 480×272
Разъем для подключения камеры «STM32F4DIS-CAM»
SAI аудио кодек
Разъем Audio Line In и Line Out;
Два MEMS микрофона «MP34DT01-M»
SPDIF RCA вход
Четыре светодиода: два индикаторных и два пользовательских
Две кнопки: сброс программы и пользовательская
Quad-SPI Flash память «N25Q128A13EF840E» на 128 Мбит
SDRAM память «MT48LC4M32B2B5-6A» на 128 Мбит (доступно 64 Мбит)
Слот для MicroSD карты
Разъем для подключения RF-EEPROM
Разъем Ethernet совместимый с IEEE-802.3-2002
USB OTG HS с разъемом Micro-AB
USB OTG FS с разъемом Micro-AB
Контактные колодки для подключения Arduino Shield’ов
Регулятор напряжения с выходом 3,3 вольта и током до 500 мА
Пять способов питания платформы:
ST-LINK/ V2-1
USB FS разъем
USB HS разъем
VIN от разъема Arduino
внешний источник питания 5В
Габариты: 130×80 мм

Список IDE

Ресурсы

STM32F746 Discovery в магазине

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution-Noncommercial-Share Alike 4.0 International

Производные работы должны содержать ссылку на http://wiki.amperka.ru, как на первоисточник, непосредственно перед содержимым работы.
Вики работает на суперском движке DokuWiki.

продукты/stm32-f746-discovery.txt · Последние изменения: 2020/11/03 19:58 — igor

Инструменты страницы

  • Показать исходный текст
  • История страницы
  • Ссылки сюда
  • Наверх

Создание изображения для платы STM32 Discovery и BSP

Возник такой вопрос: как создать изображение в формате «С» для использования с BSP (Board Support Package) на STM32F429I-Disco?

#ifndef __STLOGO_H #define __STLOGO_H #if defined ( __ICCARM__ ) /*! < IAR Compiler */#pragma data_alignment=4 #endif __ALIGN_BEGIN const unsigned char stlogo[9174] __ALIGN_END =  0x42,0x4d,0xd6,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00, 0x00,0x00,0x50,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x03,0x00, 0x00,0x00,0xa0,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, . 

Формат данных

После изучения указанного участка файла, а также исходников функции void BSP_LCD_DrawBitmap(uint32_t X, uint32_t Y, uint8_t *pBmp) из файла stm32f429i_discovery_lcd.c стало понятно, что это структура заголовка формата BMP. Видимо, это нужно для простой загрузки изображений с карт памяти SD.

Также, по исходникам этой функции можно предположить, что поддерживаются только лишь форматы A8R8G8B8, R5G6B5 и R8G8B8.

Как же вывести изображение в этом формате?

Есть готовая утилита Bitmap Converter for emWin (BmpCvt.exe) поставляемая в пакете STemwin. Можно попробовать в ней, но это простой путь.

Как сделать с помощью LCD Image Converter?

Можно просто решить (как некоторые и делают :), что это невозможно, потому что ни одна из встроенных настроек это не позволяет. Однако, задача состоит лишь в воспроизведении структуры заголовков BMP и заполнении их правильными данными.

Из упомянутой выше статьи получается такая структура:

typedef struct tagBITMAPFILEHEADER  uint16_t bfType; // Тип файла, 'BM', little-endian. uint32_t bfSize; // Размер всего файла в байтах. uint16_t bfReserved1; uint16_t bfReserved2; uint32_t bfOffBits; // Смещение пиксельных данных изображения от начала структуры (файла). > BITMAPFILEHEADER; // 14 байт // Версия 3, BITMAPINFOHEADER. typedef struct tagBITMAPINFOHEADER  uint32_t biSize; // Размер этой структуры, также указывающий её версию. int32_t biWidth; // Ширина изображения, должна быть больше 0. int32_t biHeight; // Высота изображения, должна быть больше 0. uint16_t biPlanes; // Количество плоскостей, равно 1. uint16_t biBitCount; // Количество бит на пиксел. uint32_t biCompression; // Тип сжатия. В файле от ST оно равно 3 (BI_BITFIELDS), хотя из-за biClrUsed == 0 оно не используется. uint32_t biSizeImage; // Размер данных изображения, в байтах. int32_t biXPelsPerMeter; // Здесь равно 0. int32_t biYPelsPerMeter; // Здесь равно 0. uint32_t biClrUsed; // Здесь равно 0. uint32_t biClrImportant; // Здесь равно 0. > BITMAPINFOHEADER; // 40 байт 

Шаблон

Цвета будем хранить в формате R5G6B5, т.е. в 16 битах. Для этого удобнее в качестве единицы хранения взять не uint8_t , а uin16_t , что скажется на данных в заголовке.

Шаблон для заполнения такой структуры, для компилятора GCC, будет выглядеть следующим образом:

#ifndef $(doc_name_ws)_H_ #define $(doc_name_ws)_H_ #include // struct packing, pragma for GCC . #pragma pack(push, 1) $(start_block_images_table) typedef struct $(doc_name_ws)_tagBITMAPFILEHEADER  uint16_t bfType; uint32_t bfSize; uint16_t bfReserved1; uint16_t bfReserved2; uint32_t bfOffBits; > $(doc_name_ws)_BITMAPFILEHEADER; // size is 14 bytes typedef struct $(doc_name_ws)_tagBITMAPINFOHEADER  uint32_t biSize; uint32_t biWidth; uint32_t biHeight; uint16_t biPlanes; uint16_t biBitCount; uint32_t biCompression; uint32_t biSizeImage; uint32_t biXPelsPerMeter; uint32_t biYPelsPerMeter; uint32_t biClrUsed; uint32_t biClrImportant; > $(doc_name_ws)_BITMAPINFOHEADER; // size is 40 bytes typedef struct $(doc_name_ws)_tag_Struct  // offset 0, size 14 $(doc_name_ws)_BITMAPFILEHEADER fileHeader; // offset 14, size 40 $(doc_name_ws)_BITMAPINFOHEADER infoHeader; // offset 54, size $(out_blocks_count) words uint16_t data[$(out_blocks_count)]; > $(doc_name_ws)_Struct; $(doc_name_ws)_Struct $(doc_name_ws) =   0x4d42u, sizeof($(doc_name_ws)_BITMAPINFOHEADER) + sizeof($(doc_name_ws)_BITMAPFILEHEADER) + ($(out_blocks_count) * 2), 0x0000u, 0x0000u, sizeof($(doc_name_ws)_BITMAPINFOHEADER) + sizeof($(doc_name_ws)_BITMAPFILEHEADER) >,  sizeof($(doc_name_ws)_BITMAPINFOHEADER), $(out_image_width), $(out_image_height), 1u, $(out_bpp), 0x00000003u, ($(out_blocks_count) * 2), 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul >,  $(out_image_data) > >; $(end_block_images_table) // struct packing, pragma for GCC . #pragma pack (pop) #endif /* $(doc_name_ws)_H_ */ 

Настройки

Основное окно программы.

LCD Image Converter основное окно

Настройки подготовки сканирования.

Настройки - Преобразование - Подготовка

Матрица выборки цветов для R5G6B5.

Настройки - Преобразование - Матрица

Настройки - Преобразование - Изображение

Здесь надо указать шаблон вывода, приведённый выше.

Настройки - Преобразование - Шаблоны

Результаты

#ifndef butterfly_H_ #define butterfly_H_ #include // struct packing, pragma for GCC . #pragma pack(push, 1) typedef struct butterfly_tagBITMAPFILEHEADER  uint16_t bfType; uint32_t bfSize; uint16_t bfReserved1; uint16_t bfReserved2; uint32_t bfOffBits; > butterfly_BITMAPFILEHEADER; // size is 14 bytes typedef struct butterfly_tagBITMAPINFOHEADER  uint32_t biSize; uint32_t biWidth; uint32_t biHeight; uint16_t biPlanes; uint16_t biBitCount; uint32_t biCompression; uint32_t biSizeImage; uint32_t biXPelsPerMeter; uint32_t biYPelsPerMeter; uint32_t biClrUsed; uint32_t biClrImportant; > butterfly_BITMAPINFOHEADER; // size is 40 bytes typedef struct butterfly_tag_Struct  // offset 0, size 14 butterfly_BITMAPFILEHEADER fileHeader; // offset 14, size 40 butterfly_BITMAPINFOHEADER infoHeader; // offset 54, size 76800 words uint16_t data[76800]; > butterfly_Struct; butterfly_Struct butterfly =   0x4d42u, sizeof(butterfly_BITMAPINFOHEADER) + sizeof(butterfly_BITMAPFILEHEADER) + (76800 * 2), 0x0000u, 0x0000u, sizeof(butterfly_BITMAPINFOHEADER) + sizeof(butterfly_BITMAPFILEHEADER) >,  sizeof(butterfly_BITMAPINFOHEADER), 240, 320, 1u, 16, 0x00000003u, (76800 * 2), 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul >,  0x19e2, 0x2202, 0x2202, 0x2242, 0x2262, 0x2262, 0x2ac3, 0x3b64, 0x3ba4, 0x3b84, 0x4ba5, 0x4bc5, 0x3b85, 0x3304, 0x2ac3, 0x2aa3, 0x2aa3, 0x2aa3, 0x2283, 0x2a83, 0x2aa3, 0x2aa3, 0x2ac3, 0x2ae3, 0x3324, 0x3b84, 0x43c5, 0x43e5, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x4405, 0x43e4, 0x3363, 0x2262, 0x1942, 0x1102, 0x1102, 0x1102, 0x1102, 0x1922, 0x1942, 0x1962, 0x1962, 0x1942, 0x1942, 0x1922, 0x1902, 0x1902, 0x1922, 0x1943, 0x1963, 0x1983, 0x1963, 0x1943, 0x1943, 0x1922, 0x1922, 0x1943, 0x1963, 0x1983, 0x2163, 0x1963, 0x1922, 0x1102, 0x1982, 0x2222, 0x2b22, 0x43a4, 0x5445, 0x5466, 0x5c86, 0x5c86, 0x43a3, 0x2202, 0x08a1, 0x1081, 0x1081, 0x1081, 0x10a2, 0x18e3, 0x2103, 0x2123, 0x29a3, 0x2a23, 0x2263, 0x2283, 0x2aa3, 0x22a3, 0x2aa3, 0x22a3, 0x2ac3, 0x22c3, 0x2ac3, 0x2ac3, 0x2ac3, 0x2243, 0x1983, 0x18e2, 0x18c2, 0x18e3, 0x18e2, 0x1903, 0x18e2, 0x10e2, 0x10e2, 0x10e2, 0x10c2, 0x10a1, 0x10a1, 0x10c2, 0x10e2, 0x1102, 0x1902, 0x1902, 0x18e2, 0x18e2, 0x18e2, 0x1102, 0x1922, 0x1942, 0x1942, 0x1942, 0x1943, 0x1922, 0x1102, 0x10c2, 0x10a2, 0x10c2, 0x10c2, 0x10c2, 0x10e2, 0x1902, 0x1922, 0x1962, 0x19a3, 0x19c3, 0x19a3, 0x19a3, 0x21a3, 0x19c3, 0x19c3, 0x19c3, 0x19e3, 0x22a3, 0x43c6, 0x5c88, 0x64c9, 0x64c9, 0x64ca, 0x64ca, 0x64aa, 0x5caa, 0x5caa, 0x5caa, 0x5cc9, 0x5cca, 0x5caa, 0x5ca9, 0x64a9, 0x5c87, 0x43a4, 0x2ac2, 0x19c2, 0x21c2, 0x19a2, 0x1982, 0x1982, 0x1962, 0x1982, 0x22c1, 0x43c4, 0x6486, 0x64c8, 0x64c9, 0x5cc9, 0x5ca8, 0x54a8, 0x5488, 0x54a8, 0x54c8, 0x5cc8, 0x5c87, 0x43e4, 0x2ae2, 0x1a42, 0x2282, 0x22a2, 0x2b23, 0x43e4, 0x5445, 0x4c04, 0x3323, 0x1a02, 0x1102, 0x1902, 0x1963, 0x2223, 0x3304, 0x4385, 0x4c06, 0x5426, 0x5466, 0x64a6, 0x6ce6, 0x6d07, 0x7526, 0x6d26, 0x6d26, 0x6d26, 0x6d26, 0x6d06, 0x6d07, 0x5cc8, 0x5488, 0x5469, 0x5468, 0x4c68, 0x5448, 0x4c68, 0x5468, 0x5468, 0x5468, 0x4c68, 0x4c47, 0x4c68, 0x5448, 0x4c48, 0x4c27, 0x4c27, 0x4c27, 0x4c27, 0x4c27, 0x4406, 0x4407, 0x43e6, 0x3ba6, . 0x64c0, 0x5c81, 0x43c1, 0x2b22, 0x2222, 0x1a22, 0x2242, 0x2243, 0x21e2, 0x1982, 0x1922, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x1942, 0x2223, 0x2ae3, 0x3b44, 0x4bc5, 0x6487, 0x6d29, 0x758a, 0x7d8a, 0x7daa, 0x7daa, 0x85ca, 0x85eb, 0x8deb, 0x8e0c, 0x85ec, 0x7dec, 0x85ec, 0x8e0c, 0x962c, 0x962c, 0x962c, 0x8e2c, 0x8e0c, 0x85ec, 0x85cc, 0x85ed, 0x960d, 0x962d, 0x960d, 0x8dcc, 0x858b, 0x7d4b, 0x752a, 0x752a, 0x6d29, 0x7509, 0x6d09, 0x6d09, 0x7509, 0x6ce8, 0x6487, 0x5446, 0x43e5, 0x3b84, 0x3364, 0x3344, 0x3344, 0x2b44, 0x3344, 0x3344, 0x3b85, 0x43e6, 0x4c27, 0x5c68, 0x5c88, 0x5c88, 0x5c67, 0x5427, 0x4bc5, 0x4364, 0x32a3, 0x2a03, 0x2983, 0x2963, 0x2963, 0x2122, 0x18e2, 0x1902, 0x1922, 0x3204, 0x4245, 0x4a65, 0x4244, 0x29c3, 0x1922, 0x10e2, 0x10a2, 0x2182, 0x4322, 0x6443, 0x7504, 0x7d84, 0x7da5, 0x7dc5, 0x7dc6, 0x7de6, 0x7dc6, 0x7de6, 0x7dc6, 0x7dc6, 0x7de7, 0x8608, 0x8e49, 0x9689, 0x9688, 0x9688, 0x8e68, 0x8e68, 0x85c7, 0x6d05, 0x4c03, 0x2b02, 0x3323, 0x4bc5, 0x6486, 0x7507, 0x8588, 0x8da8, 0x9609, 0x9628, 0x9628, 0x9648, 0x9648, 0x9668, 0x9688, 0x9668, 0x9648, 0x9648, 0x9629, 0x8587, 0x6cc6, 0x53e4, 0x4304, 0x4303, 0x3b23, 0x3b23, 0x3ac3, 0x3a43, 0x3a23, 0x31e3, 0x21c2, 0x21e2, 0x21e2, 0x2182, 0x1922, 0x10c2, 0x1081, 0x0861, 0x0861, 0x0861, 0x0861, 0x0841, 0x1081, 0x10c2, 0x1922, 0x1982, 0x21c2, 0x21e2, 0x2202, 0x2222, 0x2242, 0x2242, 0x2262, 0x2262, 0x2262, 0x2262, 0x2262, 0x2262, 0x2262, 0x2242, 0x2222, 0x21a3, 0x1922, 0x10c2, 0x1061, 0x0861, 0x0841, 0x0841, 0x0841, 0x0020, 0x0020, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0841, 0x1081, 0x1942, 0x5424, 0x8dc8, 0x85c9, 0x7d8a, 0x756a, 0x754b, 0x6d4a, 0x756b, 0x756b, 0x756b, 0x756b, 0x756a, 0x756a, 0x756a, 0x754b, 0x756a, 0x758a, 0x756a, 0x758a, 0x7d6b, 0x7d6c, 0x856d, 0x7d6d, 0x756c, 0x756c, 0x756c, 0x754b, 0x754a, 0x756b, 0x756b, 0x758b, 0x758b, 0x7d8b, 0x758b, 0x758b, 0x7d8b, 0x7d6c, 0x8dcd, 0xa60f, 0x8d8f, 0x752c, 0x6d2b > >; // struct packing, pragma for GCC . #pragma pack (pop) #endif /* butterfly_H_ */ 

Фото платы STM32F429I-Disco с полученным изображением

Фото платы STM32F429I-Disco с полученным изображением

STM32F746GDISCOVERY. Продолжение индустриального графического интерфейса

Эта отладочная плата была приобретена в направлении других горизонтов развития, однако, как и прежде, с чего-то нужно оживлять железо. Эти отладочные платы с мониторчиками и Toush Screen – прежде всего прекрасный набор кнопок (черная и голубая в набор не входят).

Чего не хватало в предыдущем проекте калькулятора? – В основном памяти для картинок. Здесь в полном распоряжении 16 Мбайт QSPI. Можно ни на чем не экономить.

При попытке использования более-менее свежего железа всегда возникают неожиданности.

Не смотря на то, что MXCube предлагает выбор версии IAR для генерации кода, 7-я версия выдала кучу ошибок, устранить которые я не смог.

8-я версия IAR выдала ошибки инициализации DMA2D в режиме DMA2D_M2M_BLEND, обругав 2 параметра. Поскольку эти параметры мне были особо не нужны, я их просто убил.

9-я версия IAR порадовала еще больше! Она запросто сказала, что в каталоге
C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\config\flashloader\ST нету файла
FlashSTM32F7xx_STM32F746G-DISCO.board и отказалась работать с проектом…

Ну так я скопировал туда этот и еще 2 файла из аналогичного каталога восьмой версии
FlashSTM32F7xx_QSPI_STM32F746G-DISCO.flash
FlashSTM32F7xx_QSPI_STM32F746G-DISCO.mac
И ведь все снова заработало!

STM32 Cube Programmer чистит и пишет e xternal memory ничуть не хуже STM32 ST-LINK Utility. Нужно только добавить (выбрать) в External Loader N25Q128A-STM32F746G-DISCO.

В IAR есть кнопочки Download and Debug и Debug without Downloading

Так вот, если в программе оставить только функции инициализации и ничего значимого не делать, то при нажатии Download and Debug IAR отрабатывает Debug without Downloading. То есть загрузчик не отрабатывает и, соответственно, данные во flash память не грузятся! В примере грузятся, у Вас не грузятся. Можно хорошо скоротать несколько дней!

SDRAM

Несколько озадачило начало работы. Через программатор все работает и светится. Однако, если отключить питание и включить автономно на экране начинает все дрожать, а то появляется и совсем не пойми что. Если понажимать RESET, то вроде как все встает на свои места и начинает работать. Но со стороны комично. В STM32F429i_Discovery такого не было.

Серьезные пацаны подметили, что если включить правильное питание (жрет она 0,6 А), то не дрожит. Все, что нашел в интернете, так у кого-то были плохие конденсаторы возле SDRAM. Посмотрел через хорошую лупу – у меня точно не треснувшие!

Проблема все-таки в SDRAM. При инициализации дисплея, мы сразу привязываем его к определенным адресам буферов. А вот что на момент инициализации в этих адресах лежит не всегда понятно. При серьезном питании память, видимо, сбрасывается. При питании от USB компьютера не всегда.

//В примере STM32CubeExpansion_AN4749_F7_V1.0.0
//main.c строка 152:
/* Copy picture from QSPI to SDRAM */
memset ( ( void * ) SDRAM_DEVICE_ADDR , 0 , 130560 * sizeof ( uint16_t ) ) ;
memcpy ( ( void * ) SDRAM_DEVICE_ADDR ,
//Это действо проводится до инициализации GUI.

Помогло! Нажимать смущенно черную кнопку после этого не нужно! Особенно я бы обратил внимание на pLayerCfg1.FBStartAdress. Поскольку уровень по цвету урезанный, то его использование не всегда очевидно, как и аппаратные телодвижения с ним разработчиков.

MPU (memory-protection-unit)

В LCD-TFT display controller (LTDC) on STM32 MCUs есть пример настройки MPU для нашей отладочной платы.

Данные в SDRAM там буферизованы для использования DMA2D,
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
поэтому после использования функций библиотеки stm32746g_discovery_lcd.c вперемешку с DMA2D нужно выдавать команду SCB_CleanDCache();

Рассуждения на эту тему можно почитать в обсуждении:
https://kincajou.livejournal.com/4160197.html

Переводы AN4838, AN4839:
http://microsin.net/programming/arm/an4838-managing-memory-protection-unit-stm32.html
http://microsin.net/programming/arm/an4839-level-1-cache-stm32f7.html

QSPI

В CubeMX лапки выставить как в проекте STM32F746GDISCOVERY по умолчанию.

Настройку параметров лучше подсмотреть в примере QSPI_perfs
…Repository\STM32Cube_FW_F7_V1.15.0\Projects\STM32746G-Discovery\Applications\QSPI\QSPI_perfs\EWARM
поскольку в последнем показывается крутость производительности.

Кто не любит EWARM, нашел случайно ссылку по работе с QSPI по VisualGDB
https://sysprogs.com/w/forums/topic/using-the-quadspi-on-stm32f7-discovery/

В примере разработчики пишут в QSPI данные в формате unsigned char. Если работать со словами данных – все тоже получается. (См. STM32CubeExpansion_AN4749_F7_V1.0.0). Однако при подготовке файлов для вывода на LCD через DMA2D в формате байтов а не слов, есть нюанс.

В примере QSPI_perfs добавлена куча настроек IAR

// C/C++ Compiler —> Preprosessor —>
Defined symbols ( one per line )
USE_HAL_DRIVER
STM32F756xx
USE_STM32746G_DISCO
ARM_MATH_CM7
// Linker —> Config
$ PROJ_DIR $ \ stm32f746xx_QSPI_flash . icf

Это линкер c секцией QSPI. Файл в текстовом формате. Можно посмотреть, можно и редактировать. Секцию .textqspi можно назвать по любому и без точки. Однако .text символизирует код и данные.

// Linker —> Input
__iar_sh_stdout _ swo
// Debugger —> Download
$ TOOLKIT_DIR $ \ config \ flashloader \ ST \ FlashSTM32F7xx_STM32F746G — DISCO . board

Дальше начинается самое интересное…

В примере QSPI_perfs есть файл main_images.c.

В описании AN4760 (раздел. 5.1.1 Генерация содержимого буфера кадра из памяти QSPI): «Все изображения и значки, необходимые для приложения, должны храниться во внешней памяти QSPI. В проекте доступно шесть изображений и три иконки, все они включены в файл «main_images.c», где каждое из них определяется как константа в отдельном заголовочном файле.»

Вроде бы все понятно… В stm32f746xx_QSPI_flash.icf мы создаем (уже создан разработчиками STM) раздел для памяти QSPI и директивой #pragma location = «.textqspi» мы обозначаем, что эти константы в этот раздел грузим.

Удобная штука. Все, что в «main_images.c» прописано, начинает грузиться в QSPI. Можно использовать в отдельном проекте, ничего из периферии не описывая. (Такой проект у меня вложен в основной.) Если изменить имя файла, то грузиться не будет. При этом нужно использовать линкер stm32f746xx_QSPI_flash.icf и загрузчик FlashSTM32F7xx_STM32F746G-DISCO.board. Пустую функцию dummy_init в файле «main_images.c» я тоже нигде не нашел. Возможно это намек, что именно так грузить нужно не только данные, но и код.

В следующем разделе AN4760 (5.1.2 Отображение изображений непосредственно из памяти QSPI). На этот пример (AN4749 поставляется с программным пакетом X-CUBE-LPDEMO-F7) я уже ссылался. Точно так же описываются данные. Файла main_images.c уже нет, зато в файле «nenu.c» есть функции WM_HWIN Createloadpicturefrom(void) библиотеки emWin version 5.28, описания которых я тоже поверхностно не нашел.

То есть по файлу «main_images.c» все гуманно! Работает, но не понятно как. Если кто-нибудь проникся, найдите время, пожалуйста, ПОДЕЛИТЕСЬ!

В описании AN4760 есть еще интересный подраздел «Как осуществлять программирование QSPI Flash memory только один раз».
В оригинале QUADSPI AN4760 pg. 58
How to proceed to program QSPI Flash memory only once… for IAR EWARM

Долго пытался разобраться. Так и не понял…
В Гугле ничего не нашел. Задал вопрос на форуме STMicroelectronics. Получил следующий ответ:

clive1 (NFA Crew) (Community Member)
2 months ago
If they are not part of your application image, I’d suggest writing some code to combine them, providing a table the app can access, and output them as a .HEX file, with an address starting at 0x90000000
Write that image with the STM32 Cube Programmer, using the External Loader for the QSPI memory (N25Q128 as I recall), and don’t tell IAR about it. Have you application set up the QSPI memory, and then access your table/images from there using normal memory access, ie pointers, structures, etc.

Что, собственно, и реализовано в файле QSPI_Addr_Table.h с использованием препроцессора …#ifdef IMG_NO_DATA

Но мне кажется, что это не изящно. Если кто-нибудь разобрался, пожалуйста, ПОДЕЛИТЕСЬ!

Touch panel FT5336

К stm32746g_discovery_ts.c как-то сразу возникло много вопросов…

Например функция BSP_TS_GetState, которая возвращает в строке 357 в качестве статуса
ts_status = BSP_TS_Get_GestureId(TS_State);
GestureId ну просто не работает и возвращает всегда ноль. Это не мешает разработчикам, поскольку в дефайнах статус «ОК» тоже ноль.

Строка 415 BSP_TS_ITClear с комментарием /* Clear TS IT pending bits */

Смотрим ft5336.c строка 425 /* Nothing to be done here for FT5336*/

Запросто включают и выключают режим прерываний, который не выключается, а переключается из Interrupt polling mode в Interrupt trigger mode и обратно.

Понимание обработки событий после некоторой исследовательской части окончательно у меня так и не сложилось. В проекте закомментированы функции, отображающие на экране счетчики этих самых событий. Кому интересно, можно посмотреть.

Пришлось довольствоваться обработкой внешнего прерывания, описав

ARM STM32F7. STM32F746G-DISCO.

Всем привет!
Недавно пришла отладочная плата STM32F746G-DISCO, очень был этому рад и конечно решил поделится с Вами первыми впечатлениями. В предыдущем обзоре об новом ядре Cortex M7, я уже рассказывал, какая аппаратная поддержка реализовано на данной отладочной плате.
Первое что будем делать, загрузим демонстрационную прошивку с каталога для ранее скаченного куба версии 1.1.0. Для этого необходимо будет скачать новую версию STM32 ST-LINK Utility (на момент написания статьи доступная версия 3.7.0). Файл прошивки размещается в каталоге C:\STM32Cube_FW_F7_V1.1.0\Projects\STM32746G-Discovery\Demonstration\Binaries.
Если посмотреть внимательно у нас две области памяти для загрузки прошивки на отладочную плату. Это связанно с тем, что бинарь не много, не мало, а весит 18,2 метра.

Теперь поработаем с отладочной платой и посмотрим, что из себя представляет демонстрационный проект.

Чтобы начать запускать примеры из Keil необходимо установить пакеты для работы stm32f7.

Второй пример, который я запустил, был STM32Cube_FW_F7_V1.1.0\Projects\STM32746G-Discovery\Applications\LwIP, в дальнейшем появятся статьи по работе с LwIP и со стеком протоколов TCP/IP. При включении устройство пытается получить адрес по DHCP. DHCP (Dynamic Host Configuration Protocol — протокол динамической настройки узла) — сетевой протокол, позволяющий компьютерам автоматически получать IP-адрес и другие параметры, необходимые для работы в сети TCP/IP. Данный протокол работает по модели «клиент-сервер». Для автоматической конфигурации компьютер-клиент на этапе конфигурации сетевого устройства обращается к так называемому серверу DHCP, и получает от него нужные параметры. Сетевой администратор может задать диапазон адресов, распределяемых сервером среди компьютеров. Это позволяет избежать ручной настройки компьютеров сети и уменьшает количество ошибок. Протокол DHCP используется в большинстве сетей TCP/IP. Пример – это web-server, страничка с информацией об компании ST.

/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "lwip/netif.h" #include "lwip/tcpip.h" #include "cmsis_os.h" #include "ethernetif.h" #include "app_ethernet.h" #include "lcd_log.h" #include "httpserver-netconn.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ struct netif gnetif; /* network interface structure */ /* Private function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); static void StartThread(void const * argument); static void BSP_Config(void); static void Netif_Config(void); static void MPU_Config(void); static void CPU_CACHE_Enable(void); /* Private functions ---------------------------------------------------------*/ /** * @brief Main program * @param None * @retval None */ int main(void) < /* Configure the MPU attributes as Write Through */ MPU_Config(); /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* STM32F7xx HAL library initialization: - Configure the Flash ART accelerator on ITCM interface - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 216 MHz */ SystemClock_Config(); /* Init thread */ #if defined(__GNUC__) osThreadDef(Start, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 5); #else osThreadDef(Start, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 2); #endif osThreadCreate (osThread(Start), NULL); /* Start scheduler */ osKernelStart(); /* We should never get here as control is now taken by the scheduler */ for( ;; ); >/** * @brief Start Thread * @param argument not used * @retval None */ static void StartThread(void const * argument) < /* Initialize LCD and LEDs */ BSP_Config(); /* Create tcp_ip stack thread */ tcpip_init(NULL, NULL); /* Initialize the LwIP stack */ Netif_Config(); /* Initialize webserver demo */ http_server_netconn_init(); /* Notify user about the network interface config */ User_notification(&gnetif); #ifdef USE_DHCP /* Start DHCPClient */ #if defined(__GNUC__) osThreadDef(DHCP, DHCP_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 5); #else osThreadDef(DHCP, DHCP_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 2); #endif osThreadCreate (osThread(DHCP), &gnetif); #endif for( ;; ) < /* Delete the Init Thread */ osThreadTerminate(NULL); >> /** * @brief Initializes the lwIP stack * @param None * @retval None */ static void Netif_Config(void) < struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; /* IP address setting */ IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) Adds your network interface to the netif_list. Allocate a struct netif and pass a pointer to this structure as the first argument. Give pointers to cleared ip_addr structures when using DHCP, or fill them with sane numbers otherwise. The state pointer may be NULL. The init function pointer must point to a initialization function for your ethernet netif interface. The following code illustrates it's use.*/ netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input); /* Registers the default network interface. */ netif_set_default(&gnetif); if (netif_is_link_up(&gnetif)) < /* When the netif is fully configured this function must be called.*/ netif_set_up(&gnetif); >else < /* When the netif link is down this function must be called */ netif_set_down(&gnetif); >> /** * @brief Initializes the STM32756G-EVAL's LCD and LEDs resources. * @param None * @retval None */ static void BSP_Config(void) < /* Initialize the LCD */ BSP_LCD_Init(); /* Initialize the LCD Layers */ BSP_LCD_LayerDefaultInit(1, LCD_FB_START_ADDRESS); /* Set LCD Foreground Layer */ BSP_LCD_SelectLayer(1); BSP_LCD_SetFont(&LCD_DEFAULT_FONT); /* Initialize LCD Log module */ LCD_LOG_Init(); /* Show Header and Footer texts */ LCD_LOG_SetHeader((uint8_t *)"Webserver Application Netconn API"); LCD_LOG_SetFooter((uint8_t *)"STM32746G-DISCO board"); LCD_UsrLog ((char *)" State: Ethernet Initialization . \n"); >/** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 216000000 * HCLK(Hz) = 216000000 * AHB Prescaler = 1 * APB1 Prescaler = 4 * APB2 Prescaler = 2 * HSE Frequency(Hz) = 25000000 * PLL_M = 25 * PLL_N = 432 * PLL_P = 2 * PLL_Q = 9 * VDD(V) = 3.3 * Main regulator output voltage = Scale1 mode * Flash Latency(WS) = 7 * @param None * @retval None */ static void SystemClock_Config(void) < RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; HAL_StatusTypeDef ret = HAL_OK; /* Enable HSE Oscillator and activate PLL with HSE as source */ 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 = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); if(ret != HAL_OK) < while(1) < ; >> /* Activate the OverDrive to reach the 216 MHz Frequency */ ret = HAL_PWREx_EnableOverDrive(); if(ret != HAL_OK) < while(1) < ; >> /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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; ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); if(ret != HAL_OK) < while(1) < ; >> > /** * @brief Configure the MPU attributes as Write Through for SRAM1/2. * @note The Base Address is 0x20010000 since this memory interface is the AXI. * The Region Size is 256KB, it is related to SRAM1 and SRAM2 memory size. * @param None * @retval None */ static void MPU_Config(void) < MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU */ HAL_MPU_Disable(); /* Configure the MPU attributes as WT for SRAM */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x20010000; MPU_InitStruct.Size = MPU_REGION_SIZE_256KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); >/** * @brief CPU L1-Cache enable. * @param None * @retval None */ static void CPU_CACHE_Enable(void) < /* Enable I-Cache */ SCB_EnableICache(); /* Enable D-Cache */ SCB_EnableDCache(); >#ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) < /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) < >> #endif

Итого: моя оценка отладочной плате 10 ��

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *