#define LED 2
#include "driver/ledc.h"
/* LEDC (LED Controller) basic example
*/
#include <stdio.h>
#include "soc/ledc_reg.h"
#include "soc/ledc_struct.h"
ledc_dev_t *hw = (ledc_dev_t*)DR_REG_LEDC_BASE;
static ledc_isr_handle_t s_ledc_timer_isr_handle = NULL;
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_OUTPUT_IO (25) // Define the output GPIO
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_DUTY_RES LEDC_TIMER_8_BIT // Set duty resolution to 13 bits
#define LEDC_DUTY (127) // Set duty to 50%. ((2 ** 8) - 1) * 50% = 4095
#define LEDC_FREQUENCY (22500) // Frequency in Hertz. Set frequency at 5 kHz
int8_t sine[256];
long oldPosition=0;
#define nch 4 //number of channels that can produce sound simultaneously
uint16_t phase[nch] = {0, 0, 0, 0};
int inc[nch] = {0, 0, 0, 0};
byte amp[nch] = {127, 0, 0, 0};
static void example_ledc_init(void)
{
// Prepare and then apply the LEDC PWM timer configuration
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_MODE,
.duty_resolution = LEDC_DUTY_RES,
.timer_num = LEDC_TIMER,
.freq_hz = LEDC_FREQUENCY, // Set output frequency at 5 kHz
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
// Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t ledc_channel = {
.gpio_num = LEDC_OUTPUT_IO,
.speed_mode = LEDC_MODE,
.channel = LEDC_CHANNEL,
.intr_type = LEDC_INTR_DISABLE,//LEDC_INTR_MAX,
.timer_sel = LEDC_TIMER,
.duty = 0, // Set duty to 0%
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
static inline void ledc_lll_clear_timer_ovf_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
//uint32_t int_en_base = LEDC_LSTIMER0_OVF_INT_ST_S;
uint32_t int_en_base = LEDC_LSTIMER0_OVF_INT_CLR_S;
hw->int_clr.val = BIT(int_en_base + channel_num);
}
static inline void ledc_lll_set_timer_ovf_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en){
uint32_t value = hw->int_ena.val;
uint32_t int_en_base = LEDC_LSTIMER0_OVF_INT_ENA_S;
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
}
void IRAM_ATTR ledc_isr_fnc(void * arg)
{
//r++;
digitalWrite(LED,HIGH);
ledc_lll_clear_timer_ovf_intr_status(hw,LEDC_MODE,LEDC_CHANNEL);
int val;
// //increment the phases of the note
phase[0] += inc[0];
// //calculate the output value and set pulse width for timer2
val = sine[(phase[0]) >> 8] * amp[0];
hw->channel_group[LEDC_MODE].channel[LEDC_CHANNEL].duty.duty = ((val/256)+128)<< 4;
hw->channel_group[LEDC_MODE].channel[LEDC_CHANNEL].conf0.low_speed_update = 1;
}
//set up array with sine values in signed 8-bit numbers
const float pi = 3.14159265;
void setsine() {
for (int i = 0; i < 256; ++i) {
sine[i] = (sin(2 * 3.14159265 * (i + 0.5) / 256)) * 128;
Serial.print(F("sine["));
Serial.print(i);
Serial.print(F("] "));
Serial.println(sine[i],DEC);
//sine2[i] = (sin(6 * 3.14159265 * (i + 0.5) / 256)) * 128;
//sine2[i] = sine[i];
}
}
//setup frequencies/phase increments, starting at C3=0 to B6. (A4 is defined as 440Hz)
unsigned int tone_inc[48];
void settones() {
for (byte i = 0; i < 48; i++) {
tone_inc[i] = 1760.0 * pow(2.0, ( (i - 21) / 12.0)) * 65536.0 / (16000000.0 / 512) + 0.5;
Serial.print(F("tone_inc["));
Serial.print(i);
Serial.print(F("] "));
Serial.println(tone_inc[i]);
}
}
void FMsetup() {
pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);
//disable all inerrupts to avoid glitches
//noInterrupts();
//Serial.begin(115200);
//setup the array with sine values
setsine();
//setup array with tone frequency phase increments
settones();
//Set a fast PWM signal on TIMER1A, 9-bit resolution, 31250Hz
/* pinMode(9, OUTPUT);
TCCR1A = 0B10000010; //9-bit fast PWM
TCCR1B = 0B00001001;
// включить прерывание Timer1 overflow:
TIMSK1 = (1 << TOIE1);
// */
delay(1000);
Serial.println(F("func_install"));
example_ledc_init();
Serial.print(F("esp_intr_alloc "));
esp_err_t ret;
ret = esp_intr_alloc(ETS_LEDC_INTR_SOURCE, ESP_INTR_FLAG_IRAM, ledc_isr_fnc, NULL, &s_ledc_timer_isr_handle);
Serial.println(ret);
ledc_lll_set_timer_ovf_intr(hw, LEDC_MODE,LEDC_CHANNEL, true);
hw->channel_group[LEDC_MODE].channel[LEDC_CHANNEL].conf0.sig_out_en = true;
hw->channel_group[LEDC_MODE].channel[LEDC_CHANNEL].conf0.low_speed_update = 1;
hw->channel_group[LEDC_MODE].channel[LEDC_CHANNEL].hpoint.hpoint = 0;
hw->channel_group[LEDC_MODE].channel[LEDC_CHANNEL].duty.duty = LEDC_DUTY << 4;
//Serial.end();
//interrupts();
}
#include <ESP32Encoder.h> // https://github.com/madhephaestus/ESP32Encoder.git
#define CLK 12 // CLK ENCODER
#define DT 13 // DT ENCODER
ESP32Encoder encoder;
void setup () {
encoder.attachHalfQuad ( DT, CLK );
encoder.setCount ( 0 );
ESP32Encoder::useInternalWeakPullResistors=UP;
Serial.begin ( 115200 );
FMsetup();
inc[0]=tone_inc[10];
Serial.print(F("inc[0] "));
Serial.println(inc[0]);
}
void loop () {
long newPosition = encoder.getCount() / 2;
if (newPosition < 0)
{
newPosition=0;
}
if (newPosition > 17000)
{
newPosition=17000;
}
if (oldPosition != newPosition)
{
Serial.print(newPosition);
oldPosition = newPosition;
//inc[0]=tone_inc[newPosition/100];
inc[0]=newPosition+1000;
Serial.print(F("inc="));
Serial.println(inc[0]);
}
}