Skip to content

Commit

Permalink
light: external pwm support
Browse files Browse the repository at this point in the history
- allow both new-pwm and analogWrite (Core) implementations
- rework new-pwm initialization, a bit more sane type for pin config
- remove pin setup from lights, everything is handled by provider already
Core prepares and initializes pins when updating duty, new-pwm does this
when pwm_init is called
- rework internals related to value scaling, allow percentage as pwm duty
and value limit (instead of absolute limit set by lights previously)
  • Loading branch information
mcspr committed Aug 15, 2022
1 parent 5929ae9 commit b0da3e8
Show file tree
Hide file tree
Showing 11 changed files with 578 additions and 153 deletions.
7 changes: 6 additions & 1 deletion code/espurna/config/dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@

#if IFAN_SUPPORT
#undef RELAY_SUPPORT
#define RELAY_SUPPORT 1 // Need relays to manage general state
#define RELAY_SUPPORT 1 // Need relays to manage general state
#endif

#if LIGHT_PROVIDER == LIGHT_PROVIDER_DIMMER
#undef PWM_SUPPORT
#define PWM_SUPPORT 1 // Need PWM to update channel values
#endif

//------------------------------------------------------------------------------
Expand Down
49 changes: 29 additions & 20 deletions code/espurna/config/general.h
Original file line number Diff line number Diff line change
Expand Up @@ -1139,26 +1139,6 @@
#define LIGHT_SAVE_DELAY 5000 // Persist channel & brightness values after the specified number of ms
#endif

#ifndef LIGHT_MIN_PWM
#define LIGHT_MIN_PWM 0
#endif

#ifndef LIGHT_MAX_PWM

#if LIGHT_PROVIDER == LIGHT_PROVIDER_MY92XX
#define LIGHT_MAX_PWM 255
#elif LIGHT_PROVIDER == LIGHT_PROVIDER_DIMMER
#define LIGHT_MAX_PWM 10000 // 10000 * 200ns => 2 kHz
#else
#define LIGHT_MAX_PWM 0
#endif

#endif // LIGHT_MAX_PWM

#ifndef LIGHT_LIMIT_PWM
#define LIGHT_LIMIT_PWM LIGHT_MAX_PWM // Limit PWM to this value (prevent 100% power)
#endif

#ifndef LIGHT_MIN_VALUE
#define LIGHT_MIN_VALUE 0 // Minimum light value
#endif
Expand Down Expand Up @@ -1751,6 +1731,35 @@
#define IFAN_SUPPORT 0
#endif

//--------------------------------------------------------------------------------
// PWM driver support
//--------------------------------------------------------------------------------

#ifndef PWM_SUPPORT
#define PWM_SUPPORT 0
#endif

#ifndef PWM_PROVIDER
#define PWM_PROVIDER PWM_PROVIDER_GENERIC // Currently, two software PWM providers are supported
// - PWM_PROVIDER_GENERIC (default)
// - PWM_PROVIDER_ARDUINO
#endif

#ifndef PWM_FREQUENCY
#define PWM_FREQUENCY 2000 // (Hz)
#endif

#ifndef PWM_RESOLUTION
#define PWM_RESOLUTION 10 // (bits)
// Range of raw values accepted by the driver
// 0...1023 by default
#endif

#ifndef PWM_DUTY_LIMIT
#define PWM_DUTY_LIMIT 100 // (percentage)
// Clamp duty value, prevent 100% power
#endif

// =============================================================================
// Configuration helpers to help detect features
// =============================================================================
Expand Down
7 changes: 7 additions & 0 deletions code/espurna/config/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@
#define LIGHT_EFFECT_FADE 3
#define LIGHT_EFFECT_SMOOTH 4

//------------------------------------------------------------------------------
// PWM
//------------------------------------------------------------------------------
#define PWM_PROVIDER_NONE 0
#define PWM_PROVIDER_GENERIC 1
#define PWM_PROVIDER_ARDUINO 2

//------------------------------------------------------------------------------
// ENVIRONMENTAL
//------------------------------------------------------------------------------
Expand Down
18 changes: 9 additions & 9 deletions code/espurna/pwm.c → code/espurna/esp8266_pwm.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* https://github.com/StefanBruens/ESP8266_new_pwm
* Copyright (C) 2016 Stefan Brüns <stefan.bruens@rwth-aachen.de>
*
* This program is free software; you can redistribute it and/or modify
Expand All @@ -16,6 +17,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

// Should include our own prototypes, since the original code does not provide them
#include "libs/esp8266_pwm.h"

/* Set the following three defines to your needs */

#ifndef SDK_PWM_PERIOD_COMPAT_MODE
Expand Down Expand Up @@ -47,7 +51,6 @@
#include <c_types.h>
#include <eagle_soc.h>
#include <ets_sys.h>
#include "libs/pwm.h"

// from SDK hw_timer.c
#define TIMER1_DIVIDE_BY_16 0x0004
Expand Down Expand Up @@ -80,9 +83,6 @@ static uint32_t pwm_duty[PWM_MAX_CHANNELS];
static uint16_t gpio_mask[PWM_MAX_CHANNELS];
static uint8_t pwm_channels;

// 3-tuples of MUX_REGISTER, MUX_VALUE and GPIO number
typedef uint32_t (pin_info_type)[3];

struct gpio_regs {
uint32_t out; /* 0x60000300 */
uint32_t out_w1ts; /* 0x60000304 */
Expand Down Expand Up @@ -159,7 +159,7 @@ pwm_intr_handler(void)
*/
void ICACHE_FLASH_ATTR
pwm_init(uint32_t period, uint32_t *duty, uint32_t pwm_channel_num,
uint32_t (*pin_info_list)[3])
struct pwm_pin_info *pin_info_list)
{
int i, j, n;

Expand All @@ -180,10 +180,10 @@ pwm_init(uint32_t period, uint32_t *duty, uint32_t pwm_channel_num,
uint32_t all = 0;
// PIN info: MUX-Register, Mux-Setting, PIN-Nr
for (n = 0; n < pwm_channels; n++) {
pin_info_type* pin_info = &pin_info_list[n];
PIN_FUNC_SELECT((*pin_info)[0], (*pin_info)[1]);
gpio_mask[n] = 1 << (*pin_info)[2];
all |= 1 << (*pin_info)[2];
struct pwm_pin_info* pin_info = &pin_info_list[n];
PIN_FUNC_SELECT(pin_info->addr, pin_info->func);
gpio_mask[n] = 1 << pin_info->pin;
all |= 1 << pin_info->pin;
if (duty)
pwm_set_duty(duty[n], n);
}
Expand Down
34 changes: 18 additions & 16 deletions code/espurna/libs/pwm.h → code/espurna/libs/esp8266_pwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,32 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef __PWM_H__
#define __PWM_H__
#pragma once

/*SUPPORT UP TO 8 PWM CHANNEL*/
#ifndef PWM_CHANNEL_NUM_MAX
#define PWM_CHANNEL_NUM_MAX 8
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

struct pwm_param {
uint32 period;
uint32 freq;
uint32 duty[PWM_CHANNEL_NUM_MAX]; //PWM_CHANNEL<=8
struct pwm_pin_info {
uint32_t addr;
uint32_t func;
uint32_t pin;
};

/* pwm_init should be called only once, for now */
void pwm_init(uint32 period, uint32 *duty,uint32 pwm_channel_num,uint32 (*pin_info_list)[3]);
void pwm_init(uint32_t period, uint32_t *duty, uint32_t pwm_channel_num, struct pwm_pin_info *pin_info_list);
void pwm_start(void);

void pwm_set_duty(uint32 duty, uint8 channel);
uint32 pwm_get_duty(uint8 channel);
void pwm_set_period(uint32 period);
uint32 pwm_get_period(void);
void pwm_set_duty(uint32_t duty, uint8_t channel);
uint32_t pwm_get_duty(uint8_t channel);
void pwm_set_period(uint32_t period);
uint32_t pwm_get_period(void);

uint32 get_pwm_version(void);
void set_pwm_debug_en(uint8 print_en);
uint32_t get_pwm_version(void);
void set_pwm_debug_en(uint8_t print_en);

#ifdef __cplusplus
}
#endif
10 changes: 8 additions & 2 deletions code/espurna/libs/fs_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
/*
** Portable freestanding code.
*/
#ifndef H_FS_MATH_H
#define H_FS_MATH_H

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

double fs_sqrt(double x);
double fs_log(double x);
Expand All @@ -34,6 +38,8 @@ long double fs_expl(long double x);
long double fs_cosl(long double x);
long double fs_fmodl(long double x, long double y);

#ifdef __cplusplus
}
#endif

/* END fs_math.h */
Expand Down
Loading

0 comments on commit b0da3e8

Please sign in to comment.