Espruino/targets/esp32/jshardwarePWM.c
2017-04-04 18:39:24 +12:00

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