This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

MCB2300 only receiving last byte in UART1 FIFO

Hi, I'm having some issues with reading in a serial stream on UART1. For some reason, I'm only able to receive the last byte of my message.

Some code snippets:

/*----------------------------------------------------------------------------
  Defines for ring buffers
 *---------------------------------------------------------------------------*/
#define SER_BUF_SIZE               (128)               // serial buffer in bytes (power 2)
#define SER_BUF_MASK               (SER_BUF_SIZE-1ul)  // buffer size mask

/* Buffer read / write macros */
#define SER_BUF_RESET(serBuf)      (serBuf.rdIdx = serBuf.wrIdx = 0)
#define SER_BUF_WR(serBuf, dataIn) (serBuf.data[SER_BUF_MASK & serBuf.wrIdx++] = (dataIn))
#define SER_BUF_RD(serBuf)         (serBuf.data[SER_BUF_MASK & serBuf.rdIdx++])
#define SER_BUF_EMPTY(serBuf)      (serBuf.rdIdx == serBuf.wrIdx)
#define SER_BUF_FULL(serBuf)       (serBuf.rdIdx == serBuf.wrIdx+1)
#define SER_BUF_COUNT(serBuf)      (SER_BUF_MASK & (serBuf.wrIdx - serBuf.rdIdx))

// buffer type
typedef struct __SER_BUF_T {
  unsigned char data[SER_BUF_SIZE];
  unsigned int wrIdx;
  unsigned int rdIdx;
} SER_BUF_T;

void ser_InitPort (unsigned long baudrate, unsigned int  databits,
                  unsigned int  parity,   unsigned int  stopbits) {

  unsigned char lcr_p, lcr_s, lcr_d;
  unsigned long dll;

  switch (databits) {
    case 5:                                            // 5 Data bits
      lcr_d = 0x00;
    break;
    case 6:                                            // 6 Data bits
      lcr_d = 0x01;
    break;
    case 7:                                            // 7 Data bits
      lcr_d = 0x02;
    break;
    case 8:                                            // 8 Data bits
    default:
      lcr_d = 0x03;
    break;
  }

  switch (stopbits) {
    case 1:                                            // 1,5 Stop bits
    case 2:                                            // 2   Stop bits
      lcr_s = 0x04;
    break;
    case 0:                                            // 1   Stop bit
    default:
      lcr_s = 0x00;
    break;
  }

  switch (parity) {
    case 1:                                            // Parity Odd
      lcr_p = 0x08;
    break;
    case 2:                                            // Parity Even
      lcr_p = 0x18;
    break;
    case 3:                                            // Parity Mark
      lcr_p = 0x28;
    break;
    case 4:                                            // Parity Space
      lcr_p = 0x38;
    break;
    case 0:                                            // Parity None
    default:
      lcr_p = 0x00;
    break;
  }

  SER_BUF_RESET(ser_out);                              // reset out buffer
  SER_BUF_RESET(ser_in);                               // reset in buffer

  /* Note that the pclk is 12.0 MHz.      */
  dll = ((UART_CLK / baudrate) / 16UL);

  U1FDR = 0;                                           // Fractional divider not used
  U1LCR = 0x80 | lcr_d | lcr_p | lcr_s;                // Data bits, Parity,   Stop bit
  U1DLL = dll;                                         // Baud Rate @ 12 MHZ PCLK
  U1DLM = 0;                                           // High divisor latch
  U1LCR = 0x00 | lcr_d | lcr_p | lcr_s;                // DLAB = 0
  U1IER = 0x03;                                        // Enable TX/RX interrupts
  U1FCR = 0x07;                                        // FIFO enabled, reset Tx and Rx


  ser_txRestart = 1;                                   // TX fifo is empty

  /* Set up and enable the UART interrupt in the VIC */
  VICVectAddr7 = (unsigned long)ser_irq;             // Set interrupt function
  VICVectCntl7 = 0x0F;                                 // Set interrupt priority
  VICIntEnable = (1 << 7);                             // Enable interrupt

}

/*----------------------------------------------------------------------------
  serial port 1 interrupt
 *---------------------------------------------------------------------------*/
static __irq void ser_irq (void) {
  volatile unsigned long iir;

  iir = U1IIR;

  if ((iir & 0x4) || (iir & 0xC)) {                    // RDA or CTI pending
    while (U1LSR & 0x01) {                             // Rx FIFO is not empty
      SER_BUF_WR(ser_in, U1RBR);                       // Read Rx FIFO to buffer
    }
  }

  ser_lineState = ((U1MSR << 8) | U1LSR) & 0xE01E;     // update linestate

  VICVectAddr = 0;                                     // acknowledge interrupt
}

I can receive a single byte fine but when I send multiple bytes, the FIFO only contains the last byte of the message. The LSR RDR bit is only valid for one iteration and the RBR is only read once no matter how many bytes I send.

Thanks in advance.

0