void uart_init(void) { /* Supply the clock for UART0 and PORTA */ SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Set PORTA1 as Rx and PORTA2 as Tx */ PORTA->PCR[1] &= ~PORT_PCR_MUX_MASK; // Make sure that MUX is clear PORTA->PCR[1] |= PORT_PCR_MUX(2); PORTA->PCR[2] &= ~PORT_PCR_MUX_MASK; // Make sure that MUX is clear PORTA->PCR[2] |= PORT_PCR_MUX(2); /* Choose external 8MHz crystal as a reference clock for UART0 */ /* Asynch Module Clock = 8 MHz */ SIM->SOPT2 |= SIM_SOPT2_UART0SRC(2); /* Disable the reciever and transmitter of UART0 */ UART0->C2 &= ~(UART0_C2_TE_MASK | UART0_C2_RE_MASK); // turn off the Tx and Rx /* Set the oversampling ratio to 4 */ UART0->C4 = UART0_C4_OSR(3); /* Set SBr to 139 in order to achieve Baud Rate euqal to 14400 */ UART0->BDH |= UART0_BDH_SBR(0); UART0->BDL &= ~UART0_BDL_SBR_MASK; // clear BDL first UART0->BDL |= UART0_BDL_SBR(139); /* Set 1 Stop Bit */ UART0->BDH &= ~UART0_BDH_SBNS_MASK; /* Choose 8-bits long data */ UART0->C1 &= ~UART0_C1_M_MASK; /* Disable hardware parity check */ UART0->C1 &= ~UART0_C1_PE_MASK; /* Initialize the queues for the interrupts-driven serial communication */ q_init(&TxQ); q_init(&RxQ); /* Configure the interrupts from the UART0 */ NVIC_ClearPendingIRQ(UART0_IRQn); NVIC_EnableIRQ(UART0_IRQn); /* Enable the interrupt when receiver buffer gets full */ UART0->C2 |= UART0_C2_RIE_MASK; /* Turn on the receiver and transmitter */ UART0->C2 |= UART0_C2_TE_MASK | UART0_C2_RE_MASK; // turn on the Tx and Rx }
/* * Initialize the uart for 8N1 operation, interrupts disabled, and * no hardware flow-control * * NOTE: Since the uarts are pinned out in multiple locations on most * Kinetis devices, this driver does not enable uart pin functions. * The desired pins should be enabled before calling this init function. * * Parameters: * uart0clk uart module Clock in Hz(used to calculate baud) * baud uart baud rate */ status_t uart0_init (uint32_t uart0clk, uint32_t baud, uart0_data_sink_func_t function) { // Calculate SBR rounded to nearest whole number, 14.4 = 14, 14.6 = 15 // This gives the least error possible uint32_t sbr = (uint32_t)(((uart0clk * 10)/(baud * kUART0_OSR_Value)) + 5) / 10; uint32_t calculatedBaud = (uint32_t)(uart0clk/(sbr * kUART0_OSR_Value)); uint32_t baudDiff = MAX(calculatedBaud, baud) - MIN(calculatedBaud, baud); if (baudDiff < ((baud / 100) * 3)) { s_uart0_data_sink_callback = function; // Enable clocking to UART0 SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; // Disable UART0 before changing registers UART0->C2 &= ~(UART0_C2_TE_MASK | UART0_C2_RE_MASK); // Enable both edge since we are using a OSR value between 3 and 8 UART0->C5 |= UART0_C5_BOTHEDGE_MASK; // Setup OSR value uint32_t temp = UART0->C4; temp &= ~UART0_C4_OSR_MASK; temp |= UART0_C4_OSR(kUART0_OSR_Value - 1); // BaudRate = UARTClk / ((OSR + 1) * SBR) // Write temp to C4 register UART0->C4 = temp; // Save off the current value of the uartx_BDH except for the SBR field temp = UART0->BDH & ~(UART0_BDH_SBR(0x1F)); UART0->BDH = temp | UART0_BDH_SBR(((sbr & 0x1F00) >> 8)); UART0->BDL = (uint8_t)(sbr & UART0_BDL_SBR_MASK); // Enable receive interrupts UART0->C2 |= UART0_C2_RIE_MASK; NVIC_EnableIRQ(UART0_IRQn); // Enable receiver and transmitter UART0->C2 |= (UART0_C2_TE_MASK | UART0_C2_RE_MASK ); return kStatus_Success; }