mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-04 01:23:50 +03:00
Add support for hardware Sigma Delta generator
Provides a simple interface to attach/detach pins to the sigma-delta generator, and get/set the 2 parameters prescaler & target. Working example that fades the onboard LED is provided. Code and sample by @stefaandesmet2003.
This commit is contained in:
committed by
GitHub
parent
3b269c4a96
commit
afcbcd5cc9
174
cores/esp8266/core_esp8266_sigma_delta.c
Normal file
174
cores/esp8266/core_esp8266_sigma_delta.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
core_esp8266_sigma_delta.c - sigma delta library for esp8266
|
||||||
|
|
||||||
|
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||||
|
This file is part of the esp8266 core for Arduino environment.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Arduino.h" // using pinMode
|
||||||
|
|
||||||
|
// definitions in esp8266_peri.h style
|
||||||
|
#define GPSD ESP8266_REG(0x368) // GPIO_SIGMA_DELTA register @ 0x600000368
|
||||||
|
#define GPSDT 0 // target, 8 bits
|
||||||
|
#define GPSDP 8 // prescaler, 8 bits
|
||||||
|
#define GPSDE 16 // enable
|
||||||
|
|
||||||
|
void sigmaDeltaSetPrescaler(uint8_t prescaler); // avoids compiler warning
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaEnable
|
||||||
|
* Description : enable the internal sigma delta source
|
||||||
|
* Parameters : none
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
void ICACHE_FLASH_ATTR sigmaDeltaEnable()
|
||||||
|
{
|
||||||
|
GPSD = (0 << GPSDT) | (0 << GPSDP) | (1 << GPSDE); //SIGMA_DELTA_TARGET(0) | SIGMA_DELTA_PRESCALER(0) | SIGMA_DELTA_ENABLE(ENABLED)
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaDisable
|
||||||
|
* Description : stop the internal sigma delta source
|
||||||
|
* Parameters : none
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
void ICACHE_FLASH_ATTR sigmaDeltaDisable()
|
||||||
|
{
|
||||||
|
GPSD = (0 << GPSDT) | (0 << GPSDP) | (0 << GPSDE); //SIGMA_DELTA_TARGET(0) | SIGMA_DELTA_PRESCALER(0) | SIGMA_DELTA_ENABLE(DISABLED)
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaAttachPin
|
||||||
|
* Description : connects the sigma delta source to a physical output pin
|
||||||
|
* Parameters : pin (0..15), channel = unused, for compatibility with ESP32
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
void ICACHE_FLASH_ATTR sigmaDeltaAttachPin(uint8_t pin, uint8_t channel)
|
||||||
|
{
|
||||||
|
(void) channel;
|
||||||
|
// make the chosen pin an output pin
|
||||||
|
pinMode (pin, OUTPUT);
|
||||||
|
if (pin < 16) {
|
||||||
|
// set its source to the sigma delta source
|
||||||
|
GPC(pin) |= (1 << GPCS); //SOURCE 0:GPIO_DATA,1:SigmaDelta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaDetachPin
|
||||||
|
* Description : disconnects the sigma delta source from a physical output pin
|
||||||
|
* Parameters : pin (0..16)
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
void ICACHE_FLASH_ATTR sigmaDeltaDetachPin(uint8_t pin)
|
||||||
|
{
|
||||||
|
if (pin < 16) {
|
||||||
|
// set its source to the sigma delta source
|
||||||
|
GPC(pin) &= ~(1 << GPCS); //SOURCE 0:GPIO_DATA,1:SigmaDelta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaIsPinAttached
|
||||||
|
* Description : query if pin is attached
|
||||||
|
* Parameters : pin (0..16)
|
||||||
|
* Returns : bool
|
||||||
|
*******************************************************************************/
|
||||||
|
bool ICACHE_FLASH_ATTR sigmaDeltaIsPinAttached(uint8_t pin)
|
||||||
|
{
|
||||||
|
if (pin < 16) {
|
||||||
|
// set its source to the sigma delta source
|
||||||
|
return (GPC(pin) & (1 << GPCS)); //SOURCE 0:GPIO_DATA,1:SigmaDelta
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaSetup
|
||||||
|
* Description : start the sigma delta generator with the chosen parameters
|
||||||
|
* Parameters : channel = unused (for compatibility with ESP32),
|
||||||
|
* freq : 1220-312500 (lowest frequency in the output signal's spectrum)
|
||||||
|
* Returns : uint32_t the actual frequency, closest to the input parameter
|
||||||
|
*******************************************************************************/
|
||||||
|
uint32_t ICACHE_FLASH_ATTR sigmaDeltaSetup(uint8_t channel, uint32_t freq)
|
||||||
|
{
|
||||||
|
(void) channel;
|
||||||
|
|
||||||
|
uint32_t prescaler = ((uint32_t)10000000/(freq*32)) - 1;
|
||||||
|
|
||||||
|
if(prescaler > 0xFF) {
|
||||||
|
prescaler = 0xFF;
|
||||||
|
}
|
||||||
|
sigmaDeltaEnable();
|
||||||
|
sigmaDeltaSetPrescaler ((uint8_t) prescaler);
|
||||||
|
|
||||||
|
return 10000000/((prescaler + 1) * 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaWrite
|
||||||
|
* Description : set the duty cycle for the sigma-delta source
|
||||||
|
* Parameters : uint8 duty, 0-255, duty cycle = target/256,
|
||||||
|
* channel = unused, for compatibility with ESP32
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
void ICACHE_FLASH_ATTR sigmaDeltaWrite(uint8_t channel, uint8_t duty)
|
||||||
|
{
|
||||||
|
uint32_t reg = GPSD;
|
||||||
|
(void) channel;
|
||||||
|
|
||||||
|
reg = (reg & ~(0xFF << GPSDT)) | ((duty & 0xFF) << GPSDT);
|
||||||
|
GPSD = reg;
|
||||||
|
|
||||||
|
}
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaRead
|
||||||
|
* Description : get the duty cycle for the sigma-delta source
|
||||||
|
* Parameters : channel = unused, for compatibility with ESP32
|
||||||
|
* Returns : uint8_t duty cycle value 0..255
|
||||||
|
*******************************************************************************/
|
||||||
|
uint8_t ICACHE_FLASH_ATTR sigmaDeltaRead(uint8_t channel)
|
||||||
|
{
|
||||||
|
(void) channel;
|
||||||
|
return (uint8_t)((GPSD >> GPSDT) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaSetPrescaler
|
||||||
|
* Description : set the clock divider for the sigma-delta source
|
||||||
|
* Parameters : uint8 prescaler, 0-255, divides the 80MHz base clock by this amount
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
void ICACHE_FLASH_ATTR sigmaDeltaSetPrescaler(uint8_t prescaler)
|
||||||
|
{
|
||||||
|
uint32_t reg = GPSD;
|
||||||
|
|
||||||
|
reg = (reg & ~(0xFF << GPSDP)) | ((prescaler & 0xFF) << GPSDP);
|
||||||
|
GPSD = reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : sigmaDeltaGetPrescaler
|
||||||
|
* Description : get the prescaler value from the GPIO_SIGMA_DELTA register
|
||||||
|
* Parameters : none
|
||||||
|
* Returns : uint8 prescaler, CLK_DIV , 0-255
|
||||||
|
*******************************************************************************/
|
||||||
|
uint8_t ICACHE_FLASH_ATTR sigmaDeltaGetPrescaler(void)
|
||||||
|
{
|
||||||
|
return (uint8_t)((GPSD >> GPSDP) & 0xFF);
|
||||||
|
}
|
@ -18,15 +18,55 @@
|
|||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Info Sigma delta module
|
||||||
|
|
||||||
|
This module controls the esp8266 internal sigma delta source
|
||||||
|
Each pin can be connected to the sigma delta source
|
||||||
|
The target duty and frequency can be modified via the register GPIO_SIGMA_DELTA
|
||||||
|
|
||||||
|
THE TARGET FREQUENCY IS DEFINED AS:
|
||||||
|
|
||||||
|
FREQ = 80,000,000/prescaler * target /256 HZ, 0<target<128
|
||||||
|
FREQ = 80,000,000/prescaler * (256-target) /256 HZ, 128<target<256
|
||||||
|
target: duty cycle,range 0-255
|
||||||
|
prescaler: is a clock divider, range 0-255
|
||||||
|
so the target and prescale will both affect the freq.
|
||||||
|
CPU_FREQ has no influence on the sigma delta frequency.
|
||||||
|
|
||||||
|
Usage :
|
||||||
|
1. sigmaDeltaSetup(0,f) : activate the sigma delta source with frequency f and default duty cycle (0)
|
||||||
|
2. sigmaDeltaAttachPin(pin), any pin 0..15, TBC if gpio16 supports sigma-delta source
|
||||||
|
This will set the pin to NORMAL output mode (pinMode(pin,OUTPUT))
|
||||||
|
3. sigmaDeltaWrite(0,dc) : set the output signal duty cycle, duty cycle = dc/256
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
#ifndef SIGMA_DELTA_H
|
#ifndef SIGMA_DELTA_H
|
||||||
#define SIGMA_DELTA_H
|
#define SIGMA_DELTA_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void sigma_delta_close(uint32_t gpio);
|
//channel parameter is unused (only for ESP32 compatibility) freq 1220-312500 duty 0-255
|
||||||
void set_sigma_target(uint8_t target);
|
void sigmaDeltaEnable(void);
|
||||||
void set_sigma_prescale(uint8_t prescale);
|
void sigmaDeltaDisable(void);
|
||||||
void set_sigma_duty_312KHz(uint8_t duty);
|
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq);
|
||||||
|
void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
|
||||||
|
uint8_t sigmaDeltaRead(uint8_t channel = 0);
|
||||||
|
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel = 0);
|
||||||
|
void sigmaDeltaDetachPin(uint8_t pin);
|
||||||
|
bool sigmaDeltaIsPinAttached(uint8_t pin);
|
||||||
|
|
||||||
|
// alternative way to control the sigma delta generator frequency
|
||||||
|
uint8_t sigmaDeltaGetPrescaler(void);
|
||||||
|
void sigmaDeltaSetPrescaler(uint8_t prescaler);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif//SIGMA_DELTA_H
|
#endif//SIGMA_DELTA_H
|
||||||
|
48
libraries/esp8266/examples/SigmaDeltaDemo/SigmaDeltaDemo.ino
Normal file
48
libraries/esp8266/examples/SigmaDeltaDemo/SigmaDeltaDemo.ino
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain. */
|
||||||
|
|
||||||
|
#include "sigma_delta.h"
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
pinMode(LED_BUILTIN, OUTPUT); // blinkie & sigma-delta mix
|
||||||
|
uint32_t reqFreq = 1000;
|
||||||
|
uint32_t realFreq;
|
||||||
|
|
||||||
|
realFreq = sigmaDeltaSetup(0, reqFreq); // chose a low frequency
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Start Sigma Delta Example\n");
|
||||||
|
Serial.printf("Frequency = %u\n", realFreq);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
uint8_t duty, iRepeat;
|
||||||
|
|
||||||
|
Serial.println("Attaching the built in led to the sigma delta source now\n");
|
||||||
|
Serial.printf("Current duty = %i, prescaler = %i\n", sigmaDeltaRead(), sigmaDeltaGetPrescaler());
|
||||||
|
sigmaDeltaAttachPin(LED_BUILTIN);
|
||||||
|
|
||||||
|
Serial.println("Dimming builtin led...\n");
|
||||||
|
for (iRepeat = 0; iRepeat < 10; iRepeat++) {
|
||||||
|
for (duty = 0; duty < 255; duty = duty + 5) {
|
||||||
|
sigmaDeltaWrite(0, duty);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (duty = 255; duty > 0; duty = duty - 5) {
|
||||||
|
sigmaDeltaWrite(0, duty);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("Detaching builtin led & playing a blinkie\n");
|
||||||
|
sigmaDeltaDetachPin(LED_BUILTIN);
|
||||||
|
for (iRepeat = 0; iRepeat < 20; iRepeat++) {
|
||||||
|
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
}
|
72
sigma_delta.h
Normal file
72
sigma_delta.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
sigma_delta.h - esp8266 sigma-delta source
|
||||||
|
|
||||||
|
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||||
|
This file is part of the esp8266 core for Arduino environment.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
/******************************************************************************
|
||||||
|
* Info Sigma delta module
|
||||||
|
|
||||||
|
This module controls the esp8266 internal sigma delta source
|
||||||
|
Each pin can be connected to the sigma delta source
|
||||||
|
The target duty and frequency can be modified via the register GPIO_SIGMA_DELTA
|
||||||
|
|
||||||
|
THE TARGET FREQUENCY IS DEFINED AS:
|
||||||
|
|
||||||
|
FREQ = 80,000,000/prescaler * target /256 HZ, 0<target<128
|
||||||
|
FREQ = 80,000,000/prescaler * (256-target) /256 HZ, 128<target<256
|
||||||
|
target: duty ,0-255
|
||||||
|
prescaler: clk_div,0-255
|
||||||
|
so the target and prescale will both affect the freq.
|
||||||
|
|
||||||
|
Usage :
|
||||||
|
1. sigma_delta_enable() : activate the sigma delta source with default prescalar (0) & target (0)
|
||||||
|
2. sigma_delta_attachPin(pin), any pin 0..15, TBC if gpio16 supports sigma-delta source
|
||||||
|
This will set the pin to NORMAL output mode (pinMode(pin,OUTPUT))
|
||||||
|
3. sigma_delta_setPrescaler(uint8_t) : reduce the output frequencies
|
||||||
|
4. sigma_delta_setTarget(uint8_t) : set the output signal duty cycle, duty cycle = target/256
|
||||||
|
|
||||||
|
5. sigma_delta_detachPin(pin), this will revert the pin to NORMAL output mode & GPIO source.
|
||||||
|
The sigma delta source remains on until :
|
||||||
|
6. sigma_delta_disable()
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SIGMA_DELTA_H
|
||||||
|
#define SIGMA_DELTA_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void sigma_delta_enable(void);
|
||||||
|
void sigma_delta_disable(void);
|
||||||
|
void sigma_delta_attachPin(uint8_t pin);
|
||||||
|
void sigma_delta_detachPin(uint8_t pin);
|
||||||
|
bool sigma_delta_isPinAttached(uint8_t pin);
|
||||||
|
uint8_t sigma_delta_getTarget(void);
|
||||||
|
void sigma_delta_setTarget(uint8_t target);
|
||||||
|
uint8_t sigma_delta_getPrescaler(void);
|
||||||
|
void sigma_delta_setPrescaler(uint8_t prescaler);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif//SIGMA_DELTA_H
|
Reference in New Issue
Block a user