| Форум РадиоКот https://radiokot.ru/forum/ |
|
| STMH7 + SPI + DMA https://radiokot.ru/forum/viewtopic.php?f=59&t=198950 |
Страница 1 из 1 |
| Автор: | Cheeseman [ Вт авг 26, 2025 16:14:04 ] |
| Заголовок сообщения: | STMH7 + SPI + DMA |
Всем привет. Пытаюсь подключить SPI + DMA на контроллере stm32H743ZI. Не могу настроить данную связку. Вот код инициализации DMA Код: void DMA_Init(void) { RCC->AHB2ENR |= RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN; RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; DMAMUX1_Channel0->CCR = (39 << DMAMUX_CxCR_DMAREQ_ID_Pos); // прием DMAMUX1_Channel1->CCR = (40 << DMAMUX_CxCR_DMAREQ_ID_Pos); // передача // передача DMA1_Stream4->CR = 0; // выкл DMA while (DMA1_Stream4->CR & DMA_SxCR_EN) {} // ждем, пока DMA выключится DMA1_Stream4->PAR = (uint32_t)&SPI2->TXDR; DMA1_Stream4->M0AR = (uint32_t)qca7k_spi_txBuf; DMA1_Stream4->CR |= (1u << DMA_SxCR_DIR_Pos); // Memory to peripheral DMA1_Stream4->CR |= DMA_SxCR_MINC | DMA_SxCR_TEIE | DMA_SxCR_TCIE; // инкремент памяти, разрешение прерываний DMA1_Stream4->CR |= (3u << DMA_SxCR_PL_Pos); // Very high priority DMA1_Stream4->CR &= ~DMA_SxCR_MSIZE; // 8 бит DMA1_Stream4->CR &= ~DMA_SxCR_PSIZE; DMA2_Stream4->FCR &= ~DMA_SxFCR_DMDIS; // direct mode(без fifo) DMA1_Stream4->NDTR = ARRAY_SIZE(qca7k_spi_txBuf); DMA1->HIFCR |= DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTCIF4 | DMA_HIFCR_CTEIF4; // очистка флагов //прием DMA1_Stream0->CR = 0; // выкл DMA while (DMA1_Stream0->CR & DMA_SxCR_EN) {} // ждем, пока DMA выключится DMA1_Stream0->PAR = (uint32_t)&SPI2->RXDR; DMA1_Stream0->M0AR = (uint32_t)qca7k_spi_rxBuf; DMA1_Stream0->CR = DMA_SxCR_MINC | DMA_SxCR_TEIE | DMA_SxCR_TCIE | DMA_SxCR_CIRC; // инкремент памяти DMA1_Stream0->CR &= ~DMA_SxCR_DIR; DMA1_Stream0->CR |= (3u << DMA_SxCR_PL_Pos); // Very high priority DMA1_Stream0->CR &= ~DMA_SxCR_MSIZE; // 8 бит DMA1_Stream0->CR &= ~DMA_SxCR_PSIZE; DMA1_Stream0->NDTR = ARRAY_SIZE(qca7k_spi_rxBuf); DMA1->LIFCR |= DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTCIF0 | DMA_LIFCR_CTEIF0; // очистка флагов // Включаем прерывание по приему и устанавливаем его приоритет NVIC_EnableIRQ(DMA1_Stream4_IRQn); NVIC_SetPriority(DMA1_Stream4_IRQn, 2); } /******************************************************************************* * @brief Обработчик прерывания DMA1 по передаче (канал SPI2) *******************************************************************************/ void DMA1_Stream4_IRQHandler(void) { // Обработчик передачи: if (DMA1->HISR & DMA_HISR_TCIF4) { DMA1->HIFCR |= DMA_HIFCR_CTCIF4; // очистка флагов } else if (DMA1->HISR & DMA_HISR_TEIF4) { DMA1->HIFCR |= DMA_HIFCR_CTEIF4; DMA1_Stream4->CR &= ~DMA_SxCR_EN; // выкл DMA while (DMA1_Stream4->CR & DMA_SxCR_EN) {} // ждем, пока DMA выключится } } /******************************************************************************* * @brief Обработчик прерывания DMA1 по приему (канал SPI2) *******************************************************************************/ void DMA1_Stream0_IRQHandler(void) { // Обработчик приема: if (DMA1->LISR & DMA_LISR_TCIF0) { DMA1->LIFCR |= DMA_LIFCR_CTCIF0; // очистка флагов DMA1_Stream0->CR &= ~DMA_SxCR_EN; // выкл канал DMA, понадобится снова включим // Выключаем прерывание по приему NVIC_DisableIRQ(DMA1_Stream0_IRQn); CS_HIGH(); } // если ошибка else if (DMA1->LISR & DMA_LISR_TEIF0) { DMA1->LIFCR |= DMA_LIFCR_CTEIF0; DMA1_Stream0->CR &= ~DMA_SxCR_EN; // выкл DMA while (DMA1_Stream0->CR & DMA_SxCR_EN) {} // ждем, пока DMA выключится } } Без DMA SPI работает, частота настроена. При инициализации SPI с DMA в инициализации SPI просто включаю два флага TXDMAEN и RXDMAEN. При добавлении DMA ничего не отправляется.Где могут быть подводные камни? И как выбирать номер stream (DMA1_Stream4)? Судя по примерам в интернете можно брать любые, не нашел в даташите от чего выбор зависит. |
|
| Автор: | Adrift [ Вт авг 26, 2025 16:28:10 ] |
| Заголовок сообщения: | Re: STMH7 + SPI + DMA |
И как выбирать номер stream (DMA1_Stream4)? Судя по примерам в интернете можно брать любые, не нашел в даташите от чего выбор зависит. Что у вас эти строки делают? От них выбор и должен зависеть. Код: DMAMUX1_Channel0->CCR = (39 << DMAMUX_CxCR_DMAREQ_ID_Pos); // прием DMAMUX1_Channel1->CCR = (40 << DMAMUX_CxCR_DMAREQ_ID_Pos); // передача И почему номера 10/11? Они соответствуют DMA2_Stream2/3... |
|
| Автор: | Cheeseman [ Вт авг 26, 2025 16:42:17 ] |
| Заголовок сообщения: | Re: STMH7 + SPI + DMA |
Там не 10, 11, а 0, 1. переделал на stream 1 вместо 4, пока также забыл указать функцию отправки пакета Код: void SPI1_dmaTransmit() { // Для этого выключаем канал DMA, меням регистр с длинной и снова включаем: DMA1_Stream1->CR &= ~DMA_SxCR_EN; while (DMA1_Stream1->CR & DMA_SxCR_EN) {} // ждем, пока DMA выключится DMA1_Stream1->NDTR = qca7k_spiDataSize; DMA1_Stream1->CR |= DMA_SxCR_EN; } сейчас при инициализации DMA1_Stream1 |
|
| Автор: | Adrift [ Вт авг 26, 2025 16:44:13 ] |
| Заголовок сообщения: | Re: STMH7 + SPI + DMA |
Там не 10, 11, а 0, 1. Точно ) Но все равно не правильно. |
|
| Автор: | Cheeseman [ Вт авг 26, 2025 16:49:24 ] |
| Заголовок сообщения: | Re: STMH7 + SPI + DMA |
В даташите не вижу, какой steam привязывается к какой периферии. Вижу только, что DMA request MUX input под номером 40 соответствует spi2_tx_dma. Я и подумал, что любому stream можно задать значение 40, чтобы отвечал за spi2 tx dma. Куда смотреть? UPD: сейчас инициализация на передачу выглядит так: Код: // передача DMA1_Stream1->CR = 0; // выкл DMA while (DMA1_Stream1->CR & DMA_SxCR_EN) {} // ждем, пока DMA выключится DMA1_Stream1->PAR = (uint32_t)&SPI2->TXDR; DMA1_Stream1->M0AR = (uint32_t)qca7k_spi_txBuf; DMA1_Stream1->CR |= (1u << DMA_SxCR_DIR_Pos); // Memory to peripheral DMA1_Stream1->CR |= DMA_SxCR_MINC | DMA_SxCR_TEIE | DMA_SxCR_TCIE; // инкремент памяти, разрешение прерываний DMA1_Stream1->CR |= (3u << DMA_SxCR_PL_Pos); // Very high priority DMA1_Stream1->CR &= ~DMA_SxCR_MSIZE; // 8 бит DMA1_Stream1->CR &= ~DMA_SxCR_PSIZE; DMA1_Stream1->FCR &= ~DMA_SxFCR_DMDIS; // direct mode(без fifo) DMA1_Stream1->NDTR = ARRAY_SIZE(qca7k_spi_txBuf); DMA1->LIFCR |= DMA_LIFCR_CHTIF1 | DMA_LIFCR_CTCIF1 | DMA_LIFCR_CTEIF1; // очистка флагов Ну и далее везде DMA1_Stream1 |
|
| Автор: | Adrift [ Вт авг 26, 2025 16:55:55 ] |
| Заголовок сообщения: | Re: STMH7 + SPI + DMA |
Я и подумал, что любому stream можно задать значение 40, чтобы отвечал за spi2 tx dma. Так и есть, но стримы DMA и каналы DMAMUX должны совпадать. |
|
| Автор: | Cheeseman [ Ср авг 27, 2025 12:42:42 ] |
| Заголовок сообщения: | Re: STMH7 + SPI + DMA |
Разобрался кароч. Закинул свой буфер в область памяти AXI SRAM и всё полетело |
|
| Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|


