mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
122 lines
3.3 KiB
C
122 lines
3.3 KiB
C
/*
|
|
* This file is designed to support PWM functions in Espruino,
|
|
* a JavaScript interpreter for Microcontrollers designed by Gordon Williams
|
|
*
|
|
* Copyright (C) 2016 by Juergen Marsch
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Publici
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
* This file is designed to be parsed during the build process
|
|
*
|
|
* Contains ESP32 board specific functions.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
#include "jsutils.h"
|
|
|
|
#include "jshardwarePWM.h"
|
|
#include "driver/ledc.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#define PWMFreqDefault 5000
|
|
#define PWMPinEmpty 111
|
|
#define PWMTimerDefault 3
|
|
|
|
int getTimerIndex(Pin pin,int freq){
|
|
int i;
|
|
for(i = 0; i < PWMFreqMax; i++){
|
|
if(PWMFreqChannels[i].pin == pin) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
int getFreeTimer(Pin pin,int freq){
|
|
int i;
|
|
i = getTimerIndex(pin,freq);
|
|
if(i >= 0) return i;
|
|
for(i = 0; i < PWMFreqMax; i++){
|
|
if(PWMFreqChannels[i].pin == PWMPinEmpty) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int getChannelIndex(Pin pin){
|
|
int i;
|
|
for(i = 0; i < PWMMax; i++){
|
|
if(PWMChannels[i].pin == pin) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
int getFreeChannel(pin){
|
|
int i;
|
|
i = getChannelIndex(pin);
|
|
if(i >= 0) return i;
|
|
for(i = 0; i < PWMMax; i++){
|
|
if(PWMChannels[i].pin == PWMPinEmpty) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void timerConfig(int freq,int timer){
|
|
ledc_timer_config_t PWM_timer = {
|
|
.bit_num = LEDC_TIMER_10_BIT,//set timer counter bit number
|
|
.freq_hz = freq,//set frequency of pwm
|
|
.speed_mode = LEDC_HIGH_SPEED_MODE,//timer mode,
|
|
.timer_num = timer//timer index
|
|
};
|
|
ledc_timer_config(&PWM_timer);
|
|
}
|
|
void channelConfig(int timer, int channel, int value, Pin pin){
|
|
ledc_channel_config_t PWM_channel = {
|
|
.channel = channel,//set LEDC channel 0
|
|
.duty = value,//set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
|
|
.gpio_num = pin,//GPIO number
|
|
.intr_type = LEDC_INTR_DISABLE,//GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
|
|
.speed_mode = LEDC_HIGH_SPEED_MODE,//set LEDC mode, from ledc_mode_t
|
|
.timer_sel = timer
|
|
};
|
|
ledc_channel_config(&PWM_channel);
|
|
}
|
|
|
|
void PWMInit(){
|
|
int i;
|
|
timerConfig(PWMFreqDefault,PWMTimerDefault);
|
|
for(i = 0; i < PWMMax; i++) PWMChannels[i].pin = PWMPinEmpty;
|
|
for(i = 0; i < PWMFreqMax; i++) PWMFreqChannels[i].pin = PWMPinEmpty;
|
|
}
|
|
|
|
void writePWM(Pin pin,uint16_t value,int freq){
|
|
int channel; int timer;
|
|
if(freq == PWMFreqDefault || freq == 0){
|
|
channel = getFreeChannel(pin);
|
|
if(channel < 0){jsError("no PWM channel available anymore");}
|
|
else{
|
|
PWMChannels[channel].pin = pin;
|
|
channelConfig(PWMTimerDefault,channel,value,pin);
|
|
}
|
|
}
|
|
else{
|
|
timer = getFreeTimer(pin,freq);
|
|
if(timer < 0){jsError("no PWM channel available anymore");}
|
|
else{
|
|
PWMFreqChannels[timer].pin = pin;
|
|
PWMFreqChannels[timer].freq = freq;
|
|
timerConfig(freq,timer);
|
|
channelConfig(timer,PWMMax + timer,value,pin);
|
|
}
|
|
}
|
|
}
|
|
|
|
void setPWM(Pin pin,uint16_t value){
|
|
int channel = getChannelIndex(pin);
|
|
if(channel < 0){jsError("pin not assigned to pwm");}
|
|
else{
|
|
ledc_set_duty(LEDC_HIGH_SPEED_MODE, channel, value);
|
|
}
|
|
}
|
|
|
|
|
|
|