AnsweredAssumed Answered

UART Problem with MK60F12

Question asked by nicholasf on Mar 18, 2015
Latest reply on Mar 19, 2015 by nicholasf

I am using a K60 UART module to communicate with another device, and the communication works fine, except that the UART fails to trigger an interrupt when (UART0_S1) RDRF is set, even though (UART_C2) RIE was set during configuration.  I have read every thread on the Kinetis forum related to UART, and have found nothing of any use in my case.  

 

The K60's UART is not triggering an interrupt when the number of bytes received is equal to or greater than the watermark value.  UART0_C2's RIE bit is set, and the UART0_S1 RDRF is changing from 0 to 1, but no interrupt is being generated.  The UART0_C5 RDMAS bit is set to 0, so no DMA request is being generated, and the microcontroller is not calling an undefined interrupt or freezing up.  The UART module is receiving the data well, and RWFIFO, RCFIFO, and all the other registers are behaving normally, but no interrupt is being generated by the RDRF flag. 


There is some redundant code in the configuration, because I have been trying to make this work for the last two days, so please forgive the sloppy coding.

 

The configuration function and its call are as follows:

 

void uart_init (UART_MemMapPtr uartch, int sysclk, int baud, void * lon_vector, void * rx_tx_vector, void * err_vector) // sysclk is the module clock frequency in MHz

{

  register uint16_t ubd, brfa;

  uint8_t temp;

  unsigned short int LON = NULL, RX_TX = NULL, ERR = NULL;

 

 

  /* Enable the clock to the selected UART */

  if(uartch == UART0_BASE_PTR){

  SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;

  PORTA_GPCHR = ((0x0003C000))&0xFFFF0000 | PORT_PCR_MUX(3); // set pins to UART

  PORTA_GPCLR = ((0x0003C000)<<0x10)&0xFFFF0000 | PORT_PCR_MUX(3); // set pins to UART

  SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;

  LON = INT_UART0_LON;

  RX_TX = INT_UART0_RX_TX;

  ERR = INT_UART0_ERR;

  }else if (uartch == UART1_BASE_PTR){

  SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;

  RX_TX = INT_UART1_RX_TX;

  ERR = INT_UART1_ERR;

  }else if (uartch == UART2_BASE_PTR){

  SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;

  SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;

  PORTD_GPCLR = ((0x0000000F)<<0x10)&0xFFFF0000 | PORT_PCR_MUX(2); // set pins to UART

  RX_TX = INT_UART2_RX_TX;

  ERR = INT_UART2_ERR;

  }else if(uartch == UART3_BASE_PTR){

  SIM_SCGC4 |= SIM_SCGC4_UART3_MASK;

  RX_TX = INT_UART3_RX_TX;

  ERR = INT_UART3_ERR;

  }else if(uartch == UART4_BASE_PTR){

  SIM_SCGC1 |= SIM_SCGC1_UART4_MASK;

  SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;

  PORTE_GPCHR = ((0x0F000000))&0xFFFF0000 | PORT_PCR_MUX(3); // set pins to UART

  RX_TX = INT_UART4_RX_TX;

  ERR = INT_UART4_ERR;

  }else{

  SIM_SCGC1 |= SIM_SCGC1_UART5_MASK;

  RX_TX = INT_UART5_RX_TX;

  ERR = INT_UART5_ERR;

  }

 

  if(LON != NULL)

  int_disable(LON);

  int_disable(RX_TX);

  int_disable(ERR);

 

 

 

 

  UART_C2_REG(uartch) = 0x00; //UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK ); // Make sure that the transmitter and receiver are disabled while we change settings.

 

 

  UART_C1_REG(uartch) = 0; // Configure the UART for 8-bit mode, no parity We need all default settings, so entire register is cleared

 

 

  ubd = (uint16_t)(sysclk*62500/baud); // Calculate baud settings // (sysclk*1000000)/(baud*16)

 

 

  temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F)); // Save off the current value of the UARTx_BDH except for the SBR

 

 

  UART_BDH_REG(uartch) = temp | UART_BDH_SBR(((ubd & 0x1F00) >> 8));

  UART_BDL_REG(uartch) = (uint8_t)(ubd & UART_BDL_SBR_MASK);

 

 

  brfa = ((sysclk*2000/baud) - (ubd * 32)); // Determine if a fractional divider is needed to get closer to the baud rate // (sysclk*32000)/(baud*16)

 

 

  temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F)); // Save off the current value of the UARTx_C4 register except for the BRFA

 

 

  UART_C4_REG(uartch) = temp | UART_C4_BRFA(brfa); // set the baud rate fine adjust

 

 

  //begin  F

  UART_MODEM_REG(uartch) = UART_MODEM_TXRTSPOL_MASK | UART_MODEM_TXRTSE_MASK; // select RTS controlled by transmitter, with active high polarity // UART_MODEM_TXCTSE_MASK makes it so that the CTS value can block the transmitter

  UART_PFIFO_REG(uartch) |= UART_PFIFO_RXFE_MASK /*| UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFIFOSIZE(0b001)*/; // set transmit and receive buffer sizes

  UART_RWFIFO_REG(uartch) = UART_RWFIFO_RXWATER(0x1); // this value is the number of datawords in the FIFO that will set RIE interrupt

 

 

  while(UART_RCFIFO_REG(uartch)) // clean out the FIFO

  temp = UART_D_REG(uartch);  // reading D when the data register is empty causes the FIFO pointer to become misaligned

 

  if((UART_S1_REG(uartch) & UART_S1_RDRF_MASK)||(UART_SFIFO_REG(uartch) & (UART_SFIFO_RXOF_MASK | UART_SFIFO_TXOF_MASK))){// if receipt flag is set, clear the receipt flag

  //temp = UART_D_REG(uartch);  // read D to clear RDRF

  UART_SFIFO_REG(uartch) = UART_SFIFO_RXOF_MASK | UART_SFIFO_TXOF_MASK ; // clear over and underflow error flags

  }

  if((UART_S1_REG(uartch) & UART_S1_OR_MASK) || (UART_SFIFO_REG(uartch) & UART_SFIFO_RXUF_MASK)){

  UART_D_REG(uartch) = 0x00;  // write D to clear RDRF

  UART_SFIFO_REG(uartch) = UART_SFIFO_RXUF_MASK; // clear over and underflow error flags

  }

  temp = UART_SFIFO_REG(uartch);

  //UART_SFIFO_REG(uartch) = UART_SFIFO_RXOF_MASK | UART_SFIFO_RXUF_MASK | UART_SFIFO_TXOF_MASK ; // clear over and underflow error flags

  //UART_CFIFO_REG(uartch) = UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK;

 

 

  if((lon_vector!=NULL) && (LON != NULL)){

  ram_insertVector(LON, lon_vector);

  int_enable(LON);

  }if(rx_tx_vector != NULL){

  ram_insertVector(RX_TX, rx_tx_vector);

  UART_C2_REG(uartch) |= UART_C2_RIE_MASK; //  RIE enables the receiver full interrupt

  UART_S2_REG(uartch) &= ~UART_S2_LBKDE_MASK; //  if LBKDE is set, RDRF doesn't work

  UART_C5_REG(uartch) &= ~UART_C5_RDMAS_MASK; //  disable DMA select, so that receipt generates interrupt

  int_enable(RX_TX);

  }if(err_vector != NULL){

  ram_insertVector(ERR, err_vector);

  int_enable(ERR);

  }

 

  UART_C2_REG(uartch) |= (UART_C2_TE_MASK | UART_C2_RE_MASK ); // Enable receiver and transmitter

}

 

 

Initialization funciton call call:

  uart_init(UART0_BASE_PTR, core_frequency(), PROJECT_BAUD_RATE, NULL, project_rx, NULL);// initialize UART port

 

PROJECT_BAUD_RATE == 115200

'project_rx' is the name of the function to be called in the interrupt. 

Outcomes