From 5afbb4ba17d54a6bec9a213a7ad2ad3bb683782d Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 26 Jul 2016 13:15:53 +0300 Subject: [PATCH 1/2] digitalWrite and digitalRead cancel analogWrite enabled on a pin related to https://github.com/esp8266/Arduino/issues/2175 --- cores/esp8266/core_esp8266_timer.c | 2 +- cores/esp8266/core_esp8266_wiring_digital.c | 18 ++++++++++------- cores/esp8266/core_esp8266_wiring_pwm.c | 22 +++++++++++++++++---- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/cores/esp8266/core_esp8266_timer.c b/cores/esp8266/core_esp8266_timer.c index eb9f5ffff5..a1cbc4e954 100644 --- a/cores/esp8266/core_esp8266_timer.c +++ b/cores/esp8266/core_esp8266_timer.c @@ -41,7 +41,7 @@ void ICACHE_RAM_ATTR timer1_isr_handler(void *para){ } } -void timer1_isr_init(){ +void ICACHE_RAM_ATTR timer1_isr_init(){ ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL); } diff --git a/cores/esp8266/core_esp8266_wiring_digital.c b/cores/esp8266/core_esp8266_wiring_digital.c index ea573fb7fc..1961b42283 100644 --- a/cores/esp8266/core_esp8266_wiring_digital.c +++ b/cores/esp8266/core_esp8266_wiring_digital.c @@ -1,9 +1,9 @@ -/* +/* digital.c - wiring digital implementation for esp8266 Copyright (c) 2015 Hristo Gochkov. All rights reserved. This file is part of the esp8266 core for Arduino environment. - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -25,9 +25,12 @@ #include "eagle_soc.h" #include "ets_sys.h" +extern void pwm_stop_pin(uint8_t pin); + uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10}; extern void __pinMode(uint8_t pin, uint8_t mode) { + pwm_stop_pin(pin); if(pin < 16){ if(mode == SPECIAL){ GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) @@ -77,6 +80,7 @@ extern void __pinMode(uint8_t pin, uint8_t mode) { } extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { + pwm_stop_pin(pin); if(pin < 16){ if(val) GPOS = (1 << pin); else GPOC = (1 << pin); @@ -87,6 +91,7 @@ extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { } extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) { + pwm_stop_pin(pin); if(pin < 16){ return GPIP(pin); } else if(pin == 16){ @@ -121,12 +126,12 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) { while(!(changedbits & (1 << i))) i++; changedbits &= ~(1 << i); interrupt_handler_t *handler = &interrupt_handlers[i]; - if (handler->fn && - (handler->mode == CHANGE || + if (handler->fn && + (handler->mode == CHANGE || (handler->mode & 1) == !!(levels & (1 << i)))) { // to make ISR compatible to Arduino AVR model where interrupts are disabled // we disable them before we call the client ISR - uint32_t savedPS = xt_rsil(15); // stop other interrupts + uint32_t savedPS = xt_rsil(15); // stop other interrupts handler->fn(); xt_wsr_ps(savedPS); } @@ -170,7 +175,7 @@ void initPins() { for (int i = 12; i <= 16; ++i) { pinMode(i, INPUT); } - + ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg); ETS_GPIO_INTR_ENABLE(); } @@ -180,4 +185,3 @@ extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias(" extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead"))); extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt"))); extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); - diff --git a/cores/esp8266/core_esp8266_wiring_pwm.c b/cores/esp8266/core_esp8266_wiring_pwm.c index 8297e21ee7..90e2dc31bc 100644 --- a/cores/esp8266/core_esp8266_wiring_pwm.c +++ b/cores/esp8266/core_esp8266_wiring_pwm.c @@ -126,10 +126,11 @@ void ICACHE_RAM_ATTR pwm_timer_isr() //103-138 TEIE &= ~TEIE1;//14 T1I = 0;//9 if(current_step < table->len) { //20/21 - if(table->masks[current_step] & 0xFFFF) { - GPOC = table->masks[current_step] & 0xFFFF; //15/21 + uint32_t mask = table->masks[current_step] & pwm_mask; + if(mask & 0xFFFF) { + GPOC = mask & 0xFFFF; //15/21 } - if(table->masks[current_step] & 0x10000) { + if(mask & 0x10000) { GP16O = 0; //6/13 } current_step++;//1 @@ -164,6 +165,19 @@ void pwm_start_timer() timer1_write(1); } +void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin) +{ + if(pwm_mask){ + pwm_mask &= ~(1 << pin); + if(pwm_mask == 0) { + ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); + T1C = 0; + T1I = 0; + timer1_isr_init(); + } + } +} + extern void __analogWrite(uint8_t pin, int value) { bool start_timer = false; @@ -183,9 +197,9 @@ extern void __analogWrite(uint8_t pin, int value) memset(&_pwm_isr_data, 0, sizeof(struct pwm_isr_data*)); start_timer = true; } - pwm_mask |= (1 << pin); pinMode(pin, OUTPUT); digitalWrite(pin, LOW); + pwm_mask |= (1 << pin); } if((F_CPU / ESP8266_CLOCK) == 1) { value = (value+1) / 2; From ee9795179f02de53a2e79e33933483f72596acea Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 26 Jul 2016 13:50:48 +0300 Subject: [PATCH 2/2] Optimize methods a bit --- cores/esp8266/core_esp8266_timer.c | 2 +- cores/esp8266/core_esp8266_wiring_pwm.c | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/cores/esp8266/core_esp8266_timer.c b/cores/esp8266/core_esp8266_timer.c index a1cbc4e954..d10b7c4ee6 100644 --- a/cores/esp8266/core_esp8266_timer.c +++ b/cores/esp8266/core_esp8266_timer.c @@ -66,7 +66,7 @@ void ICACHE_RAM_ATTR timer1_write(uint32_t ticks){ if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable } -void timer1_disable(){ +void ICACHE_RAM_ATTR timer1_disable(){ T1C = 0; T1I = 0; } diff --git a/cores/esp8266/core_esp8266_wiring_pwm.c b/cores/esp8266/core_esp8266_wiring_pwm.c index 90e2dc31bc..8d1ec15604 100644 --- a/cores/esp8266/core_esp8266_wiring_pwm.c +++ b/cores/esp8266/core_esp8266_wiring_pwm.c @@ -171,8 +171,7 @@ void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin) pwm_mask &= ~(1 << pin); if(pwm_mask == 0) { ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); - T1C = 0; - T1I = 0; + timer1_disable(); timer1_isr_init(); } } @@ -182,14 +181,8 @@ extern void __analogWrite(uint8_t pin, int value) { bool start_timer = false; if(value == 0) { - pwm_mask &= ~(1 << pin); - prep_pwm_steps(); digitalWrite(pin, LOW); - if(pwm_mask == 0) { - ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); - timer1_disable(); - timer1_isr_init(); - } + prep_pwm_steps(); return; } if((pwm_mask & (1 << pin)) == 0) {