Esempio n. 1
0
void spi_frequency(spi_t *obj, int hz) {
    uint32_t error = 0;
    uint32_t p_error = 0xffffffff;
    uint32_t ref = 0;
    uint8_t  spr = 0;
    uint8_t  ref_spr = 0;
    uint8_t  ref_prescaler = 0;

    // bus clk
    uint32_t PCLK = bus_frequency();
    uint8_t prescaler = 1;
    uint8_t divisor = 2;

    for (prescaler = 1; prescaler <= 8; prescaler++) {
        divisor = 2;
        for (spr = 0; spr <= 8; spr++, divisor *= 2) {
            ref = PCLK / (prescaler*divisor);
            if (ref > (uint32_t)hz)
                continue;
            error = hz - ref;
            if (error < p_error) {
                ref_spr = spr;
                ref_prescaler = prescaler - 1;
                p_error = error;
            }
        }
    }

    // set SPPR and SPR
    obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
}
Esempio n. 2
0
void spi_frequency(spi_t *obj, int hz) {
    uint32_t f_error = 0;
    uint32_t p_error = 0xffffffff;
    uint32_t ref = 0;
    uint32_t br = 0;
    uint32_t ref_spr = 0;
    uint32_t ref_prescaler = 0;
    uint32_t ref_dr = 0;

    // bus clk
    uint32_t PCLK = bus_frequency();

    for (uint32_t i = 0; i < 4; i++) {
        for (br = 0; br <= 15; br++) {
            for (uint32_t dr = 0; dr < 2; dr++) {
                ref = (PCLK * (1U + dr) / baudrate_prescaler[i]) / baudrate_scaler[br];
                if (ref > (uint32_t)hz)
                    continue;
                f_error = hz - ref;
                if (f_error < p_error) {
                    ref_spr = br;
                    ref_prescaler = i;
                    ref_dr = dr;
                    p_error = f_error;
                }
            }
        }
    }

    // set PBR and BR
    obj->spi->CTAR[0] &= ~(SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK | SPI_CTAR_DBR_MASK);
    obj->spi->CTAR[0] |= (ref_prescaler << SPI_CTAR_PBR_SHIFT) | (ref_spr << SPI_CTAR_BR_SHIFT) | (ref_dr << SPI_CTAR_DBR_SHIFT);
}
Esempio n. 3
0
/******************************************************************************
 * Timer for us timing.
 ******************************************************************************/
static void pit_init(void) {
    SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;  // Clock PIT
    PIT->MCR = 0;  // Enable PIT

    pit_ldval = bus_frequency() / 1000000;

    PIT->CHANNEL[0].LDVAL = pit_ldval;  // 1us
    PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TIE_MASK;
    PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK;  // Start timer 1

    NVIC_SetVector(PIT0_IRQn, (uint32_t)pit0_isr);
    NVIC_EnableIRQ(PIT0_IRQn);
}
Esempio n. 4
0
/******************************************************************************
 * Timer for us timing.
 ******************************************************************************/
static void pit_init(void) {
    SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;   // Clock PIT
    PIT->MCR = 0;                       // Enable PIT
    
    // Channel 1
    PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF;
    PIT->CHANNEL[1].TCTRL = PIT_TCTRL_CHN_MASK;    // Chain to timer 0, disable Interrupts
    PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK;   // Start timer 1
    
    // Use channel 0 as a prescaler for channel 1
    PIT->CHANNEL[0].LDVAL = (bus_frequency() + 500000) / 1000000 - 1;
    PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK;    // Start timer 0, disable interrupts
}
Esempio n. 5
0
void us_ticker_init(void) {
    if (us_ticker_inited)
        return;
    us_ticker_inited = 1;
    
    SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;   // Clock PIT
    PIT->MCR = 0;                       // Enable PIT
    
    clk_mhz = bus_frequency() / 1000000;

    timer_init();
    ticker_init();
}