(嵌入式 实时操作系统 rtos nuttx 7.18 stm32 源代码分析)
NuttX U盘驱动
转载请注明出处: http://blog.csdn.net/zhumaill/article/details/70175635
(code2):
NuttX U盘驱动
转载请注明出处: http://blog.csdn.net/zhumaill/article/details/70175635
1 系统启动序列中的初始化
1.1 usb otg时钟初始化:
__start() stm32_clockconfig() rcc_reset() stm32_stdclockconfig() rcc_enableperipherals() rcc_enableahb() (code1) rcc_enableapb2() rcc_enableapb1()(code1):nuttx/arch/arm/src/chip/stm32f10xxx_rcc.c
/* 使能已选的AHB外设 */ static inline void rcc_enableahb(void) { uint32_t regval; #if defined(CONFIG_STM32_CONNECTIVITYLINE) && defined(CONFIG_STM32_OTGFS) /* USB clock divider for USB OTG FS. This bit must be valid before * enabling the USB clock in the RCC_AHBENR register. This bit can't be * reset if the USB clock is enabled. */ regval = getreg32(STM32_RCC_CFGR); //STM32_RCC_CFGR = STM32_RCC_BASE + STM32_RCC_CFGR_OFFSET // = 0x40021000 + 0x0004 regval &= ~RCC_CFGR_OTGFSPRE; //RCC_CFGR_OTGFSPRE = (1 << 22) regval |= STM32_CFGR_OTGFSPRE; //STM32_CFGR_OTGFSPRE = 0 putreg32(regval, STM32_RCC_CFGR); #endif ...... #ifdef CONFIG_STM32_OTGFS /* USB OTG FS 时钟使能 */ regval |= RCC_AHBENR_OTGFSEN; //RCC_AHBENR_OTGFSEN = (1 << 12) #endif ...... putreg32(regval, STM32_RCC_AHBENR); //STM32_RCC_AHBENR = STM32_RCC_BASE + STM32_RCC_AHBENR_OFFSET // = 0x40021000 + 0x0014 }
1.2 usb otg vbus初始化:
在板级初始化时调用stm32_usbinitialize():(code2):
void stm32_usbinitialize(void) { /* The OTG FS has an internal soft pull-up. No GPIO configuration is required */ /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */ #ifdef CONFIG_STM32_OTGFS stm32_configgpio(GPIO_OTGFS_VBUS); //GPIO_OTGFS_VBUS = (GPIO_ALT|GPIO_CNF_AFPP|GPIO_MODE_50MHz|GPIO_PORTA|GPIO_PIN9) stm32_configgpio(GPIO_OTGFS_PWRON); //GPIO_OTGFS_PWRON = (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|\ // GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN8) // = 0 | 0 << 13 | 3 << 11 | 1 << 7 | 1 << 4 | 8 << 0 // stm32_configgpio(GPIO_OTGFS_OVER); #endif }
2 由用户任务调用的初始化
nsh_main() apps/examples/nsh/nsh_main.c nsh_initialize() apps/nshlib/nsh_init.c boardctl() nuttx/configs/boardctl.c board_app_initialize() nuttx/configs/shenzhou/src/stm32_appinit.c stm32_usbhost_initialize() nuttx/arch/arm/src/board/up_usb.c usbhost_msc_initialize() nuttx/drivers/usbhost/usbhost_storage.c usbhost_registerclass(&g_storage) nuttx/drivers/usbhost/usbhost_registerclass.c stm32_otgfshost_initialize(0) nuttx/arch/arm/src/chip/stm32_otgfshost.c (code3) stm32_hw_initialize(priv) nuttx/arch/arm/src/chip/stm32_otgfshost.c (code4) stm32_host_initialize(priv) nuttx/arch/arm/src/chip/stm32_otgfshost.c (code5) stm32_flush_txfifos(OTGFS_GRSTCTL_TXFNUM_HALL)nuttx/arch/arm/src/chip/stm32_otgfshost.c stm32_putreg(regval, STM32_OTGFS_GRSTCTL) nuttx/arch/arm/src/chip/stm32_otgfshost.c task_create("usbhost", CONFIG_USBHOST_DEFPRIO, CONFIG_USBHOST_STACKSIZE, (main_t)usbhost_waiter, (FAR char * const *)NULL); (code7)
2.1 usb otg gpio初始化:
(code3):FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller) { ...... stm32_sw_initialize(priv); ...... stm32_configgpio(GPIO_OTGFS_DM); stm32_configgpio(GPIO_OTGFS_DP); stm32_configgpio(GPIO_OTGFS_ID); /* Only needed for OTG */ ...... stm32_hw_initialize(priv); (code4) ...... }
2.2 usb otg硬件初始化:
(code4):static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv) { uint32_t regval; unsigned long timeout; /* Set the PHYSEL bit in the GUSBCFG register to select the OTG FS serial * transceiver: "This bit is always 1 with write-only access" */ regval = stm32_getreg(STM32_OTGFS_GUSBCFG);; //STM32_OTGFS_GUSBCFG = STM32_OTGFS_BASE + STM32_OTGFS_GUSBCFG_OFFSET // = 0x50000000 + 0x000c regval |= OTGFS_GUSBCFG_PHYSEL; //OTGFS_GUSBCFG_PHYSEL = 1 << 6 stm32_putreg(STM32_OTGFS_GUSBCFG, regval); /* Reset after a PHY select and set Host mode. First, wait for AHB master * IDLE state. */ for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) { up_udelay(3); regval = stm32_getreg(STM32_OTGFS_GRSTCTL); //STM32_OTGFS_GRSTCTL = STM32_OTGFS_BASE + STM32_OTGFS_GRSTCTL_OFFSET // = 0x50000000 + 0x0010 if ((regval & OTGFS_GRSTCTL_AHBIDL) != 0) //OTGFS_GRSTCTL_AHBIDL = 1 << 31 { break; } } /* Then perform the core soft reset. */ stm32_putreg(STM32_OTGFS_GRSTCTL, OTGFS_GRSTCTL_CSRST); //OTGFS_GRSTCTL_CSRST = 1 << 0 for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) { regval = stm32_getreg(STM32_OTGFS_GRSTCTL); if ((regval & OTGFS_GRSTCTL_CSRST) == 0) { break; }