Exemple #1
0
/***************************************************************************//**
 * @brief
 *   Enable/disable the selected PRS input of PCNT.
 *
 * @details
 *   Notice that this function does not do any configuration.
 *
 * @param[in] pcnt
 *   Pointer to PCNT peripheral register block.
 *
 * @param[in] prsInput
 *   PRS input (S0 or S1) of the selected PCNT module.
 *
 * @param[in] enable
 *   Set to true to enable, false to disable the selected PRS input.
 ******************************************************************************/
void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
                         PCNT_PRSInput_TypeDef prsInput,
                         bool enable)
{
  EFM_ASSERT(PCNT_REF_VALID(pcnt));

  /* Enable/disable the selected PRS input on the selected PCNT module. */
  switch (prsInput)
  {
  /* Enable/disable PRS input S0. */
  case pcntPRSInputS0:
  {
    BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S0PRSEN_SHIFT, (uint32_t)enable);
  }
  break;

  /* Enable/disable PRS input S1. */
  case pcntPRSInputS1:
  {
    BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S1PRSEN_SHIFT, (uint32_t)enable);
  }
  break;

  /* Invalid parameter, asserted. */
  default:
  {
    EFM_ASSERT(0);
  }
  break;
  }
}
Exemple #2
0
/***************************************************************************//**
 * @brief
 *   Reset PCNT to same state as after a HW reset.
 *
 * @details
 *   Notice the LFACLK must be enabled, since some basic reset is done with
 *   this clock. The pulse counter clock for the selected instance must also
 *   be enabled prior to init.
 *
 * @note
 *   The ROUTE register is NOT reset by this function, in order to allow for
 *   centralized setup of this feature.
 *
 * @param[in] pcnt
 *   Pointer to PCNT peripheral register block.
 ******************************************************************************/
void PCNT_Reset(PCNT_TypeDef *pcnt)
{
  unsigned int inst;

  EFM_ASSERT(PCNT_REF_VALID(pcnt));

  /* Map pointer to instance and clock info */
  inst = PCNT_Map(pcnt);

  pcnt->IEN = _PCNT_IEN_RESETVALUE;

  /* Notice that special SYNCBUSY handling is not applicable for the RSTEN
   * bit of the control register, so we don't need to wait for it when only
   * modifying RSTEN. The SYNCBUSY bit will be set, leading to a
   * synchronization in the LF domain, with in reality no changes to LF domain.
   * Enable reset of CNT and TOP register. */
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);

  /* Select LFACLK as default */
  CMU_PCNTClockExternalSet(inst, false);

  PCNT_TopBufferSet(pcnt, _PCNT_TOPB_RESETVALUE);

  /* Reset CTRL leaving RSTEN set */
  pcnt->CTRL = _PCNT_CTRL_RESETVALUE | PCNT_CTRL_RSTEN;

  /* Disable reset after CTRL reg has been synchronized */
  PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);

  /* Clear pending interrupts */
  pcnt->IFC = _PCNT_IFC_MASK;

  /* Do not reset route register, setting should be done independently */
}
Exemple #3
0
/***************************************************************************//**
 * @brief
 *   Configure the LESENSE alternate excitation modes.
 *
 * @details
 *   This function configures the alternate excitation channels of the LESENSE
 *   interface. Please refer to the configuration parameter type definition
 *   (LESENSE_ConfAltEx_TypeDef) for more details.
 *
 * @note
 *   Parameter @p useAltEx must be true in the channel configuration structrure
 *   (LESENSE_ChDesc_TypeDef) in order to use alternate excitation pins on the
 *   channel.
 *
 * @param[in] confAltEx
 *   Configuration structure for LESENSE alternate excitation pins.
 ******************************************************************************/
void LESENSE_AltExConfig(LESENSE_ConfAltEx_TypeDef const *confAltEx)
{
  uint32_t i;
  uint32_t tmp;


  /* Configure alternate excitation mapping.
   * Atomic read-modify-write using BITBAND_Peripheral function in order to
   * support reconfiguration during LESENSE operation. */
  BITBAND_Peripheral(&(LESENSE->CTRL),
                     _LESENSE_CTRL_ALTEXMAP_SHIFT,
                     (uint32_t)confAltEx->altExMap);

  switch (confAltEx->altExMap)
  {
  case lesenseAltExMapALTEX:
    /* Iterate through the 8 possible alternate excitation pin descriptors. */
    for (i = 0U; i < 8U; ++i)
    {
      /* Enable/disable alternate excitation pin i.
       * Atomic read-modify-write using BITBAND_Peripheral function in order to
       * support reconfiguration during LESENSE operation. */
      BITBAND_Peripheral(&(LESENSE->ROUTE),
                         (16UL + i),
                         (uint32_t)confAltEx->AltEx[i].enablePin);
 
      /* Setup the idle phase state of alternate excitation pin i.
       * Read-modify-write in order to support reconfiguration during LESENSE
       * operation. */
      tmp                = (LESENSE->ALTEXCONF & ~((uint32_t)0x3UL << (i * 2UL)));
      tmp               |= ((uint32_t)confAltEx->AltEx[i].idleConf << (i * 2UL));
      LESENSE->ALTEXCONF = tmp;
      
      /* Enable/disable always excite on channel i */
      BITBAND_Peripheral(&(LESENSE->ALTEXCONF),
                         (16UL + i),
                         (uint32_t)confAltEx->AltEx[i].alwaysEx);
    }
    break;

  case lesenseAltExMapACMP:
    /* Iterate through all the 16 alternate excitation channels */
    for (i = 0U; i < 16U; ++i)
    {
      /* Enable/disable alternate ACMP excitation channel pin i. */
      /* Atomic read-modify-write using BITBAND_Peripheral function in order to
       * support reconfiguration during LESENSE operation. */
      BITBAND_Peripheral(&(LESENSE->ROUTE),
                         i,
                         (uint32_t)confAltEx->AltEx[i].enablePin);
    }
    break;
  default:
    /* Illegal value. */
    EFM_ASSERT(0);
  }
}
Exemple #4
0
/***************************************************************************//**
 * @brief
 *   Restore BURTC to reset state
 * @note
 *   Before accessing the BURTC, BURSTEN in RMU->CTRL must be cleared.
 *   LOCK will not be reset to default value, as this will disable access
 *   to core BURTC registers.
 ******************************************************************************/
void BURTC_Reset(void)
{
  bool buResetState;

  /* Read reset state, set reset and restore state */
  buResetState = BITBAND_PeripheralRead(&RMU->CTRL, _RMU_CTRL_BURSTEN_SHIFT);
  BITBAND_Peripheral(&RMU->CTRL, _RMU_CTRL_BURSTEN_SHIFT, 1);
  BITBAND_Peripheral(&RMU->CTRL, _RMU_CTRL_BURSTEN_SHIFT, buResetState);
}
Exemple #5
0
/***************************************************************************//**
 * @brief
 *   Reset PCNT counters and TOP register.
 *
 * @note
 *   Notice that special SYNCBUSY handling is not applicable for the RSTEN
 *   bit of the control register, so we don't need to wait for it when only
 *   modifying RSTEN. (It would mean undefined wait time if clocked by external
 *   clock.) The SYNCBUSY bit will however be set, leading to a synchronization
 *   in the LF domain, with in reality no changes.
 *
 * @param[in] pcnt
 *   Pointer to PCNT peripheral register block.
 ******************************************************************************/
void PCNT_CounterReset(PCNT_TypeDef *pcnt)
{
  EFM_ASSERT(PCNT_REF_VALID(pcnt));

  /* Enable reset of CNT and TOP register */
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);

  /* Disable reset of CNT and TOP register */
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
}
__LINK_C error_t hw_gpio_enable_interrupt(pin_id_t pin_id)
{
    //to be absolutely safe we should put atomic blocks around this fuction but:
    //interrupts[..].interrupt_port && interrupts[..].callback will never change once they've
    //been properly set so I think we can risk it and avoid the overhead
    if(interrupts[pin_id.pin].interrupt_port != pin_id.port || interrupts[pin_id.pin].callback == 0x0)
    	return EOFF;

    BITBAND_Peripheral(&(GPIO->IFC), pin_id.pin, 1);
    BITBAND_Peripheral(&(GPIO->IEN), pin_id.pin, 1);
    return SUCCESS;
}
Exemple #7
0
/***************************************************************************//**
 * @brief
 *   Configure write operation parameters for selected bank
 *
 * @param[in] banks
 *   Mask of memory bank(s) to configure write timing for
 *
 * @param[in] writeBufDisable
 *   If true, disable the write buffer
 *
 * @param[in] halfWE
 *   Enables or disables half cycle WE strobe in last strobe cycle
 ******************************************************************************/
void EBI_BankWriteTimingConfig(uint32_t banks, bool writeBufDisable, bool halfWE)
{
    /* Verify only valid banks are used */
    EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);

    /* Configure write operation parameters */
    if( banks & EBI_BANK0 )
    {
        BITBAND_Peripheral(&EBI->WRTIMING, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
        BITBAND_Peripheral(&EBI->WRTIMING, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
    }
    if( banks & EBI_BANK1 )
    {
        BITBAND_Peripheral(&EBI->WRTIMING1, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
        BITBAND_Peripheral(&EBI->WRTIMING1, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
    }
    if( banks & EBI_BANK2 )
    {
        BITBAND_Peripheral(&EBI->WRTIMING2, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
        BITBAND_Peripheral(&EBI->WRTIMING2, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
    }
    if( banks & EBI_BANK3 )
    {
        BITBAND_Peripheral(&EBI->WRTIMING3, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
        BITBAND_Peripheral(&EBI->WRTIMING3, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
    }
}
Exemple #8
0
/***************************************************************************//**
 * @brief
 *   Initialize watchdog (assuming the watchdog configuration has not been
 *   locked).
 *
 * @note
 *   This function modifies the WDOG CTRL register which requires
 *   synchronization into the low frequency domain. If this register is modified
 *   before a previous update to the same register has completed, this function
 *   will stall until the previous synchronization has completed.
 *
 * @param[in] init
 *   Structure holding watchdog configuration. A default setting
 *   #WDOG_INIT_DEFAULT is available for init.
 ******************************************************************************/
void WDOG_Init(const WDOG_Init_TypeDef *init)
{
  uint32_t setting;

  if (init->enable)
  {
    setting = WDOG_CTRL_EN;
  }
  else
  {
    setting = 0;
  }

  if (init->debugRun)
  {
    setting |= WDOG_CTRL_DEBUGRUN;
  }

  if (init->em2Run)
  {
    setting |= WDOG_CTRL_EM2RUN;
  }

  if (init->em3Run)
  {
    setting |= WDOG_CTRL_EM3RUN;
  }

  if (init->em4Block)
  {
    setting |= WDOG_CTRL_EM4BLOCK;
  }

  if (init->swoscBlock)
  {
    setting |= WDOG_CTRL_SWOSCBLOCK;
  }

  setting |= ((uint32_t)(init->clkSel) << _WDOG_CTRL_CLKSEL_SHIFT) |
             ((uint32_t)(init->perSel) << _WDOG_CTRL_PERSEL_SHIFT);

  /* Wait for any pending previous write operation to have been completed in */
  /* low frequency domain */
  while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL) ;

  WDOG->CTRL = setting;

  /* Optional register locking */
  if (init->lock)
  {
    if (init->enable)
    {
      WDOG_Lock();
    }
    else
    {
      BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_LOCK_SHIFT, 1);
    }
  }
}
Exemple #9
0
/***************************************************************************//**
 * @brief
 *   Reset PCNT counter and TOP register.
 *
 * @param[in] pcnt
 *   Pointer to PCNT peripheral register block.
 ******************************************************************************/
void PCNT_CounterReset(PCNT_TypeDef *pcnt)
{
  EFM_ASSERT(PCNT_REF_VALID(pcnt));

  /* Notice that special SYNCBUSY handling is not applicable for the RSTEN */
  /* bit of the control register, so we don't need to wait for it when only */
  /* modifying RSTEN. (It would mean undefined wait time if clocked by */
  /* external clock.) The SYNCBUSY bit will however be set, leading to a */
  /* synchronization in the LF domain, with in reality no changes. */

  /* Enable reset of CNT and TOP register */
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);

  /* Disable reset of CNT and TOP register */
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
}
Exemple #10
0
/***************************************************************************//**
 * @brief
 *
 *
 * @param[in] acmp
 *   Pointer to the ACMP peripheral register block.
 *
 * @param[in] init
 *   Pointer to initialization structure used to configure ACMP for capacative
 *   sensing operation.
 ******************************************************************************/
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init)
{
  /* Make sure the module exists on the selected chip */
  EFM_ASSERT(ACMP_REF_VALID(acmp));

  /* Make sure biasprog is within bounds */
  EFM_ASSERT(init->biasProg < 16);

  /* Set control register. No need to set interrupt modes */
  acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
               | (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT)
               | (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT)
               | (init->interruptOnFallingEdge << _ACMP_CTRL_IFALL_SHIFT)
               | (init->interruptOnRisingEdge << _ACMP_CTRL_IRISE_SHIFT)
               | (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT)
               | (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT)
               | (init->inactiveValue << _ACMP_CTRL_INACTVAL_SHIFT);

  acmp->INPUTSEL = (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT)
                   | (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT);

  /* Enable ACMP if requested.
   * Note: BITBAND_Peripheral() function is used for setting/clearing single
   * bit peripheral register bitfields. */
  BITBAND_Peripheral(&(acmp->CTRL),
                     (uint32_t)_ACMP_CTRL_EN_SHIFT,
                     (uint32_t)init->enable);
}
Exemple #11
0
/***************************************************************************//**
 * @brief
 *   Sets up the ACMP for use in capacative sense applications.
 *
 * @details
 *   This function sets up the ACMP for use in capacacitve sense applications.
 *   To use the capacative sense functionality in the ACMP you need to use
 *   the PRS output of the ACMP module to count the number of oscillations
 *   in the capacative sense circuit (possibly using a TIMER).
 *
 * @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] init
 *   Pointer to initialization structure used to configure ACMP for capacative
 *   sensing operation.
 ******************************************************************************/
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init)
{
  /* Make sure the module exists on the selected chip */
  EFM_ASSERT(ACMP_REF_VALID(acmp));

  /* Make sure that vddLevel is within bounds */
  EFM_ASSERT(init->vddLevel < 64);

  /* Make sure biasprog is within bounds */
  EFM_ASSERT(init->biasProg < 16);

  /* Set control register. No need to set interrupt modes */
  acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
               | (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT)
               | (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT)
               | (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT)
               | (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT);

  /* Select capacative sensing mode by selecting a resistor and enabling it */
  acmp->INPUTSEL = (init->resistor << _ACMP_INPUTSEL_CSRESSEL_SHIFT)
                   | ACMP_INPUTSEL_CSRESEN
                   | (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT)
                   | (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT)
                   | ACMP_INPUTSEL_NEGSEL_CAPSENSE;

  /* Enable ACMP if requested.
   * Note: BITBAND_Peripheral() function is used for setting/clearing single
   * bit peripheral register bitfields. */
  BITBAND_Peripheral(&(acmp->CTRL),
                     (uint32_t)_ACMP_CTRL_EN_SHIFT,
                     (uint32_t)init->enable);
}
Exemple #12
0
/***************************************************************************//**
 * @brief
 *   Initialize I2C.
 *
 * @param[in] i2c
 *   Pointer to I2C peripheral register block.
 *
 * @param[in] init
 *   Pointer to I2C initialization structure.
 ******************************************************************************/
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
{
  EFM_ASSERT(I2C_REF_VALID(i2c));

  i2c->IEN = 0;
  i2c->IFC = _I2C_IFC_MASK;

  BITBAND_Peripheral(&(i2c->CTRL),
                     _I2C_CTRL_SLAVE_SHIFT,
                     init->master? 0 : 1);

  I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);

  BITBAND_Peripheral(&(i2c->CTRL),
                     _I2C_CTRL_EN_SHIFT,
                     (unsigned int)(init->enable));
}
Exemple #13
0
/***************************************************************************//**
 * @brief
 *   Enable/disable LESENSE scan channel and the pin assigned to it.
 *
 * @details
 *   Use this function to enable/disable a selected LESENSE scan channel and the
 *   pin assigned to.
 *
 * @note
 *   Users can enable/disable scan channels and the channel pin by
 *   LESENSE_ChannelConfig() function, but only with a significant overhead.
 *   This simple function serves the purpose of controlling these parameters
 *   after the channel has been configured.
 *
 * @param[in] chIdx
 *   Identifier of the scan channel. Valid range: 0-15.
 *
 * @param[in] enaScanCh
 *   Enable/disable the selected scan channel by setting this parameter to
 *   true/false respectively.
 *
 * @param[in] enaPin
 *   Enable/disable the pin assigned to the channel selected by @p chIdx.
 ******************************************************************************/
void LESENSE_ChannelEnable(uint8_t const chIdx,
                           bool const enaScanCh,
                           bool const enaPin)
{
  /* Enable/disable the assigned pin of scan channel chIdx.
   * Note: BITBAND_Peripheral() function is used for setting/clearing single
   * bit peripheral register bitfields. Read the function description in
   * efm32_bitband.h for more details. */
  BITBAND_Peripheral(&(LESENSE->ROUTE),
                     (uint32_t)chIdx,
                     (uint32_t)enaPin);

  /* Enable/disable scan channel chIdx. */
  BITBAND_Peripheral(&(LESENSE->CHEN),
                     (uint32_t)chIdx,
                     (uint32_t)enaScanCh);
}
Exemple #14
0
/***************************************************************************//**
 * @brief
 *   Lock the watchdog configuration.
 *
 * @details
 *   This prevents errors from overwriting the watchdog configuration, possibly
 *   disabling it. Only a reset can unlock the watchdog config, once locked.
 *
 *   If the LFRCO or LFXO clocks are used to clock the watchdog, one should
 *   consider using the option of inhibiting those clocks to be disabled,
 *   please see the WDOG_Enable() init structure.
 *
 * @note
 *   This function modifies the WDOG CTRL register which requires
 *   synchronization into the low frequency domain. If this register is modified
 *   before a previous update to the same register has completed, this function
 *   will stall until the previous synchronization has completed.
 ******************************************************************************/
void WDOG_Lock(void)
{
  /* Wait for any pending previous write operation to have been completed in */
  /* low frequency domain */
  while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL) ;

  /* Disable writing to the control register */
  BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_LOCK_SHIFT, 1);
}
Exemple #15
0
/***************************************************************************//**
 * @brief
 *   Enable or disable EBI Bank
 *
 * @param[in] banks
 *   Banks to reconfigure, mask of EBI_BANK<n> flags
 *
 * @param[in] enable
 *   True to enable, false to disable
 ******************************************************************************/
void EBI_BankEnable(uint32_t banks, bool enable)
{
    if (banks & EBI_BANK0)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK0EN_SHIFT, enable);
    }
    if (banks & EBI_BANK1)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK1EN_SHIFT, enable);
    }
    if (banks & EBI_BANK2)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK2EN_SHIFT, enable);
    }
    if (banks & EBI_BANK3)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK3EN_SHIFT, enable);
    }
}
Exemple #16
0
/***************************************************************************//**
 * @brief
 *   Enable/disable the watchdog timer.
 *
 * @note
 *   This function modifies the WDOG CTRL register which requires
 *   synchronization into the low frequency domain. If this register is modified
 *   before a previous update to the same register has completed, this function
 *   will stall until the previous synchronization has completed.
 *
 * @param[in] enable
 *   true to enable watchdog, false to disable. Watchdog cannot be disabled if
 *   watchdog has been locked.
 ******************************************************************************/
void WDOG_Enable(bool enable)
{
  if (!enable)
  {
    /* Wait for any pending previous write operation to have been completed in */
    /* low frequency domain */
    while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL) ;
  }
  BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_EN_SHIFT, (unsigned int) enable);
}
Exemple #17
0
/***************************************************************************//**
 * @brief
 *   Enable or disable EBI Chip Select
 *
 * @param[in] cs
 *   ChipSelect lines to reconfigure, mask of EBI_CS<n> flags
 *
 * @param[in] enable
 *   True to enable, false to disable
 ******************************************************************************/
void EBI_ChipSelectEnable(uint32_t cs, bool enable)
{
    if (cs & EBI_CS0)
    {
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS0PEN_SHIFT, enable);
    }
    if (cs & EBI_CS1)
    {
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS1PEN_SHIFT, enable);
    }
    if (cs & EBI_CS2)
    {
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS2PEN_SHIFT, enable);
    }
    if (cs & EBI_CS3)
    {
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS3PEN_SHIFT, enable);
    }
}
Exemple #18
0
/***************************************************************************//**
 * @brief
 *   Configure address operation parameters for selected bank
 *
 * @param[in] banks
 *   Mask of memory bank(s) to configure write timing for
 *
 * @param[in] halfALE
 *   Enables or disables half cycle ALE strobe in last strobe cycle
 ******************************************************************************/
void EBI_BankAddressTimingConfig(uint32_t banks, bool halfALE)
{
    /* Verify only valid banks are used */
    EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);

    if( banks & EBI_BANK0 )
    {
        BITBAND_Peripheral(&EBI->ADDRTIMING, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
    }
    if( banks & EBI_BANK1 )
    {
        BITBAND_Peripheral(&EBI->ADDRTIMING1, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
    }
    if( banks & EBI_BANK2 )
    {
        BITBAND_Peripheral(&EBI->ADDRTIMING2, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
    }
    if( banks & EBI_BANK3 )
    {
        BITBAND_Peripheral(&EBI->ADDRTIMING3, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
    }
}
/***************************************************************************//**
 * @brief
 *   Clear the reset cause register.
 ******************************************************************************/
void RMU_ResetCauseClear(void)
{
    uint32_t locked;

    RMU->CMD = RMU_CMD_RCCLR;

    /* Clear some reset causes not cleared with RMU CMD register */
    /* (If EMU registers locked, they must be unlocked first) */
    locked = EMU->LOCK & EMU_LOCK_LOCKKEY_LOCKED;
    if (locked)
    {
        EMU_Unlock();
    }

    BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 1);
    BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 0);

    if (locked)
    {
        EMU_Lock();
    }
}
Exemple #20
0
/***************************************************************************//**
 * @brief
 *   Configure Backup Power Domain settings
 *
 * @param[in] bupdInit
 *   Backup power domain initialization structure
 ******************************************************************************/
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
{
	uint32_t reg;

	/* Set power connection configuration */
	reg = EMU->PWRCONF & ~(
		_EMU_PWRCONF_PWRRES_MASK|
		_EMU_PWRCONF_VOUTSTRONG_MASK|
		_EMU_PWRCONF_VOUTMED_MASK|
		_EMU_PWRCONF_VOUTWEAK_MASK);

	reg |= (bupdInit->resistor|
		(bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
		(bupdInit->voutMed    << _EMU_PWRCONF_VOUTMED_SHIFT)|
		(bupdInit->voutWeak   << _EMU_PWRCONF_VOUTWEAK_SHIFT));

	EMU->PWRCONF = reg;

	/* Set backup domain inactive mode configuration */
	reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
	reg |= (bupdInit->inactivePower);
	EMU->BUINACT = reg;

	/* Set backup domain active mode configuration */
	reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
	reg |= (bupdInit->activePower);
	EMU->BUACT = reg;

	/* Set power control configuration */
	reg = EMU->BUCTRL & ~(
		_EMU_BUCTRL_PROBE_MASK|
		_EMU_BUCTRL_BODCAL_MASK|
		_EMU_BUCTRL_STATEN_MASK|
		_EMU_BUCTRL_EN_MASK);

	/* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
	   release reset */
	reg |= (bupdInit->probe|
		(bupdInit->bodCal          << _EMU_BUCTRL_BODCAL_SHIFT)|
		(bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
		(bupdInit->enable          << _EMU_BUCTRL_EN_SHIFT));

	/* Enable configuration */
	EMU->BUCTRL = reg;

	/* If enable is true, enable BU_VIN input power pin, if not disable it  */
	EMU_BUPinEnable(bupdInit->enable);

	/* If enable is true, release BU reset, if not keep reset asserted */
	BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
}
Exemple #21
0
/***************************************************************************//**
 * @brief
 *   Configure Byte Lane Enable for select banks
 *   timing support
 *
 * @param[in] banks
 *   Mask of memory bank(s) to configure polarity for
 *
 * @param[in] enable
 *   Flag
 ******************************************************************************/
void EBI_BankByteLaneEnable(uint32_t banks, bool enable)
{
    /* Verify only valid banks are used */
    EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);

    /* Configure byte lane support for each selected bank */
    if (banks & EBI_BANK0)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL_SHIFT, enable);
    }
    if (banks & EBI_BANK1)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL1_SHIFT, enable);
    }
    if (banks & EBI_BANK2)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL2_SHIFT, enable);
    }
    if (banks & EBI_BANK3)
    {
        BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL3_SHIFT, enable);
    }
}
Exemple #22
0
/***************************************************************************//**
 * @brief
 *   Configure GPIO interrupt.
 *
 * @details
 *   If reconfiguring a GPIO interrupt that is already enabled, it is generally
 *   recommended to disable it first, see GPIO_Disable().
 *
 *   The actual GPIO interrupt handler must be in place before enabling the
 *   interrupt.
 *
 *   Notice that any pending interrupt for the selected pin is cleared by this
 *   function.
 *
 * @note
 *   A certain pin number can only be associated with one port. Ie, if GPIO
 *   interrupt 1 is assigned to port A/pin 1, then it is not possibly to use
 *   pin 1 from any other ports for interrupts. Please refer to the reference
 *   manual.
 *
 * @param[in] port
 *   The port to associate with @p pin.
 *
 * @param[in] pin
 *   The GPIO interrupt number (= port pin).
 *
 * @param[in] risingEdge
 *   Set to true if interrupts shall be enabled on rising edge, otherwise false.
 *
 * @param[in] fallingEdge
 *   Set to true if interrupts shall be enabled on falling edge, otherwise false.
 *
 * @param[in] enable
 *   Set to true if interrupt shall be enabled after configuration completed,
 *   false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
 ******************************************************************************/
void GPIO_IntConfig(GPIO_Port_TypeDef port,
                    unsigned int pin,
                    bool risingEdge,
                    bool fallingEdge,
                    bool enable)
{
  uint32_t tmp;

  EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));

  /* There are two registers controlling the interrupt configuration:
   * The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
   * pins 8-15. */
  if (pin < 8)
  {
    GPIO->EXTIPSELL = (GPIO->EXTIPSELL & ~(0xF << (4 * pin))) |
                      (port << (4 * pin));
  }
  else
  {
    tmp             = pin - 8;
    GPIO->EXTIPSELH = (GPIO->EXTIPSELH & ~(0xF << (4 * tmp))) |
                      (port << (4 * tmp));
  }

  /* Enable/disable rising edge */
  BITBAND_Peripheral(&(GPIO->EXTIRISE), pin, (unsigned int)risingEdge);

  /* Enable/disable falling edge */
  BITBAND_Peripheral(&(GPIO->EXTIFALL), pin, (unsigned int)fallingEdge);

  /* Clear any pending interrupt */
  GPIO->IFC = 1 << pin;

  /* Finally enable/disable interrupt */
  BITBAND_Peripheral(&(GPIO->IEN), pin, (unsigned int)enable);
}
Exemple #23
0
/***************************************************************************//**
 * @brief
 *   Configure the LESENSE alternate excitation pins.
 *
 * @details
 *   This function configures the alternate excitation channels of the LESENSE
 *   interface. Please refer to the configuration parameter type definition
 *   (LESENSE_ConfAltEx_TypeDef) for more details.
 *
 * @note
 *   Parameter @p useAltEx must be true in the channel configuration structrure
 *   (LESENSE_ChDesc_TypeDef) in order to use alternate excitation pins on the
 *   channel.
 *
 * @param[in] confAltEx
 *   Configuration structure for LESENSE alternate excitation pins.
 ******************************************************************************/
void LESENSE_AltExConfig(LESENSE_ConfAltEx_TypeDef const *confAltEx)
{
  uint32_t i;
  uint32_t tmp;


  /* Configure alternate excitation mapping.
   * Atomic read-modify-write using BITBAND_Peripheral function in order to
   * support reconfiguration during LESENSE operation. */
  BITBAND_Peripheral(&(LESENSE->CTRL),
                     _LESENSE_CTRL_ALTEXMAP_SHIFT,
                     (uint32_t)confAltEx->altExMap);

  /* Iterate through all the 8 alternate excitation channels */
  for (i = 0U; i < 8U; ++i)
  {
    /* Enable/disable alternate excitation pin i.
     * Atomic read-modify-write using BITBAND_Peripheral function in order to
     * support reconfiguration during LESENSE operation. */
    BITBAND_Peripheral(&(LESENSE->ROUTE),
                       (16UL + i),
                       (uint32_t)confAltEx->AltEx[i].enablePin);

    /* Setup the idle phase state of alternate excitation pin i.
     * Read-modify-write in order to support reconfiguration during LESENSE
     * operation. */
    tmp                = (LESENSE->ALTEXCONF & ~((uint32_t)0x3UL << (i * 2UL)));
    tmp               |= ((uint32_t)confAltEx->AltEx[i].idleConf << (i * 2UL));
    LESENSE->ALTEXCONF = tmp;

    /* Enable/disable always excite on channel i */
    BITBAND_Peripheral(&(LESENSE->ALTEXCONF),
                       (16UL + i),
                       (uint32_t)confAltEx->AltEx[i].alwaysEx);
  }
}
Exemple #24
0
/***************************************************************************//**
 * @brief
 *   Init pulse counter.
 *
 * @details
 *   This function will configure the pulse counter. The clock selection is
 *   configured as follows, depending on operational mode:
 *
 *   @li #pcntModeOvsSingle - Use LFACLK.
 *   @li #pcntModeExtSingle - Use external PCNTn_S0 pin.
 *   @li #pcntModeExtQuad - Use external PCNTn_S0 pin.
 *
 *   Notice that the LFACLK must be enabled in all modes, since some basic setup
 *   is done with this clock even if external pin clock usage mode is chosen.
 *   The pulse counter clock for the selected instance must also be enabled
 *   prior to init.
 *
 *   Notice that pins used by the PCNT module must be properly configured
 *   by the user explicitly through setting the ROUTE register, in order for
 *   the PCNT to work as intended.
 *
 *   Writing to CNT will not occur in external clock modes (EXTCLKQUAD and
 *   EXTCLKSINGLE) because the external clock rate is unknown. The user should
 *   handle it manually depending on the application
 *
 *   TOPB is written for all modes but in external clock mode it will take
 *   3 external clock cycles to sync to TOP
 *
 *
 * @note
 *   Initializing requires synchronization into the low frequency domain. This
 *   may cause some delay.
 *
 * @param[in] pcnt
 *   Pointer to PCNT peripheral register block.
 *
 * @param[in] init
 *   Pointer to initialization structure used to initialize.
 ******************************************************************************/
void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init)
{
  unsigned int inst;
  uint32_t     tmp;

  EFM_ASSERT(PCNT_REF_VALID(pcnt));

#ifdef PCNT0
  if (PCNT0 == pcnt)
  {
    EFM_ASSERT((1<<PCNT0_CNT_SIZE) > init->counter);
    EFM_ASSERT((1<<PCNT0_CNT_SIZE) > init->top);
  }
#endif
  
#ifdef PCNT1
  if (PCNT1 == pcnt)
  {
    EFM_ASSERT((1<<PCNT1_CNT_SIZE) > init->counter);
    EFM_ASSERT((1<<PCNT1_CNT_SIZE) > init->top);
  }
#endif
  
#ifdef PCNT2
  if (PCNT2 == pcnt)
  {
    EFM_ASSERT((1<<PCNT2_CNT_SIZE) > init->counter);
    EFM_ASSERT((1<<PCNT2_CNT_SIZE) > init->top);
  }
#endif
  
  /* Map pointer to instance */
  inst = PCNT_Map(pcnt);

#if defined( _PCNT_INPUT_MASK )
  /* Selecting the PRS channels for the PRS input sources of the PCNT. These are
   * written with a Read-Modify-Write sequence in order to keep the value of the
   * input enable bits which can be modified using PCNT_PRSInputEnable(). */
  tmp = pcnt->INPUT & ~(_PCNT_INPUT_S0PRSSEL_MASK | _PCNT_INPUT_S1PRSSEL_MASK);
  tmp |= ((uint32_t)init->s0PRS << _PCNT_INPUT_S0PRSSEL_SHIFT) |
         ((uint32_t)init->s1PRS << _PCNT_INPUT_S1PRSSEL_SHIFT);
  pcnt->INPUT = tmp;
#endif

  /* Build CTRL setting, except for mode */
  tmp = 0;
  if (init->negEdge)
  {
    tmp |= PCNT_CTRL_EDGE_NEG;
  }

  if (init->countDown)
  {
    tmp |= PCNT_CTRL_CNTDIR_DOWN;
  }

  if (init->filter)
  {
    tmp |= PCNT_CTRL_FILT;
  }

#if defined( PCNT_CTRL_HYST )
  if (init->hyst)
  {
    tmp |= PCNT_CTRL_HYST;
  }
#endif

#if defined( PCNT_CTRL_S1CDIR )
  if (init->s1CntDir)
  {
    tmp |= PCNT_CTRL_S1CDIR;
  }
#endif

  /* Configure counter events for regular and auxiliary counter. */
#if defined( _PCNT_CTRL_CNTEV_SHIFT )
  tmp |= init->cntEvent << _PCNT_CTRL_CNTEV_SHIFT;
#endif

#if defined( _PCNT_CTRL_AUXCNTEV_SHIFT )
  {
    /* Modify the auxCntEvent value before writing to the AUXCNTEV field in
       the CTRL register because the AUXCNTEV field values are different from
       the CNTEV field values, and cntEvent and auxCntEvent are of the same type
       PCNT_CntEvent_TypeDef.
    */
    uint32_t auxCntEventField = 0; /* Get rid of compiler warning. */
    switch (init->auxCntEvent)
    {
    case pcntCntEventBoth:
      auxCntEventField = pcntCntEventNone;
      break;
    case pcntCntEventNone:
      auxCntEventField = pcntCntEventBoth;
      break;
    case pcntCntEventUp:
    case pcntCntEventDown:
      auxCntEventField = init->auxCntEvent;
      break;
    default:
      /* Invalid parameter, asserted. */
      EFM_ASSERT(0);
    }
    tmp |= auxCntEventField << _PCNT_CTRL_AUXCNTEV_SHIFT;
  }
#endif

  /* Reset pulse counter while changing clock source. The reset bit */
  /* is asynchronous, we don't have to check for SYNCBUSY. */
  BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);

  /* Select LFACLK to clock in control setting */
  CMU_PCNTClockExternalSet(inst, false);

  /* Handling depends on whether using external clock or not. */
  switch (init->mode)
  {
  case pcntModeExtSingle:
  case pcntModeExtQuad:
    tmp |= init->mode << _PCNT_CTRL_MODE_SHIFT;

    /* In most cases, the SYNCBUSY bit is set due to reset bit set, and waiting
     * for asynchronous reset bit is strictly not necessary.
     * But in theory, other operations on CTRL register may have been done
     * outside this function, so wait. */
    PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);

    /* Enable PCNT Clock Domain Reset. The PCNT must be in reset before changing
     * the clock source to an external clock */
    pcnt->CTRL = PCNT_CTRL_RSTEN;

    /* Wait until CTRL write synchronized into LF domain. */
    PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);

    /* Change to external clock BEFORE disabling reset */
    CMU_PCNTClockExternalSet(inst, true);

    /* Write to TOPB. If using external clock TOPB will sync to TOP at the same
     * time as the mode. This will insure that if the user chooses to count
     * down, the first "countable" pulse will make CNT go to TOP and not 0xFF
     * (default TOP value). */
    pcnt->TOPB = init->top;

    /* This bit has no effect on rev. C and onwards parts - for compatibility */
    pcnt->CMD = PCNT_CMD_LTOPBIM;

    /* Write the CTRL register with the configurations.
     * This should be written after TOPB in the eventuality of a pulse between
     * these two writes that would cause the CTRL register to be synced one
     * clock cycle earlier than the TOPB. */
    pcnt->CTRL = tmp;

    /* There are no syncs for TOP, CMD or CTRL because the clock rate is unknown
     * and the program could stall
     * These will be synced within 3 clock cycles of the external clock  /
     * For the same reason CNT cannot be written here. */
    break;

  /* pcntModeDisable */
  /* pcntModeOvsSingle */
  default:
    /* No need to set disabled mode if already disabled. */
    if ((pcnt->CTRL & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
    {
      /* Set control to disabled mode, leave reset on until ensured disabled.
       * We don't need to wait for CTRL SYNCBUSY completion here, it was
       * triggered by reset bit above, which is asynchronous. */
      pcnt->CTRL = tmp | PCNT_CTRL_MODE_DISABLE | PCNT_CTRL_RSTEN;

      /* Wait until CTRL write synchronized into LF domain before proceeding
       * to disable reset. */
      PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
    }

    /* Disable reset bit, counter should now be in disabled mode. */
    BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);

    /* Set counter and top values as specified. */
    PCNT_CounterTopSet(pcnt, init->counter, init->top);

    /* Enter oversampling mode if selected. */
    if (init->mode == pcntModeOvsSingle)
    {
      PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
      pcnt->CTRL = tmp | (init->mode << _PCNT_CTRL_MODE_SHIFT);
    }
    break;
  }
}
Exemple #25
0
/***************************************************************************//**
 * @brief
 *   Configure a single LESENSE sensor channel.
 *
 * @details
 *   This function configures a single sensor channel of the LESENSE interface.
 *   Please refer to the configuration parameter type definition
 *   (LESENSE_ChDesc_TypeDef) for more details.
 *
 * @note
 *   This function has been designed to minimize the effects of sensor channel
 *   reconfiguration while LESENSE is in operation, however one shall be aware
 *   of these effects and the right timing of calling this function.
 *   Parameter @p useAltEx must be true in the channel configuration in order to
 *   use alternate excitation pins.
 *
 * @param[in] confCh
 *   Configuration structure for a single LESENSE sensor channel.
 *
 * @param[in] chIdx
 *   Channel index to configure (0-15).
 ******************************************************************************/
void LESENSE_ChannelConfig(LESENSE_ChDesc_TypeDef const *confCh,
                           uint32_t const chIdx)
{
  uint32_t tmp; /* Service variable. */


  /* Sanity check of configuration parameters */
  EFM_ASSERT(chIdx < 16U);
  EFM_ASSERT(confCh->exTime < 64U);
  EFM_ASSERT(confCh->sampleDelay < 128U);
  EFM_ASSERT(confCh->measDelay < 128U);
  /* Not a complete assert, as the max. value of acmpThres depends on other
   * configuration parameters, check the parameter description of acmpThres for
   * for more details! */
  EFM_ASSERT(confCh->acmpThres < 4096U);
  EFM_ASSERT(!(confCh->chPinExMode == lesenseChPinExDACOut &&
               (chIdx != 2U) && (chIdx != 3U) && (chIdx != 4U) && (chIdx != 5U)));
  EFM_ASSERT(!(confCh->chPinIdleMode == lesenseChPinIdleDACCh1 &&
               ((chIdx != 12U) && (chIdx != 13U) && (chIdx != 14U) && (chIdx != 15U))));
  EFM_ASSERT(!(confCh->chPinIdleMode == lesenseChPinIdleDACCh0 &&
               ((chIdx != 0U) && (chIdx != 1U) && (chIdx != 2U) && (chIdx != 3U))));


  /* Configure chIdx setup in LESENSE idle phase.
   * Read-modify-write in order to support reconfiguration during LESENSE
   * operation. */
  tmp               = (LESENSE->IDLECONF & ~((uint32_t)0x3UL << (chIdx * 2UL)));
  tmp              |= ((uint32_t)confCh->chPinIdleMode << (chIdx * 2UL));
  LESENSE->IDLECONF = tmp;

  /* Channel specific timing configuration on scan channel chIdx.
   * Set excitation time, sampling delay, measurement delay. */
  LESENSE_ChannelTimingSet(chIdx,
                           (uint32_t)confCh->exTime,
                           (uint32_t)confCh->sampleDelay,
                           (uint32_t)confCh->measDelay);

  /* Channel specific configuration of clocks, sample mode, excitation pin mode
   * alternate excitation usage and interrupt mode on scan channel chIdx in
   * LESENSE_CHchIdx_INTERACT. */
  LESENSE->CH[chIdx].INTERACT = ((uint32_t)confCh->exClk << 
                                 _LESENSE_CH_INTERACT_EXCLK_SHIFT) |
                                ((uint32_t)confCh->sampleClk <<
                                 _LESENSE_CH_INTERACT_SAMPLECLK_SHIFT) |
                                (uint32_t)confCh->sampleMode |
                                (uint32_t)confCh->intMode |
                                (uint32_t)confCh->chPinExMode |
                                ((uint32_t)confCh->useAltEx <<
                                 _LESENSE_CH_INTERACT_ALTEX_SHIFT);

  /* Configure channel specific counter comparison mode, optional result
   * forwarding to decoder, optional counter value storing and optional result
   * inverting on scan channel chIdx in LESENSE_CHchIdx_EVAL. */
  LESENSE->CH[chIdx].EVAL = (uint32_t)confCh->compMode |
                            ((uint32_t)confCh->shiftRes <<
                             _LESENSE_CH_EVAL_DECODE_SHIFT) |
                            ((uint32_t)confCh->storeCntRes <<
                             _LESENSE_CH_EVAL_STRSAMPLE_SHIFT) |
                            ((uint32_t)confCh->invRes <<
                             _LESENSE_CH_EVAL_SCANRESINV_SHIFT);

  /* Configure analog comparator (ACMP) threshold and decision threshold for
   * counter separately with the function provided for that. */
  LESENSE_ChannelThresSet(chIdx,
                         (uint32_t)confCh->acmpThres,
                         (uint32_t)confCh->cntThres);

  /* Enable/disable interrupts on channel.
   * Note: BITBAND_Peripheral() function is used for setting/clearing single
   * bit peripheral register bitfields. Read the function description in
   * efm32_bitband.h for more details. */
  BITBAND_Peripheral(&(LESENSE->IEN),
                     (uint32_t)chIdx,
                     (uint32_t)confCh->enaInt);

  /* Enable/disable CHchIdx pin. */
  BITBAND_Peripheral(&(LESENSE->ROUTE),
                     (uint32_t)chIdx,
                     (uint32_t)confCh->enaPin);

  /* Enable/disable scan channel chIdx. */
  BITBAND_Peripheral(&(LESENSE->CHEN),
                     (uint32_t)chIdx,
                     (uint32_t)confCh->enaScanCh);
}
Exemple #26
0
/***************************************************************************//**
 * @brief
 *   Configure read operation parameters for selected bank
 *
 * @param[in] banks
 *   Mask of memory bank(s) to configure write timing for
 *
 * @param[in] pageMode
 *   Enables or disables half cycle WE strobe in last strobe cycle
 *
 * @param[in] prefetch
 *   Enables or disables half cycle WE strobe in last strobe cycle
 *
 * @param[in] halfRE
 *   Enables or disables half cycle WE strobe in last strobe cycle
 ******************************************************************************/
void EBI_BankReadTimingConfig(uint32_t banks, bool pageMode, bool prefetch, bool halfRE)
{
    /* Verify only valid banks are used */
    EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);

    /* Configure read operation parameters */
    if( banks & EBI_BANK0 )
    {
        BITBAND_Peripheral(&EBI->RDTIMING, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
        BITBAND_Peripheral(&EBI->RDTIMING, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
        BITBAND_Peripheral(&EBI->RDTIMING, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
    }
    if( banks & EBI_BANK1 )
    {
        BITBAND_Peripheral(&EBI->RDTIMING1, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
        BITBAND_Peripheral(&EBI->RDTIMING1, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
        BITBAND_Peripheral(&EBI->RDTIMING1, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
    }
    if( banks & EBI_BANK2 )
    {
        BITBAND_Peripheral(&EBI->RDTIMING2, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
        BITBAND_Peripheral(&EBI->RDTIMING2, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
        BITBAND_Peripheral(&EBI->RDTIMING2, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
    }
    if( banks & EBI_BANK3 )
    {
        BITBAND_Peripheral(&EBI->RDTIMING3, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
        BITBAND_Peripheral(&EBI->RDTIMING3, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
        BITBAND_Peripheral(&EBI->RDTIMING3, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
    }
}
Exemple #27
0
/***************************************************************************//**
 * @brief
 *   Configure and enable External Bus Interface
 *
 * @param[in] ebiInit
 *   EBI configuration structure
 *
 * @note
 *   GPIO lines must be configured as PUSH_PULL for correct operation
 *   GPIO and EBI clocks must be enabled in the CMU
 ******************************************************************************/
void EBI_Init(const EBI_Init_TypeDef *ebiInit)
{
    uint32_t ctrl = EBI->CTRL;

#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
    /* Enable Independent Timing for devices that supports it */
    ctrl |= EBI_CTRL_ITS;

    /* Set polarity of address ready */
    EBI_BankPolaritySet(ebiInit->banks, ebiLineARDY, ebiInit->ardyPolarity);
    /* Set polarity of address latch enable */
    EBI_BankPolaritySet(ebiInit->banks, ebiLineALE, ebiInit->alePolarity);
    /* Set polarity of write enable */
    EBI_BankPolaritySet(ebiInit->banks, ebiLineWE, ebiInit->wePolarity);
    /* Set polarity of read enable */
    EBI_BankPolaritySet(ebiInit->banks, ebiLineRE, ebiInit->rePolarity);
    /* Set polarity of chip select lines */
    EBI_BankPolaritySet(ebiInit->banks, ebiLineCS, ebiInit->csPolarity);
    /* Set polarity of byte lane line */
    EBI_BankPolaritySet(ebiInit->banks, ebiLineBL, ebiInit->blPolarity);
#else
    /* Set polarity of address ready */
    EBI_PolaritySet(ebiLineARDY, ebiInit->ardyPolarity);
    /* Set polarity of address latch enable */
    EBI_PolaritySet(ebiLineALE, ebiInit->alePolarity);
    /* Set polarity of write enable */
    EBI_PolaritySet(ebiLineWE, ebiInit->wePolarity);
    /* Set polarity of read enable */
    EBI_PolaritySet(ebiLineRE, ebiInit->rePolarity);
    /* Set polarity of chip select lines */
    EBI_PolaritySet(ebiLineCS, ebiInit->csPolarity);
#endif

    /* Configure EBI mode and control settings  */
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
    if (ebiInit->banks & EBI_BANK0)
    {
        ctrl &= ~(_EBI_CTRL_MODE_MASK|
                  _EBI_CTRL_ARDYEN_MASK|
                  _EBI_CTRL_ARDYTODIS_MASK|
                  _EBI_CTRL_BL_MASK|
                  _EBI_CTRL_NOIDLE_MASK|
                  _EBI_CTRL_BANK0EN_MASK);
        ctrl |= (ebiInit->mode << _EBI_CTRL_MODE_SHIFT);
        ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDYEN_SHIFT);
        ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTODIS_SHIFT);
        ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL_SHIFT);
        ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE_SHIFT);
        if ( ebiInit->enable)
        {
            ctrl |= EBI_CTRL_BANK0EN;
        }
    }
    if (ebiInit->banks & EBI_BANK1)
    {
        ctrl &= ~(_EBI_CTRL_BL1_MASK|
                  _EBI_CTRL_MODE1_MASK|
                  _EBI_CTRL_ARDY1EN_MASK|
                  _EBI_CTRL_ARDYTO1DIS_MASK|
                  _EBI_CTRL_NOIDLE1_MASK|
                  _EBI_CTRL_BANK1EN_MASK);
        ctrl |= (ebiInit->mode << _EBI_CTRL_MODE1_SHIFT);
        ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY1EN_SHIFT);
        ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO1DIS_SHIFT);
        ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL1_SHIFT);
        ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE1_SHIFT);
        if ( ebiInit->enable)
        {
            ctrl |= EBI_CTRL_BANK1EN;
        }
    }
    if (ebiInit->banks & EBI_BANK2)
    {
        ctrl &= ~(_EBI_CTRL_BL2_MASK|
                  _EBI_CTRL_MODE2_MASK|
                  _EBI_CTRL_ARDY2EN_MASK|
                  _EBI_CTRL_ARDYTO2DIS_MASK|
                  _EBI_CTRL_NOIDLE2_MASK|
                  _EBI_CTRL_BANK2EN_MASK);
        ctrl |= (ebiInit->mode << _EBI_CTRL_MODE2_SHIFT);
        ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY2EN_SHIFT);
        ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO2DIS_SHIFT);
        ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL2_SHIFT);
        ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE2_SHIFT);
        if ( ebiInit->enable)
        {
            ctrl |= EBI_CTRL_BANK2EN;
        }
    }
    if (ebiInit->banks & EBI_BANK3)
    {
        ctrl &= ~(_EBI_CTRL_BL3_MASK|
                  _EBI_CTRL_MODE3_MASK|
                  _EBI_CTRL_ARDY3EN_MASK|
                  _EBI_CTRL_ARDYTO3DIS_MASK|
                  _EBI_CTRL_NOIDLE3_MASK|
                  _EBI_CTRL_BANK3EN_MASK);
        ctrl |= (ebiInit->mode << _EBI_CTRL_MODE3_SHIFT);
        ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY3EN_SHIFT);
        ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO3DIS_SHIFT);
        ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL3_SHIFT);
        ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE3_SHIFT);
        if ( ebiInit->enable)
        {
            ctrl |= EBI_CTRL_BANK3EN;
        }
    }
#else
    ctrl &= ~(_EBI_CTRL_MODE_MASK|
              _EBI_CTRL_ARDYEN_MASK|
              _EBI_CTRL_ARDYTODIS_MASK|
              _EBI_CTRL_BANK0EN_MASK|
              _EBI_CTRL_BANK1EN_MASK|
              _EBI_CTRL_BANK2EN_MASK|
              _EBI_CTRL_BANK3EN_MASK);
    if ( ebiInit->enable)
    {
        if ( ebiInit->banks & EBI_BANK0 )
        {
            ctrl |= EBI_CTRL_BANK0EN;
        }
        if ( ebiInit->banks & EBI_BANK1 )
        {
            ctrl |= EBI_CTRL_BANK1EN;
        }
        if ( ebiInit->banks & EBI_BANK2 )
        {
            ctrl |= EBI_CTRL_BANK2EN;
        }
        if ( ebiInit->banks & EBI_BANK3 )
        {
            ctrl |= EBI_CTRL_BANK3EN;
        }
    }
    ctrl |= ebiInit->mode;
    ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDYEN_SHIFT);
    ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTODIS_SHIFT);
#endif

    /* Configure timing */
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
    EBI_BankReadTimingSet(ebiInit->banks,
                          ebiInit->readSetupCycles,
                          ebiInit->readStrobeCycles,
                          ebiInit->readHoldCycles);
    EBI_BankReadTimingConfig(ebiInit->banks,
                             ebiInit->readPageMode,
                             ebiInit->readPrefetch,
                             ebiInit->readHalfRE);
    EBI_BankWriteTimingSet(ebiInit->banks,
                           ebiInit->writeSetupCycles,
                           ebiInit->writeStrobeCycles,
                           ebiInit->writeHoldCycles);
    EBI_BankWriteTimingConfig(ebiInit->banks,
                              ebiInit->writeBufferDisable,
                              ebiInit->writeHalfWE);
    EBI_BankAddressTimingSet(ebiInit->banks,
                             ebiInit->addrSetupCycles,
                             ebiInit->addrHoldCycles);
    EBI_BankAddressTimingConfig(ebiInit->banks,
                                ebiInit->addrHalfALE);
#else
    EBI_ReadTimingSet(ebiInit->readSetupCycles,
                      ebiInit->readStrobeCycles,
                      ebiInit->readHoldCycles);
    EBI_WriteTimingSet(ebiInit->writeSetupCycles,
                       ebiInit->writeStrobeCycles,
                       ebiInit->writeHoldCycles);
    EBI_AddressTimingSet(ebiInit->addrSetupCycles,
                         ebiInit->addrHoldCycles);
#endif

    /* Activate new configuration */
    EBI->CTRL = ctrl;

    /* Configure Adress Latch Enable */
    switch (ebiInit->mode)
    {
    case ebiModeD16A16ALE:
    case ebiModeD8A24ALE:
        /* Address Latch Enable */
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 1);
        break;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
    case ebiModeD16:
#endif
    case ebiModeD8A8:
        /* Make sure Address Latch is disabled */
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 0);
        break;
    }
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
    /* Limit pin enable */
    EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_ALB_MASK) | ebiInit->aLow;
    EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_APEN_MASK) | ebiInit->aHigh;
    /* Location */
    EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_LOCATION_MASK) | ebiInit->location;

    /* Enable EBI BL pin if necessary */
    if(ctrl & (_EBI_CTRL_BL_MASK|_EBI_CTRL_BL1_MASK|_EBI_CTRL_BL2_MASK|_EBI_CTRL_BL3_MASK))
    {
        BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_BLPEN_SHIFT, ebiInit->blEnable);
    }
#endif
    /* Enable EBI pins EBI_WEn and EBI_REn */
    BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_EBIPEN_SHIFT, 1);

    /* Enable chip select lines */
    EBI_ChipSelectEnable(ebiInit->csLines, true);
}
Exemple #28
0
/***************************************************************************//**
 * @brief
 *   Configure EBI pin polarity
 *
 * @param[in] line
 *   Which pin/line to configure
 *
 * @param[in] polarity
 *   Active high, or active low
 ******************************************************************************/
void EBI_PolaritySet(EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity)
{
    switch (line)
    {
    case ebiLineARDY:
        BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
        break;
    case ebiLineALE:
        BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_ALEPOL_SHIFT, polarity);
        break;
    case ebiLineWE:
        BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_WEPOL_SHIFT, polarity);
        break;
    case ebiLineRE:
        BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_REPOL_SHIFT, polarity);
        break;
    case ebiLineCS:
        BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_CSPOL_SHIFT, polarity);
        break;
#if defined (_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
    case ebiLineBL:
        BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_BLPOL_SHIFT, polarity);
        break;
    case ebiLineTFTVSync:
        BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
        break;
    case ebiLineTFTHSync:
        BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
        break;
    case ebiLineTFTDataEn:
        BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
        break;
    case ebiLineTFTDClk:
        BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
        break;
    case ebiLineTFTCS:
        BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_CSPOL_SHIFT, polarity);
        break;
#endif
    default:
        EFM_ASSERT(0);
        break;
    }
}
Exemple #29
0
/***************************************************************************//**
 * @brief
 *   Configure Alternate Address Map support
 *   Enables or disables 256MB address range for all banks
 *
 * @param[in] enable
 *   Set or clear address map extension
 ******************************************************************************/
void EBI_AltMapEnable(bool enable)
{
    BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_ALTMAP_SHIFT, enable);
}
Exemple #30
0
/***************************************************************************//**
 * @brief
 *   Configure EBI pin polarity for selected bank(s) for devices with individual
 *   timing support
 *
 * @param[in] banks
 *   Mask of memory bank(s) to configure polarity for
 *
 * @param[in] line
 *   Which pin/line to configure
 *
 * @param[in] polarity
 *   Active high, or active low
 ******************************************************************************/
void EBI_BankPolaritySet(uint32_t banks, EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity)
{
    uint32_t bankSet = 0;
    volatile uint32_t *polRegister = 0;

    /* Verify only valid banks are used */
    EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);

    while (banks)
    {
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
        if (banks & EBI_BANK0)
        {
            polRegister = &EBI->POLARITY;
            bankSet = EBI_BANK0;
        }
        if (banks & EBI_BANK1)
        {
            polRegister = &EBI->POLARITY1;
            bankSet = EBI_BANK1;
        }
        if (banks & EBI_BANK2)
        {
            polRegister = &EBI->POLARITY2;
            bankSet = EBI_BANK2;
        }
        if (banks & EBI_BANK3)
        {
            polRegister = &EBI->POLARITY3;
            bankSet = EBI_BANK3;
        }
#else
        polRegister = &EBI->POLARITY;
        banks       = 0;
#endif

        /* What line to configure */
        switch (line)
        {
        case ebiLineARDY:
            BITBAND_Peripheral(polRegister, _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
            break;
        case ebiLineALE:
            BITBAND_Peripheral(polRegister, _EBI_POLARITY_ALEPOL_SHIFT, polarity);
            break;
        case ebiLineWE:
            BITBAND_Peripheral(polRegister, _EBI_POLARITY_WEPOL_SHIFT, polarity);
            break;
        case ebiLineRE:
            BITBAND_Peripheral(polRegister, _EBI_POLARITY_REPOL_SHIFT, polarity);
            break;
        case ebiLineCS:
            BITBAND_Peripheral(polRegister, _EBI_POLARITY_CSPOL_SHIFT, polarity);
            break;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
        case ebiLineBL:
            BITBAND_Peripheral(polRegister, _EBI_POLARITY_BLPOL_SHIFT, polarity);
            break;
        case ebiLineTFTVSync:
            BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
            break;
        case ebiLineTFTHSync:
            BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
            break;
        case ebiLineTFTDataEn:
            BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
            break;
        case ebiLineTFTDClk:
            BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
            break;
        case ebiLineTFTCS:
            BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_CSPOL_SHIFT, polarity);
            break;
#endif
        default:
            EFM_ASSERT(0);
            break;
        }
        banks = banks & (~bankSet);
    }
}