Skip to main content
ho_it
Associate III
June 28, 2013
Question

stm32f2xx USART RTS/CTS

  • June 28, 2013
  • 13 replies
  • 2348 views
Posted on June 28, 2013 at 07:52

May I know how can I configure my STM32F205 microcontroler for USART RTS/CTS???

I could not find any resource on the net, and my codes are below but it doesnt work: anyone can help me to configure the CTS/RTS UART configuration thanks!!!

// Enable GPIO clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOA, ENABLE);
// Enable USART2 clock 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
// Connect USART pins to AF7 
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); 
// Configure USART Tx and Rx as alternate function push-pull
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //USART Tx
GPIO_Init(GPIOA, &GPIO_InitStructure); 
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0; 
//GPIO_Init(GPIOA, &GPIO_InitStructure);
//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
// UART2
NVIC_InitTypeDef NVIC_InitStructure;
// Enable the USARTz Interrupt 
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
/* Enable USART2 Receive interrupts */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
/* Enable the USART2 */
USART_Cmd(USART2, ENABLE);

#uart-flow-control #uart.stm32-uart
This topic has been closed for replies.

13 replies

felipe
Associate III
July 31, 2013
Posted on July 31, 2013 at 13:44

I wanna know it to.

The different in my case is that i am using usart with DMA

Tesla DeLorean
Guru
July 31, 2013
Posted on July 31, 2013 at 14:22

For starters, all the pins should be in AF Mode

If you read the DR, on a RXNE interrupt it's going to re-enable reception, if you don't read DR it will keep re-entering the interrupt handler.

If you have buffers behind the USART, you might want to look at handling this manually.
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
sergio23
Associate
September 18, 2013
Posted on September 18, 2013 at 15:36

Hello,

I have the same problem as you had.

Did you solve it? How do you do?

Thank you in advance

Carmen

Tesla DeLorean
Guru
September 18, 2013
Posted on September 18, 2013 at 16:16

So what's the question here? How do you set up the hardware? or How do you read the bits in the status register and architect that into your buffering scheme?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
sergio23
Associate
September 19, 2013
Posted on September 19, 2013 at 08:02

Hello,

Thank you Clive1 for your fast answer. My question is how set up hardware to connect UART6 using RTS/CTS flow control. I have setup as I show below, and I don't receive any data, but I'm sure the other device is sending data:

USART_InitStructure.USART_BaudRate = 115200;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

/* Enable GPIO clock */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

/* Enable GPIO clock */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);

/* Enable UART clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);

/* Connect PXx to USARTx_Tx*/

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);

/* Connect PXx to USARTx_Rx*/

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);

/* Connect PXx to USARTx_RTS*/

GPIO_PinAFConfig(GPIOG, GPIO_PinSource12, GPIO_AF_USART6);

/* Connect PXx to USARTx_CTS*/

GPIO_PinAFConfig(GPIOG, GPIO_PinSource15, GPIO_AF_USART6);

// Configure USART Tx as alternate function

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Pin = TX_WIFI;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init (GPIOC, &GPIO_InitStructure);

// Configure USART Rx as alternate function

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Pin = RX_WIFI;

GPIO_Init (GPIOC, &GPIO_InitStructure);

// Configure USART RTS as alternate function

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Pin = RTS_WIFI;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init (GPIOG, &GPIO_InitStructure);

// Configure USART CTS as alternate function

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Pin = CTS_WIFI;

GPIO_Init (GPIOG, &GPIO_InitStructure);

/* USART configuration */

USART_Init (USART6, &USART_InitStructure);

/* Enable USART */

USART_Cmd (USART6, ENABLE);

I would like to know, what I'm doing wrong.

Thank you very much for your help

Carmen

gbigden
Associate III
September 9, 2015
Posted on September 09, 2015 at 12:43

Hi - why am I getting an overrun error? I am talking to a FT230 chips with cts/rts handshaking. Why is the cts/rts obviously not working? It is running in main()

//STM32F303x
void setupUART2( void ) 
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_StructInit(&USART_InitStructure); 
USART_DeInit(USART2);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_7); //CTS
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_7); //RTS
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7); //Tx
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_7); //Rx
//Configure USART2 pins: 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 57600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2,ENABLE);
}
char readUSART( void )
{
FlagStatus flagRXNE = RESET; //Receive data register not empty flag
char data=0;
flagRXNE = USART_GetFlagStatus(USART2, USART_FLAG_RXNE); 
if (flagRXNE == SET) 
{
data = USART_ReceiveData(USART2); //A read clears flagRXNE
}
else
{
data = 0;
}
if (USART_GetFlagStatus(USART2, USART_FLAG_ORE)==SET) ledOnOff( LED_10, ON ); 
if (data !=0) stringToUSART( &data, 1 ); //Echo test 
return( data );
}

Tesla DeLorean
Guru
September 9, 2015
Posted on September 09, 2015 at 14:20

I think you'd need to stick the pins on a logic analyzer to understand what the interaction is. Confirm the FT230 actually stops sending when requested to do so.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
gbigden
Associate III
September 9, 2015
Posted on September 09, 2015 at 15:48

It seems that I set RTS inactive high at the end of the first Rx byte, but then the FT230 sends me 2 bytes more before stopping. Going to have to take this up with them, because if it is the default behaviour it's serious

BTW, this site is seriously flaky. My real name is Dirk Bruere but I could not sign in under it and could not follow any recovery procedure

Tesla DeLorean
Guru
September 9, 2015
Posted on September 09, 2015 at 17:59

It's some hunk of junk from Microsoft, I've got a dead account here because the system uses an email id, and you can't change the email address, because who ever does that? It's about the most brain damaged forum software ever, and it's not like Microsoft didn't have access to two decades worth of working examples of how to do it properly... I'm so glad they've got so totally killed in the mobile space.

Yeah, I don't think FTDI is going to fix their silicon, any more than I think ST will. The 1-byte deep design is just lazy, and if you're going to put a deeper buffer behind it, and who wouldn't, I'd just manage the flow control there, where you have some margin and some control.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
jpeacock
Associate
September 9, 2015
Posted on September 09, 2015 at 20:06

Flow control has some latency, historically transmissions were never expected to stop immediately.  RTS is a highwater mark, buffer is nearly, not completely, full so the other side (DCE or DTE) should stop sending as soon as possible. 

This comes from how RTS/CTS were  first used with early phone modems like the Bell 202 (DCE or data communications equipment).  These were half duplex, message oriented and needed signals to control when to send and receive.  RTS requested a transmission to the DCE, CTS indicated the DCE could receive data.  There could be a significant delay due to line turnaround but eventually data went in a particular direction until the packet was complete.  The interface was synchronous so there was no byte by byte transfer, data always went in bursts and the application had to have enough room to handle the incoming packets.  RTS and CTS worked at message level, not byte level.

Fast forward 50 years and RTS/CTS sorta follow the same logic except RTS and CTS are decoupled for full duplex (remember the wonders of a Bell 212 modem? full duplex and 1200 baud!).  Deasserting RTS tells the other end to stop as soon as possible, but it may be several bytes, or even the rest of a packet, due to software protocols, hardware FIFOs and at least one extra byte if the shift register is in progress.  So on an STM32 USART you still have to accept data, preferably by DMA but by IRQ otherwise, and save the trailing data bytes until the far end stops.

Most likely that's what you see with the FTDI UART.  It's not a design error, there's no requirement for immediate halt on RTS request.  You see the internal hardware buffers emptying out the last few characters queued to transmit before RTS arrived.

As Clive points out there's only a one byte buffer on the USART RX, but that's not a design error either since DMA is available.  Other vendors rely on hardware FIFOs but DMA is more flexible since there's no fixed  limit on how many bytes can arrive, as long as the DMA buffer is sufficiently large enough to handle it.  I've used both methods, the DMA on an 'F405 is much more flexible than a fixed length FIFO.

  Jack Peacock