2019-08-02 21:48:36 +00:00
|
|
|
#include "controller.h"
|
2019-08-06 18:50:11 +00:00
|
|
|
#include "spi_master.h"
|
2019-08-02 21:48:36 +00:00
|
|
|
|
2019-08-11 15:15:22 +00:00
|
|
|
Controller::Controller(Player* p, MCP* m) {
|
2019-08-06 18:50:11 +00:00
|
|
|
_player = p;
|
2019-08-11 15:15:22 +00:00
|
|
|
_mcp = m;
|
2019-08-06 18:50:11 +00:00
|
|
|
_rfid = new MFRC522(PIN_RC522_CS, MFRC522::UNUSED_PIN);
|
|
|
|
|
2019-08-11 15:15:22 +00:00
|
|
|
SPIMaster::enable(PIN_MCP);
|
|
|
|
_mcp->pinMode(1, INPUT); _mcp->pullupMode(1, HIGH);
|
|
|
|
_mcp->pinMode(2, INPUT); _mcp->pullupMode(2, HIGH);
|
|
|
|
_mcp->pinMode(3, INPUT); _mcp->pullupMode(3, HIGH);
|
|
|
|
_mcp->pinMode(4, INPUT); _mcp->pullupMode(4, HIGH);
|
|
|
|
|
2019-08-06 18:50:11 +00:00
|
|
|
SPIMaster::enable(PIN_RC522_CS);
|
2019-08-09 04:27:33 +00:00
|
|
|
DEBUG("Initializing RC522...");
|
2019-08-06 18:50:11 +00:00
|
|
|
_rfid->PCD_Init();
|
2019-08-09 04:27:33 +00:00
|
|
|
#ifdef SHOW_DEBUG
|
|
|
|
_rfid->PCD_DumpVersionToSerial();
|
|
|
|
#endif
|
2019-08-06 18:50:11 +00:00
|
|
|
SPIMaster::disable();
|
2019-08-09 04:27:33 +00:00
|
|
|
INFO("RC522 initialized.\n");
|
2019-08-11 15:15:22 +00:00
|
|
|
|
|
|
|
for (uint8_t i=0; i<NUM_BUTTONS; i++) _button_last_pressed_at[i]=0;
|
2019-08-02 21:48:36 +00:00
|
|
|
}
|
|
|
|
|
2019-08-06 18:50:11 +00:00
|
|
|
void Controller::loop() {
|
2019-08-08 03:31:27 +00:00
|
|
|
unsigned long now = millis();
|
|
|
|
if ((_last_rfid_scan_at < now - RFID_SCAN_INTERVAL) || (now < _last_rfid_scan_at)) {
|
|
|
|
_check_rfid();
|
|
|
|
_last_rfid_scan_at = now;
|
|
|
|
}
|
2019-08-06 18:50:11 +00:00
|
|
|
_check_serial();
|
2019-08-11 15:15:22 +00:00
|
|
|
_check_buttons();
|
2019-08-02 21:48:36 +00:00
|
|
|
}
|
|
|
|
|
2019-08-08 04:49:35 +00:00
|
|
|
uint32_t Controller::_get_rfid_card_uid() {
|
2019-08-06 18:50:11 +00:00
|
|
|
SPIMaster::enable(PIN_RC522_CS);
|
|
|
|
if (!_rfid->PICC_ReadCardSerial()) {
|
2019-08-08 04:49:35 +00:00
|
|
|
if (!_rfid->PICC_IsNewCardPresent()) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!_rfid->PICC_ReadCardSerial()) {
|
|
|
|
return 0;
|
|
|
|
}
|
2019-08-06 18:50:11 +00:00
|
|
|
}
|
2019-08-08 04:49:35 +00:00
|
|
|
uint32_t uid = _rfid->uid.uidByte[0]<<24 | _rfid->uid.uidByte[1]<<16 | _rfid->uid.uidByte[2]<<8 | _rfid->uid.uidByte[3];
|
2019-08-06 18:50:11 +00:00
|
|
|
SPIMaster::disable();
|
2019-08-08 04:49:35 +00:00
|
|
|
return uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Controller::_check_rfid() {
|
|
|
|
uint32_t uid = _get_rfid_card_uid();
|
|
|
|
if (uid != _last_rfid_card_uid) {
|
2019-08-09 04:27:33 +00:00
|
|
|
if (uid > 0) {
|
2019-08-12 18:15:00 +00:00
|
|
|
_no_rfid_card_count = 0;
|
2019-08-09 04:27:33 +00:00
|
|
|
INFO("New RFID card uid: %08x\n", uid);
|
|
|
|
String s_uid = String(uid, HEX);
|
|
|
|
_player->play_album(s_uid);
|
|
|
|
} else {
|
2019-08-12 18:15:00 +00:00
|
|
|
if (_no_rfid_card_count >= 1) {
|
|
|
|
INFO("No more RFID card.");
|
|
|
|
_player->stop();
|
|
|
|
} else {
|
|
|
|
_no_rfid_card_count++;
|
|
|
|
return;
|
|
|
|
}
|
2019-08-09 04:27:33 +00:00
|
|
|
}
|
|
|
|
_last_rfid_card_uid = uid;
|
2019-08-08 04:49:35 +00:00
|
|
|
}
|
2019-08-02 21:48:36 +00:00
|
|
|
}
|
|
|
|
|
2019-08-06 18:50:11 +00:00
|
|
|
void Controller::_check_serial() {
|
|
|
|
if (Serial.available() > 0) {
|
|
|
|
char c = Serial.read();
|
2019-08-09 04:27:33 +00:00
|
|
|
Serial.printf("%c", c);
|
|
|
|
if (c==10 || c==13) {
|
|
|
|
if (_serial_buffer.length()>0) {
|
|
|
|
_execute_serial_command(_serial_buffer);
|
|
|
|
_serial_buffer = String();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_serial_buffer.concat(c);
|
2019-08-06 18:50:11 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-02 21:48:36 +00:00
|
|
|
}
|
2019-08-09 04:27:33 +00:00
|
|
|
|
|
|
|
void Controller::_execute_serial_command(String cmd) {
|
2019-08-12 18:15:00 +00:00
|
|
|
DEBUG("Executing command: %s\n", cmd.c_str());
|
2019-08-11 15:15:22 +00:00
|
|
|
|
2019-08-09 04:27:33 +00:00
|
|
|
if (cmd.equals("ls")) {
|
|
|
|
_execute_command_ls("/");
|
|
|
|
} else if (cmd.startsWith("ls ")) {
|
|
|
|
_execute_command_ls(cmd.substring(3));
|
2019-08-12 18:15:00 +00:00
|
|
|
} else if (cmd.equals("play")) {
|
|
|
|
_player->play_random_album();
|
2019-08-09 04:27:33 +00:00
|
|
|
} else if (cmd.startsWith("play ")) {
|
|
|
|
_player->play_album(cmd.substring(5));
|
|
|
|
} else if (cmd.startsWith("sys ")) {
|
|
|
|
_player->play_system_sound(cmd.substring(4));
|
|
|
|
} else if (cmd.equals("stop")) {
|
|
|
|
_player->stop();
|
|
|
|
} else if (cmd.equals("help")) {
|
|
|
|
_execute_command_help();
|
|
|
|
} else if (cmd.equals("-")) {
|
|
|
|
_player->vol_down();
|
|
|
|
} else if (cmd.equals("+")) {
|
|
|
|
_player->vol_up();
|
|
|
|
} else if (cmd.equals("p")) {
|
|
|
|
_player->track_prev();
|
|
|
|
} else if (cmd.equals("n")) {
|
|
|
|
_player->track_next();
|
|
|
|
} else {
|
|
|
|
ERROR("Unknown command: %s\n", cmd.c_str());
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Controller::_execute_command_ls(String path) {
|
|
|
|
INFO("Listing contents of %s:\n", path.c_str());
|
|
|
|
std::list<String> files = _player->ls(path);
|
|
|
|
for(std::list<String>::iterator it=files.begin(); it!=files.end(); it++) {
|
|
|
|
INFO(" %s\n", (*it).c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Controller::_execute_command_help() {
|
|
|
|
INFO("Valid commands are:");
|
|
|
|
INFO(" help - Displays this help\n");
|
|
|
|
INFO(" ls [dir] - Lists the contents of [dir] or, if not given, of /\n");
|
|
|
|
INFO(" play [id] - Plays the album with the given id\n");
|
|
|
|
INFO(" sys [file]- Plays the file as system sound\n");
|
|
|
|
INFO(" stop - Stops playback\n");
|
|
|
|
INFO(" - / + - Decrease or increase the volume\n");
|
|
|
|
INFO(" p / n - Previous or next track\n");
|
|
|
|
}
|
2019-08-11 15:15:22 +00:00
|
|
|
|
|
|
|
void Controller::_check_buttons() {
|
|
|
|
SPIMaster::enable(PIN_MCP);
|
|
|
|
SPI.beginTransaction(SPISettings(250000, MSBFIRST, SPI_MODE0));
|
|
|
|
/*if (millis()%100==0) {
|
|
|
|
Serial.printf("Buttons: %d %d %d %d\n", _mcp->digitalRead(1), _mcp->digitalRead(2), _mcp->digitalRead(3), _mcp->digitalRead(4));
|
|
|
|
}*/
|
|
|
|
if (_check_button(0)) {
|
2019-08-12 04:20:52 +00:00
|
|
|
_player->track_prev();
|
2019-08-11 15:15:22 +00:00
|
|
|
} else if (_check_button(1)) {
|
|
|
|
_player->vol_up();
|
|
|
|
} else if (_check_button(2)) {
|
|
|
|
_player->vol_down();
|
|
|
|
} else if (_check_button(3)) {
|
2019-08-12 04:20:52 +00:00
|
|
|
_player->track_next();
|
2019-08-11 15:15:22 +00:00
|
|
|
}
|
|
|
|
SPI.endTransaction();
|
|
|
|
SPIMaster::disable();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Controller::_check_button(uint8_t index) {
|
|
|
|
if (index >= NUM_BUTTONS) return false;
|
|
|
|
bool ret = false;
|
|
|
|
uint8_t sum = 0;
|
|
|
|
while (1) {
|
|
|
|
sum = 0;
|
|
|
|
for (int i=0; i<8; i++) {
|
|
|
|
sum += _mcp->digitalRead(index + 1) == HIGH ? 1 : 0;
|
|
|
|
}
|
|
|
|
if (sum==0 || sum==8) break;
|
|
|
|
}
|
|
|
|
if (sum == 0) {
|
|
|
|
if (_button_last_pressed_at[index] + DEBOUNCE_MILLIS < millis()) {
|
|
|
|
DEBUG("Button %d pressed.\n", index);
|
|
|
|
ret = true;
|
|
|
|
}
|
|
|
|
_button_last_pressed_at[index] = millis();
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|