In general the dsPIC is well blessed with peripherals. The dsPIC30F6015 I am using at the moment has two serial ports in addition to a couple of SPI ports and an I2C port. These UARTs seem pretty easy to use as well. Still, like other peripherals on the dsPIC, they still found a way to catch me out. My own fault for not reading the data sheet properly. The trick here is to realise that there are FIFO buffers associated with the ports.

I had found myself sharing the function of the SDO1 pin with U1TX. This was short-sighted on my part and I shan’t be doing it again if I can help it.  Consequently, when I want to send data on the serial port, I have to turn off the SPI port and vice versa. This is not too much of a hardship but it is a bit irritating. It soon became apparent that I was loosing characters from the serial port whenever I turned it off. In fact I was losing four characters. After a bit of thought I checked with the data sheet and discovered the FIFO buffer. Originally the code to switch off the serial port looked like this:

void serialOff(void){
  U1MODEbits.UARTEN = 0;    // disable the uart
  U1STAbits.UTXEN = 0;      // disable transmission
  serialEnabled = 0;
}

This immediately disabled the port and made the U1TX pin available for other purposes. The UART transmit function looked like this:

int putUART(char c)
{
  if (serialEnabled){
    while (U1STAbits.UTXBF);  // wait for room in the transmit buffer
    U1TXREG = c;
  }
  return 0;
}

Even though I had left a clue in the comment, I ignored what the UTXBF flag really meant. According to the data sheet it just means that the output buffer has room in it. After the transmit shift register empties, hardware signals, through this flag, that there is at least one space available. A very convenient feature but, of course, turning off the serial port, can leave up to four characters still in the buffer and not transmitted. Further examination of the data sheet show another flag, U1STAbits.TRMT, which is set if there are no more characters in the buffer and the transmit shift register is empty. It is a simple enough matter to make the serialOff() function wait for the buffer to empty before disabling the port:

void serialOff(void){
  while (!U1STAbits.TRMT);  // wait for the transmit buffer to empty
  U1MODEbits.UARTEN = 0;    // disable the uart
  U1STAbits.UTXEN = 0;      // disable transmission
  serialEnabled = 0;
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.