Search code examples
serial-portmodemavr-gccflow-control

Atxmega USART flow control


I'm having some troubles with USART flow control on the Atxmega256. I'm communicating with a modem which uses RTS/CTS for flow control. Once the modem sets CTS to low, I want to stop sending data until it goes high again. I'm currently using interrupt driven USART routines and can't seem to find a good way to halt the sending. If i just stop sending when CTS goes low, the data allready in the send buffers will still be sent and therefore lost.

I've tried the follow to disable/enable sending:

if(false == clearToSend()) {
  USART_TxdInterruptLevel_Set(data->usart, USART_TXCINTLVL_OFF_gc);
  while(false == clearToSend()) {}
  USART_TxdInterruptLevel_Set(data->usart, USART_TXCINTLVL_LO_gc);
}

Unfortunately that seems to disable the sending permanently. Any ideas?

Best regards Fredrik


Solution

  • Once the start bit is sent to the wire, you have to send the rest of the bits including the stop bit or else you will corrupt the data. It is not possible to stop sending data instantly when CTS is deactivated, and it is a common practise to allow for a few extra bytes before the sending is halted.

    The XMEGA series does not have any deep USART FIFO, just the transmit shift register and a transmit holding register, so if your code stops writing to the USART as soon as the CTS is deactivated, you should be fine.