To preface, I'm trying to make a lightsaber with an ESP32.
From the other people who have done this, the sound chip I see used most often is a WT588D sound module, which is capable of gapless playback.
The WT588D comes in a few different configurations. There is a module that comes with a built in USB port which allows you to upload an image to the board using software designed for the chip. This module is bulky and big (and unavailable with local shipping).
There is also a version with just the IC and breakout, and no built in USB port. In order to upload your sounds to this board, you are required to use a dedicated programmer that is sold seperately:
I do not have access to one of these, and the only ones I can find ship from china with 30+ day lead times.
A few people in an old thread have managed to flash this board using an arduino's SPI capability.
Here is how I have mine wired up:
I am using a level shifter so that I can use my 5v mega to talk to the 3v board. Unforunately, when I run a sketch that should pull up the specs of the WT588D, I get information that isn't correct.
Here's the sketch:
/*
windbond_serial_debug.cpp
A simple program for the Arduino IDE to help familiarize you with
using WinBond flash memory; can also be used to download the entire
contents of a flash chip to a file via a serial port interface.
Important bits of the code: the low-level flash functions (which
implement the timing diagrams in the datasheet), and a simple
serial-port command interface that allows you to talk to your
UNO with any generic terminal application (even the command line).
Copyright 2014, Peter J. Torelli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Revisions:
rev 2 - 21-SEP-2014.
User 'fiaskow' pointed out that driving the WEL instruction after
program and erase w/o waiting for the op to finish may be corrupting
execution. Removed this code (also not needed b/c the WEL is already
cleared after page write or chip erase).
*/
#include <Arduino.h>
#include <SPI.h>
// SS: pin 10
// MOSI: pin 11
// MISO: pin 12
// SCK: pin 13
// WinBond flash commands
#define WB_WRITE_ENABLE 0x06
#define WB_WRITE_DISABLE 0x04
#define WB_CHIP_ERASE 0xc7
#define WB_READ_STATUS_REG_1 0x05
#define WB_READ_DATA 0x03
#define WB_PAGE_PROGRAM 0x02
#define WB_JEDEC_ID 0x9f
#define WB_SECTOR_ERASE 0x20
/*
================================================================================
User Interface Routines
The functions below map to user commands. They wrap the low-level calls with
print/debug statements for readability.
================================================================================
*/
/*
* The JEDEC ID is fairly generic, I use this function to verify the setup
* is working properly.
*/
void get_jedec_id(void) {
Serial.println("command: get_jedec_id");
byte b1, b2, b3;
_get_jedec_id(&b1, &b2, &b3);
char buf[128];
sprintf(buf, "Manufacturer ID: %02xh\nMemory Type: %02xh\nCapacity: %02xh",
b1, b2, b3);
Serial.println(buf);
Serial.println("Ready");
}
/*================================================================================
Low-Level Device Routines
The functions below perform the lowest-level interactions with the flash device.
They match the timing diagrams of the datahsheet. They are called by wrapper
functions which provide a little more feedback to the user. I made them stand-
alone functions so they can be re-used. Each function corresponds to a flash
instruction opcode.
================================================================================
*/
/*
* See the timing diagram in section 9.2.35 of the
* data sheet, "Read JEDEC ID (9Fh)".
*/
void _get_jedec_id(byte *b1, byte *b2, byte *b3) {
digitalWrite(SS, HIGH);
digitalWrite(SS, LOW);
SPI.transfer(WB_JEDEC_ID);
*b1 = SPI.transfer(0); // manufacturer id
*b2 = SPI.transfer(0); // memory type
*b3 = SPI.transfer(0); // capacity
digitalWrite(SS, HIGH);
not_busy();
}
/*
* not_busy() polls the status bit of the device until it
* completes the current operation. Most operations finish
* in a few hundred microseconds or less, but chip erase
* may take 500+ms. Finish all operations with this poll.
*
* See section 9.2.8 of the datasheet
*/
void not_busy(void) {
digitalWrite(SS, HIGH);
digitalWrite(SS, LOW);
SPI.transfer(WB_READ_STATUS_REG_1);
while (SPI.transfer(0) & 1) {};
digitalWrite(SS, HIGH);
}
void setup(void) {
SPI.begin();
SPI.setDataMode(0);
SPI.setBitOrder(MSBFIRST);
Serial.begin(9600);
Serial.println("");
Serial.println("Ready");
get_jedec_id();
}
/*
* loop() dispatches the commands compiled by the serialEvent
* parser callback. Some commands take multiple arguments, so
* I have to split up the strings with some messy manipulation.
*/
void loop(void) {
}
And here is my output:
Ready
command: get_jedec_id
Manufacturer ID: 00h
Memory Type: 00h
Capacity: 00h
Ready
What I should expect to see is something more like this:
Ready
command: get_jedec_id
Manufacturer ID: c2h
Memory Type: 20h
Capacity: 16h
Ready
If I unplug the WT588D module from my breadboard, all I get is "ready" with none of the info. So I know it's communicating with the board in some way, but it's clearly not correct.
Any help would be greatly appreciated. I wonder if this has something to do with using SPI on a 2560 board instead of an Uno board?