Flow control watermark behaviour

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_2112781
Level 4
Level 4
10 likes received 10 likes given 5 likes given

Hello, I am using the flow control for the UART communication as follow and I am surprised that I have to assert/de-assert the RTS line myself, I checked with an oscilloscope and the line never changes without my intervention.

I set it myself in the following code:

#define PIN_UART_TX     GPIO_PIN_UART_TX

#define PIN_UART_RX     GPIO_PIN_UART_RX

#define PIN_UART_RTS    GPIO_PIN_P1

#define PIN_UART_CTS    GPIO_PIN_P3

#define UART_BAUDRATE   115200

#define CONV_TO_UART_PAD(_X_)  ( (((_X_) / 16) << 5) | ((_X_) % 16) )

void puart_control_rx_int_callback(void)

{

     gpio_setPinOutput(PIN_UART_RTS/16, PIN_UART_RTS%16, GPIO_PIN_OUTPUT_HIGH);           

}

void puart_control_rx_callback(void* unused)

{

     while (puart_rxFifoNotEmpty() && puart_read(&readbyte))

     {

     }

     // clear the interrupt

     P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK);

     

     // enable UART interrupt in the Main Interrupt Controller and RX Almost Full in the UART Interrupt Controller

     P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK;

     gpio_setPinOutput(PIN_UART_RTS/16, PIN_UART_RTS%16, GPIO_PIN_OUTPUT_LOW);

}

void tw_puart_init(void

{

     puart_selectUartPads( CONV_TO_UART_PAD(PIN_UART_RX), CONV_TO_UART_PAD(PIN_UART_TX), CONV_TO_UART_PAD(PIN_UART_CTS), CONV_TO_UART_PAD(PIN_UART_RTS));

     puart_init();

     puart_flowOn();

     devlpm_init();

     devlpm_registerForLowPowerQueries(uart_device_lpm_queriable, 0);

     // Clear interrupt

     P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK);

 

     // Set RX watermark

     P_UART_WATER_MARK_RX_LEVEL(P_UART_WATER_MARK_RX_LEVEL_ONE_BYTE);

     P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK;

 

     // Set callback function to app callback function.

     puart_rxCb = puart_control_rx_callback;

     puart_rxIntCb = puart_control_rx_int_callback;

 

     puart_enableTx();

 

     // Set baud rate.

     puart_setBaudrate(0x00, 0x00, UART_BAUDRATE);

  

     // Enable the CPU level interrupt

     puart_enableInterrupt();

}

With this code, every time a byte is received, I de-assert the RTS line to block the RX and I assert it again at the end of the receive callback and it works.

But I find it pretty inefficient, blocking the line for every byte is not the best, since the RX FIFO is 16 bytes, the line should be de-asserted at 14-15 bytes received. I tried to achieve that by playing with the macros:

- P_UART_WATER_MARK_TX_LEVEL

- P_UART_WATER_MARK_RX_LEVEL

But I don't see any difference when changing the first one and for the second one, if I don't set it to 1 then I won't be able to receive data if the controller sends only one byte.

Could you provide some more information about the flow control and these watermarks macros ?

0 Likes
1 Reply
Anonymous
Not applicable

Hello marmottus,

Have you checked the other posts on the forum?

Problem with UART watermarks

Re: When is the puart rx callback called?

Let me know if this helps

JT

0 Likes