diff --git a/core/include/esp/gpio_regs.h b/core/include/esp/gpio_regs.h index c5a446c..167a4d1 100644 --- a/core/include/esp/gpio_regs.h +++ b/core/include/esp/gpio_regs.h @@ -70,7 +70,7 @@ struct GPIO_REGS { uint32_t volatile STATUS_SET; // 0x20 uint32_t volatile STATUS_CLEAR; // 0x24 uint32_t volatile CONF[16]; // 0x28 - 0x64 - uint32_t volatile PWM; // 0x68 + uint32_t volatile DSM; // 0x68 uint32_t volatile RTC_CALIB; // 0x6c uint32_t volatile RTC_CALIB_RESULT; // 0x70 }; @@ -117,9 +117,9 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); * GPIO_CONF_OPEN_DRAIN does not appear to work on all pins. * * - * GPIO_CONF_SOURCE_PWM (boolean) - * When set, GPIO pin output will be connected to the sigma-delta PWM - * generator (controlled by the GPIO.PWM register). When cleared, pin + * GPIO_CONF_SOURCE_DSM (boolean) + * When set, GPIO pin output will be connected to the sigma-delta + * generator (controlled by the GPIO.DSM register). When cleared, pin * output will function as a normal GPIO output (controlled by the * GPIO.OUT* registers). */ @@ -130,7 +130,7 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size"); #define GPIO_CONF_INTTYPE_M 0x00000007 #define GPIO_CONF_INTTYPE_S 7 #define GPIO_CONF_OPEN_DRAIN BIT(2) -#define GPIO_CONF_SOURCE_PWM BIT(0) +#define GPIO_CONF_SOURCE_DSM BIT(0) /* Valid values for the GPIO_CONF_INTTYPE field */ typedef enum { @@ -142,13 +142,13 @@ typedef enum { GPIO_INTTYPE_LEVEL_HIGH = 5, } gpio_inttype_t; -/* Details for PWM register */ +/* Details for DSM register */ -#define GPIO_PWM_ENABLE BIT(16) -#define GPIO_PWM_PRESCALER_M 0x000000ff -#define GPIO_PWM_PRESCALER_S 8 -#define GPIO_PWM_TARGET_M 0x000000ff -#define GPIO_PWM_TARGET_S 0 +#define GPIO_DSM_ENABLE BIT(16) +#define GPIO_DSM_PRESCALER_M 0x000000ff +#define GPIO_DSM_PRESCALER_S 8 +#define GPIO_DSM_TARGET_M 0x000000ff +#define GPIO_DSM_TARGET_S 0 /* Details for RTC_CALIB register */ diff --git a/examples/dsm_test/Makefile b/examples/dsm_test/Makefile new file mode 100644 index 0000000..8438f41 --- /dev/null +++ b/examples/dsm_test/Makefile @@ -0,0 +1,4 @@ +# Simple makefile for simple example +PROGRAM=dsm_test +EXTRA_COMPONENTS = extras/dsm +include ../../common.mk diff --git a/examples/dsm_test/dsm_test.c b/examples/dsm_test/dsm_test.c new file mode 100644 index 0000000..234a66b --- /dev/null +++ b/examples/dsm_test/dsm_test.c @@ -0,0 +1,67 @@ +/* Very basic example to test the dsm library + * Led intensity from module will change over time. + * + * Part of esp-open-rtos + * Copyright (C) 2018 zaltora (https://github.com/Zaltora) + * BSD Licensed as described in the file LICENSE + */ +#include "espressif/esp_common.h" +#include "esp/uart.h" +#include "FreeRTOS.h" +#include "task.h" +#include "dsm.h" + +#define TEST_WITH_160MHZ (0) +#define DSM_PIN (2) + +void task1(void *pvParameters) +{ + uint32_t const init_count = 0; + uint32_t count = init_count; + while(1) + { + vTaskDelay(100/portTICK_PERIOD_MS); + printf("Target set to %3u, ", count); + //Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128) + //Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256) + if (count < 128) + { + printf("Freqency: %.1f Hz\r\n", (80000000.0/255.0 * (count/ 256.0))); + } + else + { + printf("Freqency: %.1f Hz\r\n", 80000000.0/255.0 * ((256.0-count)/ 256.0)); + } + dsm_set_target(count); + count++; + if (count > UINT8_MAX) + count = init_count; + } +} + +void user_init(void) +{ + uint8_t pins[1]; + uart_set_baud(0, 115200); + +#if (TEST_WITH_160MHZ) + sdk_system_update_cpu_freq(160); +#endif + + printf("SDK version:%s\r\n", sdk_system_get_sdk_version()); + + pins[0] = DSM_PIN; + + /* register pin to use with DSM */ + dsm_init(1, pins); + /* Set prescale to FF to get a proper signal */ + dsm_set_prescale(0xFF); + /* Target initial */ + dsm_set_target(0); + /* start dsm to pin */ + dsm_start(); + + printf("dsm start\r\n"); + + xTaskCreate(task1, "tsk1", 256, NULL, 2, NULL); +} diff --git a/extras/dsm/component.mk b/extras/dsm/component.mk new file mode 100644 index 0000000..06e56b1 --- /dev/null +++ b/extras/dsm/component.mk @@ -0,0 +1,9 @@ +# Component makefile for extras/dsm + +INC_DIRS += $(ROOT)extras/dsm + +# args for passing into compile rule generation +extras/dsm_INC_DIR = $(ROOT)extras/dsm +extras/dsm_SRC_DIR = $(ROOT)extras/dsm + +$(eval $(call component_compile_rules,extras/dsm)) diff --git a/extras/dsm/dsm.c b/extras/dsm/dsm.c new file mode 100644 index 0000000..dd54fc4 --- /dev/null +++ b/extras/dsm/dsm.c @@ -0,0 +1,111 @@ +/* Implementation of Delta-Sigma modulator support. + * + * Part of esp-open-rtos + * Copyright (C) 2018 ourairquality (https://github.com/ourairquality) + * Copyright (C) 2018 Zaltora (https://github.com/Zaltora) + * BSD Licensed as described in the file LICENSE + */ +#include "dsm.h" + +#include +#include + + +#if (DSM_DEBUG) +#define debug(fmt, ...) printf("%s: " fmt "\n", "DSM", ## __VA_ARGS__) +#else +#define debug(fmt, ...) +#endif + +typedef struct dsmInfoDefinition +{ + uint8_t running; + uint8_t preScale; + uint8_t target; + bool output; + + /* private */ + uint8_t usedPins; + uint8_t pins[8]; +} DSMInfo; + +static DSMInfo dsmInfo; + +void dsm_init(uint8_t npins, const uint8_t* pins) +{ + /* Assert number of pins is correct */ + if (npins > MAX_DSM_PINS) + { + debug("Incorrect number of DSM pins (%d)\n", npins); + return; + } + + /* Save pins information */ + dsmInfo.usedPins = npins; + + for (uint8_t i = 0 ; i < npins; ++i) + { + dsmInfo.pins[i] = pins[i]; + /* configure GPIOs */ + gpio_enable(pins[i], GPIO_OUTPUT); + } + + /* Set output to LOW */ + dsm_stop(); + + /* Flag not running */ + dsmInfo.running = 0; +} + +void dsm_set_prescale(uint8_t prescale) +{ + //TODO: Add a freq/prescale converter + dsmInfo.preScale = prescale; + debug("Set Prescale: %u",dsmInfo.preScale); +} + +void dsm_set_target(uint8_t target) +{ + dsmInfo.target = target; + if (target == 0 || target == UINT8_MAX) + { + dsmInfo.output = (target == UINT8_MAX); + } + debug("Duty set at %u",dsmInfo.target); + if (dsmInfo.running) + { + dsm_start(); + } +} + +void dsm_start() +{ + if (dsmInfo.target > 0 && dsmInfo.target < UINT8_MAX) + { + for (uint8_t i = 0; i < dsmInfo.usedPins; ++i) + { + SET_MASK_BITS(GPIO.CONF[dsmInfo.pins[i]], GPIO_CONF_SOURCE_DSM); + } + GPIO.DSM = GPIO_DSM_ENABLE | (dsmInfo.preScale << 8) | dsmInfo.target; + } + else + { + for (uint8_t i = 0; i < dsmInfo.usedPins; ++i) + { + gpio_write(dsmInfo.pins[i], dsmInfo.output ); + } + } + debug("start"); + dsmInfo.running = 1; +} + +void dsm_stop() +{ + for (uint8_t i = 0; i < dsmInfo.usedPins; ++i) + { + CLEAR_MASK_BITS(GPIO.CONF[dsmInfo.pins[i]], GPIO_CONF_SOURCE_DSM); + gpio_write(dsmInfo.pins[i], false); + } + debug("stop"); + dsmInfo.running = 0; +} diff --git a/extras/dsm/dsm.h b/extras/dsm/dsm.h new file mode 100644 index 0000000..8190f7e --- /dev/null +++ b/extras/dsm/dsm.h @@ -0,0 +1,36 @@ +/* Implementation of Delta-Sigma modulator support. + * + * Part of esp-open-rtos + * Copyright (C) 2018 ourairquality (https://github.com/ourairquality) + * Copyright (C) 2018 Zaltora (https://github.com/Zaltora) + * BSD Licensed as described in the file LICENSE + */ +#ifndef EXTRAS_DSM_H_ +#define EXTRAS_DSM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define MAX_DSM_PINS (8) +#define DSM_DEBUG (0) + +/* + * Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128) + * Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256) + */ + +void dsm_init(uint8_t npins, const uint8_t* pins); +void dsm_set_prescale(uint8_t prescale); +void dsm_set_target(uint8_t target); + +void dsm_start(); +void dsm_stop(); + +#ifdef __cplusplus +} +#endif + +#endif /* EXTRAS_DSM_H_ */