Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "mik32_hal_pcc.h"
- #include "mik32_hal_gpio.h"
- #include "mik32_memory_map.h"
- #include "csr.h"
- #include "scr1_timer.h"
- #include "scr1_csr_encoding.h"
- /*
- * Данный пример демонстрирует работу с mtime и mcycle
- *
- */
- void SystemClock_Config();
- void GPIO_Init();
- void Systick_Initialize();
- void trap_handler(void);
- int main()
- {
- SystemClock_Config();
- GPIO_Init();
- PM->CLK_APB_M_SET = PM_CLOCK_APB_M_EPIC_M;
- Systick_Initialize();
- // global interrupt enable
- set_csr(mstatus, MSTATUS_MIE); // Global interrupt enable
- set_csr(mie, MIE_MEIE); // Machine External Interrupt Enable
- while (1)
- {
- HAL_GPIO_TogglePin(GPIO_0, GPIO_PIN_9);
- HAL_DelayMs(500);
- }
- }
- void SystemClock_Config(void)
- {
- PCC_InitTypeDef PCC_OscInit = {0};
- PCC_OscInit.OscillatorEnable = PCC_OSCILLATORTYPE_ALL;
- PCC_OscInit.FreqMon.OscillatorSystem = PCC_OSCILLATORTYPE_OSC32M;
- PCC_OscInit.FreqMon.ForceOscSys = PCC_FORCE_OSC_SYS_UNFIXED;
- PCC_OscInit.FreqMon.Force32KClk = PCC_FREQ_MONITOR_SOURCE_OSC32K;
- PCC_OscInit.AHBDivider = 0;
- PCC_OscInit.APBMDivider = 0;
- PCC_OscInit.APBPDivider = 0;
- PCC_OscInit.HSI32MCalibrationValue = 128;
- PCC_OscInit.LSI32KCalibrationValue = 8;
- PCC_OscInit.RTCClockSelection = PCC_RTC_CLOCK_SOURCE_AUTO;
- PCC_OscInit.RTCClockCPUSelection = PCC_CPU_RTC_CLOCK_SOURCE_OSC32K;
- HAL_PCC_Config(&PCC_OscInit);
- }
- void GPIO_Init()
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __HAL_PCC_GPIO_0_CLK_ENABLE();
- __HAL_PCC_GPIO_1_CLK_ENABLE();
- GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
- GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
- GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
- HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
- }
- void Systick_Initialize(void )
- {
- SCR1_TIMER->TIMER_DIV = 0;
- *(unsigned long long *) &SCR1_TIMER->MTIME = 0;
- *(unsigned long long *) &SCR1_TIMER->MTIMECMP = 3200000;
- SCR1_TIMER->TIMER_CTRL |= SCR1_TIMER_CTRL_ENABLE_M ;
- set_csr(mie, MIE_MTIE); //Machine Timer Interrupt Enable
- }
- volatile uint64_t tick;
- void __attribute__((section(".ram_text"))) trap_handler(void)
- {
- unsigned long mcause = read_csr(mcause);
- static uint16_t led;
- uint32_t mcycle_lo, mcycle_hi, mcycle_hi2;
- uint64_t mcycle_64;
- static uint64_t mcycle_old_64 = 0;
- // --- правильное чтение согласованного mcycle (64 бита) ---
- do {
- mcycle_hi = read_csr(mcycleh);
- mcycle_lo = read_csr(mcycle);
- mcycle_hi2 = read_csr(mcycleh);
- } while (mcycle_hi != mcycle_hi2);
- mcycle_old_64 = ((uint64_t)mcycle_hi << 32) | mcycle_lo;
- asm("nop");
- asm("nop");
- asm("nop");
- asm("nop");
- asm("nop");
- asm("nop");
- // --- правильное чтение согласованного mcycle (64 бита) ---
- do {
- mcycle_hi = read_csr(mcycleh);
- mcycle_lo = read_csr(mcycle);
- mcycle_hi2 = read_csr(mcycleh);
- } while (mcycle_hi != mcycle_hi2);
- mcycle_64 = ((uint64_t)mcycle_hi << 32) | mcycle_lo;
- // --- вычисление дельты ---
- tick = mcycle_64 - mcycle_old_64;
- // --- обработка прерывания таймера ---
- if ((mcause & MCAUSE_EC) == 7 && (mcause & MCAUSE_INT)) {
- *(unsigned long long *)&SCR1_TIMER->MTIMECMP += 3200;
- if (++led >= 500) {
- led = 0;
- GPIO_0->OUTPUT ^= (1 << 10);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment