mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 15:27:17 +00:00
Add support for transistor-based output without DAC
Add support for transistor-based output without DAC (#10875)
This commit is contained in:
parent
5663ce7788
commit
a91beeb0cf
@ -79,8 +79,8 @@
|
|||||||
#define FALLBACK_MODULE M5STACK_CORE2 // [Module2] Select default module on fast reboot where USER_MODULE is user template
|
#define FALLBACK_MODULE M5STACK_CORE2 // [Module2] Select default module on fast reboot where USER_MODULE is user template
|
||||||
|
|
||||||
#define USE_M5STACK_CORE2 // Add support for M5Stack Core2
|
#define USE_M5STACK_CORE2 // Add support for M5Stack Core2
|
||||||
#define SAY_TIME
|
#define USE_I2S_SAY_TIME
|
||||||
#define USE_WEBRADIO
|
#define USE_I2S_WEBRADIO
|
||||||
#define USE_MPU6886
|
#define USE_MPU6886
|
||||||
#define USE_UFILESYS
|
#define USE_UFILESYS
|
||||||
#define USE_SDCARD
|
#define USE_SDCARD
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
xdrv_42_i2s_audio.ino - audio dac support for Tasmota
|
xdrv_42_i2s_audio.ino - Audio dac support for Tasmota
|
||||||
|
|
||||||
Copyright (C) 2021 Gerhard Mutz and Theo Arends
|
Copyright (C) 2021 Gerhard Mutz and Theo Arends
|
||||||
|
|
||||||
@ -17,16 +17,39 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH) || defined(USE_M5STACK_CORE2))
|
#if (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH) || defined(USE_M5STACK_CORE2))
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* I2S support using an external DAC or a speaker connected to GPIO03 using a transistor
|
||||||
|
*
|
||||||
|
* Uses fixed GPIOs for ESP8266:
|
||||||
|
* I2S Out Data GPIO03 (Rx)
|
||||||
|
* I2S Out Bit Clock GPIO15
|
||||||
|
* I2S Out Word Select GPIO02
|
||||||
|
* I2S In Data GPIO12
|
||||||
|
* I2S In Bit Clock GPIO13
|
||||||
|
* I2S In Word Select GPIO14
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#define XDRV_42 42
|
||||||
|
|
||||||
|
#define USE_I2S_EXTERNAL_DAC 1
|
||||||
|
//#define USE_I2S_NO_DAC // Add support for transistor-based output without DAC
|
||||||
|
//#define USE_I2S_WEBRADIO // Add support for web radio
|
||||||
|
//#define USE_I2S_SAY_TIME // Add support for english speaking clock
|
||||||
|
|
||||||
#include "AudioFileSourcePROGMEM.h"
|
#include "AudioFileSourcePROGMEM.h"
|
||||||
#include "AudioFileSourceID3.h"
|
#include "AudioFileSourceID3.h"
|
||||||
#include "AudioGeneratorMP3.h"
|
#include "AudioGeneratorMP3.h"
|
||||||
#include "AudioOutputI2S.h"
|
#ifdef USE_I2S_NO_DAC
|
||||||
|
#include "AudioOutputI2SNoDAC.h" // Transistor-driven lower quality connected to RX pin
|
||||||
|
#else
|
||||||
|
#include "AudioOutputI2S.h" // External I2S DAC IC
|
||||||
|
#endif // USE_I2S_NO_DAC
|
||||||
#include <ESP8266SAM.h>
|
#include <ESP8266SAM.h>
|
||||||
#include "AudioFileSourceFS.h"
|
#include "AudioFileSourceFS.h"
|
||||||
#ifdef SAY_TIME
|
#ifdef USE_I2S_SAY_TIME
|
||||||
#include "AudioGeneratorTalkie.h"
|
#include "AudioGeneratorTalkie.h"
|
||||||
#endif
|
#endif // USE_I2S_SAY_TIME
|
||||||
#include "AudioFileSourceICYStream.h"
|
#include "AudioFileSourceICYStream.h"
|
||||||
#include "AudioFileSourceBuffer.h"
|
#include "AudioFileSourceBuffer.h"
|
||||||
#include "AudioGeneratorAAC.h"
|
#include "AudioGeneratorAAC.h"
|
||||||
@ -41,7 +64,7 @@
|
|||||||
#undef AUDIO_PWR_OFF
|
#undef AUDIO_PWR_OFF
|
||||||
#define AUDIO_PWR_ON TTGO_audio_power(true);
|
#define AUDIO_PWR_ON TTGO_audio_power(true);
|
||||||
#define AUDIO_PWR_OFF TTGO_audio_power(false);
|
#define AUDIO_PWR_OFF TTGO_audio_power(false);
|
||||||
#endif // USE_TTGO_WATCH
|
#endif // USE_TTGO_WATCH
|
||||||
|
|
||||||
#ifdef USE_M5STACK_CORE2
|
#ifdef USE_M5STACK_CORE2
|
||||||
#undef AUDIO_PWR_ON
|
#undef AUDIO_PWR_ON
|
||||||
@ -54,21 +77,19 @@
|
|||||||
#define DAC_IIS_BCK 12
|
#define DAC_IIS_BCK 12
|
||||||
#define DAC_IIS_WS 0
|
#define DAC_IIS_WS 0
|
||||||
#define DAC_IIS_DOUT 2
|
#define DAC_IIS_DOUT 2
|
||||||
#endif // USE_M5STACK_CORE2
|
#endif // USE_M5STACK_CORE2
|
||||||
|
|
||||||
|
|
||||||
#define EXTERNAL_DAC_PLAY 1
|
|
||||||
|
|
||||||
#define XDRV_42 42
|
|
||||||
|
|
||||||
AudioGeneratorMP3 *mp3 = nullptr;
|
AudioGeneratorMP3 *mp3 = nullptr;
|
||||||
AudioFileSourceFS *file;
|
AudioFileSourceFS *file;
|
||||||
AudioOutputI2S *out;
|
#ifdef USE_I2S_NO_DAC
|
||||||
|
AudioOutputI2SNoDAC *out;
|
||||||
|
#else
|
||||||
|
AudioOutputI2S *out;
|
||||||
|
#endif // USE_I2S_NO_DAC
|
||||||
AudioFileSourceID3 *id3;
|
AudioFileSourceID3 *id3;
|
||||||
AudioGeneratorMP3 *decoder = NULL;
|
AudioGeneratorMP3 *decoder = NULL;
|
||||||
void *mp3ram = NULL;
|
void *mp3ram = NULL;
|
||||||
|
|
||||||
|
|
||||||
extern FS *ufsp;
|
extern FS *ufsp;
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -81,7 +102,7 @@ const int preallocateCodecSize = 29192; // MP3 codec max mem needed
|
|||||||
//const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed
|
//const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
||||||
#ifdef USE_WEBRADIO
|
#ifdef USE_I2S_WEBRADIO
|
||||||
AudioFileSourceICYStream *ifile = NULL;
|
AudioFileSourceICYStream *ifile = NULL;
|
||||||
AudioFileSourceBuffer *buff = NULL;
|
AudioFileSourceBuffer *buff = NULL;
|
||||||
char wr_title[64];
|
char wr_title[64];
|
||||||
@ -90,11 +111,11 @@ char wr_title[64];
|
|||||||
void *preallocateBuffer = NULL;
|
void *preallocateBuffer = NULL;
|
||||||
void *preallocateCodec = NULL;
|
void *preallocateCodec = NULL;
|
||||||
uint32_t retryms = 0;
|
uint32_t retryms = 0;
|
||||||
#endif // USE_WEBRADIO
|
#endif // USE_I2S_WEBRADIO
|
||||||
|
|
||||||
#ifdef SAY_TIME
|
#ifdef USE_I2S_SAY_TIME
|
||||||
AudioGeneratorTalkie *talkie = nullptr;
|
AudioGeneratorTalkie *talkie = nullptr;
|
||||||
#endif // SAY_TIME
|
#endif // USE_I2S_SAY_TIME
|
||||||
|
|
||||||
//! MAX98357A + INMP441 DOUBLE I2S BOARD
|
//! MAX98357A + INMP441 DOUBLE I2S BOARD
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -111,26 +132,26 @@ AudioGeneratorTalkie *talkie = nullptr;
|
|||||||
#ifndef DAC_IIS_BCK
|
#ifndef DAC_IIS_BCK
|
||||||
#undef DAC_IIS_BCK
|
#undef DAC_IIS_BCK
|
||||||
#define DAC_IIS_BCK 26
|
#define DAC_IIS_BCK 26
|
||||||
#endif // DAC_IIS_BCK
|
#endif // DAC_IIS_BCK
|
||||||
|
|
||||||
#ifndef DAC_IIS_WS
|
#ifndef DAC_IIS_WS
|
||||||
#undef DAC_IIS_WS
|
#undef DAC_IIS_WS
|
||||||
#define DAC_IIS_WS 25
|
#define DAC_IIS_WS 25
|
||||||
#endif // DAC_IIS_WS
|
#endif // DAC_IIS_WS
|
||||||
|
|
||||||
#ifndef DAC_IIS_DOUT
|
#ifndef DAC_IIS_DOUT
|
||||||
#undef DAC_IIS_DOUT
|
#undef DAC_IIS_DOUT
|
||||||
#define DAC_IIS_DOUT 33
|
#define DAC_IIS_DOUT 33
|
||||||
#endif // DAC_IIS_DOUT
|
#endif // DAC_IIS_DOUT
|
||||||
|
|
||||||
#ifndef DAC_IIS_DIN
|
#ifndef DAC_IIS_DIN
|
||||||
#undef DAC_IIS_DIN
|
#undef DAC_IIS_DIN
|
||||||
#define DAC_IIS_DIN 34
|
#define DAC_IIS_DIN 34
|
||||||
#endif // DAC_IIS_DIN
|
#endif // DAC_IIS_DIN
|
||||||
|
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
||||||
#ifdef SAY_TIME
|
#ifdef USE_I2S_SAY_TIME
|
||||||
long timezone = 2;
|
long timezone = 2;
|
||||||
byte daysavetime = 1;
|
byte daysavetime = 1;
|
||||||
|
|
||||||
@ -229,21 +250,29 @@ void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) {
|
|||||||
out->stop();
|
out->stop();
|
||||||
AUDIO_PWR_OFF
|
AUDIO_PWR_OFF
|
||||||
}
|
}
|
||||||
#endif // SAY_TIME
|
#endif // USE_I2S_SAY_TIME
|
||||||
|
|
||||||
// should be in settings
|
// should be in settings
|
||||||
uint8_t is2_volume;
|
uint8_t is2_volume;
|
||||||
|
|
||||||
void I2S_Init(void) {
|
void I2S_Init(void) {
|
||||||
|
|
||||||
#if EXTERNAL_DAC_PLAY
|
#if USE_I2S_EXTERNAL_DAC
|
||||||
out = new AudioOutputI2S();
|
#ifdef USE_I2S_NO_DAC
|
||||||
|
out = new AudioOutputI2SNoDAC();
|
||||||
|
#else
|
||||||
|
out = new AudioOutputI2S();
|
||||||
|
#endif // USE_I2S_NO_DAC
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT);
|
out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT);
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
#else
|
#else
|
||||||
out = new AudioOutputI2S(0, 1);
|
#ifdef USE_I2S_NO_DAC
|
||||||
#endif // EXTERNAL_DAC_PLAY
|
out = new AudioOutputI2SNoDAC();
|
||||||
|
#else
|
||||||
|
out = new AudioOutputI2S(0, 1); // Internal DAC port 0
|
||||||
|
#endif // USE_I2S_NO_DAC
|
||||||
|
#endif // USE_I2S_EXTERNAL_DAC
|
||||||
|
|
||||||
is2_volume=10;
|
is2_volume=10;
|
||||||
out->SetGain(((float)is2_volume/100.0)*4.0);
|
out->SetGain(((float)is2_volume/100.0)*4.0);
|
||||||
@ -255,7 +284,7 @@ void I2S_Init(void) {
|
|||||||
mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WEBRADIO
|
#ifdef USE_I2S_WEBRADIO
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
preallocateBuffer = heap_caps_malloc(preallocateBufferSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
preallocateBuffer = heap_caps_malloc(preallocateBufferSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
preallocateCodec = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
preallocateCodec = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
@ -266,12 +295,11 @@ void I2S_Init(void) {
|
|||||||
if (!preallocateBuffer || !preallocateCodec) {
|
if (!preallocateBuffer || !preallocateCodec) {
|
||||||
//Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize);
|
//Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize);
|
||||||
}
|
}
|
||||||
#endif // USE_WEBRADIO
|
#endif // USE_I2S_WEBRADIO
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
#define MODE_MIC 0
|
#define MODE_MIC 0
|
||||||
#define MODE_SPK 1
|
#define MODE_SPK 1
|
||||||
@ -426,7 +454,7 @@ bool SaveWav(char *path, uint8_t *buff, uint32_t size) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
TaskHandle_t mp3_task_h;
|
TaskHandle_t mp3_task_h;
|
||||||
@ -447,9 +475,9 @@ void mp3_task(void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
||||||
#ifdef USE_WEBRADIO
|
#ifdef USE_I2S_WEBRADIO
|
||||||
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *str) {
|
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *str) {
|
||||||
const char *ptr = reinterpret_cast<const char *>(cbData);
|
const char *ptr = reinterpret_cast<const char *>(cbData);
|
||||||
(void) isUnicode; // Punt this ball for now
|
(void) isUnicode; // Punt this ball for now
|
||||||
@ -557,7 +585,7 @@ void Cmd_MicRec(void) {
|
|||||||
ResponseCmndChar(XdrvMailbox.data);
|
ResponseCmndChar(XdrvMailbox.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_M5STACK_CORE2
|
#endif // USE_M5STACK_CORE2
|
||||||
|
|
||||||
const char HTTP_WEBRADIO[] PROGMEM =
|
const char HTTP_WEBRADIO[] PROGMEM =
|
||||||
"{s}" "I2S_WR-Title" "{m}%s{e}";
|
"{s}" "I2S_WR-Title" "{m}%s{e}";
|
||||||
@ -568,7 +596,7 @@ void I2S_WR_Show(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // USE_I2S_WEBRADIO
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
void Play_mp3(const char *path) {
|
void Play_mp3(const char *path) {
|
||||||
@ -610,7 +638,7 @@ void Play_mp3(const char *path) {
|
|||||||
mp3_delete();
|
mp3_delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_SCRIPT
|
#endif // USE_SCRIPT
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp3_delete(void) {
|
void mp3_delete(void) {
|
||||||
@ -620,7 +648,7 @@ void mp3_delete(void) {
|
|||||||
mp3=nullptr;
|
mp3=nullptr;
|
||||||
AUDIO_PWR_OFF
|
AUDIO_PWR_OFF
|
||||||
}
|
}
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
||||||
void Say(char *text) {
|
void Say(char *text) {
|
||||||
|
|
||||||
@ -642,22 +670,22 @@ const char kI2SAudio_Commands[] PROGMEM = "I2S|"
|
|||||||
"Say|Gain|Time"
|
"Say|Gain|Time"
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
"|Play"
|
"|Play"
|
||||||
#ifdef USE_WEBRADIO
|
#ifdef USE_I2S_WEBRADIO
|
||||||
"|WR"
|
"|WR"
|
||||||
#endif // USE_WEBRADIO
|
#endif // USE_I2S_WEBRADIO
|
||||||
#ifdef USE_M5STACK_CORE2
|
#ifdef USE_M5STACK_CORE2
|
||||||
"|REC"
|
"|REC"
|
||||||
#endif // USE_M5STACK_CORE2
|
#endif // USE_M5STACK_CORE2
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
;
|
;
|
||||||
|
|
||||||
void (* const I2SAudio_Command[])(void) PROGMEM = {
|
void (* const I2SAudio_Command[])(void) PROGMEM = {
|
||||||
&Cmd_Say, &Cmd_Gain, &Cmd_Time
|
&Cmd_Say, &Cmd_Gain, &Cmd_Time
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
,&Cmd_Play
|
,&Cmd_Play
|
||||||
#ifdef USE_WEBRADIO
|
#ifdef USE_I2S_WEBRADIO
|
||||||
,&Cmd_WebRadio
|
,&Cmd_WebRadio
|
||||||
#endif // USE_WEBRADIO
|
#endif // USE_I2S_WEBRADIO
|
||||||
#ifdef USE_M5STACK_CORE2
|
#ifdef USE_M5STACK_CORE2
|
||||||
,&Cmd_MicRec
|
,&Cmd_MicRec
|
||||||
#endif // USE_M5STACK_CORE2
|
#endif // USE_M5STACK_CORE2
|
||||||
@ -691,9 +719,9 @@ void Cmd_Say(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Cmd_Time(void) {
|
void Cmd_Time(void) {
|
||||||
#ifdef SAY_TIME
|
#ifdef USE_I2S_SAY_TIME
|
||||||
sayTime(RtcTime.hour, RtcTime.minute, talkie);
|
sayTime(RtcTime.hour, RtcTime.minute, talkie);
|
||||||
#endif // SAY_TIME
|
#endif // USE_I2S_SAY_TIME
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,12 +740,12 @@ bool Xdrv42(uint8_t function) {
|
|||||||
I2S_Init();
|
I2S_Init();
|
||||||
break;
|
break;
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
#ifdef USE_WEBRADIO
|
#ifdef USE_I2S_WEBRADIO
|
||||||
case FUNC_WEB_SENSOR:
|
case FUNC_WEB_SENSOR:
|
||||||
I2S_WR_Show();
|
I2S_WR_Show();
|
||||||
break;
|
break;
|
||||||
#endif // USE_WEBRADIO
|
#endif // USE_I2S_WEBRADIO
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user