Exemple #1
0
/*!
 * brief Ungates the LPTMR clock and configures the peripheral for a basic operation.
 *
 * note This API should be called at the beginning of the application using the LPTMR driver.
 *
 * param base   LPTMR peripheral base address
 * param config A pointer to the LPTMR configuration structure.
 */
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config)
{
    assert(config);

#if defined(LPTMR_CLOCKS)
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)

    uint32_t instance = LPTMR_GetInstance(base);

    /* Ungate the LPTMR clock*/
    CLOCK_EnableClock(s_lptmrClocks[instance]);
#if defined(LPTMR_PERIPH_CLOCKS)
    CLOCK_EnableClock(s_lptmrPeriphClocks[instance]);
#endif

#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPTMR_CLOCKS */

    /* Configure the timers operation mode and input pin setup */
    base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) |
                 LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect));

    /* Configure the prescale value and clock source */
    base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) |
                 LPTMR_PSR_PCS(config->prescalerClockSource));
}
 /*FUNCTION**********************************************************************
 *
 * Function Name : LPTMR_HAL_SetTimerWorkingMode
 * Description   : Config the LPTMR working mode.
 *
 *END**************************************************************************/
void LPTMR_HAL_SetTimerWorkingMode(LPTMR_Type * base,  lptmr_working_mode_user_config_t timerMode)
{
    uint32_t csr;
    
    csr = LPTMR_RD_CSR(base);
    csr &= ~(LPTMR_CSR_TCF_MASK | LPTMR_CSR_TMS_MASK | LPTMR_CSR_TFC_MASK 
             | LPTMR_CSR_TPP_MASK | LPTMR_CSR_TPS_MASK);
    csr |= LPTMR_CSR_TMS(timerMode.timerModeSelect) 
        | LPTMR_CSR_TFC(timerMode.freeRunningEnable)
        | LPTMR_CSR_TPP(timerMode.pinPolarity) 
        | LPTMR_CSR_TPS(timerMode.pinSelect); 
    
    LPTMR_WR_CSR(base, csr);
}
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config)
{
    assert(config);

    /* Ungate the LPTMR clock*/
    CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]);

    /* Configure the timers operation mode and input pin setup */
    base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) |
                 LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect));

    /* Configure the prescale value and clock source */
    base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) |
                 LPTMR_PSR_PCS(config->prescalerClockSource));
}
int z_clock_driver_init(struct device *unused)
{
	u32_t csr, psr, sircdiv; /* LPTMR registers */

	ARG_UNUSED(unused);
	IRQ_CONNECT(DT_OPENISA_RV32M1_LPTMR_SYSTEM_LPTMR_IRQ,
		    SYSTEM_TIMER_IRQ_PRIO, lptmr_irq_handler, NULL, 0);

	if ((SCG->SIRCCSR & SCG_SIRCCSR_SIRCEN_MASK) == SCG_SIRCCSR_SIRCEN(0)) {
		/*
		 * SIRC is on by default, so something else turned it off.
		 *
		 * This is incompatible with this driver, which is SIRC-based.
		 */
		return -ENODEV;
	}

	/* Disable the timer and clear any pending IRQ. */
	csr = SYSTEM_TIMER_INSTANCE->CSR;
	csr &= ~LPTMR_CSR_TEN(0);
	csr |= LPTMR_CSR_TFC(1);
	SYSTEM_TIMER_INSTANCE->CSR = csr;

	/*
	 * Set up the timer clock source and configure the timer.
	 */

	/*
	 * SIRCDIV3 is the SIRC divider for LPTMR (SoC dependent).
	 * Pass it directly through without any divider.
	 */
	sircdiv = SCG->SIRCDIV;
	sircdiv &= ~SCG_SIRCDIV_SIRCDIV3_MASK;
	sircdiv |= SCG_SIRCDIV_SIRCDIV3(SIRCDIV3_DIVIDE_BY_1);
	SCG->SIRCDIV = sircdiv;
	/*
	 * TMS = 0: time counter mode, not pulse counter
	 * TCF = 0: reset counter register on reaching compare value
	 * TDRE = 0: disable DMA request
	 */
	csr &= ~(LPTMR_CSR_TMS(1) | LPTMR_CSR_TFC(1) | LPTMR_CSR_TDRE(1));
	/*
	 * TIE = 1: enable interrupt
	 */
	csr |= LPTMR_CSR_TIE(1);
	SYSTEM_TIMER_INSTANCE->CSR = csr;
	/*
	 * PCS = 0: clock source is SIRCDIV3 (SoC dependent)
	 * PBYP = 1: bypass the prescaler
	 */
	psr = SYSTEM_TIMER_INSTANCE->PSR;
	psr &= ~LPTMR_PSR_PCS_MASK;
	psr |= (LPTMR_PSR_PBYP(1) | LPTMR_PSR_PCS(PCS_SOURCE_SIRCDIV3));
	SYSTEM_TIMER_INSTANCE->PSR = psr;

	/*
	 * Set compare register to the proper tick count. The check
	 * here makes sure SIRC is left at its default reset value to
	 * make the defconfig setting work properly.
	 *
	 * TODO: be smarter to meet arbitrary Kconfig settings.
	 */
	if ((SCG->SIRCCFG & SCG_SIRCCFG_RANGE_MASK) != SIRC_RANGE_8MHZ) {
		return -EINVAL;
	}
	SYSTEM_TIMER_INSTANCE->CMR = CYCLES_PER_TICK;

	/*
	 * Enable interrupts and the timer. There's no need to clear the
	 * TFC bit in the csr variable, as it's already clear.
	 */
	irq_enable(DT_OPENISA_RV32M1_LPTMR_SYSTEM_LPTMR_IRQ);
	csr = SYSTEM_TIMER_INSTANCE->CSR;
	csr |= LPTMR_CSR_TEN(1);
	SYSTEM_TIMER_INSTANCE->CSR = csr;
	return 0;
}