Board: KL25Z
I'm having trouble getting this example from my arm book to work. I'm supposed to setup UART0 and GPIOA, pins 1 and 2 to talk with OpenSDA which can communicate with my PC via Teraterm.
All I know is that in the Init_UART0() function, after Port A pins 1 and 2 are set(lines 84 & 85) to Tx and Rx the UART0_IRQHandler() immediately gets called and then the program gets stuck on the if statement that checks the Receive Data Register(line 158) like it's an infinite loop. I haven't sent any characters from my PC...
Any idea why this is happening or tips on how I can fix it?
#include "MKL25Z4.h"
#include <stdio.h>
#define UART_OVERSAMPLE_RATE (16)
#define SYS_CLOCK (48E6)
#define Q_MAX_SIZE (256)
typedef struct {
uint8_t Data[Q_MAX_SIZE];
unsigned int Head;
unsigned int Tail;
unsigned int Size;
} volatile Q_T;
Q_T TxQ;
Q_T RxQ;
void Init_UART0(uint32_t);
int Q_Enqueue(Q_T*, uint8_t);
uint8_t Q_Dequeue(Q_T* );
void Q_Init (Q_T* );
int Q_Empty (Q_T* );
int Q_Full (Q_T* );
int Q_Size (Q_T* );
int main(){
uint8_t buffer[80], myChar, * buffPtr;
Init_UART0(115200);
Q_Enqueue(&TxQ, 'a');
while(1){
while(Q_Size(&RxQ) == 0);
myChar = Q_Dequeue(&RxQ);
sprintf((char *)buffer, "You pressed %c\n\r",myChar);
buffPtr = buffer;
while(*buffPtr != '\0'){
while(Q_Full(&TxQ));
Q_Enqueue(&TxQ, *buffPtr);
buffPtr++;
}
if(!(UART0->C2 & UART0_C2_TIE_MASK)){
UART0->C2 |= UART0_C2_TIE(1);
}
}
}
void Init_UART0(uint32_t baudRate){
uint16_t sbr;
SIM->SCGC4 |= SIM_SCGC4_UART0_MASK;
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
UART0->C2 &= ~UART0_C2_TE_MASK & ~UART0_C2_RE_MASK;
SIM->SOPT2 |= SIM_SOPT2_UART0SRC(1);
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;
PORTA->PCR[1] = PORT_PCR_ISF_MASK | PORT_PCR_MUX(2);
PORTA->PCR[2] = PORT_PCR_ISF_MASK | PORT_PCR_MUX(2);
sbr = (uint16_t)((SYS_CLOCK)/(baudRate * UART_OVERSAMPLE_RATE));
UART0->BDH &= ~UART0_BDH_SBR_MASK;
UART0->BDH |= UART0_BDH_SBR(sbr>>8);
UART0->BDL = UART0_BDL_SBR(sbr );
UART0->C4 |= UART0_C4_OSR(UART_OVERSAMPLE_RATE - 1);
UART0->BDH |= UART0_BDH_RXEDGIE(0) | UART0_BDH_SBNS(0) | UART0_BDH_LBKDIE(0);
UART0->C1 |= UART0_C1_LOOPS(0) | UART0_C1_M(0) |UART_C1_PE(0);
UART0->C3 |= UART_C3_TXINV(0) | UART0_C3_ORIE(1) | UART0_C3_NEIE(1)
| UART0_C3_FEIE(1) | UART0_C3_PEIE(1);
UART0->S1 = UART0_S1_OR(1) | UART0_S1_NF(1) | UART0_S1_FE(1) | UART0_S1_PF(1);
UART0->S2 |= UART0_S2_MSBF(0) | UART0_S2_RXINV(0);
Q_Init(&TxQ);
Q_Init(&RxQ);
NVIC_SetPriority (UART0_IRQn, 2);
NVIC_ClearPendingIRQ(UART0_IRQn );
NVIC_EnableIRQ (UART0_IRQn );
UART0->C2 |= UART0_C2_RIE(1);
UART0->C2 |= UART0_C2_TE(1) | UART_C2_RE(1);
}
void UART0_IRQHandler(void){
uint8_t myChar;
if(UART0->S1 & (UART_S1_OR_MASK | UART_S1_NF_MASK |
UART_S1_FE_MASK | UART_S1_PF_MASK)){
UART0->S1 |= UART0_S1_OR_MASK | UART0_S1_NF_MASK |
UART0_S1_FE_MASK | UART0_S1_PF_MASK;
myChar = UART0->D;
}
if(UART0->S1 & UART0_S1_RDRF_MASK){
myChar = UART0->D;
if(!Q_Full(&RxQ)){
Q_Enqueue(&RxQ, myChar);
}
else{
}
}
if((UART0->C2 & UART0_C2_TIE_MASK) &&
(UART0->S1 & UART0_S1_TDRE_MASK)){
if(!Q_Empty(&TxQ)){
UART0->D = Q_Dequeue(&TxQ);
}
else{
UART0->C2 &= ~UART0_C2_TIE_MASK;
}
}
}
void Q_Init(Q_T* queue){
unsigned int i;
for(i = 0; i < Q_MAX_SIZE; i++)
queue->Data[i] = 0;
queue->Head = 0;
queue->Tail = 0;
queue->Size = 0;
}
int Q_Empty (Q_T* queue){
return queue->Size == 0;
}
int Q_Full (Q_T* queue){
return queue->Size == Q_MAX_SIZE;
}
int Q_Size (Q_T* queue){
return queue->Size;
}
int Q_Enqueue(Q_T* queue, uint8_t data){
uint32_t masking_state;
if(!Q_Full(queue)){
queue->Data[queue->Tail++] = data;
queue->Tail%= Q_MAX_SIZE;
masking_state = __get_PRIMASK();
__disable_irq();
queue->Size++;
__set_PRIMASK(masking_state);
return 1;
}else
return 0;
}
uint8_t Q_Dequeue(Q_T* queue){
uint8_t masking_state;
uint8_t transmition = 0;
if(!Q_Empty(queue)){
transmition = queue->Data[queue->Head];
queue->Data[queue->Head++] = '_';
queue->Head %= Q_MAX_SIZE;
masking_state = __get_PRIMASK();
__disable_irq();
queue->Size;
__set_PRIMASK(masking_state);
}
return transmition;
}