Skip to content

Commit b7c7bc0

Browse files
authored
digitalWrite and digitalRead cancel analogWrite enabled on a pin (#2328)
related to #2175
1 parent 3fc3e9a commit b7c7bc0

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

cores/esp8266/core_esp8266_timer.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void ICACHE_RAM_ATTR timer1_isr_handler(void *para){
4141
}
4242
}
4343

44-
void timer1_isr_init(){
44+
void ICACHE_RAM_ATTR timer1_isr_init(){
4545
ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL);
4646
}
4747

@@ -66,7 +66,7 @@ void ICACHE_RAM_ATTR timer1_write(uint32_t ticks){
6666
if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable
6767
}
6868

69-
void timer1_disable(){
69+
void ICACHE_RAM_ATTR timer1_disable(){
7070
T1C = 0;
7171
T1I = 0;
7272
}

cores/esp8266/core_esp8266_wiring_digital.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
/*
1+
/*
22
digital.c - wiring digital implementation for esp8266
33
44
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
55
This file is part of the esp8266 core for Arduino environment.
6-
6+
77
This library is free software; you can redistribute it and/or
88
modify it under the terms of the GNU Lesser General Public
99
License as published by the Free Software Foundation; either
@@ -25,9 +25,12 @@
2525
#include "eagle_soc.h"
2626
#include "ets_sys.h"
2727

28+
extern void pwm_stop_pin(uint8_t pin);
29+
2830
uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10};
2931

3032
extern void __pinMode(uint8_t pin, uint8_t mode) {
33+
pwm_stop_pin(pin);
3134
if(pin < 16){
3235
if(mode == SPECIAL){
3336
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) {
7780
}
7881

7982
extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
83+
pwm_stop_pin(pin);
8084
if(pin < 16){
8185
if(val) GPOS = (1 << pin);
8286
else GPOC = (1 << pin);
@@ -87,6 +91,7 @@ extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
8791
}
8892

8993
extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) {
94+
pwm_stop_pin(pin);
9095
if(pin < 16){
9196
return GPIP(pin);
9297
} else if(pin == 16){
@@ -121,12 +126,12 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
121126
while(!(changedbits & (1 << i))) i++;
122127
changedbits &= ~(1 << i);
123128
interrupt_handler_t *handler = &interrupt_handlers[i];
124-
if (handler->fn &&
125-
(handler->mode == CHANGE ||
129+
if (handler->fn &&
130+
(handler->mode == CHANGE ||
126131
(handler->mode & 1) == !!(levels & (1 << i)))) {
127132
// to make ISR compatible to Arduino AVR model where interrupts are disabled
128133
// we disable them before we call the client ISR
129-
uint32_t savedPS = xt_rsil(15); // stop other interrupts
134+
uint32_t savedPS = xt_rsil(15); // stop other interrupts
130135
handler->fn();
131136
xt_wsr_ps(savedPS);
132137
}
@@ -170,7 +175,7 @@ void initPins() {
170175
for (int i = 12; i <= 16; ++i) {
171176
pinMode(i, INPUT);
172177
}
173-
178+
174179
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
175180
ETS_GPIO_INTR_ENABLE();
176181
}
@@ -180,4 +185,3 @@ extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("
180185
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
181186
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
182187
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
183-

cores/esp8266/core_esp8266_wiring_pwm.c

+16-9
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,11 @@ void ICACHE_RAM_ATTR pwm_timer_isr() //103-138
126126
TEIE &= ~TEIE1;//14
127127
T1I = 0;//9
128128
if(current_step < table->len) { //20/21
129-
if(table->masks[current_step] & 0xFFFF) {
130-
GPOC = table->masks[current_step] & 0xFFFF; //15/21
129+
uint32_t mask = table->masks[current_step] & pwm_mask;
130+
if(mask & 0xFFFF) {
131+
GPOC = mask & 0xFFFF; //15/21
131132
}
132-
if(table->masks[current_step] & 0x10000) {
133+
if(mask & 0x10000) {
133134
GP16O = 0; //6/13
134135
}
135136
current_step++;//1
@@ -164,28 +165,34 @@ void pwm_start_timer()
164165
timer1_write(1);
165166
}
166167

167-
extern void __analogWrite(uint8_t pin, int value)
168+
void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin)
168169
{
169-
bool start_timer = false;
170-
if(value == 0) {
170+
if(pwm_mask){
171171
pwm_mask &= ~(1 << pin);
172-
prep_pwm_steps();
173-
digitalWrite(pin, LOW);
174172
if(pwm_mask == 0) {
175173
ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
176174
timer1_disable();
177175
timer1_isr_init();
178176
}
177+
}
178+
}
179+
180+
extern void __analogWrite(uint8_t pin, int value)
181+
{
182+
bool start_timer = false;
183+
if(value == 0) {
184+
digitalWrite(pin, LOW);
185+
prep_pwm_steps();
179186
return;
180187
}
181188
if((pwm_mask & (1 << pin)) == 0) {
182189
if(pwm_mask == 0) {
183190
memset(&_pwm_isr_data, 0, sizeof(struct pwm_isr_data*));
184191
start_timer = true;
185192
}
186-
pwm_mask |= (1 << pin);
187193
pinMode(pin, OUTPUT);
188194
digitalWrite(pin, LOW);
195+
pwm_mask |= (1 << pin);
189196
}
190197
if((F_CPU / ESP8266_CLOCK) == 1) {
191198
value = (value+1) / 2;

0 commit comments

Comments
 (0)