/* add user code begin Header */ /** ************************************************************************** * @file wk_system.c * @brief work bench config program ************************************************************************** * Copyright notice & Disclaimer * * The software Board Support Package (BSP) that is made available to * download from Artery official website is the copyrighted work of Artery. * Artery authorizes customers to use, copy, and distribute the BSP * software and its related documentation for the purpose of design and * development in conjunction with Artery microcontrollers. Use of the * software is governed by this copyright notice and the following disclaimer. * * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * ************************************************************************** */ /* add user code end Header */ #include "includes.h" /* global variable */ volatile uint32_t timebase_ticks; /** * @brief this function is called to increment a global variable "timebase_ticks" * used as application time base. * @param none * @retval none */ __WEAK void wk_timebase_increase(void) { timebase_ticks ++; } /** * @brief provides a tick value in millisecond. * @param none * @retval tick value */ __WEAK uint32_t wk_timebase_get(void) { return timebase_ticks; } /** * @brief this function provides minimum delay (in milliseconds) based * on variable incremented. * @param delay variable specifies the delay time length, in milliseconds. * @retval none */ __WEAK void wk_delay_ms(uint32_t delay) { uint32_t start_tick = wk_timebase_get(); if(delay < 0xFFFFFFFFU) { delay += 1; } while((wk_timebase_get() - start_tick) < delay) { } } /** * @brief this function configures the source of the time base * the time source is configured to have 1ms time base * @param none * @retval none */ __WEAK void wk_timebase_init(void) { crm_clocks_freq_type crm_clocks; uint32_t frequency = 0; /* get crm_clocks */ crm_clocks_freq_get(&crm_clocks); frequency = crm_clocks.ahb_freq; /* config systick clock source */ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV); /* system tick config */ SysTick->LOAD = (uint32_t)((frequency / 1000) - 1UL); SysTick->VAL = 0UL; SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; } /** * @brief this function is called at timebase handler, eg: SysTick_Handler * @param none * @retval none */ __WEAK void wk_timebase_handler(void) { wk_timebase_increase(); } /** * @brief busy-wait microsecond delay (NOP loop, no SysTick/RTOS dependency). * @param us delay in microseconds * @retval none * @note 240MHz ��Լ 1us = 24 �� NOP ѭ����ʵ���΢��ϵ���� * æ�Ȼ�ռס CPU���ʺ϶���ʱ������ʱ�򡢴������ȣ��� */ __WEAK void Delay_us(uint32_t us) { volatile uint32_t i = us * 24; while (i--) __NOP(); } /* ============ TMR6 1ms 硬件定时器(独立于 SysTick 的时间基准) ============ */ /* TMR6 1ms 累计计数 */ volatile uint32_t tmr6_ticks; /** * @brief TMR6 1ms 中断回调(弱定义,可在用户代码里重写) * @param none * @retval none * @note 默认只累加计数;如需喂 AutoBand 伴奏库,重写为: * void wk_tmr6_1ms_tick(void) { AutoBandTop1_Metronome_External_1msTick(); } */ __WEAK void wk_tmr6_1ms_tick(void) { AutoBandTop1_Metronome_External_1msTick(); } /** * @brief 获取 TMR6 1ms tick 计数值 * @param none * @retval tick 值(单位 ms) */ __WEAK uint32_t wk_tmr6_tick_get(void) { return tmr6_ticks; } /** * @brief TMR6 1ms 定时器初始化 * @note 时钟树: sclk=240MHz, apb1div=2 -> TMR6 时钟 = 2 x apb1clk = 240MHz * DIV=239 -> 计数器时钟 = 240MHz/(239+1) = 1MHz * PR=999 -> 溢出周期 = (999+1) x 1us = 1ms * @param none * @retval none */ void wk_tmr6_1ms_init(void) { /* 使能 TMR6 时钟 */ crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE); /* 时基: PR=999, DIV=239 -> 1ms 溢出一次 */ tmr_base_init(TMR6, 999, 239); /* 清一次溢出标志,防止上电残留造成一次假中断 */ tmr_flag_clear(TMR6, TMR_OVF_FLAG); /* 使能溢出中断 */ tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE); /* NVIC 使能: 抢占优先级 5(高于 PendSV=15,1ms 节拍不受调度延迟影响) */ nvic_irq_enable(TMR6_GLOBAL_IRQn, 5, 0); /* 启动计数 */ tmr_counter_enable(TMR6, TRUE); }