Added esp/timer_regs.h and esp/dport_regs.h

This commit is contained in:
Alex Stewart 2015-08-19 11:34:18 -07:00
parent 3cc5d1fa86
commit eaa090e267
6 changed files with 234 additions and 227 deletions

View file

@ -10,6 +10,7 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include "esp/dport_regs.h"
/* Timer divisor index to max frequency */
#define _FREQ_DIV1 (80*1000*1000)
@ -20,104 +21,90 @@ const static uint32_t IROM _TIMER_FREQS[] = { _FREQ_DIV1, _FREQ_DIV16, _FREQ_DIV
/* Timer divisor index to divisor value */
const static uint32_t IROM _TIMER_DIV_VAL[] = { 1, 16, 256 };
/* Timer divisor to mask value */
const static uint32_t IROM _TIMER_DIV_REG[] = { TIMER_CTRL_DIV_1, TIMER_CTRL_DIV_16, TIMER_CTRL_DIV_256 };
INLINED esp_reg_t _timer_ctrl_reg(const timer_frc_t frc)
{
return (frc == TIMER_FRC1) ? &TIMER_FRC1_CTRL_REG : &TIMER_FRC2_CTRL_REG;
}
INLINED uint32_t timer_get_count(const timer_frc_t frc)
{
return (frc == TIMER_FRC1) ? TIMER_FRC1_COUNT_REG : TIMER_FRC2_COUNT_REG;
return TIMER(frc).COUNT;
}
INLINED uint32_t timer_get_load(const timer_frc_t frc)
{
return (frc == TIMER_FRC1) ? TIMER_FRC1_LOAD_REG : TIMER_FRC2_LOAD_REG;
return TIMER(frc).LOAD;
}
INLINED void timer_set_load(const timer_frc_t frc, const uint32_t load)
{
if(frc == TIMER_FRC1)
TIMER_FRC1_LOAD_REG = load;
else
TIMER_FRC2_LOAD_REG = load;
TIMER(frc).LOAD = load;
}
INLINED uint32_t timer_max_load(const timer_frc_t frc)
{
return (frc == TIMER_FRC1) ? TIMER_FRC1_MAX_LOAD : UINT32_MAX;
return (frc == FRC1) ? TIMER_FRC1_MAX_LOAD : UINT32_MAX;
}
INLINED void timer_set_divider(const timer_frc_t frc, const timer_div_t div)
INLINED void timer_set_divider(const timer_frc_t frc, const timer_clkdiv_t div)
{
if(div < TIMER_DIV1 || div > TIMER_DIV256)
if(div < TIMER_CLKDIV_1 || div > TIMER_CLKDIV_256)
return;
esp_reg_t ctrl = _timer_ctrl_reg(frc);
*ctrl = (*ctrl & ~TIMER_CTRL_DIV_MASK) | (_TIMER_DIV_REG[div] & TIMER_CTRL_DIV_MASK);
TIMER(frc).CTRL = SET_FIELD(TIMER(frc).CTRL, TIMER_CTRL_CLKDIV, div);
}
INLINED void timer_set_interrupts(const timer_frc_t frc, bool enable)
{
const uint32_t dp_bit = (frc == TIMER_FRC1) ? INT_ENABLE_FRC1 : INT_ENABLE_FRC2;
const uint32_t int_mask = BIT((frc == TIMER_FRC1) ? INUM_TIMER_FRC1 : INUM_TIMER_FRC2);
const uint32_t dp_bit = (frc == FRC1) ? DPORT_INT_ENABLE_FRC1 : DPORT_INT_ENABLE_FRC2;
const uint32_t int_mask = BIT((frc == FRC1) ? INUM_TIMER_FRC1 : INUM_TIMER_FRC2);
if(enable) {
DP_INT_ENABLE_REG |= dp_bit;
DPORT.INT_ENABLE |= dp_bit;
_xt_isr_unmask(int_mask);
} else {
DP_INT_ENABLE_REG &= ~dp_bit;
DPORT.INT_ENABLE &= ~dp_bit;
_xt_isr_mask(int_mask);
}
}
INLINED void timer_set_run(const timer_frc_t frc, const bool run)
{
esp_reg_t ctrl = _timer_ctrl_reg(frc);
if (run)
*ctrl |= TIMER_CTRL_RUN;
TIMER(frc).CTRL |= TIMER_CTRL_RUN;
else
*ctrl &= ~TIMER_CTRL_RUN;
TIMER(frc).CTRL &= ~TIMER_CTRL_RUN;
}
INLINED bool timer_get_run(const timer_frc_t frc)
{
return *_timer_ctrl_reg(frc) & TIMER_CTRL_RUN;
return TIMER(frc).CTRL & TIMER_CTRL_RUN;
}
INLINED void timer_set_reload(const timer_frc_t frc, const bool reload)
{
esp_reg_t ctrl = _timer_ctrl_reg(frc);
if (reload)
*ctrl |= TIMER_CTRL_RELOAD;
TIMER(frc).CTRL |= TIMER_CTRL_RELOAD;
else
*ctrl &= ~TIMER_CTRL_RELOAD;
TIMER(frc).CTRL &= ~TIMER_CTRL_RELOAD;
}
INLINED bool timer_get_reload(const timer_frc_t frc)
{
return *_timer_ctrl_reg(frc) & TIMER_CTRL_RELOAD;
return TIMER(frc).CTRL & TIMER_CTRL_RELOAD;
}
INLINED timer_div_t timer_freq_to_div(uint32_t freq)
INLINED timer_clkdiv_t timer_freq_to_div(uint32_t freq)
{
/*
try to maintain resolution without risking overflows.
these values are a bit arbitrary at the moment! */
if(freq > 100*1000)
return TIMER_DIV1;
return TIMER_CLKDIV_1;
else if(freq > 100)
return TIMER_DIV16;
return TIMER_CLKDIV_16;
else
return TIMER_DIV256;
return TIMER_CLKDIV_256;
}
/* timer_timer_to_count implementation - inline if all args are constant, call normally otherwise */
INLINED uint32_t _timer_freq_to_count_impl(const timer_frc_t frc, const uint32_t freq, const timer_div_t div)
INLINED uint32_t _timer_freq_to_count_impl(const timer_frc_t frc, const uint32_t freq, const timer_clkdiv_t div)
{
if(div < TIMER_DIV1 || div > TIMER_DIV256)
if(div < TIMER_CLKDIV_1 || div > TIMER_CLKDIV_256)
return 0; /* invalid divider */
if(freq > _TIMER_FREQS[div])
@ -127,9 +114,9 @@ INLINED uint32_t _timer_freq_to_count_impl(const timer_frc_t frc, const uint32_t
return counts;
}
uint32_t _timer_freq_to_count_runtime(const timer_frc_t frc, const uint32_t freq, const timer_div_t div);
uint32_t _timer_freq_to_count_runtime(const timer_frc_t frc, const uint32_t freq, const timer_clkdiv_t div);
INLINED uint32_t timer_freq_to_count(const timer_frc_t frc, const uint32_t freq, const timer_div_t div)
INLINED uint32_t timer_freq_to_count(const timer_frc_t frc, const uint32_t freq, const timer_clkdiv_t div)
{
if(__builtin_constant_p(frc) && __builtin_constant_p(freq) && __builtin_constant_p(div))
return _timer_freq_to_count_impl(frc, freq, div);
@ -137,33 +124,33 @@ INLINED uint32_t timer_freq_to_count(const timer_frc_t frc, const uint32_t freq,
return _timer_freq_to_count_runtime(frc, freq, div);
}
INLINED timer_div_t timer_time_to_div(uint32_t us)
INLINED timer_clkdiv_t timer_time_to_div(uint32_t us)
{
/*
try to maintain resolution without risking overflows. Similar to
timer_freq_to_div, these values are a bit arbitrary at the
moment! */
if(us < 1000)
return TIMER_DIV1;
return TIMER_CLKDIV_1;
else if(us < 10*1000)
return TIMER_DIV16;
return TIMER_CLKDIV_16;
else
return TIMER_DIV256;
return TIMER_CLKDIV_256;
}
/* timer_timer_to_count implementation - inline if all args are constant, call normally otherwise */
INLINED uint32_t _timer_time_to_count_impl(const timer_frc_t frc, uint32_t us, const timer_div_t div)
INLINED uint32_t _timer_time_to_count_impl(const timer_frc_t frc, uint32_t us, const timer_clkdiv_t div)
{
if(div < TIMER_DIV1 || div > TIMER_DIV256)
if(div < TIMER_CLKDIV_1 || div > TIMER_CLKDIV_256)
return 0; /* invalid divider */
const uint32_t TIMER_MAX = timer_max_load(frc);
if(div != TIMER_DIV256) /* timer tick in MHz */
if(div != TIMER_CLKDIV_256) /* timer tick in MHz */
{
/* timer is either 80MHz or 5MHz, so either 80 or 5 MHz counts per us */
const uint32_t counts_per_us = ((div == TIMER_DIV1) ? _FREQ_DIV1 : _FREQ_DIV16)/1000/1000;
const uint32_t counts_per_us = ((div == TIMER_CLKDIV_1) ? _FREQ_DIV1 : _FREQ_DIV16)/1000/1000;
if(us > TIMER_MAX/counts_per_us)
return 0; /* Multiplying us by mhz_per_count will overflow TIMER_MAX */
return us*counts_per_us;
@ -186,9 +173,9 @@ INLINED uint32_t _timer_time_to_count_impl(const timer_frc_t frc, uint32_t us, c
}
}
uint32_t _timer_time_to_count_runtime(const timer_frc_t frc, uint32_t us, const timer_div_t div);
uint32_t _timer_time_to_count_runtime(const timer_frc_t frc, uint32_t us, const timer_clkdiv_t div);
INLINED uint32_t timer_time_to_count(const timer_frc_t frc, uint32_t us, const timer_div_t div)
INLINED uint32_t timer_time_to_count(const timer_frc_t frc, uint32_t us, const timer_clkdiv_t div)
{
if(__builtin_constant_p(frc) && __builtin_constant_p(us) && __builtin_constant_p(div))
return _timer_time_to_count_impl(frc, us, div);
@ -201,7 +188,7 @@ INLINED uint32_t timer_time_to_count(const timer_frc_t frc, uint32_t us, const t
INLINED bool _timer_set_frequency_impl(const timer_frc_t frc, uint32_t freq)
{
uint32_t counts = 0;
timer_div_t div = timer_freq_to_div(freq);
timer_clkdiv_t div = timer_freq_to_div(freq);
counts = timer_freq_to_count(frc, freq, div);
if(counts == 0)
@ -211,7 +198,7 @@ INLINED bool _timer_set_frequency_impl(const timer_frc_t frc, uint32_t freq)
}
timer_set_divider(frc, div);
if(frc == TIMER_FRC1)
if(frc == FRC1)
{
timer_set_load(frc, counts);
timer_set_reload(frc, true);
@ -219,7 +206,7 @@ INLINED bool _timer_set_frequency_impl(const timer_frc_t frc, uint32_t freq)
else /* FRC2 */
{
/* assume that if this overflows it'll wrap, so we'll get desired behaviour */
TIMER_FRC2_MATCH_REG = counts + TIMER_FRC2_COUNT_REG;
TIMER(1).ALARM = counts + TIMER(1).COUNT;
}
return true;
}
@ -239,20 +226,20 @@ INLINED bool timer_set_frequency(const timer_frc_t frc, uint32_t freq)
INLINED bool _timer_set_timeout_impl(const timer_frc_t frc, uint32_t us)
{
uint32_t counts = 0;
timer_div_t div = timer_time_to_div(us);
timer_clkdiv_t div = timer_time_to_div(us);
counts = timer_time_to_count(frc, us, div);
if(counts == 0)
return false; /* can't set frequency */
timer_set_divider(frc, div);
if(frc == TIMER_FRC1)
if(frc == FRC1)
{
timer_set_load(frc, counts);
}
else /* FRC2 */
{
TIMER_FRC2_MATCH_REG = counts + TIMER_FRC2_COUNT_REG;
TIMER(1).ALARM = counts + TIMER(1).COUNT;
}
return true;