/home/time/doc/codefile/embe/Blog/stm32/stm32h7/1gpio/bin/gpio.elf: file format elf32-littlearm Disassembly of section .text: 08000000 : 8000000: 00 00 02 20 bd 09 00 08 b9 09 00 08 b7 09 00 08 ... ............ 8000010: b7 09 00 08 b7 09 00 08 b7 09 00 08 00 00 00 00 ................ ... 800002c: b9 09 00 08 b9 09 00 08 00 00 00 00 b9 09 00 08 ................ 800003c: c9 04 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800004c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800005c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800006c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800007c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800008c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800009c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80000ac: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80000bc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80000cc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80000dc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80000ec: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80000fc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800010c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800011c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800012c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800013c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800014c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800015c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800016c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800017c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800018c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800019c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80001ac: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80001bc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80001cc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80001dc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80001ec: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 80001fc: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800020c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800021c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800022c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800023c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800024c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800025c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800026c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800027c: b7 09 00 08 b7 09 00 08 b7 09 00 08 b7 09 00 08 ................ 800028c: b7 09 00 08 b7 09 00 08 b7 09 00 08 ............ 08000298 : * 在多任务系统中,如果多个任务访问同一GPIO,可能需要添加同步机制。 * * @see rcc_periph_clock_enable(), gpio_mode_setup(), gpio_set_output_options(), gpio_clear() */ void user_gpio_setup(void) { 8000298: b580 push {r7, lr} 800029a: af00 add r7, sp, #0 // 使能GPIOE端口的时钟,必须先使能时钟才能配置和使用该端口的引脚 rcc_periph_clock_enable(RCC_GPIOE); 800029c: f641 4004 movw r0, #7172 @ 0x1c04 80002a0: f000 fb7c bl 800099c // 配置GPIOE端口的引脚3为输出模式,不使用上拉或下拉电阻 gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3); 80002a4: 2308 movs r3, #8 80002a6: 2200 movs r2, #0 80002a8: 2101 movs r1, #1 80002aa: 4810 ldr r0, [pc, #64] @ (80002ec ) 80002ac: f000 f92b bl 8000506 // 设置GPIOE端口引脚3的输出选项:推挽输出类型,速度为2MHz gpio_set_output_options(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO3); 80002b0: 2308 movs r3, #8 80002b2: 2200 movs r2, #0 80002b4: 2100 movs r1, #0 80002b6: 480d ldr r0, [pc, #52] @ (80002ec ) 80002b8: f000 f945 bl 8000546 // 将GPIOE端口引脚3设置为低电平,也就是灯灭 gpio_clear(GPIOE, GPIO3); 80002bc: 2108 movs r1, #8 80002be: 480b ldr r0, [pc, #44] @ (80002ec ) 80002c0: f000 f912 bl 80004e8 // 使能备份域访问,通过设置电源控制寄存器1的DBP位 // 这是访问RTC、备份寄存器等备份域外设的必要步骤 // PC13-PC15是备份域的GPIO引脚,需要使能备份域访问才能配置这些引脚 PWR_CR1 |= PWR_CR1_DBP; 80002c4: 4b0a ldr r3, [pc, #40] @ (80002f0 ) 80002c6: 681b ldr r3, [r3, #0] 80002c8: 4a09 ldr r2, [pc, #36] @ (80002f0 ) 80002ca: f443 7380 orr.w r3, r3, #256 @ 0x100 80002ce: 6013 str r3, [r2, #0] // 使能GPIOC端口的时钟,必须先使能时钟才能配置和使用该端口的引脚 rcc_periph_clock_enable(RCC_GPIOC); 80002d0: f641 4002 movw r0, #7170 @ 0x1c02 80002d4: f000 fb62 bl 800099c // 配置GPIOC端口的引脚13为输入模式,并启用下拉电阻 gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO13); 80002d8: f44f 5300 mov.w r3, #8192 @ 0x2000 80002dc: 2202 movs r2, #2 80002de: 2100 movs r1, #0 80002e0: 4804 ldr r0, [pc, #16] @ (80002f4 ) 80002e2: f000 f910 bl 8000506 } 80002e6: bf00 nop 80002e8: bd80 pop {r7, pc} 80002ea: bf00 nop 80002ec: 58021000 .word 0x58021000 80002f0: 58024800 .word 0x58024800 80002f4: 58020800 .word 0x58020800 080002f8
: * * @see scb_set_priority_grouping(), system_clock_setup(), systick_init(), * user_gpio_setup(), user_delay_ms(), gpio_get(), gpio_toggle() */ int main(void) { 80002f8: b580 push {r7, lr} 80002fa: af00 add r7, sp, #0 // 设置中断优先级分组为16个主优先级,无子优先级 // 这意味着每个中断都有独立的优先级,没有子优先级用于同一优先级中断的排序 scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_GROUP16_NOSUB); 80002fc: f44f 7040 mov.w r0, #768 @ 0x300 8000300: f000 fbcf bl 8000aa2 // 初始化系统时钟配置 system_clock_setup(); 8000304: f000 f82c bl 8000360 // 初始化SysTick定时器,参数1000U表示每秒产生1000次中断,即每1ms一次 systick_init(1000U); 8000308: f44f 707a mov.w r0, #1000 @ 0x3e8 800030c: f000 f8bc bl 8000488 // 初始化用户GPIO引脚配置 // 根据gpio的代码,这包括配置PE3为输出(LED)和PC13为输入(按钮) user_gpio_setup(); 8000310: f7ff ffc2 bl 8000298 // 主循环,程序将在此无限循环 while (1) { // 检测PC13引脚(按钮)的状态,如果为高电平(按钮按下)则执行以下代码 if(gpio_get(GPIOC, GPIO13)) 8000314: f44f 5100 mov.w r1, #8192 @ 0x2000 8000318: 480f ldr r0, [pc, #60] @ (8000358 ) 800031a: f000 f8e8 bl 80004ee 800031e: 4603 mov r3, r0 8000320: 2b00 cmp r3, #0 8000322: d0f7 beq.n 8000314 { // 延时20ms,用于按钮消抖 // 按钮在按下和释放时会产生机械抖动,延时可以避免误检测 user_delay_ms(20); 8000324: 2014 movs r0, #20 8000326: f000 f895 bl 8000454 // 再次检测按钮状态,确认按钮确实被按下(不是抖动) if(gpio_get(GPIOC, GPIO13)) 800032a: f44f 5100 mov.w r1, #8192 @ 0x2000 800032e: 480a ldr r0, [pc, #40] @ (8000358 ) 8000330: f000 f8dd bl 80004ee 8000334: 4603 mov r3, r0 8000336: 2b00 cmp r3, #0 8000338: d003 beq.n 8000342 { // 切换PE3引脚(LED)的状态 // 如果LED当前是亮的状态,则熄灭;如果是灭的状态,则点亮 gpio_toggle(GPIOE, GPIO3); 800033a: 2108 movs r1, #8 800033c: 4807 ldr r0, [pc, #28] @ (800035c ) 800033e: f000 f8d9 bl 80004f4 } // 等待按钮释放 // 这是一个空循环,一直检测直到按钮被释放(PC13变为低电平) // 这样可以防止在按钮按住期间多次触发LED切换 while(gpio_get(GPIOC, GPIO13)); 8000342: bf00 nop 8000344: f44f 5100 mov.w r1, #8192 @ 0x2000 8000348: 4803 ldr r0, [pc, #12] @ (8000358 ) 800034a: f000 f8d0 bl 80004ee 800034e: 4603 mov r3, r0 8000350: 2b00 cmp r3, #0 8000352: d1f7 bne.n 8000344 if(gpio_get(GPIOC, GPIO13)) 8000354: e7de b.n 8000314 8000356: bf00 nop 8000358: 58020800 .word 0x58020800 800035c: 58021000 .word 0x58021000 08000360 : * * @see rcc_periph_clock_enable(), gpio_mode_setup(), gpio_set_output_options(), * gpio_set(), rcc_clock_setup_pll() */ static void system_clock_setup(void) { 8000360: b580 push {r7, lr} 8000362: b08c sub sp, #48 @ 0x30 8000364: af00 add r7, sp, #0 // 初始化PLL配置结构体,所有成员清零 struct rcc_pll_config pll_config = {0}; 8000366: 463b mov r3, r7 8000368: 222c movs r2, #44 @ 0x2c 800036a: 2100 movs r1, #0 800036c: 4618 mov r0, r3 800036e: f000 fc91 bl 8000c94 // 使能GPIOH端口时钟,用于配置GPIOH1引脚 // OSC_IN是GPIOH0,OSC_OUT是GPIOH1 rcc_periph_clock_enable(RCC_GPIOH); 8000372: f641 4007 movw r0, #7175 @ 0x1c07 8000376: f000 fb11 bl 800099c // 使能SYSCFG时钟,用于系统配置 rcc_periph_clock_enable(RCC_SYSCFG); 800037a: f641 6081 movw r0, #7809 @ 0x1e81 800037e: f000 fb0d bl 800099c // 配置GPIOH1引脚为输出模式,启用上拉电阻 gpio_mode_setup(GPIOH, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO1); 8000382: 2302 movs r3, #2 8000384: 2201 movs r2, #1 8000386: 2101 movs r1, #1 8000388: 4830 ldr r0, [pc, #192] @ (800044c ) 800038a: f000 f8bc bl 8000506 // 设置GPIOH1引脚为推挽输出,速度为50MHz gpio_set_output_options(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO1); 800038e: 2302 movs r3, #2 8000390: 2202 movs r2, #2 8000392: 2100 movs r1, #0 8000394: 482d ldr r0, [pc, #180] @ (800044c ) 8000396: f000 f8d6 bl 8000546 // 短暂延时,确保GPIO配置稳定 for (unsigned i = 0; i < 20; i++) 800039a: 2300 movs r3, #0 800039c: 62fb str r3, [r7, #44] @ 0x2c 800039e: e003 b.n 80003a8 { __asm__("nop"); // 空操作指令,用于延时 80003a0: bf00 nop for (unsigned i = 0; i < 20; i++) 80003a2: 6afb ldr r3, [r7, #44] @ 0x2c 80003a4: 3301 adds r3, #1 80003a6: 62fb str r3, [r7, #44] @ 0x2c 80003a8: 6afb ldr r3, [r7, #44] @ 0x2c 80003aa: 2b13 cmp r3, #19 80003ac: d9f8 bls.n 80003a0 } // 将GPIOH1引脚设置为高电平 gpio_set(GPIOH, GPIO1); 80003ae: 2102 movs r1, #2 80003b0: 4826 ldr r0, [pc, #152] @ (800044c ) 80003b2: f000 f897 bl 80004e4 // 设置系统时钟源为PLL pll_config.sysclock_source = RCC_PLL; 80003b6: 2300 movs r3, #0 80003b8: 703b strb r3, [r7, #0] // 设置PLL时钟源为外部高速晶振(HSE) pll_config.pll_source = RCC_PLLCKSELR_PLLSRC_HSE; 80003ba: 2302 movs r3, #2 80003bc: 707b strb r3, [r7, #1] // 设置HSE频率为25MHz pll_config.hse_frequency = 25000000U; 80003be: 4b24 ldr r3, [pc, #144] @ (8000450 ) 80003c0: 607b str r3, [r7, #4] // 配置PLL1参数,这一部分可以和CubeMX进行一一对应 // 系统时钟频率 = HSE / M * N / P = 25MHz / 5 * 192 / 2 = 480MHz pll_config.pll1.divm = 5; 80003c2: 2305 movs r3, #5 80003c4: 723b strb r3, [r7, #8] pll_config.pll1.divn = 192; 80003c6: 23c0 movs r3, #192 @ 0xc0 80003c8: 817b strh r3, [r7, #10] pll_config.pll1.divp = 2; 80003ca: 2302 movs r3, #2 80003cc: 733b strb r3, [r7, #12] pll_config.pll1.divq = 2; 80003ce: 2302 movs r3, #2 80003d0: 737b strb r3, [r7, #13] pll_config.pll1.divr = 2; 80003d2: 2302 movs r3, #2 80003d4: 73bb strb r3, [r7, #14] // 配置PLL2参数 pll_config.pll2.divm = 32; 80003d6: 2320 movs r3, #32 80003d8: 743b strb r3, [r7, #16] pll_config.pll2.divn = 129; 80003da: 2381 movs r3, #129 @ 0x81 80003dc: 827b strh r3, [r7, #18] pll_config.pll2.divp = 2; 80003de: 2302 movs r3, #2 80003e0: 753b strb r3, [r7, #20] pll_config.pll2.divq = 2; 80003e2: 2302 movs r3, #2 80003e4: 757b strb r3, [r7, #21] pll_config.pll2.divr = 2; 80003e6: 2302 movs r3, #2 80003e8: 75bb strb r3, [r7, #22] // 配置PLL3参数 pll_config.pll3.divm = 32; 80003ea: 2320 movs r3, #32 80003ec: 763b strb r3, [r7, #24] pll_config.pll3.divn = 129; 80003ee: 2381 movs r3, #129 @ 0x81 80003f0: 837b strh r3, [r7, #26] pll_config.pll3.divp = 2; 80003f2: 2302 movs r3, #2 80003f4: 773b strb r3, [r7, #28] pll_config.pll3.divq = 2; 80003f6: 2302 movs r3, #2 80003f8: 777b strb r3, [r7, #29] pll_config.pll3.divr = 2; 80003fa: 2302 movs r3, #2 80003fc: 77bb strb r3, [r7, #30] // 配置系统时钟分频参数,还是可以和CubeMX进行一一对应 pll_config.core_pre = RCC_D1CFGR_D1CPRE_BYP; // CPU核心时钟不分频 80003fe: 2300 movs r3, #0 8000400: f887 3020 strb.w r3, [r7, #32] pll_config.hpre = RCC_D1CFGR_D1HPRE_DIV2; // AHB总线时钟2分频 8000404: 2308 movs r3, #8 8000406: f887 3021 strb.w r3, [r7, #33] @ 0x21 pll_config.ppre1 = RCC_D2CFGR_D2PPRE_DIV2; // APB1总线时钟2分频 800040a: 2304 movs r3, #4 800040c: f887 3022 strb.w r3, [r7, #34] @ 0x22 pll_config.ppre2 = RCC_D2CFGR_D2PPRE_DIV2; // APB2总线时钟2分频 8000410: 2304 movs r3, #4 8000412: f887 3023 strb.w r3, [r7, #35] @ 0x23 pll_config.ppre3 = RCC_D1CFGR_D1PPRE_DIV2; // APB3总线时钟2分频 8000416: 2304 movs r3, #4 8000418: f887 3024 strb.w r3, [r7, #36] @ 0x24 pll_config.ppre4 = RCC_D3CFGR_D3PPRE_DIV2; // APB4总线时钟2分频 800041c: 2304 movs r3, #4 800041e: f887 3025 strb.w r3, [r7, #37] @ 0x25 // 设置Flash等待状态为4个周期,确保在480MHz系统时钟下能正确访问Flash pll_config.flash_waitstates = FLASH_ACR_LATENCY_4WS; 8000422: 2304 movs r3, #4 8000424: f887 3026 strb.w r3, [r7, #38] @ 0x26 // 配置电压缩放和电源模式 pll_config.voltage_scale = PWR_VOS_SCALE_0; // 电压缩放级别0,最高性能模式 8000428: 2301 movs r3, #1 800042a: f887 3027 strb.w r3, [r7, #39] @ 0x27 pll_config.power_mode = PWR_SYS_LDO; // 使用LDO(低压差线性稳压器)电源模式 800042e: 2302 movs r3, #2 8000430: f887 3028 strb.w r3, [r7, #40] @ 0x28 pll_config.smps_level = 0; // SMPS(开关模式电源)级别 8000434: 2300 movs r3, #0 8000436: f887 3029 strb.w r3, [r7, #41] @ 0x29 // 应用PLL配置,完成系统时钟设置 rcc_clock_setup_pll(&pll_config); 800043a: 463b mov r3, r7 800043c: 4618 mov r0, r3 800043e: f000 f963 bl 8000708 } 8000442: bf00 nop 8000444: 3730 adds r7, #48 @ 0x30 8000446: 46bd mov sp, r7 8000448: bd80 pop {r7, pc} 800044a: bf00 nop 800044c: 58021c00 .word 0x58021c00 8000450: 017d7840 .word 0x017d7840 08000454 : * 最大延时时间受限于32位无符号整数的最大值(约49.7天)。 * * @see systick, __WFI() */ void user_delay_ms(uint32_t ms) { 8000454: b480 push {r7} 8000456: b085 sub sp, #20 8000458: af00 add r7, sp, #0 800045a: 6078 str r0, [r7, #4] // 记录开始延时的时刻(systick的当前值) uint32_t start = systick; 800045c: 4b09 ldr r3, [pc, #36] @ (8000484 ) 800045e: 681b ldr r3, [r3, #0] 8000460: 60fb str r3, [r7, #12] // 循环等待,直到经过的时间达到指定的毫秒数 while (systick - start < ms) 8000462: e001 b.n 8000468 __asm volatile("wfi"); 8000464: bf30 wfi } 8000466: bf00 nop while (systick - start < ms) 8000468: 4b06 ldr r3, [pc, #24] @ (8000484 ) 800046a: 681a ldr r2, [r3, #0] 800046c: 68fb ldr r3, [r7, #12] 800046e: 1ad3 subs r3, r2, r3 8000470: 687a ldr r2, [r7, #4] 8000472: 429a cmp r2, r3 8000474: d8f6 bhi.n 8000464 { // 进入低功耗模式,等待中断唤醒,有助于在延时时降低CPU功耗 __WFI(); } } 8000476: bf00 nop 8000478: bf00 nop 800047a: 3714 adds r7, #20 800047c: 46bd mov sp, r7 800047e: f85d 7b04 ldr.w r7, [sp], #4 8000482: 4770 bx lr 8000484: 20000024 .word 0x20000024 08000488 : * 此函数会覆盖任何之前的SysTick配置,包括中断处理函数的注册。 * * @see sys_tick_handler(), systick, user_delay_ms() */ void systick_init(uint32_t ticks) { 8000488: b580 push {r7, lr} 800048a: b082 sub sp, #8 800048c: af00 add r7, sp, #0 800048e: 6078 str r0, [r7, #4] // 设置SysTick时钟源为AHB总线时钟 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); 8000490: 2004 movs r0, #4 8000492: f000 fae9 bl 8000a68 // 计算重载值:总线频率除以定时器周期数减1 systick_set_reload((rcc_get_bus_clk_freq(RCC_CPUCLK) / ticks) - 1UL); 8000496: 2000 movs r0, #0 8000498: f000 fa42 bl 8000920 800049c: 4602 mov r2, r0 800049e: 687b ldr r3, [r7, #4] 80004a0: fbb2 f3f3 udiv r3, r2, r3 80004a4: 3b01 subs r3, #1 80004a6: 4618 mov r0, r3 80004a8: f000 fad8 bl 8000a5c // 清除SysTick当前值寄存器(被注释掉的代码) //STK_CVR = 0UL; // 使用函数方式清除SysTick计数器 systick_clear(); 80004ac: f000 faf4 bl 8000a98 // 设置SysTick中断优先级为15(最低优先级) nvic_set_priority(NVIC_SYSTICK_IRQ, 15); 80004b0: 210f movs r1, #15 80004b2: 20ff movs r0, #255 @ 0xff 80004b4: f000 fafe bl 8000ab4 // 使用函数方式配置SysTick控制寄存器(被注释掉的代码) // STK_CSR = STK_CSR_CLKSOURCE | STK_CSR_TICKINT | STK_CSR_ENABLE; // 分别使能SysTick中断和计数器 systick_interrupt_enable(); 80004b8: f000 fae0 bl 8000a7c systick_counter_enable(); 80004bc: f000 fae5 bl 8000a8a } 80004c0: bf00 nop 80004c2: 3708 adds r7, #8 80004c4: 46bd mov sp, r7 80004c6: bd80 pop {r7, pc} 080004c8 : * 如果systick变量在多线程/多任务环境中被访问,可能需要添加适当的同步机制。 * * @see systick, systick_init(), user_delay_ms() */ void sys_tick_handler(void) { 80004c8: b480 push {r7} 80004ca: af00 add r7, sp, #0 systick++; 80004cc: 4b04 ldr r3, [pc, #16] @ (80004e0 ) 80004ce: 681b ldr r3, [r3, #0] 80004d0: 3301 adds r3, #1 80004d2: 4a03 ldr r2, [pc, #12] @ (80004e0 ) 80004d4: 6013 str r3, [r2, #0] } 80004d6: bf00 nop 80004d8: 46bd mov sp, r7 80004da: f85d 7b04 ldr.w r7, [sp], #4 80004de: 4770 bx lr 80004e0: 20000024 .word 0x20000024 080004e4 : If multiple pins are to be changed, use bitwise OR '|' to separate them. */ void gpio_set(uint32_t gpioport, uint16_t gpios) { GPIO_BSRR(gpioport) = gpios; 80004e4: 6181 str r1, [r0, #24] } 80004e6: 4770 bx lr 080004e8 : If multiple pins are to be changed, use bitwise OR '|' to separate them. */ void gpio_clear(uint32_t gpioport, uint16_t gpios) { GPIO_BSRR(gpioport) = (gpios << 16); 80004e8: 0409 lsls r1, r1, #16 80004ea: 6181 str r1, [r0, #24] } 80004ec: 4770 bx lr 080004ee : @param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id @return Unsigned int16. The value held in the specified GPIO port. */ uint16_t gpio_port_read(uint32_t gpioport) { return (uint16_t)GPIO_IDR(gpioport); 80004ee: 6900 ldr r0, [r0, #16] } 80004f0: 4008 ands r0, r1 80004f2: 4770 bx lr 080004f4 : uint32_t port = GPIO_ODR(gpioport); 80004f4: 6943 ldr r3, [r0, #20] GPIO_BSRR(gpioport) = ((port & gpios) << 16) | (~port & gpios); 80004f6: ea01 0203 and.w r2, r1, r3 80004fa: ea21 0103 bic.w r1, r1, r3 80004fe: ea41 4102 orr.w r1, r1, r2, lsl #16 8000502: 6181 str r1, [r0, #24] } 8000504: 4770 bx lr 08000506 : If multiple pins are to be set, use bitwise OR '|' to separate them. */ void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t pull_up_down, uint16_t gpios) { 8000506: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} /* * We want to set the config only for the pins mentioned in gpios, * but keeping the others, so read out the actual config first. */ moder = GPIO_MODER(gpioport); 800050a: 6805 ldr r5, [r0, #0] pupd = GPIO_PUPDR(gpioport); 800050c: 2600 movs r6, #0 800050e: 68c4 ldr r4, [r0, #12] for (i = 0; i < 16; i++) { if (!((1 << i) & gpios)) { continue; } moder &= ~GPIO_MODE_MASK(i); 8000510: f04f 0e03 mov.w lr, #3 if (!((1 << i) & gpios)) { 8000514: fa43 f706 asr.w r7, r3, r6 8000518: 07ff lsls r7, r7, #31 800051a: d50d bpl.n 8000538 moder &= ~GPIO_MODE_MASK(i); 800051c: 0077 lsls r7, r6, #1 800051e: fa0e fc07 lsl.w ip, lr, r7 moder |= GPIO_MODE(i, mode); 8000522: fa01 f807 lsl.w r8, r1, r7 pupd &= ~GPIO_PUPD_MASK(i); pupd |= GPIO_PUPD(i, pull_up_down); 8000526: fa02 f707 lsl.w r7, r2, r7 moder &= ~GPIO_MODE_MASK(i); 800052a: ea25 050c bic.w r5, r5, ip pupd &= ~GPIO_PUPD_MASK(i); 800052e: ea24 040c bic.w r4, r4, ip moder |= GPIO_MODE(i, mode); 8000532: ea48 0505 orr.w r5, r8, r5 pupd |= GPIO_PUPD(i, pull_up_down); 8000536: 433c orrs r4, r7 for (i = 0; i < 16; i++) { 8000538: 3601 adds r6, #1 800053a: 2e10 cmp r6, #16 800053c: d1ea bne.n 8000514 } /* Set mode and pull up/down control registers. */ GPIO_MODER(gpioport) = moder; 800053e: 6005 str r5, [r0, #0] GPIO_PUPDR(gpioport) = pupd; 8000540: 60c4 str r4, [r0, #12] } 8000542: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} 08000546 : uint16_t gpios) { uint16_t i; uint32_t ospeedr; if (otype == 0x1) { 8000546: 2901 cmp r1, #1 GPIO_OTYPER(gpioport) |= gpios; 8000548: 6841 ldr r1, [r0, #4] 800054a: bf0c ite eq 800054c: 4319 orreq r1, r3 } else { GPIO_OTYPER(gpioport) &= ~gpios; 800054e: 4399 bicne r1, r3 { 8000550: b5f0 push {r4, r5, r6, r7, lr} GPIO_OTYPER(gpioport) &= ~gpios; 8000552: 6041 str r1, [r0, #4] } ospeedr = GPIO_OSPEEDR(gpioport); 8000554: 2400 movs r4, #0 8000556: 6881 ldr r1, [r0, #8] for (i = 0; i < 16; i++) { if (!((1 << i) & gpios)) { continue; } ospeedr &= ~GPIO_OSPEED_MASK(i); 8000558: 2603 movs r6, #3 if (!((1 << i) & gpios)) { 800055a: fa43 f504 asr.w r5, r3, r4 800055e: 07ed lsls r5, r5, #31 8000560: d507 bpl.n 8000572 ospeedr &= ~GPIO_OSPEED_MASK(i); 8000562: 0065 lsls r5, r4, #1 8000564: fa06 f705 lsl.w r7, r6, r5 ospeedr |= GPIO_OSPEED(i, speed); 8000568: fa02 f505 lsl.w r5, r2, r5 ospeedr &= ~GPIO_OSPEED_MASK(i); 800056c: ea21 0107 bic.w r1, r1, r7 ospeedr |= GPIO_OSPEED(i, speed); 8000570: 4329 orrs r1, r5 for (i = 0; i < 16; i++) { 8000572: 3401 adds r4, #1 8000574: 2c10 cmp r4, #16 8000576: d1f0 bne.n 800055a } GPIO_OSPEEDR(gpioport) = ospeedr; 8000578: 6081 str r1, [r0, #8] } 800057a: bdf0 pop {r4, r5, r6, r7, pc} 0800057c : .per.pclk2_mhz = RCC_HSI_BASE_FREQUENCY / HZ_PER_MHZ, .per.pclk3_mhz = RCC_HSI_BASE_FREQUENCY / HZ_PER_MHZ, .per.pclk4_mhz = RCC_HSI_BASE_FREQUENCY / HZ_PER_MHZ }; static void rcc_configure_pll(uint32_t clkin, const struct pll_config *config, int pll_num) { 800057c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} /* Only concern ourselves with the PLL if the input clock is enabled. */ if (config->divm == 0 || pll_num < 1 || pll_num > 3) { 8000580: f891 c000 ldrb.w ip, [r1] 8000584: f1bc 0f00 cmp.w ip, #0 8000588: f000 80a5 beq.w 80006d6 return; } struct pll_clocks *pll_tree_ptr; if (pll_num == 1) { 800058c: 2a01 cmp r2, #1 800058e: d026 beq.n 80005de pll_tree_ptr = &rcc_clock_tree.pll1; } else if (pll_num == 2) { pll_tree_ptr = &rcc_clock_tree.pll2; 8000590: 4b57 ldr r3, [pc, #348] @ (80006f0 ) 8000592: 1f9e subs r6, r3, #6 8000594: 2a02 cmp r2, #2 8000596: bf18 it ne 8000598: 461e movne r6, r3 } else { pll_tree_ptr = &rcc_clock_tree.pll3; } /* Let's write all of the dividers as specified. */ RCC_PLLDIVR(pll_num) = 0; 800059a: 3a01 subs r2, #1 800059c: 4d55 ldr r5, [pc, #340] @ (80006f4 ) 800059e: 2300 movs r3, #0 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVN(config->divn); 80005a0: f8b1 8002 ldrh.w r8, [r1, #2] RCC_PLLDIVR(pll_num) = 0; 80005a4: f845 3032 str.w r3, [r5, r2, lsl #3] RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVN(config->divn); 80005a8: f108 33ff add.w r3, r8, #4294967295 @ 0xffffffff 80005ac: f855 4032 ldr.w r4, [r5, r2, lsl #3] 80005b0: 4323 orrs r3, r4 /* Setup the PLL config values for this PLL. */ uint8_t vco_addshift = 4 * (pll_num - 1); /* Values spaced by 4 for PLL 1/2/3 */ 80005b2: b2d4 uxtb r4, r2 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVN(config->divn); 80005b4: f845 3032 str.w r3, [r5, r2, lsl #3] uint8_t vco_addshift = 4 * (pll_num - 1); /* Values spaced by 4 for PLL 1/2/3 */ 80005b8: 00a7 lsls r7, r4, #2 /* Set the PLL input frequency range. */ uint32_t pll_clk_mhz = (clkin / config->divm) / HZ_PER_MHZ; 80005ba: fbb0 f3fc udiv r3, r0, ip 80005be: 484e ldr r0, [pc, #312] @ (80006f8 ) uint8_t vco_addshift = 4 * (pll_num - 1); /* Values spaced by 4 for PLL 1/2/3 */ 80005c0: b2ff uxtb r7, r7 uint32_t pll_clk_mhz = (clkin / config->divm) / HZ_PER_MHZ; 80005c2: fbb3 fcf0 udiv ip, r3, r0 if (pll_clk_mhz > 2 && pll_clk_mhz <= 4) { 80005c6: f1ac 0003 sub.w r0, ip, #3 80005ca: 2801 cmp r0, #1 80005cc: 484b ldr r0, [pc, #300] @ (80006fc ) 80005ce: d808 bhi.n 80005e2 RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_2_4MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 80005d0: 2304 movs r3, #4 80005d2: f8d0 e42c ldr.w lr, [r0, #1068] @ 0x42c 80005d6: 40bb lsls r3, r7 } else if (pll_clk_mhz > 4 && pll_clk_mhz <= 8) { RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_4_8MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; } else if (pll_clk_mhz > 8) { RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_8_16MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 80005d8: ea4e 0303 orr.w r3, lr, r3 80005dc: e00d b.n 80005fa pll_tree_ptr = &rcc_clock_tree.pll1; 80005de: 4e48 ldr r6, [pc, #288] @ (8000700 ) 80005e0: e7db b.n 800059a } else if (pll_clk_mhz > 4 && pll_clk_mhz <= 8) { 80005e2: f1ac 0e05 sub.w lr, ip, #5 80005e6: f1be 0f03 cmp.w lr, #3 80005ea: d876 bhi.n 80006da RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_4_8MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 80005ec: 2308 movs r3, #8 80005ee: f8d0 942c ldr.w r9, [r0, #1068] @ 0x42c 80005f2: fa03 fe07 lsl.w lr, r3, r7 80005f6: ea4e 0309 orr.w r3, lr, r9 RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_8_16MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 80005fa: f8c0 342c str.w r3, [r0, #1068] @ 0x42c } /* Set the VCO output frequency range. */ uint32_t pll_vco_clk_mhz = (pll_clk_mhz * config->divn); 80005fe: fb0c f308 mul.w r3, ip, r8 if (pll_vco_clk_mhz <= 420) { 8000602: f5b3 7fd2 cmp.w r3, #420 @ 0x1a4 8000606: d809 bhi.n 800061c RCC_PLLCFGR |= (RCC_PLLCFGR_PLL1VCO_MED << vco_addshift); 8000608: f8df c0f0 ldr.w ip, [pc, #240] @ 80006fc 800060c: 2002 movs r0, #2 800060e: f8dc e42c ldr.w lr, [ip, #1068] @ 0x42c 8000612: 40b8 lsls r0, r7 8000614: ea40 000e orr.w r0, r0, lr 8000618: f8cc 042c str.w r0, [ip, #1068] @ 0x42c } /* Setup the enable bits for the PLL outputs. */ uint8_t diven_addshift = 3 * (pll_num - 1); /* Values spaced by 3 for PLL1/2/3 */ 800061c: 0067 lsls r7, r4, #1 if (config->divp > 0) { 800061e: 7908 ldrb r0, [r1, #4] uint8_t diven_addshift = 3 * (pll_num - 1); /* Values spaced by 3 for PLL1/2/3 */ 8000620: eb04 0444 add.w r4, r4, r4, lsl #1 8000624: b2e4 uxtb r4, r4 if (config->divp > 0) { 8000626: b1b0 cbz r0, 8000656 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVP(config->divp); 8000628: f855 c032 ldr.w ip, [r5, r2, lsl #3] 800062c: f100 3eff add.w lr, r0, #4294967295 @ 0xffffffff 8000630: ea4c 2c4e orr.w ip, ip, lr, lsl #9 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVP1EN << diven_addshift); 8000634: f8df e0c4 ldr.w lr, [pc, #196] @ 80006fc RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVP(config->divp); 8000638: f845 c032 str.w ip, [r5, r2, lsl #3] RCC_PLLCFGR |= (RCC_PLLCFGR_DIVP1EN << diven_addshift); 800063c: f44f 3c80 mov.w ip, #65536 @ 0x10000 8000640: f8de 842c ldr.w r8, [lr, #1068] @ 0x42c 8000644: fa0c fc04 lsl.w ip, ip, r4 pll_tree_ptr->p_mhz = pll_vco_clk_mhz / config->divp; 8000648: fbb3 f0f0 udiv r0, r3, r0 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVP1EN << diven_addshift); 800064c: ea4c 0c08 orr.w ip, ip, r8 8000650: f8ce c42c str.w ip, [lr, #1068] @ 0x42c pll_tree_ptr->p_mhz = pll_vco_clk_mhz / config->divp; 8000654: 8030 strh r0, [r6, #0] } if (config->divq > 0) { 8000656: 7948 ldrb r0, [r1, #5] 8000658: b1b0 cbz r0, 8000688 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVQ(config->divq); 800065a: f855 c032 ldr.w ip, [r5, r2, lsl #3] 800065e: f100 3eff add.w lr, r0, #4294967295 @ 0xffffffff 8000662: ea4c 4c0e orr.w ip, ip, lr, lsl #16 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVQ1EN << diven_addshift); 8000666: f8df e094 ldr.w lr, [pc, #148] @ 80006fc RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVQ(config->divq); 800066a: f845 c032 str.w ip, [r5, r2, lsl #3] RCC_PLLCFGR |= (RCC_PLLCFGR_DIVQ1EN << diven_addshift); 800066e: f44f 3c00 mov.w ip, #131072 @ 0x20000 8000672: f8de 842c ldr.w r8, [lr, #1068] @ 0x42c 8000676: fa0c fc04 lsl.w ip, ip, r4 pll_tree_ptr->q_mhz = pll_vco_clk_mhz / config->divq; 800067a: fbb3 f0f0 udiv r0, r3, r0 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVQ1EN << diven_addshift); 800067e: ea4c 0c08 orr.w ip, ip, r8 8000682: f8ce c42c str.w ip, [lr, #1068] @ 0x42c pll_tree_ptr->q_mhz = pll_vco_clk_mhz / config->divq; 8000686: 8070 strh r0, [r6, #2] } if (config->divr > 0) { 8000688: 7989 ldrb r1, [r1, #6] 800068a: b199 cbz r1, 80006b4 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVR(config->divr); 800068c: f855 0032 ldr.w r0, [r5, r2, lsl #3] 8000690: f101 3cff add.w ip, r1, #4294967295 @ 0xffffffff 8000694: ea40 600c orr.w r0, r0, ip, lsl #24 8000698: f845 0032 str.w r0, [r5, r2, lsl #3] RCC_PLLCFGR |= (RCC_PLLCFGR_DIVR1EN << diven_addshift); 800069c: f44f 2280 mov.w r2, #262144 @ 0x40000 80006a0: 4816 ldr r0, [pc, #88] @ (80006fc ) 80006a2: 40a2 lsls r2, r4 80006a4: f8d0 542c ldr.w r5, [r0, #1068] @ 0x42c pll_tree_ptr->r_mhz = pll_vco_clk_mhz / config->divr; 80006a8: fbb3 f3f1 udiv r3, r3, r1 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVR1EN << diven_addshift); 80006ac: 432a orrs r2, r5 80006ae: f8c0 242c str.w r2, [r0, #1068] @ 0x42c pll_tree_ptr->r_mhz = pll_vco_clk_mhz / config->divr; 80006b2: 80b3 strh r3, [r6, #4] } /* Attempt to enable and lock PLL. */ uint8_t cr_addshift = 2 * (pll_num - 1); RCC_CR |= RCC_CR_PLL1ON << cr_addshift; 80006b4: 4a11 ldr r2, [pc, #68] @ (80006fc ) 80006b6: b2ff uxtb r7, r7 80006b8: f04f 7380 mov.w r3, #16777216 @ 0x1000000 80006bc: f8d2 1400 ldr.w r1, [r2, #1024] @ 0x400 80006c0: 40bb lsls r3, r7 80006c2: 430b orrs r3, r1 80006c4: f8c2 3400 str.w r3, [r2, #1024] @ 0x400 while (!(RCC_CR & (RCC_CR_PLL1RDY << cr_addshift))); 80006c8: f04f 7300 mov.w r3, #33554432 @ 0x2000000 80006cc: 40bb lsls r3, r7 80006ce: f8d2 1400 ldr.w r1, [r2, #1024] @ 0x400 80006d2: 4219 tst r1, r3 80006d4: d0fb beq.n 80006ce } 80006d6: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} } else if (pll_clk_mhz > 8) { 80006da: f8df e028 ldr.w lr, [pc, #40] @ 8000704 80006de: 4573 cmp r3, lr 80006e0: d98d bls.n 80005fe RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_8_16MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 80006e2: f04f 0e0c mov.w lr, #12 80006e6: f8d0 342c ldr.w r3, [r0, #1068] @ 0x42c 80006ea: fa0e fe07 lsl.w lr, lr, r7 80006ee: e773 b.n 80005d8 80006f0: 2000001a .word 0x2000001a 80006f4: 58024430 .word 0x58024430 80006f8: 000f4240 .word 0x000f4240 80006fc: 58024000 .word 0x58024000 8000700: 2000000e .word 0x2000000e 8000704: 0089543f .word 0x0089543f 08000708 : /* Update our clock values in our tree based on the config values. */ rcc_clock_tree.per.pclk4_mhz = rcc_prediv_3bit_log_div(rcc_clock_tree.hclk_mhz, config->ppre4); } void rcc_clock_setup_pll(const struct rcc_pll_config *config) { 8000708: b5f8 push {r3, r4, r5, r6, r7, lr} /* First, set system clock to utilize HSI, then disable all but HSI. */ RCC_CR |= RCC_CR_HSION; 800070a: 4b81 ldr r3, [pc, #516] @ (8000910 ) void rcc_clock_setup_pll(const struct rcc_pll_config *config) { 800070c: 4604 mov r4, r0 RCC_CR |= RCC_CR_HSION; 800070e: f8d3 2400 ldr.w r2, [r3, #1024] @ 0x400 8000712: f042 0201 orr.w r2, r2, #1 8000716: f8c3 2400 str.w r2, [r3, #1024] @ 0x400 RCC_CFGR &= ~(RCC_CFGR_SW_MASK << RCC_CFGR_SW_SHIFT); 800071a: f8d3 2410 ldr.w r2, [r3, #1040] @ 0x410 800071e: f022 0207 bic.w r2, r2, #7 8000722: f8c3 2410 str.w r2, [r3, #1040] @ 0x410 while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_HSI); 8000726: f8d3 2410 ldr.w r2, [r3, #1040] @ 0x410 800072a: f012 0f38 tst.w r2, #56 @ 0x38 800072e: d1fa bne.n 8000726 RCC_CR = RCC_CR_HSION; 8000730: 2201 movs r2, #1 8000732: f8c3 2400 str.w r2, [r3, #1024] @ 0x400 /* Now that we're safely running on HSI, let's setup the power system for scaling. */ pwr_set_mode(config->power_mode, config->smps_level); 8000736: f894 1029 ldrb.w r1, [r4, #41] @ 0x29 800073a: f894 0028 ldrb.w r0, [r4, #40] @ 0x28 800073e: f000 fa2f bl 8000ba0 pwr_set_vos_scale(config->voltage_scale); 8000742: f894 0027 ldrb.w r0, [r4, #39] @ 0x27 8000746: f000 fa57 bl 8000bf8 /* Set flash waitstates. Enable flash prefetch if we have at least 1WS */ flash_set_ws(config->flash_waitstates); 800074a: f894 0026 ldrb.w r0, [r4, #38] @ 0x26 800074e: f000 f9d3 bl 8000af8 if (config->flash_waitstates > FLASH_ACR_LATENCY_0WS) { 8000752: f894 3026 ldrb.w r3, [r4, #38] @ 0x26 8000756: 2b00 cmp r3, #0 8000758: f000 80c5 beq.w 80008e6 flash_prefetch_enable(); 800075c: f000 f9bc bl 8000ad8 } else { flash_prefetch_disable(); } /* User has specified an external oscillator, make sure we turn it on. */ if (config->hse_frequency > 0) { 8000760: 6863 ldr r3, [r4, #4] 8000762: b18b cbz r3, 8000788 RCC_CR |= RCC_CR_HSEON; 8000764: 4b6a ldr r3, [pc, #424] @ (8000910 ) 8000766: f8d3 2400 ldr.w r2, [r3, #1024] @ 0x400 800076a: f442 3280 orr.w r2, r2, #65536 @ 0x10000 800076e: f8c3 2400 str.w r2, [r3, #1024] @ 0x400 while (!(RCC_CR & RCC_CR_HSERDY)); 8000772: f8d3 2400 ldr.w r2, [r3, #1024] @ 0x400 8000776: 0392 lsls r2, r2, #14 8000778: d5fb bpl.n 8000772 rcc_clock_tree.hse_khz = config->hse_frequency / HZ_PER_KHZ; 800077a: 6863 ldr r3, [r4, #4] 800077c: f44f 727a mov.w r2, #1000 @ 0x3e8 8000780: fbb3 f3f2 udiv r3, r3, r2 8000784: 4a63 ldr r2, [pc, #396] @ (8000914 ) 8000786: 8413 strh r3, [r2, #32] RCC_PLLCKSELR_DIVM2(config->pll2.divm) | 8000788: 7c23 ldrb r3, [r4, #16] RCC_PLLCKSELR = RCC_PLLCKSELR_DIVM1(config->pll1.divm) | 800078a: 7a22 ldrb r2, [r4, #8] RCC_PLLCKSELR_DIVM2(config->pll2.divm) | 800078c: 031b lsls r3, r3, #12 config->pll_source; 800078e: 7861 ldrb r1, [r4, #1] RCC_PLLCKSELR = RCC_PLLCKSELR_DIVM1(config->pll1.divm) | 8000790: ea43 1302 orr.w r3, r3, r2, lsl #4 RCC_PLLCKSELR_DIVM3(config->pll3.divm) | 8000794: 7e22 ldrb r2, [r4, #24] 8000796: 430b orrs r3, r1 8000798: ea43 5302 orr.w r3, r3, r2, lsl #20 RCC_PLLCKSELR = RCC_PLLCKSELR_DIVM1(config->pll1.divm) | 800079c: 4a5c ldr r2, [pc, #368] @ (8000910 ) 800079e: f8c2 3428 str.w r3, [r2, #1064] @ 0x428 ? RCC_HSI_BASE_FREQUENCY : config->hse_frequency; 80007a2: 2900 cmp r1, #0 80007a4: f000 80a2 beq.w 80008ec 80007a8: 6865 ldr r5, [r4, #4] RCC_PLLCFGR = 0; 80007aa: 2300 movs r3, #0 rcc_configure_pll(clkin, &config->pll1, 1); 80007ac: f104 0108 add.w r1, r4, #8 80007b0: 4628 mov r0, r5 RCC_PLLCFGR = 0; 80007b2: f8c2 342c str.w r3, [r2, #1068] @ 0x42c rcc_configure_pll(clkin, &config->pll1, 1); 80007b6: 2201 movs r2, #1 80007b8: f7ff fee0 bl 800057c rcc_configure_pll(clkin, &config->pll2, 2); 80007bc: 2202 movs r2, #2 80007be: f104 0110 add.w r1, r4, #16 80007c2: 4628 mov r0, r5 80007c4: f7ff feda bl 800057c rcc_configure_pll(clkin, &config->pll3, 3); 80007c8: 4628 mov r0, r5 80007ca: 2203 movs r2, #3 80007cc: f104 0118 add.w r1, r4, #24 80007d0: f7ff fed4 bl 800057c /* Set, enable and lock all of the pll from the config. */ rcc_set_and_enable_plls(config); /* Populate our base sysclk settings for use with domain clocks. */ if (config->sysclock_source == RCC_PLL) { 80007d4: 7823 ldrb r3, [r4, #0] 80007d6: 484f ldr r0, [pc, #316] @ (8000914 ) 80007d8: 2b00 cmp r3, #0 80007da: f040 8089 bne.w 80008f0 rcc_clock_tree.sysclk_mhz = rcc_clock_tree.pll1.p_mhz; 80007de: 89c3 ldrh r3, [r0, #14] 80007e0: f894 5024 ldrb.w r5, [r4, #36] @ 0x24 RCC_D1CFGR = 0; 80007e4: 2600 movs r6, #0 80007e6: 4f4a ldr r7, [pc, #296] @ (8000910 ) 80007e8: f894 1020 ldrb.w r1, [r4, #32] 80007ec: f894 2021 ldrb.w r2, [r4, #33] @ 0x21 rcc_clock_tree.sysclk_mhz = rcc_clock_tree.pll1.p_mhz; 80007f0: 8003 strh r3, [r0, #0] if (div_val < 0x8) { 80007f2: 2907 cmp r1, #7 RCC_D1CFGR = 0; 80007f4: f8c7 6418 str.w r6, [r7, #1048] @ 0x418 RCC_D1CFGR_D1HPRE(config->hpre) | RCC_D1CFGR_D1PPRE(config->ppre3); 80007f8: ea4f 1605 mov.w r6, r5, lsl #4 RCC_D1CFGR |= RCC_D1CFGR_D1CPRE(config->core_pre) | 80007fc: f8d7 c418 ldr.w ip, [r7, #1048] @ 0x418 RCC_D1CFGR_D1HPRE(config->hpre) | RCC_D1CFGR_D1PPRE(config->ppre3); 8000800: ea46 2601 orr.w r6, r6, r1, lsl #8 8000804: ea46 0602 orr.w r6, r6, r2 RCC_D1CFGR |= RCC_D1CFGR_D1CPRE(config->core_pre) | 8000808: ea46 060c orr.w r6, r6, ip 800080c: f8c7 6418 str.w r6, [r7, #1048] @ 0x418 if (div_val < 0x8) { 8000810: d906 bls.n 8000820 } else if (div_val <= RCC_D1CFGR_D1CPRE_DIV16) { 8000812: 290b cmp r1, #11 return clk_mhz >> (div_val - 7); 8000814: bf94 ite ls 8000816: 3907 subls r1, #7 return clk_mhz >> (div_val - 6); 8000818: 3906 subhi r1, #6 800081a: fa43 f101 asr.w r1, r3, r1 800081e: b28b uxth r3, r1 if (div_val < 0x8) { 8000820: 2a07 cmp r2, #7 rcc_clock_tree.cpu_mhz = 8000822: 8043 strh r3, [r0, #2] if (div_val < 0x8) { 8000824: d909 bls.n 800083a } else if (div_val <= RCC_D1CFGR_D1CPRE_DIV16) { 8000826: 2a0b cmp r2, #11 return clk_mhz >> (div_val - 7); 8000828: bf95 itete ls 800082a: 3a07 subls r2, #7 return clk_mhz >> (div_val - 6); 800082c: 1f91 subhi r1, r2, #6 return clk_mhz >> (div_val - 7); 800082e: fa43 f202 asrls.w r2, r3, r2 return clk_mhz >> (div_val - 6); 8000832: 410b asrhi r3, r1 return clk_mhz >> (div_val - 7); 8000834: bf94 ite ls 8000836: b293 uxthls r3, r2 return clk_mhz >> (div_val - 6); 8000838: b29b uxthhi r3, r3 if (div_val < 0x4) { 800083a: 2d03 cmp r5, #3 800083c: f894 1023 ldrb.w r1, [r4, #35] @ 0x23 RCC_D2CFGR = 0; 8000840: 4e33 ldr r6, [pc, #204] @ (8000910 ) return clk_mhz >> (div_val - 3); 8000842: bf8c ite hi 8000844: 1eea subhi r2, r5, #3 return clk_mhz; 8000846: 461a movls r2, r3 RCC_D2CFGR = 0; 8000848: f04f 0500 mov.w r5, #0 rcc_clock_tree.hclk_mhz = 800084c: 8083 strh r3, [r0, #4] return clk_mhz >> (div_val - 3); 800084e: bf84 itt hi 8000850: fa43 f202 asrhi.w r2, r3, r2 8000854: b292 uxthhi r2, r2 if (div_val < 0x4) { 8000856: 2903 cmp r1, #3 rcc_clock_tree.per.pclk3_mhz = 8000858: 8142 strh r2, [r0, #10] RCC_D2CFGR = 0; 800085a: f894 2022 ldrb.w r2, [r4, #34] @ 0x22 800085e: f8c6 541c str.w r5, [r6, #1052] @ 0x41c RCC_D2CFGR_D2PPRE2(config->ppre2); 8000862: ea4f 2501 mov.w r5, r1, lsl #8 return clk_mhz >> (div_val - 3); 8000866: bf8c ite hi 8000868: 3903 subhi r1, #3 return clk_mhz; 800086a: 4619 movls r1, r3 RCC_D2CFGR |= RCC_D2CFGR_D2PPRE1(config->ppre1) | 800086c: ea45 1502 orr.w r5, r5, r2, lsl #4 8000870: f8d6 741c ldr.w r7, [r6, #1052] @ 0x41c return clk_mhz >> (div_val - 3); 8000874: bf88 it hi 8000876: fa43 f101 asrhi.w r1, r3, r1 RCC_D2CFGR |= RCC_D2CFGR_D2PPRE1(config->ppre1) | 800087a: ea45 0507 orr.w r5, r5, r7 return clk_mhz >> (div_val - 3); 800087e: bf88 it hi 8000880: b289 uxthhi r1, r1 if (div_val < 0x4) { 8000882: 2a03 cmp r2, #3 RCC_D2CFGR |= RCC_D2CFGR_D2PPRE1(config->ppre1) | 8000884: f8c6 541c str.w r5, [r6, #1052] @ 0x41c return clk_mhz >> (div_val - 3); 8000888: bf8c ite hi 800088a: 3a03 subhi r2, #3 return clk_mhz; 800088c: 461a movls r2, r3 rcc_clock_tree.per.pclk2_mhz = 800088e: 8101 strh r1, [r0, #8] return clk_mhz >> (div_val - 3); 8000890: bf88 it hi 8000892: fa43 f202 asrhi.w r2, r3, r2 8000896: f894 1025 ldrb.w r1, [r4, #37] @ 0x25 800089a: bf88 it hi 800089c: b292 uxthhi r2, r2 if (div_val < 0x4) { 800089e: 2903 cmp r1, #3 rcc_clock_tree.per.pclk1_mhz = 80008a0: 80c2 strh r2, [r0, #6] RCC_D3CFGR &= 0; 80008a2: 4a1b ldr r2, [pc, #108] @ (8000910 ) 80008a4: f8d2 4420 ldr.w r4, [r2, #1056] @ 0x420 80008a8: f04f 0400 mov.w r4, #0 80008ac: f8c2 4420 str.w r4, [r2, #1056] @ 0x420 RCC_D3CFGR |= RCC_D3CFGR_D3PPRE(config->ppre4); 80008b0: f8d2 4420 ldr.w r4, [r2, #1056] @ 0x420 80008b4: ea44 1401 orr.w r4, r4, r1, lsl #4 return clk_mhz >> (div_val - 3); 80008b8: bf84 itt hi 80008ba: 3903 subhi r1, #3 80008bc: fa43 f101 asrhi.w r1, r3, r1 RCC_D3CFGR |= RCC_D3CFGR_D3PPRE(config->ppre4); 80008c0: f8c2 4420 str.w r4, [r2, #1056] @ 0x420 return clk_mhz >> (div_val - 3); 80008c4: bf88 it hi 80008c6: b28b uxthhi r3, r1 rcc_clock_tree.per.pclk4_mhz = 80008c8: 8183 strh r3, [r0, #12] rcc_clock_setup_domain3(config); /* TODO: Configure custom kernel mappings. */ /* Domains dividers are all configured, now we can switchover to PLL. */ RCC_CFGR |= RCC_CFGR_SW_PLL1; 80008ca: f8d2 3410 ldr.w r3, [r2, #1040] @ 0x410 80008ce: f043 0303 orr.w r3, r3, #3 80008d2: f8c2 3410 str.w r3, [r2, #1040] @ 0x410 uint32_t cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 80008d6: f8d2 3410 ldr.w r3, [r2, #1040] @ 0x410 while(cfgr_sws != RCC_CFGR_SWS_PLL1) { cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 80008da: 4a0d ldr r2, [pc, #52] @ (8000910 ) uint32_t cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 80008dc: f3c3 03c2 ubfx r3, r3, #3, #3 while(cfgr_sws != RCC_CFGR_SWS_PLL1) { 80008e0: 2b03 cmp r3, #3 80008e2: d10f bne.n 8000904 } } 80008e4: bdf8 pop {r3, r4, r5, r6, r7, pc} flash_prefetch_disable(); 80008e6: f000 f8ff bl 8000ae8 80008ea: e739 b.n 8000760 ? RCC_HSI_BASE_FREQUENCY : config->hse_frequency; 80008ec: 4d0a ldr r5, [pc, #40] @ (8000918 ) 80008ee: e75c b.n 80007aa } else if (config->sysclock_source == RCC_HSE) { 80008f0: 2b01 cmp r3, #1 rcc_clock_tree.sysclk_mhz = config->hse_frequency / HZ_PER_MHZ; 80008f2: bf09 itett eq 80008f4: 6863 ldreq r3, [r4, #4] 80008f6: 2340 movne r3, #64 @ 0x40 80008f8: 4a08 ldreq r2, [pc, #32] @ (800091c ) 80008fa: fbb3 f3f2 udiveq r3, r3, r2 80008fe: bf08 it eq 8000900: b29b uxtheq r3, r3 8000902: e76d b.n 80007e0 cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 8000904: f8d2 3410 ldr.w r3, [r2, #1040] @ 0x410 8000908: f3c3 03c2 ubfx r3, r3, #3, #3 800090c: e7e8 b.n 80008e0 800090e: bf00 nop 8000910: 58024000 .word 0x58024000 8000914: 20000000 .word 0x20000000 8000918: 03d09000 .word 0x03d09000 800091c: 000f4240 .word 0x000f4240 08000920 : uint32_t rcc_get_bus_clk_freq(enum rcc_clock_source source) { 8000920: b508 push {r3, lr} uint32_t clksel; switch (source) { 8000922: 2809 cmp r0, #9 8000924: d82c bhi.n 8000980 8000926: e8df f000 tbb [pc, r0] 800092a: 050a .short 0x050a 800092c: 0d0d0a1c .word 0x0d0d0a1c 8000930: 19161310 .word 0x19161310 case RCC_SYSCLK: return rcc_clock_tree.sysclk_mhz * HZ_PER_MHZ; 8000934: 4b15 ldr r3, [pc, #84] @ (800098c ) 8000936: 8818 ldrh r0, [r3, #0] case RCC_CPUCLK: case RCC_SYSTICKCLK: return rcc_clock_tree.cpu_mhz * HZ_PER_MHZ; 8000938: 4b15 ldr r3, [pc, #84] @ (8000990 ) case RCC_PERCLK: clksel = (RCC_D1CCIPR >> RCC_D1CCIPR_CKPERSEL_SHIFT) & RCC_D1CCIPR_CKPERSEL_MASK; if (clksel == RCC_D1CCIPR_CKPERSEL_HSI) { return RCC_HSI_BASE_FREQUENCY; } else if (clksel == RCC_D1CCIPR_CKPERSEL_HSE) { return rcc_clock_tree.hse_khz * HZ_PER_KHZ; 800093a: 4358 muls r0, r3 } default: cm3_assert_not_reached(); return 0U; } } 800093c: bd08 pop {r3, pc} return rcc_clock_tree.cpu_mhz * HZ_PER_MHZ; 800093e: 4b13 ldr r3, [pc, #76] @ (800098c ) 8000940: 8858 ldrh r0, [r3, #2] 8000942: e7f9 b.n 8000938 return rcc_clock_tree.hclk_mhz * HZ_PER_MHZ; 8000944: 4b11 ldr r3, [pc, #68] @ (800098c ) 8000946: 8898 ldrh r0, [r3, #4] 8000948: e7f6 b.n 8000938 return rcc_clock_tree.per.pclk1_mhz * HZ_PER_MHZ; 800094a: 4b10 ldr r3, [pc, #64] @ (800098c ) 800094c: 88d8 ldrh r0, [r3, #6] 800094e: e7f3 b.n 8000938 return rcc_clock_tree.per.pclk2_mhz * HZ_PER_MHZ; 8000950: 4b0e ldr r3, [pc, #56] @ (800098c ) 8000952: 8918 ldrh r0, [r3, #8] 8000954: e7f0 b.n 8000938 return rcc_clock_tree.per.pclk3_mhz * HZ_PER_MHZ; 8000956: 4b0d ldr r3, [pc, #52] @ (800098c ) 8000958: 8958 ldrh r0, [r3, #10] 800095a: e7ed b.n 8000938 return rcc_clock_tree.per.pclk4_mhz * HZ_PER_MHZ; 800095c: 4b0b ldr r3, [pc, #44] @ (800098c ) 800095e: 8998 ldrh r0, [r3, #12] 8000960: e7ea b.n 8000938 clksel = (RCC_D1CCIPR >> RCC_D1CCIPR_CKPERSEL_SHIFT) & RCC_D1CCIPR_CKPERSEL_MASK; 8000962: 4b0c ldr r3, [pc, #48] @ (8000994 ) 8000964: f8d3 344c ldr.w r3, [r3, #1100] @ 0x44c if (clksel == RCC_D1CCIPR_CKPERSEL_HSI) { 8000968: f013 5f40 tst.w r3, #805306368 @ 0x30000000 clksel = (RCC_D1CCIPR >> RCC_D1CCIPR_CKPERSEL_SHIFT) & RCC_D1CCIPR_CKPERSEL_MASK; 800096c: f3c3 7201 ubfx r2, r3, #28, #2 if (clksel == RCC_D1CCIPR_CKPERSEL_HSI) { 8000970: d008 beq.n 8000984 } else if (clksel == RCC_D1CCIPR_CKPERSEL_HSE) { 8000972: 2a02 cmp r2, #2 8000974: d108 bne.n 8000988 return rcc_clock_tree.hse_khz * HZ_PER_KHZ; 8000976: 4b05 ldr r3, [pc, #20] @ (800098c ) 8000978: 8c18 ldrh r0, [r3, #32] 800097a: f44f 737a mov.w r3, #1000 @ 0x3e8 800097e: e7dc b.n 800093a cm3_assert_not_reached(); 8000980: f000 f8a8 bl 8000ad4 return RCC_HSI_BASE_FREQUENCY; 8000984: 4804 ldr r0, [pc, #16] @ (8000998 ) 8000986: e7d9 b.n 800093c return 0U; 8000988: 2000 movs r0, #0 800098a: e7d7 b.n 800093c 800098c: 20000000 .word 0x20000000 8000990: 000f4240 .word 0x000f4240 8000994: 58024000 .word 0x58024000 8000998: 03d09000 .word 0x03d09000 0800099c : * * For available constants, see #rcc_periph_clken (RCC_UART1 for example) */ void rcc_periph_clock_enable(enum rcc_periph_clken clken) { _RCC_REG(clken) |= _RCC_BIT(clken); 800099c: 0943 lsrs r3, r0, #5 800099e: 2201 movs r2, #1 80009a0: f000 001f and.w r0, r0, #31 80009a4: f103 43b0 add.w r3, r3, #1476395008 @ 0x58000000 80009a8: 4082 lsls r2, r0 80009aa: f503 3311 add.w r3, r3, #148480 @ 0x24400 80009ae: 6819 ldr r1, [r3, #0] 80009b0: 430a orrs r2, r1 80009b2: 601a str r2, [r3, #0] } 80009b4: 4770 bx lr 080009b6 : } void blocking_handler(void) { while (1); 80009b6: e7fe b.n 80009b6 080009b8 : } void null_handler(void) { /* Do nothing. */ } 80009b8: 4770 bx lr ... 080009bc : { 80009bc: b538 push {r3, r4, r5, lr} for (src = &_data_loadaddr, dest = &_data; 80009be: 4a1d ldr r2, [pc, #116] @ (8000a34 ) 80009c0: 4b1d ldr r3, [pc, #116] @ (8000a38 ) dest < &_edata; 80009c2: 491e ldr r1, [pc, #120] @ (8000a3c ) 80009c4: 428b cmp r3, r1 80009c6: d320 bcc.n 8000a0a while (dest < &_ebss) { 80009c8: 4a1d ldr r2, [pc, #116] @ (8000a40 ) *dest++ = 0; 80009ca: 2100 movs r1, #0 while (dest < &_ebss) { 80009cc: 4293 cmp r3, r2 80009ce: d321 bcc.n 8000a14 SCB_CCR |= SCB_CCR_STKALIGN; 80009d0: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { 80009d4: 4c1b ldr r4, [pc, #108] @ (8000a44 ) 80009d6: 4d1c ldr r5, [pc, #112] @ (8000a48 ) SCB_CCR |= SCB_CCR_STKALIGN; 80009d8: f8d3 2d14 ldr.w r2, [r3, #3348] @ 0xd14 80009dc: f442 7200 orr.w r2, r2, #512 @ 0x200 80009e0: f8c3 2d14 str.w r2, [r3, #3348] @ 0xd14 #include static void pre_main(void) { /* Enable access to Floating-Point coprocessor. */ SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); 80009e4: f8d3 2d88 ldr.w r2, [r3, #3464] @ 0xd88 80009e8: f442 0270 orr.w r2, r2, #15728640 @ 0xf00000 80009ec: f8c3 2d88 str.w r2, [r3, #3464] @ 0xd88 for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { 80009f0: 42ac cmp r4, r5 80009f2: d312 bcc.n 8000a1a for (fp = &__init_array_start; fp < &__init_array_end; fp++) { 80009f4: 4c15 ldr r4, [pc, #84] @ (8000a4c ) 80009f6: 4d16 ldr r5, [pc, #88] @ (8000a50 ) 80009f8: 42ac cmp r4, r5 80009fa: d312 bcc.n 8000a22 for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { 80009fc: 4c15 ldr r4, [pc, #84] @ (8000a54 ) (void)main(); 80009fe: f7ff fc7b bl 80002f8
for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { 8000a02: 4d15 ldr r5, [pc, #84] @ (8000a58 ) 8000a04: 42ac cmp r4, r5 8000a06: d310 bcc.n 8000a2a } 8000a08: bd38 pop {r3, r4, r5, pc} *dest = *src; 8000a0a: f852 0b04 ldr.w r0, [r2], #4 8000a0e: f843 0b04 str.w r0, [r3], #4 src++, dest++) { 8000a12: e7d7 b.n 80009c4 *dest++ = 0; 8000a14: f843 1b04 str.w r1, [r3], #4 8000a18: e7d8 b.n 80009cc (*fp)(); 8000a1a: f854 3b04 ldr.w r3, [r4], #4 8000a1e: 4798 blx r3 for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { 8000a20: e7e6 b.n 80009f0 (*fp)(); 8000a22: f854 3b04 ldr.w r3, [r4], #4 8000a26: 4798 blx r3 for (fp = &__init_array_start; fp < &__init_array_end; fp++) { 8000a28: e7e6 b.n 80009f8 (*fp)(); 8000a2a: f854 3b04 ldr.w r3, [r4], #4 8000a2e: 4798 blx r3 for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { 8000a30: e7e8 b.n 8000a04 8000a32: bf00 nop 8000a34: 08000d38 .word 0x08000d38 8000a38: 20000000 .word 0x20000000 8000a3c: 20000024 .word 0x20000024 8000a40: 20000028 .word 0x20000028 8000a44: 08000d38 .word 0x08000d38 8000a48: 08000d38 .word 0x08000d38 8000a4c: 08000d38 .word 0x08000d38 8000a50: 08000d38 .word 0x08000d38 8000a54: 08000d38 .word 0x08000d38 8000a58: 08000d38 .word 0x08000d38 08000a5c : * * @param[in] value uint32_t. 24 bit reload value. */ void systick_set_reload(uint32_t value) { STK_RVR = (value & STK_RVR_RELOAD); 8000a5c: f020 407f bic.w r0, r0, #4278190080 @ 0xff000000 8000a60: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 8000a64: 6158 str r0, [r3, #20] } 8000a66: 4770 bx lr 08000a68 : * @param[in] clocksource uint8_t. Clock source from @ref systick_clksource. */ void systick_set_clocksource(uint8_t clocksource) { STK_CSR = (STK_CSR & ~STK_CSR_CLKSOURCE) | 8000a68: f04f 22e0 mov.w r2, #3758153728 @ 0xe000e000 (clocksource & STK_CSR_CLKSOURCE); 8000a6c: f000 0004 and.w r0, r0, #4 STK_CSR = (STK_CSR & ~STK_CSR_CLKSOURCE) | 8000a70: 6913 ldr r3, [r2, #16] 8000a72: f023 0304 bic.w r3, r3, #4 8000a76: 4303 orrs r3, r0 8000a78: 6113 str r3, [r2, #16] } 8000a7a: 4770 bx lr 08000a7c : * */ void systick_interrupt_enable(void) { STK_CSR |= STK_CSR_TICKINT; 8000a7c: f04f 22e0 mov.w r2, #3758153728 @ 0xe000e000 8000a80: 6913 ldr r3, [r2, #16] 8000a82: f043 0302 orr.w r3, r3, #2 8000a86: 6113 str r3, [r2, #16] } 8000a88: 4770 bx lr 08000a8a : * */ void systick_counter_enable(void) { STK_CSR |= STK_CSR_ENABLE; 8000a8a: f04f 22e0 mov.w r2, #3758153728 @ 0xe000e000 8000a8e: 6913 ldr r3, [r2, #16] 8000a90: f043 0301 orr.w r3, r3, #1 8000a94: 6113 str r3, [r2, #16] } 8000a96: 4770 bx lr 08000a98 : * The counter value is cleared. Useful for well defined startup. */ void systick_clear(void) { STK_CVR = 0; 8000a98: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 8000a9c: 2200 movs r2, #0 8000a9e: 619a str r2, [r3, #24] } 8000aa0: 4770 bx lr 08000aa2 : /* Those are defined only on CM3 or CM4 */ #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) void scb_set_priority_grouping(uint32_t prigroup) { SCB_AIRCR = SCB_AIRCR_VECTKEY | prigroup; 8000aa2: f040 60bf orr.w r0, r0, #100139008 @ 0x5f80000 8000aa6: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 8000aaa: f440 3000 orr.w r0, r0, #131072 @ 0x20000 8000aae: f8c3 0d0c str.w r0, [r3, #3340] @ 0xd0c } 8000ab2: 4770 bx lr 08000ab4 : void nvic_set_priority(uint8_t irqn, uint8_t priority) { /* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the * negative interrupt numbers assigned to the system interrupts. better * handling would mean signed integers. */ if (irqn >= NVIC_IRQ_COUNT) { 8000ab4: 2895 cmp r0, #149 @ 0x95 8000ab6: d904 bls.n 8000ac2 uint8_t shift = (irqn & 0x3) << 3; uint8_t reg = irqn >> 2; SCB_SHPR32(reg) = ((SCB_SHPR32(reg) & ~(0xFFUL << shift)) | ((uint32_t) priority) << shift); #else SCB_SHPR((irqn & 0xF) - 4) = priority; 8000ab8: f000 000f and.w r0, r0, #15 8000abc: 4b04 ldr r3, [pc, #16] @ (8000ad0 ) 8000abe: 54c1 strb r1, [r0, r3] 8000ac0: 4770 bx lr uint8_t shift = (irqn & 0x3) << 3; uint8_t reg = irqn >> 2; NVIC_IPR32(reg) = ((NVIC_IPR32(reg) & ~(0xFFUL << shift)) | ((uint32_t) priority) << shift); #else NVIC_IPR(irqn) = priority; 8000ac2: f100 4060 add.w r0, r0, #3758096384 @ 0xe0000000 8000ac6: f500 4064 add.w r0, r0, #58368 @ 0xe400 8000aca: 7001 strb r1, [r0, #0] #endif } } 8000acc: 4770 bx lr 8000ace: bf00 nop 8000ad0: e000ed14 .word 0xe000ed14 08000ad4 : #include void __attribute__((weak)) cm3_assert_failed(void) { while (1); 8000ad4: e7fe b.n 8000ad4 ... 08000ad8 : #include void flash_prefetch_enable(void) { FLASH_ACR |= FLASH_ACR_PRFTEN; 8000ad8: 4a02 ldr r2, [pc, #8] @ (8000ae4 ) 8000ada: 6813 ldr r3, [r2, #0] 8000adc: f443 7380 orr.w r3, r3, #256 @ 0x100 8000ae0: 6013 str r3, [r2, #0] } 8000ae2: 4770 bx lr 8000ae4: 52002000 .word 0x52002000 08000ae8 : void flash_prefetch_disable(void) { FLASH_ACR &= ~FLASH_ACR_PRFTEN; 8000ae8: 4a02 ldr r2, [pc, #8] @ (8000af4 ) 8000aea: 6813 ldr r3, [r2, #0] 8000aec: f423 7380 bic.w r3, r3, #256 @ 0x100 8000af0: 6013 str r3, [r2, #0] } 8000af2: 4770 bx lr 8000af4: 52002000 .word 0x52002000 08000af8 : void flash_set_ws(uint32_t ws) { uint32_t reg32; reg32 = FLASH_ACR; 8000af8: 4a03 ldr r2, [pc, #12] @ (8000b08 ) 8000afa: 6813 ldr r3, [r2, #0] reg32 &= ~(FLASH_ACR_LATENCY_MASK << FLASH_ACR_LATENCY_SHIFT); 8000afc: f023 030f bic.w r3, r3, #15 reg32 |= (ws << FLASH_ACR_LATENCY_SHIFT); 8000b00: 4303 orrs r3, r0 FLASH_ACR = reg32; 8000b02: 6013 str r3, [r2, #0] } 8000b04: 4770 bx lr 8000b06: bf00 nop 8000b08: 52002000 .word 0x52002000 08000b0c : #define DBGMCU_IDCODE_DEV_ID_STM32H7A3_B3_B0 0x480 void pwr_set_mode_ldo(void) { /* Per table in manual for SMPS, mask and set SMPSEN=0 : LDOEN=1 : BYPASS=0. */ const uint32_t cr3_mask = (PWR_CR3_SMPSEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); PWR_CR3 = (PWR_CR3 & ~cr3_mask) | (PWR_CR3_LDOEN); 8000b0c: 4a04 ldr r2, [pc, #16] @ (8000b20 ) 8000b0e: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 8000b12: f023 0307 bic.w r3, r3, #7 8000b16: f043 0302 orr.w r3, r3, #2 8000b1a: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 8000b1e: 4770 bx lr 8000b20: 58024000 .word 0x58024000 08000b24 : void pwr_set_mode_scu_ldo(void) { const uint32_t cr3_mask = (PWR_CR3_SCUEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); PWR_CR3 = (PWR_CR3 & ~cr3_mask) | (PWR_CR3_SCUEN | PWR_CR3_LDOEN); 8000b24: 4a04 ldr r2, [pc, #16] @ (8000b38 ) 8000b26: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 8000b2a: f023 0307 bic.w r3, r3, #7 8000b2e: f043 0306 orr.w r3, r3, #6 8000b32: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 8000b36: 4770 bx lr 8000b38: 58024000 .word 0x58024000 08000b3c : void pwr_set_mode_smps_ldo(bool supply_external, uint32_t smps_level, bool use_ldo) { 8000b3c: b508 push {r3, lr} uint32_t cr3_mask, cr3_set; cr3_mask = (PWR_CR3_SMPSEXTHP | PWR_CR3_SMPSEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); cr3_mask |= PWR_CR3_SMPSLEVEL_MASK << PWR_CR3_SMPSLEVEL_SHIFT; /* Default, take in unconditional settings, will OR in the rest. */ cr3_set = PWR_CR3_SMPSEN | (smps_level << PWR_CR3_SMPSLEVEL_SHIFT); 8000b3e: 010b lsls r3, r1, #4 if (supply_external) { 8000b40: b970 cbnz r0, 8000b60 cr3_set = PWR_CR3_SMPSEN | (smps_level << PWR_CR3_SMPSLEVEL_SHIFT); 8000b42: f043 0304 orr.w r3, r3, #4 } if (use_ldo) { cr3_set |= PWR_CR3_LDOEN; } PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; 8000b46: 4809 ldr r0, [pc, #36] @ (8000b6c ) if (use_ldo) { 8000b48: 4252 negs r2, r2 PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; 8000b4a: f8d0 180c ldr.w r1, [r0, #2060] @ 0x80c if (use_ldo) { 8000b4e: f002 0202 and.w r2, r2, #2 PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; 8000b52: f021 013f bic.w r1, r1, #63 @ 0x3f 8000b56: 430a orrs r2, r1 8000b58: 431a orrs r2, r3 8000b5a: f8c0 280c str.w r2, [r0, #2060] @ 0x80c } 8000b5e: bd08 pop {r3, pc} cm3_assert(smps_level != PWR_CR3_SMPSLEVEL_VOS); /* Unsupported setting! */ 8000b60: b909 cbnz r1, 8000b66 8000b62: f7ff ffb7 bl 8000ad4 cr3_set |= PWR_CR3_SMPSEXTHP; 8000b66: f043 030c orr.w r3, r3, #12 8000b6a: e7ec b.n 8000b46 8000b6c: 58024000 .word 0x58024000 08000b70 : void pwr_set_mode_bypass(void) { const uint32_t cr3_mask = (PWR_CR3_SMPSEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); PWR_CR3 = (PWR_CR3 & ~cr3_mask) | PWR_CR3_BYPASS; 8000b70: 4a04 ldr r2, [pc, #16] @ (8000b84 ) 8000b72: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 8000b76: f023 0307 bic.w r3, r3, #7 8000b7a: f043 0301 orr.w r3, r3, #1 8000b7e: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 8000b82: 4770 bx lr 8000b84: 58024000 .word 0x58024000 08000b88 : void pwr_set_mode_scu_bypass(void) { const uint32_t cr3_mask = (PWR_CR3_SCUEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); PWR_CR3 = (PWR_CR3 & ~cr3_mask) | (PWR_CR3_SCUEN | PWR_CR3_BYPASS); 8000b88: 4a04 ldr r2, [pc, #16] @ (8000b9c ) 8000b8a: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 8000b8e: f023 0307 bic.w r3, r3, #7 8000b92: f043 0305 orr.w r3, r3, #5 8000b96: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 8000b9a: 4770 bx lr 8000b9c: 58024000 .word 0x58024000 08000ba0 : void pwr_set_mode(enum pwr_sys_mode mode, uint8_t smps_level) { 8000ba0: b508 push {r3, lr} switch (mode) { 8000ba2: 2807 cmp r0, #7 8000ba4: d807 bhi.n 8000bb6 8000ba6: e8df f000 tbb [pc, r0] 8000baa: 0c04 .short 0x0c04 8000bac: 1d12120f .word 0x1d12120f 8000bb0: 211d .short 0x211d case PWR_SYS_SCU_LDO: pwr_set_mode_scu_ldo(); 8000bb2: f7ff ffb7 bl 8000b24 case PWR_SYS_BYPASS: pwr_set_mode_bypass(); break; } /* Wait for power supply status to state ready. */ while (!(PWR_CSR1 & PWR_CSR1_ACTVOSRDY)); 8000bb6: 4a0f ldr r2, [pc, #60] @ (8000bf4 ) 8000bb8: f8d2 3804 ldr.w r3, [r2, #2052] @ 0x804 8000bbc: 049b lsls r3, r3, #18 8000bbe: d5fb bpl.n 8000bb8 } 8000bc0: bd08 pop {r3, pc} pwr_set_mode_scu_bypass(); 8000bc2: f7ff ffe1 bl 8000b88 break; 8000bc6: e7f6 b.n 8000bb6 pwr_set_mode_ldo(); 8000bc8: f7ff ffa0 bl 8000b0c break; 8000bcc: e7f3 b.n 8000bb6 pwr_set_mode_smps_ldo(false, PWR_CR3_SMPSLEVEL_VOS, mode == PWR_SYS_SMPS_LDO); 8000bce: f1a0 0c04 sub.w ip, r0, #4 8000bd2: 2100 movs r1, #0 8000bd4: f1dc 0200 rsbs r2, ip, #0 8000bd8: eb42 020c adc.w r2, r2, ip pwr_set_mode_smps_ldo(false, smps_level, mode == PWR_SYS_EXT_SMPS_LDO); 8000bdc: 2000 movs r0, #0 8000bde: f7ff ffad bl 8000b3c break; 8000be2: e7e8 b.n 8000bb6 pwr_set_mode_smps_ldo(false, smps_level, mode == PWR_SYS_EXT_SMPS_LDO); 8000be4: 3805 subs r0, #5 8000be6: 4242 negs r2, r0 8000be8: 4142 adcs r2, r0 8000bea: e7f7 b.n 8000bdc pwr_set_mode_bypass(); 8000bec: f7ff ffc0 bl 8000b70 break; 8000bf0: e7e1 b.n 8000bb6 8000bf2: bf00 nop 8000bf4: 58024000 .word 0x58024000 08000bf8 : uint32_t pwr_cr1_reg = PWR_CR1; pwr_cr1_reg = (pwr_cr1_reg & ~(PWR_CR1_SVOS_MASK << PWR_CR1_SVOS_SHIFT)); PWR_CR1 = pwr_cr1_reg | scale; } void pwr_set_vos_scale(enum pwr_vos_scale scale) { 8000bf8: b5f8 push {r3, r4, r5, r6, r7, lr} PWR_D3CR_VOS_SCALE_0, PWR_D3CR_VOS_SCALE_1, PWR_D3CR_VOS_SCALE_2, PWR_D3CR_VOS_SCALE_3, }; cm3_assert(scale != PWR_VOS_SCALE_UNDEFINED); /* Make sure this has been set. */ 8000bfa: 4607 mov r7, r0 8000bfc: b908 cbnz r0, 8000c02 8000bfe: f7ff ff69 bl 8000ad4 /* "SmartRun Domain" devices (presently only know of A3/B3/B0) have different mapping. * Note: DBGMCU_IDCODE_DEV_ID_STM32H7A3 covers all three of these models. */ uint32_t devid = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK; 8000c02: 4b20 ldr r3, [pc, #128] @ (8000c84 ) if (devid == DBGMCU_IDCODE_DEV_ID_STM32H7A3_B3_B0) { const uint32_t srdcr_vos_mask = (PWR_SRDCR_VOS_MASK << PWR_SRDCR_VOS_SHIFT); const uint32_t vos_value = srdcr_vos_values[scale - 1] << PWR_SRDCR_VOS_SHIFT; 8000c04: 1e42 subs r2, r0, #1 8000c06: 4e20 ldr r6, [pc, #128] @ (8000c88 ) uint32_t devid = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK; 8000c08: 681b ldr r3, [r3, #0] 8000c0a: f3c3 030b ubfx r3, r3, #0, #12 if (devid == DBGMCU_IDCODE_DEV_ID_STM32H7A3_B3_B0) { 8000c0e: f5b3 6f90 cmp.w r3, #1152 @ 0x480 8000c12: d10f bne.n 8000c34 PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; 8000c14: f8d6 3818 ldr.w r3, [r6, #2072] @ 0x818 const uint32_t vos_value = srdcr_vos_values[scale - 1] << PWR_SRDCR_VOS_SHIFT; 8000c18: 491c ldr r1, [pc, #112] @ (8000c8c ) PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; 8000c1a: f423 4340 bic.w r3, r3, #49152 @ 0xc000 const uint32_t vos_value = srdcr_vos_values[scale - 1] << PWR_SRDCR_VOS_SHIFT; 8000c1e: 5c8a ldrb r2, [r1, r2] PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; 8000c20: ea43 3382 orr.w r3, r3, r2, lsl #14 8000c24: f8c6 3818 str.w r3, [r6, #2072] @ 0x818 } } else { PWR_D3CR = d3cr_masked | d3cr_vos; } } while (!(PWR_D3CR & PWR_D3CR_VOSRDY)); /* VOSRDY bit is same between D3CR and SRDCR. */ 8000c28: 4a17 ldr r2, [pc, #92] @ (8000c88 ) 8000c2a: f8d2 3818 ldr.w r3, [r2, #2072] @ 0x818 8000c2e: 049b lsls r3, r3, #18 8000c30: d5fb bpl.n 8000c2a } 8000c32: bdf8 pop {r3, r4, r5, r6, r7, pc} uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; 8000c34: 4916 ldr r1, [pc, #88] @ (8000c90 ) if (devid == DBGMCU_IDCODE_DEV_ID_STM32H74X_5X) { 8000c36: f5b3 6f8a cmp.w r3, #1104 @ 0x450 uint32_t d3cr_masked = PWR_D3CR & ~(PWR_D3CR_VOS_MASK << PWR_D3CR_VOS_SHIFT); 8000c3a: f8d6 5818 ldr.w r5, [r6, #2072] @ 0x818 uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; 8000c3e: 5c8c ldrb r4, [r1, r2] uint32_t d3cr_masked = PWR_D3CR & ~(PWR_D3CR_VOS_MASK << PWR_D3CR_VOS_SHIFT); 8000c40: f425 4540 bic.w r5, r5, #49152 @ 0xc000 uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; 8000c44: ea4f 3484 mov.w r4, r4, lsl #14 if (devid == DBGMCU_IDCODE_DEV_ID_STM32H74X_5X) { 8000c48: d118 bne.n 8000c7c rcc_periph_clock_enable(RCC_SYSCFG); /* Ensure we can access ODEN. */ 8000c4a: f641 6081 movw r0, #7809 @ 0x1e81 8000c4e: f7ff fea5 bl 800099c if (scale == PWR_VOS_SCALE_0) { 8000c52: 2f01 cmp r7, #1 8000c54: f04f 43b0 mov.w r3, #1476395008 @ 0x58000000 8000c58: d10a bne.n 8000c70 PWR_D3CR = d3cr_masked | (PWR_D3CR_VOS_SCALE_1 << PWR_SRDCR_VOS_SHIFT); 8000c5a: f445 4540 orr.w r5, r5, #49152 @ 0xc000 8000c5e: f8c6 5818 str.w r5, [r6, #2072] @ 0x818 SYSCFG_PWRCR |= SYSCFG_PWRCR_ODEN; 8000c62: f8d3 242c ldr.w r2, [r3, #1068] @ 0x42c 8000c66: f042 0201 orr.w r2, r2, #1 8000c6a: f8c3 242c str.w r2, [r3, #1068] @ 0x42c 8000c6e: e7db b.n 8000c28 SYSCFG_PWRCR &= ~SYSCFG_PWRCR_ODEN; 8000c70: f8d3 242c ldr.w r2, [r3, #1068] @ 0x42c 8000c74: f022 0201 bic.w r2, r2, #1 8000c78: f8c3 242c str.w r2, [r3, #1068] @ 0x42c PWR_D3CR = d3cr_masked | d3cr_vos; 8000c7c: 432c orrs r4, r5 8000c7e: f8c6 4818 str.w r4, [r6, #2072] @ 0x818 8000c82: e7d1 b.n 8000c28 8000c84: 5c001000 .word 0x5c001000 8000c88: 58024000 .word 0x58024000 8000c8c: 08000d34 .word 0x08000d34 8000c90: 08000d30 .word 0x08000d30 08000c94 : 8000c94: 0783 lsls r3, r0, #30 8000c96: b530 push {r4, r5, lr} 8000c98: d046 beq.n 8000d28 8000c9a: 1884 adds r4, r0, r2 8000c9c: 4684 mov ip, r0 8000c9e: e004 b.n 8000caa 8000ca0: f803 1b01 strb.w r1, [r3], #1 8000ca4: 079d lsls r5, r3, #30 8000ca6: d004 beq.n 8000cb2 8000ca8: 469c mov ip, r3 8000caa: 45a4 cmp ip, r4 8000cac: 4663 mov r3, ip 8000cae: d1f7 bne.n 8000ca0 8000cb0: bd30 pop {r4, r5, pc} 8000cb2: 3a01 subs r2, #1 8000cb4: 4402 add r2, r0 8000cb6: eba2 020c sub.w r2, r2, ip 8000cba: 2a03 cmp r2, #3 8000cbc: d929 bls.n 8000d12 8000cbe: b2cc uxtb r4, r1 8000cc0: eb04 2404 add.w r4, r4, r4, lsl #8 8000cc4: 2a0f cmp r2, #15 8000cc6: eb04 4404 add.w r4, r4, r4, lsl #16 8000cca: d92f bls.n 8000d2c 8000ccc: f1a2 0c10 sub.w ip, r2, #16 8000cd0: f02c 0c0f bic.w ip, ip, #15 8000cd4: f103 0510 add.w r5, r3, #16 8000cd8: 44ac add ip, r5 8000cda: e9c3 4400 strd r4, r4, [r3] 8000cde: e9c3 4402 strd r4, r4, [r3, #8] 8000ce2: 3310 adds r3, #16 8000ce4: 4563 cmp r3, ip 8000ce6: d1f8 bne.n 8000cda 8000ce8: f012 0f0c tst.w r2, #12 8000cec: f002 0e0f and.w lr, r2, #15 8000cf0: d018 beq.n 8000d24 8000cf2: f02e 0c03 bic.w ip, lr, #3 8000cf6: 449c add ip, r3 8000cf8: f1ae 0504 sub.w r5, lr, #4 8000cfc: 461a mov r2, r3 8000cfe: f842 4b04 str.w r4, [r2], #4 8000d02: 4562 cmp r2, ip 8000d04: d1fb bne.n 8000cfe 8000d06: f025 0403 bic.w r4, r5, #3 8000d0a: 3304 adds r3, #4 8000d0c: f00e 0203 and.w r2, lr, #3 8000d10: 4423 add r3, r4 8000d12: 2a00 cmp r2, #0 8000d14: d0cc beq.n 8000cb0 8000d16: b2c9 uxtb r1, r1 8000d18: 441a add r2, r3 8000d1a: f803 1b01 strb.w r1, [r3], #1 8000d1e: 4293 cmp r3, r2 8000d20: d1fb bne.n 8000d1a 8000d22: bd30 pop {r4, r5, pc} 8000d24: 4672 mov r2, lr 8000d26: e7f4 b.n 8000d12 8000d28: 4603 mov r3, r0 8000d2a: e7c6 b.n 8000cba 8000d2c: 4696 mov lr, r2 8000d2e: e7e0 b.n 8000cf2 08000d30 : 8000d30: 0300 0102 .... 08000d34 : 8000d34: 0203 0001 ....