mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 00:31:58 +00:00
dfplayer: batch UART reads to reduce per-loop overhead
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#include "dfplayer.h"
|
#include "dfplayer.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
@@ -132,139 +133,151 @@ void DFPlayer::send_cmd_(uint8_t cmd, uint16_t argument) {
|
|||||||
|
|
||||||
void DFPlayer::loop() {
|
void DFPlayer::loop() {
|
||||||
// Read message
|
// Read message
|
||||||
while (this->available()) {
|
int avail = this->available();
|
||||||
uint8_t byte;
|
if (avail <= 0)
|
||||||
this->read_byte(&byte);
|
return;
|
||||||
|
|
||||||
if (this->read_pos_ == DFPLAYER_READ_BUFFER_LENGTH)
|
uint8_t buf[64];
|
||||||
this->read_pos_ = 0;
|
while (avail > 0) {
|
||||||
|
size_t to_read = std::min(static_cast<size_t>(avail), sizeof(buf));
|
||||||
switch (this->read_pos_) {
|
if (!this->read_array(buf, to_read)) {
|
||||||
case 0: // Start mark
|
break;
|
||||||
if (byte != 0x7E)
|
}
|
||||||
continue;
|
avail -= to_read;
|
||||||
break;
|
for (size_t bi = 0; bi < to_read; bi++) {
|
||||||
case 1: // Version
|
uint8_t byte = buf[bi];
|
||||||
if (byte != 0xFF) {
|
|
||||||
ESP_LOGW(TAG, "Expected Version 0xFF, got %#02x", byte);
|
if (this->read_pos_ == DFPLAYER_READ_BUFFER_LENGTH)
|
||||||
this->read_pos_ = 0;
|
this->read_pos_ = 0;
|
||||||
continue;
|
|
||||||
}
|
switch (this->read_pos_) {
|
||||||
break;
|
case 0: // Start mark
|
||||||
case 2: // Buffer length
|
if (byte != 0x7E)
|
||||||
if (byte != 0x06) {
|
continue;
|
||||||
ESP_LOGW(TAG, "Expected Buffer length 0x06, got %#02x", byte);
|
break;
|
||||||
this->read_pos_ = 0;
|
case 1: // Version
|
||||||
continue;
|
if (byte != 0xFF) {
|
||||||
}
|
ESP_LOGW(TAG, "Expected Version 0xFF, got %#02x", byte);
|
||||||
break;
|
this->read_pos_ = 0;
|
||||||
case 9: // End byte
|
continue;
|
||||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
}
|
||||||
char byte_sequence[100];
|
break;
|
||||||
byte_sequence[0] = '\0';
|
case 2: // Buffer length
|
||||||
for (size_t i = 0; i < this->read_pos_ + 1; ++i) {
|
if (byte != 0x06) {
|
||||||
snprintf(byte_sequence + strlen(byte_sequence), sizeof(byte_sequence) - strlen(byte_sequence), "%02X ",
|
ESP_LOGW(TAG, "Expected Buffer length 0x06, got %#02x", byte);
|
||||||
this->read_buffer_[i]);
|
this->read_pos_ = 0;
|
||||||
}
|
continue;
|
||||||
ESP_LOGVV(TAG, "Received byte sequence: %s", byte_sequence);
|
}
|
||||||
#endif
|
break;
|
||||||
if (byte != 0xEF) {
|
case 9: // End byte
|
||||||
ESP_LOGW(TAG, "Expected end byte 0xEF, got %#02x", byte);
|
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||||
this->read_pos_ = 0;
|
char byte_sequence[100];
|
||||||
continue;
|
byte_sequence[0] = '\0';
|
||||||
}
|
for (size_t i = 0; i < this->read_pos_ + 1; ++i) {
|
||||||
// Parse valid received command
|
snprintf(byte_sequence + strlen(byte_sequence), sizeof(byte_sequence) - strlen(byte_sequence), "%02X ",
|
||||||
uint8_t cmd = this->read_buffer_[3];
|
this->read_buffer_[i]);
|
||||||
uint16_t argument = (this->read_buffer_[5] << 8) | this->read_buffer_[6];
|
}
|
||||||
|
ESP_LOGVV(TAG, "Received byte sequence: %s", byte_sequence);
|
||||||
ESP_LOGV(TAG, "Received message cmd: %#02x arg %#04x", cmd, argument);
|
#endif
|
||||||
|
if (byte != 0xEF) {
|
||||||
switch (cmd) {
|
ESP_LOGW(TAG, "Expected end byte 0xEF, got %#02x", byte);
|
||||||
case 0x3A:
|
this->read_pos_ = 0;
|
||||||
if (argument == 1) {
|
continue;
|
||||||
ESP_LOGI(TAG, "USB loaded");
|
}
|
||||||
} else if (argument == 2) {
|
// Parse valid received command
|
||||||
ESP_LOGI(TAG, "TF Card loaded");
|
uint8_t cmd = this->read_buffer_[3];
|
||||||
}
|
uint16_t argument = (this->read_buffer_[5] << 8) | this->read_buffer_[6];
|
||||||
break;
|
|
||||||
case 0x3B:
|
ESP_LOGV(TAG, "Received message cmd: %#02x arg %#04x", cmd, argument);
|
||||||
if (argument == 1) {
|
|
||||||
ESP_LOGI(TAG, "USB unloaded");
|
switch (cmd) {
|
||||||
} else if (argument == 2) {
|
case 0x3A:
|
||||||
ESP_LOGI(TAG, "TF Card unloaded");
|
if (argument == 1) {
|
||||||
}
|
ESP_LOGI(TAG, "USB loaded");
|
||||||
break;
|
} else if (argument == 2) {
|
||||||
case 0x3F:
|
ESP_LOGI(TAG, "TF Card loaded");
|
||||||
if (argument == 1) {
|
}
|
||||||
ESP_LOGI(TAG, "USB available");
|
break;
|
||||||
} else if (argument == 2) {
|
case 0x3B:
|
||||||
ESP_LOGI(TAG, "TF Card available");
|
if (argument == 1) {
|
||||||
} else if (argument == 3) {
|
ESP_LOGI(TAG, "USB unloaded");
|
||||||
ESP_LOGI(TAG, "USB, TF Card available");
|
} else if (argument == 2) {
|
||||||
}
|
ESP_LOGI(TAG, "TF Card unloaded");
|
||||||
break;
|
}
|
||||||
case 0x40:
|
break;
|
||||||
ESP_LOGV(TAG, "Nack");
|
case 0x3F:
|
||||||
this->ack_set_is_playing_ = false;
|
if (argument == 1) {
|
||||||
this->ack_reset_is_playing_ = false;
|
ESP_LOGI(TAG, "USB available");
|
||||||
switch (argument) {
|
} else if (argument == 2) {
|
||||||
case 0x01:
|
ESP_LOGI(TAG, "TF Card available");
|
||||||
ESP_LOGE(TAG, "Module is busy or uninitialized");
|
} else if (argument == 3) {
|
||||||
break;
|
ESP_LOGI(TAG, "USB, TF Card available");
|
||||||
case 0x02:
|
}
|
||||||
ESP_LOGE(TAG, "Module is in sleep mode");
|
break;
|
||||||
break;
|
case 0x40:
|
||||||
case 0x03:
|
ESP_LOGV(TAG, "Nack");
|
||||||
ESP_LOGE(TAG, "Serial receive error");
|
this->ack_set_is_playing_ = false;
|
||||||
break;
|
this->ack_reset_is_playing_ = false;
|
||||||
case 0x04:
|
switch (argument) {
|
||||||
ESP_LOGE(TAG, "Checksum incorrect");
|
case 0x01:
|
||||||
break;
|
ESP_LOGE(TAG, "Module is busy or uninitialized");
|
||||||
case 0x05:
|
break;
|
||||||
ESP_LOGE(TAG, "Specified track is out of current track scope");
|
case 0x02:
|
||||||
this->is_playing_ = false;
|
ESP_LOGE(TAG, "Module is in sleep mode");
|
||||||
break;
|
break;
|
||||||
case 0x06:
|
case 0x03:
|
||||||
ESP_LOGE(TAG, "Specified track is not found");
|
ESP_LOGE(TAG, "Serial receive error");
|
||||||
this->is_playing_ = false;
|
break;
|
||||||
break;
|
case 0x04:
|
||||||
case 0x07:
|
ESP_LOGE(TAG, "Checksum incorrect");
|
||||||
ESP_LOGE(TAG, "Insertion error (an inserting operation only can be done when a track is being played)");
|
break;
|
||||||
break;
|
case 0x05:
|
||||||
case 0x08:
|
ESP_LOGE(TAG, "Specified track is out of current track scope");
|
||||||
ESP_LOGE(TAG, "SD card reading failed (SD card pulled out or damaged)");
|
this->is_playing_ = false;
|
||||||
break;
|
break;
|
||||||
case 0x09:
|
case 0x06:
|
||||||
ESP_LOGE(TAG, "Entered into sleep mode");
|
ESP_LOGE(TAG, "Specified track is not found");
|
||||||
this->is_playing_ = false;
|
this->is_playing_ = false;
|
||||||
break;
|
break;
|
||||||
}
|
case 0x07:
|
||||||
break;
|
ESP_LOGE(TAG,
|
||||||
case 0x41:
|
"Insertion error (an inserting operation only can be done when a track is being played)");
|
||||||
ESP_LOGV(TAG, "Ack ok");
|
break;
|
||||||
this->is_playing_ |= this->ack_set_is_playing_;
|
case 0x08:
|
||||||
this->is_playing_ &= !this->ack_reset_is_playing_;
|
ESP_LOGE(TAG, "SD card reading failed (SD card pulled out or damaged)");
|
||||||
this->ack_set_is_playing_ = false;
|
break;
|
||||||
this->ack_reset_is_playing_ = false;
|
case 0x09:
|
||||||
break;
|
ESP_LOGE(TAG, "Entered into sleep mode");
|
||||||
case 0x3C:
|
this->is_playing_ = false;
|
||||||
ESP_LOGV(TAG, "Playback finished (USB drive)");
|
break;
|
||||||
this->is_playing_ = false;
|
}
|
||||||
this->on_finished_playback_callback_.call();
|
break;
|
||||||
case 0x3D:
|
case 0x41:
|
||||||
ESP_LOGV(TAG, "Playback finished (SD card)");
|
ESP_LOGV(TAG, "Ack ok");
|
||||||
this->is_playing_ = false;
|
this->is_playing_ |= this->ack_set_is_playing_;
|
||||||
this->on_finished_playback_callback_.call();
|
this->is_playing_ &= !this->ack_reset_is_playing_;
|
||||||
break;
|
this->ack_set_is_playing_ = false;
|
||||||
default:
|
this->ack_reset_is_playing_ = false;
|
||||||
ESP_LOGE(TAG, "Received unknown cmd %#02x arg %#04x", cmd, argument);
|
break;
|
||||||
}
|
case 0x3C:
|
||||||
this->sent_cmd_ = 0;
|
ESP_LOGV(TAG, "Playback finished (USB drive)");
|
||||||
this->read_pos_ = 0;
|
this->is_playing_ = false;
|
||||||
continue;
|
this->on_finished_playback_callback_.call();
|
||||||
|
case 0x3D:
|
||||||
|
ESP_LOGV(TAG, "Playback finished (SD card)");
|
||||||
|
this->is_playing_ = false;
|
||||||
|
this->on_finished_playback_callback_.call();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGE(TAG, "Received unknown cmd %#02x arg %#04x", cmd, argument);
|
||||||
|
}
|
||||||
|
this->sent_cmd_ = 0;
|
||||||
|
this->read_pos_ = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this->read_buffer_[this->read_pos_] = byte;
|
||||||
|
this->read_pos_++;
|
||||||
}
|
}
|
||||||
this->read_buffer_[this->read_pos_] = byte;
|
|
||||||
this->read_pos_++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void DFPlayer::dump_config() {
|
void DFPlayer::dump_config() {
|
||||||
|
|||||||
Reference in New Issue
Block a user