diff --git a/include/controller.h b/include/controller.h index 0b908bb..0e5cf2c 100644 --- a/include/controller.h +++ b/include/controller.h @@ -1,13 +1,15 @@ #pragma once #include "player.h" +#include "sd_card.h" class Controller { private: Player* _player; + SDCard* _sd_card; public: - Controller(Player* p) : _player(p) {} + Controller(Player* p, SDCard* c) : _player(p), _sd_card(c) {} void vol_up(); void vol_down(); void track_next(); diff --git a/include/player.h b/include/player.h index 7868fc8..7ccd86c 100644 --- a/include/player.h +++ b/include/player.h @@ -1,7 +1,27 @@ #pragma once +#include "sd_card.h" +#include "config.h" + +#define SCI_MODE 0x00 +#define SCI_STATUS 0x01 +#define SCI_CLOCKF 0x03 + +#define CMD_WRITE 0x02 +#define CMD_READ 0x03 + +#define XRESET PIN_VS1053_XRESET +#define DREQ PIN_VS1053_DREQ class Player { +private: + SDCard* _sd_card; + void _reset(); + void _init(); + void _wait(); + uint16_t _read_register(uint8_t address, uint32_t spi_speed, uint16_t t);//=SPI_CLOCK_DIV4); + void _write_register(uint8_t address, uint16_t value, uint32_t spi_speed);//=SPI_CLOCK_DIV2); public: + Player(SDCard* c); void vol_up(); void vol_down(); void track_next(); diff --git a/include/sd_card.h b/include/sd_card.h new file mode 100644 index 0000000..96c4a30 --- /dev/null +++ b/include/sd_card.h @@ -0,0 +1,8 @@ +#pragma once +#include +#include "config.h" + +class SDCard { +public: + SDCard(); +}; diff --git a/include/spi_master.h b/include/spi_master.h new file mode 100644 index 0000000..6f8ffe3 --- /dev/null +++ b/include/spi_master.h @@ -0,0 +1,27 @@ +#pragma once + +class SPIMaster { +public: + static void init() { + SPI.setHwCs(false); + pinMode(PIN_SD_CS, OUTPUT); + pinMode(PIN_VS1053_XCS, OUTPUT); + pinMode(PIN_VS1053_XDCS, OUTPUT); + } + static void enable(uint8_t pin) { + digitalWrite(PIN_SD_CS, pin==PIN_SD_CS ? LOW : HIGH); + digitalWrite(PIN_VS1053_XCS, pin==PIN_VS1053_XCS ? LOW : HIGH); + digitalWrite(PIN_VS1053_XDCS, pin==PIN_VS1053_XDCS ? LOW : HIGH); + } + + static void printStatus() { + Serial.printf("CS state: SD:%d, VS1053_XCS:%d, VS1053_XDCS:%d\n", + digitalRead(PIN_SD_CS), + digitalRead(PIN_VS1053_XCS), + digitalRead(PIN_VS1053_XDCS)); + } + + static void disable() { + enable(142); + } +}; diff --git a/platformio.ini b/platformio.ini index 2c7f0eb..d33493a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,3 +12,5 @@ platform = espressif8266 board = esp12e framework = arduino +upload_port = /dev/cu.wchusbserial1420 +upload_speed = 921600 diff --git a/src/main.cpp b/src/main.cpp index ae9d530..7376551 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,52 @@ #include +#include #include "config.h" #include "buttons.h" #include "controller.h" #include "player.h" +#include "sd_card.h" +#include "spi_master.h" Buttons* buttons; Controller* controller; Player* player; +SDCard* sd; + +void printDirectory(File dir, int numTabs) { + while (true) { + + File entry = dir.openNextFile(); + if (! entry) { + // no more files + break; + } + for (uint8_t i = 0; i < numTabs; i++) { + Serial.print('\t'); + } + Serial.print(entry.name()); + if (entry.isDirectory()) { + Serial.println("/"); + printDirectory(entry, numTabs + 1); + } else { + // files have sizes, directories do not + Serial.print("\t\t"); + Serial.println(entry.size(), DEC); + } + entry.close(); + } +} void setup() { - player = new Player(); - controller = new Controller(player); + Serial.begin(74880); + Serial.println("Starting."); + + Serial.println("Setting up SPI..."); + SPI.begin(); + SPIMaster::init(); + + sd = new SDCard(); + player = new Player(sd); + controller = new Controller(player, sd); buttons = new Buttons(controller); } diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 0000000..c06496b --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,99 @@ +// Based on https://github.com/mpflaga/Arduino_Library-vs1053_for_SdFat/blob/master/src/vs1053_SdFat.cpp + +#include "player.h" +#include "spi_master.h" + +Player::Player(SDCard* c) { + pinMode(XRESET, OUTPUT); + digitalWrite(XRESET, HIGH); + pinMode(DREQ, INPUT); + + _init(); +} + +void Player::_reset() { + digitalWrite(XRESET, LOW); + delay(50); + digitalWrite(XRESET, HIGH); + delay(50); +} + +void Player::_init() { + SPI.setClockDivider(SPI_CLOCK_DIV16); + + _reset(); + uint16_t result; + for(uint8_t x=0; x<255; x++) { + result = _read_register(SCI_MODE, 0, x); + if (result != 0) Serial.printf("Try %3d: 0x%04X\n", x, result); + } + delay(10); + /*_read_register(SCI_MODE, SPI_CLOCK_DIV16); // First read fails for some unknown reason... + _read_register(SCI_MODE, SPI_CLOCK_DIV16); + _read_register(SCI_STATUS, SPI_CLOCK_DIV16); + + _read_register(SCI_STATUS, SPI_CLOCK_DIV16); + + + _read_register(SCI_MODE, SPI_CLOCK_DIV16); + _read_register(SCI_MODE, SPI_CLOCK_DIV16); + uint16_t response = _read_register(SCI_MODE, SPI_CLOCK_DIV16); + if (response != 0x4800) { + Serial.printf("Initialization failed. SCI_MODE was: 0x%04X. Expected: 0x4800\n", response); + return; + }*/ + /*_write_register(SCI_CLOCKF, 0x6000); // Set multiplier to 3x + delay(10); + response = _read_register(SCI_CLOCKF); + if (response != 0x6000) { + Serial.printf("Initialization failed. SCI_CLOCKF was: 0x%04X. Expected: 0x6000\n", response); + return; + }*/ + //Serial.println(result, HEX); +} + +inline void Player::_wait() { + delayMicroseconds(100); + //Serial.print("Waiting for DREQ..."); + while(!digitalRead(DREQ)); + //Serial.printf(" done (%d cycles).\n", i); +} + +uint16_t Player::_read_register(uint8_t address, uint32_t spi_speed, uint16_t t) { + Serial.printf("Try %03d, querying register 0x%02X...", t, address); + //SPI.setClockDivider(spi_speed); + if (t & (1<<1)) _wait(); + SPIMaster::enable(PIN_VS1053_XCS); + if (t & (1<<2)) _wait(); + //_wait(); + SPI.transfer(CMD_READ); + if (t & (1<<3)) _wait(); + SPI.transfer(address); + if (t & (1<<4)) _wait(); + uint8_t b1 = SPI.transfer(0xFF); + if (t & (1<<5)) _wait(); + uint8_t b2 = SPI.transfer(0xFF); + if (t & (1<<6)) _wait(); + + uint16_t result = b1 << 8 | b2; + Serial.printf("Response: 0x%02X 0x%02X -> 0x%04X\n", b1, b2, result); + if (t & (1<<7)) delay(10); + + //_wait(); + //SPIMaster::disable(); + + return result; +} + +void Player::_write_register(uint8_t address, uint16_t value, uint32_t spi_speed) { + Serial.printf("Writing to register 0x%02X...", address); + SPI.setClockDivider(spi_speed); + SPIMaster::enable(PIN_VS1053_XCS); + SPI.transfer(CMD_WRITE); + SPI.transfer(address); + SPI.transfer(value >> 8); + SPI.transfer(value & 0xFF); + _wait(); + SPIMaster::disable(); + Serial.println(" done."); +} diff --git a/src/sd_card.cpp b/src/sd_card.cpp new file mode 100644 index 0000000..d6cecb3 --- /dev/null +++ b/src/sd_card.cpp @@ -0,0 +1,9 @@ +#include "sd_card.h" + +SDCard::SDCard() { + if (!SD.begin(PIN_SD_CS)) { + Serial.println("Could not initialize SD card."); + } else { + Serial.println("SD card successfully initialized."); + } +}