Jump to content

    

AlanDrakes

Участник
  • Content Count

    115
  • Joined

  • Last visited

Community Reputation

0 Обычный

About AlanDrakes

  • Rank
    Частый гость
  • Birthday 01/31/1988

Контакты

  • Сайт
    http://
  • ICQ
    0

Информация

  • Город
    Россия, Омск

Recent Profile Visitors

1202 profile views
  1. STM32H743ZI + FPGA + Mux PSRAM

    Аналогично с STM32F7: Перенесите работу с памятью в адресное пространство 0xC000'0000 и сделайте так: SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_0; // Remapping memory (FMC->SRAM from 0x60000000 to 0xC0000000). Я даже нашёл причину на другом форуме. Довольно занимательный поиск причины.
  2. stm32 i2c

    Это просто у Вас попался бит "1" сразу после "START", потому его длительность и была короче - ведомый должен получить сам сигнал начала транзакции, а уже затем в состоянии SCL=0 можно менять состояние SDA. Но так как требуется сразу передать "1" - автоматика вынуждена делать такой финт на начале. Попробуйте передать адрес, например, 0x55 - все единицы и нули будут иметь одинаковую длину.
  3. STM32L476 + SD. f_write выдает FR_DISK_ERR

    Интересное подозрение.. А Вы точно полностью сбрасываете периферию в процессе инициализации? Именно через сброс периферийного блока. Это можно быть причиной, когда после перепрограммирования программа начинает выполняться не после аппаратного сброса, а посредством установки указатетя выполнения на начальный адрес. В частности, где-то в недрах железки (хотя и на F7) используется такой код: // Enable clock RCC->APB2ENR |= RCC_APB2ENR_SDMMC1EN; // Сброс RCC->APB2RSTR |= RCC_APB2RSTR_SDMMC1RST; // Антисброс RCC->APB2RSTR &= ~RCC_APB2RSTR_SDMMC1RST; tempreg=0; //Reset value tempreg|=SDMMC_CLKCR_CLKEN; //Clock is enabled tempreg|=(uint32_t)0x76; //Clock Divider. Clock=48000/(118+2)=400Khz //Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width=0, Power save Disable SDMMC1->CLKCR=tempreg; //Power up the SDMMC SDMMC1->POWER = 0x03;
  4. STM32H7 - LTDC + DM2D (ChromART)

    Лично у меня получается вот так: RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN; // Генерация CLUT таблицы for (i=0;i<256;i++) { #ifdef ILI9341 // RRRGGGBB // RRRxxxxx = 0xE0 // xxxxxxxxRRRRRRRRxxxxxxxx j = ((i & 0xE0) << 8) | ((i & 0xE0) << 5) | ((i & 0xC0) << 2); // xxxGGGxx = 0x1C // xxxxxxxxRRRRRRRRxxxxxxxx // xxxGGGxx // xxGGGxxx << 1 // xxxxxGGG >> 2 // xxxxxxxxRRRRRRRRxxGGGGGG ?! j |= ((i & 0x1C) << 1) | ((i & 0x1C) >> 2);// | ((i & 0x18) >> 3); // xxxxxxxxRRRRRRRRxxGGGGGG // xxxxxxBB // xxxBBxxx // xxxxxBBx // xxxxxxxBB // xxxxxxxxxBB // WHAT THE FUCK?! // But working ( j |= ((i & 0x03) << 19) | ((i & 0x03) << 17) | ((i & 0x03) << 15) | ((i & 0x03) << 13); #endif DMA2D->FGCLUT[i] = j; }; // Естественно, должна быть проинициализирована периферия и всё верно настроено. // В моём случае LCD находится на шине FMC (FSMC) в режиме SRAM с ремапом адресов на область без кэша записи. // LCD_SetBounds(0, 0, 319, 239); // Set full screen bounds. <- Функция устанавливает размеры окна вывода на дисплей и готовит его к получению данных. DMA2D->CR = 0x00010000; // Mem to Mem with PFC DMA2D->FGMAR = (uint32_t)&(ScreenBuffer[0]); // Frame memory (indexed) DMA2D->OMAR = (0xC0040000); // LCD address DMA2D->FGOR = 0; // Memory Offset (added on each line end) DMA2D->OOR = 0; // LCD Offset (Same as FGOR) DMA2D->FGPFCCR = 5; // From L8 DMA2D->OPFCCR = 2; // To RGB565 DMA2D->NLR = (240 << 16) | 320; // Number of lines and rows DMA2D->CR |= DMA2D_CR_START; // Start transmission while (DMA2D->CR & DMA2D_CR_START) {} ; // Ожидание завершения. Пример прекрасно себя ощущает на кристалле STM32F7456 / STM32F767 PS: А вот подружить DMA2D и LTDC у меня не получается. По даташиту (во всяком случае для F7) я не нашёл возможности их взаимодействия. А было бы интересно хранить экранные слои в памяти в сжатом виде. PS2: Кстати, можно даже в 16-цветной палитре работать.
  5. Неполадки с очередью в USART

    Очередь для байтов UART'а... чтож, мсье знает толк. Накладные расходы большие для такого дела. Лучше уж принимать данные в кольцевой буфер, затем копировать их поблочно в динамическую память, и кидать ссылки на неё. Но это тоже плохой вариант при работе из прерывания. Я бы рекомендовал описать свой вариант очереди без блокировок и с некоторым кольцевым буфером отправки. У себя использую около 4kiB на отправку и 128 байт на приём. Переполнения не ловил уже давно. Отправляю посредством DMA, принимаю - тоже. Прекращение отправки происходит по событию DMA-Transfer-Complete, обработка приёма - по USART-IDLE. Но в прерываниях только взводятся флаги и запоминаются новые позиции указателей на буфер, а в основном потоке происходит сравнение новых позиций с их копией в потоке (атомарность операций не нарушается). Быстро, достаточно эффективно, относительно безопасно для критических секций и потоков. Во всяком случае, не вызывает зависаний.
  6. У себя в проектах использую кольцевой буфер DMA + прерывание USART-IDLE. Работает корректно. Глобальная переменная хранит позицию записи в DMA буфер, которая была обработана последней. При прерывании IDLE сравнивается указатель DMA_ChannelX->CNDTR и переменная. Вычитанием (RCVD = DMA_ChannelX->CNDTR - LAST_CNDTR) получаю количество принятых байт. В случае перехода указателя буфера через ноль - получаем отрицательное число и обрабатываю данные особым образом. В ином случае (положительное число) - копирую их за один проход и вызываю функцию, либо отправляю в очередь ОС.
  7. STM32L1XX - свой загрузчик

    1. Нет. Память именно для этого и Read-only. Писать в неё физически невозможно. Позозреваю масочное ПЗУ на данном месте. 2. Да. Есть варианты, в зависимости от собственно, загрузчика. 3. Можете сделать наоборот. Располагать загрузчик в первых секторах и исполнять прошивку именно с него (не трогая конфигурационные биты). Естественно, собирать прошивку нужно с соответствующим адресом начала памяти. Практически все контроллеры ARM умеют переносить таблицу векторов в RAM. Многие - даже в произвольное место. Ищите информацию о регистре SCB->VTOR - как раз указатель на смещение таблицы векторов прерываний. На тех кристаллах, что я пробовал лично, он 32-битный и покрывает ВЕСЬ диапазон доступных адресов. Могу предложить подобный алгоритм работы: 1. Контроллер получает новую прошивку и записывает её во Flash память. Делает в определённом месте соответствующую пометку "Нужно обновиться!". 2. Контроллер перезапускается. Стартует загрузчик. 3. Загрузчик настраивает периферию, прерывания, всё что нужно, проверяет внешнуюю память на наличие прошивки. При необходимости стирает адреса, в которые будет записана новая прошивка. В случае сбоя питания - перезагружается и начинает с начала - стирает и перезаписывает снова. 4. Загрузчик проверяет целостность прошивки, сверяет её с содержимым внешней памяти, снимает метку "Нужно обновиться" и передаёт управление на вектор сброса основной прошивки. 5. Основная прошивка копирует таблицу векторов прерываний в RAM, настраивает адрес этой самой таблицы, и работает будто ничего и не происходило. ЗЫ: Рекомендую таки оставить лазейку для дополнительного сброса в виде WatchDog'а.
  8. STM32H7 работа с SDRAM. Проблема

    При использовании SPI интерфейса, чтение пиксельных данных из экрана невозможно. У меня экран висит на 8-ми битной шине FMC контроллера. LTDC не задействовал - у него хоть и имеются интересные возможности, но нельзя использовать запакованые пиксели формата L4. Таких помещается два в одном байте - экономия памяти, которая потребуется в других задачах. Дисплей обладает своей памятью и её даже можно читать, но скорость этого чтения... во всяком случае, в попадавшихся мне экземплярах экранов, значительно ниже скорости записи, и для чтения пикселя приходилось играть с таймингами. Например, на 8-ми битной шине, при частоте ядра контроллера в 100МГц (уточню, что использую STM32F745, а эта частота выбрана как удобная для расчётов), можно получить около 30 заполнений экрана в секунду. Именно заполнений - полноценных выводов нового кадра из памяти в экран. При бОльших частотах, естественно, можно и быстрее отрисовывать, но скорее всего сам контроллер экрана не сможет. Считывания упирались в какие-то внутренние тайминги экрана, и сильно портили картину. Чтение проихсодит, да, но как-то не всегда стабильно, и крайне медленно (1-2 секунды на чтение экрана - это просто что-то в чём-то). Ответил выше, но всё же. FMC позволяет использовать пин RS (выполняет роль D/C) напрямую записывая данные в разные адреса памяти. Например, запись массива пикселей в адреса 0xC0040000...0xC007FFFF приводит к поднятию пина A18 (RS) в 1 и воспринимается контроллером дисплея как поток данных. Запись же в адреса 0xC0000000...0xC003FFFF - опускает пин в 0 и дисплей воспринимает значения как команды. Выглядит сие безумие примерно так: if ((DMA2D->CR & DMA2D_CR_START) == 0) { LCD_SetBounds(0, 0, 319, 239); // Set full screen bounds. DMA2D->CR = 0x00010000; // Mem to Mem with PFC DMA2D->FGMAR = (uint32_t)&(ScreenBuffer[0]); // Frame memory (indexed) DMA2D->OMAR = (0xC0040000); // LCD address DMA2D->FGOR = 0; // Memory Offset DMA2D->OOR = 0; // LCD Offset DMA2D->FGPFCCR = 8; // From L4 DMA2D->OPFCCR = 2; // To RGB565 DMA2D->NLR = (240 << 16) | 320; // Number of lines and rows DMA2D->CR |= DMA2D_CR_START; // Start transmission }; Буфер выдаётся на максимально доступной скорости с помощью встроеного DMA из DMA2D "ускорителя" (от ускорителя там только DMA и преобразование). Мне приходится использовать исключительно внутреннюю память. Из 100 пинов заняты более 90, так что особо не разгуляться. В моём случае проблемы могут быть при одновременном доступе от ядра и DMA2D. Но на практике незаметно. Смотрю я на H743/753 чипы референс в области памяти... и тихонько так выпадаю в осадок. Есть у меня подозрение, что в Вашем случае может оказаться быстрее из внешней памяти. Знаете... Попробуйте оба варианта - буфер в памяти и буфер во внешней памяти. Напишите бенчмарк (я именно так и делал несколько раз ради смеха и попугаев).
  9. Можно ли "убить" STM32 прошивкой?

    Нет. RAM это 0x20000000 А вот 0x00200000 - это обычно флеш (отражёный на нулевые адреса). Но всё же чаще пишут в 0x08000000. Может таки в этом дело?
  10. STM32H7 работа с SDRAM. Проблема

    Помнится, мучался со считыванием пикселей на F7 из LCD на ILI9431 и им подобных. Там ТАКИЕ тормоза требуются для процесса считывания, что скорость шины становится просто смешной. В итоге, плюнул на это неблагодарное дело и подключил LCD так: FrameBuffer -> CromeART -> FMC -> LCD Данные пишутся в экранный буфер (Использую 16 цветов в режиме L4), на дисплей при обновлении кадра автоматически конвертируется в RGB-565 посредством DMA2D (CromeART), затем через FMC пишется на скорости интерфейса прямо в дисплей (но дисплей получает команды X=>0, Y=>0, RamWrite (0x22), а затем поток данных, и так каждый кадр). Из минусов - имею частые обращения к памяти от DMA (должно сказаться на скорости, но пока проект отложен - не могу сказать точных цифр) и собственно, выделение памяти (в моём случае это 320*240/2 = 38400 байт) и динамическое выделение данных под скриншот (дёргаю из кучи, затем освобождаю по готовности). Запись на карту памяти из буфера - в разы быстрее чем из экрана, а так же свободна от артефактов считывания пикселей.
  11. Default Handler вызывается в том случае, когда произошло прерывание, не описаное в коде (имеющее вектор в таблице, но не получившее обработчика). Рекомендую добавить в код строки: void HardFault_Handler(void) { while(1) {} };
  12. stm32f407 SPI обнаружил косяк

    Такое поведение я бы понял при наличии буферов FIFO на кристалле (в частности, для STM32F745 / F3xx / F030 такое поведение нормально. Данные загружаются в регистр данных, но попадают в FIFO буфер, в очередь передачи (размер - 32 бита), и фактически буфер передачи в этот момент становится пуст. Но в указаном Вами кристалле, FIFO не описан, значит его и быть не должно. Если есть логический анализатор - можете попробовать выводить отладку на пины. Сверьтесь с графиком 248 (параграф 25.3.9) по передачи данных со стороны ведомого контроллера. Естественно, внутренние сигналы придётся выводить во вне во время прерываний. И помните, что последние будут отставать от фактического события. Но можно сильно увеличить делитель частоты для SPI, чтобы минимизировать отставание.
  13. Как-то у меня с аналогичным дымом сгорел STM32F103. Просто очень неудачно упал силовой провод (+12V) на тестовую плату. Естественно, щёлк, вспышка, снесло крышу одному сдвиговому регистру, контроллер задымил. Самое странное при этом, что он продолжал работать. Естественно, минус несколько IO портов, но в консоль он продолжал слать отчёты о загрузке системы, видимости части переферии (вокруг него) и даже мог связаться с соседним контроллером по внешней шине. Ток потребления, конечно, ушёл куда-то за 100мА. Но через минуту и это перестало работать. Да, пробой по кремнию прямо внутри кристалла это очень печальная штука. :(
  14. +1 Бэкапы-то сделали? А вообще, какой же он стал страшный :( Шрифты - ладно, читаемы. Переносы в блоке профиля пользователя - позабавили (слово "Микроконтроллеры" слегка порвалось, но это так, менлочи на самом деле). Половина заголовков на русском, половина - на английском. Постоянно запрашивает какие-то разрешения для сайта. Зачем? Раньше такого не было и было нормально (лично мне). И, да. Здравствуй, гигантизм кнопок :(
  15. stm32f4 + Chan's FatFS

    Пилил я как-то свой тест скорости карточек. Не оптимальный до ужаса. Тем не менее, результат был таким: File created. Write test... [0000000030.080] File write done. Total bytes written: 5242880 bytes. Time: 27684 ms. Avg: ~189 kBps Read test... [0000000036.114] File read done. Total bytes read: 5242880 bytes. Time: 6033 ms. Avg: ~869 kBps Здесь кристалл работал на ~96МГц, возможно, меньше. SDIO тактировалось от PLL на 48МГц. Если тактирование SDIO было быстрее тактирования ядра - работать с картой памяти было невозможно. Были у меня ещё какие-то весёлые проблемы с записью больших блоков через FatFS, хотя библиотека собиралась с неправильными параметрами, и объём памяти под неё старательно ужимался. В итоге, при записи огромных буферов из памяти (как раз размером в несколько секторов) получал странные зависания в случайных местах. В причинах не разобрался, добавив костыль, заставив код писать мелкими блоками.