/home/time/doc/codefile/embe/Blog/stm32/stm32h7/2gpio-lib/bin/gpio-lib.elf: file format elf32-littlearm Disassembly of section .text: 08000000 : 8000000: 00 00 02 20 55 17 00 08 51 17 00 08 4f 17 00 08 ... U...Q...O... 8000010: 4f 17 00 08 4f 17 00 08 4f 17 00 08 00 00 00 00 O...O...O....... ... 800002c: 51 17 00 08 51 17 00 08 00 00 00 00 51 17 00 08 Q...Q.......Q... 800003c: 8d 04 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 ....O...O...O... 800004c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800005c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800006c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800007c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800008c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800009c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80000ac: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80000bc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80000cc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80000dc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80000ec: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80000fc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800010c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800011c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800012c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800013c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800014c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800015c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800016c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800017c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800018c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800019c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80001ac: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80001bc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80001cc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80001dc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80001ec: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 80001fc: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800020c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800021c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800022c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800023c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800024c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800025c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800026c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800027c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O...O... 800028c: 4f 17 00 08 4f 17 00 08 4f 17 00 08 O...O...O... 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: f001 fa48 bl 8001734 // 配置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 fff7 bl 800129e // 设置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: f001 f811 bl 80012de // 将GPIOE端口引脚3设置为低电平,也就是灯灭 gpio_clear(GPIOE, GPIO3); 80002bc: 2108 movs r1, #8 80002be: 480b ldr r0, [pc, #44] @ (80002ec ) 80002c0: f000 ffde bl 8001280 // 使能备份域访问,通过设置电源控制寄存器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: f001 fa2e bl 8001734 // 配置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 ffdc bl 800129e } 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: f001 fa9b bl 800183a // 初始化系统时钟配置 system_clock_setup(); 8000304: f000 f80e bl 8000324 // 初始化SysTick定时器,参数1000U表示每秒产生1000次中断,即每1ms一次 systick_init(1000U); 8000308: f44f 707a mov.w r0, #1000 @ 0x3e8 800030c: f000 f89e bl 800044c // 初始化用户GPIO引脚配置 // 根据gpio的代码,这包括配置PE3为输出(LED)和PC13为输入(按钮) user_gpio_setup(); 8000310: f7ff ffc2 bl 8000298 // 初始化按键库 ebtn_user_init(); 8000314: f000 f926 bl 8000564 // 主循环,程序将在此无限循环 while (1) { // 处理按键事件,该函数可以放到其他可以周期运行的地方 ebtn_user_process(); 8000318: f000 f93a bl 8000590 user_delay_ms(5); 800031c: 2005 movs r0, #5 800031e: f000 f87b bl 8000418 ebtn_user_process(); 8000322: e7f9 b.n 8000318 08000324 : * * @see rcc_periph_clock_enable(), gpio_mode_setup(), gpio_set_output_options(), * gpio_set(), rcc_clock_setup_pll() */ static void system_clock_setup(void) { 8000324: b580 push {r7, lr} 8000326: b08c sub sp, #48 @ 0x30 8000328: af00 add r7, sp, #0 // 初始化PLL配置结构体,所有成员清零 struct rcc_pll_config pll_config = {0}; 800032a: 463b mov r3, r7 800032c: 222c movs r2, #44 @ 0x2c 800032e: 2100 movs r1, #0 8000330: 4618 mov r0, r3 8000332: f001 fba9 bl 8001a88 // 使能GPIOH端口时钟,用于配置GPIOH1引脚 // OSC_IN是GPIOH0,OSC_OUT是GPIOH1 rcc_periph_clock_enable(RCC_GPIOH); 8000336: f641 4007 movw r0, #7175 @ 0x1c07 800033a: f001 f9fb bl 8001734 // 使能SYSCFG时钟,用于系统配置 rcc_periph_clock_enable(RCC_SYSCFG); 800033e: f641 6081 movw r0, #7809 @ 0x1e81 8000342: f001 f9f7 bl 8001734 // 配置GPIOH1引脚为输出模式,启用上拉电阻 gpio_mode_setup(GPIOH, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO1); 8000346: 2302 movs r3, #2 8000348: 2201 movs r2, #1 800034a: 2101 movs r1, #1 800034c: 4830 ldr r0, [pc, #192] @ (8000410 ) 800034e: f000 ffa6 bl 800129e // 设置GPIOH1引脚为推挽输出,速度为50MHz gpio_set_output_options(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO1); 8000352: 2302 movs r3, #2 8000354: 2202 movs r2, #2 8000356: 2100 movs r1, #0 8000358: 482d ldr r0, [pc, #180] @ (8000410 ) 800035a: f000 ffc0 bl 80012de // 短暂延时,确保GPIO配置稳定 for (unsigned i = 0; i < 20; i++) 800035e: 2300 movs r3, #0 8000360: 62fb str r3, [r7, #44] @ 0x2c 8000362: e003 b.n 800036c { __asm__("nop"); // 空操作指令,用于延时 8000364: bf00 nop for (unsigned i = 0; i < 20; i++) 8000366: 6afb ldr r3, [r7, #44] @ 0x2c 8000368: 3301 adds r3, #1 800036a: 62fb str r3, [r7, #44] @ 0x2c 800036c: 6afb ldr r3, [r7, #44] @ 0x2c 800036e: 2b13 cmp r3, #19 8000370: d9f8 bls.n 8000364 } // 将GPIOH1引脚设置为高电平 gpio_set(GPIOH, GPIO1); 8000372: 2102 movs r1, #2 8000374: 4826 ldr r0, [pc, #152] @ (8000410 ) 8000376: f000 ff81 bl 800127c // 设置系统时钟源为PLL pll_config.sysclock_source = RCC_PLL; 800037a: 2300 movs r3, #0 800037c: 703b strb r3, [r7, #0] // 设置PLL时钟源为外部高速晶振(HSE) pll_config.pll_source = RCC_PLLCKSELR_PLLSRC_HSE; 800037e: 2302 movs r3, #2 8000380: 707b strb r3, [r7, #1] // 设置HSE频率为25MHz pll_config.hse_frequency = 25000000U; 8000382: 4b24 ldr r3, [pc, #144] @ (8000414 ) 8000384: 607b str r3, [r7, #4] // 配置PLL1参数,这一部分可以和CubeMX进行一一对应 // 系统时钟频率 = HSE / M * N / P = 25MHz / 5 * 192 / 2 = 480MHz pll_config.pll1.divm = 5; 8000386: 2305 movs r3, #5 8000388: 723b strb r3, [r7, #8] pll_config.pll1.divn = 192; 800038a: 23c0 movs r3, #192 @ 0xc0 800038c: 817b strh r3, [r7, #10] pll_config.pll1.divp = 2; 800038e: 2302 movs r3, #2 8000390: 733b strb r3, [r7, #12] pll_config.pll1.divq = 2; 8000392: 2302 movs r3, #2 8000394: 737b strb r3, [r7, #13] pll_config.pll1.divr = 2; 8000396: 2302 movs r3, #2 8000398: 73bb strb r3, [r7, #14] // 配置PLL2参数 pll_config.pll2.divm = 32; 800039a: 2320 movs r3, #32 800039c: 743b strb r3, [r7, #16] pll_config.pll2.divn = 129; 800039e: 2381 movs r3, #129 @ 0x81 80003a0: 827b strh r3, [r7, #18] pll_config.pll2.divp = 2; 80003a2: 2302 movs r3, #2 80003a4: 753b strb r3, [r7, #20] pll_config.pll2.divq = 2; 80003a6: 2302 movs r3, #2 80003a8: 757b strb r3, [r7, #21] pll_config.pll2.divr = 2; 80003aa: 2302 movs r3, #2 80003ac: 75bb strb r3, [r7, #22] // 配置PLL3参数 pll_config.pll3.divm = 32; 80003ae: 2320 movs r3, #32 80003b0: 763b strb r3, [r7, #24] pll_config.pll3.divn = 129; 80003b2: 2381 movs r3, #129 @ 0x81 80003b4: 837b strh r3, [r7, #26] pll_config.pll3.divp = 2; 80003b6: 2302 movs r3, #2 80003b8: 773b strb r3, [r7, #28] pll_config.pll3.divq = 2; 80003ba: 2302 movs r3, #2 80003bc: 777b strb r3, [r7, #29] pll_config.pll3.divr = 2; 80003be: 2302 movs r3, #2 80003c0: 77bb strb r3, [r7, #30] // 配置系统时钟分频参数,还是可以和CubeMX进行一一对应 pll_config.core_pre = RCC_D1CFGR_D1CPRE_BYP; // CPU核心时钟不分频 80003c2: 2300 movs r3, #0 80003c4: f887 3020 strb.w r3, [r7, #32] pll_config.hpre = RCC_D1CFGR_D1HPRE_DIV2; // AHB总线时钟2分频 80003c8: 2308 movs r3, #8 80003ca: f887 3021 strb.w r3, [r7, #33] @ 0x21 pll_config.ppre1 = RCC_D2CFGR_D2PPRE_DIV2; // APB1总线时钟2分频 80003ce: 2304 movs r3, #4 80003d0: f887 3022 strb.w r3, [r7, #34] @ 0x22 pll_config.ppre2 = RCC_D2CFGR_D2PPRE_DIV2; // APB2总线时钟2分频 80003d4: 2304 movs r3, #4 80003d6: f887 3023 strb.w r3, [r7, #35] @ 0x23 pll_config.ppre3 = RCC_D1CFGR_D1PPRE_DIV2; // APB3总线时钟2分频 80003da: 2304 movs r3, #4 80003dc: f887 3024 strb.w r3, [r7, #36] @ 0x24 pll_config.ppre4 = RCC_D3CFGR_D3PPRE_DIV2; // APB4总线时钟2分频 80003e0: 2304 movs r3, #4 80003e2: f887 3025 strb.w r3, [r7, #37] @ 0x25 // 设置Flash等待状态为4个周期,确保在480MHz系统时钟下能正确访问Flash pll_config.flash_waitstates = FLASH_ACR_LATENCY_4WS; 80003e6: 2304 movs r3, #4 80003e8: f887 3026 strb.w r3, [r7, #38] @ 0x26 // 配置电压缩放和电源模式 pll_config.voltage_scale = PWR_VOS_SCALE_0; // 电压缩放级别0,最高性能模式 80003ec: 2301 movs r3, #1 80003ee: f887 3027 strb.w r3, [r7, #39] @ 0x27 pll_config.power_mode = PWR_SYS_LDO; // 使用LDO(低压差线性稳压器)电源模式 80003f2: 2302 movs r3, #2 80003f4: f887 3028 strb.w r3, [r7, #40] @ 0x28 pll_config.smps_level = 0; // SMPS(开关模式电源)级别 80003f8: 2300 movs r3, #0 80003fa: f887 3029 strb.w r3, [r7, #41] @ 0x29 // 应用PLL配置,完成系统时钟设置 rcc_clock_setup_pll(&pll_config); 80003fe: 463b mov r3, r7 8000400: 4618 mov r0, r3 8000402: f001 f84d bl 80014a0 } 8000406: bf00 nop 8000408: 3730 adds r7, #48 @ 0x30 800040a: 46bd mov sp, r7 800040c: bd80 pop {r7, pc} 800040e: bf00 nop 8000410: 58021c00 .word 0x58021c00 8000414: 017d7840 .word 0x017d7840 08000418 : * 最大延时时间受限于32位无符号整数的最大值(约49.7天)。 * * @see systick, __WFI() */ void user_delay_ms(uint32_t ms) { 8000418: b480 push {r7} 800041a: b085 sub sp, #20 800041c: af00 add r7, sp, #0 800041e: 6078 str r0, [r7, #4] // 记录开始延时的时刻(systick的当前值) uint32_t start = systick; 8000420: 4b09 ldr r3, [pc, #36] @ (8000448 ) 8000422: 681b ldr r3, [r3, #0] 8000424: 60fb str r3, [r7, #12] // 循环等待,直到经过的时间达到指定的毫秒数 while (systick - start < ms) 8000426: e001 b.n 800042c __asm volatile("wfi"); 8000428: bf30 wfi } 800042a: bf00 nop while (systick - start < ms) 800042c: 4b06 ldr r3, [pc, #24] @ (8000448 ) 800042e: 681a ldr r2, [r3, #0] 8000430: 68fb ldr r3, [r7, #12] 8000432: 1ad3 subs r3, r2, r3 8000434: 687a ldr r2, [r7, #4] 8000436: 429a cmp r2, r3 8000438: d8f6 bhi.n 8000428 { // 进入低功耗模式,等待中断唤醒,有助于在延时时降低CPU功耗 __WFI(); } } 800043a: bf00 nop 800043c: bf00 nop 800043e: 3714 adds r7, #20 8000440: 46bd mov sp, r7 8000442: f85d 7b04 ldr.w r7, [sp], #4 8000446: 4770 bx lr 8000448: 20000040 .word 0x20000040 0800044c : * 此函数会覆盖任何之前的SysTick配置,包括中断处理函数的注册。 * * @see sys_tick_handler(), systick, user_delay_ms() */ void systick_init(uint32_t ticks) { 800044c: b580 push {r7, lr} 800044e: b082 sub sp, #8 8000450: af00 add r7, sp, #0 8000452: 6078 str r0, [r7, #4] // 设置SysTick时钟源为AHB总线时钟 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); 8000454: 2004 movs r0, #4 8000456: f001 f9d3 bl 8001800 // 计算重载值:总线频率除以定时器周期数减1 systick_set_reload((rcc_get_bus_clk_freq(RCC_CPUCLK) / ticks) - 1UL); 800045a: 2000 movs r0, #0 800045c: f001 f92c bl 80016b8 8000460: 4602 mov r2, r0 8000462: 687b ldr r3, [r7, #4] 8000464: fbb2 f3f3 udiv r3, r2, r3 8000468: 3b01 subs r3, #1 800046a: 4618 mov r0, r3 800046c: f001 f9c2 bl 80017f4 // 清除SysTick当前值寄存器(被注释掉的代码) //STK_CVR = 0UL; // 使用函数方式清除SysTick计数器 systick_clear(); 8000470: f001 f9de bl 8001830 // 设置SysTick中断优先级为15(最低优先级) nvic_set_priority(NVIC_SYSTICK_IRQ, 15); 8000474: 210f movs r1, #15 8000476: 20ff movs r0, #255 @ 0xff 8000478: f001 f9e8 bl 800184c // 使用函数方式配置SysTick控制寄存器(被注释掉的代码) // STK_CSR = STK_CSR_CLKSOURCE | STK_CSR_TICKINT | STK_CSR_ENABLE; // 分别使能SysTick中断和计数器 systick_interrupt_enable(); 800047c: f001 f9ca bl 8001814 systick_counter_enable(); 8000480: f001 f9cf bl 8001822 } 8000484: bf00 nop 8000486: 3708 adds r7, #8 8000488: 46bd mov sp, r7 800048a: bd80 pop {r7, pc} 0800048c : * 如果systick变量在多线程/多任务环境中被访问,可能需要添加适当的同步机制。 * * @see systick, systick_init(), user_delay_ms() */ void sys_tick_handler(void) { 800048c: b480 push {r7} 800048e: af00 add r7, sp, #0 systick++; 8000490: 4b04 ldr r3, [pc, #16] @ (80004a4 ) 8000492: 681b ldr r3, [r3, #0] 8000494: 3301 adds r3, #1 8000496: 4a03 ldr r2, [pc, #12] @ (80004a4 ) 8000498: 6013 str r3, [r2, #0] } 800049a: bf00 nop 800049c: 46bd mov sp, r7 800049e: f85d 7b04 ldr.w r7, [sp], #4 80004a2: 4770 bx lr 80004a4: 20000040 .word 0x20000040 080004a8 : EBTN_BUTTON_INIT(USER_BUTTON1, &default_param), }; /* ---------------- 获取按键状态 ---------------- */ static uint8_t prv_btn_get_state(struct ebtn_btn* btn) { 80004a8: b580 push {r7, lr} 80004aa: b082 sub sp, #8 80004ac: af00 add r7, sp, #0 80004ae: 6078 str r0, [r7, #4] switch(btn->key_id) 80004b0: 687b ldr r3, [r7, #4] 80004b2: 881b ldrh r3, [r3, #0] 80004b4: 2b00 cmp r3, #0 80004b6: d10c bne.n 80004d2 { case USER_BUTTON1: return gpio_get(GPIOC, GPIO13) == GPIO13; 80004b8: f44f 5100 mov.w r1, #8192 @ 0x2000 80004bc: 4807 ldr r0, [pc, #28] @ (80004dc ) 80004be: f000 fee2 bl 8001286 80004c2: 4603 mov r3, r0 80004c4: f5b3 5f00 cmp.w r3, #8192 @ 0x2000 80004c8: bf0c ite eq 80004ca: 2301 moveq r3, #1 80004cc: 2300 movne r3, #0 80004ce: b2db uxtb r3, r3 80004d0: e000 b.n 80004d4 default: return 0; 80004d2: 2300 movs r3, #0 } } 80004d4: 4618 mov r0, r3 80004d6: 3708 adds r7, #8 80004d8: 46bd mov sp, r7 80004da: bd80 pop {r7, pc} 80004dc: 58020800 .word 0x58020800 080004e0 : /* ---------------- 事件回调函数 ---------------- */ static void prv_btn_event(struct ebtn_btn* btn, ebtn_evt_t evt) { 80004e0: b580 push {r7, lr} 80004e2: b082 sub sp, #8 80004e4: af00 add r7, sp, #0 80004e6: 6078 str r0, [r7, #4] 80004e8: 460b mov r3, r1 80004ea: 70fb strb r3, [r7, #3] switch(evt) 80004ec: 78fb ldrb r3, [r7, #3] 80004ee: 2b03 cmp r3, #3 80004f0: d820 bhi.n 8000534 80004f2: a201 add r2, pc, #4 @ (adr r2, 80004f8 ) 80004f4: f852 f023 ldr.w pc, [r2, r3, lsl #2] 80004f8: 08000535 .word 0x08000535 80004fc: 08000535 .word 0x08000535 8000500: 08000509 .word 0x08000509 8000504: 08000523 .word 0x08000523 break; case EBTN_EVT_ONRELEASE: break; case EBTN_EVT_ONCLICK: if((ebtn_click_get_count(btn) == 2) && (btn->key_id == USER_BUTTON1)) 8000508: 687b ldr r3, [r7, #4] 800050a: 8adb ldrh r3, [r3, #22] 800050c: 2b02 cmp r3, #2 800050e: d113 bne.n 8000538 8000510: 687b ldr r3, [r7, #4] 8000512: 881b ldrh r3, [r3, #0] 8000514: 2b00 cmp r3, #0 8000516: d10f bne.n 8000538 { gpio_toggle(GPIOE, GPIO3); 8000518: 2108 movs r1, #8 800051a: 480b ldr r0, [pc, #44] @ (8000548 ) 800051c: f000 feb6 bl 800128c } //printf("[BTN %d] Clicked, count=%d\r\n", btn->key_id, ebtn_click_get_count(btn)); break; 8000520: e00a b.n 8000538 case EBTN_EVT_KEEPALIVE: if(btn->key_id == USER_BUTTON1) 8000522: 687b ldr r3, [r7, #4] 8000524: 881b ldrh r3, [r3, #0] 8000526: 2b00 cmp r3, #0 8000528: d108 bne.n 800053c { gpio_toggle(GPIOE, GPIO3); 800052a: 2108 movs r1, #8 800052c: 4806 ldr r0, [pc, #24] @ (8000548 ) 800052e: f000 fead bl 800128c } //printf("[BTN %d] Keepalive, cnt=%d\r\n", btn->key_id, ebtn_keepalive_get_count(btn)); break; 8000532: e003 b.n 800053c default: break; 8000534: bf00 nop 8000536: e002 b.n 800053e break; 8000538: bf00 nop 800053a: e000 b.n 800053e break; 800053c: bf00 nop } } 800053e: bf00 nop 8000540: 3708 adds r7, #8 8000542: 46bd mov sp, r7 8000544: bd80 pop {r7, pc} 8000546: bf00 nop 8000548: 58021000 .word 0x58021000 0800054c : /* ---------------- 系统时间 ---------------- */ static uint32_t ebtn_user_get_tick(void) { 800054c: b480 push {r7} 800054e: af00 add r7, sp, #0 return systick; 8000550: 4b03 ldr r3, [pc, #12] @ (8000560 ) 8000552: 681b ldr r3, [r3, #0] } 8000554: 4618 mov r0, r3 8000556: 46bd mov sp, r7 8000558: f85d 7b04 ldr.w r7, [sp], #4 800055c: 4770 bx lr 800055e: bf00 nop 8000560: 20000040 .word 0x20000040 08000564 : /* ---------------- 初始化函数 ---------------- */ void ebtn_user_init(void) { 8000564: b580 push {r7, lr} 8000566: b082 sub sp, #8 8000568: af02 add r7, sp, #8 ebtn_init(btns, 800056a: 4b06 ldr r3, [pc, #24] @ (8000584 ) 800056c: 9301 str r3, [sp, #4] 800056e: 4b06 ldr r3, [pc, #24] @ (8000588 ) 8000570: 9300 str r3, [sp, #0] 8000572: 2300 movs r3, #0 8000574: 2200 movs r2, #0 8000576: 2101 movs r1, #1 8000578: 4804 ldr r0, [pc, #16] @ (800058c ) 800057a: f000 fad3 bl 8000b24 EBTN_ARRAY_SIZE(btns), NULL, 0, // 无组合键 prv_btn_get_state, prv_btn_event); } 800057e: bf00 nop 8000580: 46bd mov sp, r7 8000582: bd80 pop {r7, pc} 8000584: 080004e1 .word 0x080004e1 8000588: 080004a9 .word 0x080004a9 800058c: 20000000 .word 0x20000000 08000590 : /* ---------------- 周期处理函数 ---------------- */ void ebtn_user_process(void) { 8000590: b580 push {r7, lr} 8000592: af00 add r7, sp, #0 ebtn_process(ebtn_user_get_tick()); 8000594: f7ff ffda bl 800054c 8000598: 4603 mov r3, r0 800059a: 4618 mov r0, r3 800059c: f000 fc32 bl 8000e04 } 80005a0: bf00 nop 80005a2: bd80 pop {r7, pc} 080005a4 <_windows_popcount>: #define BIT_ARRAY_DEFINE(name, num_bits) bit_array_t name[BIT_ARRAY_BITMAP_SIZE(num_bits)] #if 1 // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel static inline bit_array_val_t _windows_popcount(bit_array_val_t w) { 80005a4: b480 push {r7} 80005a6: b083 sub sp, #12 80005a8: af00 add r7, sp, #0 80005aa: 6078 str r0, [r7, #4] w = w - ((w >> 1) & (bit_array_val_t) ~(bit_array_val_t)0 / 3); 80005ac: 687b ldr r3, [r7, #4] 80005ae: 085b lsrs r3, r3, #1 80005b0: f003 3355 and.w r3, r3, #1431655765 @ 0x55555555 80005b4: 687a ldr r2, [r7, #4] 80005b6: 1ad3 subs r3, r2, r3 80005b8: 607b str r3, [r7, #4] w = (w & (bit_array_val_t) ~(bit_array_val_t)0 / 15 * 3) + ((w >> 2) & (bit_array_val_t) ~(bit_array_val_t)0 / 15 * 3); 80005ba: 687b ldr r3, [r7, #4] 80005bc: f003 3233 and.w r2, r3, #858993459 @ 0x33333333 80005c0: 687b ldr r3, [r7, #4] 80005c2: 089b lsrs r3, r3, #2 80005c4: f003 3333 and.w r3, r3, #858993459 @ 0x33333333 80005c8: 4413 add r3, r2 80005ca: 607b str r3, [r7, #4] w = (w + (w >> 4)) & (bit_array_val_t) ~(bit_array_val_t)0 / 255 * 15; 80005cc: 687b ldr r3, [r7, #4] 80005ce: 091a lsrs r2, r3, #4 80005d0: 687b ldr r3, [r7, #4] 80005d2: 4413 add r3, r2 80005d4: f003 330f and.w r3, r3, #252645135 @ 0xf0f0f0f 80005d8: 607b str r3, [r7, #4] return (bit_array_val_t)(w * ((bit_array_val_t) ~(bit_array_val_t)0 / 255)) >> (sizeof(bit_array_val_t) - 1) * 8; 80005da: 687a ldr r2, [r7, #4] 80005dc: 4613 mov r3, r2 80005de: 021b lsls r3, r3, #8 80005e0: 4413 add r3, r2 80005e2: 041a lsls r2, r3, #16 80005e4: 4413 add r3, r2 80005e6: 0e1b lsrs r3, r3, #24 } 80005e8: 4618 mov r0, r3 80005ea: 370c adds r7, #12 80005ec: 46bd mov sp, r7 80005ee: f85d 7b04 ldr.w r7, [sp], #4 80005f2: 4770 bx lr 080005f4 : * @param bit Bit number (starting from 0). * * @return true if the bit was set, false if it wasn't. */ static inline int bit_array_get(const bit_array_t *target, int bit) { 80005f4: b480 push {r7} 80005f6: b085 sub sp, #20 80005f8: af00 add r7, sp, #0 80005fa: 6078 str r0, [r7, #4] 80005fc: 6039 str r1, [r7, #0] bit_array_val_t val = BIT_ARRAY_ELEM(target, bit); 80005fe: 683b ldr r3, [r7, #0] 8000600: 095b lsrs r3, r3, #5 8000602: 009b lsls r3, r3, #2 8000604: 687a ldr r2, [r7, #4] 8000606: 4413 add r3, r2 8000608: 681b ldr r3, [r3, #0] 800060a: 60fb str r3, [r7, #12] return (1 & (val >> (bit & (BIT_ARRAY_BITS - 1)))) != 0; 800060c: 683b ldr r3, [r7, #0] 800060e: f003 031f and.w r3, r3, #31 8000612: 68fa ldr r2, [r7, #12] 8000614: fa22 f303 lsr.w r3, r2, r3 8000618: f003 0301 and.w r3, r3, #1 } 800061c: 4618 mov r0, r3 800061e: 3714 adds r7, #20 8000620: 46bd mov sp, r7 8000622: f85d 7b04 ldr.w r7, [sp], #4 8000626: 4770 bx lr 08000628 : * * @param target Address of bit array variable or array. * @param bit Bit number (starting from 0). */ static inline void bit_array_clear(bit_array_t *target, int bit) { 8000628: b480 push {r7} 800062a: b085 sub sp, #20 800062c: af00 add r7, sp, #0 800062e: 6078 str r0, [r7, #4] 8000630: 6039 str r1, [r7, #0] bit_array_val_t mask = BIT_ARRAY_MASK(bit); 8000632: 683b ldr r3, [r7, #0] 8000634: f003 031f and.w r3, r3, #31 8000638: 2201 movs r2, #1 800063a: fa02 f303 lsl.w r3, r2, r3 800063e: 60fb str r3, [r7, #12] BIT_ARRAY_ELEM(target, bit) &= ~mask; 8000640: 683b ldr r3, [r7, #0] 8000642: 095b lsrs r3, r3, #5 8000644: 009a lsls r2, r3, #2 8000646: 6879 ldr r1, [r7, #4] 8000648: 440a add r2, r1 800064a: 6811 ldr r1, [r2, #0] 800064c: 68fa ldr r2, [r7, #12] 800064e: 43d2 mvns r2, r2 8000650: 009b lsls r3, r3, #2 8000652: 6878 ldr r0, [r7, #4] 8000654: 4403 add r3, r0 8000656: 400a ands r2, r1 8000658: 601a str r2, [r3, #0] } 800065a: bf00 nop 800065c: 3714 adds r7, #20 800065e: 46bd mov sp, r7 8000660: f85d 7b04 ldr.w r7, [sp], #4 8000664: 4770 bx lr 08000666 : * * @param target Address of bit array variable or array. * @param bit Bit number (starting from 0). */ static inline void bit_array_set(bit_array_t *target, int bit) { 8000666: b480 push {r7} 8000668: b085 sub sp, #20 800066a: af00 add r7, sp, #0 800066c: 6078 str r0, [r7, #4] 800066e: 6039 str r1, [r7, #0] bit_array_val_t mask = BIT_ARRAY_MASK(bit); 8000670: 683b ldr r3, [r7, #0] 8000672: f003 031f and.w r3, r3, #31 8000676: 2201 movs r2, #1 8000678: fa02 f303 lsl.w r3, r2, r3 800067c: 60fb str r3, [r7, #12] BIT_ARRAY_ELEM(target, bit) |= mask; 800067e: 683b ldr r3, [r7, #0] 8000680: 095b lsrs r3, r3, #5 8000682: 009a lsls r2, r3, #2 8000684: 6879 ldr r1, [r7, #4] 8000686: 440a add r2, r1 8000688: 6811 ldr r1, [r2, #0] 800068a: 009b lsls r3, r3, #2 800068c: 687a ldr r2, [r7, #4] 800068e: 4413 add r3, r2 8000690: 68fa ldr r2, [r7, #12] 8000692: 430a orrs r2, r1 8000694: 601a str r2, [r3, #0] } 8000696: bf00 nop 8000698: 3714 adds r7, #20 800069a: 46bd mov sp, r7 800069c: f85d 7b04 ldr.w r7, [sp], #4 80006a0: 4770 bx lr 080006a2 : * @param target Address of bit array variable or array. * @param bit Bit number (starting from 0). * @param val true for 1, false for 0. */ static inline void bit_array_assign(bit_array_t *target, int bit, int val) { 80006a2: b480 push {r7} 80006a4: b087 sub sp, #28 80006a6: af00 add r7, sp, #0 80006a8: 60f8 str r0, [r7, #12] 80006aa: 60b9 str r1, [r7, #8] 80006ac: 607a str r2, [r7, #4] bit_array_val_t mask = BIT_ARRAY_MASK(bit); 80006ae: 68bb ldr r3, [r7, #8] 80006b0: f003 031f and.w r3, r3, #31 80006b4: 2201 movs r2, #1 80006b6: fa02 f303 lsl.w r3, r2, r3 80006ba: 617b str r3, [r7, #20] if (val) 80006bc: 687b ldr r3, [r7, #4] 80006be: 2b00 cmp r3, #0 80006c0: d00c beq.n 80006dc { BIT_ARRAY_ELEM(target, bit) |= mask; 80006c2: 68bb ldr r3, [r7, #8] 80006c4: 095b lsrs r3, r3, #5 80006c6: 009a lsls r2, r3, #2 80006c8: 68f9 ldr r1, [r7, #12] 80006ca: 440a add r2, r1 80006cc: 6811 ldr r1, [r2, #0] 80006ce: 009b lsls r3, r3, #2 80006d0: 68fa ldr r2, [r7, #12] 80006d2: 4413 add r3, r2 80006d4: 697a ldr r2, [r7, #20] 80006d6: 430a orrs r2, r1 80006d8: 601a str r2, [r3, #0] } else { BIT_ARRAY_ELEM(target, bit) &= ~mask; } } 80006da: e00c b.n 80006f6 BIT_ARRAY_ELEM(target, bit) &= ~mask; 80006dc: 68bb ldr r3, [r7, #8] 80006de: 095b lsrs r3, r3, #5 80006e0: 009a lsls r2, r3, #2 80006e2: 68f9 ldr r1, [r7, #12] 80006e4: 440a add r2, r1 80006e6: 6811 ldr r1, [r2, #0] 80006e8: 697a ldr r2, [r7, #20] 80006ea: 43d2 mvns r2, r2 80006ec: 009b lsls r3, r3, #2 80006ee: 68f8 ldr r0, [r7, #12] 80006f0: 4403 add r3, r0 80006f2: 400a ands r2, r1 80006f4: 601a str r2, [r3, #0] } 80006f6: bf00 nop 80006f8: 371c adds r7, #28 80006fa: 46bd mov sp, r7 80006fc: f85d 7b04 ldr.w r7, [sp], #4 8000700: 4770 bx lr 08000702 : } } // Get the number of bits set (hamming weight) static inline int bit_array_num_bits_set(bit_array_t *target, int num_bits) { 8000702: b580 push {r7, lr} 8000704: b084 sub sp, #16 8000706: af00 add r7, sp, #0 8000708: 6078 str r0, [r7, #4] 800070a: 6039 str r1, [r7, #0] int i; int num_of_bits_set = 0; 800070c: 2300 movs r3, #0 800070e: 60bb str r3, [r7, #8] for (i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++) 8000710: 2300 movs r3, #0 8000712: 60fb str r3, [r7, #12] 8000714: e015 b.n 8000742 { if (target[i] > 0) 8000716: 68fb ldr r3, [r7, #12] 8000718: 009b lsls r3, r3, #2 800071a: 687a ldr r2, [r7, #4] 800071c: 4413 add r3, r2 800071e: 681b ldr r3, [r3, #0] 8000720: 2b00 cmp r3, #0 8000722: d00b beq.n 800073c { num_of_bits_set += POPCOUNT(target[i]); 8000724: 68fb ldr r3, [r7, #12] 8000726: 009b lsls r3, r3, #2 8000728: 687a ldr r2, [r7, #4] 800072a: 4413 add r3, r2 800072c: 681b ldr r3, [r3, #0] 800072e: 4618 mov r0, r3 8000730: f7ff ff38 bl 80005a4 <_windows_popcount> 8000734: 4602 mov r2, r0 8000736: 68bb ldr r3, [r7, #8] 8000738: 4413 add r3, r2 800073a: 60bb str r3, [r7, #8] for (i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++) 800073c: 68fb ldr r3, [r7, #12] 800073e: 3301 adds r3, #1 8000740: 60fb str r3, [r7, #12] 8000742: 683b ldr r3, [r7, #0] 8000744: 3b01 subs r3, #1 8000746: 095b lsrs r3, r3, #5 8000748: 1c5a adds r2, r3, #1 800074a: 68fb ldr r3, [r7, #12] 800074c: 429a cmp r2, r3 800074e: d8e2 bhi.n 8000716 } } return num_of_bits_set; 8000750: 68bb ldr r3, [r7, #8] } 8000752: 4618 mov r0, r3 8000754: 3710 adds r7, #16 8000756: 46bd mov sp, r7 8000758: bd80 pop {r7, pc} 0800075a : _bit_array_mask_top_word(dst, dst_num_bits); } // copy all of src to dst. dst is resized to match src. static inline void bit_array_copy_all(bit_array_t *dst, const bit_array_t *src, int num_bits) { 800075a: b480 push {r7} 800075c: b087 sub sp, #28 800075e: af00 add r7, sp, #0 8000760: 60f8 str r0, [r7, #12] 8000762: 60b9 str r1, [r7, #8] 8000764: 607a str r2, [r7, #4] for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++) 8000766: 2300 movs r3, #0 8000768: 617b str r3, [r7, #20] 800076a: e00c b.n 8000786 { dst[i] = src[i]; 800076c: 697b ldr r3, [r7, #20] 800076e: 009b lsls r3, r3, #2 8000770: 68ba ldr r2, [r7, #8] 8000772: 441a add r2, r3 8000774: 697b ldr r3, [r7, #20] 8000776: 009b lsls r3, r3, #2 8000778: 68f9 ldr r1, [r7, #12] 800077a: 440b add r3, r1 800077c: 6812 ldr r2, [r2, #0] 800077e: 601a str r2, [r3, #0] for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++) 8000780: 697b ldr r3, [r7, #20] 8000782: 3301 adds r3, #1 8000784: 617b str r3, [r7, #20] 8000786: 687b ldr r3, [r7, #4] 8000788: 3b01 subs r3, #1 800078a: 095b lsrs r3, r3, #5 800078c: 1c5a adds r2, r3, #1 800078e: 697b ldr r3, [r7, #20] 8000790: 429a cmp r2, r3 8000792: d8eb bhi.n 800076c } } 8000794: bf00 nop 8000796: bf00 nop 8000798: 371c adds r7, #28 800079a: 46bd mov sp, r7 800079c: f85d 7b04 ldr.w r7, [sp], #4 80007a0: 4770 bx lr 080007a2 : // Logic operators // // Destination can be the same as one or both of the sources static inline void bit_array_and(bit_array_t *dest, const bit_array_t *src1, const bit_array_t *src2, int num_bits) { 80007a2: b480 push {r7} 80007a4: b087 sub sp, #28 80007a6: af00 add r7, sp, #0 80007a8: 60f8 str r0, [r7, #12] 80007aa: 60b9 str r1, [r7, #8] 80007ac: 607a str r2, [r7, #4] 80007ae: 603b str r3, [r7, #0] for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++) 80007b0: 2300 movs r3, #0 80007b2: 617b str r3, [r7, #20] 80007b4: e012 b.n 80007dc { dest[i] = src1[i] & src2[i]; 80007b6: 697b ldr r3, [r7, #20] 80007b8: 009b lsls r3, r3, #2 80007ba: 68ba ldr r2, [r7, #8] 80007bc: 4413 add r3, r2 80007be: 6819 ldr r1, [r3, #0] 80007c0: 697b ldr r3, [r7, #20] 80007c2: 009b lsls r3, r3, #2 80007c4: 687a ldr r2, [r7, #4] 80007c6: 4413 add r3, r2 80007c8: 681a ldr r2, [r3, #0] 80007ca: 697b ldr r3, [r7, #20] 80007cc: 009b lsls r3, r3, #2 80007ce: 68f8 ldr r0, [r7, #12] 80007d0: 4403 add r3, r0 80007d2: 400a ands r2, r1 80007d4: 601a str r2, [r3, #0] for (int i = 0; i < BIT_ARRAY_BITMAP_SIZE(num_bits); i++) 80007d6: 697b ldr r3, [r7, #20] 80007d8: 3301 adds r3, #1 80007da: 617b str r3, [r7, #20] 80007dc: 683b ldr r3, [r7, #0] 80007de: 3b01 subs r3, #1 80007e0: 095b lsrs r3, r3, #5 80007e2: 1c5a adds r2, r3, #1 80007e4: 697b ldr r3, [r7, #20] 80007e6: 429a cmp r2, r3 80007e8: d8e5 bhi.n 80007b6 } } 80007ea: bf00 nop 80007ec: bf00 nop 80007ee: 371c adds r7, #28 80007f0: 46bd mov sp, r7 80007f2: f85d 7b04 ldr.w r7, [sp], #4 80007f6: 4770 bx lr 080007f8 : // returns: // >0 iff bitarr1 > bitarr2 // 0 iff bitarr1 == bitarr2 // <0 iff bitarr1 < bitarr2 static inline int bit_array_cmp(const bit_array_t *bitarr1, const bit_array_t *bitarr2, int num_bits) { 80007f8: b580 push {r7, lr} 80007fa: b084 sub sp, #16 80007fc: af00 add r7, sp, #0 80007fe: 60f8 str r0, [r7, #12] 8000800: 60b9 str r1, [r7, #8] 8000802: 607a str r2, [r7, #4] return memcmp(bitarr1, bitarr2, BIT_ARRAY_BITMAP_SIZE(num_bits) * sizeof(bit_array_val_t)); 8000804: 687b ldr r3, [r7, #4] 8000806: 3b01 subs r3, #1 8000808: 095b lsrs r3, r3, #5 800080a: 3301 adds r3, #1 800080c: 009b lsls r3, r3, #2 800080e: 461a mov r2, r3 8000810: 68b9 ldr r1, [r7, #8] 8000812: 68f8 ldr r0, [r7, #12] 8000814: f001 f90a bl 8001a2c 8000818: 4603 mov r3, r0 } 800081a: 4618 mov r0, r3 800081c: 3710 adds r7, #16 800081e: 46bd mov sp, r7 8000820: bd80 pop {r7, pc} 08000822 : * @param[in] time1: Absolute time expressed in internal time units. * @param[in] time2: Absolute time expressed in internal time units. * @return resulting signed relative time expressed in internal time units. */ static inline ebtn_time_sign_t ebtn_timer_sub(ebtn_time_t time1, ebtn_time_t time2) { 8000822: b480 push {r7} 8000824: b083 sub sp, #12 8000826: af00 add r7, sp, #0 8000828: 6078 str r0, [r7, #4] 800082a: 6039 str r1, [r7, #0] return time1 - time2; 800082c: 687a ldr r2, [r7, #4] 800082e: 683b ldr r3, [r7, #0] 8000830: 1ad3 subs r3, r2, r3 } 8000832: 4618 mov r0, r3 8000834: 370c adds r7, #12 8000836: 46bd mov sp, r7 8000838: f85d 7b04 ldr.w r7, [sp], #4 800083c: 4770 bx lr 0800083e : * \param[in] old_state: old state * \param[in] new_state: new state * \param[in] mstime: Current milliseconds system time */ static void prv_process_btn(ebtn_btn_t *btn, uint8_t old_state, uint8_t new_state, ebtn_time_t mstime) { 800083e: b580 push {r7, lr} 8000840: b086 sub sp, #24 8000842: af00 add r7, sp, #0 8000844: 60f8 str r0, [r7, #12] 8000846: 607b str r3, [r7, #4] 8000848: 460b mov r3, r1 800084a: 72fb strb r3, [r7, #11] 800084c: 4613 mov r3, r2 800084e: 72bb strb r3, [r7, #10] ebtn_t *ebtobj = &ebtn_default; 8000850: 4b7d ldr r3, [pc, #500] @ (8000a48 ) 8000852: 617b str r3, [r7, #20] /* Check params set or not. */ if (btn->param == NULL) 8000854: 68fb ldr r3, [r7, #12] 8000856: 699b ldr r3, [r3, #24] 8000858: 2b00 cmp r3, #0 800085a: f000 815f beq.w 8000b1c { return; } /* Button state has just changed */ if (new_state != old_state) 800085e: 7aba ldrb r2, [r7, #10] 8000860: 7afb ldrb r3, [r7, #11] 8000862: 429a cmp r2, r3 8000864: d00c beq.n 8000880 { btn->time_state_change = mstime; 8000866: 68fb ldr r3, [r7, #12] 8000868: 687a ldr r2, [r7, #4] 800086a: 609a str r2, [r3, #8] if (new_state) 800086c: 7abb ldrb r3, [r7, #10] 800086e: 2b00 cmp r3, #0 8000870: d006 beq.n 8000880 { btn->flags |= EBTN_FLAG_IN_PROCESS; 8000872: 68fb ldr r3, [r7, #12] 8000874: 789b ldrb r3, [r3, #2] 8000876: f043 0302 orr.w r3, r3, #2 800087a: b2da uxtb r2, r3 800087c: 68fb ldr r3, [r7, #12] 800087e: 709a strb r2, [r3, #2] } } /* Button is still pressed */ if (new_state) 8000880: 7abb ldrb r3, [r7, #10] 8000882: 2b00 cmp r3, #0 8000884: f000 8098 beq.w 80009b8 /* * Handle debounce and send on-press event * * This is when we detect valid press */ if (!(btn->flags & EBTN_FLAG_ONPRESS_SENT)) 8000888: 68fb ldr r3, [r7, #12] 800088a: 789b ldrb r3, [r3, #2] 800088c: f003 0301 and.w r3, r3, #1 8000890: 2b00 cmp r3, #0 8000892: d15f bne.n 8000954 * Run if statement when: * * - Runtime mode is enabled -> user sets its own config for debounce * - Config debounce time for press is more than `0` */ if (ebtn_timer_sub(mstime, btn->time_state_change) >= btn->param->time_debounce) 8000894: 68fb ldr r3, [r7, #12] 8000896: 689b ldr r3, [r3, #8] 8000898: 4619 mov r1, r3 800089a: 6878 ldr r0, [r7, #4] 800089c: f7ff ffc1 bl 8000822 80008a0: 4602 mov r2, r0 80008a2: 68fb ldr r3, [r7, #12] 80008a4: 699b ldr r3, [r3, #24] 80008a6: 881b ldrh r3, [r3, #0] 80008a8: 429a cmp r2, r3 80008aa: f2c0 8138 blt.w 8000b1e { /* * Check mutlti click limit reach or not. */ if ((btn->click_cnt > 0) && (ebtn_timer_sub(mstime, btn->click_last_time) >= btn->param->time_click_multi_max)) 80008ae: 68fb ldr r3, [r7, #12] 80008b0: 8adb ldrh r3, [r3, #22] 80008b2: 2b00 cmp r3, #0 80008b4: d019 beq.n 80008ea 80008b6: 68fb ldr r3, [r7, #12] 80008b8: 691b ldr r3, [r3, #16] 80008ba: 4619 mov r1, r3 80008bc: 6878 ldr r0, [r7, #4] 80008be: f7ff ffb0 bl 8000822 80008c2: 4602 mov r2, r0 80008c4: 68fb ldr r3, [r7, #12] 80008c6: 699b ldr r3, [r3, #24] 80008c8: 891b ldrh r3, [r3, #8] 80008ca: 429a cmp r2, r3 80008cc: db0d blt.n 80008ea { if (btn->event_mask & EBTN_EVT_MASK_ONCLICK) 80008ce: 68fb ldr r3, [r7, #12] 80008d0: 78db ldrb r3, [r3, #3] 80008d2: f003 0304 and.w r3, r3, #4 80008d6: 2b00 cmp r3, #0 80008d8: d004 beq.n 80008e4 { ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK); 80008da: 697b ldr r3, [r7, #20] 80008dc: 699b ldr r3, [r3, #24] 80008de: 2102 movs r1, #2 80008e0: 68f8 ldr r0, [r7, #12] 80008e2: 4798 blx r3 } btn->click_cnt = 0; 80008e4: 68fb ldr r3, [r7, #12] 80008e6: 2200 movs r2, #0 80008e8: 82da strh r2, [r3, #22] } /* Set keep alive time */ btn->keepalive_last_time = mstime; 80008ea: 68fb ldr r3, [r7, #12] 80008ec: 687a ldr r2, [r7, #4] 80008ee: 60da str r2, [r3, #12] btn->keepalive_cnt = 0; 80008f0: 68fb ldr r3, [r7, #12] 80008f2: 2200 movs r2, #0 80008f4: 829a strh r2, [r3, #20] /* Start with new on-press */ btn->flags |= EBTN_FLAG_ONPRESS_SENT; 80008f6: 68fb ldr r3, [r7, #12] 80008f8: 789b ldrb r3, [r3, #2] 80008fa: f043 0301 orr.w r3, r3, #1 80008fe: b2da uxtb r2, r3 8000900: 68fb ldr r3, [r7, #12] 8000902: 709a strb r2, [r3, #2] if (btn->event_mask & EBTN_EVT_MASK_ONPRESS) 8000904: 68fb ldr r3, [r7, #12] 8000906: 78db ldrb r3, [r3, #3] 8000908: f003 0301 and.w r3, r3, #1 800090c: 2b00 cmp r3, #0 800090e: d004 beq.n 800091a { ebtobj->evt_fn(btn, EBTN_EVT_ONPRESS); 8000910: 697b ldr r3, [r7, #20] 8000912: 699b ldr r3, [r3, #24] 8000914: 2100 movs r1, #0 8000916: 68f8 ldr r0, [r7, #12] 8000918: 4798 blx r3 } btn->time_change = mstime; /* Button state has now changed */ 800091a: 68fb ldr r3, [r7, #12] 800091c: 687a ldr r2, [r7, #4] 800091e: 605a str r2, [r3, #4] 8000920: e0fd b.n 8000b1e */ else { while ((btn->param->time_keepalive_period > 0) && (ebtn_timer_sub(mstime, btn->keepalive_last_time) >= btn->param->time_keepalive_period)) { btn->keepalive_last_time += btn->param->time_keepalive_period; 8000922: 68fb ldr r3, [r7, #12] 8000924: 68db ldr r3, [r3, #12] 8000926: 68fa ldr r2, [r7, #12] 8000928: 6992 ldr r2, [r2, #24] 800092a: 8952 ldrh r2, [r2, #10] 800092c: 441a add r2, r3 800092e: 68fb ldr r3, [r7, #12] 8000930: 60da str r2, [r3, #12] ++btn->keepalive_cnt; 8000932: 68fb ldr r3, [r7, #12] 8000934: 8a9b ldrh r3, [r3, #20] 8000936: 3301 adds r3, #1 8000938: b29a uxth r2, r3 800093a: 68fb ldr r3, [r7, #12] 800093c: 829a strh r2, [r3, #20] if (btn->event_mask & EBTN_EVT_MASK_KEEPALIVE) 800093e: 68fb ldr r3, [r7, #12] 8000940: 78db ldrb r3, [r3, #3] 8000942: f003 0308 and.w r3, r3, #8 8000946: 2b00 cmp r3, #0 8000948: d004 beq.n 8000954 { ebtobj->evt_fn(btn, EBTN_EVT_KEEPALIVE); 800094a: 697b ldr r3, [r7, #20] 800094c: 699b ldr r3, [r3, #24] 800094e: 2103 movs r1, #3 8000950: 68f8 ldr r0, [r7, #12] 8000952: 4798 blx r3 while ((btn->param->time_keepalive_period > 0) && (ebtn_timer_sub(mstime, btn->keepalive_last_time) >= btn->param->time_keepalive_period)) 8000954: 68fb ldr r3, [r7, #12] 8000956: 699b ldr r3, [r3, #24] 8000958: 895b ldrh r3, [r3, #10] 800095a: 2b00 cmp r3, #0 800095c: d00b beq.n 8000976 800095e: 68fb ldr r3, [r7, #12] 8000960: 68db ldr r3, [r3, #12] 8000962: 4619 mov r1, r3 8000964: 6878 ldr r0, [r7, #4] 8000966: f7ff ff5c bl 8000822 800096a: 4602 mov r2, r0 800096c: 68fb ldr r3, [r7, #12] 800096e: 699b ldr r3, [r3, #24] 8000970: 895b ldrh r3, [r3, #10] 8000972: 429a cmp r2, r3 8000974: dad5 bge.n 8000922 } } // Scene1: multi click end with a long press, need send onclick event. if ((btn->click_cnt > 0) && (ebtn_timer_sub(mstime, btn->time_change) > btn->param->time_click_pressed_max)) 8000976: 68fb ldr r3, [r7, #12] 8000978: 8adb ldrh r3, [r3, #22] 800097a: 2b00 cmp r3, #0 800097c: f000 80cf beq.w 8000b1e 8000980: 68fb ldr r3, [r7, #12] 8000982: 685b ldr r3, [r3, #4] 8000984: 4619 mov r1, r3 8000986: 6878 ldr r0, [r7, #4] 8000988: f7ff ff4b bl 8000822 800098c: 4602 mov r2, r0 800098e: 68fb ldr r3, [r7, #12] 8000990: 699b ldr r3, [r3, #24] 8000992: 88db ldrh r3, [r3, #6] 8000994: 429a cmp r2, r3 8000996: f340 80c2 ble.w 8000b1e { if (btn->event_mask & EBTN_EVT_MASK_ONCLICK) 800099a: 68fb ldr r3, [r7, #12] 800099c: 78db ldrb r3, [r3, #3] 800099e: f003 0304 and.w r3, r3, #4 80009a2: 2b00 cmp r3, #0 80009a4: d004 beq.n 80009b0 { ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK); 80009a6: 697b ldr r3, [r7, #20] 80009a8: 699b ldr r3, [r3, #24] 80009aa: 2102 movs r1, #2 80009ac: 68f8 ldr r0, [r7, #12] 80009ae: 4798 blx r3 } btn->click_cnt = 0; 80009b0: 68fb ldr r3, [r7, #12] 80009b2: 2200 movs r2, #0 80009b4: 82da strh r2, [r3, #22] 80009b6: e0b2 b.n 8000b1e /* * We only need to react if on-press event has even been started. * * Do nothing if that was not the case */ if (btn->flags & EBTN_FLAG_ONPRESS_SENT) 80009b8: 68fb ldr r3, [r7, #12] 80009ba: 789b ldrb r3, [r3, #2] 80009bc: f003 0301 and.w r3, r3, #1 80009c0: 2b00 cmp r3, #0 80009c2: d07e beq.n 8000ac2 * Run if statement when: * * - Runtime mode is enabled -> user sets its own config for debounce * - Config debounce time for release is more than `0` */ if (ebtn_timer_sub(mstime, btn->time_state_change) >= btn->param->time_debounce_release) 80009c4: 68fb ldr r3, [r7, #12] 80009c6: 689b ldr r3, [r3, #8] 80009c8: 4619 mov r1, r3 80009ca: 6878 ldr r0, [r7, #4] 80009cc: f7ff ff29 bl 8000822 80009d0: 4602 mov r2, r0 80009d2: 68fb ldr r3, [r7, #12] 80009d4: 699b ldr r3, [r3, #24] 80009d6: 885b ldrh r3, [r3, #2] 80009d8: 429a cmp r2, r3 80009da: f2c0 80a0 blt.w 8000b1e { /* Handle on-release event */ btn->flags &= ~EBTN_FLAG_ONPRESS_SENT; 80009de: 68fb ldr r3, [r7, #12] 80009e0: 789b ldrb r3, [r3, #2] 80009e2: f023 0301 bic.w r3, r3, #1 80009e6: b2da uxtb r2, r3 80009e8: 68fb ldr r3, [r7, #12] 80009ea: 709a strb r2, [r3, #2] if (btn->event_mask & EBTN_EVT_MASK_ONRELEASE) 80009ec: 68fb ldr r3, [r7, #12] 80009ee: 78db ldrb r3, [r3, #3] 80009f0: f003 0302 and.w r3, r3, #2 80009f4: 2b00 cmp r3, #0 80009f6: d004 beq.n 8000a02 { ebtobj->evt_fn(btn, EBTN_EVT_ONRELEASE); 80009f8: 697b ldr r3, [r7, #20] 80009fa: 699b ldr r3, [r3, #24] 80009fc: 2101 movs r1, #1 80009fe: 68f8 ldr r0, [r7, #12] 8000a00: 4798 blx r3 } /* Check time validity for click event */ if (ebtn_timer_sub(mstime, btn->time_change) >= btn->param->time_click_pressed_min && 8000a02: 68fb ldr r3, [r7, #12] 8000a04: 685b ldr r3, [r3, #4] 8000a06: 4619 mov r1, r3 8000a08: 6878 ldr r0, [r7, #4] 8000a0a: f7ff ff0a bl 8000822 8000a0e: 4602 mov r2, r0 8000a10: 68fb ldr r3, [r7, #12] 8000a12: 699b ldr r3, [r3, #24] 8000a14: 889b ldrh r3, [r3, #4] 8000a16: 429a cmp r2, r3 8000a18: db18 blt.n 8000a4c ebtn_timer_sub(mstime, btn->time_change) <= btn->param->time_click_pressed_max) 8000a1a: 68fb ldr r3, [r7, #12] 8000a1c: 685b ldr r3, [r3, #4] 8000a1e: 4619 mov r1, r3 8000a20: 6878 ldr r0, [r7, #4] 8000a22: f7ff fefe bl 8000822 8000a26: 4602 mov r2, r0 8000a28: 68fb ldr r3, [r7, #12] 8000a2a: 699b ldr r3, [r3, #24] 8000a2c: 88db ldrh r3, [r3, #6] if (ebtn_timer_sub(mstime, btn->time_change) >= btn->param->time_click_pressed_min && 8000a2e: 429a cmp r2, r3 8000a30: dc0c bgt.n 8000a4c { ++btn->click_cnt; 8000a32: 68fb ldr r3, [r7, #12] 8000a34: 8adb ldrh r3, [r3, #22] 8000a36: 3301 adds r3, #1 8000a38: b29a uxth r2, r3 8000a3a: 68fb ldr r3, [r7, #12] 8000a3c: 82da strh r2, [r3, #22] btn->click_last_time = mstime; 8000a3e: 68fb ldr r3, [r7, #12] 8000a40: 687a ldr r2, [r7, #4] 8000a42: 611a str r2, [r3, #16] 8000a44: e020 b.n 8000a88 8000a46: bf00 nop 8000a48: 20000044 .word 0x20000044 } else { // Scene2: If last press was too short, and previous sequence of clicks was // positive, send event to user. if ((btn->click_cnt > 0) && (ebtn_timer_sub(mstime, btn->time_change) < btn->param->time_click_pressed_min)) 8000a4c: 68fb ldr r3, [r7, #12] 8000a4e: 8adb ldrh r3, [r3, #22] 8000a50: 2b00 cmp r3, #0 8000a52: d016 beq.n 8000a82 8000a54: 68fb ldr r3, [r7, #12] 8000a56: 685b ldr r3, [r3, #4] 8000a58: 4619 mov r1, r3 8000a5a: 6878 ldr r0, [r7, #4] 8000a5c: f7ff fee1 bl 8000822 8000a60: 4602 mov r2, r0 8000a62: 68fb ldr r3, [r7, #12] 8000a64: 699b ldr r3, [r3, #24] 8000a66: 889b ldrh r3, [r3, #4] 8000a68: 429a cmp r2, r3 8000a6a: da0a bge.n 8000a82 { if (btn->event_mask & EBTN_EVT_MASK_ONCLICK) 8000a6c: 68fb ldr r3, [r7, #12] 8000a6e: 78db ldrb r3, [r3, #3] 8000a70: f003 0304 and.w r3, r3, #4 8000a74: 2b00 cmp r3, #0 8000a76: d004 beq.n 8000a82 { ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK); 8000a78: 697b ldr r3, [r7, #20] 8000a7a: 699b ldr r3, [r3, #24] 8000a7c: 2102 movs r1, #2 8000a7e: 68f8 ldr r0, [r7, #12] 8000a80: 4798 blx r3 * There was an on-release event, but timing * for click event detection is outside allowed window. * * Reset clicks counter -> not valid sequence for click event. */ btn->click_cnt = 0; 8000a82: 68fb ldr r3, [r7, #12] 8000a84: 2200 movs r2, #0 8000a86: 82da strh r2, [r3, #22] } // Scene3: this part will send on-click event immediately after release event, if // maximum number of consecutive clicks has been reached. if ((btn->click_cnt > 0) && (btn->click_cnt == btn->param->max_consecutive)) 8000a88: 68fb ldr r3, [r7, #12] 8000a8a: 8adb ldrh r3, [r3, #22] 8000a8c: 2b00 cmp r3, #0 8000a8e: d014 beq.n 8000aba 8000a90: 68fb ldr r3, [r7, #12] 8000a92: 8ada ldrh r2, [r3, #22] 8000a94: 68fb ldr r3, [r7, #12] 8000a96: 699b ldr r3, [r3, #24] 8000a98: 899b ldrh r3, [r3, #12] 8000a9a: 429a cmp r2, r3 8000a9c: d10d bne.n 8000aba { if (btn->event_mask & EBTN_EVT_MASK_ONCLICK) 8000a9e: 68fb ldr r3, [r7, #12] 8000aa0: 78db ldrb r3, [r3, #3] 8000aa2: f003 0304 and.w r3, r3, #4 8000aa6: 2b00 cmp r3, #0 8000aa8: d004 beq.n 8000ab4 { ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK); 8000aaa: 697b ldr r3, [r7, #20] 8000aac: 699b ldr r3, [r3, #24] 8000aae: 2102 movs r1, #2 8000ab0: 68f8 ldr r0, [r7, #12] 8000ab2: 4798 blx r3 } btn->click_cnt = 0; 8000ab4: 68fb ldr r3, [r7, #12] 8000ab6: 2200 movs r2, #0 8000ab8: 82da strh r2, [r3, #22] } btn->time_change = mstime; /* Button state has now changed */ 8000aba: 68fb ldr r3, [r7, #12] 8000abc: 687a ldr r2, [r7, #4] 8000abe: 605a str r2, [r3, #4] 8000ac0: e02d b.n 8000b1e * * This feature is useful if users prefers multi-click feature * that is reported only after last click event happened, * including number of clicks made by user */ if (btn->click_cnt > 0) 8000ac2: 68fb ldr r3, [r7, #12] 8000ac4: 8adb ldrh r3, [r3, #22] 8000ac6: 2b00 cmp r3, #0 8000ac8: d01a beq.n 8000b00 { if (ebtn_timer_sub(mstime, btn->click_last_time) >= btn->param->time_click_multi_max) 8000aca: 68fb ldr r3, [r7, #12] 8000acc: 691b ldr r3, [r3, #16] 8000ace: 4619 mov r1, r3 8000ad0: 6878 ldr r0, [r7, #4] 8000ad2: f7ff fea6 bl 8000822 8000ad6: 4602 mov r2, r0 8000ad8: 68fb ldr r3, [r7, #12] 8000ada: 699b ldr r3, [r3, #24] 8000adc: 891b ldrh r3, [r3, #8] 8000ade: 429a cmp r2, r3 8000ae0: db1d blt.n 8000b1e { if (btn->event_mask & EBTN_EVT_MASK_ONCLICK) 8000ae2: 68fb ldr r3, [r7, #12] 8000ae4: 78db ldrb r3, [r3, #3] 8000ae6: f003 0304 and.w r3, r3, #4 8000aea: 2b00 cmp r3, #0 8000aec: d004 beq.n 8000af8 { ebtobj->evt_fn(btn, EBTN_EVT_ONCLICK); 8000aee: 697b ldr r3, [r7, #20] 8000af0: 699b ldr r3, [r3, #24] 8000af2: 2102 movs r1, #2 8000af4: 68f8 ldr r0, [r7, #12] 8000af6: 4798 blx r3 } btn->click_cnt = 0; 8000af8: 68fb ldr r3, [r7, #12] 8000afa: 2200 movs r2, #0 8000afc: 82da strh r2, [r3, #22] 8000afe: e00e b.n 8000b1e } } else { // check button in process if (btn->flags & EBTN_FLAG_IN_PROCESS) 8000b00: 68fb ldr r3, [r7, #12] 8000b02: 789b ldrb r3, [r3, #2] 8000b04: f003 0302 and.w r3, r3, #2 8000b08: 2b00 cmp r3, #0 8000b0a: d008 beq.n 8000b1e { btn->flags &= ~EBTN_FLAG_IN_PROCESS; 8000b0c: 68fb ldr r3, [r7, #12] 8000b0e: 789b ldrb r3, [r3, #2] 8000b10: f023 0302 bic.w r3, r3, #2 8000b14: b2da uxtb r2, r3 8000b16: 68fb ldr r3, [r7, #12] 8000b18: 709a strb r2, [r3, #2] 8000b1a: e000 b.n 8000b1e return; 8000b1c: bf00 nop } } } } } 8000b1e: 3718 adds r7, #24 8000b20: 46bd mov sp, r7 8000b22: bd80 pop {r7, pc} 08000b24 : int ebtn_init(ebtn_btn_t *btns, uint16_t btns_cnt, ebtn_btn_combo_t *btns_combo, uint16_t btns_combo_cnt, ebtn_get_state_fn get_state_fn, ebtn_evt_fn evt_fn) { 8000b24: b580 push {r7, lr} 8000b26: b086 sub sp, #24 8000b28: af00 add r7, sp, #0 8000b2a: 60f8 str r0, [r7, #12] 8000b2c: 607a str r2, [r7, #4] 8000b2e: 461a mov r2, r3 8000b30: 460b mov r3, r1 8000b32: 817b strh r3, [r7, #10] 8000b34: 4613 mov r3, r2 8000b36: 813b strh r3, [r7, #8] ebtn_t *ebtobj = &ebtn_default; 8000b38: 4b12 ldr r3, [pc, #72] @ (8000b84 ) 8000b3a: 617b str r3, [r7, #20] if (evt_fn == NULL || get_state_fn == NULL /* Parameter is a must only in callback-only mode */ 8000b3c: 6a7b ldr r3, [r7, #36] @ 0x24 8000b3e: 2b00 cmp r3, #0 8000b40: d002 beq.n 8000b48 8000b42: 6a3b ldr r3, [r7, #32] 8000b44: 2b00 cmp r3, #0 8000b46: d101 bne.n 8000b4c ) { return 0; 8000b48: 2300 movs r3, #0 8000b4a: e017 b.n 8000b7c } memset(ebtobj, 0x00, sizeof(*ebtobj)); 8000b4c: 2228 movs r2, #40 @ 0x28 8000b4e: 2100 movs r1, #0 8000b50: 6978 ldr r0, [r7, #20] 8000b52: f000 ff99 bl 8001a88 ebtobj->btns = btns; 8000b56: 697b ldr r3, [r7, #20] 8000b58: 68fa ldr r2, [r7, #12] 8000b5a: 601a str r2, [r3, #0] ebtobj->btns_cnt = btns_cnt; 8000b5c: 697b ldr r3, [r7, #20] 8000b5e: 897a ldrh r2, [r7, #10] 8000b60: 809a strh r2, [r3, #4] ebtobj->btns_combo = btns_combo; 8000b62: 697b ldr r3, [r7, #20] 8000b64: 687a ldr r2, [r7, #4] 8000b66: 609a str r2, [r3, #8] ebtobj->btns_combo_cnt = btns_combo_cnt; 8000b68: 697b ldr r3, [r7, #20] 8000b6a: 893a ldrh r2, [r7, #8] 8000b6c: 819a strh r2, [r3, #12] ebtobj->evt_fn = evt_fn; 8000b6e: 697b ldr r3, [r7, #20] 8000b70: 6a7a ldr r2, [r7, #36] @ 0x24 8000b72: 619a str r2, [r3, #24] ebtobj->get_state_fn = get_state_fn; 8000b74: 697b ldr r3, [r7, #20] 8000b76: 6a3a ldr r2, [r7, #32] 8000b78: 61da str r2, [r3, #28] return 1; 8000b7a: 2301 movs r3, #1 } 8000b7c: 4618 mov r0, r3 8000b7e: 3718 adds r7, #24 8000b80: 46bd mov sp, r7 8000b82: bd80 pop {r7, pc} 8000b84: 20000044 .word 0x20000044 08000b88 : * \brief Get all button state with get_state_fn. * * \param[out] state_array: store the button state */ static void ebtn_get_current_state(bit_array_t *state_array) { 8000b88: b580 push {r7, lr} 8000b8a: b086 sub sp, #24 8000b8c: af00 add r7, sp, #0 8000b8e: 6078 str r0, [r7, #4] ebtn_t *ebtobj = &ebtn_default; 8000b90: 4b22 ldr r3, [pc, #136] @ (8000c1c ) 8000b92: 60fb str r3, [r7, #12] ebtn_btn_dyn_t *target; int i; /* Process all buttons */ for (i = 0; i < ebtobj->btns_cnt; ++i) 8000b94: 2300 movs r3, #0 8000b96: 613b str r3, [r7, #16] 8000b98: e016 b.n 8000bc8 { /* Get button state */ uint8_t new_state = ebtobj->get_state_fn(&ebtobj->btns[i]); 8000b9a: 68fb ldr r3, [r7, #12] 8000b9c: 69d9 ldr r1, [r3, #28] 8000b9e: 68fb ldr r3, [r7, #12] 8000ba0: 6818 ldr r0, [r3, #0] 8000ba2: 693a ldr r2, [r7, #16] 8000ba4: 4613 mov r3, r2 8000ba6: 00db lsls r3, r3, #3 8000ba8: 1a9b subs r3, r3, r2 8000baa: 009b lsls r3, r3, #2 8000bac: 4403 add r3, r0 8000bae: 4618 mov r0, r3 8000bb0: 4788 blx r1 8000bb2: 4603 mov r3, r0 8000bb4: 72bb strb r3, [r7, #10] // save state bit_array_assign(state_array, i, new_state); 8000bb6: 7abb ldrb r3, [r7, #10] 8000bb8: 461a mov r2, r3 8000bba: 6939 ldr r1, [r7, #16] 8000bbc: 6878 ldr r0, [r7, #4] 8000bbe: f7ff fd70 bl 80006a2 for (i = 0; i < ebtobj->btns_cnt; ++i) 8000bc2: 693b ldr r3, [r7, #16] 8000bc4: 3301 adds r3, #1 8000bc6: 613b str r3, [r7, #16] 8000bc8: 68fb ldr r3, [r7, #12] 8000bca: 889b ldrh r3, [r3, #4] 8000bcc: 461a mov r2, r3 8000bce: 693b ldr r3, [r7, #16] 8000bd0: 4293 cmp r3, r2 8000bd2: dbe2 blt.n 8000b9a } for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000bd4: 68fb ldr r3, [r7, #12] 8000bd6: 691b ldr r3, [r3, #16] 8000bd8: 617b str r3, [r7, #20] 8000bda: 68fb ldr r3, [r7, #12] 8000bdc: 889b ldrh r3, [r3, #4] 8000bde: 613b str r3, [r7, #16] 8000be0: e013 b.n 8000c0a { /* Get button state */ uint8_t new_state = ebtobj->get_state_fn(&target->btn); 8000be2: 68fb ldr r3, [r7, #12] 8000be4: 69db ldr r3, [r3, #28] 8000be6: 697a ldr r2, [r7, #20] 8000be8: 3204 adds r2, #4 8000bea: 4610 mov r0, r2 8000bec: 4798 blx r3 8000bee: 4603 mov r3, r0 8000bf0: 72fb strb r3, [r7, #11] // save state bit_array_assign(state_array, i, new_state); 8000bf2: 7afb ldrb r3, [r7, #11] 8000bf4: 461a mov r2, r3 8000bf6: 6939 ldr r1, [r7, #16] 8000bf8: 6878 ldr r0, [r7, #4] 8000bfa: f7ff fd52 bl 80006a2 for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000bfe: 697b ldr r3, [r7, #20] 8000c00: 681b ldr r3, [r3, #0] 8000c02: 617b str r3, [r7, #20] 8000c04: 693b ldr r3, [r7, #16] 8000c06: 3301 adds r3, #1 8000c08: 613b str r3, [r7, #16] 8000c0a: 697b ldr r3, [r7, #20] 8000c0c: 2b00 cmp r3, #0 8000c0e: d1e8 bne.n 8000be2 } } 8000c10: bf00 nop 8000c12: bf00 nop 8000c14: 3718 adds r7, #24 8000c16: 46bd mov sp, r7 8000c18: bd80 pop {r7, pc} 8000c1a: bf00 nop 8000c1c: 20000044 .word 0x20000044 08000c20 : * \param[in] curr_state: all button current state * \param[in] idx: Button internal key_idx * \param[in] mstime: Current milliseconds system time */ static void ebtn_process_btn(ebtn_btn_t *btn, bit_array_t *old_state, bit_array_t *curr_state, int idx, ebtn_time_t mstime) { 8000c20: b590 push {r4, r7, lr} 8000c22: b085 sub sp, #20 8000c24: af00 add r7, sp, #0 8000c26: 60f8 str r0, [r7, #12] 8000c28: 60b9 str r1, [r7, #8] 8000c2a: 607a str r2, [r7, #4] 8000c2c: 603b str r3, [r7, #0] prv_process_btn(btn, bit_array_get(old_state, idx), bit_array_get(curr_state, idx), mstime); 8000c2e: 6839 ldr r1, [r7, #0] 8000c30: 68b8 ldr r0, [r7, #8] 8000c32: f7ff fcdf bl 80005f4 8000c36: 4603 mov r3, r0 8000c38: b2dc uxtb r4, r3 8000c3a: 6839 ldr r1, [r7, #0] 8000c3c: 6878 ldr r0, [r7, #4] 8000c3e: f7ff fcd9 bl 80005f4 8000c42: 4603 mov r3, r0 8000c44: b2da uxtb r2, r3 8000c46: 6a3b ldr r3, [r7, #32] 8000c48: 4621 mov r1, r4 8000c4a: 68f8 ldr r0, [r7, #12] 8000c4c: f7ff fdf7 bl 800083e } 8000c50: bf00 nop 8000c52: 3714 adds r7, #20 8000c54: 46bd mov sp, r7 8000c56: bd90 pop {r4, r7, pc} 08000c58 : * \param[in] curr_state: all button current state * \param[in] comb_key: Combo key * \param[in] mstime: Current milliseconds system time */ static void ebtn_process_btn_combo(ebtn_btn_t *btn, bit_array_t *old_state, bit_array_t *curr_state, bit_array_t *comb_key, ebtn_time_t mstime) { 8000c58: b580 push {r7, lr} 8000c5a: b088 sub sp, #32 8000c5c: af00 add r7, sp, #0 8000c5e: 60f8 str r0, [r7, #12] 8000c60: 60b9 str r1, [r7, #8] 8000c62: 607a str r2, [r7, #4] 8000c64: 603b str r3, [r7, #0] BIT_ARRAY_DEFINE(tmp_data, EBTN_MAX_KEYNUM) = {0}; 8000c66: f107 0314 add.w r3, r7, #20 8000c6a: 2200 movs r2, #0 8000c6c: 601a str r2, [r3, #0] 8000c6e: 605a str r2, [r3, #4] if (bit_array_num_bits_set(comb_key, EBTN_MAX_KEYNUM) == 0) 8000c70: 2140 movs r1, #64 @ 0x40 8000c72: 6838 ldr r0, [r7, #0] 8000c74: f7ff fd45 bl 8000702 8000c78: 4603 mov r3, r0 8000c7a: 2b00 cmp r3, #0 8000c7c: d030 beq.n 8000ce0 { return; } bit_array_and(tmp_data, curr_state, comb_key, EBTN_MAX_KEYNUM); 8000c7e: f107 0014 add.w r0, r7, #20 8000c82: 2340 movs r3, #64 @ 0x40 8000c84: 683a ldr r2, [r7, #0] 8000c86: 6879 ldr r1, [r7, #4] 8000c88: f7ff fd8b bl 80007a2 uint8_t curr = bit_array_cmp(tmp_data, comb_key, EBTN_MAX_KEYNUM) == 0; 8000c8c: f107 0314 add.w r3, r7, #20 8000c90: 2240 movs r2, #64 @ 0x40 8000c92: 6839 ldr r1, [r7, #0] 8000c94: 4618 mov r0, r3 8000c96: f7ff fdaf bl 80007f8 8000c9a: 4603 mov r3, r0 8000c9c: 2b00 cmp r3, #0 8000c9e: bf0c ite eq 8000ca0: 2301 moveq r3, #1 8000ca2: 2300 movne r3, #0 8000ca4: b2db uxtb r3, r3 8000ca6: 77fb strb r3, [r7, #31] bit_array_and(tmp_data, old_state, comb_key, EBTN_MAX_KEYNUM); 8000ca8: f107 0014 add.w r0, r7, #20 8000cac: 2340 movs r3, #64 @ 0x40 8000cae: 683a ldr r2, [r7, #0] 8000cb0: 68b9 ldr r1, [r7, #8] 8000cb2: f7ff fd76 bl 80007a2 uint8_t old = bit_array_cmp(tmp_data, comb_key, EBTN_MAX_KEYNUM) == 0; 8000cb6: f107 0314 add.w r3, r7, #20 8000cba: 2240 movs r2, #64 @ 0x40 8000cbc: 6839 ldr r1, [r7, #0] 8000cbe: 4618 mov r0, r3 8000cc0: f7ff fd9a bl 80007f8 8000cc4: 4603 mov r3, r0 8000cc6: 2b00 cmp r3, #0 8000cc8: bf0c ite eq 8000cca: 2301 moveq r3, #1 8000ccc: 2300 movne r3, #0 8000cce: b2db uxtb r3, r3 8000cd0: 77bb strb r3, [r7, #30] prv_process_btn(btn, old, curr, mstime); 8000cd2: 7ffa ldrb r2, [r7, #31] 8000cd4: 7fb9 ldrb r1, [r7, #30] 8000cd6: 6abb ldr r3, [r7, #40] @ 0x28 8000cd8: 68f8 ldr r0, [r7, #12] 8000cda: f7ff fdb0 bl 800083e 8000cde: e000 b.n 8000ce2 return; 8000ce0: bf00 nop } 8000ce2: 3720 adds r7, #32 8000ce4: 46bd mov sp, r7 8000ce6: bd80 pop {r7, pc} 08000ce8 : void ebtn_process_with_curr_state(bit_array_t *curr_state, ebtn_time_t mstime) { 8000ce8: b590 push {r4, r7, lr} 8000cea: b089 sub sp, #36 @ 0x24 8000cec: af02 add r7, sp, #8 8000cee: 6078 str r0, [r7, #4] 8000cf0: 6039 str r1, [r7, #0] ebtn_t *ebtobj = &ebtn_default; 8000cf2: 4b43 ldr r3, [pc, #268] @ (8000e00 ) 8000cf4: 60bb str r3, [r7, #8] ebtn_btn_dyn_t *target; ebtn_btn_combo_dyn_t *target_combo; int i; /* Process all buttons */ for (i = 0; i < ebtobj->btns_cnt; ++i) 8000cf6: 2300 movs r3, #0 8000cf8: 60fb str r3, [r7, #12] 8000cfa: e013 b.n 8000d24 { ebtn_process_btn(&ebtobj->btns[i], ebtobj->old_state, curr_state, i, mstime); 8000cfc: 68bb ldr r3, [r7, #8] 8000cfe: 6819 ldr r1, [r3, #0] 8000d00: 68fa ldr r2, [r7, #12] 8000d02: 4613 mov r3, r2 8000d04: 00db lsls r3, r3, #3 8000d06: 1a9b subs r3, r3, r2 8000d08: 009b lsls r3, r3, #2 8000d0a: 18c8 adds r0, r1, r3 8000d0c: 68bb ldr r3, [r7, #8] 8000d0e: f103 0120 add.w r1, r3, #32 8000d12: 683b ldr r3, [r7, #0] 8000d14: 9300 str r3, [sp, #0] 8000d16: 68fb ldr r3, [r7, #12] 8000d18: 687a ldr r2, [r7, #4] 8000d1a: f7ff ff81 bl 8000c20 for (i = 0; i < ebtobj->btns_cnt; ++i) 8000d1e: 68fb ldr r3, [r7, #12] 8000d20: 3301 adds r3, #1 8000d22: 60fb str r3, [r7, #12] 8000d24: 68bb ldr r3, [r7, #8] 8000d26: 889b ldrh r3, [r3, #4] 8000d28: 461a mov r2, r3 8000d2a: 68fb ldr r3, [r7, #12] 8000d2c: 4293 cmp r3, r2 8000d2e: dbe5 blt.n 8000cfc } for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000d30: 68bb ldr r3, [r7, #8] 8000d32: 691b ldr r3, [r3, #16] 8000d34: 617b str r3, [r7, #20] 8000d36: 68bb ldr r3, [r7, #8] 8000d38: 889b ldrh r3, [r3, #4] 8000d3a: 60fb str r3, [r7, #12] 8000d3c: e010 b.n 8000d60 { ebtn_process_btn(&target->btn, ebtobj->old_state, curr_state, i, mstime); 8000d3e: 697b ldr r3, [r7, #20] 8000d40: 1d18 adds r0, r3, #4 8000d42: 68bb ldr r3, [r7, #8] 8000d44: f103 0120 add.w r1, r3, #32 8000d48: 683b ldr r3, [r7, #0] 8000d4a: 9300 str r3, [sp, #0] 8000d4c: 68fb ldr r3, [r7, #12] 8000d4e: 687a ldr r2, [r7, #4] 8000d50: f7ff ff66 bl 8000c20 for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000d54: 697b ldr r3, [r7, #20] 8000d56: 681b ldr r3, [r3, #0] 8000d58: 617b str r3, [r7, #20] 8000d5a: 68fb ldr r3, [r7, #12] 8000d5c: 3301 adds r3, #1 8000d5e: 60fb str r3, [r7, #12] 8000d60: 697b ldr r3, [r7, #20] 8000d62: 2b00 cmp r3, #0 8000d64: d1eb bne.n 8000d3e } /* Process all comb buttons */ for (i = 0; i < ebtobj->btns_combo_cnt; ++i) 8000d66: 2300 movs r3, #0 8000d68: 60fb str r3, [r7, #12] 8000d6a: e01f b.n 8000dac { ebtn_process_btn_combo(&ebtobj->btns_combo[i].btn, ebtobj->old_state, curr_state, ebtobj->btns_combo[i].comb_key, mstime); 8000d6c: 68bb ldr r3, [r7, #8] 8000d6e: 6899 ldr r1, [r3, #8] 8000d70: 68fa ldr r2, [r7, #12] 8000d72: 4613 mov r3, r2 8000d74: 00db lsls r3, r3, #3 8000d76: 4413 add r3, r2 8000d78: 009b lsls r3, r3, #2 8000d7a: 440b add r3, r1 8000d7c: f103 0008 add.w r0, r3, #8 8000d80: 68bb ldr r3, [r7, #8] 8000d82: f103 0420 add.w r4, r3, #32 8000d86: 68bb ldr r3, [r7, #8] 8000d88: 6899 ldr r1, [r3, #8] 8000d8a: 68fa ldr r2, [r7, #12] 8000d8c: 4613 mov r3, r2 8000d8e: 00db lsls r3, r3, #3 8000d90: 4413 add r3, r2 8000d92: 009b lsls r3, r3, #2 8000d94: 440b add r3, r1 8000d96: 461a mov r2, r3 8000d98: 683b ldr r3, [r7, #0] 8000d9a: 9300 str r3, [sp, #0] 8000d9c: 4613 mov r3, r2 8000d9e: 687a ldr r2, [r7, #4] 8000da0: 4621 mov r1, r4 8000da2: f7ff ff59 bl 8000c58 for (i = 0; i < ebtobj->btns_combo_cnt; ++i) 8000da6: 68fb ldr r3, [r7, #12] 8000da8: 3301 adds r3, #1 8000daa: 60fb str r3, [r7, #12] 8000dac: 68bb ldr r3, [r7, #8] 8000dae: 899b ldrh r3, [r3, #12] 8000db0: 461a mov r2, r3 8000db2: 68fb ldr r3, [r7, #12] 8000db4: 4293 cmp r3, r2 8000db6: dbd9 blt.n 8000d6c } for (target_combo = ebtobj->btn_combo_dyn_head; target_combo; target_combo = target_combo->next) 8000db8: 68bb ldr r3, [r7, #8] 8000dba: 695b ldr r3, [r3, #20] 8000dbc: 613b str r3, [r7, #16] 8000dbe: e010 b.n 8000de2 { ebtn_process_btn_combo(&target_combo->btn.btn, ebtobj->old_state, curr_state, target_combo->btn.comb_key, mstime); 8000dc0: 693b ldr r3, [r7, #16] 8000dc2: f103 000c add.w r0, r3, #12 8000dc6: 68bb ldr r3, [r7, #8] 8000dc8: f103 0120 add.w r1, r3, #32 8000dcc: 693b ldr r3, [r7, #16] 8000dce: 1d1a adds r2, r3, #4 8000dd0: 683b ldr r3, [r7, #0] 8000dd2: 9300 str r3, [sp, #0] 8000dd4: 4613 mov r3, r2 8000dd6: 687a ldr r2, [r7, #4] 8000dd8: f7ff ff3e bl 8000c58 for (target_combo = ebtobj->btn_combo_dyn_head; target_combo; target_combo = target_combo->next) 8000ddc: 693b ldr r3, [r7, #16] 8000dde: 681b ldr r3, [r3, #0] 8000de0: 613b str r3, [r7, #16] 8000de2: 693b ldr r3, [r7, #16] 8000de4: 2b00 cmp r3, #0 8000de6: d1eb bne.n 8000dc0 } bit_array_copy_all(ebtobj->old_state, curr_state, EBTN_MAX_KEYNUM); 8000de8: 68bb ldr r3, [r7, #8] 8000dea: 3320 adds r3, #32 8000dec: 2240 movs r2, #64 @ 0x40 8000dee: 6879 ldr r1, [r7, #4] 8000df0: 4618 mov r0, r3 8000df2: f7ff fcb2 bl 800075a } 8000df6: bf00 nop 8000df8: 371c adds r7, #28 8000dfa: 46bd mov sp, r7 8000dfc: bd90 pop {r4, r7, pc} 8000dfe: bf00 nop 8000e00: 20000044 .word 0x20000044 08000e04 : void ebtn_process(ebtn_time_t mstime) { 8000e04: b580 push {r7, lr} 8000e06: b084 sub sp, #16 8000e08: af00 add r7, sp, #0 8000e0a: 6078 str r0, [r7, #4] BIT_ARRAY_DEFINE(curr_state, EBTN_MAX_KEYNUM) = {0}; 8000e0c: f107 0308 add.w r3, r7, #8 8000e10: 2200 movs r2, #0 8000e12: 601a str r2, [r3, #0] 8000e14: 605a str r2, [r3, #4] // Get Current State ebtn_get_current_state(curr_state); 8000e16: f107 0308 add.w r3, r7, #8 8000e1a: 4618 mov r0, r3 8000e1c: f7ff feb4 bl 8000b88 ebtn_process_with_curr_state(curr_state, mstime); 8000e20: f107 0308 add.w r3, r7, #8 8000e24: 6879 ldr r1, [r7, #4] 8000e26: 4618 mov r0, r3 8000e28: f7ff ff5e bl 8000ce8 } 8000e2c: bf00 nop 8000e2e: 3710 adds r7, #16 8000e30: 46bd mov sp, r7 8000e32: bd80 pop {r7, pc} 08000e34 : int ebtn_get_total_btn_cnt(void) { 8000e34: b480 push {r7} 8000e36: b085 sub sp, #20 8000e38: af00 add r7, sp, #0 ebtn_t *ebtobj = &ebtn_default; 8000e3a: 4b0f ldr r3, [pc, #60] @ (8000e78 ) 8000e3c: 607b str r3, [r7, #4] int total_cnt = 0; 8000e3e: 2300 movs r3, #0 8000e40: 60fb str r3, [r7, #12] ebtn_btn_dyn_t *curr = ebtobj->btn_dyn_head; 8000e42: 687b ldr r3, [r7, #4] 8000e44: 691b ldr r3, [r3, #16] 8000e46: 60bb str r3, [r7, #8] total_cnt += ebtobj->btns_cnt; 8000e48: 687b ldr r3, [r7, #4] 8000e4a: 889b ldrh r3, [r3, #4] 8000e4c: 461a mov r2, r3 8000e4e: 68fb ldr r3, [r7, #12] 8000e50: 4413 add r3, r2 8000e52: 60fb str r3, [r7, #12] while (curr) 8000e54: e005 b.n 8000e62 { total_cnt++; 8000e56: 68fb ldr r3, [r7, #12] 8000e58: 3301 adds r3, #1 8000e5a: 60fb str r3, [r7, #12] curr = curr->next; 8000e5c: 68bb ldr r3, [r7, #8] 8000e5e: 681b ldr r3, [r3, #0] 8000e60: 60bb str r3, [r7, #8] while (curr) 8000e62: 68bb ldr r3, [r7, #8] 8000e64: 2b00 cmp r3, #0 8000e66: d1f6 bne.n 8000e56 } return total_cnt; 8000e68: 68fb ldr r3, [r7, #12] } 8000e6a: 4618 mov r0, r3 8000e6c: 3714 adds r7, #20 8000e6e: 46bd mov sp, r7 8000e70: f85d 7b04 ldr.w r7, [sp], #4 8000e74: 4770 bx lr 8000e76: bf00 nop 8000e78: 20000044 .word 0x20000044 08000e7c : int ebtn_get_btn_index_by_key_id(uint16_t key_id) { 8000e7c: b480 push {r7} 8000e7e: b087 sub sp, #28 8000e80: af00 add r7, sp, #0 8000e82: 4603 mov r3, r0 8000e84: 80fb strh r3, [r7, #6] ebtn_t *ebtobj = &ebtn_default; 8000e86: 4b1e ldr r3, [pc, #120] @ (8000f00 ) 8000e88: 60fb str r3, [r7, #12] int i = 0; 8000e8a: 2300 movs r3, #0 8000e8c: 617b str r3, [r7, #20] ebtn_btn_dyn_t *target; for (i = 0; i < ebtobj->btns_cnt; ++i) 8000e8e: 2300 movs r3, #0 8000e90: 617b str r3, [r7, #20] 8000e92: e010 b.n 8000eb6 { if (ebtobj->btns[i].key_id == key_id) 8000e94: 68fb ldr r3, [r7, #12] 8000e96: 6819 ldr r1, [r3, #0] 8000e98: 697a ldr r2, [r7, #20] 8000e9a: 4613 mov r3, r2 8000e9c: 00db lsls r3, r3, #3 8000e9e: 1a9b subs r3, r3, r2 8000ea0: 009b lsls r3, r3, #2 8000ea2: 440b add r3, r1 8000ea4: 881b ldrh r3, [r3, #0] 8000ea6: 88fa ldrh r2, [r7, #6] 8000ea8: 429a cmp r2, r3 8000eaa: d101 bne.n 8000eb0 { return i; 8000eac: 697b ldr r3, [r7, #20] 8000eae: e021 b.n 8000ef4 for (i = 0; i < ebtobj->btns_cnt; ++i) 8000eb0: 697b ldr r3, [r7, #20] 8000eb2: 3301 adds r3, #1 8000eb4: 617b str r3, [r7, #20] 8000eb6: 68fb ldr r3, [r7, #12] 8000eb8: 889b ldrh r3, [r3, #4] 8000eba: 461a mov r2, r3 8000ebc: 697b ldr r3, [r7, #20] 8000ebe: 4293 cmp r3, r2 8000ec0: dbe8 blt.n 8000e94 } } for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000ec2: 68fb ldr r3, [r7, #12] 8000ec4: 691b ldr r3, [r3, #16] 8000ec6: 613b str r3, [r7, #16] 8000ec8: 68fb ldr r3, [r7, #12] 8000eca: 889b ldrh r3, [r3, #4] 8000ecc: 617b str r3, [r7, #20] 8000ece: e00c b.n 8000eea { if (target->btn.key_id == key_id) 8000ed0: 693b ldr r3, [r7, #16] 8000ed2: 889b ldrh r3, [r3, #4] 8000ed4: 88fa ldrh r2, [r7, #6] 8000ed6: 429a cmp r2, r3 8000ed8: d101 bne.n 8000ede { return i; 8000eda: 697b ldr r3, [r7, #20] 8000edc: e00a b.n 8000ef4 for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000ede: 693b ldr r3, [r7, #16] 8000ee0: 681b ldr r3, [r3, #0] 8000ee2: 613b str r3, [r7, #16] 8000ee4: 697b ldr r3, [r7, #20] 8000ee6: 3301 adds r3, #1 8000ee8: 617b str r3, [r7, #20] 8000eea: 693b ldr r3, [r7, #16] 8000eec: 2b00 cmp r3, #0 8000eee: d1ef bne.n 8000ed0 } } return -1; 8000ef0: f04f 33ff mov.w r3, #4294967295 @ 0xffffffff } 8000ef4: 4618 mov r0, r3 8000ef6: 371c adds r7, #28 8000ef8: 46bd mov sp, r7 8000efa: f85d 7b04 ldr.w r7, [sp], #4 8000efe: 4770 bx lr 8000f00: 20000044 .word 0x20000044 08000f04 : ebtn_btn_t *ebtn_get_btn_by_key_id(uint16_t key_id) { 8000f04: b480 push {r7} 8000f06: b087 sub sp, #28 8000f08: af00 add r7, sp, #0 8000f0a: 4603 mov r3, r0 8000f0c: 80fb strh r3, [r7, #6] ebtn_t *ebtobj = &ebtn_default; 8000f0e: 4b22 ldr r3, [pc, #136] @ (8000f98 ) 8000f10: 60fb str r3, [r7, #12] int i = 0; 8000f12: 2300 movs r3, #0 8000f14: 617b str r3, [r7, #20] ebtn_btn_dyn_t *target; for (i = 0; i < ebtobj->btns_cnt; ++i) 8000f16: 2300 movs r3, #0 8000f18: 617b str r3, [r7, #20] 8000f1a: e017 b.n 8000f4c { if (ebtobj->btns[i].key_id == key_id) 8000f1c: 68fb ldr r3, [r7, #12] 8000f1e: 6819 ldr r1, [r3, #0] 8000f20: 697a ldr r2, [r7, #20] 8000f22: 4613 mov r3, r2 8000f24: 00db lsls r3, r3, #3 8000f26: 1a9b subs r3, r3, r2 8000f28: 009b lsls r3, r3, #2 8000f2a: 440b add r3, r1 8000f2c: 881b ldrh r3, [r3, #0] 8000f2e: 88fa ldrh r2, [r7, #6] 8000f30: 429a cmp r2, r3 8000f32: d108 bne.n 8000f46 { return &ebtobj->btns[i]; 8000f34: 68fb ldr r3, [r7, #12] 8000f36: 6819 ldr r1, [r3, #0] 8000f38: 697a ldr r2, [r7, #20] 8000f3a: 4613 mov r3, r2 8000f3c: 00db lsls r3, r3, #3 8000f3e: 1a9b subs r3, r3, r2 8000f40: 009b lsls r3, r3, #2 8000f42: 440b add r3, r1 8000f44: e021 b.n 8000f8a for (i = 0; i < ebtobj->btns_cnt; ++i) 8000f46: 697b ldr r3, [r7, #20] 8000f48: 3301 adds r3, #1 8000f4a: 617b str r3, [r7, #20] 8000f4c: 68fb ldr r3, [r7, #12] 8000f4e: 889b ldrh r3, [r3, #4] 8000f50: 461a mov r2, r3 8000f52: 697b ldr r3, [r7, #20] 8000f54: 4293 cmp r3, r2 8000f56: dbe1 blt.n 8000f1c } } for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000f58: 68fb ldr r3, [r7, #12] 8000f5a: 691b ldr r3, [r3, #16] 8000f5c: 613b str r3, [r7, #16] 8000f5e: 68fb ldr r3, [r7, #12] 8000f60: 889b ldrh r3, [r3, #4] 8000f62: 617b str r3, [r7, #20] 8000f64: e00d b.n 8000f82 { if (target->btn.key_id == key_id) 8000f66: 693b ldr r3, [r7, #16] 8000f68: 889b ldrh r3, [r3, #4] 8000f6a: 88fa ldrh r2, [r7, #6] 8000f6c: 429a cmp r2, r3 8000f6e: d102 bne.n 8000f76 { return &target->btn; 8000f70: 693b ldr r3, [r7, #16] 8000f72: 3304 adds r3, #4 8000f74: e009 b.n 8000f8a for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8000f76: 693b ldr r3, [r7, #16] 8000f78: 681b ldr r3, [r3, #0] 8000f7a: 613b str r3, [r7, #16] 8000f7c: 697b ldr r3, [r7, #20] 8000f7e: 3301 adds r3, #1 8000f80: 617b str r3, [r7, #20] 8000f82: 693b ldr r3, [r7, #16] 8000f84: 2b00 cmp r3, #0 8000f86: d1ee bne.n 8000f66 } } return NULL; 8000f88: 2300 movs r3, #0 } 8000f8a: 4618 mov r0, r3 8000f8c: 371c adds r7, #28 8000f8e: 46bd mov sp, r7 8000f90: f85d 7b04 ldr.w r7, [sp], #4 8000f94: 4770 bx lr 8000f96: bf00 nop 8000f98: 20000044 .word 0x20000044 08000f9c : int ebtn_get_btn_index_by_btn(ebtn_btn_t *btn) { 8000f9c: b580 push {r7, lr} 8000f9e: b082 sub sp, #8 8000fa0: af00 add r7, sp, #0 8000fa2: 6078 str r0, [r7, #4] return ebtn_get_btn_index_by_key_id(btn->key_id); 8000fa4: 687b ldr r3, [r7, #4] 8000fa6: 881b ldrh r3, [r3, #0] 8000fa8: 4618 mov r0, r3 8000faa: f7ff ff67 bl 8000e7c 8000fae: 4603 mov r3, r0 } 8000fb0: 4618 mov r0, r3 8000fb2: 3708 adds r7, #8 8000fb4: 46bd mov sp, r7 8000fb6: bd80 pop {r7, pc} 08000fb8 : int ebtn_get_btn_index_by_btn_dyn(ebtn_btn_dyn_t *btn) { 8000fb8: b580 push {r7, lr} 8000fba: b082 sub sp, #8 8000fbc: af00 add r7, sp, #0 8000fbe: 6078 str r0, [r7, #4] return ebtn_get_btn_index_by_key_id(btn->btn.key_id); 8000fc0: 687b ldr r3, [r7, #4] 8000fc2: 889b ldrh r3, [r3, #4] 8000fc4: 4618 mov r0, r3 8000fc6: f7ff ff59 bl 8000e7c 8000fca: 4603 mov r3, r0 } 8000fcc: 4618 mov r0, r3 8000fce: 3708 adds r7, #8 8000fd0: 46bd mov sp, r7 8000fd2: bd80 pop {r7, pc} 08000fd4 : void ebtn_combo_btn_add_btn_by_idx(ebtn_btn_combo_t *btn, int idx) { 8000fd4: b580 push {r7, lr} 8000fd6: b082 sub sp, #8 8000fd8: af00 add r7, sp, #0 8000fda: 6078 str r0, [r7, #4] 8000fdc: 6039 str r1, [r7, #0] bit_array_set(btn->comb_key, idx); 8000fde: 687b ldr r3, [r7, #4] 8000fe0: 6839 ldr r1, [r7, #0] 8000fe2: 4618 mov r0, r3 8000fe4: f7ff fb3f bl 8000666 } 8000fe8: bf00 nop 8000fea: 3708 adds r7, #8 8000fec: 46bd mov sp, r7 8000fee: bd80 pop {r7, pc} 08000ff0 : void ebtn_combo_btn_remove_btn_by_idx(ebtn_btn_combo_t *btn, int idx) { 8000ff0: b580 push {r7, lr} 8000ff2: b082 sub sp, #8 8000ff4: af00 add r7, sp, #0 8000ff6: 6078 str r0, [r7, #4] 8000ff8: 6039 str r1, [r7, #0] bit_array_clear(btn->comb_key, idx); 8000ffa: 687b ldr r3, [r7, #4] 8000ffc: 6839 ldr r1, [r7, #0] 8000ffe: 4618 mov r0, r3 8001000: f7ff fb12 bl 8000628 } 8001004: bf00 nop 8001006: 3708 adds r7, #8 8001008: 46bd mov sp, r7 800100a: bd80 pop {r7, pc} 0800100c : void ebtn_combo_btn_add_btn(ebtn_btn_combo_t *btn, uint16_t key_id) { 800100c: b580 push {r7, lr} 800100e: b084 sub sp, #16 8001010: af00 add r7, sp, #0 8001012: 6078 str r0, [r7, #4] 8001014: 460b mov r3, r1 8001016: 807b strh r3, [r7, #2] int idx = ebtn_get_btn_index_by_key_id(key_id); 8001018: 887b ldrh r3, [r7, #2] 800101a: 4618 mov r0, r3 800101c: f7ff ff2e bl 8000e7c 8001020: 60f8 str r0, [r7, #12] if (idx < 0) 8001022: 68fb ldr r3, [r7, #12] 8001024: 2b00 cmp r3, #0 8001026: db04 blt.n 8001032 { return; } ebtn_combo_btn_add_btn_by_idx(btn, idx); 8001028: 68f9 ldr r1, [r7, #12] 800102a: 6878 ldr r0, [r7, #4] 800102c: f7ff ffd2 bl 8000fd4 8001030: e000 b.n 8001034 return; 8001032: bf00 nop } 8001034: 3710 adds r7, #16 8001036: 46bd mov sp, r7 8001038: bd80 pop {r7, pc} 0800103a : void ebtn_combo_btn_remove_btn(ebtn_btn_combo_t *btn, uint16_t key_id) { 800103a: b580 push {r7, lr} 800103c: b084 sub sp, #16 800103e: af00 add r7, sp, #0 8001040: 6078 str r0, [r7, #4] 8001042: 460b mov r3, r1 8001044: 807b strh r3, [r7, #2] int idx = ebtn_get_btn_index_by_key_id(key_id); 8001046: 887b ldrh r3, [r7, #2] 8001048: 4618 mov r0, r3 800104a: f7ff ff17 bl 8000e7c 800104e: 60f8 str r0, [r7, #12] if (idx < 0) 8001050: 68fb ldr r3, [r7, #12] 8001052: 2b00 cmp r3, #0 8001054: db04 blt.n 8001060 { return; } ebtn_combo_btn_remove_btn_by_idx(btn, idx); 8001056: 68f9 ldr r1, [r7, #12] 8001058: 6878 ldr r0, [r7, #4] 800105a: f7ff ffc9 bl 8000ff0 800105e: e000 b.n 8001062 return; 8001060: bf00 nop } 8001062: 3710 adds r7, #16 8001064: 46bd mov sp, r7 8001066: bd80 pop {r7, pc} 08001068 : int ebtn_is_btn_active(const ebtn_btn_t *btn) { 8001068: b480 push {r7} 800106a: b083 sub sp, #12 800106c: af00 add r7, sp, #0 800106e: 6078 str r0, [r7, #4] return btn != NULL && (btn->flags & EBTN_FLAG_ONPRESS_SENT); 8001070: 687b ldr r3, [r7, #4] 8001072: 2b00 cmp r3, #0 8001074: d007 beq.n 8001086 8001076: 687b ldr r3, [r7, #4] 8001078: 789b ldrb r3, [r3, #2] 800107a: f003 0301 and.w r3, r3, #1 800107e: 2b00 cmp r3, #0 8001080: d001 beq.n 8001086 8001082: 2301 movs r3, #1 8001084: e000 b.n 8001088 8001086: 2300 movs r3, #0 } 8001088: 4618 mov r0, r3 800108a: 370c adds r7, #12 800108c: 46bd mov sp, r7 800108e: f85d 7b04 ldr.w r7, [sp], #4 8001092: 4770 bx lr 08001094 : int ebtn_is_btn_in_process(const ebtn_btn_t *btn) { 8001094: b480 push {r7} 8001096: b083 sub sp, #12 8001098: af00 add r7, sp, #0 800109a: 6078 str r0, [r7, #4] return btn != NULL && (btn->flags & EBTN_FLAG_IN_PROCESS); 800109c: 687b ldr r3, [r7, #4] 800109e: 2b00 cmp r3, #0 80010a0: d007 beq.n 80010b2 80010a2: 687b ldr r3, [r7, #4] 80010a4: 789b ldrb r3, [r3, #2] 80010a6: f003 0302 and.w r3, r3, #2 80010aa: 2b00 cmp r3, #0 80010ac: d001 beq.n 80010b2 80010ae: 2301 movs r3, #1 80010b0: e000 b.n 80010b4 80010b2: 2300 movs r3, #0 } 80010b4: 4618 mov r0, r3 80010b6: 370c adds r7, #12 80010b8: 46bd mov sp, r7 80010ba: f85d 7b04 ldr.w r7, [sp], #4 80010be: 4770 bx lr 080010c0 : int ebtn_is_in_process(void) { 80010c0: b580 push {r7, lr} 80010c2: b084 sub sp, #16 80010c4: af00 add r7, sp, #0 ebtn_t *ebtobj = &ebtn_default; 80010c6: 4b37 ldr r3, [pc, #220] @ (80011a4 ) 80010c8: 603b str r3, [r7, #0] ebtn_btn_dyn_t *target; ebtn_btn_combo_dyn_t *target_combo; int i; /* Process all buttons */ for (i = 0; i < ebtobj->btns_cnt; ++i) 80010ca: 2300 movs r3, #0 80010cc: 607b str r3, [r7, #4] 80010ce: e012 b.n 80010f6 { if (ebtn_is_btn_in_process(&ebtobj->btns[i])) 80010d0: 683b ldr r3, [r7, #0] 80010d2: 6819 ldr r1, [r3, #0] 80010d4: 687a ldr r2, [r7, #4] 80010d6: 4613 mov r3, r2 80010d8: 00db lsls r3, r3, #3 80010da: 1a9b subs r3, r3, r2 80010dc: 009b lsls r3, r3, #2 80010de: 440b add r3, r1 80010e0: 4618 mov r0, r3 80010e2: f7ff ffd7 bl 8001094 80010e6: 4603 mov r3, r0 80010e8: 2b00 cmp r3, #0 80010ea: d001 beq.n 80010f0 { return 1; 80010ec: 2301 movs r3, #1 80010ee: e054 b.n 800119a for (i = 0; i < ebtobj->btns_cnt; ++i) 80010f0: 687b ldr r3, [r7, #4] 80010f2: 3301 adds r3, #1 80010f4: 607b str r3, [r7, #4] 80010f6: 683b ldr r3, [r7, #0] 80010f8: 889b ldrh r3, [r3, #4] 80010fa: 461a mov r2, r3 80010fc: 687b ldr r3, [r7, #4] 80010fe: 4293 cmp r3, r2 8001100: dbe6 blt.n 80010d0 } } for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8001102: 683b ldr r3, [r7, #0] 8001104: 691b ldr r3, [r3, #16] 8001106: 60fb str r3, [r7, #12] 8001108: 683b ldr r3, [r7, #0] 800110a: 889b ldrh r3, [r3, #4] 800110c: 607b str r3, [r7, #4] 800110e: e00f b.n 8001130 { if (ebtn_is_btn_in_process(&target->btn)) 8001110: 68fb ldr r3, [r7, #12] 8001112: 3304 adds r3, #4 8001114: 4618 mov r0, r3 8001116: f7ff ffbd bl 8001094 800111a: 4603 mov r3, r0 800111c: 2b00 cmp r3, #0 800111e: d001 beq.n 8001124 { return 1; 8001120: 2301 movs r3, #1 8001122: e03a b.n 800119a for (target = ebtobj->btn_dyn_head, i = ebtobj->btns_cnt; target; target = target->next, i++) 8001124: 68fb ldr r3, [r7, #12] 8001126: 681b ldr r3, [r3, #0] 8001128: 60fb str r3, [r7, #12] 800112a: 687b ldr r3, [r7, #4] 800112c: 3301 adds r3, #1 800112e: 607b str r3, [r7, #4] 8001130: 68fb ldr r3, [r7, #12] 8001132: 2b00 cmp r3, #0 8001134: d1ec bne.n 8001110 } } /* Process all comb buttons */ for (i = 0; i < ebtobj->btns_combo_cnt; ++i) 8001136: 2300 movs r3, #0 8001138: 607b str r3, [r7, #4] 800113a: e013 b.n 8001164 { if (ebtn_is_btn_in_process(&ebtobj->btns_combo[i].btn)) 800113c: 683b ldr r3, [r7, #0] 800113e: 6899 ldr r1, [r3, #8] 8001140: 687a ldr r2, [r7, #4] 8001142: 4613 mov r3, r2 8001144: 00db lsls r3, r3, #3 8001146: 4413 add r3, r2 8001148: 009b lsls r3, r3, #2 800114a: 440b add r3, r1 800114c: 3308 adds r3, #8 800114e: 4618 mov r0, r3 8001150: f7ff ffa0 bl 8001094 8001154: 4603 mov r3, r0 8001156: 2b00 cmp r3, #0 8001158: d001 beq.n 800115e { return 1; 800115a: 2301 movs r3, #1 800115c: e01d b.n 800119a for (i = 0; i < ebtobj->btns_combo_cnt; ++i) 800115e: 687b ldr r3, [r7, #4] 8001160: 3301 adds r3, #1 8001162: 607b str r3, [r7, #4] 8001164: 683b ldr r3, [r7, #0] 8001166: 899b ldrh r3, [r3, #12] 8001168: 461a mov r2, r3 800116a: 687b ldr r3, [r7, #4] 800116c: 4293 cmp r3, r2 800116e: dbe5 blt.n 800113c } } for (target_combo = ebtobj->btn_combo_dyn_head; target_combo; target_combo = target_combo->next) 8001170: 683b ldr r3, [r7, #0] 8001172: 695b ldr r3, [r3, #20] 8001174: 60bb str r3, [r7, #8] 8001176: e00c b.n 8001192 { if (ebtn_is_btn_in_process(&target_combo->btn.btn)) 8001178: 68bb ldr r3, [r7, #8] 800117a: 330c adds r3, #12 800117c: 4618 mov r0, r3 800117e: f7ff ff89 bl 8001094 8001182: 4603 mov r3, r0 8001184: 2b00 cmp r3, #0 8001186: d001 beq.n 800118c { return 1; 8001188: 2301 movs r3, #1 800118a: e006 b.n 800119a for (target_combo = ebtobj->btn_combo_dyn_head; target_combo; target_combo = target_combo->next) 800118c: 68bb ldr r3, [r7, #8] 800118e: 681b ldr r3, [r3, #0] 8001190: 60bb str r3, [r7, #8] 8001192: 68bb ldr r3, [r7, #8] 8001194: 2b00 cmp r3, #0 8001196: d1ef bne.n 8001178 } } return 0; 8001198: 2300 movs r3, #0 } 800119a: 4618 mov r0, r3 800119c: 3710 adds r7, #16 800119e: 46bd mov sp, r7 80011a0: bd80 pop {r7, pc} 80011a2: bf00 nop 80011a4: 20000044 .word 0x20000044 080011a8 : int ebtn_register(ebtn_btn_dyn_t *button) { 80011a8: b580 push {r7, lr} 80011aa: b086 sub sp, #24 80011ac: af00 add r7, sp, #0 80011ae: 6078 str r0, [r7, #4] ebtn_t *ebtobj = &ebtn_default; 80011b0: 4b18 ldr r3, [pc, #96] @ (8001214 ) 80011b2: 60fb str r3, [r7, #12] ebtn_btn_dyn_t *curr = ebtobj->btn_dyn_head; 80011b4: 68fb ldr r3, [r7, #12] 80011b6: 691b ldr r3, [r3, #16] 80011b8: 617b str r3, [r7, #20] ebtn_btn_dyn_t *last = NULL; 80011ba: 2300 movs r3, #0 80011bc: 613b str r3, [r7, #16] if (!button) 80011be: 687b ldr r3, [r7, #4] 80011c0: 2b00 cmp r3, #0 80011c2: d101 bne.n 80011c8 { return 0; 80011c4: 2300 movs r3, #0 80011c6: e020 b.n 800120a } if (ebtn_get_total_btn_cnt() >= EBTN_MAX_KEYNUM) 80011c8: f7ff fe34 bl 8000e34 80011cc: 4603 mov r3, r0 80011ce: 2b3f cmp r3, #63 @ 0x3f 80011d0: dd01 ble.n 80011d6 { return 0; /* reach max cnt. */ 80011d2: 2300 movs r3, #0 80011d4: e019 b.n 800120a } if (curr == NULL) 80011d6: 697b ldr r3, [r7, #20] 80011d8: 2b00 cmp r3, #0 80011da: d10f bne.n 80011fc { ebtobj->btn_dyn_head = button; 80011dc: 68fb ldr r3, [r7, #12] 80011de: 687a ldr r2, [r7, #4] 80011e0: 611a str r2, [r3, #16] return 1; 80011e2: 2301 movs r3, #1 80011e4: e011 b.n 800120a } while (curr) { if (curr == button) 80011e6: 697a ldr r2, [r7, #20] 80011e8: 687b ldr r3, [r7, #4] 80011ea: 429a cmp r2, r3 80011ec: d101 bne.n 80011f2 { return 0; /* already exist. */ 80011ee: 2300 movs r3, #0 80011f0: e00b b.n 800120a } last = curr; 80011f2: 697b ldr r3, [r7, #20] 80011f4: 613b str r3, [r7, #16] curr = curr->next; 80011f6: 697b ldr r3, [r7, #20] 80011f8: 681b ldr r3, [r3, #0] 80011fa: 617b str r3, [r7, #20] while (curr) 80011fc: 697b ldr r3, [r7, #20] 80011fe: 2b00 cmp r3, #0 8001200: d1f1 bne.n 80011e6 } last->next = button; 8001202: 693b ldr r3, [r7, #16] 8001204: 687a ldr r2, [r7, #4] 8001206: 601a str r2, [r3, #0] return 1; 8001208: 2301 movs r3, #1 } 800120a: 4618 mov r0, r3 800120c: 3718 adds r7, #24 800120e: 46bd mov sp, r7 8001210: bd80 pop {r7, pc} 8001212: bf00 nop 8001214: 20000044 .word 0x20000044 08001218 : int ebtn_combo_register(ebtn_btn_combo_dyn_t *button) { 8001218: b480 push {r7} 800121a: b087 sub sp, #28 800121c: af00 add r7, sp, #0 800121e: 6078 str r0, [r7, #4] ebtn_t *ebtobj = &ebtn_default; 8001220: 4b15 ldr r3, [pc, #84] @ (8001278 ) 8001222: 60fb str r3, [r7, #12] ebtn_btn_combo_dyn_t *curr = ebtobj->btn_combo_dyn_head; 8001224: 68fb ldr r3, [r7, #12] 8001226: 695b ldr r3, [r3, #20] 8001228: 617b str r3, [r7, #20] ebtn_btn_combo_dyn_t *last = NULL; 800122a: 2300 movs r3, #0 800122c: 613b str r3, [r7, #16] if (!button) 800122e: 687b ldr r3, [r7, #4] 8001230: 2b00 cmp r3, #0 8001232: d101 bne.n 8001238 { return 0; 8001234: 2300 movs r3, #0 8001236: e019 b.n 800126c } if (curr == NULL) 8001238: 697b ldr r3, [r7, #20] 800123a: 2b00 cmp r3, #0 800123c: d10f bne.n 800125e { ebtobj->btn_combo_dyn_head = button; 800123e: 68fb ldr r3, [r7, #12] 8001240: 687a ldr r2, [r7, #4] 8001242: 615a str r2, [r3, #20] return 1; 8001244: 2301 movs r3, #1 8001246: e011 b.n 800126c } while (curr) { if (curr == button) 8001248: 697a ldr r2, [r7, #20] 800124a: 687b ldr r3, [r7, #4] 800124c: 429a cmp r2, r3 800124e: d101 bne.n 8001254 { return 0; /* already exist. */ 8001250: 2300 movs r3, #0 8001252: e00b b.n 800126c } last = curr; 8001254: 697b ldr r3, [r7, #20] 8001256: 613b str r3, [r7, #16] curr = curr->next; 8001258: 697b ldr r3, [r7, #20] 800125a: 681b ldr r3, [r3, #0] 800125c: 617b str r3, [r7, #20] while (curr) 800125e: 697b ldr r3, [r7, #20] 8001260: 2b00 cmp r3, #0 8001262: d1f1 bne.n 8001248 } last->next = button; 8001264: 693b ldr r3, [r7, #16] 8001266: 687a ldr r2, [r7, #4] 8001268: 601a str r2, [r3, #0] return 1; 800126a: 2301 movs r3, #1 } 800126c: 4618 mov r0, r3 800126e: 371c adds r7, #28 8001270: 46bd mov sp, r7 8001272: f85d 7b04 ldr.w r7, [sp], #4 8001276: 4770 bx lr 8001278: 20000044 .word 0x20000044 0800127c : 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; 800127c: 6181 str r1, [r0, #24] } 800127e: 4770 bx lr 08001280 : 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); 8001280: 0409 lsls r1, r1, #16 8001282: 6181 str r1, [r0, #24] } 8001284: 4770 bx lr 08001286 : @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); 8001286: 6900 ldr r0, [r0, #16] } 8001288: 4008 ands r0, r1 800128a: 4770 bx lr 0800128c : uint32_t port = GPIO_ODR(gpioport); 800128c: 6943 ldr r3, [r0, #20] GPIO_BSRR(gpioport) = ((port & gpios) << 16) | (~port & gpios); 800128e: ea01 0203 and.w r2, r1, r3 8001292: ea21 0103 bic.w r1, r1, r3 8001296: ea41 4102 orr.w r1, r1, r2, lsl #16 800129a: 6181 str r1, [r0, #24] } 800129c: 4770 bx lr 0800129e : 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) { 800129e: 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); 80012a2: 6805 ldr r5, [r0, #0] pupd = GPIO_PUPDR(gpioport); 80012a4: 2600 movs r6, #0 80012a6: 68c4 ldr r4, [r0, #12] for (i = 0; i < 16; i++) { if (!((1 << i) & gpios)) { continue; } moder &= ~GPIO_MODE_MASK(i); 80012a8: f04f 0e03 mov.w lr, #3 if (!((1 << i) & gpios)) { 80012ac: fa43 f706 asr.w r7, r3, r6 80012b0: 07ff lsls r7, r7, #31 80012b2: d50d bpl.n 80012d0 moder &= ~GPIO_MODE_MASK(i); 80012b4: 0077 lsls r7, r6, #1 80012b6: fa0e fc07 lsl.w ip, lr, r7 moder |= GPIO_MODE(i, mode); 80012ba: fa01 f807 lsl.w r8, r1, r7 pupd &= ~GPIO_PUPD_MASK(i); pupd |= GPIO_PUPD(i, pull_up_down); 80012be: fa02 f707 lsl.w r7, r2, r7 moder &= ~GPIO_MODE_MASK(i); 80012c2: ea25 050c bic.w r5, r5, ip pupd &= ~GPIO_PUPD_MASK(i); 80012c6: ea24 040c bic.w r4, r4, ip moder |= GPIO_MODE(i, mode); 80012ca: ea48 0505 orr.w r5, r8, r5 pupd |= GPIO_PUPD(i, pull_up_down); 80012ce: 433c orrs r4, r7 for (i = 0; i < 16; i++) { 80012d0: 3601 adds r6, #1 80012d2: 2e10 cmp r6, #16 80012d4: d1ea bne.n 80012ac } /* Set mode and pull up/down control registers. */ GPIO_MODER(gpioport) = moder; 80012d6: 6005 str r5, [r0, #0] GPIO_PUPDR(gpioport) = pupd; 80012d8: 60c4 str r4, [r0, #12] } 80012da: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} 080012de : uint16_t gpios) { uint16_t i; uint32_t ospeedr; if (otype == 0x1) { 80012de: 2901 cmp r1, #1 GPIO_OTYPER(gpioport) |= gpios; 80012e0: 6841 ldr r1, [r0, #4] 80012e2: bf0c ite eq 80012e4: 4319 orreq r1, r3 } else { GPIO_OTYPER(gpioport) &= ~gpios; 80012e6: 4399 bicne r1, r3 { 80012e8: b5f0 push {r4, r5, r6, r7, lr} GPIO_OTYPER(gpioport) &= ~gpios; 80012ea: 6041 str r1, [r0, #4] } ospeedr = GPIO_OSPEEDR(gpioport); 80012ec: 2400 movs r4, #0 80012ee: 6881 ldr r1, [r0, #8] for (i = 0; i < 16; i++) { if (!((1 << i) & gpios)) { continue; } ospeedr &= ~GPIO_OSPEED_MASK(i); 80012f0: 2603 movs r6, #3 if (!((1 << i) & gpios)) { 80012f2: fa43 f504 asr.w r5, r3, r4 80012f6: 07ed lsls r5, r5, #31 80012f8: d507 bpl.n 800130a ospeedr &= ~GPIO_OSPEED_MASK(i); 80012fa: 0065 lsls r5, r4, #1 80012fc: fa06 f705 lsl.w r7, r6, r5 ospeedr |= GPIO_OSPEED(i, speed); 8001300: fa02 f505 lsl.w r5, r2, r5 ospeedr &= ~GPIO_OSPEED_MASK(i); 8001304: ea21 0107 bic.w r1, r1, r7 ospeedr |= GPIO_OSPEED(i, speed); 8001308: 4329 orrs r1, r5 for (i = 0; i < 16; i++) { 800130a: 3401 adds r4, #1 800130c: 2c10 cmp r4, #16 800130e: d1f0 bne.n 80012f2 } GPIO_OSPEEDR(gpioport) = ospeedr; 8001310: 6081 str r1, [r0, #8] } 8001312: bdf0 pop {r4, r5, r6, r7, pc} 08001314 : .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) { 8001314: 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) { 8001318: f891 c000 ldrb.w ip, [r1] 800131c: f1bc 0f00 cmp.w ip, #0 8001320: f000 80a5 beq.w 800146e return; } struct pll_clocks *pll_tree_ptr; if (pll_num == 1) { 8001324: 2a01 cmp r2, #1 8001326: d026 beq.n 8001376 pll_tree_ptr = &rcc_clock_tree.pll1; } else if (pll_num == 2) { pll_tree_ptr = &rcc_clock_tree.pll2; 8001328: 4b57 ldr r3, [pc, #348] @ (8001488 ) 800132a: 1f9e subs r6, r3, #6 800132c: 2a02 cmp r2, #2 800132e: bf18 it ne 8001330: 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; 8001332: 3a01 subs r2, #1 8001334: 4d55 ldr r5, [pc, #340] @ (800148c ) 8001336: 2300 movs r3, #0 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVN(config->divn); 8001338: f8b1 8002 ldrh.w r8, [r1, #2] RCC_PLLDIVR(pll_num) = 0; 800133c: f845 3032 str.w r3, [r5, r2, lsl #3] RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVN(config->divn); 8001340: f108 33ff add.w r3, r8, #4294967295 @ 0xffffffff 8001344: f855 4032 ldr.w r4, [r5, r2, lsl #3] 8001348: 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 */ 800134a: b2d4 uxtb r4, r2 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVN(config->divn); 800134c: 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 */ 8001350: 00a7 lsls r7, r4, #2 /* Set the PLL input frequency range. */ uint32_t pll_clk_mhz = (clkin / config->divm) / HZ_PER_MHZ; 8001352: fbb0 f3fc udiv r3, r0, ip 8001356: 484e ldr r0, [pc, #312] @ (8001490 ) uint8_t vco_addshift = 4 * (pll_num - 1); /* Values spaced by 4 for PLL 1/2/3 */ 8001358: b2ff uxtb r7, r7 uint32_t pll_clk_mhz = (clkin / config->divm) / HZ_PER_MHZ; 800135a: fbb3 fcf0 udiv ip, r3, r0 if (pll_clk_mhz > 2 && pll_clk_mhz <= 4) { 800135e: f1ac 0003 sub.w r0, ip, #3 8001362: 2801 cmp r0, #1 8001364: 484b ldr r0, [pc, #300] @ (8001494 ) 8001366: d808 bhi.n 800137a RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_2_4MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 8001368: 2304 movs r3, #4 800136a: f8d0 e42c ldr.w lr, [r0, #1068] @ 0x42c 800136e: 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; 8001370: ea4e 0303 orr.w r3, lr, r3 8001374: e00d b.n 8001392 pll_tree_ptr = &rcc_clock_tree.pll1; 8001376: 4e48 ldr r6, [pc, #288] @ (8001498 ) 8001378: e7db b.n 8001332 } else if (pll_clk_mhz > 4 && pll_clk_mhz <= 8) { 800137a: f1ac 0e05 sub.w lr, ip, #5 800137e: f1be 0f03 cmp.w lr, #3 8001382: d876 bhi.n 8001472 RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_4_8MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 8001384: 2308 movs r3, #8 8001386: f8d0 942c ldr.w r9, [r0, #1068] @ 0x42c 800138a: fa03 fe07 lsl.w lr, r3, r7 800138e: ea4e 0309 orr.w r3, lr, r9 RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_8_16MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 8001392: 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); 8001396: fb0c f308 mul.w r3, ip, r8 if (pll_vco_clk_mhz <= 420) { 800139a: f5b3 7fd2 cmp.w r3, #420 @ 0x1a4 800139e: d809 bhi.n 80013b4 RCC_PLLCFGR |= (RCC_PLLCFGR_PLL1VCO_MED << vco_addshift); 80013a0: f8df c0f0 ldr.w ip, [pc, #240] @ 8001494 80013a4: 2002 movs r0, #2 80013a6: f8dc e42c ldr.w lr, [ip, #1068] @ 0x42c 80013aa: 40b8 lsls r0, r7 80013ac: ea40 000e orr.w r0, r0, lr 80013b0: 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 */ 80013b4: 0067 lsls r7, r4, #1 if (config->divp > 0) { 80013b6: 7908 ldrb r0, [r1, #4] uint8_t diven_addshift = 3 * (pll_num - 1); /* Values spaced by 3 for PLL1/2/3 */ 80013b8: eb04 0444 add.w r4, r4, r4, lsl #1 80013bc: b2e4 uxtb r4, r4 if (config->divp > 0) { 80013be: b1b0 cbz r0, 80013ee RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVP(config->divp); 80013c0: f855 c032 ldr.w ip, [r5, r2, lsl #3] 80013c4: f100 3eff add.w lr, r0, #4294967295 @ 0xffffffff 80013c8: ea4c 2c4e orr.w ip, ip, lr, lsl #9 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVP1EN << diven_addshift); 80013cc: f8df e0c4 ldr.w lr, [pc, #196] @ 8001494 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVP(config->divp); 80013d0: f845 c032 str.w ip, [r5, r2, lsl #3] RCC_PLLCFGR |= (RCC_PLLCFGR_DIVP1EN << diven_addshift); 80013d4: f44f 3c80 mov.w ip, #65536 @ 0x10000 80013d8: f8de 842c ldr.w r8, [lr, #1068] @ 0x42c 80013dc: fa0c fc04 lsl.w ip, ip, r4 pll_tree_ptr->p_mhz = pll_vco_clk_mhz / config->divp; 80013e0: fbb3 f0f0 udiv r0, r3, r0 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVP1EN << diven_addshift); 80013e4: ea4c 0c08 orr.w ip, ip, r8 80013e8: f8ce c42c str.w ip, [lr, #1068] @ 0x42c pll_tree_ptr->p_mhz = pll_vco_clk_mhz / config->divp; 80013ec: 8030 strh r0, [r6, #0] } if (config->divq > 0) { 80013ee: 7948 ldrb r0, [r1, #5] 80013f0: b1b0 cbz r0, 8001420 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVQ(config->divq); 80013f2: f855 c032 ldr.w ip, [r5, r2, lsl #3] 80013f6: f100 3eff add.w lr, r0, #4294967295 @ 0xffffffff 80013fa: ea4c 4c0e orr.w ip, ip, lr, lsl #16 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVQ1EN << diven_addshift); 80013fe: f8df e094 ldr.w lr, [pc, #148] @ 8001494 RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVQ(config->divq); 8001402: f845 c032 str.w ip, [r5, r2, lsl #3] RCC_PLLCFGR |= (RCC_PLLCFGR_DIVQ1EN << diven_addshift); 8001406: f44f 3c00 mov.w ip, #131072 @ 0x20000 800140a: f8de 842c ldr.w r8, [lr, #1068] @ 0x42c 800140e: fa0c fc04 lsl.w ip, ip, r4 pll_tree_ptr->q_mhz = pll_vco_clk_mhz / config->divq; 8001412: fbb3 f0f0 udiv r0, r3, r0 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVQ1EN << diven_addshift); 8001416: ea4c 0c08 orr.w ip, ip, r8 800141a: f8ce c42c str.w ip, [lr, #1068] @ 0x42c pll_tree_ptr->q_mhz = pll_vco_clk_mhz / config->divq; 800141e: 8070 strh r0, [r6, #2] } if (config->divr > 0) { 8001420: 7989 ldrb r1, [r1, #6] 8001422: b199 cbz r1, 800144c RCC_PLLDIVR(pll_num) |= RCC_PLLNDIVR_DIVR(config->divr); 8001424: f855 0032 ldr.w r0, [r5, r2, lsl #3] 8001428: f101 3cff add.w ip, r1, #4294967295 @ 0xffffffff 800142c: ea40 600c orr.w r0, r0, ip, lsl #24 8001430: f845 0032 str.w r0, [r5, r2, lsl #3] RCC_PLLCFGR |= (RCC_PLLCFGR_DIVR1EN << diven_addshift); 8001434: f44f 2280 mov.w r2, #262144 @ 0x40000 8001438: 4816 ldr r0, [pc, #88] @ (8001494 ) 800143a: 40a2 lsls r2, r4 800143c: f8d0 542c ldr.w r5, [r0, #1068] @ 0x42c pll_tree_ptr->r_mhz = pll_vco_clk_mhz / config->divr; 8001440: fbb3 f3f1 udiv r3, r3, r1 RCC_PLLCFGR |= (RCC_PLLCFGR_DIVR1EN << diven_addshift); 8001444: 432a orrs r2, r5 8001446: f8c0 242c str.w r2, [r0, #1068] @ 0x42c pll_tree_ptr->r_mhz = pll_vco_clk_mhz / config->divr; 800144a: 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; 800144c: 4a11 ldr r2, [pc, #68] @ (8001494 ) 800144e: b2ff uxtb r7, r7 8001450: f04f 7380 mov.w r3, #16777216 @ 0x1000000 8001454: f8d2 1400 ldr.w r1, [r2, #1024] @ 0x400 8001458: 40bb lsls r3, r7 800145a: 430b orrs r3, r1 800145c: f8c2 3400 str.w r3, [r2, #1024] @ 0x400 while (!(RCC_CR & (RCC_CR_PLL1RDY << cr_addshift))); 8001460: f04f 7300 mov.w r3, #33554432 @ 0x2000000 8001464: 40bb lsls r3, r7 8001466: f8d2 1400 ldr.w r1, [r2, #1024] @ 0x400 800146a: 4219 tst r1, r3 800146c: d0fb beq.n 8001466 } 800146e: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} } else if (pll_clk_mhz > 8) { 8001472: f8df e028 ldr.w lr, [pc, #40] @ 800149c 8001476: 4573 cmp r3, lr 8001478: d98d bls.n 8001396 RCC_PLLCFGR |= (RCC_PLLCFGR_PLLRGE_8_16MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT) << vco_addshift; 800147a: f04f 0e0c mov.w lr, #12 800147e: f8d0 342c ldr.w r3, [r0, #1068] @ 0x42c 8001482: fa0e fe07 lsl.w lr, lr, r7 8001486: e773 b.n 8001370 8001488: 20000036 .word 0x20000036 800148c: 58024430 .word 0x58024430 8001490: 000f4240 .word 0x000f4240 8001494: 58024000 .word 0x58024000 8001498: 2000002a .word 0x2000002a 800149c: 0089543f .word 0x0089543f 080014a0 : /* 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) { 80014a0: 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; 80014a2: 4b81 ldr r3, [pc, #516] @ (80016a8 ) void rcc_clock_setup_pll(const struct rcc_pll_config *config) { 80014a4: 4604 mov r4, r0 RCC_CR |= RCC_CR_HSION; 80014a6: f8d3 2400 ldr.w r2, [r3, #1024] @ 0x400 80014aa: f042 0201 orr.w r2, r2, #1 80014ae: f8c3 2400 str.w r2, [r3, #1024] @ 0x400 RCC_CFGR &= ~(RCC_CFGR_SW_MASK << RCC_CFGR_SW_SHIFT); 80014b2: f8d3 2410 ldr.w r2, [r3, #1040] @ 0x410 80014b6: f022 0207 bic.w r2, r2, #7 80014ba: f8c3 2410 str.w r2, [r3, #1040] @ 0x410 while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_HSI); 80014be: f8d3 2410 ldr.w r2, [r3, #1040] @ 0x410 80014c2: f012 0f38 tst.w r2, #56 @ 0x38 80014c6: d1fa bne.n 80014be RCC_CR = RCC_CR_HSION; 80014c8: 2201 movs r2, #1 80014ca: 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); 80014ce: f894 1029 ldrb.w r1, [r4, #41] @ 0x29 80014d2: f894 0028 ldrb.w r0, [r4, #40] @ 0x28 80014d6: f000 fa2f bl 8001938 pwr_set_vos_scale(config->voltage_scale); 80014da: f894 0027 ldrb.w r0, [r4, #39] @ 0x27 80014de: f000 fa57 bl 8001990 /* Set flash waitstates. Enable flash prefetch if we have at least 1WS */ flash_set_ws(config->flash_waitstates); 80014e2: f894 0026 ldrb.w r0, [r4, #38] @ 0x26 80014e6: f000 f9d3 bl 8001890 if (config->flash_waitstates > FLASH_ACR_LATENCY_0WS) { 80014ea: f894 3026 ldrb.w r3, [r4, #38] @ 0x26 80014ee: 2b00 cmp r3, #0 80014f0: f000 80c5 beq.w 800167e flash_prefetch_enable(); 80014f4: f000 f9bc bl 8001870 } else { flash_prefetch_disable(); } /* User has specified an external oscillator, make sure we turn it on. */ if (config->hse_frequency > 0) { 80014f8: 6863 ldr r3, [r4, #4] 80014fa: b18b cbz r3, 8001520 RCC_CR |= RCC_CR_HSEON; 80014fc: 4b6a ldr r3, [pc, #424] @ (80016a8 ) 80014fe: f8d3 2400 ldr.w r2, [r3, #1024] @ 0x400 8001502: f442 3280 orr.w r2, r2, #65536 @ 0x10000 8001506: f8c3 2400 str.w r2, [r3, #1024] @ 0x400 while (!(RCC_CR & RCC_CR_HSERDY)); 800150a: f8d3 2400 ldr.w r2, [r3, #1024] @ 0x400 800150e: 0392 lsls r2, r2, #14 8001510: d5fb bpl.n 800150a rcc_clock_tree.hse_khz = config->hse_frequency / HZ_PER_KHZ; 8001512: 6863 ldr r3, [r4, #4] 8001514: f44f 727a mov.w r2, #1000 @ 0x3e8 8001518: fbb3 f3f2 udiv r3, r3, r2 800151c: 4a63 ldr r2, [pc, #396] @ (80016ac ) 800151e: 8413 strh r3, [r2, #32] RCC_PLLCKSELR_DIVM2(config->pll2.divm) | 8001520: 7c23 ldrb r3, [r4, #16] RCC_PLLCKSELR = RCC_PLLCKSELR_DIVM1(config->pll1.divm) | 8001522: 7a22 ldrb r2, [r4, #8] RCC_PLLCKSELR_DIVM2(config->pll2.divm) | 8001524: 031b lsls r3, r3, #12 config->pll_source; 8001526: 7861 ldrb r1, [r4, #1] RCC_PLLCKSELR = RCC_PLLCKSELR_DIVM1(config->pll1.divm) | 8001528: ea43 1302 orr.w r3, r3, r2, lsl #4 RCC_PLLCKSELR_DIVM3(config->pll3.divm) | 800152c: 7e22 ldrb r2, [r4, #24] 800152e: 430b orrs r3, r1 8001530: ea43 5302 orr.w r3, r3, r2, lsl #20 RCC_PLLCKSELR = RCC_PLLCKSELR_DIVM1(config->pll1.divm) | 8001534: 4a5c ldr r2, [pc, #368] @ (80016a8 ) 8001536: f8c2 3428 str.w r3, [r2, #1064] @ 0x428 ? RCC_HSI_BASE_FREQUENCY : config->hse_frequency; 800153a: 2900 cmp r1, #0 800153c: f000 80a2 beq.w 8001684 8001540: 6865 ldr r5, [r4, #4] RCC_PLLCFGR = 0; 8001542: 2300 movs r3, #0 rcc_configure_pll(clkin, &config->pll1, 1); 8001544: f104 0108 add.w r1, r4, #8 8001548: 4628 mov r0, r5 RCC_PLLCFGR = 0; 800154a: f8c2 342c str.w r3, [r2, #1068] @ 0x42c rcc_configure_pll(clkin, &config->pll1, 1); 800154e: 2201 movs r2, #1 8001550: f7ff fee0 bl 8001314 rcc_configure_pll(clkin, &config->pll2, 2); 8001554: 2202 movs r2, #2 8001556: f104 0110 add.w r1, r4, #16 800155a: 4628 mov r0, r5 800155c: f7ff feda bl 8001314 rcc_configure_pll(clkin, &config->pll3, 3); 8001560: 4628 mov r0, r5 8001562: 2203 movs r2, #3 8001564: f104 0118 add.w r1, r4, #24 8001568: f7ff fed4 bl 8001314 /* 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) { 800156c: 7823 ldrb r3, [r4, #0] 800156e: 484f ldr r0, [pc, #316] @ (80016ac ) 8001570: 2b00 cmp r3, #0 8001572: f040 8089 bne.w 8001688 rcc_clock_tree.sysclk_mhz = rcc_clock_tree.pll1.p_mhz; 8001576: 89c3 ldrh r3, [r0, #14] 8001578: f894 5024 ldrb.w r5, [r4, #36] @ 0x24 RCC_D1CFGR = 0; 800157c: 2600 movs r6, #0 800157e: 4f4a ldr r7, [pc, #296] @ (80016a8 ) 8001580: f894 1020 ldrb.w r1, [r4, #32] 8001584: f894 2021 ldrb.w r2, [r4, #33] @ 0x21 rcc_clock_tree.sysclk_mhz = rcc_clock_tree.pll1.p_mhz; 8001588: 8003 strh r3, [r0, #0] if (div_val < 0x8) { 800158a: 2907 cmp r1, #7 RCC_D1CFGR = 0; 800158c: f8c7 6418 str.w r6, [r7, #1048] @ 0x418 RCC_D1CFGR_D1HPRE(config->hpre) | RCC_D1CFGR_D1PPRE(config->ppre3); 8001590: ea4f 1605 mov.w r6, r5, lsl #4 RCC_D1CFGR |= RCC_D1CFGR_D1CPRE(config->core_pre) | 8001594: f8d7 c418 ldr.w ip, [r7, #1048] @ 0x418 RCC_D1CFGR_D1HPRE(config->hpre) | RCC_D1CFGR_D1PPRE(config->ppre3); 8001598: ea46 2601 orr.w r6, r6, r1, lsl #8 800159c: ea46 0602 orr.w r6, r6, r2 RCC_D1CFGR |= RCC_D1CFGR_D1CPRE(config->core_pre) | 80015a0: ea46 060c orr.w r6, r6, ip 80015a4: f8c7 6418 str.w r6, [r7, #1048] @ 0x418 if (div_val < 0x8) { 80015a8: d906 bls.n 80015b8 } else if (div_val <= RCC_D1CFGR_D1CPRE_DIV16) { 80015aa: 290b cmp r1, #11 return clk_mhz >> (div_val - 7); 80015ac: bf94 ite ls 80015ae: 3907 subls r1, #7 return clk_mhz >> (div_val - 6); 80015b0: 3906 subhi r1, #6 80015b2: fa43 f101 asr.w r1, r3, r1 80015b6: b28b uxth r3, r1 if (div_val < 0x8) { 80015b8: 2a07 cmp r2, #7 rcc_clock_tree.cpu_mhz = 80015ba: 8043 strh r3, [r0, #2] if (div_val < 0x8) { 80015bc: d909 bls.n 80015d2 } else if (div_val <= RCC_D1CFGR_D1CPRE_DIV16) { 80015be: 2a0b cmp r2, #11 return clk_mhz >> (div_val - 7); 80015c0: bf95 itete ls 80015c2: 3a07 subls r2, #7 return clk_mhz >> (div_val - 6); 80015c4: 1f91 subhi r1, r2, #6 return clk_mhz >> (div_val - 7); 80015c6: fa43 f202 asrls.w r2, r3, r2 return clk_mhz >> (div_val - 6); 80015ca: 410b asrhi r3, r1 return clk_mhz >> (div_val - 7); 80015cc: bf94 ite ls 80015ce: b293 uxthls r3, r2 return clk_mhz >> (div_val - 6); 80015d0: b29b uxthhi r3, r3 if (div_val < 0x4) { 80015d2: 2d03 cmp r5, #3 80015d4: f894 1023 ldrb.w r1, [r4, #35] @ 0x23 RCC_D2CFGR = 0; 80015d8: 4e33 ldr r6, [pc, #204] @ (80016a8 ) return clk_mhz >> (div_val - 3); 80015da: bf8c ite hi 80015dc: 1eea subhi r2, r5, #3 return clk_mhz; 80015de: 461a movls r2, r3 RCC_D2CFGR = 0; 80015e0: f04f 0500 mov.w r5, #0 rcc_clock_tree.hclk_mhz = 80015e4: 8083 strh r3, [r0, #4] return clk_mhz >> (div_val - 3); 80015e6: bf84 itt hi 80015e8: fa43 f202 asrhi.w r2, r3, r2 80015ec: b292 uxthhi r2, r2 if (div_val < 0x4) { 80015ee: 2903 cmp r1, #3 rcc_clock_tree.per.pclk3_mhz = 80015f0: 8142 strh r2, [r0, #10] RCC_D2CFGR = 0; 80015f2: f894 2022 ldrb.w r2, [r4, #34] @ 0x22 80015f6: f8c6 541c str.w r5, [r6, #1052] @ 0x41c RCC_D2CFGR_D2PPRE2(config->ppre2); 80015fa: ea4f 2501 mov.w r5, r1, lsl #8 return clk_mhz >> (div_val - 3); 80015fe: bf8c ite hi 8001600: 3903 subhi r1, #3 return clk_mhz; 8001602: 4619 movls r1, r3 RCC_D2CFGR |= RCC_D2CFGR_D2PPRE1(config->ppre1) | 8001604: ea45 1502 orr.w r5, r5, r2, lsl #4 8001608: f8d6 741c ldr.w r7, [r6, #1052] @ 0x41c return clk_mhz >> (div_val - 3); 800160c: bf88 it hi 800160e: fa43 f101 asrhi.w r1, r3, r1 RCC_D2CFGR |= RCC_D2CFGR_D2PPRE1(config->ppre1) | 8001612: ea45 0507 orr.w r5, r5, r7 return clk_mhz >> (div_val - 3); 8001616: bf88 it hi 8001618: b289 uxthhi r1, r1 if (div_val < 0x4) { 800161a: 2a03 cmp r2, #3 RCC_D2CFGR |= RCC_D2CFGR_D2PPRE1(config->ppre1) | 800161c: f8c6 541c str.w r5, [r6, #1052] @ 0x41c return clk_mhz >> (div_val - 3); 8001620: bf8c ite hi 8001622: 3a03 subhi r2, #3 return clk_mhz; 8001624: 461a movls r2, r3 rcc_clock_tree.per.pclk2_mhz = 8001626: 8101 strh r1, [r0, #8] return clk_mhz >> (div_val - 3); 8001628: bf88 it hi 800162a: fa43 f202 asrhi.w r2, r3, r2 800162e: f894 1025 ldrb.w r1, [r4, #37] @ 0x25 8001632: bf88 it hi 8001634: b292 uxthhi r2, r2 if (div_val < 0x4) { 8001636: 2903 cmp r1, #3 rcc_clock_tree.per.pclk1_mhz = 8001638: 80c2 strh r2, [r0, #6] RCC_D3CFGR &= 0; 800163a: 4a1b ldr r2, [pc, #108] @ (80016a8 ) 800163c: f8d2 4420 ldr.w r4, [r2, #1056] @ 0x420 8001640: f04f 0400 mov.w r4, #0 8001644: f8c2 4420 str.w r4, [r2, #1056] @ 0x420 RCC_D3CFGR |= RCC_D3CFGR_D3PPRE(config->ppre4); 8001648: f8d2 4420 ldr.w r4, [r2, #1056] @ 0x420 800164c: ea44 1401 orr.w r4, r4, r1, lsl #4 return clk_mhz >> (div_val - 3); 8001650: bf84 itt hi 8001652: 3903 subhi r1, #3 8001654: fa43 f101 asrhi.w r1, r3, r1 RCC_D3CFGR |= RCC_D3CFGR_D3PPRE(config->ppre4); 8001658: f8c2 4420 str.w r4, [r2, #1056] @ 0x420 return clk_mhz >> (div_val - 3); 800165c: bf88 it hi 800165e: b28b uxthhi r3, r1 rcc_clock_tree.per.pclk4_mhz = 8001660: 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; 8001662: f8d2 3410 ldr.w r3, [r2, #1040] @ 0x410 8001666: f043 0303 orr.w r3, r3, #3 800166a: f8c2 3410 str.w r3, [r2, #1040] @ 0x410 uint32_t cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 800166e: 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); 8001672: 4a0d ldr r2, [pc, #52] @ (80016a8 ) uint32_t cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 8001674: f3c3 03c2 ubfx r3, r3, #3, #3 while(cfgr_sws != RCC_CFGR_SWS_PLL1) { 8001678: 2b03 cmp r3, #3 800167a: d10f bne.n 800169c } } 800167c: bdf8 pop {r3, r4, r5, r6, r7, pc} flash_prefetch_disable(); 800167e: f000 f8ff bl 8001880 8001682: e739 b.n 80014f8 ? RCC_HSI_BASE_FREQUENCY : config->hse_frequency; 8001684: 4d0a ldr r5, [pc, #40] @ (80016b0 ) 8001686: e75c b.n 8001542 } else if (config->sysclock_source == RCC_HSE) { 8001688: 2b01 cmp r3, #1 rcc_clock_tree.sysclk_mhz = config->hse_frequency / HZ_PER_MHZ; 800168a: bf09 itett eq 800168c: 6863 ldreq r3, [r4, #4] 800168e: 2340 movne r3, #64 @ 0x40 8001690: 4a08 ldreq r2, [pc, #32] @ (80016b4 ) 8001692: fbb3 f3f2 udiveq r3, r3, r2 8001696: bf08 it eq 8001698: b29b uxtheq r3, r3 800169a: e76d b.n 8001578 cfgr_sws = ((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK); 800169c: f8d2 3410 ldr.w r3, [r2, #1040] @ 0x410 80016a0: f3c3 03c2 ubfx r3, r3, #3, #3 80016a4: e7e8 b.n 8001678 80016a6: bf00 nop 80016a8: 58024000 .word 0x58024000 80016ac: 2000001c .word 0x2000001c 80016b0: 03d09000 .word 0x03d09000 80016b4: 000f4240 .word 0x000f4240 080016b8 : uint32_t rcc_get_bus_clk_freq(enum rcc_clock_source source) { 80016b8: b508 push {r3, lr} uint32_t clksel; switch (source) { 80016ba: 2809 cmp r0, #9 80016bc: d82c bhi.n 8001718 80016be: e8df f000 tbb [pc, r0] 80016c2: 050a .short 0x050a 80016c4: 0d0d0a1c .word 0x0d0d0a1c 80016c8: 19161310 .word 0x19161310 case RCC_SYSCLK: return rcc_clock_tree.sysclk_mhz * HZ_PER_MHZ; 80016cc: 4b15 ldr r3, [pc, #84] @ (8001724 ) 80016ce: 8818 ldrh r0, [r3, #0] case RCC_CPUCLK: case RCC_SYSTICKCLK: return rcc_clock_tree.cpu_mhz * HZ_PER_MHZ; 80016d0: 4b15 ldr r3, [pc, #84] @ (8001728 ) 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; 80016d2: 4358 muls r0, r3 } default: cm3_assert_not_reached(); return 0U; } } 80016d4: bd08 pop {r3, pc} return rcc_clock_tree.cpu_mhz * HZ_PER_MHZ; 80016d6: 4b13 ldr r3, [pc, #76] @ (8001724 ) 80016d8: 8858 ldrh r0, [r3, #2] 80016da: e7f9 b.n 80016d0 return rcc_clock_tree.hclk_mhz * HZ_PER_MHZ; 80016dc: 4b11 ldr r3, [pc, #68] @ (8001724 ) 80016de: 8898 ldrh r0, [r3, #4] 80016e0: e7f6 b.n 80016d0 return rcc_clock_tree.per.pclk1_mhz * HZ_PER_MHZ; 80016e2: 4b10 ldr r3, [pc, #64] @ (8001724 ) 80016e4: 88d8 ldrh r0, [r3, #6] 80016e6: e7f3 b.n 80016d0 return rcc_clock_tree.per.pclk2_mhz * HZ_PER_MHZ; 80016e8: 4b0e ldr r3, [pc, #56] @ (8001724 ) 80016ea: 8918 ldrh r0, [r3, #8] 80016ec: e7f0 b.n 80016d0 return rcc_clock_tree.per.pclk3_mhz * HZ_PER_MHZ; 80016ee: 4b0d ldr r3, [pc, #52] @ (8001724 ) 80016f0: 8958 ldrh r0, [r3, #10] 80016f2: e7ed b.n 80016d0 return rcc_clock_tree.per.pclk4_mhz * HZ_PER_MHZ; 80016f4: 4b0b ldr r3, [pc, #44] @ (8001724 ) 80016f6: 8998 ldrh r0, [r3, #12] 80016f8: e7ea b.n 80016d0 clksel = (RCC_D1CCIPR >> RCC_D1CCIPR_CKPERSEL_SHIFT) & RCC_D1CCIPR_CKPERSEL_MASK; 80016fa: 4b0c ldr r3, [pc, #48] @ (800172c ) 80016fc: f8d3 344c ldr.w r3, [r3, #1100] @ 0x44c if (clksel == RCC_D1CCIPR_CKPERSEL_HSI) { 8001700: f013 5f40 tst.w r3, #805306368 @ 0x30000000 clksel = (RCC_D1CCIPR >> RCC_D1CCIPR_CKPERSEL_SHIFT) & RCC_D1CCIPR_CKPERSEL_MASK; 8001704: f3c3 7201 ubfx r2, r3, #28, #2 if (clksel == RCC_D1CCIPR_CKPERSEL_HSI) { 8001708: d008 beq.n 800171c } else if (clksel == RCC_D1CCIPR_CKPERSEL_HSE) { 800170a: 2a02 cmp r2, #2 800170c: d108 bne.n 8001720 return rcc_clock_tree.hse_khz * HZ_PER_KHZ; 800170e: 4b05 ldr r3, [pc, #20] @ (8001724 ) 8001710: 8c18 ldrh r0, [r3, #32] 8001712: f44f 737a mov.w r3, #1000 @ 0x3e8 8001716: e7dc b.n 80016d2 cm3_assert_not_reached(); 8001718: f000 f8a8 bl 800186c return RCC_HSI_BASE_FREQUENCY; 800171c: 4804 ldr r0, [pc, #16] @ (8001730 ) 800171e: e7d9 b.n 80016d4 return 0U; 8001720: 2000 movs r0, #0 8001722: e7d7 b.n 80016d4 8001724: 2000001c .word 0x2000001c 8001728: 000f4240 .word 0x000f4240 800172c: 58024000 .word 0x58024000 8001730: 03d09000 .word 0x03d09000 08001734 : * * 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); 8001734: 0943 lsrs r3, r0, #5 8001736: 2201 movs r2, #1 8001738: f000 001f and.w r0, r0, #31 800173c: f103 43b0 add.w r3, r3, #1476395008 @ 0x58000000 8001740: 4082 lsls r2, r0 8001742: f503 3311 add.w r3, r3, #148480 @ 0x24400 8001746: 6819 ldr r1, [r3, #0] 8001748: 430a orrs r2, r1 800174a: 601a str r2, [r3, #0] } 800174c: 4770 bx lr 0800174e : } void blocking_handler(void) { while (1); 800174e: e7fe b.n 800174e 08001750 : } void null_handler(void) { /* Do nothing. */ } 8001750: 4770 bx lr ... 08001754 : { 8001754: b538 push {r3, r4, r5, lr} for (src = &_data_loadaddr, dest = &_data; 8001756: 4a1d ldr r2, [pc, #116] @ (80017cc ) 8001758: 4b1d ldr r3, [pc, #116] @ (80017d0 ) dest < &_edata; 800175a: 491e ldr r1, [pc, #120] @ (80017d4 ) 800175c: 428b cmp r3, r1 800175e: d320 bcc.n 80017a2 while (dest < &_ebss) { 8001760: 4a1d ldr r2, [pc, #116] @ (80017d8 ) *dest++ = 0; 8001762: 2100 movs r1, #0 while (dest < &_ebss) { 8001764: 4293 cmp r3, r2 8001766: d321 bcc.n 80017ac SCB_CCR |= SCB_CCR_STKALIGN; 8001768: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { 800176c: 4c1b ldr r4, [pc, #108] @ (80017dc ) 800176e: 4d1c ldr r5, [pc, #112] @ (80017e0 ) SCB_CCR |= SCB_CCR_STKALIGN; 8001770: f8d3 2d14 ldr.w r2, [r3, #3348] @ 0xd14 8001774: f442 7200 orr.w r2, r2, #512 @ 0x200 8001778: 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); 800177c: f8d3 2d88 ldr.w r2, [r3, #3464] @ 0xd88 8001780: f442 0270 orr.w r2, r2, #15728640 @ 0xf00000 8001784: f8c3 2d88 str.w r2, [r3, #3464] @ 0xd88 for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { 8001788: 42ac cmp r4, r5 800178a: d312 bcc.n 80017b2 for (fp = &__init_array_start; fp < &__init_array_end; fp++) { 800178c: 4c15 ldr r4, [pc, #84] @ (80017e4 ) 800178e: 4d16 ldr r5, [pc, #88] @ (80017e8 ) 8001790: 42ac cmp r4, r5 8001792: d312 bcc.n 80017ba for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { 8001794: 4c15 ldr r4, [pc, #84] @ (80017ec ) (void)main(); 8001796: f7fe fdaf bl 80002f8
for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { 800179a: 4d15 ldr r5, [pc, #84] @ (80017f0 ) 800179c: 42ac cmp r4, r5 800179e: d310 bcc.n 80017c2 } 80017a0: bd38 pop {r3, r4, r5, pc} *dest = *src; 80017a2: f852 0b04 ldr.w r0, [r2], #4 80017a6: f843 0b04 str.w r0, [r3], #4 src++, dest++) { 80017aa: e7d7 b.n 800175c *dest++ = 0; 80017ac: f843 1b04 str.w r1, [r3], #4 80017b0: e7d8 b.n 8001764 (*fp)(); 80017b2: f854 3b04 ldr.w r3, [r4], #4 80017b6: 4798 blx r3 for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { 80017b8: e7e6 b.n 8001788 (*fp)(); 80017ba: f854 3b04 ldr.w r3, [r4], #4 80017be: 4798 blx r3 for (fp = &__init_array_start; fp < &__init_array_end; fp++) { 80017c0: e7e6 b.n 8001790 (*fp)(); 80017c2: f854 3b04 ldr.w r3, [r4], #4 80017c6: 4798 blx r3 for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { 80017c8: e7e8 b.n 800179c 80017ca: bf00 nop 80017cc: 08001b3c .word 0x08001b3c 80017d0: 20000000 .word 0x20000000 80017d4: 20000040 .word 0x20000040 80017d8: 2000006c .word 0x2000006c 80017dc: 08001b3c .word 0x08001b3c 80017e0: 08001b3c .word 0x08001b3c 80017e4: 08001b3c .word 0x08001b3c 80017e8: 08001b3c .word 0x08001b3c 80017ec: 08001b3c .word 0x08001b3c 80017f0: 08001b3c .word 0x08001b3c 080017f4 : * * @param[in] value uint32_t. 24 bit reload value. */ void systick_set_reload(uint32_t value) { STK_RVR = (value & STK_RVR_RELOAD); 80017f4: f020 407f bic.w r0, r0, #4278190080 @ 0xff000000 80017f8: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 80017fc: 6158 str r0, [r3, #20] } 80017fe: 4770 bx lr 08001800 : * @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) | 8001800: f04f 22e0 mov.w r2, #3758153728 @ 0xe000e000 (clocksource & STK_CSR_CLKSOURCE); 8001804: f000 0004 and.w r0, r0, #4 STK_CSR = (STK_CSR & ~STK_CSR_CLKSOURCE) | 8001808: 6913 ldr r3, [r2, #16] 800180a: f023 0304 bic.w r3, r3, #4 800180e: 4303 orrs r3, r0 8001810: 6113 str r3, [r2, #16] } 8001812: 4770 bx lr 08001814 : * */ void systick_interrupt_enable(void) { STK_CSR |= STK_CSR_TICKINT; 8001814: f04f 22e0 mov.w r2, #3758153728 @ 0xe000e000 8001818: 6913 ldr r3, [r2, #16] 800181a: f043 0302 orr.w r3, r3, #2 800181e: 6113 str r3, [r2, #16] } 8001820: 4770 bx lr 08001822 : * */ void systick_counter_enable(void) { STK_CSR |= STK_CSR_ENABLE; 8001822: f04f 22e0 mov.w r2, #3758153728 @ 0xe000e000 8001826: 6913 ldr r3, [r2, #16] 8001828: f043 0301 orr.w r3, r3, #1 800182c: 6113 str r3, [r2, #16] } 800182e: 4770 bx lr 08001830 : * The counter value is cleared. Useful for well defined startup. */ void systick_clear(void) { STK_CVR = 0; 8001830: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 8001834: 2200 movs r2, #0 8001836: 619a str r2, [r3, #24] } 8001838: 4770 bx lr 0800183a : /* 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; 800183a: f040 60bf orr.w r0, r0, #100139008 @ 0x5f80000 800183e: f04f 23e0 mov.w r3, #3758153728 @ 0xe000e000 8001842: f440 3000 orr.w r0, r0, #131072 @ 0x20000 8001846: f8c3 0d0c str.w r0, [r3, #3340] @ 0xd0c } 800184a: 4770 bx lr 0800184c : 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) { 800184c: 2895 cmp r0, #149 @ 0x95 800184e: d904 bls.n 800185a 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; 8001850: f000 000f and.w r0, r0, #15 8001854: 4b04 ldr r3, [pc, #16] @ (8001868 ) 8001856: 54c1 strb r1, [r0, r3] 8001858: 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; 800185a: f100 4060 add.w r0, r0, #3758096384 @ 0xe0000000 800185e: f500 4064 add.w r0, r0, #58368 @ 0xe400 8001862: 7001 strb r1, [r0, #0] #endif } } 8001864: 4770 bx lr 8001866: bf00 nop 8001868: e000ed14 .word 0xe000ed14 0800186c : #include void __attribute__((weak)) cm3_assert_failed(void) { while (1); 800186c: e7fe b.n 800186c ... 08001870 : #include void flash_prefetch_enable(void) { FLASH_ACR |= FLASH_ACR_PRFTEN; 8001870: 4a02 ldr r2, [pc, #8] @ (800187c ) 8001872: 6813 ldr r3, [r2, #0] 8001874: f443 7380 orr.w r3, r3, #256 @ 0x100 8001878: 6013 str r3, [r2, #0] } 800187a: 4770 bx lr 800187c: 52002000 .word 0x52002000 08001880 : void flash_prefetch_disable(void) { FLASH_ACR &= ~FLASH_ACR_PRFTEN; 8001880: 4a02 ldr r2, [pc, #8] @ (800188c ) 8001882: 6813 ldr r3, [r2, #0] 8001884: f423 7380 bic.w r3, r3, #256 @ 0x100 8001888: 6013 str r3, [r2, #0] } 800188a: 4770 bx lr 800188c: 52002000 .word 0x52002000 08001890 : void flash_set_ws(uint32_t ws) { uint32_t reg32; reg32 = FLASH_ACR; 8001890: 4a03 ldr r2, [pc, #12] @ (80018a0 ) 8001892: 6813 ldr r3, [r2, #0] reg32 &= ~(FLASH_ACR_LATENCY_MASK << FLASH_ACR_LATENCY_SHIFT); 8001894: f023 030f bic.w r3, r3, #15 reg32 |= (ws << FLASH_ACR_LATENCY_SHIFT); 8001898: 4303 orrs r3, r0 FLASH_ACR = reg32; 800189a: 6013 str r3, [r2, #0] } 800189c: 4770 bx lr 800189e: bf00 nop 80018a0: 52002000 .word 0x52002000 080018a4 : #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); 80018a4: 4a04 ldr r2, [pc, #16] @ (80018b8 ) 80018a6: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 80018aa: f023 0307 bic.w r3, r3, #7 80018ae: f043 0302 orr.w r3, r3, #2 80018b2: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 80018b6: 4770 bx lr 80018b8: 58024000 .word 0x58024000 080018bc : 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); 80018bc: 4a04 ldr r2, [pc, #16] @ (80018d0 ) 80018be: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 80018c2: f023 0307 bic.w r3, r3, #7 80018c6: f043 0306 orr.w r3, r3, #6 80018ca: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 80018ce: 4770 bx lr 80018d0: 58024000 .word 0x58024000 080018d4 : void pwr_set_mode_smps_ldo(bool supply_external, uint32_t smps_level, bool use_ldo) { 80018d4: 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); 80018d6: 010b lsls r3, r1, #4 if (supply_external) { 80018d8: b970 cbnz r0, 80018f8 cr3_set = PWR_CR3_SMPSEN | (smps_level << PWR_CR3_SMPSLEVEL_SHIFT); 80018da: f043 0304 orr.w r3, r3, #4 } if (use_ldo) { cr3_set |= PWR_CR3_LDOEN; } PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; 80018de: 4809 ldr r0, [pc, #36] @ (8001904 ) if (use_ldo) { 80018e0: 4252 negs r2, r2 PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; 80018e2: f8d0 180c ldr.w r1, [r0, #2060] @ 0x80c if (use_ldo) { 80018e6: f002 0202 and.w r2, r2, #2 PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; 80018ea: f021 013f bic.w r1, r1, #63 @ 0x3f 80018ee: 430a orrs r2, r1 80018f0: 431a orrs r2, r3 80018f2: f8c0 280c str.w r2, [r0, #2060] @ 0x80c } 80018f6: bd08 pop {r3, pc} cm3_assert(smps_level != PWR_CR3_SMPSLEVEL_VOS); /* Unsupported setting! */ 80018f8: b909 cbnz r1, 80018fe 80018fa: f7ff ffb7 bl 800186c cr3_set |= PWR_CR3_SMPSEXTHP; 80018fe: f043 030c orr.w r3, r3, #12 8001902: e7ec b.n 80018de 8001904: 58024000 .word 0x58024000 08001908 : 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; 8001908: 4a04 ldr r2, [pc, #16] @ (800191c ) 800190a: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 800190e: f023 0307 bic.w r3, r3, #7 8001912: f043 0301 orr.w r3, r3, #1 8001916: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 800191a: 4770 bx lr 800191c: 58024000 .word 0x58024000 08001920 : 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); 8001920: 4a04 ldr r2, [pc, #16] @ (8001934 ) 8001922: f8d2 380c ldr.w r3, [r2, #2060] @ 0x80c 8001926: f023 0307 bic.w r3, r3, #7 800192a: f043 0305 orr.w r3, r3, #5 800192e: f8c2 380c str.w r3, [r2, #2060] @ 0x80c } 8001932: 4770 bx lr 8001934: 58024000 .word 0x58024000 08001938 : void pwr_set_mode(enum pwr_sys_mode mode, uint8_t smps_level) { 8001938: b508 push {r3, lr} switch (mode) { 800193a: 2807 cmp r0, #7 800193c: d807 bhi.n 800194e 800193e: e8df f000 tbb [pc, r0] 8001942: 0c04 .short 0x0c04 8001944: 1d12120f .word 0x1d12120f 8001948: 211d .short 0x211d case PWR_SYS_SCU_LDO: pwr_set_mode_scu_ldo(); 800194a: f7ff ffb7 bl 80018bc case PWR_SYS_BYPASS: pwr_set_mode_bypass(); break; } /* Wait for power supply status to state ready. */ while (!(PWR_CSR1 & PWR_CSR1_ACTVOSRDY)); 800194e: 4a0f ldr r2, [pc, #60] @ (800198c ) 8001950: f8d2 3804 ldr.w r3, [r2, #2052] @ 0x804 8001954: 049b lsls r3, r3, #18 8001956: d5fb bpl.n 8001950 } 8001958: bd08 pop {r3, pc} pwr_set_mode_scu_bypass(); 800195a: f7ff ffe1 bl 8001920 break; 800195e: e7f6 b.n 800194e pwr_set_mode_ldo(); 8001960: f7ff ffa0 bl 80018a4 break; 8001964: e7f3 b.n 800194e pwr_set_mode_smps_ldo(false, PWR_CR3_SMPSLEVEL_VOS, mode == PWR_SYS_SMPS_LDO); 8001966: f1a0 0c04 sub.w ip, r0, #4 800196a: 2100 movs r1, #0 800196c: f1dc 0200 rsbs r2, ip, #0 8001970: eb42 020c adc.w r2, r2, ip pwr_set_mode_smps_ldo(false, smps_level, mode == PWR_SYS_EXT_SMPS_LDO); 8001974: 2000 movs r0, #0 8001976: f7ff ffad bl 80018d4 break; 800197a: e7e8 b.n 800194e pwr_set_mode_smps_ldo(false, smps_level, mode == PWR_SYS_EXT_SMPS_LDO); 800197c: 3805 subs r0, #5 800197e: 4242 negs r2, r0 8001980: 4142 adcs r2, r0 8001982: e7f7 b.n 8001974 pwr_set_mode_bypass(); 8001984: f7ff ffc0 bl 8001908 break; 8001988: e7e1 b.n 800194e 800198a: bf00 nop 800198c: 58024000 .word 0x58024000 08001990 : 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) { 8001990: 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. */ 8001992: 4607 mov r7, r0 8001994: b908 cbnz r0, 800199a 8001996: f7ff ff69 bl 800186c /* "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; 800199a: 4b20 ldr r3, [pc, #128] @ (8001a1c ) 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; 800199c: 1e42 subs r2, r0, #1 800199e: 4e20 ldr r6, [pc, #128] @ (8001a20 ) uint32_t devid = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK; 80019a0: 681b ldr r3, [r3, #0] 80019a2: f3c3 030b ubfx r3, r3, #0, #12 if (devid == DBGMCU_IDCODE_DEV_ID_STM32H7A3_B3_B0) { 80019a6: f5b3 6f90 cmp.w r3, #1152 @ 0x480 80019aa: d10f bne.n 80019cc PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; 80019ac: f8d6 3818 ldr.w r3, [r6, #2072] @ 0x818 const uint32_t vos_value = srdcr_vos_values[scale - 1] << PWR_SRDCR_VOS_SHIFT; 80019b0: 491c ldr r1, [pc, #112] @ (8001a24 ) PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; 80019b2: f423 4340 bic.w r3, r3, #49152 @ 0xc000 const uint32_t vos_value = srdcr_vos_values[scale - 1] << PWR_SRDCR_VOS_SHIFT; 80019b6: 5c8a ldrb r2, [r1, r2] PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; 80019b8: ea43 3382 orr.w r3, r3, r2, lsl #14 80019bc: 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. */ 80019c0: 4a17 ldr r2, [pc, #92] @ (8001a20 ) 80019c2: f8d2 3818 ldr.w r3, [r2, #2072] @ 0x818 80019c6: 049b lsls r3, r3, #18 80019c8: d5fb bpl.n 80019c2 } 80019ca: bdf8 pop {r3, r4, r5, r6, r7, pc} uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; 80019cc: 4916 ldr r1, [pc, #88] @ (8001a28 ) if (devid == DBGMCU_IDCODE_DEV_ID_STM32H74X_5X) { 80019ce: f5b3 6f8a cmp.w r3, #1104 @ 0x450 uint32_t d3cr_masked = PWR_D3CR & ~(PWR_D3CR_VOS_MASK << PWR_D3CR_VOS_SHIFT); 80019d2: f8d6 5818 ldr.w r5, [r6, #2072] @ 0x818 uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; 80019d6: 5c8c ldrb r4, [r1, r2] uint32_t d3cr_masked = PWR_D3CR & ~(PWR_D3CR_VOS_MASK << PWR_D3CR_VOS_SHIFT); 80019d8: f425 4540 bic.w r5, r5, #49152 @ 0xc000 uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; 80019dc: ea4f 3484 mov.w r4, r4, lsl #14 if (devid == DBGMCU_IDCODE_DEV_ID_STM32H74X_5X) { 80019e0: d118 bne.n 8001a14 rcc_periph_clock_enable(RCC_SYSCFG); /* Ensure we can access ODEN. */ 80019e2: f641 6081 movw r0, #7809 @ 0x1e81 80019e6: f7ff fea5 bl 8001734 if (scale == PWR_VOS_SCALE_0) { 80019ea: 2f01 cmp r7, #1 80019ec: f04f 43b0 mov.w r3, #1476395008 @ 0x58000000 80019f0: d10a bne.n 8001a08 PWR_D3CR = d3cr_masked | (PWR_D3CR_VOS_SCALE_1 << PWR_SRDCR_VOS_SHIFT); 80019f2: f445 4540 orr.w r5, r5, #49152 @ 0xc000 80019f6: f8c6 5818 str.w r5, [r6, #2072] @ 0x818 SYSCFG_PWRCR |= SYSCFG_PWRCR_ODEN; 80019fa: f8d3 242c ldr.w r2, [r3, #1068] @ 0x42c 80019fe: f042 0201 orr.w r2, r2, #1 8001a02: f8c3 242c str.w r2, [r3, #1068] @ 0x42c 8001a06: e7db b.n 80019c0 SYSCFG_PWRCR &= ~SYSCFG_PWRCR_ODEN; 8001a08: f8d3 242c ldr.w r2, [r3, #1068] @ 0x42c 8001a0c: f022 0201 bic.w r2, r2, #1 8001a10: f8c3 242c str.w r2, [r3, #1068] @ 0x42c PWR_D3CR = d3cr_masked | d3cr_vos; 8001a14: 432c orrs r4, r5 8001a16: f8c6 4818 str.w r4, [r6, #2072] @ 0x818 8001a1a: e7d1 b.n 80019c0 8001a1c: 5c001000 .word 0x5c001000 8001a20: 58024000 .word 0x58024000 8001a24: 08001b36 .word 0x08001b36 8001a28: 08001b32 .word 0x08001b32 08001a2c : 8001a2c: 2a03 cmp r2, #3 8001a2e: b430 push {r4, r5} 8001a30: d912 bls.n 8001a58 8001a32: ea41 0400 orr.w r4, r1, r0 8001a36: 07a4 lsls r4, r4, #30 8001a38: 4684 mov ip, r0 8001a3a: 460b mov r3, r1 8001a3c: d121 bne.n 8001a82 8001a3e: 4619 mov r1, r3 8001a40: 4660 mov r0, ip 8001a42: f853 4b04 ldr.w r4, [r3], #4 8001a46: f85c 5b04 ldr.w r5, [ip], #4 8001a4a: 42a5 cmp r5, r4 8001a4c: d119 bne.n 8001a82 8001a4e: 3a04 subs r2, #4 8001a50: 2a03 cmp r2, #3 8001a52: d8f4 bhi.n 8001a3e 8001a54: 4660 mov r0, ip 8001a56: 4619 mov r1, r3 8001a58: 1e54 subs r4, r2, #1 8001a5a: b17a cbz r2, 8001a7c 8001a5c: 1e43 subs r3, r0, #1 8001a5e: 3901 subs r1, #1 8001a60: 1902 adds r2, r0, r4 8001a62: e001 b.n 8001a68 8001a64: 429a cmp r2, r3 8001a66: d009 beq.n 8001a7c 8001a68: f813 0f01 ldrb.w r0, [r3, #1]! 8001a6c: f811 cf01 ldrb.w ip, [r1, #1]! 8001a70: 4560 cmp r0, ip 8001a72: d0f7 beq.n 8001a64 8001a74: eba0 000c sub.w r0, r0, ip 8001a78: bc30 pop {r4, r5} 8001a7a: 4770 bx lr 8001a7c: 2000 movs r0, #0 8001a7e: bc30 pop {r4, r5} 8001a80: 4770 bx lr 8001a82: 1e54 subs r4, r2, #1 8001a84: e7ea b.n 8001a5c 8001a86: bf00 nop 08001a88 : 8001a88: 0783 lsls r3, r0, #30 8001a8a: b530 push {r4, r5, lr} 8001a8c: d046 beq.n 8001b1c 8001a8e: 1884 adds r4, r0, r2 8001a90: 4684 mov ip, r0 8001a92: e004 b.n 8001a9e 8001a94: f803 1b01 strb.w r1, [r3], #1 8001a98: 079d lsls r5, r3, #30 8001a9a: d004 beq.n 8001aa6 8001a9c: 469c mov ip, r3 8001a9e: 45a4 cmp ip, r4 8001aa0: 4663 mov r3, ip 8001aa2: d1f7 bne.n 8001a94 8001aa4: bd30 pop {r4, r5, pc} 8001aa6: 3a01 subs r2, #1 8001aa8: 4402 add r2, r0 8001aaa: eba2 020c sub.w r2, r2, ip 8001aae: 2a03 cmp r2, #3 8001ab0: d929 bls.n 8001b06 8001ab2: b2cc uxtb r4, r1 8001ab4: eb04 2404 add.w r4, r4, r4, lsl #8 8001ab8: 2a0f cmp r2, #15 8001aba: eb04 4404 add.w r4, r4, r4, lsl #16 8001abe: d92f bls.n 8001b20 8001ac0: f1a2 0c10 sub.w ip, r2, #16 8001ac4: f02c 0c0f bic.w ip, ip, #15 8001ac8: f103 0510 add.w r5, r3, #16 8001acc: 44ac add ip, r5 8001ace: e9c3 4400 strd r4, r4, [r3] 8001ad2: e9c3 4402 strd r4, r4, [r3, #8] 8001ad6: 3310 adds r3, #16 8001ad8: 4563 cmp r3, ip 8001ada: d1f8 bne.n 8001ace 8001adc: f012 0f0c tst.w r2, #12 8001ae0: f002 0e0f and.w lr, r2, #15 8001ae4: d018 beq.n 8001b18 8001ae6: f02e 0c03 bic.w ip, lr, #3 8001aea: 449c add ip, r3 8001aec: f1ae 0504 sub.w r5, lr, #4 8001af0: 461a mov r2, r3 8001af2: f842 4b04 str.w r4, [r2], #4 8001af6: 4562 cmp r2, ip 8001af8: d1fb bne.n 8001af2 8001afa: f025 0403 bic.w r4, r5, #3 8001afe: 3304 adds r3, #4 8001b00: f00e 0203 and.w r2, lr, #3 8001b04: 4423 add r3, r4 8001b06: 2a00 cmp r2, #0 8001b08: d0cc beq.n 8001aa4 8001b0a: b2c9 uxtb r1, r1 8001b0c: 441a add r2, r3 8001b0e: f803 1b01 strb.w r1, [r3], #1 8001b12: 4293 cmp r3, r2 8001b14: d1fb bne.n 8001b0e 8001b16: bd30 pop {r4, r5, pc} 8001b18: 4672 mov r2, lr 8001b1a: e7f4 b.n 8001b06 8001b1c: 4603 mov r3, r0 8001b1e: e7c6 b.n 8001aae 8001b20: 4696 mov lr, r2 8001b22: e7e0 b.n 8001ae6 08001b24 : 8001b24: 0014 0014 0014 012c 00c8 01f4 000a ......,....... 08001b32 : 8001b32: 0300 0102 .... 08001b36 : 8001b36: 0203 0001 0000 ......