EdgeAligned 83 10 июля Опубликовано 10 июля · Жалоба Для интерфейсов как SPI, отправка байтов по DMA происходит не по таймеру, а по запросу от самого модуля SPI, по событию TXE, и все байты в пакете идут без разрывов: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 10 июля Опубликовано 10 июля · Жалоба On 7/10/2024 at 4:56 PM, EdgeAligned said: отправка байтов по DMA происходит не по таймеру А отправка пакетов по DMA может по таймеру происходить ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 83 10 июля Опубликовано 10 июля · Жалоба Косвенно. То есть, методом программного запуска канала. Но в таком случае прерывание TCIF от DMA всё-таки лучше использовать, потому что в случае дисплея время передачи всего пакета может быть значительным Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimir 2 10 июля Опубликовано 10 июля · Жалоба В 10.07.2024 в 15:38, Andrey190 сказал: SPI1->CR2 &= ~SPI_CR2_TXDMAEN; DMA2_Stream3->CR &= ~DMA_SxCR_EN; DMA2->LIFCR = DMA_LIFCR_CTCIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTEIF3 | DMA_LIFCR_CDMEIF3; DMA2_Stream3->NDTR = 48; DMA2_Stream3->M0AR = (uint32_t) &buf[(uint8_t)i][0]; DMA2_Stream3->PAR = (uint32_t)(&SPI1->DR); DMA2_Stream3->CR |= DMA_SxCR_EN; SPI1->CR2 |= SPI_CR2_TXDMAEN; прерывания от DMA не использую. отправка по таймеру Это какой контроллер? А каким образом таймер может участвовать в отправке.SPI_DMA? У меня есть библиотека Хал для ST7735 DMA запускаю полный 0 .На регистрах запускаю -наложение картинок происходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrey190 2 11 июля Опубликовано 11 июля · Жалоба 11 часов назад, dimir сказал: Это какой контроллер? А каким образом таймер может участвовать в отправке.SPI_DMA? У меня есть библиотека Хал для ST7735 DMA запускаю полный 0 .На регистрах запускаю -наложение картинок происходит. STM32F401. отправка данных начинается в прерывании от таймера, запуская указанный выше код (не аппаратный запуск). в моем случае, весь буфер гарантированно будет выдан раньше, чем сработает таймер - поэтому прерывания от DMA не нужны. сначала идет настройка DMA и SPI - сгенерировано в кубе, с кодом даже не разбирался, просто настроил по своей схеме. static void MX_DMA_Init(void) { /* Init with LL driver */ /* DMA controller clock enable */ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2); ............... static void MX_SPI1_Init(void) { LL_SPI_InitTypeDef SPI_InitStruct = {0}; ..................... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 83 11 июля Опубликовано 11 июля · Жалоба Для случая с отправкой графических данных в дисплей, такой как ST7735, длительность передачи может достигать десятков миллисекунд, что отрицательно скажется на производительности в показанном примере. Соппсна, нет никаких проблем в том, чтобы использовать прерывание по завершению передачи DMA, TCIF. Да, конечно нужно иметь некоторые знания, приложить усилия написать несколько дополнительных строчек. Ну а как вы хотели то? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimir 2 12 июля Опубликовано 12 июля · Жалоба В 11.07.2024 в 08:47, Andrey190 сказал: STM32F401. отправка данных начинается в прерывании от таймера, запуская указанный выше код (не аппаратный запуск). в моем случае, весь буфер гарантированно будет выдан раньше, чем сработает таймер - поэтому прерывания от DMA не нужны. сначала идет настройка DMA и SPI - сгенерировано в кубе, с кодом даже не разбирался, просто настроил по своей схеме. static void MX_DMA_Init(void) { /* Init with LL driver */ /* DMA controller clock enable */ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2); ............... static void MX_SPI1_Init(void) { LL_SPI_InitTypeDef SPI_InitStruct = {0}; ..................... Запустил я в прерывании по ДМА.Я понимаю как Запустить прерывание по ДМА используя флаг и внешнее прерывание и прерывание по таймеру.Таким же образом можно сделать аппаратно-программную задержку для дисплея . Да и проблема по ДМА -не было флага LL_DMA_ClearFlag_TC2(DMA2) в обработчике прерывания. И по моему вы ни чего не показали.А вот мой вариант реальнее.Я на avr правда сделал 4 канальную герлянду ШИМ эфффектами с аппаратно- программной задержкой. Да и вы мне не обязаны показывать.Но мой вариант лучше.И сын ошибок трудных и гений парадоксов друг-учёба всю жизнь ежеминутно и ежесекундно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 12 июля Опубликовано 12 июля · Жалоба 18 минут назад, dimir сказал: Но мой вариант лучше. Ничего лучше я сегодня на форумах уже не прочту :))) 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrey190 2 12 июля Опубликовано 12 июля · Жалоба 23 минуты назад, dimir сказал: И по моему вы ни чего не показали. я же написал - там нагенерил куб. под мой проект. что нагенерил - я не разбирался даже. но если поможет, пожалуйста. Спойлер /** * @brief SPI1 Initialization Function * @param None * @retval None */ static void MX_SPI1_Init(void) { /* USER CODE BEGIN SPI1_Init 0 */ /* USER CODE END SPI1_Init 0 */ LL_SPI_InitTypeDef SPI_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); /**SPI1 GPIO Configuration PA5 ------> SPI1_SCK PA7 ------> SPI1_MOSI */ GPIO_InitStruct.Pin = LL_GPIO_PIN_5|LL_GPIO_PIN_7; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* SPI1 DMA Init */ /* SPI1_TX Init */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_3, LL_DMA_CHANNEL_3); LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_3, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_3, LL_DMA_PRIORITY_MEDIUM); LL_DMA_SetMode(DMA2, LL_DMA_STREAM_3, LL_DMA_MODE_NORMAL); LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_3, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_3, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_3, LL_DMA_PDATAALIGN_HALFWORD); LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_3, LL_DMA_MDATAALIGN_HALFWORD); LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_3); /* USER CODE BEGIN SPI1_Init 1 */ /* USER CODE END SPI1_Init 1 */ /* SPI1 parameter configuration*/ SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_16BIT; SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8; SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; SPI_InitStruct.CRCPoly = 10; LL_SPI_Init(SPI1, &SPI_InitStruct); LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA); /* USER CODE BEGIN SPI1_Init 2 */ /* USER CODE END SPI1_Init 2 */ } /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { /* Init with LL driver */ /* DMA controller clock enable */ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2); /* Configure DMA request MEMTOMEM_DMA2_Stream0 */ /* Select channel */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_0, LL_DMA_CHANNEL_0); /* Set transfer direction */ LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_0, LL_DMA_DIRECTION_MEMORY_TO_MEMORY); /* Set priority level */ LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_0, LL_DMA_PRIORITY_LOW); /* Set DMA mode */ LL_DMA_SetMode(DMA2, LL_DMA_STREAM_0, LL_DMA_MODE_NORMAL); /* Set peripheral increment mode */ LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_0, LL_DMA_PERIPH_INCREMENT); /* Set memory increment mode */ LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_0, LL_DMA_MEMORY_INCREMENT); /* Set peripheral data width */ LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_HALFWORD); /* Set memory data width */ LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_0, LL_DMA_MDATAALIGN_HALFWORD); /* Enable FIFO mode */ LL_DMA_EnableFifoMode(DMA2, LL_DMA_STREAM_0); /* Set FIFO threshold */ LL_DMA_SetFIFOThreshold(DMA2, LL_DMA_STREAM_0, LL_DMA_FIFOTHRESHOLD_FULL); /* Set memory burst size */ LL_DMA_SetMemoryBurstxfer(DMA2, LL_DMA_STREAM_0, LL_DMA_MBURST_INC4); /* Set peripheral burst size */ LL_DMA_SetPeriphBurstxfer(DMA2, LL_DMA_STREAM_0, LL_DMA_PBURST_INC4); /* Configure DMA request MEMTOMEM_DMA2_Stream1 */ /* Select channel */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_1, LL_DMA_CHANNEL_0); /* Set transfer direction */ LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_1, LL_DMA_DIRECTION_MEMORY_TO_MEMORY); /* Set priority level */ LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_1, LL_DMA_PRIORITY_LOW); /* Set DMA mode */ LL_DMA_SetMode(DMA2, LL_DMA_STREAM_1, LL_DMA_MODE_NORMAL); /* Set peripheral increment mode */ LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_1, LL_DMA_PERIPH_INCREMENT); /* Set memory increment mode */ LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_1, LL_DMA_MEMORY_INCREMENT); /* Set peripheral data width */ LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_HALFWORD); /* Set memory data width */ LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_1, LL_DMA_MDATAALIGN_HALFWORD); /* Enable FIFO mode */ LL_DMA_EnableFifoMode(DMA2, LL_DMA_STREAM_1); /* Set FIFO threshold */ LL_DMA_SetFIFOThreshold(DMA2, LL_DMA_STREAM_1, LL_DMA_FIFOTHRESHOLD_FULL); /* Set memory burst size */ LL_DMA_SetMemoryBurstxfer(DMA2, LL_DMA_STREAM_1, LL_DMA_MBURST_INC4); /* Set peripheral burst size */ LL_DMA_SetPeriphBurstxfer(DMA2, LL_DMA_STREAM_1, LL_DMA_PBURST_INC4); /* Configure DMA request MEMTOMEM_DMA2_Stream2 */ /* Select channel */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_2, LL_DMA_CHANNEL_0); /* Set transfer direction */ LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_2, LL_DMA_DIRECTION_MEMORY_TO_MEMORY); /* Set priority level */ LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_2, LL_DMA_PRIORITY_LOW); /* Set DMA mode */ LL_DMA_SetMode(DMA2, LL_DMA_STREAM_2, LL_DMA_MODE_NORMAL); /* Set peripheral increment mode */ LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_2, LL_DMA_PERIPH_INCREMENT); /* Set memory increment mode */ LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_2, LL_DMA_MEMORY_INCREMENT); /* Set peripheral data width */ LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_2, LL_DMA_PDATAALIGN_HALFWORD); /* Set memory data width */ LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_2, LL_DMA_MDATAALIGN_HALFWORD); /* Enable FIFO mode */ LL_DMA_EnableFifoMode(DMA2, LL_DMA_STREAM_2); /* Set FIFO threshold */ LL_DMA_SetFIFOThreshold(DMA2, LL_DMA_STREAM_2, LL_DMA_FIFOTHRESHOLD_FULL); /* Set memory burst size */ LL_DMA_SetMemoryBurstxfer(DMA2, LL_DMA_STREAM_2, LL_DMA_MBURST_INC4); /* Set peripheral burst size */ LL_DMA_SetPeriphBurstxfer(DMA2, LL_DMA_STREAM_2, LL_DMA_PBURST_INC4); /* DMA interrupt init */ /* DMA2_Stream3_IRQn interrupt configuration */ NVIC_SetPriority(DMA2_Stream3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0)); NVIC_EnableIRQ(DMA2_Stream3_IRQn); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 83 12 июля Опубликовано 12 июля · Жалоба 5 часов назад, Andrey190 сказал: я не разбирался даже Эх, хотел бы я тоже так - не разбираться ни в чем 🙂 Но вот ведь беда - разбираюсь же. Как теперь научиться не разбираться? Научите? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrey190 2 12 июля Опубликовано 12 июля · Жалоба 1 час назад, EdgeAligned сказал: Эх, хотел бы я тоже так - не разбираться ни в чем 🙂 Но вот ведь беда - разбираюсь же. Как теперь научиться не разбираться? Научите? легко. проект - часы себе на стол. хобби так сказать. зависли - питание выкл/вкл (несколько месяцев после разработки пока не пришлось перезапускать). p.s. халокуб только для начальной инициализации... коммерческий проект - через чтение мануалов, без халокубов и прочих генераторов кодов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 17 июля Опубликовано 17 июля · Жалоба В 12.07.2024 в 14:57, Andrey190 сказал: коммерческий проект - через чтение мануалов, без халокубов и прочих генераторов кодов. Что ж вы так коммерсантов-то не любите Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться