Example #1
0
/**************************************************************************//**
 * @brief Energy Mode 3 demonstration, GPIO wake up - will restart application
 *****************************************************************************/
void Demo_EM3_GPIO(void)
{
  /* Disable systick timer */
  SysTick->CTRL  = 0;

  /* Keep GPIO and EBI active, do not disable peripherals */

  /* Disable LF peripherals */
  CMU->LFACLKEN0 = 0x00000000;
  CMU->LFBCLKEN0 = 0x00000000;

  /* Enter Energy Mode 3 - wake up on GPIO interrupt */
  /* Press AEM button again to read EFM, and then any PB/Joystick button */
  EMU_EnterEM3(false);

  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ;

  /* Show LED pattern after wake up, to show we're alive */
  while(1)
  {
    BSP_LedsSet(0xf00f);
    Delay(200);
    BSP_LedsSet(0x0ff0);
    Delay(200);
  }
}
Example #2
0
/*==============================================================================
  hal_delay_us()
 =============================================================================*/
void hal_delay_us( uint32_t i_delay )
{
    volatile int i = 0;
    uint32_t l_ticks = ((SystemCoreClockGet() / 1000000) * i_delay) / 10;
    for( i = 0; i < l_ticks; i++ );

} /* hal_delay_us() */
Example #3
0
/***************************************************************************//**
 * @brief
 *   Configure the SysTick for OS tick.
 *
 * @details
 *
 * @note
 *
 ******************************************************************************/
void  SysTick_Configuration(void)
{
	rt_uint32_t 	core_clock;
	rt_uint32_t 	cnts;

	core_clock = SystemCoreClockGet();
	cnts = core_clock / RT_TICK_PER_SECOND;

	SysTick_Config(cnts);
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
}
Example #4
0
/**************************************************************************//**
 * @brief  TFT initialize or reinitialize
 *         Assumes EBI has been configured correctly in BSP_Init(BSP_INIT_DK_EBI)
 *
 * @param[in] tftInit Pointer to EBI TFT initialization structure
 *
 * @return true if we should redraw into buffer, false if BC has control
 *         over display
 *****************************************************************************/
bool TFT_DirectInit(const EBI_TFTInit_TypeDef *tftInit)
{
  bool     ret;
  uint32_t i, freq;
  EMSTATUS stat;

  /* If we are in BC_UIF_AEM_EFM state, we can redraw graphics */
  if (BSP_RegisterRead(&BC_REGISTER->UIF_AEM) == BC_UIF_AEM_EFM)
  {
    /* If we're not BC_ARB_CTRL_EBI state, we need to reconfigure display controller */
    if ((BSP_RegisterRead(&BC_REGISTER->ARB_CTRL) != BC_ARB_CTRL_EBI) || runOnce)
    {
      /* Enable SSD2119 Serial Port Interface */
      BSP_PeripheralAccess(BSP_TFT, true);

      /* Enable EBI mode of operation on SSD2119 controller */
      BSP_DisplayControl(BSP_Display_EBI);
      BSP_DisplayControl(BSP_Display_ResetAssert);
      BSP_DisplayControl(BSP_Display_PowerDisable);
      freq = SystemCoreClockGet();
      for (i = 0; i < (freq / 100); i++)
      {
        __NOP();
      }
      /* Configure display for Direct Drive "Mode Generic" + 3-wire SPI mode */
      BSP_DisplayControl(BSP_Display_ModeGeneric);
      BSP_DisplayControl(BSP_Display_PowerEnable);
      BSP_DisplayControl(BSP_Display_ResetRelease);

      /* Configure GPIO for EBI and TFT */
      TFT_DirectGPIOConfig();

      /* Initialize display */
      stat = DMD_init(0);
      if (DMD_OK == stat) stat = DMD_selectFramebuffer((void*)EBI_BankAddress(EBI_BANK2));
      if (DMD_OK != stat) while (1) ;

      /* Configure EBI TFT direct drive */
      EBI_TFTInit(tftInit);

      runOnce = false;
    }
    ret = true;
  }
  else
  {
    ret = false;
  }

  return ret;
}
Example #5
0
/**************************************************************************//**
 * @brief
 *   Set low frequency crystal oscillator clock frequency for target system.
 *
 * @note
 *   This function is mainly provided for being able to handle target systems
 *   with different HF crystal oscillator frequencies run-time. If used, it
 *   should probably only be used once during system startup.
 *
 * @note
 *   This is an EFM32 proprietary function, not part of the CMSIS definition.
 *
 * @param[in] freq
 *   LFXO frequency in Hz used for target.
 *****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
  /* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
  SystemLFXOClock = freq;

  /* Update core clock frequency if LFXO is used to clock core */
  if (CMU->STATUS & CMU_STATUS_LFXOSEL)
  {
    /* The function will update the global variable */
    SystemCoreClockGet();
  }
#else
  (void)freq; /* Unused parameter */
#endif
}
Example #6
0
/***************************************************************************//**
 * @brief
 *   Enables the flash controller for writing.
 * @note
 *   IMPORTANT: This function must be called before flash operations when
 *   AUXHFRCO clock has been changed from default 14MHz band.
 * @note
 *   This function calls SystemCoreClockGet in order to set the global variable
 *   SystemCoreClock which is used in subseqent calls of MSC_WriteWord to make
 *   sure the frequency is sufficiently high for flash operations. If the clock
 *   frequency is changed then software is responsible for calling MSC_Init or
 *   SystemCoreClockGet in order to set the SystemCoreClock variable to the
 *   correct value.
 ******************************************************************************/
void MSC_Init(void)
{
#if defined( _MSC_TIMEBASE_MASK )
  uint32_t freq, cycles;
#endif
  /* Unlock the MSC */
  MSC->LOCK = MSC_UNLOCK_CODE;
  /* Disable writing to the flash */
  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;

  /* Call SystemCoreClockGet in order to set the global variable SystemCoreClock
     which is used in MSC_LoadWriteData to make sure the frequency is
     sufficiently high. If the clock frequency is changed then software is
     responsible for calling MSC_Init or SystemCoreClockGet in order to set the
     SystemCoreClock variable to the correct value. */
  SystemCoreClockGet();

#if defined( _MSC_TIMEBASE_MASK )
  /* Configure MSC->TIMEBASE according to selected frequency */
  freq = CMU_ClockFreqGet(cmuClock_AUX);

  if (freq > 7000000)
  {
    /* Calculate number of clock cycles for 1us as base period */
    freq   = (freq * 11) / 10;
    cycles = (freq / 1000000) + 1;

    /* Configure clock cycles for flash timing */
    MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK
                                       | _MSC_TIMEBASE_PERIOD_MASK))
                    | MSC_TIMEBASE_PERIOD_1US
                    | (cycles << _MSC_TIMEBASE_BASE_SHIFT);
  }
  else
  {
    /* Calculate number of clock cycles for 5us as base period */
    freq   = (freq * 5 * 11) / 10;
    cycles = (freq / 1000000) + 1;

    /* Configure clock cycles for flash timing */
    MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK
                                       | _MSC_TIMEBASE_PERIOD_MASK))
                    | MSC_TIMEBASE_PERIOD_5US
                    | (cycles << _MSC_TIMEBASE_BASE_SHIFT);
  }
#endif
}
Example #7
0
/**************************************************************************//**
 * @brief  TFT initialize or reinitialize to Address Mapped Mode
 *         Assumes EBI has been configured correctly in BSP_Init(BSP_INIT_DK_EBI)
 *
 * @return true if we should redraw into buffer, false if BC has control
 *         over display
 *****************************************************************************/
bool TFT_AddressMappedInit(void)
{
    bool     ret;
    EMSTATUS status;
    uint32_t i, freq;

    /* If we are in BC_UIF_AEM_EFM state, we can redraw graphics */
    if (BSP_RegisterRead(&BC_REGISTER->UIF_AEM) == BC_UIF_AEM_EFM)
    {
        /* If we're not BC_ARB_CTRL_EBI state, we need to reconfigure display controller */
        if ((BSP_RegisterRead(&BC_REGISTER->ARB_CTRL) != BC_ARB_CTRL_EBI) || runOnce)
        {
            /* Configure for EBI mode and reset display */
            BSP_DisplayControl(BSP_Display_EBI);
            BSP_DisplayControl(BSP_Display_ResetAssert);
            BSP_DisplayControl(BSP_Display_PowerDisable);
            /* Short reset delay */
            freq = SystemCoreClockGet();
            for (i = 0; i < (freq / 100); i++)
            {
                __NOP();
            }
            /* Configure display for Direct Drive + SPI mode */
            BSP_DisplayControl(BSP_Display_Mode8080);
            BSP_DisplayControl(BSP_Display_PowerEnable);
            BSP_DisplayControl(BSP_Display_ResetRelease);

            /* Initialize graphics - abort on failure */
            status = DMDIF_init(BC_SSD2119_BASE, BC_SSD2119_BASE + 2);
            if (status == DMD_OK) status = DMD_init(0);
            if ((status != DMD_OK) && (status != DMD_ERROR_DRIVER_ALREADY_INITIALIZED)) while (1) ;
            /* Make sure display is configured with correct rotation */
            if ((status == DMD_OK)) DMD_flipDisplay(1, 1);

            runOnce = false;
        }
        ret = true;
    }
    else
    {
        ret = false;
    }
    return ret;
}
Example #8
0
File: em_msc.c Project: kraj/zephyr
MSC_RAMFUNC_DEFINITION_END

/* Undef the define from em_assert.h and redirect to local ramfunc version. */
#undef  EFM_ASSERT
#if defined(DEBUG_EFM) || defined(DEBUG_EFM_USER)
#define EFM_ASSERT(expr)    ((expr) ? ((void)0) : mscRfAssertEFM(__FILE__, __LINE__))
#else
#define EFM_ASSERT(expr)    ((void)(expr))
#endif /* defined(DEBUG_EFM) || defined(DEBUG_EFM_USER) */

#endif /* !EM_MSC_RUN_FROM_FLASH */

/** @endcond */

/***************************************************************************//**
 * @addtogroup emlib
 * @{
 ******************************************************************************/

/***************************************************************************//**
 * @addtogroup MSC
 * @{
 ******************************************************************************/

/*******************************************************************************
 **************************   GLOBAL FUNCTIONS   *******************************
 ******************************************************************************/

/***************************************************************************//**
 * @brief
 *   Enables the flash controller for writing.
 * @note
 *   This function must be called before flash operations when
 *   AUXHFRCO clock has been changed from default band.
 * @note
 *   This function calls SystemCoreClockGet in order to set the global variable
 *   SystemCoreClock which is used in subseqent calls of MSC_WriteWord to make
 *   sure the frequency is sufficiently high for flash operations. If the clock
 *   frequency is changed then software is responsible for calling MSC_Init or
 *   SystemCoreClockGet in order to set the SystemCoreClock variable to the
 *   correct value.
 ******************************************************************************/
void MSC_Init(void)
{
#if defined( _MSC_TIMEBASE_MASK )
  uint32_t freq, cycles;
#endif

#if defined( _EMU_STATUS_VSCALE_MASK )
  /* VSCALE must be done and flash erase and write requires VSCALE2 */
  EFM_ASSERT(!(EMU->STATUS & _EMU_STATUS_VSCALEBUSY_MASK));
  EFM_ASSERT((EMU->STATUS & _EMU_STATUS_VSCALE_MASK) == EMU_STATUS_VSCALE_VSCALE2);
#endif

  /* Unlock the MSC */
  MSC->LOCK = MSC_UNLOCK_CODE;
  /* Disable writing to the flash */
  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;

  /* Call SystemCoreClockGet in order to set the global variable SystemCoreClock
     which is used in MSC_LoadWriteData to make sure the frequency is
     sufficiently high. If the clock frequency is changed then software is
     responsible for calling MSC_Init or SystemCoreClockGet in order to set the
     SystemCoreClock variable to the correct value. */
  SystemCoreClockGet();

#if defined( _MSC_TIMEBASE_MASK )
  /* Configure MSC->TIMEBASE according to selected frequency */
  freq = CMU_ClockFreqGet(cmuClock_AUX);

  /* Timebase 5us is used for the 1/1.2MHz band only. Note that the 1MHz band
     is tuned to 1.2MHz on newer revisions.  */
  if (freq > 1200000)
  {
    /* Calculate number of clock cycles for 1us as base period */
    freq   = (freq * 11) / 10;
    cycles = (freq / 1000000) + 1;

    /* Configure clock cycles for flash timing */
    MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK
                                       | _MSC_TIMEBASE_PERIOD_MASK))
                    | MSC_TIMEBASE_PERIOD_1US
                    | (cycles << _MSC_TIMEBASE_BASE_SHIFT);
  }
  else
  {
    /* Calculate number of clock cycles for 5us as base period */
    freq   = (freq * 5 * 11) / 10;
    cycles = (freq / 1000000) + 1;

    /* Configure clock cycles for flash timing */
    MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK
                                       | _MSC_TIMEBASE_PERIOD_MASK))
                    | MSC_TIMEBASE_PERIOD_5US
                    | (cycles << _MSC_TIMEBASE_BASE_SHIFT);
  }
#endif
}
Example #9
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  int   value, delayCount = 0, hfrcoband = 0;
  float current, voltage;
  bool  vboost;
  char  buffer[8];

  /* Chip errata */
  CHIP_Init();

  /* If first word of user data page is non-zero, enable eA Profiler trace */
  BSP_TraceProfilerSetup();

  /* Initialize board support package */
  BSP_Init(BSP_INIT_BCC);

  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ;

  /* Initialize voltage comparator, to check supply voltage */
  VDDCHECK_Init();

  /* Check if voltage is below 3V, if so use voltage boost */
  if (VDDCHECK_LowVoltage(2.9))
  {
    vboost = true;
  }
  else
  {
    vboost = false;
  }

  /* Disable Voltage Comparator */
  VDDCHECK_Disable();

  /* Initialize segment LCD */
  SegmentLCD_Init(vboost);

  /* Infinite loop */
  while (1)
  {
    /* Read and display current */
    current = BSP_CurrentGet();
    value   = (int)(1000 * current);

    /* Check that we fall within displayable value */
    if ((value > 0) && (value < 10000))
    {
      SegmentLCD_Number(value);
    }
    else
    {
      SegmentLCD_Number(-1);
    }

    /* Alternate between voltage and clock frequency */
    if (((delayCount / 10) & 1) == 0)
    {
      voltage = BSP_VoltageGet();
      value   = (int)(voltage * 100);
      SegmentLCD_Symbol(LCD_SYMBOL_DP6, 1);
      sprintf(buffer, "Volt%3d", value);
      SegmentLCD_Write(buffer);
    }
    else
    {
      SegmentLCD_Symbol(LCD_SYMBOL_DP6, 0);
      sprintf(buffer, "%3u MHz", (int)(SystemCoreClockGet() / 1000000));
      SegmentLCD_Write(buffer);
    }
    /* After 5 seconds, use another HFRCO band */
    if (delayCount % 50 == 0)
    {
      switch (hfrcoband)
      {
      case 0:
        CMU_HFRCOBandSet(cmuHFRCOBand_11MHz);
        break;
      case 1:
        CMU_HFRCOBandSet(cmuHFRCOBand_14MHz);
        break;
      case 2:
        CMU_HFRCOBandSet(cmuHFRCOBand_21MHz);
        break;
      default:
        CMU_HFRCOBandSet(cmuHFRCOBand_28MHz);
        /* Restart iteartion */
        hfrcoband = -1;
        break;
      }
      hfrcoband++;
      /* Recalculate delay tick count and baudrate generation */
      if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ;
      BSP_Init(BSP_INIT_BCC);
    }

    Delay(100);
    delayCount++;
  }
}
Example #10
0
__ramfunc
#endif
#endif /* !EM_MSC_RUN_FROM_FLASH */
__STATIC_INLINE MSC_Status_TypeDef
  MSC_LoadWriteData(uint32_t* data,
                    uint32_t numWords,
                    MSC_WriteStrategy_Typedef writeStrategy)
{
  uint32_t timeOut;
  uint32_t wordIndex;
  uint32_t wordsPerDataPhase;
  MSC_Status_TypeDef retval = mscReturnOk;

#if defined(_MSC_WRITECTRL_LPWRITE_MASK) && defined(_MSC_WRITECTRL_WDOUBLE_MASK)
  /* If LPWRITE (Low Power Write) is NOT enabled, set WDOUBLE (Write Double word) */
  if (!(MSC->WRITECTRL & MSC_WRITECTRL_LPWRITE))
  {
    /* If the number of words to be written are odd, we need to align by writing
       a single word first, before setting the WDOUBLE bit. */
    if (numWords & 0x1)
    {
      /* Wait for the MSC to become ready for the next word. */
      timeOut = MSC_PROGRAM_TIMEOUT;
      while ((!(MSC->STATUS & MSC_STATUS_WDATAREADY)) && (timeOut != 0))
      {
        timeOut--;
      }
      /* Check for timeout */
      if (timeOut == 0)
      {
        return mscReturnTimeOut;
      }
      /* Clear double word option, in order to write the initial single word. */
      MSC->WRITECTRL &= ~MSC_WRITECTRL_WDOUBLE;
      /* Write first data word. */
      MSC->WDATA = *data++;
      MSC->WRITECMD = MSC_WRITECMD_WRITEONCE;

      /* Wait for the operation to finish. It may be required to change the WDOUBLE
         config after the initial write. It should not be changed while BUSY. */
      timeOut = MSC_PROGRAM_TIMEOUT;
      while((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
      {
        timeOut--;
      }
      /* Check for timeout */
      if (timeOut == 0)
      {
        return mscReturnTimeOut;
      }
      /* Subtract this initial odd word for the write loop below */
      numWords -= 1;
      retval = mscReturnOk;
    }
    /* Now we can set the double word option in order to write two words per
       data phase. */
    MSC->WRITECTRL |= MSC_WRITECTRL_WDOUBLE;
    wordsPerDataPhase = 2;
  }
  else
#endif /* defined( _MSC_WRITECTRL_LPWRITE_MASK ) && defined( _MSC_WRITECTRL_WDOUBLE_MASK ) */
  {
    wordsPerDataPhase = 1;
  }

  /* Write the rest as double word write if wordsPerDataPhase == 2 */
  if (numWords > 0)
  {
    /**** Write strategy: mscWriteIntSafe ****/
    if (writeStrategy == mscWriteIntSafe)
    {
      /* Requires a system core clock at 1MHz or higher */
      EFM_ASSERT(SystemCoreClockGet() >= 1000000);
      wordIndex = 0;
      while(wordIndex < numWords)
      {
        MSC->WDATA = *data++;
        wordIndex++;
        if (wordsPerDataPhase == 2)
        {
          while (!(MSC->STATUS & MSC_STATUS_WDATAREADY));
          MSC->WDATA = *data++;
          wordIndex++;
        }
        MSC->WRITECMD = MSC_WRITECMD_WRITEONCE;

        /* Wait for the transaction to finish. */
        timeOut = MSC_PROGRAM_TIMEOUT;
        while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
        {
          timeOut--;
        }
        /* Check for timeout */
        if (timeOut == 0)
        {
          retval = mscReturnTimeOut;
          break;
        }
#if defined( _EFM32_GECKO_FAMILY )
        MSC->ADDRB += 4;
        MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
#endif
      }
    }

    /**** Write strategy: mscWriteFast ****/
    else
    {
#if defined( _EFM32_GECKO_FAMILY )
      /* Gecko does not have auto-increment of ADDR. */
      EFM_ASSERT(0);
#else
      /* Requires a system core clock at 14MHz or higher */
      EFM_ASSERT(SystemCoreClockGet() >= 14000000);

      wordIndex = 0;
      INT_Disable();
      while(wordIndex < numWords)
      {
        /* Wait for the MSC to be ready for the next word. */
        while (!(MSC->STATUS & MSC_STATUS_WDATAREADY))
        {
          /* If the write to MSC->WDATA below missed the 30us timeout and the
             following MSC_WRITECMD_WRITETRIG command arrived while
             MSC_STATUS_BUSY is 1, then the MSC_WRITECMD_WRITETRIG could be ignored by
             the MSC. In this case, MSC_STATUS_WORDTIMEOUT is set to 1
             and MSC_STATUS_BUSY is 0. A new trigger is therefore needed here to
             complete write of data in MSC->WDATA.
             If WDATAREADY became high since entry into this loop, exit and continue
             to the next WDATA write.
          */
          if ((MSC->STATUS & (MSC_STATUS_WORDTIMEOUT
                              | MSC_STATUS_BUSY
                              | MSC_STATUS_WDATAREADY))
              == MSC_STATUS_WORDTIMEOUT)
          {
            MSC->WRITECMD = MSC_WRITECMD_WRITETRIG;
          }
        }
        MSC->WDATA = *data;
        if ((wordsPerDataPhase == 1)
            || ((wordsPerDataPhase == 2) && (wordIndex & 0x1)))
        {
          MSC->WRITECMD = MSC_WRITECMD_WRITETRIG;
        }
        data++;
        wordIndex++;
      }
      INT_Enable();

      /* Wait for the transaction to finish. */
      timeOut = MSC_PROGRAM_TIMEOUT;
      while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
      {
        timeOut--;
      }
      /* Check for timeout */
      if (timeOut == 0)
      {
        retval = mscReturnTimeOut;
      }
#endif
    } /* writeStrategy */
  }

#if defined( _MSC_WRITECTRL_WDOUBLE_MASK )
  /* Clear double word option, which should not be left on when returning. */
  MSC->WRITECTRL &= ~MSC_WRITECTRL_WDOUBLE;
#endif

  return retval;
}
Example #11
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  const int msDelay = 100;

  /* Chip errata */
  CHIP_Init();

  /* If first word of user data page is non-zero, enable eA Profiler trace */
  BSP_TraceProfilerSetup();

    /* Power down special RAM blocks to reduce current consumption with some nA. */
  CMU_ClockEnable(cmuClock_CORELE, true);
  LESENSE->POWERDOWN = LESENSE_POWERDOWN_RAM;
  CMU_ClockEnable(cmuClock_CORELE, false);

  /* Configure push button interrupts */
  gpioSetup();

  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ;

  /* Initialize LCD controller */
  SegmentLCD_Init(false);

  /* Run countdown for user to select energy mode */
  msCountDown = 4000; /* milliseconds */
  while (msCountDown > 0)
  {
    switch (eMode)
    {
    case 0:
      SegmentLCD_Write("EM0 32M");
      break;
    case 1:
      SegmentLCD_Write("EM1 32M");
      break;
    case 2:
      SegmentLCD_Write("EM2 32K");
      break;
    case 3:
      SegmentLCD_Write("EM3");
      break;
    case 4:
      SegmentLCD_Write("EM4");
      break;
    case 5:
      SegmentLCD_Write("EM2+RTC");
      break;
    case 6:
      SegmentLCD_Write("RTC+LCD");
      break;
    case 7:
      SegmentLCD_Write("EM3+RTC");
      break;
    case 8:
      SegmentLCD_Write("USER");
      break;
    }
    SegmentLCD_Number(msCountDown);
    Delay(msDelay);
    msCountDown -= msDelay;
  }
  /* Disable components, reenable when needed */
  SegmentLCD_Disable();
  RTC_Enable(false);

  /* GPIO->ROUTE = 0x00000000; */

  /* Go to energy mode and wait for reset */
  switch (eMode)
  {
  case 0:
    /* Disable pin input */
    GPIO_PinModeSet(gpioPortB, 10, gpioModeDisabled, 1);

    /* Disable systick timer */
    SysTick->CTRL = 0;

    /* 32Mhz primes demo - running off HFXO */
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
    /* Disable HFRCO, LFRCO and all unwanted clocks */
    CMU->OSCENCMD     = CMU_OSCENCMD_HFRCODIS;
    CMU->OSCENCMD     = CMU_OSCENCMD_LFRCODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    CMU->LFCLKSEL     = 0x00000000;
    /* Supress Conditional Branch Target Prefetch */
    MSC->READCTRL = MSC_READCTRL_MODE_WS1SCBTP;
    {
      #define PRIM_NUMS    64
      uint32_t i, d, n;
      uint32_t primes[PRIM_NUMS];

      /* Find prime numbers forever */
      while (1)
      {
        primes[0] = 1;
        for (i = 1; i < PRIM_NUMS;)
        {
          for (n = primes[i - 1] + 1;; n++)
          {
            for (d = 2; d <= n; d++)
            {
              if (n == d)
              {
                primes[i] = n;
                goto nexti;
              }
              if (n % d == 0) break;
            }
          }
 nexti:
          i++;
        }
      }
    }
  case 1:
    /* Disable pin input */
    GPIO_PinModeSet(gpioPortB, 10, gpioModeDisabled, 1);

    /* Disable systick timer */
    SysTick->CTRL = 0;

    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
    /* Disable HFRCO, LFRCO and all unwanted clocks */
    CMU->OSCENCMD     = CMU_OSCENCMD_HFRCODIS;
    CMU->OSCENCMD     = CMU_OSCENCMD_LFRCODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    CMU->LFCLKSEL     = 0x00000000;
    EMU_EnterEM1();
    break;
  case 2:
    /* Enable LFRCO */
    CMU->OSCENCMD = CMU_OSCENCMD_LFRCOEN;
    /* Disable everything else */
    CMU->OSCENCMD     = CMU_OSCENCMD_LFXODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    /* Disable LFB clock select */
    CMU->LFCLKSEL     = 0x00000000;
    EMU_EnterEM2(false);
    break;
  case 3:
    /* Disable all clocks */
    CMU->OSCENCMD     = CMU_OSCENCMD_LFXODIS;
    CMU->OSCENCMD     = CMU_OSCENCMD_LFRCODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    CMU->LFCLKSEL     = 0x00000000;
    EMU_EnterEM3(false);
    break;
  case 4:
    /* Go straight down to EM4 */
    EMU_EnterEM4();
    break;
  case 5:
    /* EM2 + RTC - only briefly wake up to reconfigure every 2 seconds */
    /* Disable LFB clock select */
    CMU->LFCLKSEL     &= ~(_CMU_LFCLKSEL_LFB_MASK);
    RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32);
    while (1)
    {
      RTCDRV_Trigger(2000, NULL);
      EMU_EnterEM2(false);
    }
  case 6:
    /* EM2 + RTC + LCD (if battery slips below 3V vboost should be enabled) */
    /* Disable LFB clock select */
    CMU->LFCLKSEL     &= ~(_CMU_LFCLKSEL_LFB_MASK);
    SegmentLCD_Init(false);
    RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32);
    while (1)
    {
      SegmentLCD_Write("Silicon");
      /* Sleep in EM2 */
      RTCDRV_Trigger(2000, NULL);
      EMU_EnterEM2(false);

      SegmentLCD_Write(" Labs");
      /* Sleep in EM2 */
      RTCDRV_Trigger(2000, NULL);
      EMU_EnterEM2(false);
    }
  case 7:
    /* EM3 + RTC - only briefly wake up to reconfigure every ~5 seconds */
    while (1)
    {
      /* Disable LFB clock select */
      CMU->LFCLKSEL     &= ~(_CMU_LFCLKSEL_LFB_MASK);
      /* This RTCDRV_Setup will configure LFCLK A as ULFRCO */
      RTCDRV_Setup(cmuSelect_ULFRCO, cmuClkDiv_1);
      RTCDRV_Trigger(5000, NULL);
      /* Sleep in EM3, wake up on RTC trigger */
      EMU_EnterEM3(false);
      /* SegmentLCD_Init will configure LFCLK A as LFRCO */
      SegmentLCD_Init(false);
      SegmentLCD_Write("ULFRCO");
      Delay(1000);
      SegmentLCD_Disable();
    }
  case 8:
  default:
    /* User defined */
    break;
  }

  return 0;
}
Example #12
0
/***************************************************************************//**
 * @brief
 *   Initialize LCD device
 *
 * @details
 *
 * @note
 *
 ******************************************************************************/
void efm32_spiLcd_init(void)
{
    struct efm32_usart_device_t *usart;
    rt_uint32_t                 flag;
    DMD_DisplayGeometry         *geometry;
    rt_uint32_t                 ret;

	do
	{
        USART_InitSync_TypeDef init = USART_INITSYNC_DEFAULT;

		/* Find SPI device */
		lcd = rt_device_find(LCD_USING_DEVICE_NAME);
		if (lcd == RT_NULL)
		{
			lcd_debug("LCD err: Can't find %s!\n", LCD_USING_DEVICE_NAME);
			break;
		}
		lcd_debug("LCD: Find device %s\n", LCD_USING_DEVICE_NAME);

        /* Config CS pin */
        usart = (struct efm32_usart_device_t *)(lcd->user_data);
        if (!(usart->state & USART_STATE_AUTOCS))
        {
            GPIO_PinModeSet(LCD_CS_PORT, LCD_CS_PIN, gpioModePushPull, 1);
            lcdAutoCs = false;
        }

        /* TFT initialize or reinitialize. Assumes EBI has been configured
           correctly in DVK_init(DVK_Init_EBI) */
        rt_uint32_t freq = SystemCoreClockGet();
        rt_uint32_t i;
        rt_bool_t warning = RT_FALSE;

        /* If we are in BC_UIF_AEM_EFM state, we can redraw graphics */
        while (DVK_readRegister(&BC_REGISTER->UIF_AEM) != BC_UIF_AEM_EFM)
        {
            if (!warning)
            {
                lcd_debug("LCD: Please press AEM button!!!\n");
                warning = RT_TRUE;
            }
        }

        lcd_debug("LCD: Got LCD control\n");
        /* If we're not BC_ARB_CTRL_EBI state, we need to reconfigure display controller */
        if (DVK_readRegister(&BC_REGISTER->ARB_CTRL) != BC_ARB_CTRL_EBI)
        {
            lcd_debug("LCD: Set to EBI mode\n");
            /* Configure for EBI mode and reset display */
            DVK_displayControl(DVK_Display_EBI);
            DVK_displayControl(DVK_Display_ResetAssert);
            DVK_displayControl(DVK_Display_PowerDisable);
            /* Short delay */
            freq = SystemCoreClockGet();
            for(i = 0; i < (freq / 100); i++)
            {
                __NOP();
            }
#if defined(LCD_MAPPED)
            /* Configure display for address mapped method + 3-wire SPI mode */
            DVK_displayControl(DVK_Display_Mode8080);
            DVK_displayControl(DVK_Display_PowerEnable);
            DVK_displayControl(DVK_Display_ResetRelease);

            /* Initialize graphics - abort on failure */
            ret = DMD_init(BC_SSD2119_BASE, BC_SSD2119_BASE + 2);
            if (ret == DMD_OK)
            {
                /* Make sure display is configured with correct rotation */
                DMD_flipDisplay(1, 1);
            }
            else if (ret != DMD_ERROR_DRIVER_ALREADY_INITIALIZED)
            {
                lcd_debug("LCD err: driver init failed %x\n", ret);
                break;
            }
#elif defined(LCD_DIRECT)
            /* Configure TFT direct drive method from EBI BANK2 */
            const EBI_TFTInit_TypeDef tftInit =
            {
                ebiTFTBank2,                  /* Select EBI Bank 2 */
                ebiTFTWidthHalfWord,          /* Select 2-byte (16-bit RGB565) increments */
                ebiTFTColorSrcMem,            /* Use memory as source for mask/blending */
                ebiTFTInterleaveUnlimited,    /* Unlimited interleaved accesses */
                ebiTFTFrameBufTriggerVSync,   /* VSYNC as frame buffer update trigger */
                false,                        /* Drive DCLK from negative edge of internal clock */
                ebiTFTMBDisabled,             /* No masking and alpha blending enabled */
                ebiTFTDDModeExternal,         /* Drive from external memory */
                ebiActiveLow,                 /* CS Active Low polarity */
                ebiActiveHigh,                /* DCLK Active High polarity */
                ebiActiveLow,                 /* DATAEN Active Low polarity */
                ebiActiveLow,                 /* HSYNC Active Low polarity */
                ebiActiveLow,                 /* VSYNC Active Low polarity */
                320,                          /* Horizontal size in pixels */
                1,                            /* Horizontal Front Porch */
                30,                           /* Horizontal Back Porch */
                2,                            /* Horizontal Synchronization Pulse Width */
                240,                          /* Vertical size in pixels */
                1,                            /* Vertical Front Porch */
                4,                            /* Vertical Back Porch */
                2,                            /* Vertical Synchronization Pulse Width */
                0x0000,                       /* Frame Address pointer offset to EBI memory base */
                4,                            /* DCLK Period */
                0,                            /* DCLK Start cycles */
                0,                            /* DCLK Setup cycles */
                0,                            /* DCLK Hold cycles */
            };

            DVK_enablePeripheral(DVK_TFT);

            /* Configure display for Direct Drive + 3-wire SPI mode */
            DVK_displayControl(DVK_Display_ModeGeneric);
            DVK_displayControl(DVK_Display_PowerEnable);
            DVK_displayControl(DVK_Display_ResetRelease);

            /* Configure GPIO for EBI and TFT */
            /* EBI TFT DCLK/Dot Clock */
            GPIO_PinModeSet(gpioPortA, 8, gpioModePushPull, 0);
            /* EBI TFT DATAEN */
            GPIO_PinModeSet(gpioPortA, 9, gpioModePushPull, 0);
            /* EBI TFT VSYNC  */
            GPIO_PinModeSet(gpioPortA, 10, gpioModePushPull, 0);
            /* EBI TFT HSYNC */
            GPIO_PinModeSet(gpioPortA, 11, gpioModePushPull, 0);

            /* Initialize display */
            DMD_init(0, (rt_uint32_t)EBI_BankAddress(EBI_BANK2));

            /* Configure EBI TFT direct drive */
            EBI_TFTInit(&tftInit);
#endif
        }

        /* Get LCD geometry */
        ret = DMD_getDisplayGeometry(&geometry);
        if (ret != DMD_OK)
        {
            lcd_debug("LCD err: get geometry failed!\n");
            break;
        }

        /* Init LCD info */
		flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DMA_TX;
        lcd_info.pixel_format       = RTGRAPHIC_PIXEL_FORMAT_RGB565P;
        lcd_info.bits_per_pixel     = 16;
        lcd_info.width              = geometry->xSize;
        lcd_info.height             = geometry->ySize;
#if defined(LCD_MAPPED)
        lcd_info.framebuffer        = RT_NULL;
        efm32_spiLcd_register(&lcd_device, LCD_DEVICE_NAME, flag, (void *)&lcd_ops);
#elif defined(LCD_DIRECT)
        lcd_info.framebuffer        = (rt_uint8_t *)EBI_BankAddress(EBI_BANK2);
        efm32_spiLcd_register(&lcd_device, LCD_DEVICE_NAME, flag, RT_NULL);
#endif

        /* Set clipping area */
        ret = DMD_setClippingArea(0, 0, geometry->xSize, geometry->ySize);
        if (ret != DMD_OK)
        {
            lcd_debug("LCD err: set clipping area failed!\n");
            break;
        }
        /* Read device code */
        rt_uint16_t code = 0xFFFF;
#if defined(LCD_MAPPED)
        code = DMDIF_readDeviceCode();
#endif
        /* Set as rtgui graphic driver */
        rtgui_graphic_set_device(&lcd_device);

        lcd_debug("LCD: H/W init OK!\n");
        return;
    } while(0);

    lcd_debug("LCD err: H/W init failed!\n");
}
Example #13
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  int msCountDown;
  const int msDelay = 100;
  char displayString[8];
  LCD_AnimInit_TypeDef anim = {
    true,
    0x00,
    lcdAnimShiftNone,
    0x03,
    lcdAnimShiftLeft,
    lcdAnimLogicOr
  };
  LCD_FrameCountInit_TypeDef fc = {
    true,
    2, /* Update each 2nd frame */
    lcdFCPrescDiv1,
  };

  /* Chip errata */
  CHIP_Init();

  /* If first word of user data page is non-zero, enable eA Profiler trace */
  BSP_TraceProfilerSetup();

  /* Configure push button interrupts */
  gpioSetup();

  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ;

  /* Initialize LCD controller */
  SegmentLCD_Init(false);

  /* Run countdown for user to select energy mode */
  msCountDown = 4000; /* milliseconds */
  while(msCountDown > 0)
  {
    if ( eMode >=3 && eMode<=4) {
      sprintf(displayString, "EM%d", eMode);
      SegmentLCD_Write(displayString);
    }
    switch( eMode )
    {
    case 0:
      SegmentLCD_Write("EM0 32M");
      break;
    case 1:
      SegmentLCD_Write("EM1 32M");
      break;
    case 2:
      SegmentLCD_Write("EM2 32K");
      break;
    case 5:
      SegmentLCD_Write("EM2+RTC");
      break;
    case 6:
      SegmentLCD_Write("RTC+LCD");
      break;
    }
    SegmentLCD_Number(msCountDown);
    Delay(msDelay);
    msCountDown -= msDelay;
  }
  /* Disable components, reenable when needed */
  SegmentLCD_Disable();
  RTC_Enable(false);

  /* Go to energy mode and wait for reset */
  switch(eMode)
  {
  case 0:
    /* Disable pin input */
    GPIO_PinModeSet(gpioPortB, 10, gpioModeDisabled, 1);

    /* Disable systick timer */
    SysTick->CTRL  = 0;

    /* 32Mhz primes demo - running off HFXO */
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
    /* Disable HFRCO, LFRCO and all unwanted clocks */
    CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
    CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    CMU->LFCLKSEL     = 0x00000000;
    /* Supress Conditional Branch Target Prefetch */
    MSC->READCTRL = MSC_READCTRL_MODE_WS1SCBTP;
    {
      #define PRIM_NUMS 64
      uint32_t i, d, n;
      uint32_t primes[PRIM_NUMS];

      /* Find prime numbers forever */
      while (1)
      {
        primes[0] = 1;
        for (i = 1; i < PRIM_NUMS;)
        {
          for (n = primes[i - 1] + 1; ;n++)
          {
            for (d = 2; d <= n; d++)
            {
              if (n == d)
              {
                primes[i] = n;
                goto nexti;
              }
              if (n%d == 0) break;
            }
          }
        nexti:
          i++;
        }
      }
    }
  case 1:
    /* Disable pin input */
    GPIO_PinModeSet(gpioPortB, 10, gpioModeDisabled, 1);

    /* Disable systick timer */
    SysTick->CTRL  = 0;

    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
    /* Disable HFRCO, LFRCO and all unwanted clocks */
    CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
    CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    CMU->LFCLKSEL     = 0x00000000;
    EMU_EnterEM1();
    break;
  case 2:
    /* Enable LFRCO */
    CMU->OSCENCMD = CMU_OSCENCMD_LFRCOEN;
    /* Disable everything else */
    CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    CMU->LFCLKSEL     = 0x00000000;
    EMU_EnterEM2(false);
    break;
  case 3:
    /* Disable all clocks */
    CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS;
    CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS;
    CMU->HFPERCLKEN0  = 0x00000000;
    CMU->HFCORECLKEN0 = 0x00000000;
    CMU->LFACLKEN0    = 0x00000000;
    CMU->LFBCLKEN0    = 0x00000000;
    EMU_EnterEM3(false);
    break;
  case 4:
    EMU_EnterEM4();
    break;
  case 5:
    /* EM2 + RTC - only briefly wake up to reconfigure each second */
    CMU->LFCLKSEL     = CMU_LFCLKSEL_LFA_LFRCO;
    while(1)
    {
      RTCDRV_Trigger(2000, NULL);
      EMU_EnterEM2(false);
    }
  case 6:
  default:
    /* EM2 + RTC + LCD (if battery slips below 3V vboost should be */
    /* enabled) */
    CMU->LFCLKSEL     = CMU_LFCLKSEL_LFA_LFRCO;
    SegmentLCD_Init(false);
    /* Animate LCD */
    LCD_FrameCountInit(&fc);
    LCD_AnimInit(&anim);
    while(1)
    {
      SegmentLCD_Write("Energy");
      /* Sleep in EM2 */
      RTCDRV_Trigger(2000,NULL);
      EMU_EnterEM2(false);

      SegmentLCD_Write("Micro");
      /* Sleep in EM2 */
      RTCDRV_Trigger(2000,NULL);
      EMU_EnterEM2(false);
    }
  }

  return 0;
}