Browse Source

Add sigma_delta module.

devsaurus 8 years ago
parent
commit
8982650df9

+ 33 - 0
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));
+}

+ 11 - 0
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

+ 1 - 0
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

+ 87 - 0
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);

+ 64 - 0
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
 

+ 13 - 0
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
 

+ 94 - 0
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<br />
+    t<sub>high</sub> = (prescale + 1) / 80 µs<br />
+    t<sub>period</sub>  = t<sub>high</sub> * 256 / target
+  * 128 < target < 256<br />
+    t<sub>low</sub>  = (prescale + 1) / 80 µs<br />
+    t<sub>period</sub> = t<sub>low</sub> * 256 / (256 - target)
+  * target = 0<br />
+    signal stopped at low
+
+Fixed frequency PWM at ~312.5&nbsp;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`

+ 1 - 0
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'

+ 32 - 0
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_GET(x)  (((x) & GPIO_SIGMA_DELTA_MASK) >> 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_GET(x) (((x) & GPIO_SIGMA_DELTA_TARGET_MASK) >> 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_GET(x) (((x) & GPIO_SIGMA_DELTA_PRESCALE_MASK) >> GPIO_SIGMA_DELTA_PRESCALE_LSB)
+#define GPIO_SIGMA_DELTA_PRESCALE_SET(x) (((x) << GPIO_SIGMA_DELTA_PRESCALE_LSB) & GPIO_SIGMA_DELTA_PRESCALE_MASK)
+
+
+#endif