static inline void smi_set_address(struct bcm2835_smi_instance *inst, unsigned int address) { int smia_temp = 0, smida_temp = 0; SET_BIT_FIELD(smia_temp, SMIA_ADDR, address); SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address); /* Write to both address registers - user doesn't care whether we're doing programmed or direct transfers. */ write_smi_reg(inst, smia_temp, SMIA); write_smi_reg(inst, smida_temp, SMIDA); }
/***************************************************************************//** * @brief * Sets the ACMP channel used for capacative sensing. * * @note * A basic example of capacative sensing can be found in the STK BSP * (capsense demo). * * @param[in] acmp * Pointer to ACMP peripheral register block. * * @param[in] channel * The ACMP channel to use for capacative sensing (Possel). ******************************************************************************/ void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel) { /* Make sure that only external channels are used */ EFM_ASSERT(channel <= _ACMP_INPUTSEL_POSSEL_CH7); /* Set channel as positive channel in ACMP */ SET_BIT_FIELD(acmp->INPUTSEL, _ACMP_INPUTSEL_POSSEL_MASK, channel, _ACMP_INPUTSEL_POSSEL_SHIFT); }
/***************************************************************************//** * @brief * Sets up GPIO output from the ACMP. * * @note * GPIO must be enabled in the CMU before this function call, i.e. * @verbatim CMU_ClockEnable(cmuClock_GPIO, true); @endverbatim * * @param[in] acmp * Pointer to the ACMP peripheral register block. * * @param location * The pin location to use. See the datasheet for location to pin mappings. * * @param enable * Enable or disable pin output. * * @param invert * Invert output. ******************************************************************************/ void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert) { /* Sanity checking of location */ EFM_ASSERT(location < 4); /* Set GPIO inversion */ SET_BIT_FIELD(acmp->CTRL, _ACMP_CTRL_GPIOINV_MASK, invert, _ACMP_CTRL_GPIOINV_SHIFT); acmp->ROUTE = (location << _ACMP_ROUTE_LOCATION_SHIFT) | (enable << _ACMP_ROUTE_ACMPPEN_SHIFT); }
/***************************************************************************//** * @brief * Sets up GPIO output from the ACMP. * * @note * GPIO must be enabled in the CMU before this function call, i.e. * @verbatim CMU_ClockEnable(cmuClock_GPIO, true); @endverbatim * * @param[in] acmp * Pointer to the ACMP peripheral register block. * * @param location * The pin location to use. See the datasheet for location to pin mappings. * * @param enable * Enable or disable pin output. * * @param invert * Invert output. ******************************************************************************/ void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert) { /* Sanity checking of location */ #if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_TINY_FAMILY) EFM_ASSERT(location <= _ACMP_ROUTE_LOCATION_LOC3); #elif defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY) EFM_ASSERT(location <= _ACMP_ROUTE_LOCATION_LOC2); #else #error Illegal pin location (ACMP). #endif /* Set GPIO inversion */ SET_BIT_FIELD(acmp->CTRL, _ACMP_CTRL_GPIOINV_MASK, invert, _ACMP_CTRL_GPIOINV_SHIFT); acmp->ROUTE = (location << _ACMP_ROUTE_LOCATION_SHIFT) | (enable << _ACMP_ROUTE_ACMPPEN_SHIFT); }
void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst) { struct smi_settings *settings = &inst->settings; int smidsr_temp = 0, smidsw_temp = 0, smics_temp, smidcs_temp, smidc_temp = 0; spin_lock(&inst->transaction_lock); /* temporarily disable the peripheral: */ smics_temp = read_smi_reg(inst, SMICS); write_smi_reg(inst, 0, SMICS); smidcs_temp = read_smi_reg(inst, SMIDCS); write_smi_reg(inst, 0, SMIDCS); if (settings->pack_data) smics_temp |= SMICS_PXLDAT; else smics_temp &= ~SMICS_PXLDAT; SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width); SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time); SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time); SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time); SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time); write_smi_reg(inst, smidsr_temp, SMIDSR0); SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width); if (settings->data_width == SMI_WIDTH_8BIT) smidsw_temp |= SMIDSW_WSWAP; else smidsw_temp &= ~SMIDSW_WSWAP; SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time); SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time); SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time); SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE, settings->write_strobe_time); write_smi_reg(inst, smidsw_temp, SMIDSW0); SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh); SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh); SET_BIT_FIELD(smidc_temp, SMIDC_PANICR, settings->dma_panic_read_thresh); SET_BIT_FIELD(smidc_temp, SMIDC_PANICW, settings->dma_panic_write_thresh); if (settings->dma_passthrough_enable) { smidc_temp |= SMIDC_DMAP; smidsr_temp |= SMIDSR_RDREQ; write_smi_reg(inst, smidsr_temp, SMIDSR0); smidsw_temp |= SMIDSW_WDREQ; write_smi_reg(inst, smidsw_temp, SMIDSW0); } else smidc_temp &= ~SMIDC_DMAP; if (settings->dma_enable) smidc_temp |= SMIDC_DMAEN; else smidc_temp &= ~SMIDC_DMAEN; write_smi_reg(inst, smidc_temp, SMIDC); /* re-enable (if was previously enabled) */ write_smi_reg(inst, smics_temp, SMICS); write_smi_reg(inst, smidcs_temp, SMIDCS); spin_unlock(&inst->transaction_lock); }