Merge pull request #1000 from devsaurus/sigma_delta

Add sigma_delta module.
This commit is contained in:
Arnim Läuger 2016-02-20 20:11:42 +01:00
commit 8743319b02
9 changed files with 336 additions and 0 deletions

33
app/driver/sigma_delta.c Normal file
View File

@ -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));
}

View File

@ -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

View File

@ -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
app/modules/sigma_delta.c Normal file
View File

@ -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);

View File

@ -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();
@ -444,6 +445,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

View File

@ -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

View File

@ -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`

View File

@ -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'

View File

@ -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