Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 24 additions & 46 deletions lib/pbio/drv/clock/clock_ev3.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@
#include <tiam1808/hw/soc_AM1808.h>
#include <tiam1808/timer.h>

/**
* The compare value to set for the 16 least significant bits of the hardware timer
*
* This is the value which causes the interrupt to be triggered every millisecond.
*/
#define TMR_PERIOD_LSB32 0x05CC
/*
* The compare value to set for the 16 most significant bits of the hardware timer
*/
#define TMR_PERIOD_MSB32 0x0
// The input to the Timer0 module is PLL0_AUXCLK. This will always run at 24 MHz on the EV3,
// regardless of what the CPU speed is set to. We configure the timer to generate interrupts
// every millisecond, and we configure the timer to reset to 0 when it reaches a count value
// corresponding to one millisecond of time. Finer timing resolution can be obtained by
// combining the software-managed millisecond counter with the timer value.
//
// The system tick uses the "12" half of the timer, and the PRU1 (TODO) uses the "34" half.
static const uint32_t auxclk_freq_hz = SOC_ASYNC_2_FREQ;
static const uint32_t timer_ms_period = (auxclk_freq_hz / 1000) - 1;
static const uint32_t timer_us_division = auxclk_freq_hz / 1000000;

/**
* The current tick in milliseconds
Expand All @@ -41,37 +41,14 @@ volatile uint32_t systick_ms = 0;
* The systick interrupt service routine (ISR) which will be called every millisecond.
*/
void systick_isr_C(void) {
/* Disable the timer interrupt */
TimerIntDisable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE);

/* Clear the interrupt status in AINTC and in timer */
IntSystemStatusClear(SYS_INT_TINT34_0);
TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE);
IntSystemStatusClear(SYS_INT_TINT12_0);
TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INTSTAT12_TIMER_NON_CAPT);

++systick_ms;

etimer_request_poll();
pbio_os_request_poll();

/* Enable the timer interrupt */
TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE);
}

/**
* Disable the timer and therefore the systick
*
*/
void systick_suspend(void) {
/* Disable the timer interrupt */
TimerDisable(SOC_TMR_0_REGS, TMR_TIMER34);
}

/**
* Enable the timer and therefore the systick
*/
void systick_resume(void) {
/* Enable the timer interrupt */
TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONTRELOAD);
}

/**
Expand All @@ -86,37 +63,38 @@ void pbdrv_clock_init(void) {

/* Set up the timer */
TimerConfigure(SOC_TMR_0_REGS, TMR_CFG_32BIT_UNCH_CLK_BOTH_INT);
TimerPeriodSet(SOC_TMR_0_REGS, TMR_TIMER34, TMR_PERIOD_LSB32);
TimerReloadSet(SOC_TMR_0_REGS, TMR_TIMER34, TMR_PERIOD_LSB32);
TimerPeriodSet(SOC_TMR_0_REGS, TMR_TIMER12, timer_ms_period);

/* Register the Timer ISR */
IntRegister(SYS_INT_TINT34_0, systick_isr_C);
IntRegister(SYS_INT_TINT12_0, systick_isr_C);

/* Set the channel number for Timer interrupt, it will map to IRQ */
IntChannelSet(SYS_INT_TINT34_0, 3);
IntChannelSet(SYS_INT_TINT12_0, 3);

/* Enable timer interrupts in AINTC */
IntSystemEnable(SYS_INT_TINT34_0);
IntSystemEnable(SYS_INT_TINT12_0);

/* Enable the timer interrupt */
TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE);
TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

/* Start the timer */
TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONTRELOAD);
TimerEnable(SOC_TMR_0_REGS, TMR_TIMER12, TMR_ENABLE_CONT);
}

uint32_t pbdrv_clock_get_us(void) {
// TODO: TIAM1808 implementation.
return 0;
uint32_t tim_val = TimerCounterGet(SOC_TMR_0_REGS, TMR_TIMER12);
uint32_t t_us = tim_val / timer_us_division;
return pbdrv_clock_get_ms() * 1000 + t_us;
}

uint32_t pbdrv_clock_get_ms(void) {
return systick_ms;
}

uint32_t pbdrv_clock_get_100us(void) {
// REVISIT: Use actual time since this isn't providing better resolution.
return pbdrv_clock_get_ms() * 10;
uint32_t tim_val = TimerCounterGet(SOC_TMR_0_REGS, TMR_TIMER12);
uint32_t t_100_us = tim_val / timer_us_division / 100;
return pbdrv_clock_get_ms() * 10 + t_100_us;
}

#endif // PBDRV_CONFIG_CLOCK_TIAM1808