This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM3358:DMTIMER 不工作

Guru**** 2465890 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1473842/am3358-dmtimer-not-working

器件型号:AM3358

工具与软件:

你(们)好、

我目前正在为我的最后一个高中项目开发裸机操作系统。 我目前在设置 DMTIMER2模块时遇到一些问题。

中断看起来像触发的、但当尝试在主循环中使用 WAIT 函数时、它由于某种原因而卡住、我不知道。

下面的代码是用铁锈写的,虽然我希望它是可读的人不熟悉铁锈。

感谢任何帮助、

此致、Felix

use crate::{
    interrupts::{enable_interrupt, register_handler, Mode},
    sys::{read_addr, write_addr, CM_DPLL, CM_PER},
};

const TIMER2: u32 = 0x4804_0000;

const CM_PER_L4LS_CLKCTRL: u32 = 0x60;
const CM_PER_TIMER2_CLKCTRL: u32 = 0x80;

const CLKSEL_TIMER2_CLK: u32 = 0x8;

const TIMER_CONTROL: u32 = 0x38;
const TIMER_COUNTER: u32 = 0x3C;
const TIMER_LOAD: u32 = 0x40;

const TIMER_IRQ_EOI: u32 = 0x20;
const TIMER_IRQSTATUS: u32 = 0x28;
const TIMER_IRQENABLE_SET: u32 = 0x2C;
const TIMER_IRQENABLE_CLR: u32 = 0x30;

const TIMER_RELOAD_VALUE: u32 = 0xFFFF_FFE0;

const TINT2: u32 = 68;

static mut TIMER: Timer = Timer::new();

#[allow(static_mut_refs)]
pub fn get_timer<'a>() -> &'a mut Timer {
    unsafe { &mut TIMER }
}

pub fn initialize() {
    let timer = get_timer();
    timer.init_clocks();

    timer.stop();
    timer.init_timer();
    timer.init_interrupt();
    timer.start();
}

pub struct Timer {
    counter: u32,
}

impl Timer {
    const fn new() -> Self {
        Timer { counter: 0 }
    }

    fn init_clocks(&self) {
        write_addr(CM_PER + CM_PER_L4LS_CLKCTRL, 0x2);
        write_addr(CM_PER + CM_PER_TIMER2_CLKCTRL, 0x2);

        write_addr(CM_DPLL + CLKSEL_TIMER2_CLK, 0x2);

        while read_addr(CM_PER + CM_PER_L4LS_CLKCTRL) & (0x3 << 16) != 0 {}
        while read_addr(CM_PER + CM_PER_TIMER2_CLKCTRL) & (0x3 << 16) != 0 {}
    }

    fn init_timer(&self) {
        write_addr(TIMER2 + TIMER_COUNTER, TIMER_RELOAD_VALUE);
        write_addr(TIMER2 + TIMER_LOAD, TIMER_RELOAD_VALUE);
    }

    fn init_interrupt(&self) {
        self.irq_enable();

        register_handler(handle_timer_interrupt, TINT2 as usize);
        enable_interrupt(TINT2, Mode::IRQ, 0);
    }

    fn start(&self) {
        write_addr(TIMER2 + TIMER_CONTROL, 0x3);
    }

    fn stop(&self) {
        write_addr(TIMER2 + TIMER_CONTROL, 0x0);
    }

    fn irq_enable(&self) {
        write_addr(TIMER2 + TIMER_IRQENABLE_SET, 0x2);
    }

    fn irq_disable(&self) {
        write_addr(TIMER2 + TIMER_IRQENABLE_CLR, 0x2);
    }

    fn irq_acknowledge(&self) {
        write_addr(TIMER2 + TIMER_IRQ_EOI, 0x0);
        write_addr(TIMER2 + TIMER_IRQSTATUS, 0x2);
    }

    fn increment(&mut self) {
        self.counter += 1;
    }
}

pub fn millis() -> u32 {
    let timer = get_timer();
    timer.counter
}

pub fn wait(ms: u32) {
    let target = millis() + ms;
    while millis() < target {}
}

fn handle_timer_interrupt() {
    let timer = get_timer();

    timer.irq_disable();
    timer.irq_acknowledge();
    timer.increment();
    timer.irq_enable();
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Alex、我们目前支持使用现有 SDK 进行 AM335x 开发。 因此、对于裸机问题、我们的支持非常有限。 我将在内部与您联系、看看我们是否可以提供任何文档或技巧。 请允许我们花一些时间。

    谢谢!

    Paula.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请查看此常见问题解答: