Пример #1
0
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
}
Пример #2
0
/*
 * 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;
    }