1 Reply Latest reply on Dec 14, 2015 4:01 PM by jota_1939431

    Flow control watermark behaviour

    user_2112781

      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 ?