Download firmware/hal/timer.c from Snapkitty/phaser-ags: direct link, hf CLI and curl.
- Browser
- Download file 2.74 kB
-
https://huggingface.co/Snapkitty/phaser-ags/resolve/main/firmware/hal/timer.c
- Command line
-
hf download hf://Snapkitty/phaser-ags/firmware/hal/timer.c
-
curl -L -o timer.c https://huggingface.co/Snapkitty/phaser-ags/resolve/main/firmware/hal/timer.c
2.74 kB
| /* | |
| * HAL — Timer driver for OMAP3530 GP Timers | |
| */ | |
| void timer_init(timer_dev_t *dev, uint32_t base, uint32_t clock_hz) { | |
| dev->base = (hw_reg32_t)base; | |
| dev->clock_hz = clock_hz; | |
| timer_stop(dev); | |
| /* Soft reset */ | |
| reg_write32(dev->base + GPTIMER_TIOCP_CFG, 0x02); | |
| delay_cycles(50); | |
| while (!(reg_read32(dev->base + GPTIMER_TISTAT) & 0x01)) | |
| ; | |
| /* Clear any pending IRQ */ | |
| reg_write32(dev->base + GPTIMER_TISR, 0x07); | |
| /* No prescaler (1:1 from source clock) */ | |
| reg_write32(dev->base + GPTIMER_TCLR, 0x00); | |
| /* Start from 0 */ | |
| reg_write32(dev->base + GPTIMER_TCRR, 0x00000000); | |
| reg_write32(dev->base + GPTIMER_TLDR, 0x00000000); | |
| } | |
| void timer_start(timer_dev_t *dev) { | |
| reg_set32(dev->base + GPTIMER_TCLR, GPTIMER_TCLR_ST); | |
| } | |
| void timer_stop(timer_dev_t *dev) { | |
| reg_clr32(dev->base + GPTIMER_TCLR, GPTIMER_TCLR_ST); | |
| } | |
| void timer_set_period_ms(timer_dev_t *dev, uint32_t ms) { | |
| uint32_t ticks = (dev->clock_hz / 1000UL) * ms; | |
| reg32_t load = 0xFFFFFFFFUL - ticks + 1; | |
| reg_write32(dev->base + GPTIMER_TLDR, load); | |
| reg_write32(dev->base + GPTIMER_TCRR, load); | |
| /* Enable auto-reload */ | |
| reg_set32(dev->base + GPTIMER_TCLR, GPTIMER_TCLR_AR); | |
| } | |
| void timer_set_period_us(timer_dev_t *dev, uint32_t us) { | |
| uint32_t ticks = (dev->clock_hz / 1000000UL) * us; | |
| reg32_t load = 0xFFFFFFFFUL - ticks + 1; | |
| reg_write32(dev->base + GPTIMER_TLDR, load); | |
| reg_write32(dev->base + GPTIMER_TCRR, load); | |
| reg_set32(dev->base + GPTIMER_TCLR, GPTIMER_TCLR_AR); | |
| } | |
| uint32_t timer_get_count(timer_dev_t *dev) { | |
| return reg_read32(dev->base + GPTIMER_TCRR); | |
| } | |
| void timer_reset(timer_dev_t *dev) { | |
| reg_write32(dev->base + GPTIMER_TCRR, 0x00000000); | |
| /* Trigger reload on next overflow */ | |
| reg_write32(dev->base + GPTIMER_TTGR, 0x00); | |
| } | |
| int timer_expired(timer_dev_t *dev) { | |
| return (reg_read32(dev->base + GPTIMER_TISR) & 0x01) != 0; | |
| } | |
| void timer_clear_irq(timer_dev_t *dev) { | |
| reg_write32(dev->base + GPTIMER_TISR, 0x07); | |
| } | |
| void timer_enable_irq(timer_dev_t *dev) { | |
| reg_write32(dev->base + GPTIMER_TIER, 0x01); /* Overflow IRQ */ | |
| reg_write32(dev->base + GPTIMER_TWER, 0x01); /* Wake-up on overflow */ | |
| } | |
| void timer_delay_ms(timer_dev_t *dev, uint32_t ms) { | |
| timer_stop(dev); | |
| timer_set_period_ms(dev, ms); | |
| timer_clear_irq(dev); | |
| timer_start(dev); | |
| while (!timer_expired(dev)) | |
| ; | |
| timer_stop(dev); | |
| timer_clear_irq(dev); | |
| } | |
| void timer_delay_us(timer_dev_t *dev, uint32_t us) { | |
| timer_stop(dev); | |
| timer_set_period_us(dev, us); | |
| timer_clear_irq(dev); | |
| timer_start(dev); | |
| while (!timer_expired(dev)) | |
| ; | |
| timer_stop(dev); | |
| timer_clear_irq(dev); | |
| } | |