Alex_Golubev 0 10 сентября, 2020 Опубликовано 10 сентября, 2020 · Жалоба Добавил связь DMA ---> USART3. И не смог запустить. Скрытый текст ExternalsBlocks_TX[0] = 0x85; RCC->APB1LENR |= RCC_APB1LENR_USART3EN; // подключаем USART 3 к шине ABP1 while (!(RCC->APB1LENR & RCC_APB1LENR_USART3EN)); // ждем чтобы гарантированно подключилась MODIFY_REG(GPIOD->MODER, GPIO_MODER_MODE8, 0x2 << GPIO_MODER_MODE8_Pos); // перевод порта на альтернативную функцию в частности USART_TX MODIFY_REG(GPIOD->MODER, GPIO_MODER_MODE9, 0x2 << GPIO_MODER_MODE9_Pos); // перевод порта на альтернативную функцию в частности USART_RX MODIFY_REG(GPIOD->OSPEEDR, GPIO_OSPEEDR_OSPEED8,0x2 << GPIO_OSPEEDR_OSPEED8_Pos); // настройка скорости фронта USART скорость наибольшая MODIFY_REG(GPIOD->OSPEEDR, GPIO_OSPEEDR_OSPEED9,0x2 << GPIO_OSPEEDR_OSPEED9_Pos); // настройка скорости фронта USART скорость наибольшая MODIFY_REG(GPIOD->PUPDR, GPIO_PUPDR_PUPD8, 0x00 << GPIO_PUPDR_PUPD8_Pos); // отключение подтяжки MODIFY_REG(GPIOD->PUPDR, GPIO_PUPDR_PUPD9, 0x00 << GPIO_PUPDR_PUPD9_Pos); // отключение подтяжки MODIFY_REG(GPIOD->AFR[1], GPIO_AFRH_AFSEL8, 0x7 << GPIO_AFRH_AFSEL8_Pos); // переключение на альтернативный режим работы порта AF7 MODIFY_REG(GPIOD->AFR[1], GPIO_AFRH_AFSEL9, 0x7 << GPIO_AFRH_AFSEL9_Pos); // переключение на альтернативный режим работы порта AF7 MODIFY_REG(GPIOD->MODER, GPIO_MODER_MODE10, 0x1 << GPIO_MODER_MODE10_Pos); // перевод порта на выход RE MODIFY_REG(GPIOD->OSPEEDR,GPIO_OSPEEDR_OSPEED10,0x2 << GPIO_OSPEEDR_OSPEED10_Pos); // настройка скорости фронта для RE скорость наибольшая MODIFY_REG(GPIOD->PUPDR, GPIO_PUPDR_PUPD10, 0x00 << GPIO_PUPDR_PUPD10_Pos); // отключение подтяжки SET_BIT(GPIOD->BSRR, GPIO_BSRR_BR10); //установка логического нуля на линии RE USART3->CR1 &= ~USART_CR1_UE; // отключение USART 3 для настройки while (USART3->CR1 & USART_CR1_UE); // проверяем что бит включения USART3 сброшен USART3->CR2 = 0x00; USART3->CR3 = USART_CR3_DMAT | USART_CR3_DMAR; // включение DMA USART3->PRESC = 0; // предделитель тактовой частоты USART3->BRR = 521; // установка скорости расчетная формула 521 USART3->CR1 |= USART_CR1_TE; // включение передатчика USART3->CR1 |= USART_CR1_RE; // включение приемника USART3->CR1 |= USART_CR1_UE; // включаем USART3 while (!(USART3->CR1 & USART_CR1_UE)); // проверяем что бит включения USART3 установлен RCC->AHB1ENR |= RCC_AHB1LPENR_DMA1LPEN; // подключаем DMA1 к шине AHB1 while (!(RCC->AHB1ENR & RCC_AHB1LPENR_DMA1LPEN)); // ждем гарантированого включения DMA1_Stream1->CR &= ~DMA_SxCR_EN; // выключаем DMA while (DMA1_Stream1->CR & DMA_SxCR_EN); // ждем чтобы гарантировано был отключен DMA DMA1_Stream1->CR = DMA_SxCR_MINC | DMA_SxCR_TCIE; // настройка ДМА для USART3 инкремент памяти, включение прерывания по завершению приема DMA1_Stream1->NDTR = 1; // количество данных для передачи с USART3 в ОЗУ буфер DMA1_Stream1->PAR = (uint32_t) &USART3->RDR; // адрес от куда брать данные DMA1_Stream1->M0AR = (uint32_t)&ExternalsBlocks_RX; // указываем адрес масива куда писать DMA1_Stream1->CR |= DMA_SxCR_EN; // включаем DMA while (!(DMA1_Stream1->CR & DMA_SxCR_EN)); // ждем гарантированого включения DMA1_Stream2->CR &= ~DMA_SxCR_EN; // выключаем DMA while (DMA1_Stream2->CR & DMA_SxCR_EN); // ждем чтобы гарантировано был отключен DMA DMA1_Stream2->CR = DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC; // настройка ДМА для USART3 инкремент памяти, передача из памяти ---> USART3 DMA1_Stream2->NDTR = 1; // количество данных для передачи с USART3 в ОЗУ буфер DMA1_Stream2->PAR = (uint32_t) &USART3->TDR; // адрес от куда брать данные DMA1_Stream2->M0AR = (uint32_t)&ExternalsBlocks_TX; // указываем адрес масива куда писать DMA1_Stream2->CR |= DMA_SxCR_EN; // включаем DMA while (!(DMA1_Stream2->CR & DMA_SxCR_EN)); // ждем гарантированого включения Добавил буферы: Скрытый текст __attribute__((section(".dma_buffer"))) uint8_t ExternalsBlocks_TX[256]; __attribute__((section(".dma_buffer"))) uint8_t ExternalsBlocks_RX[256]; Определил их в файле flash.id Скрытый текст .dma_buffer : { *(.dma_buffer) } >RAM_D3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 10 сентября, 2020 Опубликовано 10 сентября, 2020 · Жалоба А зачем их в какую-то отдельную секцию помещать ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 10 сентября, 2020 Опубликовано 10 сентября, 2020 · Жалоба 49 минут назад, Alex_Golubev сказал: Добавил связь DMA ---> USART3. И не смог запустить. Если делать по уму, то сначала настраивают какую-то периферию, и только потом - подключают к ней мультиплексором нужные пины. А не наоборот, как здесь - подключаются пины к ещё неинициализированной периферии. То же самое и с DMA: сперва настраивается DMA для обслуживания запросов периферии, и только потом - источник этих запросов (периферия). А не наоборот как здесь - сперва включается UART генерящий DMA-запрос неизвестно куда. PS: Вы бы хоть думали когда что-то делаете - для чего и почему что-ли.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 11 сентября, 2020 Опубликовано 11 сентября, 2020 · Жалоба Это не есть решение проблемы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 11 сентября, 2020 Опубликовано 11 сентября, 2020 (изменено) · Жалоба Забыли про DMAMUX (подставьте ваши значения и нужные каналы): 46 usart3_tx_dma 45 usart3_rx_dma #if CPUSTYLE_STM32MP1 || CPUSTYLE_STM32H7XX // DMAMUX init // DMAMUX1 channels 0 to 7 are connected to DMA1 channels 0 to 7 // DMAMUX1 channels 8 to 15 are connected to DMA2 channels 0 to 7 DMAMUX1_Channel0->CCR = 61 * DMAMUX_CxCR_DMAREQ_ID_0; // SPI3_RX #endif /* CPUSTYLE_STM32MP1 || CPUSTYLE_STM32H7XX */ Ну и кеши... Перед чтением invalidate или cleaninvalidate на приемный буфер, перед передачей clean на передающий. И убедиться что у вас не DTCM память. Изменено 11 сентября, 2020 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 11 сентября, 2020 Опубликовано 11 сентября, 2020 (изменено) · Жалоба И еще... а почему LP тактирование настраиваете? А сейчас - не LP - будете? RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; // включил DMA1 (void) RCC->AHB1ENR; Изменено 11 сентября, 2020 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 11 сентября, 2020 Опубликовано 11 сентября, 2020 · Жалоба 3 часа назад, GenaSPB сказал: Ну и кеши... Перед чтением invalidate или cleaninvalidate на приемный буфер, перед передачей clean на передающий. Это необязательно. Можно просто MPU настроить соответствующе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 11 сентября, 2020 Опубликовано 11 сентября, 2020 (изменено) · Жалоба Да. И гланды автогеном. Если есть механизм, зачем его нужно избегать? Кстати, в h7 на usart есть fifo. Лучше его а не dma для разумных скоростей применять. Проще. Изменено 11 сентября, 2020 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 11 сентября, 2020 Опубликовано 11 сентября, 2020 · Жалоба 1 час назад, GenaSPB сказал: Да. И гланды автогеном. Если есть механизм, зачем его нужно избегать? Зачем изобретать какой-то "механизм" если и без него работает? Цитата Кстати, в h7 на usart есть fifo. Лучше его а не dma для разумных скоростей применять. Проще. А лучше - и то и другое. 22 часа назад, dimka76 сказал: А зачем их в какую-то отдельную секцию помещать ? Затем, чтобы компоновщик разместил их в область памяти, с которой DMA умеет работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться