2011-05-10 07:50 AM
I'm trying to get flow control working on Uart1 on the discovery board and am seeing some odd behavior. I have a little test program that receives 10 characters, pauses, and then echos them back. At the host (linux) side I'm using a cp2102 based usb/uart bridge with the flow control pins brought out. The cp2102 isn't consistently stopping when the stm32 raises RTS. When it continues to send, the stm32 lowers (enables) RTS and leaves RTS enabled until the next time the stm32 firmware reads a character from the uart buffer.
Obviously the cp2102 issue is outside the scope of this forum, but I'm surprised that the response of the stm32 uart is to enable RTS. I've attached a screenshot from the logic analyzer. I'm curious if anybody understands what's going on with the stm32 end of things. Here is my UART initialization and the key test loop: int uart_open (uint8_t uart, uint32_t baud, uint32_t flags) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructureTx; GPIO_InitTypeDef GPIO_InitStructureRx; if (uart == 1) { // Turn on clocks RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // Configure TX pin GPIO_InitStructureTx.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructureTx.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructureTx.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructureTx); // Configure RX pin GPIO_InitStructureRx.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructureRx.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructureRx.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructureRx); // Configure CTS pin GPIO_InitStructureRx.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructureRx.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructureRx.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructureRx); // Configure RTS pin GPIO_InitStructureTx.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructureTx.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructureTx.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructureTx); // Configure the UART USART_StructInit(&USART_InitStructure); USART_InitStructure.USART_BaudRate = baud; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; USART_Init(USART1,&USART_InitStructure); USART_Cmd(USART1, ENABLE); return 0; } } ssize_t uart_write(uint8_t uart, const void *buf, size_t nbyte) { int i; for (i = 0; i < nbyte; i++) { while (!(USART1->SR & USART_FLAG_TXE)); USART1->DR = ((uint8_t *) buf)[i]; } } ssize_t uart_read (uint8_t uart, void *buf, size_t nbyte) { int i; for (i = 0; i < nbyte; i++) { while (!(USART1->SR & USART_FLAG_RXNE)); ((uint8_t *) buf)[i] = USART1->DR & 0xff; } return i; } while(1) { Delay(20); uart_read(1, buf, 10); Delay(20); uart_write(1,buf,10); } #uart-flow-control #cts #rts2011-05-10 12:10 PM
I found a partial answer to my question. The cp2102 (and similarly the ftdi parts) continues to send 1 to several bytes after its CTS line goes high (RTS from the stm32).
Thus, the only way to reliably use it is to keep a software receive buffer and raise RTS with software (at the stm32) when the buffer is nearly full. I guess this begs the question -- what use is hardware controlled RTS on the stm32 if there is only a single character buffer ?2011-05-15 11:25 PM
''The cp2102 (and similarly the ftdi parts) continues to send 1 to several bytes after its CTS line goes high (RTS from the stm32)''
Yes, it is ''normal behaviour'' for any device to continue to send ''a few'' characters after flow control is asserted.
''I guess this begs the question -- what use is hardware controlled RTS on the stm32 if there is only a single character buffer?'' Yes, that is a very good question!/4108fad7
2014-03-05 12:01 AM