Merge branch 'bugfix/timer_group_intr_enable_v4.0' into 'release/v4.0'

Fix timer group intr enable (backport v4.0)

See merge request espressif/esp-idf!8530
This commit is contained in:
Michael (XIAO Xufeng) 2020-05-21 17:42:02 +08:00
commit 6fe46c1798
6 changed files with 44 additions and 33 deletions

View File

@ -101,7 +101,7 @@ esp_err_t sigmadelta_set_prescale(sigmadelta_channel_t channel, uint8_t prescale
*/
esp_err_t sigmadelta_set_pin(sigmadelta_channel_t channel, gpio_num_t gpio_num);
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif

View File

@ -258,7 +258,12 @@ esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask)
{
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&timer_spinlock[group_num]);
TG[group_num]->int_ena.val |= en_mask;
for (int i = 0; i < 2; i++) {
if (en_mask & (1 << i)) {
TG[group_num]->hw_timer[i].config.level_int_en = 1;
TG[group_num]->int_ena.val |= (1 << i);
}
}
portEXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK;
}
@ -267,7 +272,12 @@ esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mas
{
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&timer_spinlock[group_num]);
TG[group_num]->int_ena.val &= (~disable_mask);
for (int i = 0; i < 2; i++) {
if (disable_mask & (1 << i)) {
TG[group_num]->hw_timer[i].config.level_int_en = 0;
TG[group_num]->int_ena.val &= ~(1 << i);
}
}
portEXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK;
}
@ -276,14 +286,22 @@ esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num)
{
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
return timer_group_intr_enable(group_num, BIT(timer_num));
portENTER_CRITICAL(&timer_spinlock[group_num]);
TG[group_num]->hw_timer[timer_num].config.level_int_en = 1;
TG[group_num]->int_ena.val |= (1 << timer_num);
portEXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK;
}
esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num)
{
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
return timer_group_intr_disable(group_num, BIT(timer_num));
portENTER_CRITICAL(&timer_spinlock[group_num]);
TG[group_num]->hw_timer[timer_num].config.level_int_en = 0;
TG[group_num]->int_ena.val &= ~(1 << timer_num);
portEXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK;
}

View File

@ -41,7 +41,7 @@ static const char *TAG = "dp83848";
typedef union {
struct {
uint32_t link_status : 1; /* Link Status */
uint32_t speed_status : 1; /* Link Status */
uint32_t speed_status : 1; /* Speed Status */
uint32_t duplex_status : 1; /* Duplex Status */
uint32_t loopback_status : 1; /* MII Loopback */
uint32_t auto_nego_complete : 1; /* Auto-Negotiation Complete */
@ -98,17 +98,14 @@ static esp_err_t dp83848_update_link_duplex_speed(phy_dp83848_t *dp83848)
esp_eth_mediator_t *eth = dp83848->eth;
eth_speed_t speed = ETH_SPEED_10M;
eth_duplex_t duplex = ETH_DUPLEX_HALF;
bmsr_reg_t bmsr;
physts_reg_t physts;
PHY_CHECK(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
"read BMSR failed", err);
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
PHY_CHECK(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_STS_REG_ADDR, &(physts.val)) == ESP_OK,
"read PHYSTS failed", err);
eth_link_t link = physts.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
/* check if link status changed */
if (dp83848->link_status != link) {
/* when link up, read negotiation result */
if (link == ETH_LINK_UP) {
PHY_CHECK(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_STS_REG_ADDR, &(physts.val)) == ESP_OK,
"read PHYSTS failed", err);
if (physts.speed_status) {
speed = ETH_SPEED_10M;
} else {

View File

@ -128,19 +128,14 @@ static esp_err_t ip101_update_link_duplex_speed(phy_ip101_t *ip101)
eth_speed_t speed = ETH_SPEED_10M;
eth_duplex_t duplex = ETH_DUPLEX_HALF;
cssr_reg_t cssr;
bmsr_reg_t bmsr;
PHY_CHECK(ip101_page_select(ip101, 16) == ESP_OK, "select page 16 failed", err);
PHY_CHECK(eth->phy_reg_read(eth, ip101->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
"read BMSR failed", err);
PHY_CHECK(eth->phy_reg_read(eth, ip101->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
"read BMSR failed", err);
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
PHY_CHECK(eth->phy_reg_read(eth, ip101->addr, ETH_PHY_CSSR_REG_ADDR, &(cssr.val)) == ESP_OK,
"read CSSR failed", err);
eth_link_t link = cssr.link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
/* check if link status changed */
if (ip101->link_status != link) {
/* when link up, read negotiation result */
if (link == ETH_LINK_UP) {
PHY_CHECK(eth->phy_reg_read(eth, ip101->addr, ETH_PHY_CSSR_REG_ADDR, &(cssr.val)) == ESP_OK,
"read CSSR failed", err);
switch (cssr.op_mode) {
case 1: //10M Half
speed = ETH_SPEED_10M;

View File

@ -108,6 +108,7 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[
// When we resume scheduler, we expect the counter task
// will preempt and count at least one more item
esp_intr_noniram_enable();
timer_enable_intr(TIMER_GROUP_0, TIMER_0);
xTaskResumeAll();
TEST_ASSERT_NOT_EQUAL(count_config.counter, no_sched_task);

View File

@ -42,7 +42,7 @@ xQueueHandle timer_queue;
static void inline print_timer_counter(uint64_t counter_value)
{
printf("Counter: 0x%08x%08x\n", (uint32_t) (counter_value >> 32),
(uint32_t) (counter_value));
(uint32_t) (counter_value));
printf("Time : %.8f s\n", (double) counter_value / TIMER_SCALE);
}
@ -62,7 +62,7 @@ void IRAM_ATTR timer_group0_isr(void *para)
from the timer that reported the interrupt */
uint32_t intr_status = TIMERG0.int_st_timers.val;
TIMERG0.hw_timer[timer_idx].update = 1;
uint64_t timer_counter_value =
uint64_t timer_counter_value =
((uint64_t) TIMERG0.hw_timer[timer_idx].cnt_high) << 32
| TIMERG0.hw_timer[timer_idx].cnt_low;
@ -103,17 +103,17 @@ void IRAM_ATTR timer_group0_isr(void *para)
* auto_reload - should the timer auto reload on alarm?
* timer_interval_sec - the interval of alarm to set
*/
static void example_tg0_timer_init(int timer_idx,
bool auto_reload, double timer_interval_sec)
static void example_tg0_timer_init(int timer_idx,
bool auto_reload, double timer_interval_sec)
{
/* Select and initialize basic parameters of the timer */
timer_config_t config;
config.divider = TIMER_DIVIDER;
config.counter_dir = TIMER_COUNT_UP;
config.counter_en = TIMER_PAUSE;
config.alarm_en = TIMER_ALARM_EN;
config.intr_type = TIMER_INTR_LEVEL;
config.auto_reload = auto_reload;
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = auto_reload,
}; // default clock source is APB
timer_init(TIMER_GROUP_0, timer_idx, &config);
/* Timer's counter will initially start from value below.
@ -123,8 +123,8 @@ static void example_tg0_timer_init(int timer_idx,
/* Configure the alarm value and the interrupt on alarm. */
timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE);
timer_enable_intr(TIMER_GROUP_0, timer_idx);
timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr,
(void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr,
(void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
timer_start(TIMER_GROUP_0, timer_idx);
}