Пример #1
0
void sam_gclk_config(FAR const struct sam_gclkconfig_s *config)
{
  irqstate_t flags;
  uintptr_t regaddr;
  uint32_t regval;
  uint32_t genctrl;

  /* Select the requested source clock for the generator */

  genctrl = ((uint32_t)config->clksrc << GCLK_GENCTRL_SRC_SHIFT);

#if 0 /* Not yet supported */
  /* Configure the clock to be either high or low when disabled */

  if (config->level)
    {
      genctrl |= GCLK_GENCTRL_OOV;
    }
#endif

  /* Configure if the clock output to I/O pin should be enabled */

  if (config->output)
    {
      genctrl |= GCLK_GENCTRL_OE;
    }

  /* Set the prescaler division factor */

  if (config->prescaler > 1)
    {
      /* Check if division is a power of two */

      if (((config->prescaler & (config->prescaler - 1)) == 0))
        {
          /* Determine the index of the highest bit set to get the
           * division factor that must be loaded into the division
           * register.
           */

          uint32_t count = 0;
          uint32_t mask;

          for (mask = 2; mask < (uint32_t)config->prescaler; mask <<= 1)
            {
              count++;
            }

          /* Set binary divider power of 2 division factor */

          genctrl |= count << GCLK_GENCTRL_DIV_SHIFT;
          genctrl |= GCLK_GENCTRL_DIVSEL;
        }
      else
        {
          /* Set integer division factor */

          genctrl |= GCLK_GENCTRL_DIV((uint32_t)config->prescaler);

          /* Enable non-binary division with increased duty cycle accuracy */

          genctrl |= GCLK_GENCTRL_IDC;
        }
    }

  /* Enable or disable the clock in standby mode */

  if (config->runstandby)
    {
      genctrl |= GCLK_GENCTRL_RUNSTDBY;
    }

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy(config->gclk);

  /* Preserve the GENEN bit */

  regaddr  = SAM_GCLK_GENCTRL(config->gclk);

  flags    = enter_critical_section();
  regval   = getreg32(regaddr);
  regval  &= GCLK_GENCTRL_GENEN;
  genctrl |= regval;

  /* Configure the generator */

  putreg32(genctrl, regaddr);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy(config->gclk);
  leave_critical_section(flags);
  sam_gclck_waitsyncbusy(config->gclk);

  /* Enable the clock generator */

  flags    = enter_critical_section();
  genctrl |= GCLK_GENCTRL_GENEN;
  putreg32(genctrl, regaddr);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy(config->gclk);
  leave_critical_section(flags);
}
Пример #2
0
static void lpc31_domaininit(struct lpc31_domainconfig_s* dmn)
{
  const struct lpc31_subdomainconfig_s * sub = dmn->sub;
  uint32_t fdivcfg;
  uint32_t regaddr;
  uint32_t regval;
  int fdndx;
  int clkndx;
  int bcrndx = lpc31_bcrndx(dmn->dmnid);
  int esrndx;

  if (bcrndx != BCRNDX_INVALID)
    {
      /* Disable BCR for domain */

      regaddr = LPC31_CGU_BCR(bcrndx);
      putreg32(0, regaddr);
    }

  /* Configure the fractional dividers in this domain */
 
  for (fdndx = 0; fdndx < dmn->nfdiv; fdndx++, sub++)
    {
      /* Set fractional divider confiruation but don't enable it yet */

      fdivcfg = lpc31_fdivinit(fdndx + dmn->fdiv1, &sub->fdiv, false);

      /* Enable frac divider only if it has valid settings */

      if (fdivcfg != 0)
        {
          /* Select the fractional dividir for each clock in this
           * sub domain.
           */

          for (clkndx = 0; clkndx <= dmn->nclks; clkndx++)
            {
              /* Does this clock have an ESR register? */
 
              esrndx = lpc31_esrndx((enum lpc31_clockid_e)(clkndx + dmn->clk1));
              if (esrndx != ESRNDX_INVALID)
                {
                  /* Yes.. Check if this clock belongs to this sub-domain */

                  if (sub->clkset & (1 << clkndx))
                    {
                      /* Yes.. configure the clock to use this fractional divider */

                      regaddr = LPC31_CGU_ESR(esrndx);
                      putreg32((fdndx << CGU_ESR_ESRSEL_SHIFT) | CGU_ESR_ESREN, regaddr);
                    }
                 }
             }

          /* Enable the fractional divider */

          regaddr = LPC31_CGU_FDC(fdndx + dmn->fdiv1);
          regval  = getreg32(regaddr);
          regval |= CGU_FDC_RUN;
          putreg32(regval, regaddr);
        }
    }

  if (bcrndx != BCRNDX_INVALID)
    {
      /* Enable the BCR for domain */

      regaddr = LPC31_CGU_BCR(bcrndx);
      putreg32(CGU_BCR_FDRUN, regaddr);
    }

   /* Select input base clock for domain*/

  lpc31_selectfreqin(dmn->dmnid, dmn->finsel);
}
Пример #3
0
void up_irqinitialize(void)
{
  uint32_t regaddr;
#ifdef CONFIG_DEBUG
  uint32_t regval;
#endif
  int num_priority_registers;

  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);

  /* Make sure that we are using the correct vector table.  The default
   * vector address is 0x0000:0000 but if we are executing code that is
   * positioned in SRAM or in external FLASH, then we may need to reset
   * the interrupt vector so that it refers to the table in SRAM or in
   * external FLASH.
   */

  putreg32((uint32_t)_vectors, NVIC_VECTAB);

#ifdef CONFIG_ARCH_RAMVECTORS
  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

  up_ramvec_initialize();
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports:
   *
   *  0 -> 32 interrupt lines,  8 priority registers
   *  1 -> 64 "       " "   ", 16 priority registers
   *  2 -> 96 "       " "   ", 32 priority registers
   *  ...
   */

  num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;

  /* Now set all of the interrupt lines to the default priority */

  regaddr = NVIC_IRQ0_3_PRIORITY;
  while (num_priority_registers--)
    {
      putreg32(DEFPRIORITY32, regaddr);
      regaddr += 4;
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  CURRENT_REGS = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(LPC43_IRQ_SVCALL, up_svcall);
  irq_attach(LPC43_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
  /* up_prioritize_irq(LPC43_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
  lpc43_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARM_MPU
  irq_attach(LPC43_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(LPC43_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(LPC43_IRQ_NMI, lpc43_nmi);
#ifndef CONFIG_ARM_MPU
  irq_attach(LPC43_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(LPC43_IRQ_BUSFAULT, lpc43_busfault);
  irq_attach(LPC43_IRQ_USAGEFAULT, lpc43_usagefault);
  irq_attach(LPC43_IRQ_PENDSV, lpc43_pendsv);
  irq_attach(LPC43_IRQ_DBGMONITOR, lpc43_dbgmonitor);
  irq_attach(LPC43_IRQ_RESERVED, lpc43_reserved);
#endif

  lpc43_dumpnvic("initial", LPC43M4_IRQ_NIRQS);

  /* If a debugger is connected, try to prevent it from catching hardfaults.
   * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal
   * operation.
   */

#if defined(CONFIG_DEBUG) && !defined(CONFIG_ARMV7M_USEBASEPRI)
  regval  = getreg32(NVIC_DEMCR);
  regval &= ~NVIC_DEMCR_VCHARDERR;
  putreg32(regval, NVIC_DEMCR);
#endif

  /* And finally, enable interrupts */

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  up_irq_enable();
#endif
}
Пример #4
0
void up_irqinitialize(void)
{
  uintptr_t regaddr;
  int nintlines;
  int i;

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports, defined in groups of 32. That is,
   * the total number of interrupt lines is up to (32*(INTLINESNUM+1)).
   *
   *  0 -> 32 interrupt lines, 1 enable register,   8 priority registers
   *  1 -> 64 "       " "   ", 2 enable registers, 16 priority registers
   *  2 -> 96 "       " "   ", 3 enable regsiters, 24 priority registers
   *  ...
   */

  nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1;

  /* Disable all interrupts.  There are nintlines interrupt enable
   * registers.
   */

  for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(0, regaddr);
    }

  /* Make sure that we are using the correct vector table.  The default
   * vector address is 0x0000:0000 but if we are executing code that is
   * positioned in SRAM or in external FLASH, then we may need to reset
   * the interrupt vector so that it refers to the table in SRAM or in
   * external FLASH.
   */

  putreg32((uint32_t)_vectors, NVIC_VECTAB);

#ifdef CONFIG_ARCH_RAMVECTORS
  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

  up_ramvec_initialize();
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* Now set all of the interrupt lines to the default priority.  There are
   * nintlines * 8 priority registers.
   */

  for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(DEFPRIORITY32, regaddr);
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(KINETIS_IRQ_SVCALL, up_svcall);
  irq_attach(KINETIS_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
  /* up_prioritize_irq(KINETIS_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
  kinetis_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARM_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(KINETIS_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(KINETIS_IRQ_NMI, kinetis_nmi);
#ifndef CONFIG_ARM_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(KINETIS_IRQ_BUSFAULT, kinetis_busfault);
  irq_attach(KINETIS_IRQ_USAGEFAULT, kinetis_usagefault);
  irq_attach(KINETIS_IRQ_PENDSV, kinetis_pendsv);
  irq_attach(KINETIS_IRQ_DBGMONITOR, kinetis_dbgmonitor);
  irq_attach(KINETIS_IRQ_RESERVED, kinetis_reserved);
#endif

  kinetis_dumpnvic("initial", NR_IRQS);

  /* Initialize logic to support a second level of interrupt decoding for
   * configured pin interrupts.
   */

#ifdef CONFIG_GPIO_IRQ
  kinetis_pinirqinitialize();
#endif

  /* And finally, enable interrupts */

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  irqenable();
#endif
}
Пример #5
0
void board_deepsleep_with_stopmode(uint32_t secs)
{
#if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME)
  struct tm t;
  struct timespec ts;
  struct timespec rtc_start_ts;
  struct timespec rtc_end_ts;
#endif
#ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS
  uint32_t gpio_off_mask;
  bool sdcard_enabled;
#endif
  uint32_t regval;
  int ret;
#ifdef DEEPSLEEP_WAKETIME_DEBUG
  static struct timespec wake_ts;
#endif
#ifdef DEEPSLEEP_SLEEPTIME_DEBUG
  bool slept = false;
#endif

  /* Do not allow other tasks to takeover (for example, by wake-up with semaphore
   * from EXTI interrupt) before we have restored MCU functionalities. */

  sched_lock();

#ifdef DEEPSLEEP_SLEEPTIME_DEBUG
  lldbg("sleep for %d\n", secs);
#endif

#ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS

  /* Special support for SDcard. */

  if (stm32_gpioread(GPIO_CHIP_SELECT_SDCARD) == false)
    {
      lldbg("ERROR! SDcard communication active while trying deep-sleep!\n");

      goto skip_deepsleep;
    }

  /* Following devices do not have proper GPIO reconfigure recovery yet (and
   * some cannot work with deep-sleep at all). Abort deep-sleep instead of
   * introducing hard-to-diagnose bugs and general instability.
   */

  if (stm32_gpioread(GPIO_REGULATOR_WLAN))
    {
      lldbg("ERROR! Trying to deep-sleep when WLAN active!\n");

      goto skip_deepsleep;
    }

  if (stm32_gpioread(GPIO_PWR_SWITCH_MODEM))
    {
      lldbg("ERROR! Trying to deep-sleep when Modem active!\n");

      goto skip_deepsleep;
    }

  if (stm32_gpioread(GPIO_REGULATOR_GPS))
    {
      lldbg("ERROR! Trying to deep-sleep when GPS active!\n");

      goto skip_deepsleep;
    }

  if (stm32_gpioread(GPIO_REGULATOR_BLUETOOTH))
    {
      lldbg("ERROR! Trying to deep-sleep when Bluetooth active!\n");

      goto skip_deepsleep;
    }

  if (stm32_gpioread(GPIO_REGULATOR_DISPLAY))
    {
      lldbg("ERROR! Trying to deep-sleep when Display active!\n");

      goto skip_deepsleep;
    }
#endif /* CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS */

#if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME)
  /* Get RTC clock before STOP. */

  stm32_rtc_getdatetime_with_subseconds(&t, &rtc_start_ts.tv_nsec);
  rtc_start_ts.tv_sec = mktime(&t);

  /* Get current time. */

  ret = clock_gettime(CLOCK_REALTIME, &ts);
  DEBUGASSERT(ret != ERROR);

  /* Add nanoseconds to entropy pool. */

  add_time_randomness(ts.tv_nsec);

#endif

#ifdef DEEPSLEEP_WAKETIME_DEBUG
  if (wake_ts.tv_nsec || wake_ts.tv_sec)
    {
      struct timespec curr_ts;
      int64_t msecs;

      clock_gettime(CLOCK_REALTIME, &curr_ts);

      msecs = ((int64_t)curr_ts.tv_sec - wake_ts.tv_sec) * 1000;
      msecs += ((int64_t)curr_ts.tv_nsec - wake_ts.tv_nsec) / (1000 * 1000);

      lldbg("sleep to sleep time: %d msecs\n", (int)msecs);
    }
  else
    {
      lldbg("first sleep (for %u secs)\n", secs);
    }
#endif

#ifdef CONFIG_RTC_PERIODIC_AUTORELOAD_WAKEUP
  if (secs > 0)
    {
      /* Prepare RTC for wake-up. */

      ret = up_rtc_setperiodicwakeup(secs, NULL);
      DEBUGASSERT(ret == OK);
    }
#else
  DEBUGASSERT(secs == 0);
#endif

  /* Prevent USART interrupt activity, make sure that last transmission has
   * completed. */

  stm32_serial_set_suspend(true);

#ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS

  /* Read control state of SDCard regulator (TODO: add proper pwrctl api) */

  sdcard_enabled = stm32_gpioread(GPIO_REGULATOR_SDCARD);
  if (sdcard_enabled)
    {
      /* Mark SDcard as disconnected for block driver. */

      mmcsd_slot_pm_suspend(CONFIG_BOARD_MMCSDSLOTNO);
    }

  /* Force SDcard off. */

  stm32_gpiowrite(GPIO_REGULATOR_SDCARD, false);

  /* SDcard is off, and does not react on GPIOs. Force GPIOs low to avoid leak
   * current.
   */

  gpio_off_mask = ~(GPIO_PUPD_MASK | GPIO_MODE_MASK | GPIO_OUTPUT_SET);
  stm32_configgpio((GPIO_SPI3_MOSI & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT);
  stm32_configgpio((GPIO_SPI3_MISO & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT);
  stm32_configgpio((GPIO_SPI3_SCK & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT);
  stm32_configgpio((GPIO_CHIP_SELECT_SDCARD & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT);

  /* Reconfigure GPIO's for stop mode (most pins are setup as analog input). */

  up_reconfigure_gpios_for_pmstop();

#endif

#if defined(CONFIG_USBDEV) && defined (CONFIG_STM32_USB)
  /* Reset USB peripheral */

  regval = getreg32(STM32_RCC_APB1RSTR);
  putreg32(regval | RCC_APB1RSTR_USBRST, STM32_RCC_APB1RSTR);
  putreg32(regval, STM32_RCC_APB1RSTR);
#endif

#if defined(CONFIG_STM32_PWR)
  /* Disable PVD during sleep because I_DD (PVD/BOR) consumes 2.6 uA,
     and because there is nothing better to do than die while sleeping
     if lose power in stop-mode. */

  stm32_pwr_disablepvd();
#endif

#ifndef CONFIG_BOARD_DEEPSLEEP_SKIP_PMSTOP
  /* Enter stop-mode with MCU internal regulator in low-power mode. */

  ret = stm32_pmstop(true);
#endif

#ifdef DEEPSLEEP_SLEEPTIME_DEBUG
  slept = true;
#endif

#if defined(CONFIG_STM32_PWR)
  /* Re-enable PVD and check if voltage has dropped too much
     while we slept. We might have enough power for MCU, but not
     for SD card or other peripherals. */

  stm32_pwr_enablepvd();
  board_pwr_checkpvd();
#endif

#ifdef CONFIG_RTC_PERIODIC_AUTORELOAD_WAKEUP
  if (secs > 0)
    {
      /* Prevent more wake-ups. */

      (void)up_rtc_cancelperiodicwakeup();
    }
#endif

#if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME)
  /* Get RTC clock after STOP. */

  stm32_rtc_getdatetime_with_subseconds(&t, &rtc_end_ts.tv_nsec);
  rtc_end_ts.tv_sec = mktime(&t);

  /* Advance time by RTC. */

  ts.tv_sec += rtc_end_ts.tv_sec - rtc_start_ts.tv_sec;
  ts.tv_nsec += rtc_end_ts.tv_nsec - rtc_start_ts.tv_nsec;
  if (ts.tv_nsec < 0)
    {
      ts.tv_nsec += 1000 * 1000 * 1000;
      ts.tv_sec--;
    }
  if (ts.tv_nsec >= 1000 * 1000 * 1000)
    {
      ts.tv_nsec -= 1000 * 1000 * 1000;
      ts.tv_sec++;
    }

  /* Set current time / date */

  ret = clock_settime(CLOCK_REALTIME, &ts);
  DEBUGASSERT(ret != ERROR);

#ifdef DEEPSLEEP_WAKETIME_DEBUG
  wake_ts = ts;
#endif

#if defined(CONFIG_CLOCK_MONOTONIC) && defined(CONFIG_CLOCK_MONOTONIC_OFFSET_TIME)

  /* Get amount of time adjusted by RTC. */

  ts.tv_sec = rtc_end_ts.tv_sec - rtc_start_ts.tv_sec;
  ts.tv_nsec = rtc_end_ts.tv_nsec - rtc_start_ts.tv_nsec;
  if (ts.tv_nsec < 0)
    {
      ts.tv_nsec += 1000 * 1000 * 1000;
      ts.tv_sec--;
    }
  if (ts.tv_nsec >= 1000 * 1000 * 1000)
    {
      ts.tv_nsec -= 1000 * 1000 * 1000;
      ts.tv_sec++;
    }

  /* Adjust CLOCK_MONOTONIC offset. */

  clock_increase_monotonic_offset(&ts);
#endif

#endif

  /* Stop mode disables HSE/HSI/PLL and wake happens with default system
   * clock (MSI, 2Mhz). So reconfigure clocks early on. RTC is however
   * handled before this for accurate time keeping.
   */

  stm32_clockconfig();

#ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS
  /* Restore pin configuration */

  up_restore_gpios_after_pmstop();
#endif

#if defined(CONFIG_USBDEV) && defined (CONFIG_STM32_USB)
  /* Initialize USB */
  /* TODO initialize USB properly, up_usbinitialize() call alone is not sufficient */

  up_usbinitialize();

#endif

  /* Resume serial ports after setting up system clock, as USART baud rate is
   * configured relative to system clock. */

  stm32_serial_set_suspend(false);

  /* Check that we have enough battery left, just in case
     PVD detection missed it. */

  board_pwr_checkvbat(false);

#ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS
  /* Special support for SD card. */

  /* Restore SDcard GPIOs */

  stm32_configgpio(GPIO_SPI3_MOSI);
  stm32_configgpio(GPIO_SPI3_MISO);
  stm32_configgpio(GPIO_SPI3_SCK);
  stm32_configgpio(GPIO_CHIP_SELECT_SDCARD);

  if (sdcard_enabled)
    {
      /* Re-enable power now that GPIOs are in correct state. */

      stm32_gpiowrite(GPIO_REGULATOR_SDCARD, true);

      /* Mark SDcard as reconnected for block driver, will reinitialize/reconfigure
       * SDcard. Apparently, block driver works fine without additional delay
       * for regulator. Might be because plug-in nature of SDcards require
       * block driver to keep retrying initialization until card stabilizes.
       */

      mmcsd_slot_pm_resume(CONFIG_BOARD_MMCSDSLOTNO);
    }

skip_deepsleep:
#endif

  /* Allow scheduler to switch tasks. */

  sched_unlock();

#ifdef DEEPSLEEP_SLEEPTIME_DEBUG
  if (slept)
    {
      /* Get amount of time adjusted by RTC. */

      ts.tv_sec = rtc_end_ts.tv_sec - rtc_start_ts.tv_sec;
      ts.tv_nsec = rtc_end_ts.tv_nsec - rtc_start_ts.tv_nsec;
      if (ts.tv_nsec < 0)
        {
          ts.tv_nsec += 1000 * 1000 * 1000;
          ts.tv_sec--;
        }
      if (ts.tv_nsec >= 1000 * 1000 * 1000)
        {
          ts.tv_nsec -= 1000 * 1000 * 1000;
          ts.tv_sec++;
        }

      lldbg("slept for %u.%03u\n", ts.tv_sec, ts.tv_nsec / (1000 * 1000));
    }
#endif
}
Пример #6
0
static inline void rcc_enableapb1(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the APB1ENR register to enabled the
   * selected APB1 peripherals.
   */

  regval  = getreg32(STM32_RCC_APB1ENR);

#ifdef CONFIG_STM32_TIM2
  /* Timer 2 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM2EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM3
  /* Timer 3 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM3EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM6
  /* Timer 6 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM6EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM7
  /* Timer 7 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM7EN;
#endif
#endif

#ifdef CONFIG_STM32_WWDG
  /* Window Watchdog clock enable */

  regval |= RCC_APB1ENR_WWDGEN;
#endif

#ifdef CONFIG_STM32_USART2
  /* USART 2 clock enable */

  regval |= RCC_APB1ENR_USART2EN;
#endif

#ifdef CONFIG_STM32_USART3
  /* USART 3 clock enable */

  regval |= RCC_APB1ENR_USART3EN;
#endif

#ifdef CONFIG_STM32_I2C1
  /* I2C 1 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_I2C1EN;
#endif
#endif

#ifdef CONFIG_STM32_CAN1
  /* CAN1 clock enable */

  regval |= RCC_APB1ENR_CANEN;
#endif

#ifdef CONFIG_STM32_DAC2
  /* DAC2 interface clock enable */

  regval |= RCC_APB1ENR_DAC2EN;
#endif

#ifdef CONFIG_STM32_PWR
  /*  Power interface clock enable */

  regval |= RCC_APB1ENR_PWREN;
#endif

#ifdef CONFIG_STM32_DAC1
  /* DAC1 interface clock enable */

  regval |= RCC_APB1ENR_DAC1EN;
#endif

  putreg32(regval, STM32_RCC_APB1ENR);
}
Пример #7
0
static void stm32_stdclockconfig(void)
{
  uint32_t regval;

  /* If the PLL is using the HSE, or the HSE is the system clock */

#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE)
  {
    volatile int32_t timeout;

    /* Enable External High-Speed Clock (HSE) */

    regval  = getreg32(STM32_RCC_CR);
    regval &= ~RCC_CR_HSEBYP;         /* Disable HSE clock bypass */
    regval |= RCC_CR_HSEON;           /* Enable HSE */
    putreg32(regval, STM32_RCC_CR);

    /* Wait until the HSE is ready (or until a timeout elapsed) */

    for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--)
      {
        /* Check if the HSERDY flag is the set in the CR */

        if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0)
          {
            /* If so, then break-out with timeout > 0 */

            break;
          }
      }

    if (timeout == 0)
      {
        /* In the case of a timeout starting the HSE, we really don't have a
         * strategy.  This is almost always a hardware failure or
         * misconfiguration.
         */

        return;
      }
  }

#endif

  /* Set the HCLK source/divider */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_HPRE_MASK;
  regval |= STM32_RCC_CFGR_HPRE;
  putreg32(regval, STM32_RCC_CFGR);

  /* Set the PCLK2 divider */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_PPRE2_MASK;
  regval |= STM32_RCC_CFGR_PPRE2;
  putreg32(regval, STM32_RCC_CFGR);

  /* Set the PCLK1 divider */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_PPRE1_MASK;
  regval |= STM32_RCC_CFGR_PPRE1;
  putreg32(regval, STM32_RCC_CFGR);

#if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL
  /* If we are using the PLL, configure and start it */
  /* Set the PLL divider and multiplier */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK);
  regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLXTPRE | STM32_CFGR_PLLMUL);
  putreg32(regval, STM32_RCC_CFGR);

  /* Enable the PLL */

  regval = getreg32(STM32_RCC_CR);
  regval |= RCC_CR_PLLON;
  putreg32(regval, STM32_RCC_CR);

  /* Wait until the PLL is ready */

  while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0);

#endif

  /* Set flash wait states according to sysclk:
   *
   *   0WS from 0-24MHz
   *   1WS from 24-48MHz
   *   2WS from 48-72MHz
   */

  regval = getreg32(STM32_FLASH_ACR);
  regval &= ~(FLASH_ACR_LATENCY_MASK);

#if STM32_SYSCLK_FREQUENCY <= 24000000
  regval |= FLASH_ACR_LATENCY_0;
#elif STM32_SYSCLK_FREQUENCY <= 48000000
  regval |= FLASH_ACR_LATENCY_1;
#else
  regval |= FLASH_ACR_LATENCY_2;
#endif

  regval |= FLASH_ACR_PRTFBE;
  putreg32(regval, STM32_FLASH_ACR);

  /* Select the system clock source (probably the PLL) */

  regval  = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_SW_MASK;
  regval |= STM32_SYSCLK_SW;
  putreg32(regval, STM32_RCC_CFGR);

  /* Wait until the selected source is used as the system clock source */

  while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS);

#if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK)
  /* Low speed internal clock source LSI
   *
   * TODO: There is another case where the LSI needs to
   * be enabled: if the MCO pin selects LSI as source.
   */

  stm32_rcc_enablelsi();
#endif

#if defined(CONFIG_RTC_LSECLOCK)
  /* Low speed external clock source LSE
   *
   * TODO: There is another case where the LSE needs to
   * be enabled: if the MCO pin selects LSE as source.
   *
   * TODO: There is another case where the LSE needs to
   * be enabled: if USARTx selects LSE as source.
   */

  stm32_rcc_enablelse();
#endif

#ifdef CONFIG_STM32_HRTIM_CLK_FROM_PLL
  regval  = getreg32(STM32_RCC_CFGR3);
  regval |= RCC_CFGR3_HRTIM1SW;
  putreg32(regval, STM32_RCC_CFGR3);
#endif
}
Пример #8
0
static inline void rcc_enableahb1(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the AHB1ENR register to enabled the
   * selected AHB1 peripherals.
   */

  regval = getreg32(STM32_RCC_AHB1ENR);

  /* Enable GPIOA, GPIOB, .... GPIOI*/

#if STM32_NGPIO > 0
  regval |= (RCC_AHB1ENR_GPIOAEN
#if STM32_NGPIO > 16
             |RCC_AHB1ENR_GPIOBEN
#endif
#if STM32_NGPIO > 32
             |RCC_AHB1ENR_GPIOCEN
#endif
#if STM32_NGPIO > 48
             |RCC_AHB1ENR_GPIODEN
#endif
#if STM32_NGPIO > 64
             |RCC_AHB1ENR_GPIOEEN
#endif
#if STM32_NGPIO > 80
             |RCC_AHB1ENR_GPIOFEN
#endif
#if STM32_NGPIO > 96
             |RCC_AHB1ENR_GPIOGEN
#endif
#if STM32_NGPIO > 112
             |RCC_AHB1ENR_GPIOHEN
#endif
#if STM32_NGPIO > 128
             |RCC_AHB1ENR_GPIOIEN
#endif
             );
#endif

#ifdef CONFIG_STM32_CRC
  /* CRC clock enable */

  regval |= RCC_AHB1ENR_CRCEN;
#endif

#ifdef CONFIG_STM32_BKPSRAM
  /* Backup SRAM clock enable */

  regval |= RCC_AHB1ENR_BKPSRAMEN;
#endif

#ifdef CONFIG_STM32_DMA1
  /* DMA 1 clock enable */

  regval |= RCC_AHB1ENR_DMA1EN;
#endif

#ifdef CONFIG_STM32_DMA2
  /* DMA 2 clock enable */

  regval |= RCC_AHB1ENR_DMA2EN;
#endif

#ifdef CONFIG_STM32_ETHMAC
  /* Ethernet MAC clocking */

  regval |= (RCC_AHB1ENR_ETHMACEN|RCC_AHB1ENR_ETHMACTXEN|RCC_AHB1ENR_ETHMACRXEN);

#ifdef CONFIG_STM32_ETH_PTP
  /* Precision Time Protocol (PTP) */

  regval |= RCC_AHB1ENR_ETHMACPTPEN;

#endif
#endif

#ifdef CONFIG_STM32_OTGHS
  /* USB OTG HS */

  regval |= (RCC_AHB1ENR_OTGHSEN|RCC_AHB1ENR_OTGHSULPIEN);
#endif

  putreg32(regval, STM32_RCC_AHB1ENR);   /* Enable peripherals */
}
Пример #9
0
static inline void rcc_enableapb1(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the APB1ENR register to enabled the
   * selected APB1 peripherals.
   */

  regval = getreg32(STM32_RCC_APB1ENR);

#ifdef CONFIG_STM32_TIM2
  /* TIM2 clock enable */

  regval |= RCC_APB1ENR_TIM2EN;
#endif

#ifdef CONFIG_STM32_TIM3
  /* TIM3 clock enable */

  regval |= RCC_APB1ENR_TIM3EN;
#endif

#ifdef CONFIG_STM32_TIM4
  /* TIM4 clock enable */

  regval |= RCC_APB1ENR_TIM4EN;
#endif

#ifdef CONFIG_STM32_TIM5
  /* TIM5 clock enable */

  regval |= RCC_APB1ENR_TIM5EN;
#endif

#ifdef CONFIG_STM32_TIM6
  /* TIM6 clock enable */

  regval |= RCC_APB1ENR_TIM6EN;
#endif

#ifdef CONFIG_STM32_TIM7
  /* TIM7 clock enable */

  regval |= RCC_APB1ENR_TIM7EN;
#endif

#ifdef CONFIG_STM32_TIM12
  /* TIM12 clock enable */

  regval |= RCC_APB1ENR_TIM12EN;
#endif

#ifdef CONFIG_STM32_TIM13
  /* TIM13 clock enable */

  regval |= RCC_APB1ENR_TIM13EN;
#endif

#ifdef CONFIG_STM32_TIM14
  /* TIM14 clock enable */

  regval |= RCC_APB1ENR_TIM14EN;
#endif

#ifdef CONFIG_STM32_WWDG
  /* Window watchdog clock enable */

  regval |= RCC_APB1ENR_WWDGEN;
#endif

#ifdef CONFIG_STM32_SPI2
  /* SPI2 clock enable */

  regval |= RCC_APB1ENR_SPI2EN;
#endif

#ifdef CONFIG_STM32_SPI3
  /* SPI3 clock enable */

  regval |= RCC_APB1ENR_SPI3EN;
#endif

#ifdef CONFIG_STM32_USART2
  /* USART 2 clock enable */

  regval |= RCC_APB1ENR_USART2EN;
#endif

#ifdef CONFIG_STM32_USART3
  /* USART3 clock enable */

  regval |= RCC_APB1ENR_USART3EN;
#endif

#ifdef CONFIG_STM32_UART4
  /* UART4 clock enable */

  regval |= RCC_APB1ENR_UART4EN;
#endif

#ifdef CONFIG_STM32_UART5
  /* UART5 clock enable */

  regval |= RCC_APB1ENR_UART5EN;
#endif

#ifdef CONFIG_STM32_I2C1
  /* I2C1 clock enable */

  regval |= RCC_APB1ENR_I2C1EN;
#endif

#ifdef CONFIG_STM32_I2C2
  /* I2C2 clock enable */

  regval |= RCC_APB1ENR_I2C2EN;
#endif

#ifdef CONFIG_STM32_I2C3
  /* I2C3 clock enable */

  regval |= RCC_APB1ENR_I2C3EN;
#endif

#ifdef CONFIG_STM32_CAN1
  /* CAN 1 clock enable */

  regval |= RCC_APB1ENR_CAN1EN;
#endif

#ifdef CONFIG_STM32_CAN2
  /* CAN2 clock enable.  NOTE: CAN2 needs CAN1 clock as well. */

  regval |= (RCC_APB1ENR_CAN1EN | RCC_APB1ENR_CAN2EN);
#endif

  /* Power interface clock enable.  The PWR block is always enabled so that
   * we can set the internal voltage regulator for maximum performance.
   */

  regval |= RCC_APB1ENR_PWREN;

#if defined (CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2)
  /* DAC interface clock enable */

  regval |= RCC_APB1ENR_DACEN;
#endif

  putreg32(regval, STM32_RCC_APB1ENR);   /* Enable peripherals */
}
Пример #10
0
static inline int sam_configperiph(uintptr_t base, uint32_t pin,
                                   gpio_pinset_t cfgset)
{
  uint32_t regval;

  /* Disable interrupts on the pin */

  putreg32(pin, base + SAM_PIO_IDR_OFFSET);

  /* Enable/disable the pull-up as requested */

  if ((cfgset & GPIO_CFG_PULLUP) != 0)
    {
      putreg32(pin, base + SAM_PIO_PUER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_PUDR_OFFSET);
    }

#ifdef GPIO_HAVE_PULLDOWN
  /* Enable/disable the pull-down as requested */

  if ((cfgset & GPIO_CFG_PULLDOWN) != 0)
    {
      putreg32(pin, base + SAM_PIO_PPDER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_PPDDR_OFFSET);
    }
#endif

#ifdef GPIO_HAVE_DRIVER
  /* Reset output drive strength (PIO outputs only) */

  regval  = getreg32(base + SAM_PIO_DRIVER_OFFSET);
  regval &= ~pin;
  putreg32(regval, base + SAM_PIO_DRIVER_OFFSET);
#endif

#ifdef GPIO_HAVE_PERIPHCD
  /* Configure pin, depending upon the peripheral A, B, C or D
   *
   *   PERIPHA: ABCDSR1[n] = 0 ABCDSR2[n] = 0
   *   PERIPHB: ABCDSR1[n] = 1 ABCDSR2[n] = 0
   *   PERIPHC: ABCDSR1[n] = 0 ABCDSR2[n] = 1
   *   PERIPHD: ABCDSR1[n] = 1 ABCDSR2[n] = 1
   */

  regval = getreg32(base + SAM_PIO_ABCDSR1_OFFSET);
  if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA ||
      (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHC)
    {
      regval &= ~pin;
    }
  else
    {
      regval |= pin;
    }
  putreg32(regval, base + SAM_PIO_ABCDSR1_OFFSET);

  regval = getreg32(base + SAM_PIO_ABCDSR2_OFFSET);
  if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA ||
      (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHB)
    {
      regval &= ~pin;
    }
  else
    {
      regval |= pin;
    }
  putreg32(regval, base + SAM_PIO_ABCDSR2_OFFSET);

#else
  /* Configure pin, depending upon the peripheral A or B:
   *
   *   PERIPHA: ABSR[n] = 0
   *   PERIPHB: ABSR[n] = 1
   */

  regval = getreg32(base + SAM_PIO_ABSR_OFFSET);
  if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA)
    {
      regval &= ~pin;
    }
  else
    {
      regval |= pin;
    }

  putreg32(regval, base + SAM_PIO_ABSR_OFFSET);
#endif

  /* Disable PIO functionality */

  putreg32(pin, base + SAM_PIO_PDR_OFFSET);
  return OK;
}
Пример #11
0
int kl_configgpio(uint32_t cfgset)
{
  uintptr_t    base;
  uint32_t     regval;
  unsigned int port;
  unsigned int pin;
  unsigned int mode;

  /* Get the port number and pin number */

  port = (cfgset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT;
  pin  = (cfgset & _PIN_MASK)      >> _PIN_SHIFT;

  DEBUGASSERT(port < KL_NPORTS);
  if (port < KL_NPORTS)
    {
      /* Get the base address of PORT block for this port */

      base =  KL_PORT_BASE(port);

      /* Get the port mode */

      mode = (cfgset & _PIN_MODE_MASK)  >> _PIN_MODE_SHIFT;

      /* Special case analog port mode.  In this case, not of the digital
       * options are applicable.
       */

      if (mode == PIN_MODE_ANALOG)
        {
          /* Set the analog mode with all digital options zeroed */

          regval = PORT_PCR_MUX_ANALOG | PORT_PCR_IRQC_DISABLED;
          putreg32(regval, base + KL_PORT_PCR_OFFSET(pin));
        }
      else
        {
          /* Configure the digital pin options */

          regval = (mode << PORT_PCR_MUX_SHIFT);
          if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT)
            {
              /* Handle input-only digital options */
              /* Check for pull-up or pull-down */

              if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLDOWN)
                {
                  regval |= PORT_PCR_PE;
                }
              else if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLUP)
                {
                  regval |= (PORT_PCR_PE | PORT_PCR_PS);
                }
            }
          else
            {
              /* Handle output-only digital options */
              /* Check for slow slew rate setting */

              if ((cfgset & _PIN_OUTPUT_SLEW_MASK) == _PIN_OUTPUT_SLOW)
                {
                  regval |= PORT_PCR_SRE;
                }

              /* Check for open drain output */

              if ((cfgset & _PIN_OUTPUT_OD_MASK) == _PIN_OUTPUT_OPENDRAIN)
                {
                  regval |= PORT_PCR_ODE;
                }
              
              /* Check for high drive output */

              if ((cfgset & _PIN_OUTPUT_DRIVE_MASK) == _PIN_OUTPUT_HIGHDRIVE)
                {
                  regval |= PORT_PCR_DSE;
                }
            }

          /* Check for passive filter enable.  Passive Filter configuration
           * is valid in all digital pin muxing modes.
           */

          if ((cfgset & PIN_PASV_FILTER) != 0)
            {
              regval |= PORT_PCR_PFE;
            }

          /* Set the digital mode with all of the selected options */

          putreg32(regval, base + KL_PORT_PCR_OFFSET(pin));

          /* Check for digital filter enable.  Digital Filter configuration
           * is valid in all digital pin muxing modes.
           */

          regval = getreg32(base + KL_PORT_DFER_OFFSET);
          if ((cfgset & PIN_DIG_FILTER) != 0)
            {
              regval |= (1 << pin);
            }
          else
            {
              regval &= ~(1 << pin);
            }
          putreg32(regval, base + KL_PORT_DFER_OFFSET);

          /* Additional configuration for the case of Alternative 1 (GPIO) modes */

          if (mode == PIN_MODE_GPIO)
            {
              /* Set the GPIO port direction */

              base   = KL_GPIO_BASE(port);
              regval = getreg32(base + KL_GPIO_PDDR_OFFSET);
              if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT)
                {
                  /* Select GPIO input */

                  regval &= ~(1 << pin);
                  putreg32(regval, base + KL_GPIO_PDDR_OFFSET);
                }
              else /* if ((cfgset & _PIN_IO_MASK) == _PIN_OUTPUT) */
                {
                  /* Select GPIO input */

                  regval |= (1 << pin);
                  putreg32(regval, base + KL_GPIO_PDDR_OFFSET);

                  /* Set the initial value of the GPIO output */

                  kl_gpiowrite(cfgset, ((cfgset & GPIO_OUTPUT_ONE) != 0));
                }
            }
        }

      return OK;
    }
Пример #12
0
static inline int sam_configoutput(uintptr_t base, uint32_t pin,
                                   gpio_pinset_t cfgset)
{
#ifdef GPIO_HAVE_DRIVER
  uint32_t regval;
#endif

  /* Disable interrupts on the pin */

  putreg32(pin, base + SAM_PIO_IDR_OFFSET);

  /* Enable/disable the pull-up as requested */

  if ((cfgset & GPIO_CFG_PULLUP) != 0)
    {
      putreg32(pin, base + SAM_PIO_PUER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_PUDR_OFFSET);
    }

#ifdef GPIO_HAVE_PULLDOWN
  /* Enable/disable the pull-down as requested */

  if ((cfgset & GPIO_CFG_PULLDOWN) != 0)
    {
      putreg32(pin, base + SAM_PIO_PPDER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_PPDDR_OFFSET);
    }
#endif

  /* Enable the open drain driver if requrested */

  if ((cfgset & GPIO_CFG_OPENDRAIN) != 0)
    {
      putreg32(pin, base + SAM_PIO_MDER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_MDDR_OFFSET);
    }

  /* Set default value */

  if ((cfgset & GPIO_OUTPUT_SET) != 0)
    {
      putreg32(pin, base + SAM_PIO_SODR_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_CODR_OFFSET);
    }

#ifdef GPIO_HAVE_DRIVER
  /* Select the pin output drive strength */

  regval = getreg32(base + SAM_PIO_DRIVER_OFFSET);
  if ((cfgset & GPIO_OUTPUT_DRIVE) != GPIO_OUTPUT_LOW_DRIVE)
    {
      regval |= pin;
    }
  else
    {
      regval &= ~pin;
    }

  putreg32(regval, base + SAM_PIO_DRIVER_OFFSET);
#endif

  /* Configure the pin as an output and enable the GPIO function */

  putreg32(pin, base + SAM_PIO_OER_OFFSET);
  putreg32(pin, base + SAM_PIO_PER_OFFSET);
  return OK;
}
Пример #13
0
static inline int sam_configinput(uintptr_t base, uint32_t pin,
                                  gpio_pinset_t cfgset)
{
#ifdef GPIO_HAVE_SCHMITT
  uint32_t regval;
#endif

  /* Disable interrupts on the pin */

  putreg32(pin, base + SAM_PIO_IDR_OFFSET);

  /* Enable/disable the pull-up as requested */

  if ((cfgset & GPIO_CFG_PULLUP) != 0)
    {
      putreg32(pin, base + SAM_PIO_PUER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_PUDR_OFFSET);
    }

#ifdef GPIO_HAVE_PULLDOWN
  /* Enable/disable the pull-down as requested */

  if ((cfgset & GPIO_CFG_PULLDOWN) != 0)
    {
      putreg32(pin, base + SAM_PIO_PPDER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_PPDDR_OFFSET);
    }
#endif

  /* Check if filtering should be enabled */

  if ((cfgset & GPIO_CFG_DEGLITCH) != 0)
    {
      putreg32(pin, base + SAM_PIO_IFER_OFFSET);
    }
  else
    {
      putreg32(pin, base + SAM_PIO_IFDR_OFFSET);
    }

#ifdef GPIO_HAVE_SCHMITT
  /* Enable/disable the Schmitt trigger */

  regval = getreg32(base + SAM_PIO_SCHMITT_OFFSET);
  if ((cfgset & GPIO_CFG_PULLDOWN) != 0)
    {
      regval |= pin;
    }
  else
    {
      regval &= ~pin;
    }

  putreg32(regval, base + SAM_PIO_SCHMITT_OFFSET);
#endif

#ifdef GPIO_HAVE_DRIVER
  /* Reset output drive strength (PIO outputs only) */

  regval  = getreg32(base + SAM_PIO_DRIVER_OFFSET);
  regval &= ~pin;
  putreg32(regval, base + SAM_PIO_DRIVER_OFFSET);
#endif

  /* Configure the pin as an input and enable the GPIO function */

  putreg32(pin, base + SAM_PIO_ODR_OFFSET);
  putreg32(pin, base + SAM_PIO_PER_OFFSET);

  /* To-Do:  If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and
   *         IFDGSR registers.  This would probably best be done with
   *         another, new API... perhaps sam_configfilter()
   */

  return OK;
}
Пример #14
0
void up_irqinitialize(void)
{
  uint32_t regaddr;
  int num_priority_registers;

  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);

  /* Colorize the interrupt stack for debug purposes */

#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3
  {
    size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
    up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
                   intstack_size);
  }
#endif

  /* The standard location for the vector table is at the beginning of FLASH
   * at address 0x0800:0000.  If we are using the STMicro DFU bootloader, then
   * the vector table will be offset to a different location in FLASH and we
   * will need to set the NVIC vector location to this alternative location.
   *
   * If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

#if defined(CONFIG_ARCH_RAMVECTORS)
  up_ramvec_initialize();
#elif defined(CONFIG_STM32_DFU)
  putreg32((uint32_t)_vectors, NVIC_VECTAB);
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports:
   *
   *  0 -> 32 interrupt lines,  8 priority registers
   *  1 -> 64 "       " "   ", 16 priority registers
   *  2 -> 96 "       " "   ", 32 priority registers
   *  ...
   */

  num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;

  /* Now set all of the interrupt lines to the default priority */

  regaddr = NVIC_IRQ0_3_PRIORITY;
  while (num_priority_registers--)
    {
      putreg32(DEFPRIORITY32, regaddr);
      regaddr += 4;
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(STM32_IRQ_SVCALL, up_svcall);
  irq_attach(STM32_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
   stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(STM32_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(STM32_IRQ_NMI, stm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault);
  irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault);
  irq_attach(STM32_IRQ_PENDSV, stm32_pendsv);
  irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor);
  irq_attach(STM32_IRQ_RESERVED, stm32_reserved);
#endif

  stm32_dumpnvic("initial", NR_IRQS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS

  /* And finally, enable interrupts */

  irqenable();
#endif
}
static void lpc17_gpiodemux(uint32_t intbase, uint32_t intmask,
                            int irqbase, void *context)
{
  uint32_t intstatr;
  uint32_t intstatf;
  uint32_t intstatus;
  uint32_t bit;
  int      irq;

  /* Get the interrupt rising and falling edge status and mask out only the
   * interrupts that are enabled.
   */

  intstatr  = getreg32(intbase + LPC17_GPIOINT_INTSTATR_OFFSET);
  intstatr &= getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET);

  intstatf  = getreg32(intbase + LPC17_GPIOINT_INTSTATF_OFFSET);
  intstatf &= getreg32(intbase + LPC17_GPIOINT_INTENF_OFFSET);

  /* And get the OR of the enabled interrupt sources.  We do not make any
   * distinction between rising and falling edges (but the hardware does support
   * the ability to handle them differently if needed).
   */

  intstatus = intstatr | intstatf;

  /* Now march through the (valid) bits and dispatch each interrupt */

  irq = irqbase;
  bit = 1;
  while (intstatus != 0)
    {
      /* Does this pin support an interrupt?  If no, skip over it WITHOUT
       * incrementing irq.
       */

      if ((intmask & bit) != 0)
        {
           /* This pin can support an interrupt.  Is there an interrupt pending
            * and enabled?
            */

           if ((intstatus & bit) != 0)
             {
               /* Clear the interrupt status */

               putreg32(bit, intbase + LPC17_GPIOINT_INTCLR_OFFSET);

               /* And dispatch the interrupt */

               irq_dispatch(irq, context);
             }

           /* Increment the IRQ number on each interrupt pin */

           irq++;
        }

      /* Next bit */

      intstatus &= ~bit;
      bit      <<= 1;
    }
}
Пример #16
0
static inline void rcc_enableapb2(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the APB2ENR register to enabled the
   * selected APB2 peripherals.
   */

  regval = getreg32(STM32_RCC_APB2ENR);

#ifdef CONFIG_STM32_TIM1
  /* TIM1 clock enable */

  regval |= RCC_APB2ENR_TIM1EN;
#endif

#ifdef CONFIG_STM32_TIM8
  /* TIM8 clock enable */

  regval |= RCC_APB2ENR_TIM8EN;
#endif

#ifdef CONFIG_STM32_USART1
  /* USART1 clock enable */

  regval |= RCC_APB2ENR_USART1EN;
#endif

#ifdef CONFIG_STM32_USART6
  /* USART6 clock enable */

  regval |= RCC_APB2ENR_USART6EN;
#endif

#ifdef CONFIG_STM32_ADC1
  /* ADC1 clock enable */

  regval |= RCC_APB2ENR_ADC1EN;
#endif

#ifdef CONFIG_STM32_ADC2
  /* ADC2 clock enable */

  regval |= RCC_APB2ENR_ADC2EN;
#endif

#ifdef CONFIG_STM32_ADC3
  /* ADC3 clock enable */

  regval |= RCC_APB2ENR_ADC3EN;
#endif

#ifdef CONFIG_STM32_SDIO
  /* SDIO clock enable */

  regval |= RCC_APB2ENR_SDIOEN;
#endif

#ifdef CONFIG_STM32_SPI1
  /* SPI1 clock enable */

  regval |= RCC_APB2ENR_SPI1EN;
#endif

#ifdef CONFIG_STM32_SYSCFG
  /* System configuration controller clock enable */

  regval |= RCC_APB2ENR_SYSCFGEN;
#endif

#ifdef CONFIG_STM32_TIM9
  /* TIM9 clock enable */

  regval |= RCC_APB2ENR_TIM9EN;
#endif

#ifdef CONFIG_STM32_TIM10
  /* TIM10 clock enable */

  regval |= RCC_APB2ENR_TIM10EN;
#endif

#ifdef CONFIG_STM32_TIM11
  /* TIM11 clock enable */

  regval |= RCC_APB2ENR_TIM11EN;
#endif

  putreg32(regval, STM32_RCC_APB2ENR);   /* Enable peripherals */
}
Пример #17
0
ssize_t up_progmem_eraseblock(size_t block)
{
  uintptr_t base;
  size_t page_address;

  if (block >= STM32_FLASH_NPAGES)
    {
      return -EFAULT;
    }

#if defined(STM32_FLASH_DUAL_BANK)
  /* Handle paged FLASH */

  if (block >= STM32_FLASH_BANK0_NPAGES)
    {
      base = STM32_FLASH_BANK1_BASE;
    }
  else
#endif
    {
      base = STM32_FLASH_BANK0_BASE;
    }

  sem_lock();

  if ((getreg32(base + STM32_RCC_CR_OFFSET) & RCC_CR_HSION) == 0)
    {
      sem_unlock();
      return -EPERM;
    }

  /* Get flash ready and begin erasing single page */

  flash_unlock(base);

  modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_PER);

  /* Must be valid - page index checked above */

  page_address = up_progmem_getaddress(block);
  putreg32(page_address, base + STM32_FLASH_AR_OFFSET);

  modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_STRT);

  while ((getreg32(base + STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) != 0)
    {
      up_waste();
    }

  modifyreg32(base + STM32_FLASH_CR_OFFSET, FLASH_CR_PER, 0);
  sem_unlock();

  /* Verify */

  if (up_progmem_ispageerased(block) == 0)
    {
      return up_progmem_erasesize(block); /* success */
    }
  else
    {
      return -EIO; /* failure */
    }
}
Пример #18
0
static void stm32_stdclockconfig(void)
{
  uint32_t regval;
  volatile int32_t timeout;

  /* Enable External High-Speed Clock (HSE) */

  regval  = getreg32(STM32_RCC_CR);
  regval |= RCC_CR_HSEON;           /* Enable HSE */
  putreg32(regval, STM32_RCC_CR);

  /* Wait until the HSE is ready (or until a timeout elapsed) */

  for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--)
  {
    /* Check if the HSERDY flag is the set in the CR */

    if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0)
      {
        /* If so, then break-out with timeout > 0 */

        break;
      }
  }

  /* Check for a timeout.  If this timeout occurs, then we are hosed.  We
   * have no real back-up plan, although the following logic makes it look
   * as though we do.
   */

  if (timeout > 0)
    {
      /* Select regulator voltage output Scale 1 mode to support system
       * frequencies up to 168 MHz.
       */

      regval  = getreg32(STM32_RCC_APB1ENR);
      regval |= RCC_APB1ENR_PWREN;
      putreg32(regval, STM32_RCC_APB1ENR);

      regval  = getreg32(STM32_PWR_CR);
      regval |= PWR_CR_VOS;
      putreg32(regval, STM32_PWR_CR);

      /* Set the HCLK source/divider */

      regval = getreg32(STM32_RCC_CFGR);
      regval &= ~RCC_CFGR_HPRE_MASK;
      regval |= STM32_RCC_CFGR_HPRE;
      putreg32(regval, STM32_RCC_CFGR);

      /* Set the PCLK2 divider */

      regval = getreg32(STM32_RCC_CFGR);
      regval &= ~RCC_CFGR_PPRE2_MASK;
      regval |= STM32_RCC_CFGR_PPRE2;
      putreg32(regval, STM32_RCC_CFGR);

      /* Set the PCLK1 divider */

      regval = getreg32(STM32_RCC_CFGR);
      regval &= ~RCC_CFGR_PPRE1_MASK;
      regval |= STM32_RCC_CFGR_PPRE1;
      putreg32(regval, STM32_RCC_CFGR);

#ifdef CONFIG_RTC_HSECLOCK
      /* Set the RTC clock divisor */

      regval = getreg32(STM32_RCC_CFGR);
      regval &= ~RCC_CFGR_RTCPRE_MASK;
      regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR);
      putreg32(regval, STM32_RCC_CFGR);
#endif

      /* Set the PLL dividers and multipliers to configure the main PLL */

      regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN |STM32_PLLCFG_PLLP |
                RCC_PLLCFG_PLLSRC_HSE | STM32_PLLCFG_PLLQ);
      putreg32(regval, STM32_RCC_PLLCFG);

      /* Enable the main PLL */

      regval = getreg32(STM32_RCC_CR);
      regval |= RCC_CR_PLLON;
      putreg32(regval, STM32_RCC_CR);

      /* Wait until the PLL is ready */

      while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0);

      /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */

#ifdef CONFIG_STM32_FLASH_PREFETCH
      regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN);
#else
      regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN);
#endif
      putreg32(regval, STM32_FLASH_ACR);

      /* Select the main PLL as system clock source */

      regval  = getreg32(STM32_RCC_CFGR);
      regval &= ~RCC_CFGR_SW_MASK;
      regval |= RCC_CFGR_SW_PLL;
      putreg32(regval, STM32_RCC_CFGR);

      /* Wait until the PLL source is used as the system clock source */

      while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL);
    }
}
Пример #19
0
static inline void rcc_enableapb2(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the APB2ENR register to enabled the
   * selected APB2 peripherals.
   */

  regval = getreg32(STM32_RCC_APB2ENR);

#ifdef CONFIG_STM32_SYSCFG
  /* SYSCFG clock */

  regval |= RCC_APB2ENR_SYSCFGEN;
#endif

#ifdef CONFIG_STM32_TIM1
  /* TIM1 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM1EN;
#endif
#endif

#ifdef CONFIG_STM32_SPI1
  /* SPI 1 clock enable */

  regval |= RCC_APB2ENR_SPI1EN;
#endif

#ifdef CONFIG_STM32_USART1
  /* USART1 clock enable */

  regval |= RCC_APB2ENR_USART1EN;
#endif

#ifdef CONFIG_STM32_TIM15
  /* TIM15 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM15EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM16
  /* TIM16 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM16EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM17
  /* TIM17 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM17EN;
#endif
#endif

#ifdef CONFIG_STM32_HRTIM1
  /* HRTIM1 Timer clock enable */

  regval |= RCC_APB2ENR_HRTIM1EN;
#endif

  putreg32(regval, STM32_RCC_APB2ENR);
}
Пример #20
0
static inline void rcc_enableapb1(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the APB1ENR register to enabled the
   * selected APB1 peripherals.
   */

  regval  = getreg32(STM32_RCC_APB1ENR);

#ifdef CONFIG_STM32_TIM2
  /* Timer 2 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM2EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM3
  /* Timer 3 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM3EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM4
  /* Timer 4 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM4EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM5
  /* Timer 5 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM5EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM6
  /* Timer 6 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM6EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM7
  /* Timer 7 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_TIM7EN;
#endif
#endif

#ifdef CONFIG_STM32_LCD
  /* LCD clock enable */

  regval |= RCC_APB1ENR_LCDEN;
#endif

#ifdef CONFIG_STM32_WWDG
  /* Window Watchdog clock enable */

  regval |= RCC_APB1ENR_WWDGEN;
#endif

#ifdef CONFIG_STM32_SPI2
  /* SPI 2 clock enable */

  regval |= RCC_APB1ENR_SPI2EN;
#endif

#ifdef CONFIG_STM32_SPI3
  /* SPI 3 clock enable */

  regval |= RCC_APB1ENR_SPI3EN;
#endif

#ifdef CONFIG_STM32_USART2
  /* USART 2 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_USART2EN;
#endif
#endif

#ifdef CONFIG_STM32_USART3
  /* USART 3 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_USART3EN;
#endif
#endif

#ifdef CONFIG_STM32_UART4
  /* USART 4 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_UART4EN;
#endif
#endif

#ifdef CONFIG_STM32_UART5
  /* USART 5 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_UART5EN;
#endif
#endif

#ifdef CONFIG_STM32_I2C1
  /* I2C 1 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_I2C1EN;
#endif
#endif

#ifdef CONFIG_STM32_I2C2
  /* I2C 2 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB1ENR_I2C2EN;
#endif
#endif

#ifdef CONFIG_STM32_USB
  /* USB clock enable */

  regval |= RCC_APB1ENR_USBEN;
#endif

#ifdef CONFIG_STM32_PWR
  /*  Power interface clock enable */

  regval |= RCC_APB1ENR_PWREN;
#endif

#ifdef CONFIG_STM32_DAC
  /* DAC interface clock enable */

  regval |= RCC_APB1ENR_DACEN;
#endif

#ifdef CONFIG_STM32_COMP
  /* COMP interface clock enable */

  regval |= RCC_APB1ENR_COMPEN;
#endif

  putreg32(regval, STM32_RCC_APB1ENR);
}
Пример #21
0
static inline void rcc_reset(void)
{
  uint32_t regval;

  putreg32(0, STM32_RCC_APB2RSTR);          /* Disable APB2 Peripheral Reset */
  putreg32(0, STM32_RCC_APB1RSTR);          /* Disable APB1 Peripheral Reset */
  putreg32(RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN, STM32_RCC_AHBENR); /* FLITF and SRAM Clock ON */
  putreg32(0, STM32_RCC_APB2ENR);           /* Disable APB2 Peripheral Clock */
  putreg32(0, STM32_RCC_APB1ENR);           /* Disable APB1 Peripheral Clock */

  regval  = getreg32(STM32_RCC_CR);         /* Set the HSION bit */
  regval |= RCC_CR_HSION;
  putreg32(regval, STM32_RCC_CR);

  regval  = getreg32(STM32_RCC_CFGR);       /* Reset SW, HPRE, PPRE1, PPRE2, and MCO bits */
  regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK |
              RCC_CFGR_PPRE2_MASK | RCC_CFGR_MCO_MASK);

  putreg32(regval, STM32_RCC_CFGR);

  regval  = getreg32(STM32_RCC_CFGR2);       /* Reset PREDIV, and ADC12PRE bits */
  regval &= ~(RCC_CFGR2_PREDIV_MASK | RCC_CFGR2_ADC12PRES_MASK);
  putreg32(regval, STM32_RCC_CFGR2);

  regval  = getreg32(STM32_RCC_CFGR3);       /* Reset all U[S]ARTs, I2C1, TIM1 and HRTIM1 bits */
  regval &= ~(RCC_CFGR3_USART1SW_MASK | RCC_CFGR3_USART2SW_MASK | RCC_CFGR3_USART3SW_MASK | \
              RCC_CFGR3_I2C1SW | RCC_CFGR3_TIM1SW | RCC_CFGR3_HRTIM1SW);
  putreg32(regval, STM32_RCC_CFGR3);

  regval  = getreg32(STM32_RCC_CR);         /* Reset HSEON, CSSON and PLLON bits */
  regval &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON);
  putreg32(regval, STM32_RCC_CR);

  regval  = getreg32(STM32_RCC_CR);         /* Reset HSEBYP bit */
  regval &= ~RCC_CR_HSEBYP;
  putreg32(regval, STM32_RCC_CR);

  regval  = getreg32(STM32_RCC_CFGR);       /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
  regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK);
  putreg32(regval, STM32_RCC_CFGR);

  putreg32(0, STM32_RCC_CIR);               /* Disable all interrupts */
}
Пример #22
0
static inline void rcc_enableapb2(void)
{
  uint32_t regval;

  /* Set the appropriate bits in the APB2ENR register to enabled the
   * selected APB2 peripherals.
   */

  regval = getreg32(STM32_RCC_APB2ENR);

#ifdef CONFIG_STM32_SYSCFG
  /* SYSCFG clock */

  regval |= RCC_APB2ENR_SYSCFGEN;
#endif

#ifdef CONFIG_STM32_TIM9
  /* TIM9 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM9EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM10
  /* TIM10 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM10EN;
#endif
#endif

#ifdef CONFIG_STM32_TIM11
  /* TIM11 Timer clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_TIM11EN;
#endif
#endif

#ifdef CONFIG_STM32_ADC1
  /* ADC 1 clock enable */

  regval |= RCC_APB2ENR_ADC1EN;
#endif

#ifdef CONFIG_STM32_SDIO
  /* SDIO clock enable */

  regval |= RCC_APB2ENR_SDIOEN;
#endif

#ifdef CONFIG_STM32_SPI1
  /* SPI 1 clock enable */

  regval |= RCC_APB2ENR_SPI1EN;
#endif

#ifdef CONFIG_STM32_USART1
  /* USART1 clock enable */

#ifdef CONFIG_STM32_FORCEPOWER
  regval |= RCC_APB2ENR_USART1EN;
#endif
#endif

  putreg32(regval, STM32_RCC_APB2ENR);
}
Пример #23
0
void up_irqinitialize(void)
{
  uint32_t regaddr;
  int num_priority_registers;

  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32)
  putreg32(0, NVIC_IRQ32_63_ENABLE);
#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64)
  putreg32(0, NVIC_IRQ64_95_ENABLE);
#endif
#endif

#if defined(CONFIG_DEBUG_STACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
  /* Colorize the interrupt stack for debug purposes */

  {
    size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
    up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
                   intstack_size);
  }
#endif

#ifdef CONFIG_ARCH_RAMVECTORS
  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

  up_ramvec_initialize();
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports:
   *
   *  0 -> 32 interrupt lines,  8 priority registers
   *  1 -> 64 "       " "   ", 16 priority registers
   *  2 -> 96 "       " "   ", 32 priority registers
   *  ...
   */

  num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;

  /* Now set all of the interrupt lines to the default priority */

  regaddr = NVIC_IRQ0_3_PRIORITY;
  while (num_priority_registers--)
    {
      putreg32(DEFPRIORITY32, regaddr);
      regaddr += 4;
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(EFM32_IRQ_SVCALL, up_svcall);
  irq_attach(EFM32_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARMV7M_USEBASEPRI
   efm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(EFM32_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(EFM32_IRQ_NMI, efm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(EFM32_IRQ_BUSFAULT, efm32_busfault);
  irq_attach(EFM32_IRQ_USAGEFAULT, efm32_usagefault);
  irq_attach(EFM32_IRQ_PENDSV, efm32_pendsv);
  irq_attach(EFM32_IRQ_DBGMONITOR, efm32_dbgmonitor);
  irq_attach(EFM32_IRQ_RESERVED, efm32_reserved);
#endif

  efm32_dumpnvic("initial", NR_VECTORS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS
#ifdef CONFIG_EFM32_GPIO_IRQ
  /* Initialize logic to support a second level of interrupt decoding for
   * GPIO pins.
   */

  efm32_gpioirqinitialize();
#endif

  /* And finally, enable interrupts */

  irqenable();
#endif
}
Пример #24
0
static void stm32_stdclockconfig(void)
{
  uint32_t regval;
#if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_LCD_HSECLOCK)
  uint16_t pwrcr;
#endif

#if defined(CONFIG_STM32_ENERGYLITE)

  /* Enable PWR clock from APB1 to give access to PWR_CR register */

  regval  = getreg32(STM32_RCC_APB1ENR);
  regval |= RCC_APB1ENR_PWREN;
  putreg32(regval, STM32_RCC_APB1ENR);
#endif /* CONFIG_STM32_ENERGYLITE */

  /* Go to the high performance voltage range 1 if necessary.  In this mode,
   * the PLL VCO frequency can be up to 96MHz.  USB and SDIO can be supported.
   *
   * Range 1: PLLVCO up to 96MHz in range 1 (1.8V)
   * Range 2: PLLVCO up to 48MHz in range 2 (1.5V) (default)
   * Range 3: PLLVCO up to 24MHz in range 3 (1.2V)
   */

#if STM32_PLL_FREQUENCY > 48000000
  stm32_pwr_setvos(PWR_CR_VOS_SCALE_1);
#endif

#if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_LCD_HSECLOCK)
  /* If RTC / LCD selects HSE as clock source, the RTC prescaler
   * needs to be set before HSEON bit is set.
   */

  /* The RTC domain has write access denied after reset,
   * you have to enable write access using DBP bit in the PWR CR
   * register before to selecting the clock source ( and the PWR
   * peripheral must be enabled)
   */

  regval  = getreg32(STM32_RCC_APB1ENR);
  regval |= RCC_APB1ENR_PWREN;
  putreg32(regval, STM32_RCC_APB1ENR);

  pwrcr = getreg16(STM32_PWR_CR);
  putreg16(pwrcr | PWR_CR_DBP, STM32_PWR_CR);

  /* Set the RTC clock divisor */

  regval = getreg32(STM32_RCC_CSR);
  regval &= ~RCC_CSR_RTCSEL_MASK;
  regval |= RCC_CSR_RTCSEL_HSE;
  putreg32(regval, STM32_RCC_CSR);

  regval = getreg32(STM32_RCC_CR);
  regval &= ~RCC_CR_RTCPRE_MASK;
  regval |= HSE_DIVISOR);
  putreg32(regval, STM32_RCC_CR);

   /* Restore the previous state of the DBP bit */

  putreg32(regval, STM32_PWR_CR);

#endif

  /* Enable the source clock for the PLL (via HSE or HSI), HSE, and HSI.
   * NOTE that only PLL, HSE, or HSI are supported for the system clock
   * in this implementation
   */

#if (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) || \
    ((STM32_SYSCLK_SW == RCC_CFGR_SW_PLL) && (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC))
  /* The PLL is using the HSE, or the HSE is the system clock.  In either
   * case, we need to enable HSE clocking.
   */

  if (!stm32_rcc_enablehse())
    {
      /* In the case of a timeout starting the HSE, we really don't have a
       * strategy.  This is almost always a hardware failure or
       * misconfiguration (for example, if no crystal is fitted on the board.
       */

      return;
    }

#elif (STM32_SYSCLK_SW == RCC_CFGR_SW_HSI) || \
      ((STM32_SYSCLK_SW == RCC_CFGR_SW_PLL) && STM32_CFGR_PLLSRC == 0)
  /* The PLL is using the HSI, or the HSI is the system clock.  In either
   * case, we need to enable HSI clocking.
   */

  regval  = getreg32(STM32_RCC_CR);   /* Enable the HSI */
  regval |= RCC_CR_HSION;
  putreg32(regval, STM32_RCC_CR);

  /* Wait until the HSI clock is ready.  Since this is an internal clock, no
   * timeout is expected
   */

  while ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) == 0);

#endif

#if (STM32_SYSCLK_SW != RCC_CFGR_SW_MSI)

  /* Increasing the CPU frequency (in the same voltage range):
   *
   * After reset, the used clock is the MSI (2 MHz) with 0 WS configured in the
   * FLASH_ACR register. 32-bit access is enabled and prefetch is disabled.
   * ST strongly recommends to use the following software sequences to tune the
   * number of wait states needed to access the Flash memory with the CPU
   * frequency.
   *
   *   - Program the 64-bit access by setting the ACC64 bit in Flash access
   *     control register (FLASH_ACR)
   *   - Check that 64-bit access is taken into account by reading FLASH_ACR
   *   - Program 1 WS to the LATENCY bit in FLASH_ACR
   *   - Check that the new number of WS is taken into account by reading FLASH_ACR
   *   - Modify the CPU clock source by writing to the SW bits in the Clock
   *     configuration register (RCC_CFGR)
   *   - If needed, modify the CPU clock prescaler by writing to the HPRE bits in
   *     RCC_CFGR
   *   - Check that the new CPU clock source or/and the new CPU clock prescaler
   *     value is/are taken into account by reading the clock source status (SWS
   *     bits) or/and the AHB prescaler value (HPRE bits), respectively, in the
   *     RCC_CFGR register
   */

  regval = getreg32(STM32_FLASH_ACR);
  regval |= FLASH_ACR_ACC64;          /* 64-bit access mode */
  putreg32(regval, STM32_FLASH_ACR);

  regval |= FLASH_ACR_LATENCY;        /* One wait state */
  putreg32(regval, STM32_FLASH_ACR);

  /* Enable FLASH prefetch */

  regval |= FLASH_ACR_PRFTEN;
  putreg32(regval, STM32_FLASH_ACR);

#endif

  /* Set the HCLK source/divider */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_HPRE_MASK;
  regval |= STM32_RCC_CFGR_HPRE;
  putreg32(regval, STM32_RCC_CFGR);

  /* Set the PCLK2 divider */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_PPRE2_MASK;
  regval |= STM32_RCC_CFGR_PPRE2;
  putreg32(regval, STM32_RCC_CFGR);

  /* Set the PCLK1 divider */

  regval = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_PPRE1_MASK;
  regval |= STM32_RCC_CFGR_PPRE1;
  putreg32(regval, STM32_RCC_CFGR);

  /* If we are using the PLL, configure and start it */

#if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL

  /* Set the PLL divider and multiplier.  NOTE:  The PLL needs to be disabled
   * to do these operation.  We know this is the case here because pll_reset()
   * was previously called by stm32_clockconfig().
   */

  regval  = getreg32(STM32_RCC_CFGR);
  regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK | RCC_CFGR_PLLDIV_MASK);
  regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLMUL | STM32_CFGR_PLLDIV);
  putreg32(regval, STM32_RCC_CFGR);

  /* Enable the PLL */

  regval = getreg32(STM32_RCC_CR);
  regval |= RCC_CR_PLLON;
  putreg32(regval, STM32_RCC_CR);

  /* Wait until the PLL is ready */

  while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0);

#endif

  /* Select the system clock source (probably the PLL) */

  regval  = getreg32(STM32_RCC_CFGR);
  regval &= ~RCC_CFGR_SW_MASK;
  regval |= STM32_SYSCLK_SW;
  putreg32(regval, STM32_RCC_CFGR);

  /* Wait until the selected source is used as the system clock source */

  while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS);

#if defined(CONFIG_STM32_IWDG)   || \
    defined(CONFIG_RTC_LSICLOCK) || defined(CONFIG_LCD_LSICLOCK)
  /* Low speed internal clock source LSI */
  /*
   * TODO: There is another case where the LSI needs to
   * be enabled: if the MCO pin selects LSI as source.
   */

  stm32_rcc_enablelsi();

#endif

#if defined(CONFIG_RTC_LSECLOCK) || defined(CONFIG_LCD_LSECLOCK)
  /* Low speed external clock source LSE
   *
   * TODO: There is another case where the LSE needs to
   * be enabled: if the MCO pin selects LSE as source.
   *
   * TODO: There is another case where the LSE needs to
   * be enabled: if TIM9-10 Channel 1 selects LSE as input.
   *
   * TODO: There is another case where the LSE needs to
   * be enabled: if TIM10-11 selects LSE as ETR Input.
   *
   */

  stm32_rcc_enablelse();
#endif
}
Пример #25
0
void nokia_blinitialize(void)
{
  uint32_t regval;

  /* Enable clocking of PWM1 */

  regval = getreg32(LPC17_SYSCON_PCONP);
  regval |= SYSCON_PCONP_PCPWM1;
  putreg32(regval, LPC17_SYSCON_PCONP);

  /* Disable and reset PWM1 */

  regval  = getreg32(LPC17_PWM1_TCR);
  regval &= ~(PWM_TCR_PWMEN|PWM_TCR_CNTREN);
  regval |= PWM_TCR_CNTRRST;
  putreg32(regval, LPC17_PWM1_TCR);

  /* Put PWM1 in timer mode */

  regval  = getreg32(LPC17_PWM1_CTCR);
  regval &= ~PWM_CTCR_MODE_MASK;
  regval |= PWM_CTCR_MODE_TIMER;
  putreg32(regval, LPC17_PWM1_CTCR);

  /* Reset on MR0 */

  putreg32(PWM_MCR_MR0R, LPC17_PWM1_MCR);

  /* Single edge controlled mod for PWM3 and enable output */

  regval  = getreg32(LPC17_PWM1_PCR);
  regval &= ~PWM_PCR_SEL3;
  regval |= PWM_PCR_ENA3;
  putreg32(regval, LPC17_PWM1_PCR);

  /* Clear prescaler */

  putreg32(0, LPC17_PWM1_PR);

  /* Set 8-bit resolution */

  putreg32(0xff, LPC17_PWM1_MCR);

  /* Enable PWM match 1 latch */

  regval  = getreg32(LPC17_PWM1_LER);
  regval |= PWM_LER_M0EN;
  putreg32(regval, LPC17_PWM1_LER);

  /* Clear match register 3 */

  putreg32(0, LPC17_PWM1_MR3);

  /* Enable PWM1 */
  
  regval |= PWM_LER_M3EN;
  putreg32(regval, LPC17_PWM1_LER);

  regval  = getreg32(LPC17_PWM1_TCR);
  regval &= ~(PWM_TCR_CNTRRST);
  regval |= (PWM_TCR_PWMEN|PWM_TCR_CNTREN);
  putreg32(regval, LPC17_PWM1_TCR);

  nokia_backlight(0);
}
Пример #26
0
static inline void rcc_reset(void)
{
#if 0 /* None of this is necessary if only called from power up */
  uint32_t regval;

  /* Make sure that all devices are out of reset */

  putreg32(0, STM32_RCC_AHBRSTR);           /* Disable AHB Peripheral Reset */
  putreg32(0, STM32_RCC_APB2RSTR);          /* Disable APB2 Peripheral Reset */
  putreg32(0, STM32_RCC_APB1RSTR);          /* Disable APB1 Peripheral Reset */

  /* Disable all clocking (other than to FLASH) */

  putreg32(RCC_AHBENR_FLITFEN, STM32_RCC_AHBENR); /* FLITF Clock ON */
  putreg32(0, STM32_RCC_APB2ENR);           /* Disable APB2 Peripheral Clock */
  putreg32(0, STM32_RCC_APB1ENR);           /* Disable APB1 Peripheral Clock */

  /* Set the Internal clock sources calibration register to its reset value.
   * MSI to the default frequency (nominally 2.097MHz), MSITRIM=0, HSITRIM=0x10.
   * Preserve the factory HSICAL and MSICAL settings.
   */

  regval  = getreg32(STM32_RCC_ICSCR);
  regval &= (RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK);
  regval |= (RCC_ICSR_RSTVAL & ~(RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK));
  putreg32(regval, STM32_RCC_ICSCR);

  /* Enable the internal MSI */

  regval  = getreg32(STM32_RCC_CR);         /* Enable the MSI */
  regval |= RCC_CR_MSION;
  putreg32(regval, STM32_RCC_CR);

  /* Set the CFGR register to its reset value: Reset SW, HPRE, PPRE1, PPRE2,
   * and MCO bits.  Resetting SW selects the MSI clock as the system clock
   * source. We do not clear PLL values yet because the PLL may be providing
   * the SYSCLK and we want the PLL to be stable through the transition.
   */

  regval  = getreg32(STM32_RCC_CFGR);
  regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK |
              RCC_CFGR_PPRE2_MASK | RCC_CFGR_MCOSEL_MASK | RCC_CFGR_MCOPRE_MASK);
  putreg32(regval, STM32_RCC_CFGR);

  /* Make sure that the selected MSI source is used as the system clock source */

  while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_MSI);

  /* Now we can disable the alternative clock sources: HSE, HSI, PLL, CSS and RTCPRE. Also,
   * reset the HSE bypass.  This restores the RCC CR to its reset state.
   */

  regval  = getreg32(STM32_RCC_CR);         /* Disable the HSE and the PLL */
  regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_RTCPRE_MASK);
  putreg32(regval, STM32_RCC_CR);

  regval  = getreg32(STM32_RCC_CR);         /* Reset HSEBYP bit */
  regval &= ~RCC_CR_HSEBYP;
  putreg32(regval, STM32_RCC_CR);

  /* Now we can reset the CFGR PLL fields to their reset value */

  regval  = getreg32(STM32_RCC_CFGR);       /* Reset PLLSRC, PLLMUL, and PLLDIV bits */
  regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK | RCC_CFGR_PLLDIV_MASK);
  putreg32(regval, STM32_RCC_CFGR);

  /* Make sure that all interrupts are disabled */

  putreg32(0, STM32_RCC_CIR);               /* Disable all interrupts */

  /* Go to the (default) voltage range 2 */

  stm32_pwr_setvos(PWR_CR_VOS_SCALE_2);

  /* Reset the FLASH controller to 32-bit mode, no wait states.
   *
   * First, program the new number of WS to the LATENCY bit in Flash access
   * control register (FLASH_ACR)
   */

  regval  = getreg32(STM32_FLASH_ACR);
  regval &= ~FLASH_ACR_LATENCY;             /* No wait states */
  putreg32(regval, STM32_FLASH_ACR);

  /* Check that the new number of WS is taken into account by reading FLASH_ACR */

  /* Program the 32-bit access by clearing ACC64 in FLASH_ACR */

  regval &= ~FLASH_ACR_ACC64;             /* 32-bit access mode */
  putreg32(regval, STM32_FLASH_ACR);

  /* Check that 32-bit access is taken into account by reading FLASH_ACR */
#endif
}
Пример #27
0
FAR struct spi_dev_s *up_spiinitialize(int port)
{
  uint32_t regval32;
  uint8_t regval8;
  int i;

  /* Only the SPI1 interface is supported */

#ifdef CONFIG_DEBUG
  if (port != 1)
    {
      return NULL;
    }
#endif

  /* Configure multiplexed pins as connected on the ZP213X/4XPA board:
   *
   *   PINSEL1 P0.17/CAP1.2/SCK1/MAT1.2  Bits 2-3=10 for SCK1
   *   PINSEL1 P0.18/CAP1.3/MISO1/MAT1.3 Bits 4-5=10 for MISO1
   *                                     (This is the RESET line for the UG_2864AMBAG01,
   *                                      although it is okay to configure it as an input too)
   *   PINSEL1 P0.19/MAT1.2/MOSI1/CAP1.2 Bits 6-7=10 for MOSI1
   *   PINSEL1 P0.20/MAT1.3/SSEL1/EINT3  Bits 8-9=00 for P0.20 (we'll control it via GPIO or FIO)
   *   PINSEL1 P0.23/VBUS                Bits 12-13=00 for P0.21 (we'll control it via GPIO or FIO)
   */

  regval32  = getreg32(LPC214X_PINSEL1);
#ifdef CONFIG_LCD_UG2864AMBAG01
  regval32 &= ~(LPC214X_PINSEL1_P017_MASK|LPC214X_PINSEL1_P019_MASK|
                LPC214X_PINSEL1_P020_MASK|LPC214X_PINSEL1_P023_MASK);
  regval32 |= (LPC214X_PINSEL1_P017_SCK1|LPC214X_PINSEL1_P019_MOSI1|
               LPC214X_PINSEL1_P020_GPIO|LPC214X_PINSEL1_P023_GPIO);
#else
  regval32 &= ~(LPC214X_PINSEL1_P017_MASK|LPC214X_PINSEL1_P018_MASK
                LPC214X_PINSEL1_P019_MASK|LPC214X_PINSEL1_P020_MASK|
                LPC214X_PINSEL1_P023_MASK);
  regval32 |= (LPC214X_PINSEL1_P017_SCK1|LPC214X_PINSEL1_P018_MISO1|
               LPC214X_PINSEL1_P019_MOSI1|LPC214X_PINSEL1_P020_GPIO|
               LPC214X_PINSEL1_P023_GPIO);
#endif
  putreg32(regval32, LPC214X_PINSEL1);

  /* De-select chip select using P0.20 (SSEL1)  (low enables) and select A0
   * for commands (also low)
   */

  regval32 = (1 << 20) | (1 << 23);
  putreg32(regval32, CS_SET_REGISTER);
  regval32 |= getreg32(CS_DIR_REGISTER);
  putreg32(regval32, CS_DIR_REGISTER);

  spidbg("CS Pin Config: PINSEL1: %08x PIN: %08x DIR: %08x\n",
         getreg32(LPC214X_PINSEL1), getreg32(CS_PIN_REGISTER),
         getreg32(CS_DIR_REGISTER));

  /* Enable peripheral clocking to SPI1 */

  regval32  = getreg32(LPC214X_PCON_PCONP);
  regval32 |= LPC214X_PCONP_PCSPI1;
  putreg32(regval32, LPC214X_PCON_PCONP);

  /* Configure 8-bit SPI mode */

  putreg16(LPC214X_SPI1CR0_DSS8BIT|LPC214X_SPI1CR0_FRFSPI, LPC214X_SPI1_CR0);

  /* Disable the SSP and all interrupts (we'll poll for all data) */

  putreg8(0, LPC214X_SPI1_CR1);
  putreg8(0, LPC214X_SPI1_IMSC);

  /* Set the initial clock frequency for indentification mode < 400kHz */

  spi_setfrequency(NULL, 400000);

  /* Enable the SPI */

  regval8 = getreg8(LPC214X_SPI1_CR1);
  putreg8(regval8 | LPC214X_SPI1CR1_SSE, LPC214X_SPI1_CR1);

  for (i = 0; i < 8; i++)
    {
      (void)getreg16(LPC214X_SPI1_DR);
    }

  return &g_spidev;
}
Пример #28
0
void up_irqinitialize(void)
{
  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);
  putreg32(0, NVIC_IRQ64_95_ENABLE);
  putreg32(0, NVIC_IRQ96_127_ENABLE);

  /* Set all interrrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ32_35_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ36_39_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ40_43_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ44_47_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ48_51_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ52_55_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ56_59_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ60_63_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ64_67_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ68_71_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ72_75_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ76_79_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ80_83_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ84_87_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ88_91_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ92_95_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ96_99_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ100_103_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ104_107_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ108_111_PRIORITY); /* K40 has 111 defined vectors */
#if NR_VECTORS > 111
  putreg32(DEFPRIORITY32, NVIC_IRQ112_115_PRIORITY); /* K60 has 120 defined vectors */
  putreg32(DEFPRIORITY32, NVIC_IRQ116_119_PRIORITY);
#endif

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(KINETIS_IRQ_SVCALL, up_svcall);
  irq_attach(KINETIS_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(KINETIS_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(KINETIS_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(KINETIS_IRQ_NMI, kinetis_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(KINETIS_IRQ_BUSFAULT, kinetis_busfault);
  irq_attach(KINETIS_IRQ_USAGEFAULT, kinetis_usagefault);
  irq_attach(KINETIS_IRQ_PENDSV, kinetis_pendsv);
  irq_attach(KINETIS_IRQ_DBGMONITOR, kinetis_dbgmonitor);
  irq_attach(KINETIS_IRQ_RESERVED, kinetis_reserved);
#endif

  kinetis_dumpnvic("initial", NR_IRQS);

  /* Initialize FIQs */

#ifdef CONFIG_ARCH_FIQ
  up_fiqinitialize();
#endif

  /* Initialize logic to support a second level of interrupt decoding for
   * configured pin interrupts.
   */
 
#ifdef CONFIG_GPIO_IRQ
  kinetis_pinirqinitialize();
#endif

  /* And finally, enable interrupts */

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  setbasepri(NVIC_SYSH_PRIORITY_MAX);
  irqrestore(0);
#endif
}
Пример #29
0
static inline void stm32_gpioremap(void)
{
#if defined(CONFIG_STM32_STM32F10XX)

  /* Remap according to the configuration within .config file */

  uint32_t val = 0;

#ifdef CONFIG_STM32_SPI1_REMAP
  val |= AFIO_MAPR_SPI1_REMAP;
#endif
#ifdef CONFIG_STM32_SPI3_REMAP
  val |= AFIO_MAPR_SPI3_REMAP;
#endif

#ifdef CONFIG_STM32_I2C1_REMAP
  val |= AFIO_MAPR_I2C1_REMAP;
#endif

#ifdef CONFIG_STM32_USART1_REMAP
  val |= AFIO_MAPR_USART1_REMAP;
#endif
#ifdef CONFIG_STM32_USART2_REMAP
  val |= AFIO_MAPR_USART2_REMAP;
#endif
#ifdef CONFIG_STM32_USART3_FULL_REMAP
  val |= AFIO_MAPR_USART3_FULLREMAP;
#endif
#ifdef CONFIG_STM32_USART3_PARTIAL_REMAP
  val |= AFIO_MAPR_USART3_PARTREMAP;
#endif

#ifdef CONFIG_STM32_TIM1_FULL_REMAP
  val |= AFIO_MAPR_TIM1_FULLREMAP;
#endif
#ifdef CONFIG_STM32_TIM1_PARTIAL_REMAP
  val |= AFIO_MAPR_TIM1_PARTREMAP;
#endif
#ifdef CONFIG_STM32_TIM2_FULL_REMAP
  val |= AFIO_MAPR_TIM2_FULLREMAP;
#endif
#ifdef CONFIG_STM32_TIM2_PARTIAL_REMAP_1
  val |= AFIO_MAPR_TIM2_PARTREMAP1;
#endif
#ifdef CONFIG_STM32_TIM2_PARTIAL_REMAP_2
  val |= AFIO_MAPR_TIM2_PARTREMAP2;
#endif
#ifdef CONFIG_STM32_TIM3_FULL_REMAP
  val |= AFIO_MAPR_TIM3_FULLREMAP;
#endif
#ifdef CONFIG_STM32_TIM3_PARTIAL_REMAP
  val |= AFIO_MAPR_TIM3_PARTREMAP;
#endif
#ifdef CONFIG_STM32_TIM4_REMAP
  val |= AFIO_MAPR_TIM4_REMAP;
#endif

#ifdef CONFIG_STM32_CAN1_REMAP1
  val |= AFIO_MAPR_PB89;
#endif
#ifdef CONFIG_STM32_CAN1_REMAP2
  val |= AFIO_MAPR_PD01;
#endif
#ifdef CONFIG_STM32_CAN2_REMAP /* Connectivity line only */
  val |= AFIO_MAPR_CAN2_REMAP;
#endif

#ifdef CONFIG_STM32_ETH_REMAP /* Connectivity line only */
  val |= AFIO_MAPR_ETH_REMAP;
#endif

#ifdef CONFIG_STM32_JTAG_FULL_ENABLE
  /* The reset default */
#elif CONFIG_STM32_JTAG_NOJNTRST_ENABLE
  val |= AFIO_MAPR_SWJ;       /* enabled but without JNTRST */
#elif CONFIG_STM32_JTAG_SW_ENABLE
  val |= AFIO_MAPR_SWDP;      /* set JTAG-DP disabled and SW-DP enabled */
#else
  val |= AFIO_MAPR_DISAB;     /* set JTAG-DP and SW-DP Disabled */
#endif

  putreg32(val, STM32_AFIO_MAPR);
#endif
}
Пример #30
0
int nuc_configgpio(gpio_cfgset_t cfgset)
{
  uintptr_t base;
  uint32_t regaddr;
  uint32_t regval;
  uint32_t isrc;
  uint32_t imd;
  uint32_t ien;
  uint32_t value;
  int port;
  int pin;

  /* Decode the port and pin.  Use the port number to get the GPIO base
   * address.
   */

  port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
  pin  = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;

  DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE);
  base = NUC_GPIO_CTRL_BASE(port);

  /* Set the GPIO PMD register */

  regaddr = base + NUC_GPIO_PMD_OFFSET;
  regval = getreg32(regaddr);
  regval &= ~GPIO_PMD_MASK(pin);

  switch (cfgset & GPIO_MODE_MASK)
    {
    default:
    case GPIO_INPUT:     /* Input */
      value = GPIO_PMD_INPUT;
      break;

    case GPIO_OUTPUT:    /* Push-pull output */
      value = GPIO_PMD_OUTPUT;
      break;

    case GPIO_OPENDRAIN: /* Open drain output */
      value = GPIO_PMD_OPENDRAIN;
      break;

    case GPIO_BIDI:      /* Quasi bi-directional */
      value = GPIO_PMD_BIDI;
      break;
    }

  regval |= GPIO_PMD(pin, value);
  putreg32(regval, regaddr);

  /* Check if we need to disable the digital input path */

  regaddr = base + NUC_GPIO_OFFD_OFFSET;
  regval  = getreg32(regaddr);
  regval &= ~GPIO_OFFD(pin);

  if ((cfgset & GPIO_ANALOG) != 0)
    {
      regval |= GPIO_OFFD(pin);
    }

  putreg32(regval, regaddr);

  /* Check if we need to enable debouncing */

  regaddr = base + NUC_GPIO_DBEN_OFFSET;
  regval  = getreg32(regaddr);
  regval &= ~GPIO_DBEN(pin);

  if ((cfgset & GPIO_DEBOUNCE) != 0)
    {
      regval |= GPIO_DBEN(pin);
    }

  putreg32(regval, regaddr);

  /* Configure interrupting pins */

  isrc = getreg32(base + NUC_GPIO_ISRC_OFFSET);
  isrc &= ~GPIO_ISRC(pin);

  imd  = getreg32(base + NUC_GPIO_IMD_OFFSET);
  imd &= ~GPIO_IMD(pin);

  ien  = getreg32(base + NUC_GPIO_IEN_OFFSET);
  ien &= ~(GPIO_IF_EN(pin) | GPIO_IR_EN(pin));

  switch (cfgset & GPIO_INTERRUPT_MASK)
    {
    case GPIO_INTERRUPT_RISING_EDGE:
      isrc |= GPIO_ISRC(pin);
      ien  |= GPIO_IR_EN(pin);
      break;

    case GPIO_INTERRUPT_FALLING_EDGE:
      isrc |= GPIO_ISRC(pin);
      ien  |= GPIO_IF_EN(pin);
      break;

    case GPIO_INTERRUPT_BOTH_EDGES:
      isrc |= GPIO_ISRC(pin);
      ien  |= (GPIO_IF_EN(pin) | GPIO_IR_EN(pin));
      break;

    case GPIO_INTERRUPT_HIGH_LEVEL:
      isrc |= GPIO_ISRC(pin);
      imd  |= GPIO_IMD(pin);
      ien  |= GPIO_IR_EN(pin);
      break;

    case GPIO_INTERRUPT_LOW_LEVEL:
      isrc |= GPIO_ISRC(pin);
      imd  |= GPIO_IMD(pin);
      ien  |= GPIO_IF_EN(pin);
      break;

    default:
      break;
    }

  putreg32(ien, base + NUC_GPIO_IEN_OFFSET);
  putreg32(imd, base + NUC_GPIO_IMD_OFFSET);
  putreg32(isrc, base + NUC_GPIO_ISRC_OFFSET);

  /* If the pin is an output, set the initial output value */

  if ((cfgset & GPIO_MODE_MASK) == GPIO_OUTPUT)
    {
      nuc_gpiowrite(cfgset, (cfgset & GPIO_OUTPUT_SET) != 0);
    }

  return 0;
}