diff --git a/app/driver/sigma_delta.c b/app/driver/sigma_delta.c
new file mode 100644
index 00000000..50c99005
--- /dev/null
+++ b/app/driver/sigma_delta.c
@@ -0,0 +1,33 @@
+
+#include "driver/sigma_delta.h"
+
+
+void sigma_delta_setup( void )
+{
+ GPIO_REG_WRITE(GPIO_SIGMA_DELTA,
+ GPIO_SIGMA_DELTA_SET(GPIO_SIGMA_DELTA_ENABLE) |
+ GPIO_SIGMA_DELTA_TARGET_SET(0x00) |
+ GPIO_SIGMA_DELTA_PRESCALE_SET(0x00));
+}
+
+void sigma_delta_stop( void )
+{
+ GPIO_REG_WRITE(GPIO_SIGMA_DELTA,
+ GPIO_SIGMA_DELTA_SET(GPIO_SIGMA_DELTA_DISABLE) |
+ GPIO_SIGMA_DELTA_TARGET_SET(0x00) |
+ GPIO_SIGMA_DELTA_PRESCALE_SET(0x00) );
+}
+
+void sigma_delta_set_prescale_target( sint16 prescale, sint16 target )
+{
+ uint32_t prescale_mask, target_mask;
+
+ prescale_mask = prescale >= 0 ? GPIO_SIGMA_DELTA_PRESCALE_MASK : 0x00;
+ target_mask = target >= 0 ? GPIO_SIGMA_DELTA_TARGET_MASK : 0x00;
+
+ // set prescale and target with one register access to avoid glitches
+ GPIO_REG_WRITE(GPIO_SIGMA_DELTA,
+ (GPIO_REG_READ(GPIO_SIGMA_DELTA) & ~(prescale_mask | target_mask)) |
+ (GPIO_SIGMA_DELTA_PRESCALE_SET(prescale) & prescale_mask) |
+ (GPIO_SIGMA_DELTA_TARGET_SET(target) & target_mask));
+}
diff --git a/app/include/driver/sigma_delta.h b/app/include/driver/sigma_delta.h
new file mode 100644
index 00000000..13148e19
--- /dev/null
+++ b/app/include/driver/sigma_delta.h
@@ -0,0 +1,11 @@
+#ifndef SIGMA_DELTA_APP_H
+#define SIGMA_DELTA_APP_H
+
+#include "eagle_soc.h"
+#include "os_type.h"
+
+void sigma_delta_setup( void );
+void sigma_delta_stop( void );
+void sigma_delta_set_prescale_target( sint16 prescale, sint16 target );
+
+#endif
diff --git a/app/include/user_modules.h b/app/include/user_modules.h
index a250e060..79e32a1f 100644
--- a/app/include/user_modules.h
+++ b/app/include/user_modules.h
@@ -37,6 +37,7 @@
#define LUA_USE_MODULES_RTCFIFO
#define LUA_USE_MODULES_RTCMEM
#define LUA_USE_MODULES_RTCTIME
+//#define LUA_USE_MODULES_SIGMA_DELTA
#define LUA_USE_MODULES_SNTP
#define LUA_USE_MODULES_SPI
#define LUA_USE_MODULES_TMR
diff --git a/app/modules/sigma_delta.c b/app/modules/sigma_delta.c
new file mode 100644
index 00000000..7bcbb7e7
--- /dev/null
+++ b/app/modules/sigma_delta.c
@@ -0,0 +1,87 @@
+// Module for interfacing with sigma-delta hardware
+
+#include "module.h"
+#include "lauxlib.h"
+#include "platform.h"
+
+
+// Lua: setup( pin )
+static int sigma_delta_setup( lua_State *L )
+{
+ int pin = luaL_checkinteger( L, 1 );
+
+ MOD_CHECK_ID(sigma_delta, pin);
+
+ platform_sigma_delta_setup( pin );
+
+ return 0;
+}
+
+// Lua: close( pin )
+static int sigma_delta_close( lua_State *L )
+{
+ int pin = luaL_checkinteger( L, 1 );
+
+ MOD_CHECK_ID(sigma_delta, pin);
+
+ platform_sigma_delta_close( pin );
+
+ return 0;
+}
+
+
+// Lua: setpwmduty( duty_cycle )
+static int sigma_delta_setpwmduty( lua_State *L )
+{
+ int duty = luaL_checkinteger( L, 1 );
+
+ if (duty < 0 || duty > 255) {
+ return luaL_error( L, "wrong arg range" );
+ }
+
+ platform_sigma_delta_set_pwmduty( duty );
+
+ return 0;
+}
+
+// Lua: setprescale( value )
+static int sigma_delta_setprescale( lua_State *L )
+{
+ int prescale = luaL_checkinteger( L, 1 );
+
+ if (prescale < 0 || prescale > 255) {
+ return luaL_error( L, "wrong arg range" );
+ }
+
+ platform_sigma_delta_set_prescale( prescale );
+
+ return 0;
+}
+
+// Lua: settarget( value )
+static int sigma_delta_settarget( lua_State *L )
+{
+ int target = luaL_checkinteger( L, 1 );
+
+ if (target < 0 || target > 255) {
+ return luaL_error( L, "wrong arg range" );
+ }
+
+ platform_sigma_delta_set_target( target );
+
+ return 0;
+}
+
+
+// Module function map
+static const LUA_REG_TYPE sigma_delta_map[] =
+{
+ { LSTRKEY( "setup" ), LFUNCVAL( sigma_delta_setup ) },
+ { LSTRKEY( "close" ), LFUNCVAL( sigma_delta_close ) },
+ { LSTRKEY( "setpwmduty" ), LFUNCVAL( sigma_delta_setpwmduty ) },
+ { LSTRKEY( "setprescale" ), LFUNCVAL( sigma_delta_setprescale ) },
+ { LSTRKEY( "settarget" ), LFUNCVAL( sigma_delta_settarget ) },
+ { LNILKEY, LNILVAL }
+};
+
+NODEMCU_MODULE(SIGMA_DELTA, "sigma_delta", sigma_delta_map, NULL);
diff --git a/app/platform/platform.c b/app/platform/platform.c
index 2c28bd6f..6121f84f 100755
--- a/app/platform/platform.c
+++ b/app/platform/platform.c
@@ -12,6 +12,7 @@
#include "driver/i2c_master.h"
#include "driver/spi.h"
#include "driver/uart.h"
+#include "driver/sigma_delta.h"
static void pwms_init();
@@ -440,6 +441,69 @@ void platform_pwm_stop( unsigned pin )
}
}
+
+// *****************************************************************************
+// Sigma-Delta platform interface
+
+uint8_t platform_sigma_delta_setup( uint8_t pin )
+{
+ if (pin < 1 || pin > NUM_GPIO)
+ return 0;
+
+ sigma_delta_setup();
+
+ // set GPIO output mode for this pin
+ platform_gpio_mode( pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
+ platform_gpio_write( pin, PLATFORM_GPIO_LOW );
+
+ // enable sigma-delta on this pin
+ GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin])),
+ (GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin]))) &(~GPIO_PIN_SOURCE_MASK)) |
+ GPIO_PIN_SOURCE_SET( SIGMA_AS_PIN_SOURCE ));
+
+ return 1;
+}
+
+uint8_t platform_sigma_delta_close( uint8_t pin )
+{
+ if (pin < 1 || pin > NUM_GPIO)
+ return 0;
+
+ sigma_delta_stop();
+
+ // set GPIO input mode for this pin
+ platform_gpio_mode( pin, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP );
+
+ // CONNECT GPIO TO PIN PAD
+ GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin])),
+ (GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[pin]))) &(~GPIO_PIN_SOURCE_MASK)) |
+ GPIO_PIN_SOURCE_SET( GPIO_AS_PIN_SOURCE ));
+
+ return 1;
+}
+
+void platform_sigma_delta_set_pwmduty( uint8_t duty )
+{
+ uint8_t target = 0, prescale = 0;
+
+ target = duty > 128 ? 256 - duty : duty;
+ prescale = target == 0 ? 0 : target-1;
+
+ //freq = 80000 (khz) /256 /duty_target * (prescale+1)
+ sigma_delta_set_prescale_target( prescale, duty );
+}
+
+void platform_sigma_delta_set_prescale( uint8_t prescale )
+{
+ sigma_delta_set_prescale_target( prescale, -1 );
+}
+
+void platform_sigma_delta_set_target( uint8_t target )
+{
+ sigma_delta_set_prescale_target( -1, target );
+}
+
+
// *****************************************************************************
// I2C platform interface
diff --git a/app/platform/platform.h b/app/platform/platform.h
index 46e65e0f..af102bd9 100644
--- a/app/platform/platform.h
+++ b/app/platform/platform.h
@@ -203,6 +203,19 @@ static inline int platform_ow_exists( unsigned id ) { return ((id < NUM_OW) && (
static inline int platform_tmr_exists( unsigned id ) { return id < NUM_TMR; }
+// *****************************************************************************
+// Sigma-Delta platform interface
+
+// ****************************************************************************
+// Sigma-Delta functions
+
+static inline int platform_sigma_delta_exists( unsigned id ) {return ((id < NUM_GPIO) && (id > 0)); }
+uint8_t platform_sigma_delta_setup( uint8_t pin );
+uint8_t platform_sigma_delta_close( uint8_t pin );
+void platform_sigma_delta_set_pwmduty( uint8_t duty );
+void platform_sigma_delta_set_prescale( uint8_t prescale );
+void platform_sigma_delta_set_target( uint8_t target );
+
// *****************************************************************************
// I2C platform interface
diff --git a/docs/en/modules/sigma-delta.md b/docs/en/modules/sigma-delta.md
new file mode 100644
index 00000000..aa5a8d91
--- /dev/null
+++ b/docs/en/modules/sigma-delta.md
@@ -0,0 +1,94 @@
+# sigma delta Module
+This module provides access to the sigma-delta component. It's a hardware signal generator that can be routed to any of the GPIOs except pin 0.
+
+The signal generation is controlled by the [`setprescale()`](#sigma_deltasetprescale) and [`settarget()`](#sigma_deltasettarget) functions.
+ * 0 < target <= 128
+ thigh = (prescale + 1) / 80 µs
+ tperiod = thigh * 256 / target
+ * 128 < target < 256
+ tlow = (prescale + 1) / 80 µs
+ tperiod = tlow * 256 / (256 - target)
+ * target = 0
+ signal stopped at low
+
+Fixed frequency PWM at ~312.5 kHz is availble with the [`setpwmduty()`](#sigma_deltasetpwmduty) function.
+
+## sigma_delta.close()
+Stops signal generation and reenables GPIO functionality at the specified pin.
+
+#### Syntax
+`sigma_delta.close(pin)`
+
+#### Parameters
+`pin` 1~12, IO index
+
+#### Returns
+`nil`
+
+## sigma_delta.setprescale()
+Sets the prescale value.
+
+#### Syntax
+`sigma_delta.setprescale(value)
+
+#### Parameters
+`value` prescale 1 to 255
+
+#### Returns
+`nil`
+
+#### See also
+[`sigma_delta.settarget()`](#sigma_deltasettarget)
+
+## sigma_delta.setpwmduty()
+Operate the sigma-delta module in PWM-like mode with fixed base frequency.
+
+#### Syntax
+`sigma_delta.setpwmduty(ratio)`
+
+#### Parameters
+`ratio` 0...255 for duty cycle 0...100%, 0 stops the signal at low
+
+#### Returns
+`nil`
+
+#### Example
+```lua
+-- attach generator to pin 2
+sigma_delta.setup(2)
+-- set 50% duty cycle ratio (and implicitly start signal)
+sigma_delta.setpwmduty(128)
+-- stop
+sigma_delta.setpwmduty(0)
+-- resume with ~99.6% ratio
+sigma_delta.setpwmduty(255)
+-- stop and detach generator from pin 2
+sigma_delta.close(2)
+```
+
+## sigma_delta.settarget()
+Sets the target value.
+
+#### Syntax
+`sigma_delta.settarget(value)
+
+#### Parameters
+`value` target 0 to 255
+
+#### Returns
+`nil`
+
+#### See also
+[`sigma_delta.setprescale()`](#sigma_deltasetprescale)
+
+## sigma_delta.setup()
+Stops the signal generator and routes it to the specified pin.
+
+#### Syntax
+`sigma_delta.setup(pin)`
+
+#### Parameters
+`pin` 1~12, IO index
+
+#### Returns
+`nil`
diff --git a/mkdocs.yml b/mkdocs.yml
index 3ea3fade..ba7c42fa 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -56,6 +56,7 @@ pages:
- 'rtcmem': 'en/modules/rtcmem.md'
- 'rtctime': 'en/modules/rtctime.md'
- 'rtcfifo': 'en/modules/rtcfifo.md'
+ - 'sigma delta': 'en/modules/sigma-delta.md'
- 'sntp': 'en/modules/sntp.md'
- 'spi': 'en/modules/spi.md'
- 'tmr': 'en/modules/tmr.md'
diff --git a/sdk-overrides/include/eagle_soc.h b/sdk-overrides/include/eagle_soc.h
new file mode 100644
index 00000000..efca7dc5
--- /dev/null
+++ b/sdk-overrides/include/eagle_soc.h
@@ -0,0 +1,32 @@
+#ifndef _SDK_OVERRIDE_EAGLE_SOC_H_
+#define _SDK_OVERRIDE_EAGLE_SOC_H_
+
+
+#include_next "eagle_soc.h"
+
+#define GPIO_SIGMA_DELTA 0x00000068 //defined in gpio register.xls
+
+#define GPIO_SIGMA_DELTA_SETTING_MASK (0x00000001ff)
+
+#define GPIO_SIGMA_DELTA_ENABLE 1
+#define GPIO_SIGMA_DELTA_DISABLE (~GPIO_SIGMA_DELTA_ENABLE)
+#define GPIO_SIGMA_DELTA_MSB 16
+#define GPIO_SIGMA_DELTA_LSB 16
+#define GPIO_SIGMA_DELTA_MASK (0x00000001<> GPIO_SIGMA_DELTA_LSB)
+#define GPIO_SIGMA_DELTA_SET(x) (((x) << GPIO_SIGMA_DELTA_LSB) & GPIO_SIGMA_DELTA_MASK)
+
+#define GPIO_SIGMA_DELTA_TARGET_MSB 7
+#define GPIO_SIGMA_DELTA_TARGET_LSB 0
+#define GPIO_SIGMA_DELTA_TARGET_MASK (0x000000FF<> GPIO_SIGMA_DELTA_TARGET_LSB)
+#define GPIO_SIGMA_DELTA_TARGET_SET(x) (((x) << GPIO_SIGMA_DELTA_TARGET_LSB) & GPIO_SIGMA_DELTA_TARGET_MASK)
+
+#define GPIO_SIGMA_DELTA_PRESCALE_MSB 15
+#define GPIO_SIGMA_DELTA_PRESCALE_LSB 8
+#define GPIO_SIGMA_DELTA_PRESCALE_MASK (0x000000FF<> GPIO_SIGMA_DELTA_PRESCALE_LSB)
+#define GPIO_SIGMA_DELTA_PRESCALE_SET(x) (((x) << GPIO_SIGMA_DELTA_PRESCALE_LSB) & GPIO_SIGMA_DELTA_PRESCALE_MASK)
+
+
+#endif