Ejemplo n.º 1
0
void up_boot_standby_mode(void)
{
  uint32_t gpio_off_mask;
  uint32_t regval;
  int i;

  DEBUGASSERT((getreg32(STM32_PWR_CR) & PWR_CR_DBP) != 0);

  /*
   * This function is called from up_boot.c, stm32_boardinitialize(). OS is not
   * running yet. Regulators and chip-selects have been initialized. IWDG not
   * enabled. If board has HWWDG, we must enable it from this function before
   * going to standby mode.
   */

  regval = getreg32(CONFIG_STANDBYMODE_MAGIC_BKREG);
  if (regval != CONFIG_STANDBYMODE_MAGIC)
    {
      g_board_wakeup_from_standby = (regval == CONFIG_STANDBYMODE_MAGIC + 1);

      /* Standby mode was not requested, continue with regular boot. */

      putreg32(0, CONFIG_STANDBYMODE_MAGIC_BKREG);

      for (i = 0; i < 4; i++)
        up_lowputc('r');

      return;
    }

#if defined(CONFIG_STM32_DFU) || defined (CONFIG_BOARD_HALTIAN_HWWDG)
  up_irqinitialize();
#endif

  /* Go into standby mode. */

  putreg32(CONFIG_STANDBYMODE_MAGIC + 1, CONFIG_STANDBYMODE_MAGIC_BKREG);

  for (i = 0; i < 4; i++)
    up_lowputc('s');

  /* Setup bootloader to jump directly to firmware. */

  putreg32(BOARD_FIRMWARE_BASE_ADDR, CONFIG_BOOTLOADER_ADDR_BKREG);

  /* Now disable backup register access. If following interrupt handlers
   * access backup registers, they need to make sure to re-enable access. */

  stm32_pwr_enablebkp(false);

  while (true)
    {
      /* Configure SDcard pins. */

      gpio_initialize_sdcard_pins();

      /* Configure display GPIOs. */

      gpio_off_mask = ~(GPIO_PUPD_MASK | GPIO_MODE_MASK | GPIO_OUTPUT_SET);
      stm32_configgpio(GPIO_CHIP_SELECT_DISPLAY);
      stm32_configgpio(GPIO_LCD_SSD1309_CMDDATA);
      stm32_configgpio(GPIO_LCD_SSD1309_RESET);
      stm32_configgpio((GPIO_SPI2_MOSI & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT);
      stm32_configgpio((GPIO_SPI2_SCK & 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();

      /* We must kick HWWDG even from standby mode, else it resets device. */

      board_wdginitialize_autokick(hwwdg_irq_in_standby);

      /* Setup 'power'-button as EXTI for wake-up. */

      stm32_configgpio(GPIO_BTN_POWERKEY);
      stm32_gpiosetevent(GPIO_BTN_POWERKEY, true, false, true,
                         button_pressed_down_handler);

      /* Our standby-mode is really ARM core's stop-mode.
         Enter stop-mode with MCU internal regulator in low-power mode. */

      (void)stm32_pmstop(true);

      standby_do_trace('p');
    }
}
Ejemplo n.º 2
0
void stm32_boardinitialize(void)
{
#ifdef BOARD_HAS_BOOTLOADER
  /* Check if IWDG is enabled by bootloader. This is the case when
   * CONFIG_BOOTLOADER_NOWD_BKREG has lowest bit cleared.
   */

  if ((getreg32(CONFIG_BOOTLOADER_NOWD_BKREG) & 1) == 0)
    {
      int i;

      /* Bootloader has enabled IWDG. This happens after POR-reset (since
       * backup-registers have been reset to zero) and after firmware update.
       *
       * Disabling IWDG is used as early boot firmware check (new firmware
       * started). We now enable NOWD flag and do reset loop with ADDR value
       * set to application firmware.
       *
       * If firmware does not manage to do early boot and gets stuck, IWDG will
       * reset device and bootloader will either attempt to flash backup
       * firmware or will reset loop by IWDG until 'current boot try count'
       * reaches threshold and bootloader boots device to DFU-mode.
       */

      for (i = 0; i < 4; i++)
        up_lowputc('>');

      /* Enable BKREG writing. */

      stm32_pwr_enablebkp(true);

      /* Make bootloader disable IWDG. */

      putreg32(1, CONFIG_BOOTLOADER_NOWD_BKREG);

      /* Setup bootloader to jump directly to firmware. */

      putreg32(BOARD_FIRMWARE_BASE_ADDR, CONFIG_BOOTLOADER_ADDR_BKREG);

      /* Disable BKREG writing. */

      stm32_pwr_enablebkp(false);

      /* Do system reset. */

      board_systemreset();
    }
#endif /* BOARD_HAS_BOOTLOADER */

#if defined(CONFIG_ASSERT_COUNT_BKREG)
  /* Check value of assert counter (note: does not enable/disable BKREG access
   * with argument==0). */

  if (up_add_assert_count(0) >= CONFIG_ASSERT_COUNT_TO_DFU_MODE)
    {
      const char *str = "\nToo many ASSERT resets; something wrong with software. Forcing DFU mode!\n";

      while (*str)
        up_lowputc(*str++);

      up_mdelay(500);
      up_reset_to_system_bootloader();
    }
#endif

  /* Setup GPIOs based on HW version. */

  up_configure_dynamic_gpios();

  /* Configure MCU so that debugging is possible in idle modes. */

#ifdef CONFIG_STM32_KEEP_CORE_CLOCK_ENABLED_IN_IDLE_MODES
  uint32_t cr = getreg32(STM32_DBGMCU_CR);

  cr |= DBGMCU_CR_STANDBY | DBGMCU_CR_STOP | DBGMCU_CR_SLEEP;
  putreg32(cr, STM32_DBGMCU_CR);
#endif

#ifdef CONFIG_BOARD_MCO_SYSCLK
  /* Output SYSCLK to MCO pin for clock measurements. */

  stm32_configgpio(GPIO_MCO);
  stm32_mcodivconfig(RCC_CFGR_MCOSEL_SYSCLK, RCC_CFGR_MCOPRE_DIV4);
#endif

  /* Configure on-board LEDs if LED support has been selected. */

#ifdef CONFIG_ARCH_LEDS
  board_led_initialize();
#endif

  /* Configure chip-select pins. */

  board_initialize_chipselects();

  /* Configure SDcard pins (needs to be after chip-select init, to pull SDcard
   * CS down). */

  gpio_initialize_sdcard_pins();

  /* Configure power control pins. */

  board_initialize_pwrctl_pins();

  /* Initialize modem gpios. */

  up_modem_initialize_gpios();

  /* Initialize unused gpio pads. */

  gpio_initialize_unused_pads();

  /* Enable BKREG writing. */

  stm32_pwr_enablebkp(true);

  /* Reset 'current boot try count' for bootloader. */

  putreg32(0, CONFIG_BOOTLOADER_CBTC_BKREG);

  /* Make bootloader disable IWDG. */

  putreg32(1, CONFIG_BOOTLOADER_NOWD_BKREG);

  /* Check if we need to enter standby/power-off mode. */

  up_boot_standby_mode();

  /* Disable BKREG writing. */

  stm32_pwr_enablebkp(false);

  /* Force enable capsense and 9-axis for duration
   * of I2C initialization. After bus initialization
   * is done, this is undone and drivers will take care
   * of requesting power for themselves.
   */

  board_pwrctl_get(PWRCTL_SWITCH_CAPSENSE_SENSOR);
  board_pwrctl_get(PWRCTL_SWITCH_9AXIS_INERTIAL_SENSOR);

  /* Flash mass-erase can leave option-bytes is bad shape, restore defaults if
   * needed. */

  up_check_and_restore_valid_optionbytes();

  /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak function
   * stm32_spiinitialize() has been brought into the link.
   */

#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || defined(CONFIG_STM32_SPI3)
  if (stm32_spiinitialize)
    {
      stm32_spiinitialize();
    }
#endif

  /* Give early information about reset reason. */

  print_reset_reason();
}