/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
    TEMPSENS_Temp_TypeDef temp;

    /* Chip revision alignment and errata fixes */
    CHIP_Init();

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

    I2C_Tempsens_Init();

    /* Main loop - just read temperature and update LCD */
    while (1)
    {
        if (TEMPSENS_TemperatureGet(I2C0,
                                    TEMPSENS_DVK_ADDR,
                                    &temp) < 0)
        {
            SegmentLCD_Write("ERROR");
            /* Enter EM2, no wakeup scheduled */
            EMU_EnterEM2(true);
        }

        /* Update LCD display */
        temperatureUpdateLCD(&temp);

        /* Read every 2 seconds which is more than it takes worstcase to */
        /* finish measurement inside sensor. */
        RTCDRV_Trigger(2000, NULL);
        EMU_EnterEM2(true);
    }
}
Example #2
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  I2C_Init_TypeDef      i2cInit = I2C_INIT_DEFAULT;
  TEMPSENS_Temp_TypeDef temp;
  /* Define previous temp to invalid, just to ensure update first time */
  TEMPSENS_Temp_TypeDef prevTemp = {1000, 0};
  int                   prevShowFahrenheit = showFahrenheit;

  /* Initialize DK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  /* Initialize TFT */
  RETARGET_SerialInit();
  printf("\nEFM32 I2C temperature sensor example\n\n");

  /* Enable board control interrupts */
  BSP_InterruptDisable(0xffff);
  BSP_InterruptFlagsClear(0xffff);
  BSP_InterruptEnable(BC_INTEN_JOYSTICK);
  temperatureIRQInit();

  /* Initialize I2C driver, using standard rate. Devices on DK itself */
  /* supports fast mode, but in case some slower devices are added on */
  /* prototype board, we use standard mode. */
  I2CDRV_Init(&i2cInit);

  /* Main loop - just read temperature and update LCD */
  while (1)
  {
    if (TEMPSENS_TemperatureGet(I2C0,
                                TEMPSENS_DK_ADDR,
                                &temp) < 0)
    {
      printf("ERROR\n");
      /* Enter EM2, no wakeup scheduled */
      EMU_EnterEM2(true);
    }

    /* Update LCD display if any change. This is just an example of how */
    /* to save some energy, since the temperature normally is quite static. */
    /* The compare overhead is much smaller than actually updating the display. */
    if ((prevTemp.i != temp.i) ||
        (prevTemp.f != temp.f) ||
        (prevShowFahrenheit != showFahrenheit))
    {
      temperatureUpdate(&temp);
    }
    prevTemp           = temp;
    prevShowFahrenheit = showFahrenheit;

    /* Read every 2 seconds which is more than it takes worstcase to */
    /* finish measurement inside sensor. */
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(true);
  }
}
Example #3
0
/**************************************************************************//**
 * @brief Sleeps in EM2 in given time unless some other IRQ sources has been
 *        enabled
 * @param msec Time in milliseconds
 *****************************************************************************/
void EM2Sleep(uint32_t msec)
{
  /* Wake us up after msec (or joystick pressed) */
  NVIC_DisableIRQ(LCD_IRQn);
  RTCDRV_Trigger(msec, NULL);
  EMU_EnterEM2(true);
  NVIC_EnableIRQ(LCD_IRQn);
}
Example #4
0
/**************************************************************************//**
 * @brief Sleeps in EM1 in given time unless some other IRQ sources has been
 *        enabled
 * @param msec Time in milliseconds
 *****************************************************************************/
void EM1Sleep(uint32_t msec)
{
  /* Wake us up after msec (or joystick pressed) */
  NVIC_DisableIRQ(LCD_IRQn);
  /* Tell AEM we're in EM1 */
  RTCDRV_Trigger(msec, RtcTrigger);
  EMU_EnterEM1();
  NVIC_EnableIRQ(LCD_IRQn);
}
Example #5
0
int main(void) 
{
	
	CHIP_Init();

	if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ;

  BSP_Init(BSP_INIT_DEFAULT);
	BSP_LedsSet(0);

  BSP_PeripheralAccess(BSP_AUDIO_IN, true);
  BSP_PeripheralAccess(BSP_AUDIO_OUT, true);

  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  initSource();

	setupCMU();
  setupDMA();
  
  //setupADC();
  //setupDAC();

  //setupDMAInput();
  //setupDMAOutput();

	//setupDMASplit();
	//setupDMAMerge();

  ADCConfig();
  DACConfig();

  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
  TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_HFPER) / SAMPLE_RATE);
  TIMER_Init(TIMER0, &timerInit);

	Delay(100);
	BSP_LedsSet(3);
	Delay(500);
	BSP_LedsSet(0);
	Delay(100);

	while(1) {
		volatile bool result = test();
		if (result) {
			BSP_LedsSet(0x00FF);
		} else {
			BSP_LedsSet(0xFF00);			
		}
		Delay(1000);
    BSP_LedsSet(0x0);    
    Delay(1000);
	}

}
Example #6
0
/**************************************************************************//**
 * @brief Sleeps in EM2 in given time unless some other IRQ sources has been
 *        enabled
 * @param msec Time in milliseconds
 *****************************************************************************/
void EM2Sleep(uint32_t msec)
{
  /* Wake us up after msec (or joystick pressed) */
  NVIC_DisableIRQ(LCD_IRQn);
  /* Tell AEM we're in EM2 */
  BSP_EnergyModeSet(2);
  RTCDRV_Trigger(msec, NULL);
  EMU_EnterEM2(true);
  BSP_EnergyModeSet(0);
  NVIC_EnableIRQ(LCD_IRQn);
}
Example #7
0
/***************************************************************************//**
 * @brief RTC delay function
 * @param msec Number of msec to delay
 * @param useEM2 Enter EM2 while waiting
 ******************************************************************************/
void RTCDRV_Delay(uint32_t msec, bool useEM2)
{
  rtcDelayComplete = false;
  RTCDRV_Trigger(msec, DelayCB);

  while (!rtcDelayComplete)
  {
    if (useEM2)
    {
      EMU_EnterEM2(true);
    }
  }
}
Example #8
0
/**************************************************************************//**
 * @brief Sleeps in EM2 in given time
 * @param msec Time in milliseconds
 *****************************************************************************/
void EM2Sleep(uint32_t msec)
{
  /* Wake us up after msec */
  NVIC_DisableIRQ(LCD_IRQn);
  rtcFlag = true;
  RTCDRV_Trigger(msec, RTC_TimeOutHandler);
  /* The rtcFlag variable is set in the RTC interrupt routine using the callback
   * RTC_TimeOutHandler. This makes sure that the elapsed time is correct. */
  while (rtcFlag)
  {
    EMU_EnterEM2(true);
  }
  NVIC_EnableIRQ(LCD_IRQn);
}
Example #9
0
/**************************************************************************//**
 * @brief Energy Mode 2 demonstration, with RTC wake up every 2nd second
 *****************************************************************************/
void Demo_EM2_RTC(void)
{
  /* Disable systick timer */
  SysTick->CTRL  = 0;

  /* Disable DK interrupts */
  BSP_InterruptDisable(0xffff);

  /* Disable all peripheral clocks */
  CMU->HFPERCLKEN0  = 0x00000000;
  CMU->HFCORECLKEN0 = 0x00000000;
  CMU->LFACLKEN0    = 0x00000000;
  CMU->LFBCLKEN0    = 0x00000000;

  /* LFRCO will be enabled by RTCDRV_Trigger below */

  /* Enter Energy Mode 2 - this will never wake up */
  while(1)
  {
    /* Wake up every 2nd second */
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(false);
  }
}
Example #10
0
/**************************************************************************//**
 * @brief  Main function
 * The DAC produces an output signal which the ADC measures. The measured
 * result is printed on the LCD screen.
 *
 * The code shows two different examples of ADC input:
 *
 * One version uses DAC output channel 0 as input.
 *
 * The other version uses ADC input channel 3 (PD3 on the STK). This pin must
 * then be connected with a wire to the DAC output channel 0 (PB11 on the STK).
 *
 *****************************************************************************/
int main(void)
{
  /* Variable declarations */
  uint32_t DAC_Value;
  uint32_t sample;
  double   voltage;

  /* Initialize chip */
  CHIP_Init();

  /* Initialize LCD */
  SegmentLCD_Init(false);

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);

  /* Configure ADC */
  ADCConfig();

  /* Initialize the DAC */
  DAC_setup();

  /* Enable DAC channel 0, located on pin PB11 */
  DAC_Enable(DAC0, 0, true);


  /* This code is only necessary when using ADC input channel 3 which
   * is connected to pin PD3 on the STK. Enable it by uncommenting the
   * definition of EXTERNAL above */
#ifdef EXTERNAL
  CMU_ClockEnable(cmuClock_GPIO, true);
  GPIO_PinModeSet(gpioPortD, 3, gpioModeInputPull, 1);
  GPIO_PinOutClear(gpioPortD, 3);
#endif

  /* Stay in this loop forever */
  while (1)
  {
    /* Calculate DAC output to 0.5 V. */
    DAC_Value = (uint32_t)((0.5 * 4096) / 1.25);

    /* Write the new value to DAC register */
    DAC_WriteData(DAC0, DAC_Value, 0);

    /* Start single conversion for ADC */
    ADC_Start(ADC0, adcStartSingle);

    /* Wait while conversion is active */
    while (ADC0->STATUS & ADC_STATUS_SINGLEACT) ;

    /* Get ADC result */
    sample = ADC_DataSingleGet(ADC0);

    /* Calculate output voltage produced by the DAC  */
    voltage = (sample * 1.25) / 4096;

    /* Write the result to LCD */
    char buffer[10];
    snprintf(buffer, 8, "%1.2f", voltage);
    SegmentLCD_Write(buffer);

    /* wait 100ms in EM2 before next conversion */
    RTCDRV_Trigger(100, NULL);
    EMU_EnterEM2(true);
  }
}
Example #11
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  SYSTEM_ChipRevision_TypeDef revision;
  char string[8];
  int i;
  uint32_t temp;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

  /* Initialize DVK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_GPIO, true);

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

  SegmentLCD_AllOff();

  /* Check for revision after revision B. Chips with revision earlier than */
  /* Revision C has known problems with the internal temperature sensor. */
  /* Display a warning in this case */
  SYSTEM_ChipRevisionGet(&revision);
  if (revision.minor < 2)
  {
    SegmentLCD_Write("WARNING");
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(true);
    SegmentLCD_Write("REV C+");
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(true);
    SegmentLCD_Write("REQUIRD");
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(true);
  }

  /* Enable board control interrupts */
  BSP_InterruptDisable(0xffff);
  BSP_InterruptFlagsClear(0xffff);
  BSP_InterruptEnable(BC_INTEN_JOYSTICK);
  temperatureIRQInit();

  /* Setup ADC for sampling internal temperature sensor. */
  setupSensor();

  /* Main loop - just read temperature and update LCD */
  while (1)
  {
    /* Start one ADC sample */
    ADC_Start(ADC0, adcStartSingle);

    /* Wait in EM1 for ADC to complete */
    EMU_EnterEM1();

    /* Read sensor value */
    temp = ADC_DataSingleGet(ADC0);

    /* Convert ADC sample to Fahrenheit / Celsius and print string to display */
    if (showFahrenheit)
    {
      /* Show Fahrenheit on alphanumeric part of display */
      i = (int)(convertToFahrenheit(temp) * 10);
      snprintf(string, 8, "%2d,%1d%%F", (i/10), i%10);
      /* Show Celsius on numeric part of display */
      i = (int)(convertToCelsius(temp) * 10);
      SegmentLCD_Number(i*10);
      SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1);
   }
    else
    {
      /* Show Celsius on alphanumeric part of display */
      i = (int)(convertToCelsius(temp) * 10);
      snprintf(string, 8, "%2d,%1d%%C", (i/10), i%10);
      /* Show Fahrenheit on numeric part of display */
      i = (int)(convertToFahrenheit(temp) * 10);
      SegmentLCD_Number(i*10);
      SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1);
    }
    SegmentLCD_Write(string);

    /* Sleep for 2 seconds in EM 2 */
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(true);
  }
}
/***************************************************************************//**
* @brief
*   Main function. Setup ADC, FFT, clocks, PRS, DMA, Timer,
*   and process FFT forever.
*******************************************************************************/
int main(void)
{
  arm_status status;
  char buf[20];
  bool redraw = false;
  int glibStatus;
  
  DMA_Init_TypeDef   dmaInit;
  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;

  /* Initialize DVK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  /* Connect audio in to ADC */
  BSP_PeripheralAccess(BSP_AUDIO_IN, true);

  /* Wait a while in order to let signal from audio-in stabilize after */
  /* enabling audio-in peripheral. */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);
  
  /* Initialize the CFFT/CIFFT module */
  status = arm_rfft_init_f32(&rfft_instance,
                             &cfft_instance,
                             GUITAR_AUDIO_BUFFER_SAMPLES,
                             0,  /* forward transform */
                             1); /* normal, not bitreversed, order */
  
  if (status != ARM_MATH_SUCCESS) {
    /* Error initializing RFFT module. */
    while (1) ;
  }
  
  dataReadyForFFT = false;
  processingFFT   = false;
  
  /* Use the HFXO. We still only manage to process about
   * a third the buffers through FFT
   */
  CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
  
  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000))
  {
    while (1) ;
  }

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_PRS, true);
  CMU_ClockEnable(cmuClock_DMA, true);
  CMU_ClockEnable(cmuClock_TIMER0, true);

  NVIC_SetPriority(DMA_IRQn, 0); /* Highest priority */

  /* Configure peripheral reflex system used by TIMER to trigger ADC/DAC */
  guitarPRSConfig(GUITAR_PRS_CHANNEL);

  /* Configure general DMA issues */
  dmaInit.hprot        = 0;
  dmaInit.controlBlock = dmaControlBlock;
  DMA_Init(&dmaInit);

  /* Configure ADC used for audio-in */
  guitarADCConfig();

  /* Trigger sampling according to configured sample rate */
  TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_HFPER) / GUITAR_AUDIO_SAMPLE_RATE);
  TIMER_Init(TIMER0, &timerInit);

  /* Wait until we have control over display */
  while(!redraw)
  {
    redraw = TFT_AddressMappedInit();
  }
  
  /* Init graphics context - abort on failure */
  glibStatus = GLIB_contextInit(&gc);
  if (glibStatus != GLIB_OK) while (1) ;
  
  /* Clear the screen */
  gc.backgroundColor = GLIB_rgbColor(0, 0, 0);
  GLIB_clear(&gc);
  
  while (1)
  {
    while (dataReadyForFFT)
    {
      float32_t freq;

      processingFFT = true;
      processFFT();
      dataReadyForFFT = false;
      processingFFT = false;
      
      /* Get frequency and make string with one decimal accuracy */
      freq = getFreq();
      sprintf(buf, "%6.1f", freq);
      
      /* Check if we should control TFT display instead of AEM/board controller */
      redraw = TFT_AddressMappedInit();
      if (redraw)
      {
        gc.foregroundColor = GLIB_rgbColor(220, 220, 220);
        gc.backgroundColor = GLIB_rgbColor(0, 0, 0);

        /* Print the frequency somewhere in the middle of the screen */
        GLIB_drawString(&gc,
                        buf,
                        strlen(buf),
                        100,
                        120,
                        1);
      }
    }
    EMU_EnterEM1();
  }
}
Example #13
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  uint8_t prod_rev;
  uint32_t temp;
  uint32_t temp_offset;
  float    temperature;

  /* Initialize DK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  /* Initialize the TFT stdio retarget module. */
  RETARGET_TftInit();

  printf("\nEFM32 onchip temperature sensor example\n\n");

  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_GPIO, true);

  /* Enable board control interrupts */
  BSP_InterruptDisable(0xffff);
  BSP_InterruptFlagsClear(0xffff);
  BSP_InterruptEnable(BC_INTEN_JOYSTICK);
  temperatureIRQInit();

  /* This is a work around for Chip Rev.D Errata, Revision 0.6. */
  /* Check for product revision 16 and 17 and set the offset */
  /* for ADC0_TEMP_0_READ_1V25. */
  prod_rev = (DEVINFO->PART & _DEVINFO_PART_PROD_REV_MASK) >> _DEVINFO_PART_PROD_REV_SHIFT;
  if( (prod_rev == 16) || (prod_rev == 17) )
  {
    temp_offset = 112;
  }
  else
  {
    temp_offset = 0;
  }

  /* Setup ADC for sampling internal temperature sensor. */
  setupSensor();

  /* Main loop - just read temperature and update LCD */
  while (1)
  {
    /* Start one ADC sample */
    ADC_Start(ADC0, adcStartSingle);

    /* Wait in EM1 for ADC to complete */
    EMU_EnterEM1();

    /* Read sensor value */
    /* According to rev. D errata ADC0_TEMP_0_READ_1V25 should be decreased */
    /* by the offset  but it is the same if ADC reading is increased - */
    /* reference manual 28.3.4.2. */
    temp = ADC_DataSingleGet(ADC0) + temp_offset;

    /* Convert ADC sample to Fahrenheit / Celsius and print string to display */
    if (showFahrenheit)
    {
      temperature = convertToFahrenheit(temp);
    }
    else
    {
      temperature = convertToCelsius(temp);
    }

    printf("%d.%d %c\n",
           (int) temperature, (int)(10*(temperature-(int)temperature)),
           showFahrenheit? 'F' : 'C');

    /* Sleep for 2 seconds in EM 2 */
    RTCDRV_Trigger(2000, NULL);
    EMU_EnterEM2(true);
  }
}
Example #14
0
int main(void)
{
  /** Number of samples/channels taken from accelerometer. */
  #define ACCEL_SAMPLES               3

  /** X axis sample index. */
  #define ACCEL_X                     0
  /** Y axis sample index. */
  #define ACCEL_Y                     1
  /** Z axis sample index. */
  #define ACCEL_Z                     2

  /*
   * Tilt levels: Midpoint is theoretically half value of max sampling value
   * (ie 0x800 for 12 bit sampling). In real world, some sort of calibration
   * is required if more accurate sensing is required. We just use set some
   * fixed limit, that should be sufficient for this basic example.
   */

  /** Tilt left limit */
  #define TILT_LEFT                   0x750
  /** Tilt right limit */
  #define TILT_RIGHT                  0x8b0

  SYSTEM_ChipRevision_TypeDef chipRev;
  uint32_t leds;
  uint32_t samples[ACCEL_SAMPLES];
  int errataShift = 0;
  int i;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

  /* ADC errata for rev B when using VDD as reference, need to multiply */
  /* result by 2 */
  SYSTEM_ChipRevisionGet(&chipRev);
  if ((chipRev.major == 1) && (chipRev.minor == 1))
  {
    errataShift = 1;
  }

  /* Initialize DK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  /* Connect accelerometer to EFM32. */
  BSP_PeripheralAccess(BSP_ACCEL, true);

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_DMA, true);

  /* Configure ADC and DMA used for scanning accelerometer */
  accelADCConfig();
  accelDMAConfig();

  /* Main loop, keep polling accelerometer */
  leds = 0x0180;
  while (1)
  {
    DMA_ActivateBasic(ACCEL_DMA_CHANNEL,
                      true,
                      false,
                      samples,
                      (void *)((uint32_t)&(ADC0->SCANDATA)),
                      ACCEL_SAMPLES - 1);

    /* Scan all axis', even though this app only use the X axis */
    ADC_IntClear(ADC0, ADC_IF_SCAN);
    ADC_Start(ADC0, adcStartScan);

    /* Poll for completion, entering EM2 when waiting for next poll */
    while (!(ADC_IntGet(ADC0) & ADC_IF_SCAN))
    {
      RTCDRV_Trigger(5, NULL);
      EMU_EnterEM2(true);
    }

    if (errataShift)
    {
      for (i = 0; i < ACCEL_SAMPLES; i++)
      {
        samples[i] <<= errataShift;
      }
    }

    if (samples[ACCEL_X] < TILT_LEFT)
    {
      if (leds < 0xc000)
      {
        leds <<= 1;
      }
    }
    else if (samples[ACCEL_X] > TILT_RIGHT)
    {
      if (leds > 0x0003)
      {
        leds >>= 1;
      }
    }
    else
    {
      if (leds > 0x0180)
Example #15
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 #16
0
int main(void)
{
  DMA_Init_TypeDef   dmaInit;
  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
  uint32_t           leds;
  static uint16_t    last_buttons = 0;
  uint16_t           buttons;

  /* Initialize DK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  volume             = 7;
  preampAdjustFactor = preampVolume[ volume ];
  BSP_LedsSet((uint16_t)(0x00003FFF << (15 - volume)));

  /* Connect audio in/out to ADC/DAC */
  BSP_PeripheralAccess(BSP_AUDIO_IN, true);
  BSP_PeripheralAccess(BSP_AUDIO_OUT, true);

  /* Wait a while in order to let signal from audio-in stabilize after */
  /* enabling audio-in peripheral. */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* Current example gets by at 14MHz core clock (also with low level of compiler */
  /* optimization). That may however change if modified, consider changing to */
  /* higher HFRCO band or HFXO. */
  /*
   * Use for instance one of below statements to increase core clock.
   * CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
   * CMU_HFRCOBandSet(cmuHFRCOBand_28MHz);
   */

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_DAC0, true);
  CMU_ClockEnable(cmuClock_PRS, true);
  CMU_ClockEnable(cmuClock_DMA, true);
  CMU_ClockEnable(cmuClock_TIMER0, true);

  /* Ensure DMA interrupt at higher priority than PendSV. */
  /* (PendSV used to process sampled audio). */
  NVIC_SetPriority(DMA_IRQn, 0);                              /* Highest priority */
  NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1); /* Lowest priority */

  /* Configure peripheral reflex system used by TIMER to trigger ADC/DAC */
  preampPRSConfig(PREAMP_PRS_CHANNEL);

  /* Configure general DMA issues */
  dmaInit.hprot        = 0;
  dmaInit.controlBlock = dmaControlBlock;
  DMA_Init(&dmaInit);

  /* Configure DAC used for audio-out */
  preampDACConfig();

  /* Configure ADC used for audio-in */
  preampADCConfig();

  /* Trigger sampling according to configured sample rate */
  TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_HFPER) / PREAMP_AUDIO_SAMPLE_RATE);
  TIMER_Init(TIMER0, &timerInit);

  /* Main loop, only responsible for checking volume */
  while (1)
  {
    /* Triggered to check volume setting? */
    if (preampCheckVolume)
    {
      preampCheckVolume = false;

      /* Calculate new output volume. */

      buttons = BSP_PushButtonsGet() & PB_MASK; /* Check pushbuttons */
      if (buttons != last_buttons)
      {
        if (buttons & BC_UIF_PB2)               /* Increase volume */
        {
          if (volume < VOLUME_MAX)
            volume++;
        }
        else if (buttons & BC_UIF_PB1)          /* Decrease volume */
        {
          if (volume)
            volume--;
        }
        preampAdjustFactor = preampVolume[ volume ];
        last_buttons       = buttons;
      }

      /* Use 14 leftmost leds for volume control indication. Rightmost led is */
      /* used to indicate clipping of audio out signal.                       */

      leds = 0x00003FFF << (15 - volume);

      /* Audio out clipped? */
      if (preampAudioOutClipped)
      {
        preampAudioOutClipped = false;
        leds                 |= 0x0001;
      }
      BSP_LedsSet((uint16_t) leds);
    }

    EMU_EnterEM1();
  }
}
Example #17
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;
}
Example #18
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
  ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
  uint32_t sample;
  uint32_t vpot;
  uint32_t rpot;
  SYSTEM_ChipRevision_TypeDef chipRev;
  int errataShift = 0;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

  /* ADC errata for rev B when using VDD as reference, need to multiply */
  /* result by 2 */
  SYSTEM_ChipRevisionGet(&chipRev);
  if ((chipRev.major == 1) && (chipRev.minor == 1))
  {
    errataShift = 1;
  }

  /* Initialize DVK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  /* Connect potentiometer to EFM32 (and ensure ambient light sensor */
  /* sharing same ADC channel is not enabled). */
  BSP_PeripheralAccess(BSP_AMBIENT, false);
  BSP_PeripheralAccess(BSP_POTMETER, true);

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);

  /* Init common issues for both single conversion and scan mode */
  init.timebase = ADC_TimebaseCalc(0);
  /* Might as well finish conversion as quickly as possibly since polling */
  /* for completion. */
  init.prescale = ADC_PrescaleCalc(7000000, 0);
  /* WARMUPMODE must be set to Normal according to ref manual before */
  /* entering EM2. In this example, the warmup time is not a big problem */
  /* due to relatively infrequent polling. Leave at default NORMAL, */
  ADC_Init(ADC0, &init);

  /* Init for single conversion use. */
  singleInit.reference = adcRefVDD;
  singleInit.input = adcSingleInpCh5; /* According to DVK HW design */
  singleInit.resolution = adcRes8Bit; /* Use at least 8 bit since unlinear voltage */
  ADC_InitSingle(ADC0, &singleInit);

  /* Ensure internal reference settled */
  RTCDRV_Trigger(1, NULL);
  EMU_EnterEM2(true);

  /* Main loop - just check potentiometer and update LEDs */
  while (1)
  {
    ADC_IntClear(ADC0, ADC_IF_SINGLE);
    ADC_Start(ADC0, adcStartSingle);

    /* Wait for completion */
    while (!(ADC_IntGet(ADC0) & ADC_IF_SINGLE));
    sample = ADC_DataSingleGet(ADC0) << errataShift;

    /*
      DVK potentiometer design:

               | Vdd = 3.3V
              +-+
              | | Rpullup = 10kOhm
              +-+
               |
               +------> Vpot (to ADC)
               |
              +-+
              | | Rpot = 0-100kOhm
              +-+
               | Gnd

       Vpot = Rpot * Vdd / (Rpullup + Rpot)

       This gives a non-linear voltage level measured by ADC with respect to
       pot meter position. In order to determine the actual Rpot setting, which
       is linear with respect to position, rewrite the above formula to:

       Rpot = Rpullup * Vpot / (Vdd - Vpot)
    */

    /* Vpot sampled with 8 bit, divide by max value */
    vpot = (POTENTIOMETER_VDD_mV * sample) / 0xff;

    /* Calculate Rpot determining volume */
    rpot = (POTENTIOMETER_PULLUP_OHM * vpot) / (POTENTIOMETER_VDD_mV - vpot);
    /* The potentiometer may not be exact in upper range, make sure we don't use a higher */
    /* value than assumed by defines. */
    if (rpot > POTENTIOMETER_MAX_OHM)
    {
      rpot = POTENTIOMETER_MAX_OHM;
    }

    /* We have 16 LEDs, add half interval for improving rounding effects. */
    rpot += (POTENTIOMETER_MAX_OHM / (16 * 2));

    BSP_LedsSet((uint16_t)((1 << ((16 * rpot) / POTENTIOMETER_MAX_OHM)) - 1));

    /* Wait some time before polling again */
    RTCDRV_Trigger(100, NULL);
    EMU_EnterEM2(true);
  }
}
Example #19
0
/**************************************************************************//**
 * @brief  Capsense demo loop
 *****************************************************************************/
void capSenseDemo(void)
{
  int32_t slider;
  bool oldBoost = vboost;

  /* Setup RTC. */
  RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32);

  /* Setup capSense callbacks. */
  CAPLESENSE_setupCallbacks(&capSenseScanComplete, &capSenseChTrigger);

  /* Main loop */
  while (1)
  {
    switch(demoState)
    {
      case DEMO_SLEEP_PREPARE:
      {
        /* Setup LESENSE in sleep mode. */
        CAPLESENSE_setupLESENSE(true);
        /* Disable LCD to avoid excessive current consumption */
        SegmentLCD_Disable();
        /* Disable Vdd check. */
        VDDCHECK_Disable();
        /* Go to sleep state. */
        demoState = DEMO_SLEEP;
      }
      break;

      case DEMO_SLEEP:
      {
        /* Go to sleep and wait until the measurement completes. */
        CAPLESENSE_Sleep();
      }
      break;

      case DEMO_SENSE_PREPARE:
      {
        /* Setup LESENSE in high-accuracy sense mode. */
        CAPLESENSE_setupLESENSE(false);
        /* Start timeout counter. */
        RTCDRV_Trigger(1000U, &capSenseTimerFired);
        /* Enable vboost */
        SegmentLCD_Init(vboost);
        /* Go to sense state. */
        demoState = DEMO_SENSE;
      }
      break;

      case DEMO_SENSE:
      {
        /* Go to sleep and wait until the measurement completes. */
        CAPLESENSE_Sleep();

        /* Get slider position. */
        slider = CAPLESENSE_getSliderPosition();
        if (-1 != slider)
        {
          /* Reset RTC */
          RTC_Enable(false);
          RTC_Enable(true);
        }
        capSenseAringUpdate(slider);

        /* Check for change in input voltage. Enable vboost if necessary */
        /* Initialize voltage comparator */
        VDDCHECK_Init();

        /* Check if voltage is below 3V, if so use voltage boost */
        if (VDDCHECK_LowVoltage(2.9))
        {
          vboost = true;
          if (oldBoost != vboost)
          {
            /* Enable vboost */
            SegmentLCD_Init(vboost);
            /* Use antenna symbol to signify enabling of vboost */
            SegmentLCD_Symbol(LCD_SYMBOL_ANT, vboost);
          }
          oldBoost = vboost;
        }
        else
        {
          vboost = false;
        }

        switch (demoMode)
        {
        case (DEMOMODE_SCROLLTEXT):
          capSenseScrollText();
          break;
        case (DEMOMODE_BARS):
          capSenseBars();
          break;
        case (DEMOMODE_VALUES):
          capSenseValues();
          break;
        default:
          break;
        }
      }
      break;

      default:
      {
        ;
      }
      break;
    }
  }
}
Example #20
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  WDOG_Init_TypeDef wInit = WDOG_INIT_DEFAULT;
  int i;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

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

  /* Watchdog setup - Use defaults, excepts for these :*/
  wInit.em2Run = true;
  wInit.em3Run = true;
  wInit.perSel = wdogPeriod_4k; /* 4k 1kHz periods should give ~4 seconds in EM3 */

  /* Do the demo forever. */

  /* EM0 - 1 sec HFXO  */
  CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000))
  {
    while (1) ;
  }
  Delay(1000);

  /* EM0 - 1 sec HFRCO */
  CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000))
  {
    while (1) ;
  }
  Delay(1000);

  /* Turn off systick */
  SysTick_Disable();

  /* EM1 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM1();

  /* EM2 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* EM1 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM1();

  /* EM2 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* Up and down from EM2 each 10 msec */
  for (i=0; i < 10; i++)
  {
    RTCDRV_Trigger(10, NULL);
    EMU_EnterEM2(true);
    RTCDRV_Delay(10, false);
  }

  /* EM2 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* Up and down from EM2 each 2 msec */
  for (i=0; i < 10; i++)
  {
    RTCDRV_Trigger(2, NULL);
    EMU_EnterEM2(true);
  }

  /* EM2 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* Up and down from EM2 each msec */
  for (i=0; i < 10; i++)
  {
    RTCDRV_Trigger(1, NULL);
    EMU_EnterEM2(true);
  }

  /* EM2 - 1 sec */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* Start watchdog */
  WDOG_Init(&wInit);

  /* Enter EM3 - Watchdog will reset chip (and confuse debuggers) */
  EMU_EnterEM3(true);

  /* We will never reach this point */
  return 0;
}
Example #21
0
int main(void)
{
  DMA_Init_TypeDef dmaInit;
  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
  SYSTEM_ChipRevision_TypeDef chipRev;
  uint32_t volSample;
  uint32_t vpot;
  uint32_t rpot;
  uint32_t leds;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

  /* ADC errata for rev B when using VDD as reference, need to multiply */
  /* result by 2 */
  SYSTEM_ChipRevisionGet(&chipRev);
  if ((chipRev.major == 1) && (chipRev.minor == 1))
  {
    preampErrataShift = 1;
  }

  /* Initialize DVK board register access */
  BSP_Init(BSP_INIT_DEFAULT);

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

  /* Connect potentiometer to EFM32 (and ensure ambient light sensor */
  /* sharing same ADC channel is not enabled). */
  BSP_PeripheralAccess(BSP_AMBIENT, false);
  BSP_PeripheralAccess(BSP_POTMETER, true);

  /* Connect audio in/out to ADC/DAC */
  BSP_PeripheralAccess(BSP_AUDIO_IN, true);
  BSP_PeripheralAccess(BSP_AUDIO_OUT, true);

  /* Wait a while in order to let signal from audio-in stabilize after */
  /* enabling audio-in peripheral. */
  RTCDRV_Trigger(1000, NULL);
  EMU_EnterEM2(true);

  /* Current example gets by at 14MHz core clock (also with low level of compiler */
  /* optimization). That may however change if modified, consider changing to */
  /* higher HFRCO band or HFXO. */
  /*
    Use for instance one of below statements to increase core clock.
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
    CMU_HFRCOBandSet(cmuHFRCOBand_28MHz);
  */

  /* Enable clocks required */
  CMU_ClockEnable(cmuClock_HFPER, true);
  CMU_ClockEnable(cmuClock_ADC0, true);
  CMU_ClockEnable(cmuClock_DAC0, true);
  CMU_ClockEnable(cmuClock_PRS, true);
  CMU_ClockEnable(cmuClock_DMA, true);
  CMU_ClockEnable(cmuClock_TIMER0, true);

  /* Ensure DMA interrupt at higher priority than PendSV. */
  /* (PendSV used to process sampled audio). */
  NVIC_SetPriority(DMA_IRQn, 0); /* Highest priority */
  NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1); /* Lowest priority */

  /* Configure peripheral reflex system used by TIMER to trigger ADC/DAC */
  preampPRSConfig(PREAMP_PRS_CHANNEL);

  /* Configure general DMA issues */
  dmaInit.hprot = 0;
  dmaInit.controlBlock = dmaControlBlock;
  DMA_Init(&dmaInit);

  /* Configure DAC used for audio-out */
  preampDACConfig();

  /* Configure ADC used for audio-in */
  preampADCConfig();

  /* Trigger sampling according to configured sample rate */
  TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_HFPER) / PREAMP_AUDIO_SAMPLE_RATE);
  TIMER_Init(TIMER0, &timerInit);

  /* Main loop, only responsible for checking volume */
  while (1)
  {
    /* Triggered to check volume setting? */
    if (preampCheckVolume)
    {
      preampCheckVolume = false;

      /* Trigger single conversion, and wait for it to complete */
      ADC_IntClear(ADC0, ADC_IF_SINGLE);
      ADC_Start(ADC0, adcStartSingle);
      while (!(ADC_IntGet(ADC0), ADC_IF_SINGLE))
      {
        /* Just wait for an interrupt to wake us up (DMA interrupts occur */
        /* regularly). Thus, we don't need to enable ADC interrupt. */
        EMU_EnterEM1();
      }
      volSample = ADC_DataSingleGet(ADC0) << preampErrataShift;

      /*
        DVK potentiometer design:

                 | Vdd = 3.3V
                +-+
                | | Rpullup = 10kOhm
                +-+
                 |
                 +------> Vpot (to ADC)
                 |
                +-+
                | | Rpot = 0-100kOhm
                +-+
                 | Gnd

         Vpot = Rpot * Vdd / (Rpullup + Rpot)

         This gives a non-linear voltage level measured by ADC with respect to
         pot meter position. In order to determine the actual Rpot setting, which
         is linear with respect to position, rewrite the above formula to:

         Rpot = Rpullup * Vpot / (Vdd - Vpot)
      */

      /* Vpot sampled with 8 bit, divide by max value */
      vpot = (POTENTIOMETER_VDD_mV * volSample) / 0xff;

      /* Calculate Rpot determining volume */
      rpot = (POTENTIOMETER_PULLUP_OHM * vpot) / (POTENTIOMETER_VDD_mV - vpot);
      /* The potentiometer may not be exact in upper range, make sure we don't use a higher */
      /* value than assumed by defines. */
      if (rpot > POTENTIOMETER_MAX_OHM)
      {
        rpot = POTENTIOMETER_MAX_OHM;
      }

      /* Precalculate adjustment factor to avoid repeated calculation when used. */
      /* Scale down Rpot a bit to use in integer calculation without overflowing 32 bit reg. */
      preampAdjustFactor = rpot / PREAMP_ADJUST_DIVISOR;

      /* Use 14 right leds for volume control indicating. Leftmost led is used to indicate */
      /* clipping of audio out signal (in order to limit volume out). Add half interval */
      /* for improving integer rounding effects. */
      leds = rpot + (POTENTIOMETER_MAX_OHM / (14 * 2));
      leds = (1 << ((14 * leds) / POTENTIOMETER_MAX_OHM)) - 1;

      /* Audio out clipped? */
      if (preampAudioOutClipped)
      {
        preampAudioOutClipped = false;
        leds |= 0x8000;
      }
      BSP_LedsSet((uint16_t)leds);
    }

    EMU_EnterEM1();
  }
}