Added the command SerialConfig with the capability of changing the data bits/parity/stop bits setting in the hardware serial port.

This commit is contained in:
Luis Teixeira 2019-12-04 22:51:21 +00:00
parent 8cf2d15ed1
commit 7c857b0feb
8 changed files with 158 additions and 18 deletions

View File

@ -284,6 +284,7 @@
#define D_CMND_I2CDRIVER "I2CDriver"
#define D_CMND_SERIALSEND "SerialSend"
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
#define D_CMND_SERIALCONFIG "SerialConfig"
#define D_CMND_BAUDRATE "Baudrate"
#define D_CMND_TEMPLATE "Template"
#define D_JSON_NAME "NAME"

View File

@ -190,6 +190,7 @@
#define D_SYSLOG_LOGGING_REENABLED "Syslog logging re-enabled"
#define D_SET_BAUDRATE_TO "Set Baudrate to"
#define D_SET_SERIAL_CONFIG_TO "Set serial port mode to"
#define D_RECEIVED_TOPIC "Received Topic"
#define D_DATA_SIZE "Data Size"
#define D_ANALOG_INPUT "Analog"

View File

@ -190,6 +190,7 @@
#define D_SYSLOG_LOGGING_REENABLED "Registro do Syslog reativado"
#define D_SET_BAUDRATE_TO "Ajuste da velocidade para"
#define D_SET_SERIAL_CONFIG_TO "Ajuste do modo da porta série"
#define D_RECEIVED_TOPIC "Topico Recebido"
#define D_DATA_SIZE "Tamanho de Dados"
#define D_ANALOG_INPUT "Entrada Analógica"

View File

@ -231,6 +231,26 @@ typedef struct {
const uint8_t MAX_TUYA_FUNCTIONS = 16;
/**
* Structure used for holding the hardware serial port settings.
*
* Description of the fields:
*
* baudrate - the baud rate multiplier, which can range from 0 - 15360 (multiply by 300 to obtain the actual baud rate)
* mode - encodes a selection of the main serial port settings.
*
* The mode field can take the following values:
*
* 0 - 7N1 (7 data bits / no parity / 1 stop bit)
* 1 - 7E1 (7 data bits / even parity / 1 stop bit)
* 2 - 8N1 (8 data bits / no parity / 1 stop bit)
* 3 - 8E1 (8 data bits / even parity / 1 stop bit)
*/
typedef struct {
uint16_t baudrate; // the baud rate multiplier, which can range from 0 - 15360 (multiply by 300 to obtain the actual baud rate)
uint8_t mode; // encodes a selection of the main serial port settings: 8E1, 8N1, 7E1 and 7N1
} SerialCfg;
/*
struct SYSCFG {
unsigned long cfg_holder; // 000 Pre v6 header
@ -397,7 +417,7 @@ struct SYSCFG {
uint8_t web_color[18][3]; // 73E
uint16_t display_width; // 774
uint16_t display_height; // 776
uint16_t baudrate; // 778
uint16_t serial_config; // 778 - 11 MSB's define the baud rate; 5 LSB's define the serial config (e.g. 8N1). Maps to the SerialCfg struct.
uint16_t sbaudrate; // 77A
EnergyUsage energy_usage; // 77C
// uint32_t drivers[3]; // 794 - 6.5.0.12 replaced by below three entries

View File

@ -670,8 +670,13 @@ void SettingsDefaultSet2(void)
// for (uint32_t i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; }
// Serial
Settings.baudrate = APP_BAUDRATE / 300;
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
config.baudrate = APP_BAUDRATE / 300;
Settings.serial_config = SerialCfgToSetting(config);
Settings.sbaudrate = SOFT_BAUDRATE / 300;
//Settings.serial_config = SERIAL_8N1;
Settings.serial_delimiter = 0xff;
Settings.seriallog_level = SERIAL_LOG_LEVEL;
@ -1059,7 +1064,10 @@ void SettingsDelta(void)
}
}
if (Settings.version < 0x06060009) {
Settings.baudrate = Settings.ex_baudrate * 4;
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
config.baudrate = Settings.ex_baudrate * 4;
Settings.serial_config = SerialCfgToSetting(config);
Settings.sbaudrate = Settings.ex_sbaudrate * 4;
}
if (Settings.version < 0x0606000A) {
@ -1160,3 +1168,26 @@ void SettingsDelta(void)
SettingsSave(1);
}
}
/* Performs the bitwise operations needed for translating the serial port settings 16-bit word
to the SerialCfg struct: */
SerialCfg SettingToSerialCfg(uint16_t setting)
{
SerialCfg serial_config;
serial_config.baudrate = (uint16_t) (setting >> 2) & 0x3FFF;
serial_config.mode = (uint8_t) (setting) & 0x3;
return serial_config;
}
/* Performs the bitwise operations needed for translating from the SerialCfg struct
to the serial port settings 16-bit word: */
uint16_t SerialCfgToSetting(SerialCfg serial_config)
{
uint16_t setting;
setting = (uint16_t) ((uint16_t) (serial_config.baudrate << 2 & 0xFFFC)) | (serial_config.mode & 0x3);
return setting;
}

View File

@ -738,16 +738,42 @@ int GetStateNumber(char *state_text)
return state_number;
}
void SetSerialBaudrate(int baudrate)
void SetSerialConfig(uint8_t mode)
{
Settings.baudrate = baudrate / 300;
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
config.mode = mode;
Settings.serial_config = SerialCfgToSetting(config);
SerialConfig hardware_serial_config = ConvertSettingByteToSerialConfig(mode);
if (seriallog_level) {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SET_SERIAL_CONFIG_TO " %d"), mode);
}
delay(100);
Serial.flush();
Serial.begin(Serial.baudRate(), hardware_serial_config);
delay(10);
Serial.println();
}
void SetSerialBaudrate(uint32_t baudrate)
{
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
config.baudrate = ((baudrate / 300) & 0x3FFF);
Settings.serial_config = SerialCfgToSetting(config);
SerialConfig hardware_serial_config = ConvertSettingByteToSerialConfig(config.mode);
if (Serial.baudRate() != baudrate) {
if (seriallog_level) {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SET_BAUDRATE_TO " %d"), baudrate);
}
delay(100);
Serial.flush();
Serial.begin(baudrate, serial_config);
Serial.begin(baudrate, hardware_serial_config);
delay(10);
Serial.println();
}
@ -759,7 +785,10 @@ void ClaimSerial(void)
AddLog_P(LOG_LEVEL_INFO, PSTR("SNS: Hardware Serial"));
SetSeriallog(LOG_LEVEL_NONE);
baudrate = Serial.baudRate();
Settings.baudrate = baudrate / 300;
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
config.baudrate = baudrate / 300;
Settings.serial_config = SerialCfgToSetting(config);
}
void SerialSendRaw(char *codes)
@ -1647,3 +1676,28 @@ void AddLogMissed(char *sensor, uint32_t misses)
{
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SNS: %s missed %d"), sensor, SENSOR_MAX_MISS - misses);
}
SerialConfig ConvertSettingByteToSerialConfig(uint8_t setting_byte)
{
SerialConfig hardware_serial_config;
switch(setting_byte) {
case 0:
hardware_serial_config = SERIAL_7N1;
break;
case 1:
hardware_serial_config = SERIAL_7E1;
break;
case 2:
hardware_serial_config = SERIAL_8N1;
break;
case 3:
hardware_serial_config = SERIAL_8E1;
break;
default:
hardware_serial_config = SERIAL_8N1;
break;
}
return hardware_serial_config;
}

View File

@ -23,10 +23,10 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|"
D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_FREQUENCY_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_WEIGHT_RESOLUTION "|"
D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_TEMPLATE "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|"
D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|"
D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|"
D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|"
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|"
D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_SERIALSEND "|" D_CMND_SERIALCONFIG "|"
D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|"
D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|"
#ifdef USE_I2C
D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|"
#endif
@ -38,7 +38,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
&CmndSetoption, &CmndTemperatureResolution, &CmndHumidityResolution, &CmndPressureResolution, &CmndPowerResolution,
&CmndVoltageResolution, &CmndFrequencyResolution, &CmndCurrentResolution, &CmndEnergyResolution, &CmndWeightResolution,
&CmndModule, &CmndModules, &CmndGpio, &CmndGpios, &CmndTemplate, &CmndPwm, &CmndPwmfrequency, &CmndPwmrange,
&CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialSend, &CmndBaudrate,
&CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialSend, &CmndSerialConfig, &CmndBaudrate,
&CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig,
&CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset,
@ -1072,14 +1072,44 @@ void CmndSwitchDebounce(void)
ResponseCmndNumber(Settings.switch_debounce);
}
/**
* Changes the Serial port number of bits, parity and stop bits.
* For the time being this command only has effect on the hardware
* serial port (GPIO1 and GPIO3)
*
* Meaning of the values:
*
* 0 - 7N1 (7 data bits / no parity / 1 stop bit)
* 1 - 7E1 (7 data bits / even parity / 1 stop bit)
* 2 - 8N1 (8 data bits / no parity / 1 stop bit)
* 3 - 8E1 (8 data bits / even parity / 1 stop bit)
*
*/
void CmndSerialConfig(void)
{
// a frugal validation to check if the provided serial port mode is valid:
if (XdrvMailbox.payload >= 0 && XdrvMailbox.payload <= 3) {
uint8_t mode = (uint8_t) (XdrvMailbox.payload & 3);
SetSerialConfig(mode);
}
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
ResponseCmndNumber(config.mode);
}
void CmndBaudrate(void)
{
if (XdrvMailbox.payload >= 300) {
XdrvMailbox.payload /= 300; // Make it a valid baudrate
baudrate = (XdrvMailbox.payload & 0xFFFF) * 300;
SetSerialBaudrate(baudrate);
if (XdrvMailbox.payload >= 300) {
SetSerialBaudrate(XdrvMailbox.payload);
}
ResponseCmndNumber(Settings.baudrate * 300);
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
ResponseCmndNumber(config.baudrate * 300);
}
void CmndSerialSend(void)

View File

@ -1535,7 +1535,9 @@ void setup(void)
XdrvCall(FUNC_SETTINGS_OVERRIDE);
}
baudrate = Settings.baudrate * 300;
SerialCfg config = SettingToSerialCfg(Settings.serial_config);
baudrate = config.baudrate * 300;
// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START];
seriallog_level = Settings.seriallog_level;
seriallog_timer = SERIALLOG_TIMER;