Параллельная работа нескольких каналов DMA

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

Параллельная работа нескольких каналов DMA

Сообщение Alex-Elektron »

Доброго времени суток! Возникла необходимость запустить 3 ЮСАРТА на STM32, желательно через DMA. С одним каналом нет проблем. Не понятно, как запустить параллельно несколько каналов. Это вообще возможно?
ПС. Собственно, на прерываниях тоже вполне устроит. Но пока не получается настроить. Код следующий:

Код: Выделить всё

//--- Конфиг USART1 --------------------------------------------------------------------------------------------------------
USART1->BRR = 0x88C;
USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_TCIE;
NVIC_SetPriority (USART1_IRQn, 2);
NVIC_EnableIRQ(USART1_IRQn);
//-------------------------------------------------------------------------------------------------------------------------------

void put_char_rs232(uint8_t data){
	while(!(USART1->SR & USART_SR_TC)); 
	
	USART1->DR = data;
}


void USART1_IRQHandler(){
	if (USART1->SR & USART_SR_RXNE){ 
		USART1->SR&=~USART_SR_RXNE;
		uart_data = USART1->DR;
	}

	if(USART1->SR & USART_SR_TC){
		USART1->SR&=~USART_SR_TC;
		if(UartAnswers--)	USART1->DR = 'S';
	}
}



В бесконечном цикле с частотой 10 Гц посылаю

Код: Выделить всё

UartAnswers = 2;
put_char_rs232('B');
В порт летит постоянно 0x28. Остальная программа не выполняется. Такое ощущение, что где-то не сброшены флаги.
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Параллельная работа нескольких каналов DMA

Сообщение Reflector »

Для каждого Usart своя пара каналов, только их номера и меняются, потому не вижу в чем у тебя вообще проблема, если один канал работает...
Реклама
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

Re: Параллельная работа нескольких каналов DMA

Сообщение Alex-Elektron »

Проблема послать одновременно

Добавлено after 1 minute 21 second:
При работе на разных потоках никаких проблем нет, на разных каналах - есть.

Добавлено after 3 minutes 4 seconds:
Настройка DMA

Код: Выделить всё

void Start_DMA_USART1_Tx (uint8_t am_bytes, uint8_t *m_data){
		
    DMA2_Stream7->CR = 0;                           // Отключаем поток. Нужно обеспечить, чтобы не была вызвана
																										// функция Start_DMA_USART3_Rx, когда предыдущая передача 
                                                    // еще не завершилась, иначе данные будут потеряны.
    while(DMA2_Stream7->CR & DMA_SxCR_EN);          // ждем пока поток эффективно остановится
                                                    // поток готов к настройке
    DMA2_Stream7->PAR = (uint32_t) & USART1->DR;    // устанавливаем адрес периферии
    DMA2_Stream7->M0AR = (uint32_t) m_data;
    DMA2_Stream7->NDTR = am_bytes;									// количество байт
 
    DMA2_Stream7->CR = DMA_SxCR_EN | DMA_SxCR_DIR_0 | DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_TCIE ;   
	
    USART1->CR3 |= USART_CR3_DMAT;
		NVIC_EnableIRQ( DMA2_Stream7_IRQn );
}

void Start_DMA_USART6_Tx (uint8_t am_bytes, uint8_t *m_data){
		
    DMA2_Stream7->CR = 0;                           // Отключаем поток. Нужно обеспечить, чтобы не была вызвана
																										// функция Start_DMA_USART3_Rx, когда предыдущая передача 
                                                    // еще не завершилась, иначе данные будут потеряны.
    while(DMA2_Stream7->CR & DMA_SxCR_EN);          // ждем пока поток эффективно остановится
                                                    // поток готов к настройке
    DMA2_Stream7->PAR = (uint32_t) & USART6->DR;    // устанавливаем адрес периферии
    DMA2_Stream7->M0AR = (uint32_t) m_data;
    DMA2_Stream7->NDTR = am_bytes;									// количество байт
 
    DMA2_Stream7->CR = DMA_SxCR_EN | DMA_SxCR_DIR_0 | DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_0 |DMA_SxCR_MINC | DMA_SxCR_TCIE ;   
	
    USART6->CR3 |= USART_CR3_DMAT;
		NVIC_EnableIRQ( DMA2_Stream7_IRQn );
}
Запуск отправки данных (с частотой 10 Гц)

Код: Выделить всё

Start_DMA_USART1_Tx(rec_bt, config_6);	
			Start_DMA_USART6_Tx(rec_bt, config_6);
			
			DMA2_Stream7->CR |= DMA_SxCR_EN;

Добавлено after 4 minutes 30 seconds:
При этом по USART1 прилетает хотя бы 1й байт массива, а вот по USART6 вообще тишина
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Параллельная работа нескольких каналов DMA

Сообщение Reflector »

Ты хочешь прям совсем синхронно 3 канала запустить?
Реклама
Эиком - электронные компоненты и радиодетали
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

Re: Параллельная работа нескольких каналов DMA

Сообщение Alex-Elektron »

Совсем синхронно не получится, не ПЛИС всё таки. Хотя бы друг за другом - отправил посылку по USART1, следом эту же посылку отправляю по USART6. Засовывал уже даже в прерывание по окончанию передачи DMA отправку по USART6 - раз в 10 минут чё-то выкидывает.

Добавлено after 2 minutes 10 seconds:
О, даже раз в 10 минут перестал выкидывать
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Параллельная работа нескольких каналов DMA

Сообщение Reflector »

Мк какой? USART6 без USART1 я так понимаю нормально работает?
Реклама
Alex-Elektron
Встал на лапы
Сообщения: 113
Зарегистрирован: Сб янв 11, 2014 21:25:55

Re: Параллельная работа нескольких каналов DMA

Сообщение Alex-Elektron »

STM32f401, да, один без другого работает нормально

Добавлено after 1 minute 58 seconds:
Всё, нашёл проблему. Как обычно, невнимательность...

Добавлено after 1 minute 31 second:

Код: Выделить всё

void DMA2_Stream7_IRQHandler(void){
	if( DMA2->HISR & DMA_HISR_TCIF7){
		DMA2->HIFCR = DMA_HIFCR_CTCIF7;
	
		if((DMAState)<1){
			Start_DMA_USART6_Tx(rec_bt, config_6);
			DMAState++;
		}
		else{
			DMA2_Stream7->CR &=~ DMA_SxCR_EN;
		}
	
        }
}
В бесконечном цикле не обнулял DMAState. Спасибо, что уделили время!
Ответить

Вернуться в «ARM»