mirror of
https://github.com/SemvdH/OBD2-car-display.git
synced 2025-12-15 04:01:04 +00:00
96 lines
2.8 KiB
C
96 lines
2.8 KiB
C
// #include "sam3xa/include/component/component_tc.h"
|
|
#include "obd2_timer.h"
|
|
|
|
void obd2_RTT_init(void)
|
|
{
|
|
/* enable the timer: reset the RTT
|
|
RTT->RTT_MR = RTT_MR_RTTRST;
|
|
/* set the alarm value to 0*/
|
|
RTT->RTT_AR = 0;
|
|
}
|
|
|
|
void obd2_RTT_enable()
|
|
{
|
|
/* enable the alarm interrupt and set the prescaler to the processor frequency to generate an interrupt every second*/
|
|
RTT->RTT_MR |= RTT_MR_ALMIEN | RTT_MR_RTPRES(CLOCK_FREQ);
|
|
|
|
/* enable the interrupt*/
|
|
NVIC_EnableIRQ(RTT_IRQn);
|
|
}
|
|
|
|
void obd2_RTT_reset()
|
|
{
|
|
/* To prevent several executions of the interrupt handler,
|
|
the interrupt must be disabled in the interrupt handler
|
|
and re-enabled when the status register is cleared.
|
|
*/
|
|
/* disable interrupts */
|
|
RTT->RTT_MR &= ~RTT_MR_ALMIEN;
|
|
/* clear the status register (reading it clears it)
|
|
SAM3X datasheet section 13.4: Reading the RTT_SR status register resets the RTTINC and ALMS fields.
|
|
*/
|
|
RTT->RTT_SR;
|
|
/* set the alarm value to 0*/
|
|
RTT->RTT_AR = 0;
|
|
/* re-enable the interrupt*/
|
|
RTT->RTT_MR |= RTT_MR_ALMIEN;
|
|
/* reset the RTT*/
|
|
RTT->RTT_MR |= RTT_MR_RTTRST;
|
|
}
|
|
|
|
void obd2_RTT_set_period(__UINT32_TYPE__ period)
|
|
{
|
|
/* set the prescaler value equal to the clock speed divided by how many milliseconds*/
|
|
RTT->RTT_MR |= RTT_MR_RTPRES(CLOCK_FREQ / (1000/period));
|
|
}
|
|
|
|
void obd2_TC_init()
|
|
{
|
|
/* disable write protection */
|
|
pmc_set_writeprotect(false);
|
|
// /* set clock source to main clock */
|
|
// pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK);
|
|
|
|
/* Enable peripheral clock */
|
|
pmc_enable_periph_clk(TC0_IRQn);
|
|
|
|
/* Disable clock (from arduino15/packages/arduino/hardware/sam/1.6.12/system/libsam/source/tc.c))*/
|
|
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKDIS;
|
|
/* Disable interrupts*/
|
|
TC0->TC_CHANNEL[0].TC_IDR = 0xFFFFFFFF;
|
|
/* Clear status register by reading it*/
|
|
TC0->TC_CHANNEL[0].TC_SR;
|
|
|
|
/* Set wave mode to UP mode with automatic trigger, select wave mode, set the clock to MCK / 2*/
|
|
TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1;
|
|
/* Enable the RC Compare interrupt*/
|
|
TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
|
|
/* Disable all other interrupts */
|
|
TC0->TC_CHANNEL[0].TC_IDR = ~TC_IER_CPCS;
|
|
}
|
|
|
|
void obd2_TC_set_RC_value(__UINT32_TYPE__ value)
|
|
{
|
|
TC0->TC_CHANNEL[0].TC_RC = TC_RC_RC(value);
|
|
}
|
|
|
|
void obd2_TC_start()
|
|
{
|
|
|
|
/* Clear any still pending IRQs */
|
|
NVIC_ClearPendingIRQ(TC0_IRQn);
|
|
/* Enable the IRQ */
|
|
NVIC_EnableIRQ(TC0_IRQn);
|
|
/* software trigger the timer resets it and start the clock, also enable the clock */
|
|
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;
|
|
}
|
|
|
|
void obd2_TC_stop()
|
|
{
|
|
/* stop the clock using an RB load event in capture mode e (LDBSTOP = 1 in TC_CMR (datasheet 36.6.4) */
|
|
// TC0->TC_CHANNEL[0].TC_CMR |= TC_CMR_CPCSTOP;
|
|
|
|
/* Disable the clock*/
|
|
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKDIS;
|
|
}
|