mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 21:01:25 +01:00
Merge pull request #396 from DCC-EX/temp-Ash-0204
Recent updates from devel I2CDFPlayer and WifiESP32
This commit is contained in:
commit
72a3fc77d3
19
EXRAIL2.h
19
EXRAIL2.h
@ -258,4 +258,23 @@ private:
|
||||
#define GET_OPCODE GETHIGHFLASH(RMFT2::RouteCode,progCounter)
|
||||
#define SKIPOP progCounter+=3
|
||||
|
||||
// IO_I2CDFPlayer commands and values
|
||||
enum : uint8_t{
|
||||
DF_PLAY = 0x0F,
|
||||
DF_VOL = 0x06,
|
||||
DF_FOLDER = 0x2B, // Not a DFPlayer command, used to set folder nr where audio file is
|
||||
DF_REPEATPLAY = 0x08,
|
||||
DF_STOPPLAY = 0x16,
|
||||
DF_EQ = 0x07, // Set equaliser, require parameter NORMAL, POP, ROCK, JAZZ, CLASSIC or BASS
|
||||
DF_RESET = 0x0C,
|
||||
DF_DACON = 0x1A,
|
||||
DF_SETAM = 0x2A, // Set audio mixer 1 or 2 for this DFPLayer
|
||||
DF_NORMAL = 0x00, // Equalizer parameters
|
||||
DF_POP = 0x01,
|
||||
DF_ROCK = 0x02,
|
||||
DF_JAZZ = 0x03,
|
||||
DF_CLASSIC = 0x04,
|
||||
DF_BASS = 0x05,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -59,6 +59,10 @@
|
||||
// helper macro for turnout description as HIDDEN
|
||||
#define HIDDEN "\x01"
|
||||
|
||||
// PLAYSOUND is alias of ANOUT to make the user experience of a Conductor beter for
|
||||
// playing sounds with IO_I2CDFPlayer
|
||||
#define PLAYSOUND ANOUT
|
||||
|
||||
// helper macro to strip leading zeros off time inputs
|
||||
// (10#mins)%100)
|
||||
#define STRIP_ZERO(value) 10##value%100
|
||||
|
@ -1 +1 @@
|
||||
#define GITHUB_SHA "devel-stm32EC 202402041220Z"
|
||||
#define GITHUB_SHA "devel-stm32EC 202402041604Z"
|
||||
|
@ -54,8 +54,8 @@ static const FSH * guessI2CDeviceType(uint8_t address) {
|
||||
return F("Time-of-flight sensor");
|
||||
else if (address >= 0x3c && address <= 0x3d)
|
||||
return F("OLED Display");
|
||||
else if (address >= 0x48 && address <= 0x57) // Henkk: Added SC16IS752 UART detection
|
||||
return F("SC16IS752 UART");
|
||||
else if (address >= 0x48 && address <= 0x57) // SC16IS752x UART detection
|
||||
return F("SC16IS75x UART");
|
||||
else if (address >= 0x48 && address <= 0x4f)
|
||||
return F("Analogue Inputs or PWM");
|
||||
else if (address >= 0x40 && address <= 0x4f)
|
||||
|
103
IO_I2CDFPlayer.h
103
IO_I2CDFPlayer.h
@ -23,23 +23,28 @@
|
||||
* This driver is a modified version of the IO_DFPlayer.h file
|
||||
* *********************************************************************************************
|
||||
*
|
||||
* 2023, Added NXP SC16IS752 I2C Dual UART to enable the DFPlayer connection over the I2C bus
|
||||
* Dec 2023, Added NXP SC16IS752 I2C Dual UART to enable the DFPlayer connection over the I2C bus
|
||||
* The SC16IS752 has 64 bytes TX & RX FIFO buffer
|
||||
* First version without interrupts from I2C UART and only RX/TX are used, interrupts may not be
|
||||
* needed as the RX Fifo holds the reply
|
||||
*
|
||||
* Jan 2024, Issue with using both UARTs simultaniously, the secod uart seems to work but the first transmit
|
||||
* corrupt data. This need more analysis and experimenatation.
|
||||
* Will push this driver to the dev branch with the uart fixed to 0
|
||||
* Both SC16IS750 (single uart) and SC16IS752 (dual uart, but only uart 0 is enable)
|
||||
*
|
||||
* myHall.cpp configuration syntax:
|
||||
*
|
||||
* I2CDFPlayer::create(1st vPin, vPins, I2C address, UART ch, AM);
|
||||
* I2CDFPlayer::create(1st vPin, vPins, I2C address, xtal);
|
||||
*
|
||||
* Parameters:
|
||||
* 1st vPin : First virtual pin that EX-Rail can control to play a sound, use PLAYSOUND command (alias of ANOUT)
|
||||
* vPins : Total number of virtual pins allocated (only 1 vPin is supported)
|
||||
* I2C Address : I2C address of the serial controller, in 0x format,
|
||||
* UART ch : Indicating UART 0 or UART 1, values 0 or 1
|
||||
* AM : audio mixer, values: 1 or 2 to select an audio amplifier, no effect if AM is not installed
|
||||
* vPins : Total number of virtual pins allocated (2 vPins are supported, one for each UART)
|
||||
* 1st vPin for UART 0, 2nd for UART 1
|
||||
* I2C Address : I2C address of the serial controller, in 0x format
|
||||
* xtal : 0 for 1,8432Mhz, 1 for 14,7456Mhz
|
||||
*
|
||||
* The vPin is also an pin that can be read, it indicated if the DFPlayer has finished playing a track
|
||||
* The vPin is also a pin that can be read, it indicate if the DFPlayer has finished playing a track
|
||||
*
|
||||
*/
|
||||
|
||||
@ -75,7 +80,7 @@ private:
|
||||
// SC16IS752 defines
|
||||
I2CAddress _I2CAddress;
|
||||
I2CRB _rb;
|
||||
uint8_t _UART_CH;
|
||||
uint8_t _UART_CH=0x00; // Fix uart ch to 0 for now
|
||||
// Communication parameters for the DFPlayer are fixed at 8 bit, No parity, 1 stopbit
|
||||
uint8_t WORD_LEN = 0x03; // Value LCR bit 0,1
|
||||
uint8_t STOP_BIT = 0x00; // Value LCR bit 2
|
||||
@ -96,33 +101,36 @@ private:
|
||||
bool _stopplayCmd = false;
|
||||
bool _resetCmd = false;
|
||||
bool _eqCmd = false;
|
||||
uint8_t _requestedEQValue = NORMAL;
|
||||
uint8_t _currentEQvalue = NORMAL; // start equalizer value
|
||||
uint8_t _requestedEQValue = DF_NORMAL;
|
||||
uint8_t _currentEQvalue = DF_NORMAL; // start equalizer value
|
||||
bool _daconCmd = false;
|
||||
uint8_t _audioMixer = 0x01; // Default to output amplifier 1
|
||||
bool _setamCmd = false; // Set the Audio mixer channel
|
||||
uint8_t _outbuffer [11]; // DFPlayer command is 10 bytes + 1 byte register address & UART channel
|
||||
uint8_t _inbuffer[10]; // expected DFPlayer return 10 bytes
|
||||
|
||||
//unsigned long SC16IS752_XTAL_FREQ = 1843200; // To support cheap eBay/AliExpress SC16IS752 boards
|
||||
unsigned long SC16IS752_XTAL_FREQ = 14745600; // Support for higher baud rates, standard for modular EX-IO system
|
||||
|
||||
|
||||
unsigned long _sc16is752_xtal_freq;
|
||||
unsigned long SC16IS752_XTAL_FREQ_LOW = 1843200; // To support cheap eBay/AliExpress SC16IS752 boards
|
||||
unsigned long SC16IS752_XTAL_FREQ_HIGH = 14745600; // Support for higher baud rates, standard for modular EX-IO system
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
I2CDFPlayer(VPIN firstVpin, int nPins, I2CAddress i2cAddress, uint8_t UART_CH, uint8_t AM){
|
||||
I2CDFPlayer(VPIN firstVpin, int nPins, I2CAddress i2cAddress, uint8_t xtal){
|
||||
_firstVpin = firstVpin;
|
||||
_nPins = nPins;
|
||||
_I2CAddress = i2cAddress;
|
||||
_UART_CH = UART_CH;
|
||||
_audioMixer = AM;
|
||||
if (xtal == 0){
|
||||
_sc16is752_xtal_freq = SC16IS752_XTAL_FREQ_LOW;
|
||||
} else { // should be 1
|
||||
_sc16is752_xtal_freq = SC16IS752_XTAL_FREQ_HIGH;
|
||||
}
|
||||
addDevice(this);
|
||||
}
|
||||
|
||||
public:
|
||||
static void create(VPIN firstVpin, int nPins, I2CAddress i2cAddress, uint8_t UART_CH, uint8_t AM) {
|
||||
if (checkNoOverlap(firstVpin, nPins, i2cAddress)) new I2CDFPlayer(firstVpin, nPins, i2cAddress, UART_CH, AM);
|
||||
}
|
||||
static void create(VPIN firstVpin, int nPins, I2CAddress i2cAddress, uint8_t xtal) {
|
||||
if (checkNoOverlap(firstVpin, nPins, i2cAddress)) new I2CDFPlayer(firstVpin, nPins, i2cAddress, xtal);
|
||||
}
|
||||
|
||||
void _begin() override {
|
||||
// check if SC16IS752 exist first, initialize and then resume DFPlayer init via SC16IS752
|
||||
@ -426,18 +434,18 @@ public:
|
||||
//case NONE:
|
||||
// DFPlayerCmd = cmd;
|
||||
// break;
|
||||
case PLAY:
|
||||
case DF_PLAY:
|
||||
_playCmd = true;
|
||||
_volCmd = true;
|
||||
_requestedSong = value;
|
||||
_requestedVolumeLevel = volume;
|
||||
_playing = true;
|
||||
break;
|
||||
case VOL:
|
||||
case DF_VOL:
|
||||
_volCmd = true;
|
||||
_requestedVolumeLevel = volume;
|
||||
break;
|
||||
case FOLDER:
|
||||
case DF_FOLDER:
|
||||
_folderCmd = true;
|
||||
if (volume <= 0 || volume > 99){ // Range checking, valid values 1-99, else default to 1
|
||||
_requestedFolder = 0x01; // if outside range, default to folder 01
|
||||
@ -445,7 +453,7 @@ public:
|
||||
_requestedFolder = volume;
|
||||
}
|
||||
break;
|
||||
case REPEATPLAY: // Need to check if _repeat == true, if so do nothing
|
||||
case DF_REPEATPLAY: // Need to check if _repeat == true, if so do nothing
|
||||
if (_repeat == false) {
|
||||
#ifdef DIAG_I2CDFplayer_playing
|
||||
DIAG(F("I2CDFPlayer: WriteAnalog Repeat: _repeat: 0x0%x, value: %d _repeatCmd: 0x%x"), _repeat, value, _repeatCmd);
|
||||
@ -456,30 +464,30 @@ public:
|
||||
_playing = true;
|
||||
}
|
||||
break;
|
||||
case STOPPLAY:
|
||||
case DF_STOPPLAY:
|
||||
_stopplayCmd = true;
|
||||
break;
|
||||
case EQ:
|
||||
case DF_EQ:
|
||||
#ifdef DIAG_I2CDFplayer_playing
|
||||
DIAG(F("I2CDFPlayer: WriteAnalog EQ: cmd: 0x%x, EQ value: 0x%x"), cmd, volume);
|
||||
#endif
|
||||
_eqCmd = true;
|
||||
if (volume <= 0 || volume > 5) { // If out of range, default to NORMAL
|
||||
_requestedEQValue = NORMAL;
|
||||
_requestedEQValue = DF_NORMAL;
|
||||
} else { // Valid EQ parameter range
|
||||
_requestedEQValue = volume;
|
||||
}
|
||||
break;
|
||||
case RESET:
|
||||
case DF_RESET:
|
||||
_resetCmd = true;
|
||||
break;
|
||||
case DACON: // Works, but without the DACOFF command limited value, except when not relying on DFPlayer default to turn the DAC on
|
||||
case DF_DACON: // Works, but without the DACOFF command limited value, except when not relying on DFPlayer default to turn the DAC on
|
||||
#ifdef DIAG_I2CDFplayer_playing
|
||||
DIAG(F("I2CDFPlayer: WrtieAnalog DACON: cmd: 0x%x"), cmd);
|
||||
#endif
|
||||
_daconCmd = true;
|
||||
break;
|
||||
case SETAM: // Set the audio mixer channel to 1 or 2
|
||||
case DF_SETAM: // Set the audio mixer channel to 1 or 2
|
||||
_setamCmd = true;
|
||||
#ifdef DIAG_I2CDFplayer_playing
|
||||
DIAG(F("I2CDFPlayer: WrtieAnalog SETAM: cmd: 0x%x"), cmd);
|
||||
@ -604,7 +612,8 @@ private:
|
||||
#ifdef DIAG_I2CDFplayer
|
||||
DIAG(F("SC16IS752: Initialize I2C: %s , UART Ch: 0x%x"), _I2CAddress.toString(), _UART_CH);
|
||||
#endif
|
||||
uint16_t _divisor = (SC16IS752_XTAL_FREQ / PRESCALER) / (BAUD_RATE * 16);
|
||||
//uint16_t _divisor = (SC16IS752_XTAL_FREQ / PRESCALER) / (BAUD_RATE * 16);
|
||||
uint16_t _divisor = (_sc16is752_xtal_freq/PRESCALER)/(BAUD_RATE * 16); // Calculate _divisor for baudrate
|
||||
TEMP_REG_VAL = 0x08; // UART Software reset
|
||||
UART_WriteRegister(REG_IOCONTROL, TEMP_REG_VAL);
|
||||
TEMP_REG_VAL = 0x00; // Set pins to GPIO mode
|
||||
@ -770,23 +779,25 @@ enum : uint8_t{
|
||||
REG_XOFF2 = 0x07, // R/W
|
||||
};
|
||||
|
||||
|
||||
// DFPlayer commands and values
|
||||
// Declared in this scope
|
||||
enum : uint8_t{
|
||||
PLAY = 0x0F,
|
||||
VOL = 0x06,
|
||||
FOLDER = 0x2B, // Not a DFPlayer command, used to set folder nr where audio file is
|
||||
REPEATPLAY = 0x08,
|
||||
STOPPLAY = 0x16,
|
||||
EQ = 0x07, // Set equaliser, require parameter NORMAL, POP, ROCK, JAZZ, CLASSIC or BASS
|
||||
RESET = 0x0C,
|
||||
DACON = 0x1A,
|
||||
SETAM = 0x2A, // Set audio mixer 1 or 2 for this DFPLayer
|
||||
NORMAL = 0x00, // Equalizer parameters
|
||||
POP = 0x01,
|
||||
ROCK = 0x02,
|
||||
JAZZ = 0x03,
|
||||
CLASSIC = 0x04,
|
||||
BASS = 0x05,
|
||||
DF_PLAY = 0x0F,
|
||||
DF_VOL = 0x06,
|
||||
DF_FOLDER = 0x2B, // Not a DFPlayer command, used to set folder nr where audio file is
|
||||
DF_REPEATPLAY = 0x08,
|
||||
DF_STOPPLAY = 0x16,
|
||||
DF_EQ = 0x07, // Set equaliser, require parameter NORMAL, POP, ROCK, JAZZ, CLASSIC or BASS
|
||||
DF_RESET = 0x0C,
|
||||
DF_DACON = 0x1A,
|
||||
DF_SETAM = 0x2A, // Set audio mixer 1 or 2 for this DFPLayer
|
||||
DF_NORMAL = 0x00, // Equalizer parameters
|
||||
DF_POP = 0x01,
|
||||
DF_ROCK = 0x02,
|
||||
DF_JAZZ = 0x03,
|
||||
DF_CLASSIC = 0x04,
|
||||
DF_BASS = 0x05,
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -164,6 +164,8 @@ bool WifiESP::setup(const char *SSid,
|
||||
if (haveSSID && havePassword && !forceAP) {
|
||||
WiFi.setHostname(hostname); // Strangely does not work unless we do it HERE!
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); // Scan all channels so we find strongest
|
||||
// (default in Wifi library is first match)
|
||||
#ifdef SERIAL_BT_COMMANDS
|
||||
WiFi.setSleep(true);
|
||||
#else
|
||||
@ -204,7 +206,7 @@ bool WifiESP::setup(const char *SSid,
|
||||
if (!haveSSID || forceAP) {
|
||||
// prepare all strings
|
||||
String strSSID(forceAP ? SSid : "DCCEX_");
|
||||
String strPass(forceAP ? password : "PASS_");
|
||||
String strPass( (forceAP && havePassword) ? password : "PASS_");
|
||||
if (!forceAP) {
|
||||
String strMac = WiFi.macAddress();
|
||||
strMac.remove(0,9);
|
||||
@ -228,7 +230,8 @@ bool WifiESP::setup(const char *SSid,
|
||||
// DIAG(F("Wifi AP SSID %s PASS %s"),strSSID.c_str(),havePassword ? password : strPass.c_str());
|
||||
DIAG(F("Wifi in AP mode"));
|
||||
LCD(5, F("Wifi: %s"), strSSID.c_str());
|
||||
LCD(6, F("PASS: %s"),havePassword ? password : strPass.c_str());
|
||||
if (!havePassword)
|
||||
LCD(6, F("PASS: %s"),strPass.c_str());
|
||||
// DIAG(F("Wifi AP IP %s"),WiFi.softAPIP().toString().c_str());
|
||||
LCD(7, F("IP: %s"),WiFi.softAPIP().toString().c_str());
|
||||
wifiUp = true;
|
||||
|
@ -25,6 +25,7 @@
|
||||
//#include "IO_EXTurntable.h" // Turntable-EX turntable controller
|
||||
//#include "IO_EXFastClock.h" // FastClock driver
|
||||
//#include "IO_PCA9555.h" // 16-bit I/O expander (NXP & Texas Instruments).
|
||||
//#include "IO_I2CDFPlayer.h" // DFPlayer over I2C
|
||||
//#include "IO_CMRI.h" // CMRI nodes
|
||||
|
||||
//==========================================================================
|
||||
@ -275,19 +276,27 @@ void halSetup() {
|
||||
|
||||
|
||||
//=======================================================================
|
||||
// Play mp3 files from a Micro-SD card, using a DFPlayer MP3 Module on a SC16IS752 I2C Dual UART
|
||||
// Play mp3 files from a Micro-SD card, using a DFPlayer MP3 Module on a SC16IS750/SC16IS752 I2C UART
|
||||
//=======================================================================
|
||||
// DFPlayer via NXP SC16IS752 I2C Dual UART. Each device has 2 UARTs on a single I2C address
|
||||
// Total nr of devices on an I2C bus is 16, with 2 UARTs on each address making a total of 32 UARTs per I2C bus
|
||||
// DFPlayer via NXP SC16IS752 I2C Dual UART.
|
||||
// I2C address range 0x48 - 0x57
|
||||
// I2CDFPlayer::create(1st vPin,vPins, I2C address, UART ch);
|
||||
|
||||
// I2CDFPlayer::create(10000, 10, 0x48, 0);
|
||||
// I2CDFPlayer::create(10010, 10, 0x48, 1);
|
||||
|
||||
// Multiplexer example
|
||||
// I2CDFPlayer::create(10020, 10, {I2CMux_0, SubBus_0, 0x50}, 0);
|
||||
|
||||
//
|
||||
// Generic format:
|
||||
// I2CDFPlayer::create(1st vPin, vPins, I2C address, xtal);
|
||||
// Parameters:
|
||||
// 1st vPin : First virtual pin that EX-Rail can control to play a sound, use PLAYSOUND command (alias of ANOUT)
|
||||
// vPins : Total number of virtual pins allocated (1 vPin is supported currently)
|
||||
// 1st vPin for UART 0
|
||||
// I2C Address : I2C address of the serial controller, in 0x format
|
||||
// xtal : 0 for 1.8432Mhz, 1 for 14.7456Mhz
|
||||
//
|
||||
// The vPin is also a pin that can be read with the WAITFOR(vPin) command indicating if the DFPlayer has finished playing a track
|
||||
//
|
||||
|
||||
// I2CDFPlayer::create(10000, 1, 0x48, 1);
|
||||
//
|
||||
// Configuration example on a multiplexer
|
||||
// I2CDFPlayer::create(10000, 1, {I2CMux_0, SubBus_0, 0x48}, 1);
|
||||
|
||||
|
||||
|
||||
|
@ -8,6 +8,13 @@
|
||||
// 5.3.3 - Fix Ethernet cable disconnected message, wait for DHCP
|
||||
// 5.3.2 - MDNS Generic library integration for Ethernet
|
||||
// 5.3.1 - Variable frequency for DC mode
|
||||
// 5.2.40 - Bugfix: WiThrottle sendIntro after initial N message as well
|
||||
// 5.2.29 - Added IO_I2CDFPlayer.h to support DFPLayer over I2C connected to NXP SC16IS750/SC16IS752 (currently only single UART for SC16IS752)
|
||||
// - Added enhanced IO_I2CDFPLayer enum commands to EXRAIL2.h
|
||||
// - Added PLAYSOUND alias of ANOUT to EXRAILMacros.h
|
||||
// - Added UART detection to I2CManager.cpp
|
||||
// 5.2.28 - ESP32: Can all Wifi channels.
|
||||
// - ESP32: Only write Wifi password to display if it is a well known one
|
||||
// 5.2.27 - Bugfix: IOExpander memory allocation
|
||||
// 5.2.26 - Silently ignore overridden HAL defaults
|
||||
// - include HAL_IGNORE_DEFAULTS macro in EXRAIL
|
||||
@ -24,7 +31,7 @@
|
||||
// 5.2.18 - Display network IP fix
|
||||
// 5.2.17 - ESP32 simplify network logic
|
||||
// 5.2.16 - Bugfix to allow for devices using the EX-IOExpander protocol to have no analogue or no digital pins
|
||||
// df - I2C DFPlayper capability
|
||||
// df - I2C DFPlayper capability in stm32 branch
|
||||
// 5.2.15 - move call to CommandDistributor::broadcastPower() into the TrackManager::setTrackPower(*) functions
|
||||
// - add repeats to function packets that are not reminded in accordance with accessory packets
|
||||
// 5.2.14eth - Initial ethernet code for STM32F429ZI and F439ZI boards
|
||||
|
Loading…
Reference in New Issue
Block a user