From 17b29fc437b8334c4d0089a7e576cc386687f361 Mon Sep 17 00:00:00 2001 From: Makuna Date: Sun, 24 May 2015 19:21:47 -0700 Subject: [PATCH 1/7] Expose Chip CCompare0 timer --- .../esp8266/cores/esp8266/Arduino.h | 18 +++++++++++++-- .../esp8266com/esp8266/cores/esp8266/Esp.h | 18 ++++++++++++++- .../cores/esp8266/core_esp8266_timer.c | 22 +++++++++++++++++++ .../esp8266/tools/sdk/include/ets_sys.h | 22 +++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 89dbff873f..7ebc77b791 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -107,6 +107,20 @@ void timer1_attachInterrupt(void (*userFunc)(void)); void timer1_detachInterrupt(void); void timer1_write(uint32_t ticks); //maximum ticks 8388607 +// timer0 is a special CPU timer that has very high resolution but with +// limited control. +// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter +// it does not support divide, type, or reload flags +// it is auto-disabled when the compare value matches CCOUNT +// it is auto-enabled when the compare value changes +#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) +#define timer0_read() (ESP.getCycleCompare0()) +#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) + +void timer0_isr_init(void); +void timer0_attachInterrupt(void(*userFunc)(void)); +void timer0_detachInterrupt(void); + // undefine stdlib's abs if encountered #ifdef abs #undef abs @@ -126,13 +140,13 @@ void ets_intr_unlock(); // level 15 will disable ALL interrupts, // level 0 will disable most software interrupts // -#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) "; esync; isync; dsync" : "=a" (state)) +#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state)) #define xt_enable_interrupts(state) __asm__ __volatile__("wsr %0,ps; esync" :: "a" (state) : "memory") extern uint32_t interruptsState; #define interrupts() xt_enable_interrupts(interruptsState) -#define noInterrupts() __asm__ __volatile__("rsil %0,15; esync; isync; dsync" : "=a" (interruptsState)) +#define noInterrupts() __asm__ __volatile__("rsil %0,15" : "=a" (interruptsState)) #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index 5e356459e1..c887c89e92 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -99,15 +99,31 @@ class EspClass { uint32_t getFlashChipSizeByChipId(void); inline uint32_t getCycleCount(void); + inline uint32_t getCycleCompare0(void); + inline void setCycleCompare0(uint32_t count); }; uint32_t EspClass::getCycleCount(void) { uint32_t ccount; - __asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); + __asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount)); return ccount; } +// this returns a value in the range of (0 - 2^32) +uint32_t EspClass::getCycleCompare0(void) +{ + uint32_t count; + __asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count)); + return count; +} + +// this takes a value in the range of (0 - 2^32) +void EspClass::setCycleCompare0(uint32_t count) +{ + __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory"); +} + extern EspClass ESP; #endif //ESP_H diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index bfdd3692cf..979ab0bfc1 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -59,3 +59,25 @@ void timer1_disable(){ T1C = 0; T1I = 0; } + +void(*timer0_user_cb)(void); + +void timer0_isr_handler(void *para){ + if (timer0_user_cb) { + timer0_user_cb(); + } +} + +void timer0_isr_init(){ + ETS_CCOMPARE0_INTR_ATTACH(timer0_isr_handler, NULL); +} + +void timer0_attachInterrupt(void(*userFunc)(void)) { + timer1_user_cb = userFunc; + ETS_CCOMPARE0_ENABLE(); +} + +void timer0_detachInterrupt() { + timer1_user_cb = NULL; + ETS_CCOMPARE0_DISABLE(); +} \ No newline at end of file diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 7908699bb5..3cdb51d2af 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -43,6 +43,7 @@ typedef void (*int_handler_t)(void*); #define ETS_GPIO_INUM 4 #define ETS_UART_INUM 5 #define ETS_UART1_INUM 5 +#define ETS_CCOMPARE0_INUM 6 #define ETS_FRC_TIMER1_INUM 9 /* use edge*/ #define ETS_INTR_LOCK() \ @@ -51,6 +52,9 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_UNLOCK() \ ets_intr_unlock() +#define ETS_CCOMPARE0_INTR_ATTACH(func, arg) \ + ets_isr_attach(ETS_CCOMPARE0_INUM, (int_handler_t)(func), (void *)(arg)) + #define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) \ ets_isr_attach(ETS_FRC_TIMER1_INUM, (int_handler_t)(func), (void *)(arg)) @@ -69,6 +73,18 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Sun, 24 May 2015 19:22:29 -0700 Subject: [PATCH 2/7] ETS_INTR_ENABLED & ETS_INT_PENDING as inline --- hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 3cdb51d2af..e11e619708 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -73,12 +73,14 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Mon, 25 May 2015 12:24:39 -0700 Subject: [PATCH 3/7] Fixed timer bug and cleaned up Decided to not expose compare timer in ESP object to minimize the exposure surface Fixed incorrect timer callback being used and initialized timer callbacks --- .../esp8266com/esp8266/cores/esp8266/Arduino.h | 4 ++-- hardware/esp8266com/esp8266/cores/esp8266/Esp.h | 16 ---------------- .../esp8266/cores/esp8266/core_esp8266_timer.c | 10 ++++++---- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 7ebc77b791..dcaa47b09e 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -114,8 +114,8 @@ void timer1_write(uint32_t ticks); //maximum ticks 8388607 // it is auto-disabled when the compare value matches CCOUNT // it is auto-enabled when the compare value changes #define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) -#define timer0_read() (ESP.getCycleCompare0()) -#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) +#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;}))) +#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory") void timer0_isr_init(void); void timer0_attachInterrupt(void(*userFunc)(void)); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index c887c89e92..fc52371965 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -99,8 +99,6 @@ class EspClass { uint32_t getFlashChipSizeByChipId(void); inline uint32_t getCycleCount(void); - inline uint32_t getCycleCompare0(void); - inline void setCycleCompare0(uint32_t count); }; uint32_t EspClass::getCycleCount(void) @@ -110,20 +108,6 @@ uint32_t EspClass::getCycleCount(void) return ccount; } -// this returns a value in the range of (0 - 2^32) -uint32_t EspClass::getCycleCompare0(void) -{ - uint32_t count; - __asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count)); - return count; -} - -// this takes a value in the range of (0 - 2^32) -void EspClass::setCycleCompare0(uint32_t count) -{ - __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory"); -} - extern EspClass ESP; #endif //ESP_H diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index 979ab0bfc1..b9b2f1256a 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -22,7 +22,9 @@ #include "pins_arduino.h" #include "c_types.h" -void (*timer1_user_cb)(void); +typedef void(*_timercallback)(void); + +static volatile _timercallback timer1_user_cb = NULL; void timer1_isr_handler(void *para){ if((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable @@ -60,7 +62,7 @@ void timer1_disable(){ T1I = 0; } -void(*timer0_user_cb)(void); +static volatile _timercallback timer0_user_cb = NULL; void timer0_isr_handler(void *para){ if (timer0_user_cb) { @@ -73,11 +75,11 @@ void timer0_isr_init(){ } void timer0_attachInterrupt(void(*userFunc)(void)) { - timer1_user_cb = userFunc; + timer0_user_cb = userFunc; ETS_CCOMPARE0_ENABLE(); } void timer0_detachInterrupt() { - timer1_user_cb = NULL; + timer0_user_cb = NULL; ETS_CCOMPARE0_DISABLE(); } \ No newline at end of file From 7647df15dbe525d2c1a48cc93e2247d77d02d8d0 Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 08:36:11 -0700 Subject: [PATCH 4/7] Revert "Fixed timer bug and cleaned up" This reverts commit cff57490feae778b68740e0ef878d4521ae4eb2b. --- .../esp8266com/esp8266/cores/esp8266/Arduino.h | 4 ++-- hardware/esp8266com/esp8266/cores/esp8266/Esp.h | 16 ++++++++++++++++ .../esp8266/cores/esp8266/core_esp8266_timer.c | 10 ++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index dcaa47b09e..7ebc77b791 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -114,8 +114,8 @@ void timer1_write(uint32_t ticks); //maximum ticks 8388607 // it is auto-disabled when the compare value matches CCOUNT // it is auto-enabled when the compare value changes #define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) -#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;}))) -#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory") +#define timer0_read() (ESP.getCycleCompare0()) +#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) void timer0_isr_init(void); void timer0_attachInterrupt(void(*userFunc)(void)); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index fc52371965..c887c89e92 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -99,6 +99,8 @@ class EspClass { uint32_t getFlashChipSizeByChipId(void); inline uint32_t getCycleCount(void); + inline uint32_t getCycleCompare0(void); + inline void setCycleCompare0(uint32_t count); }; uint32_t EspClass::getCycleCount(void) @@ -108,6 +110,20 @@ uint32_t EspClass::getCycleCount(void) return ccount; } +// this returns a value in the range of (0 - 2^32) +uint32_t EspClass::getCycleCompare0(void) +{ + uint32_t count; + __asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count)); + return count; +} + +// this takes a value in the range of (0 - 2^32) +void EspClass::setCycleCompare0(uint32_t count) +{ + __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory"); +} + extern EspClass ESP; #endif //ESP_H diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index b9b2f1256a..979ab0bfc1 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -22,9 +22,7 @@ #include "pins_arduino.h" #include "c_types.h" -typedef void(*_timercallback)(void); - -static volatile _timercallback timer1_user_cb = NULL; +void (*timer1_user_cb)(void); void timer1_isr_handler(void *para){ if((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable @@ -62,7 +60,7 @@ void timer1_disable(){ T1I = 0; } -static volatile _timercallback timer0_user_cb = NULL; +void(*timer0_user_cb)(void); void timer0_isr_handler(void *para){ if (timer0_user_cb) { @@ -75,11 +73,11 @@ void timer0_isr_init(){ } void timer0_attachInterrupt(void(*userFunc)(void)) { - timer0_user_cb = userFunc; + timer1_user_cb = userFunc; ETS_CCOMPARE0_ENABLE(); } void timer0_detachInterrupt() { - timer0_user_cb = NULL; + timer1_user_cb = NULL; ETS_CCOMPARE0_DISABLE(); } \ No newline at end of file From a5a7872d2f150b0b34ee099c415db3c619a01603 Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 08:36:50 -0700 Subject: [PATCH 5/7] Revert "ETS_INTR_ENABLED & ETS_INT_PENDING as inline" This reverts commit 9560c67aa86659bd9f8210f807706e35b85ae9be. --- hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index e11e619708..3cdb51d2af 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -73,14 +73,12 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Fri, 29 May 2015 08:37:13 -0700 Subject: [PATCH 6/7] Revert "Expose Chip CCompare0 timer" This reverts commit 17b29fc437b8334c4d0089a7e576cc386687f361. --- .../esp8266/cores/esp8266/Arduino.h | 18 ++------------- .../esp8266com/esp8266/cores/esp8266/Esp.h | 18 +-------------- .../cores/esp8266/core_esp8266_timer.c | 22 ------------------- .../esp8266/tools/sdk/include/ets_sys.h | 22 ------------------- 4 files changed, 3 insertions(+), 77 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 7ebc77b791..89dbff873f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -107,20 +107,6 @@ void timer1_attachInterrupt(void (*userFunc)(void)); void timer1_detachInterrupt(void); void timer1_write(uint32_t ticks); //maximum ticks 8388607 -// timer0 is a special CPU timer that has very high resolution but with -// limited control. -// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter -// it does not support divide, type, or reload flags -// it is auto-disabled when the compare value matches CCOUNT -// it is auto-enabled when the compare value changes -#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) -#define timer0_read() (ESP.getCycleCompare0()) -#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) - -void timer0_isr_init(void); -void timer0_attachInterrupt(void(*userFunc)(void)); -void timer0_detachInterrupt(void); - // undefine stdlib's abs if encountered #ifdef abs #undef abs @@ -140,13 +126,13 @@ void ets_intr_unlock(); // level 15 will disable ALL interrupts, // level 0 will disable most software interrupts // -#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state)) +#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) "; esync; isync; dsync" : "=a" (state)) #define xt_enable_interrupts(state) __asm__ __volatile__("wsr %0,ps; esync" :: "a" (state) : "memory") extern uint32_t interruptsState; #define interrupts() xt_enable_interrupts(interruptsState) -#define noInterrupts() __asm__ __volatile__("rsil %0,15" : "=a" (interruptsState)) +#define noInterrupts() __asm__ __volatile__("rsil %0,15; esync; isync; dsync" : "=a" (interruptsState)) #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index c887c89e92..5e356459e1 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -99,31 +99,15 @@ class EspClass { uint32_t getFlashChipSizeByChipId(void); inline uint32_t getCycleCount(void); - inline uint32_t getCycleCompare0(void); - inline void setCycleCompare0(uint32_t count); }; uint32_t EspClass::getCycleCount(void) { uint32_t ccount; - __asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount)); + __asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); return ccount; } -// this returns a value in the range of (0 - 2^32) -uint32_t EspClass::getCycleCompare0(void) -{ - uint32_t count; - __asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count)); - return count; -} - -// this takes a value in the range of (0 - 2^32) -void EspClass::setCycleCompare0(uint32_t count) -{ - __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory"); -} - extern EspClass ESP; #endif //ESP_H diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index 979ab0bfc1..bfdd3692cf 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -59,25 +59,3 @@ void timer1_disable(){ T1C = 0; T1I = 0; } - -void(*timer0_user_cb)(void); - -void timer0_isr_handler(void *para){ - if (timer0_user_cb) { - timer0_user_cb(); - } -} - -void timer0_isr_init(){ - ETS_CCOMPARE0_INTR_ATTACH(timer0_isr_handler, NULL); -} - -void timer0_attachInterrupt(void(*userFunc)(void)) { - timer1_user_cb = userFunc; - ETS_CCOMPARE0_ENABLE(); -} - -void timer0_detachInterrupt() { - timer1_user_cb = NULL; - ETS_CCOMPARE0_DISABLE(); -} \ No newline at end of file diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 3cdb51d2af..7908699bb5 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -43,7 +43,6 @@ typedef void (*int_handler_t)(void*); #define ETS_GPIO_INUM 4 #define ETS_UART_INUM 5 #define ETS_UART1_INUM 5 -#define ETS_CCOMPARE0_INUM 6 #define ETS_FRC_TIMER1_INUM 9 /* use edge*/ #define ETS_INTR_LOCK() \ @@ -52,9 +51,6 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_UNLOCK() \ ets_intr_unlock() -#define ETS_CCOMPARE0_INTR_ATTACH(func, arg) \ - ets_isr_attach(ETS_CCOMPARE0_INUM, (int_handler_t)(func), (void *)(arg)) - #define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) \ ets_isr_attach(ETS_FRC_TIMER1_INUM, (int_handler_t)(func), (void *)(arg)) @@ -73,18 +69,6 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Fri, 29 May 2015 08:57:00 -0700 Subject: [PATCH 7/7] strtok fix public strtok_r implementation --- .../esp8266/cores/esp8266/libc_replacements.c | 83 ++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c b/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c index 519ea233ae..39ee925a43 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c @@ -169,60 +169,65 @@ char* ICACHE_FLASH_ATTR strncat(char * dest, const char * src, size_t n) { return dest; } +char* ICACHE_FLASH_ATTR strtok_r(char* s, const char* delim, char** last) { + const char* spanp; + char* tok; + char c; + char sc; + + if (s == NULL && (s = *last) == NULL) { + return (NULL); + } -char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** temp) { - static char * ret = NULL; - char * start = NULL; - char * end = NULL; - uint32_t size = 0; - if(str == NULL) { - if(temp == NULL) { - return NULL; + // Skip (span) leading delimiters + // +cont: + c = *s++; + for (spanp = delim; (sc = *spanp++) != 0;) { + if (c == sc) { + goto cont; } - start = *temp; - } else { - start = str; } - if(start == NULL) { - return NULL; + // check for no delimiters left + // + if (c == '\0') { + *last = NULL; + return (NULL); } - if(delimiters == NULL) { - return NULL; - } + tok = s - 1; - end = start; - while(1) { - for(uint16_t i = 0; i < strlen(delimiters); i++) { - if(*end == *(delimiters + i)) { - break; + // Scan token + // Note that delim must have one NUL; we stop if we see that, too. + // + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) { + s = NULL; + } + else { + s[-1] = '\0'; + } + *last = s; + return (tok); } - } - end++; - if(*end == 0x00) { - break; - } - } - *temp = end; - - if(ret != NULL) { - free(ret); + } while (sc != 0); } - size = (end - start); - ret = (char *) malloc(size); - strncpy(ret, start, size); - return ret; + // NOTREACHED EVER } -char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) { - static char * ret = NULL; - ret = strtok_r(str, delimiters, &ret); - return ret; +char* ICACHE_FLASH_ATTR strtok(char* s, const char* delim) { + static char* last; + + return (strtok_r(s, delim, &last)); } int ICACHE_FLASH_ATTR strcasecmp(const char * str1, const char * str2) {