Jeff Brown

MCF52235 UART Problems

Discussion created by Jeff Brown on Jul 30, 2006
Latest reply on Jul 31, 2006 by Butcher
Has anyone sucessfully used the UARTs in the 52235?
 
I thought I had them working but now some strange things are happening.
 
I know I am initializing correctly, my code basically matches the code generated by CFINIT.
 
Here is a brief explaination of what I am trying to do.
 
When I receive a character via the UART I put the data into a que.
The mainline code will check to que to see if any data is available.  When checking the que I disable the receive interrupt, the re-enable when the routine is finished.  When I disable the interrupt I first set the SR interrupt priority up to 7, disable the RX interrupt, then set the SR interrupt priority back to 0.
 
Now for what is happening.  When I disable the RX interrupt, a pending interrupt (INT14 for UART1) is getting set in the IPRL register.  As soon and I set the SR priority back to 0 the interrupt gets serviced. During the interrupt service routine I check the transmit que an if it is empty I disable the TX interrupt.  When I do that, the pending interrupt bit gets cleared.
 
I have include the relevant code and would appreciate if anyone could take a look at it.  Any pointers would be helpful.  I have also made sure the no interrupts share the same level and priority.
 
Code:uint16 UART0_BAUDTABLE[10] =
{
 (SYS_CLOCK/32)/300, 
 (SYS_CLOCK/32)/600, 
 (SYS_CLOCK/32)/1200, 
 (SYS_CLOCK/32)/2400, 
 (SYS_CLOCK/32)/4800, 
 (SYS_CLOCK/32)/9600, 
 (SYS_CLOCK/32)/19200, 
 (SYS_CLOCK/32)/38400, 
 (SYS_CLOCK/32)/57600, 
 (SYS_CLOCK/32)/115200, 
};
//*****************************************************************************//*//*  InitUART1 //* //* Initialize UART1.//* Default Settings:  9600,8,N,1//*              //*****************************************************************************void InitUART1(uint8 BaudRate){ // assign port pins to UART functions MCF_GPIO_PUBPAR = 0     | MCF_GPIO_PUBPAR_TXD1_TXD1     | MCF_GPIO_PUBPAR_RXD1_RXD1;        // Reset Receiver and Transmitter (UCR) MCF_UART1_UCR = MCF_UART_UCR_RESET_TX; MCF_UART1_UCR = MCF_UART_UCR_RESET_RX;     // Reset Mode Pointer MCF_UART1_UCR = MCF_UART_UCR_RESET_MR;  // Enable Interrupt Source (UIMR) // Transmit Interrupt will be enabled when que is not empty MCF_UART1_UIMR = 0     | MCF_UART_UIMR_RXRDY_FU;       MCF_INTC0_IMRL &= ~(0    | MCF_INTC_IMRL_MASK14    | MCF_INTC_IMRL_MASKALL); MCF_INTC0_ICR14 = 0b00110110; // level 6, priority 6     // Initialize Input Enable Control (UACR) MCF_UART1_UACR = 0;     // Select Receiver and Transmitter Clock (UCSR)   MCF_UART1_UBG2 = (uint8)UART1_BAUDTABLE[5];  MCF_UART1_UBG1 = (uint8)(UART1_BAUDTABLE[5] >> 8);   MCF_UART1_UCSR = 0 //Set Rx and Tx clocks to system clock     | MCF_UART_UCSR_TCS(MCF_UART_UCSR_TCS_SYS_CLK)     | MCF_UART_UCSR_RCS(MCF_UART_UCSR_TCS_SYS_CLK);       // Set Mode Register 1 (UMR1) MCF_UART1_UMR = 0 // RX Ready will generate interrupt     | MCF_UART_UMR_BC_8  // 8 bits/char     | MCF_UART_UMR_PM_NONE;  // no parity      // Set Mode Register 2 (UMR2) MCF_UART1_UMR = 0 // normal mode     | MCF_UART_UMR_SB_STOP_BITS_15; // stop bit width  // Enable Transmitter and Receiver (UCR) MCF_UART1_UCR = 0     | MCF_UART_UCR_TX_ENABLED     | MCF_UART_UCR_RX_ENABLED;}

 
Code:
//*****************************************************************************//*//*  UART1 Interrupt Routine //* //*              //*****************************************************************************__interrupt__void UART1Interrupt(void){uint8 temp; // Determine interrupt source if ((MCF_UART1_UISR & 4)) {  temp = MCF_UART1_URB;  MCF_UART1_UCR = MCF_UART_UCR_RESET_ERROR;  MCF_UART1_UCR = MCF_UART_UCR_BKCHGINT;  }  if ((MCF_UART1_UISR & MCF_UART_UISR_TXRDY) == MCF_UART_UISR_TXRDY) {  // Transmit Empty  if (UART1_q_TX_size() == 0)  {   // nothing more to send, shutoff TX interrupt   MCF_UART1_UIMR &= ~MCF_UART_UIMR_TXRDY;  }  else  {   // send the next byte    MCF_UART1_UTB = pull_UART1_TX_q();  } } if((MCF_UART1_UISR & MCF_UART_UISR_RXRDY_FU) == MCF_UART_UISR_RXRDY_FU) {  // Receive interrupt  // put the received byte on the que  // check error bit here  if (MCF_UART1_USR & (0xF0))  {   temp = MCF_UART1_URB;   MCF_UART1_UCR  = MCF_UART_UCR_RESET_ERROR;   MCF_UART1_UCR = MCF_UART_UCR_BKCHGINT;    }  else  {   add_UART1_RX_q(MCF_UART1_URB);   } }}

 
Code:
//*****************************************************************************//*//*  UART1_getchar //* //*              //*****************************************************************************uint16 UART1_getchar(void){uint16 RetVal; // set interrupt level to 7 mcf5xxx_wr_sr(0x2700);  // disable RX interrupt MCF_UART1_UIMR &= ~MCF_UART_UIMR_RXRDY_FU;  mcf5xxx_wr_sr(0x2000);  if (UART1_q_RX_size() == 0)  RetVal = QUE_EMPTY; // que is empty else {    RetVal = UART1_RX_Q[UART1_RX_Q_TAIL];  if (++UART1_RX_Q_TAIL == UART1_Q_MAX)  {   UART1_RX_Q_TAIL = 0;  } }  mcf5xxx_wr_sr(0x2700); // Re-enable RX interrupt MCF_UART1_UIMR |= MCF_UART_UIMR_RXRDY_FU;  mcf5xxx_wr_sr(0x2000);  return(RetVal); }

 

 

Outcomes