ESPHome  2024.4.1
dfplayer.cpp
Go to the documentation of this file.
1 #include "dfplayer.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace dfplayer {
6 
7 static const char *const TAG = "dfplayer";
8 
9 void DFPlayer::play_folder(uint16_t folder, uint16_t file) {
10  if (folder < 100 && file < 256) {
11  this->ack_set_is_playing_ = true;
12  this->send_cmd_(0x0F, (uint8_t) folder, (uint8_t) file);
13  } else if (folder <= 15 && file <= 3000) {
14  this->ack_set_is_playing_ = true;
15  this->send_cmd_(0x14, (((uint16_t) folder) << 12) | file);
16  } else {
17  ESP_LOGE(TAG, "Cannot play folder %d file %d.", folder, file);
18  }
19 }
20 
21 void DFPlayer::send_cmd_(uint8_t cmd, uint16_t argument) {
22  uint8_t buffer[10]{0x7e, 0xff, 0x06, cmd, 0x01, (uint8_t) (argument >> 8), (uint8_t) argument, 0x00, 0x00, 0xef};
23  uint16_t checksum = 0;
24  for (uint8_t i = 1; i < 7; i++)
25  checksum += buffer[i];
26  checksum = -checksum;
27  buffer[7] = checksum >> 8;
28  buffer[8] = (uint8_t) checksum;
29 
30  this->sent_cmd_ = cmd;
31 
32  ESP_LOGD(TAG, "Send Command %#02x arg %#04x", cmd, argument);
33  this->write_array(buffer, 10);
34 }
35 
37  // Read message
38  while (this->available()) {
39  uint8_t byte;
40  this->read_byte(&byte);
41 
43  this->read_pos_ = 0;
44 
45  switch (this->read_pos_) {
46  case 0: // Start mark
47  if (byte != 0x7E)
48  continue;
49  break;
50  case 1: // Version
51  if (byte != 0xFF) {
52  ESP_LOGW(TAG, "Expected Version 0xFF, got %#02x", byte);
53  this->read_pos_ = 0;
54  continue;
55  }
56  break;
57  case 2: // Buffer length
58  if (byte != 0x06) {
59  ESP_LOGW(TAG, "Expected Buffer length 0x06, got %#02x", byte);
60  this->read_pos_ = 0;
61  continue;
62  }
63  break;
64  case 9: // End byte
65  if (byte != 0xEF) {
66  ESP_LOGW(TAG, "Expected end byte 0xEF, got %#02x", byte);
67  this->read_pos_ = 0;
68  continue;
69  }
70  // Parse valid received command
71  uint8_t cmd = this->read_buffer_[3];
72  uint16_t argument = (this->read_buffer_[5] << 8) | this->read_buffer_[6];
73 
74  ESP_LOGV(TAG, "Received message cmd: %#02x arg %#04x", cmd, argument);
75 
76  switch (cmd) {
77  case 0x3A:
78  if (argument == 1) {
79  ESP_LOGI(TAG, "USB loaded");
80  } else if (argument == 2) {
81  ESP_LOGI(TAG, "TF Card loaded");
82  }
83  break;
84  case 0x3B:
85  if (argument == 1) {
86  ESP_LOGI(TAG, "USB unloaded");
87  } else if (argument == 2) {
88  ESP_LOGI(TAG, "TF Card unloaded");
89  }
90  break;
91  case 0x3F:
92  if (argument == 1) {
93  ESP_LOGI(TAG, "USB available");
94  } else if (argument == 2) {
95  ESP_LOGI(TAG, "TF Card available");
96  } else if (argument == 3) {
97  ESP_LOGI(TAG, "USB, TF Card available");
98  }
99  break;
100  case 0x40:
101  ESP_LOGV(TAG, "Nack");
102  this->ack_set_is_playing_ = false;
103  this->ack_reset_is_playing_ = false;
104  if (argument == 6) {
105  ESP_LOGV(TAG, "File not found");
106  this->is_playing_ = false;
107  }
108  break;
109  case 0x41:
110  ESP_LOGV(TAG, "Ack ok");
111  this->is_playing_ |= this->ack_set_is_playing_;
112  this->is_playing_ &= !this->ack_reset_is_playing_;
113  this->ack_set_is_playing_ = false;
114  this->ack_reset_is_playing_ = false;
115  break;
116  case 0x3D: // Playback finished
117  this->is_playing_ = false;
118  this->on_finished_playback_callback_.call();
119  break;
120  default:
121  ESP_LOGD(TAG, "Command %#02x arg %#04x", cmd, argument);
122  }
123  this->sent_cmd_ = 0;
124  this->read_pos_ = 0;
125  continue;
126  }
127  this->read_buffer_[this->read_pos_] = byte;
128  this->read_pos_++;
129  }
130 }
132  ESP_LOGCONFIG(TAG, "DFPlayer:");
133  this->check_uart_settings(9600);
134 }
135 
136 } // namespace dfplayer
137 } // namespace esphome
void loop() override
Definition: dfplayer.cpp:36
void send_cmd_(uint8_t cmd, uint16_t argument=0)
Definition: dfplayer.cpp:21
void dump_config() override
Definition: dfplayer.cpp:131
CallbackManager< void()> on_finished_playback_callback_
Definition: dfplayer.h:106
void write_array(const uint8_t *data, size_t len)
Definition: uart.h:21
void check_uart_settings(uint32_t baud_rate, uint8_t stop_bits=1, UARTParityOptions parity=UART_CONFIG_PARITY_NONE, uint8_t data_bits=8)
Check that the configuration of the UART bus matches the provided values and otherwise print a warnin...
Definition: uart.cpp:13
bool read_byte(uint8_t *data)
Definition: uart.h:29
const size_t DFPLAYER_READ_BUFFER_LENGTH
Definition: dfplayer.h:7
void play_folder(uint16_t folder, uint16_t file)
Definition: dfplayer.cpp:9
uint8_t checksum
Definition: bl0939.h:35
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
char read_buffer_[DFPLAYER_READ_BUFFER_LENGTH]
Definition: dfplayer.h:99
stm32_cmd_t * cmd
Definition: stm32flash.h:96