1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

digitalWrite and digitalRead cancel analogWrite enabled on a pin (#2328)

related to https://github.com/esp8266/Arduino/issues/2175
This commit is contained in:
Me No Dev 2016-07-26 14:16:02 +03:00 committed by GitHub
parent 3fc3e9a99d
commit b7c7bc038d
3 changed files with 29 additions and 18 deletions

View File

@ -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); ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL);
} }
@ -66,7 +66,7 @@ void ICACHE_RAM_ATTR timer1_write(uint32_t ticks){
if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable
} }
void timer1_disable(){ void ICACHE_RAM_ATTR timer1_disable(){
T1C = 0; T1C = 0;
T1I = 0; T1I = 0;
} }

View File

@ -1,9 +1,9 @@
/* /*
digital.c - wiring digital implementation for esp8266 digital.c - wiring digital implementation for esp8266
Copyright (c) 2015 Hristo Gochkov. All rights reserved. Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -25,9 +25,12 @@
#include "eagle_soc.h" #include "eagle_soc.h"
#include "ets_sys.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}; 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) { extern void __pinMode(uint8_t pin, uint8_t mode) {
pwm_stop_pin(pin);
if(pin < 16){ if(pin < 16){
if(mode == SPECIAL){ if(mode == SPECIAL){
GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) 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) { extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
pwm_stop_pin(pin);
if(pin < 16){ if(pin < 16){
if(val) GPOS = (1 << pin); if(val) GPOS = (1 << pin);
else GPOC = (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) { extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) {
pwm_stop_pin(pin);
if(pin < 16){ if(pin < 16){
return GPIP(pin); return GPIP(pin);
} else if(pin == 16){ } else if(pin == 16){
@ -121,12 +126,12 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
while(!(changedbits & (1 << i))) i++; while(!(changedbits & (1 << i))) i++;
changedbits &= ~(1 << i); changedbits &= ~(1 << i);
interrupt_handler_t *handler = &interrupt_handlers[i]; interrupt_handler_t *handler = &interrupt_handlers[i];
if (handler->fn && if (handler->fn &&
(handler->mode == CHANGE || (handler->mode == CHANGE ||
(handler->mode & 1) == !!(levels & (1 << i)))) { (handler->mode & 1) == !!(levels & (1 << i)))) {
// to make ISR compatible to Arduino AVR model where interrupts are disabled // to make ISR compatible to Arduino AVR model where interrupts are disabled
// we disable them before we call the client ISR // 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(); handler->fn();
xt_wsr_ps(savedPS); xt_wsr_ps(savedPS);
} }
@ -170,7 +175,7 @@ void initPins() {
for (int i = 12; i <= 16; ++i) { for (int i = 12; i <= 16; ++i) {
pinMode(i, INPUT); pinMode(i, INPUT);
} }
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg); ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
ETS_GPIO_INTR_ENABLE(); 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 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 attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));

View File

@ -126,10 +126,11 @@ void ICACHE_RAM_ATTR pwm_timer_isr() //103-138
TEIE &= ~TEIE1;//14 TEIE &= ~TEIE1;//14
T1I = 0;//9 T1I = 0;//9
if(current_step < table->len) { //20/21 if(current_step < table->len) { //20/21
if(table->masks[current_step] & 0xFFFF) { uint32_t mask = table->masks[current_step] & pwm_mask;
GPOC = table->masks[current_step] & 0xFFFF; //15/21 if(mask & 0xFFFF) {
GPOC = mask & 0xFFFF; //15/21
} }
if(table->masks[current_step] & 0x10000) { if(mask & 0x10000) {
GP16O = 0; //6/13 GP16O = 0; //6/13
} }
current_step++;//1 current_step++;//1
@ -164,18 +165,24 @@ void pwm_start_timer()
timer1_write(1); timer1_write(1);
} }
extern void __analogWrite(uint8_t pin, int value) void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin)
{ {
bool start_timer = false; if(pwm_mask){
if(value == 0) {
pwm_mask &= ~(1 << pin); pwm_mask &= ~(1 << pin);
prep_pwm_steps();
digitalWrite(pin, LOW);
if(pwm_mask == 0) { if(pwm_mask == 0) {
ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
timer1_disable(); timer1_disable();
timer1_isr_init(); timer1_isr_init();
} }
}
}
extern void __analogWrite(uint8_t pin, int value)
{
bool start_timer = false;
if(value == 0) {
digitalWrite(pin, LOW);
prep_pwm_steps();
return; return;
} }
if((pwm_mask & (1 << pin)) == 0) { if((pwm_mask & (1 << pin)) == 0) {
@ -183,9 +190,9 @@ extern void __analogWrite(uint8_t pin, int value)
memset(&_pwm_isr_data, 0, sizeof(struct pwm_isr_data*)); memset(&_pwm_isr_data, 0, sizeof(struct pwm_isr_data*));
start_timer = true; start_timer = true;
} }
pwm_mask |= (1 << pin);
pinMode(pin, OUTPUT); pinMode(pin, OUTPUT);
digitalWrite(pin, LOW); digitalWrite(pin, LOW);
pwm_mask |= (1 << pin);
} }
if((F_CPU / ESP8266_CLOCK) == 1) { if((F_CPU / ESP8266_CLOCK) == 1) {
value = (value+1) / 2; value = (value+1) / 2;