/*FUNCTION**********************************************************************
 *
 * Function Name : SPI_HAL_SetBaud
 * This function takes in the desired bitsPerSec (baud rate) and calculates the nearest
 * possible baud rate without exceeding the desired baud rate unless the baud rate requested is
 * less than the absolute minimum in which case the minimum baud rate will be returned. The returned
 * baud rate is in bits-per-second. It requires that the caller also provide the frequency of the
 * module source clock (in Hertz).
 *
 *END**************************************************************************/
uint32_t SPI_HAL_SetBaud(SPI_Type * base, uint32_t bitsPerSec, uint32_t sourceClockInHz)
{
    uint32_t prescaler, bestPrescaler;
    uint32_t rateDivisor, bestDivisor;
    uint32_t rateDivisorValue;
    uint32_t realBaudrate, bestBaudrate;
    uint32_t diff, min_diff;
    uint32_t baudrate = bitsPerSec;

    /* find combination of prescaler and scaler resulting in baudrate closest to the
     * requested value
     */
    min_diff = 0xFFFFFFFFU;

    /* Set the maximum divisor bit settings for each of the following divisors */
    bestPrescaler = 7;
    bestDivisor = 8;

    /* Set baud rate to minimum baud rate possible, adjust prescale divisor and divisor
     * bit settings in acutal divisor values
     */
    bestBaudrate = sourceClockInHz / ((bestPrescaler + 1) * (bestDivisor * 64));

    /* In all for loops, if min_diff = 0, the exit for loop*/
    for (prescaler = 0; (prescaler <= 7) && min_diff; prescaler++)
    {
        rateDivisorValue = 2U;  /* Initialize to div-by-2 */

        for (rateDivisor = 0; (rateDivisor <= 8U) && min_diff; rateDivisor++)
        {
            /* calculate actual baud rate, note need to add 1 to prescaler */
            realBaudrate = ((sourceClockInHz) /
                            ((prescaler + 1) * rateDivisorValue));

            /* calculate the baud rate difference based on the conditional statement*/
            /* that states that the calculated baud rate must not exceed the desired baud rate*/
            if (baudrate >= realBaudrate)
            {
                diff = baudrate-realBaudrate;
                if (min_diff > diff)
                {
                    /* a better match found */
                    min_diff = diff;
                    bestPrescaler = prescaler; /* Prescale divisor SPIx_BR register bit setting */
                    bestDivisor = rateDivisor; /* baud rate divisor SPIx_BR register bit setting */
                    bestBaudrate = realBaudrate;
                }
            }
            /* Multiply by 2 for each iteration, possible divisor values: 2, 4, 8, 16, ... 512 */
            rateDivisorValue *= 2U;
        }
    }

    /* write the best prescalar and baud rate scalar */
    SPI_WR_BR(base, SPI_BR_SPR(bestDivisor) | SPI_BR_SPPR(bestPrescaler));

    /* return the actual calculated baud rate*/
    return bestBaudrate;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : SPI_HAL_Init
 * Description   : RestoreS SPI to reset configuration.
 * This function basically resets all of the SPI registers to their default setting including
 * disabling the module.
 *
 *END**************************************************************************/
void SPI_HAL_Init(SPI_Type * base)
{
    SPI_WR_C1(base, SPI_C1_CPHA_MASK);
    SPI_WR_C2(base, 0);
    SPI_WR_BR(base, 0);

#if FSL_FEATURE_SPI_16BIT_TRANSFERS
    SPI_WR_MH(base, 0);
    SPI_WR_ML(base, 0);
#else
    SPI_WR_M(base, 0);
#endif
}
예제 #3
0
// See fsl_spi_hal.h for documentation of this function.
void spi_hal_reset(SPI_Type * baseAddr)
{
    // Restore those control and configuration registers which are used to
    // be operated
    SPI_WR_C1(baseAddr, SPI_C1_CPHA_MASK);
    SPI_WR_C2(baseAddr, 0);
    SPI_WR_BR(baseAddr, 0);

#if FSL_FEATURE_SPI_16BIT_TRANSFERS
    SPI_WR_ML(baseAddr, 0);
#else // FSL_FEATURE_SPI_16BIT_TRANSFERS
    SPI_WR_M(baseAddr, 0);
#endif // FSL_FEATURE_SPI_16BIT_TRANSFERS
}