STM32F4'de Uart Bridge Kurulumu ve FIFO konusu

Başlatan Mucit23, 02 Nisan 2021, 13:34:33

Mucit23

Selamlar

STM32F449 da farklı uart kanallarında farklı aygıtlarım var. Bu aygıtları STM32F4 üzerinde Uart biridge kullanarak bir birine yönlendirmeye çalışıyorum.

Örneğin Uart4 RX kanalından gelen veriyi DMA USART1'TX üzerinden yollamak istiyorum. Çok öncelerden bunu STM32F1 ile yapmıştım. Şimdi Aynı işlemleri Cortex M4 ile yapmaya çalışıyorum. USART1, UART4 ile DMA ayarlarını yaptım. USART1 ile kendim veri gönderebiliyorum. 

UART4 Ayarlarını yaptım. DMA ile gelen veri yi herhangi bir değişkene alabiliyorum. DMA TC kesmesi oluşuyor.

void UART4_DMA_Configuration(void)
{
	USART_InitTypeDef USART_InitStruct;
	GPIO_InitTypeDef 	GPIO_InitStruct;
	DMA_InitTypeDef  DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
	// Enable clock for GPIOA
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  /* DMA1 clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_UART4);  //UART4_TX
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_UART4);  //UART4_RX
		
	// Initialize pins as alternating function
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	USART_InitStruct.USART_BaudRate = 38400;
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStruct.USART_Parity = USART_Parity_No;
	USART_InitStruct.USART_StopBits = USART_StopBits_1;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;
	USART_Init(UART4, &USART_InitStruct);
	
	/* Configure DMA Initialization Structure */
	DMA_DeInit(DMA1_Stream2);
  DMA_InitStructure.DMA_BufferSize = 1 ;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(UART4->DR)) ;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  /* Configure RX DMA */
  DMA_InitStructure.DMA_Channel = DMA_Channel_4 ;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;
  DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t) (&Uart4_Rx_Buffer); 
  DMA_Init(DMA1_Stream2,&DMA_InitStructure);
	
		/* Configure the Priority Group to 2 bits */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	/* Enable the UART4 RX DMA Interrupt */
	NVIC_InitStruct.NVIC_IRQChannel = DMA1_Stream2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStruct);
	
			  /* Enable DMA USART RX Stream */
  DMA_Cmd(DMA1_Stream2,ENABLE);
  
	DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE); 
  /* Enable USART DMA RX Requsts */
  USART_DMACmd(UART4, USART_DMAReq_Rx, ENABLE);

	USART_Cmd(UART4, ENABLE);
}

DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(UART4->DR)) ; Donanım Adresini UART4_DR_BASE yaptık.
Memory Adresini aşağıdaki gibi bir değişken olarak gösterirsem sorun yok.

DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t) (&Uart4_Rx_Buffer);

Fakat Hedef Adresi &USART1->DR verdiğim zaman çalışmıyor. USART1 Ayarları başka bir fonksiyonda yapıyorum ve Tek başına USART1 üzerinden veri gönderebiliyorum.

STM32F4 Serisinin Blok diyagramına baktığımda USART1 ve USART6'nın'in APB2 Bus'unda yer aldığını görüyorum. USART2,USART3, UART4 ve UART5 ise APB1 de yer alıyor


Bu durumda Teknik olarak iki farklı Bus'da yer alan donanımı DMA ile bir birine bağlamak mümkün olmuyor mu?

İkinci sorum şu. Eğer böyle bir uygulamada iki tarafında uart hızları aynı ise FIFO ya gerek olur mu?

RaMu

Direk cevap değil ama bus matrix diye bir kısım var,
o kısımda biraz daha faydalı bilgiler olabiliyor,
ilgili mcu için bulup bakmak lazım:

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Tagli

#2
@RaMu 'nun verdiği şemada gözüktüğü üzere DMA1'in memory port'unun APB2 bağlantısı yok. Aslında pek de şaşırtıcı bir durum değil, adı üstünde zaten.

DMA ile ilgili daha ayrıntılı bir bağlantı şeması referans dokümanında mevcut:



Her iki şekilden de aynı sonuç çıkıyor.

Düzeltme: Aslında yanlış şekli eklemişim, bir sayfa aşağıdaki Şekil 34 olmalıydı. Ama pek fark yok ikisi arasında, sonuç yine aynı.
Gökçe Tağlıoğlu

Mucit23

Evet sanırım teknik olarak mümkün değil. Rx kesmeleri içinde gelen veriyi yönlendirmek daha iyi gibi.