Compare commits

...

3 Commits

2 changed files with 55 additions and 80 deletions

View File

@ -1,43 +1,6 @@
#pragma once #pragma once
#include <Arduino.h> #include <Arduino.h>
// Pins according to https://www.instructables.com/id/NodeMCU-ESP8266-Details-and-Pinout/
// D0 = 16
// D1 = 5
// D2 = 4
// D3 = 0
// D4 = 2
// D5 = 14
// D6 = 12
// D7 = 13
// D8 = 15
// A0 = 17
// Other usable pins:
// 6, 7, 8, 11 not readable
// 1, 3, 6, 7, 8, 11 nor writable -> 1 (TX) and 3 (RX) can be used read-only
// 9 -> S2
// 10 -> S3
#define RX 3
#define TX 1
// Pins for MCP23017
#define GPA0 0
#define GPA1 1
#define GPA2 2
#define GPA3 3
#define GPA4 4
#define GPA5 5
#define GPA6 6
#define GPA7 7
#define GPB0 8
#define GPB1 9
#define GPB2 10
#define GPB3 11
#define GPB4 12
#define GPB5 13
#define GPB6 14
#define GPB7 15
#define SHOW_DEBUG #define SHOW_DEBUG
//#define SHOW_TRACE //#define SHOW_TRACE
#define FTP_DEBUG #define FTP_DEBUG

View File

@ -104,7 +104,7 @@ void Player::_sleep() {
} }
void Player::_wakeup() { void Player::_wakeup() {
if (_state != sleeping) return; if (_state != sleeping && _state != recording) return;
_stopped_at = millis(); _stopped_at = millis();
DEBUG("Waking VS1053...\n"); DEBUG("Waking VS1053...\n");
set_volume(_volume, false); set_volume(_volume, false);
@ -118,13 +118,14 @@ void Player::_wakeup() {
} }
void Player::_record() { void Player::_record() {
DEBUG("Starting recording.\n");
_set_volume(1, false);
_write_control_register(SCI_AICTRL0, 8000U); // Sampling rate 8000 Hz _write_control_register(SCI_AICTRL0, 8000U); // Sampling rate 8000 Hz
_write_control_register(SCI_AICTRL1, 2048U); // Manual gain, 2x _write_control_register(SCI_AICTRL1, 2048U); // Manual gain, 2x
_write_control_register(SCI_AICTRL2, 2048U); // Maximum gain for autogain - ignored _write_control_register(SCI_AICTRL2, 2048U); // Maximum gain for autogain - ignored
_write_control_register(SCI_AICTRL3, 6); // 2 (left channel) + 4 (PCM) _write_control_register(SCI_AICTRL3, 6); // 2 (left channel) + 4 (PCM)
uint16_t mode = _read_control_register(SCI_MODE); _write_control_register(SCI_MODE, _read_control_register(SCI_MODE) | SM_ADPCM);
mode = mode | SM_RESET | SM_ADPCM; DEBUG("SCI_MODE is now 0x%04X\n", _read_control_register(SCI_MODE));
_write_control_register(SCI_MODE, mode);
_patch_adpcm(); _patch_adpcm();
_state = recording; _state = recording;
} }
@ -162,56 +163,66 @@ void Player::_write_control_register(uint8_t address, uint16_t value) {
_wait(); _wait();
_spi->select_vs1053_xcs(); _spi->select_vs1053_xcs();
SPI.beginTransaction(*_spi_settings); SPI.beginTransaction(*_spi_settings);
_write_direct(address, value);
SPI.endTransaction();
_spi->select_vs1053_xcs(false);
}
void Player::_write_direct(uint8_t target, uint16_t value) {
SPI.transfer(CMD_WRITE); SPI.transfer(CMD_WRITE);
SPI.transfer(target); SPI.transfer(address);
SPI.transfer(value >> 8); SPI.transfer(value >> 8);
SPI.transfer(value & 0xFF); SPI.transfer(value & 0xFF);
SPI.endTransaction();
_spi->select_vs1053_xcs(false);
_wait(); _wait();
} }
void Player::_patch_adpcm() { void Player::_patch_adpcm() {
const uint16_t patch_data[] = {
0x0007,0x0001, /*copy 1*/
0x8050,
0x0006,0x0042, /*copy 66*/
0x0000,0x1790,0xf400,0x5400,0x0000,0x0a10,0xf400,0x5600,
0xb080,0x0024,0x0007,0x9257,0x3f00,0x0024,0x0030,0x0297,
0x3f00,0x0024,0x0000,0x004d,0x0014,0x958f,0x0000,0x1b4e,
0x280f,0xe100,0x0006,0x2016,0x2a00,0x17ce,0x3e12,0xb817,
0x3e14,0xf812,0x3e01,0xb811,0x0007,0x9717,0x0020,0xffd2,
0x0030,0x11d1,0x3111,0x8024,0x3704,0xc024,0x3b81,0x8024,
0x3101,0x8024,0x3b81,0x8024,0x3f04,0xc024,0x2808,0x4800,
0x36f1,0x9811,0x2814,0x9c91,0x0000,0x004d,0x2814,0x9940,
0x003f,0x0013,
0x000a,0x0001, /*copy 1*/
0x0050,
};
const uint8_t patch_size = 74;
DEBUG("Executing patch_adpcm()...\n");
_spi->select_vs1053_xcs(); _spi->select_vs1053_xcs();
SPI.beginTransaction(*_spi_settings); SPI.beginTransaction(*_spi_settings);
_write_direct(SCI_WRAMADDR, 0x8010);
_write_direct(SCI_WRAM, 0x3e12); for (int i=0; i<patch_size; i++) {
_write_direct(SCI_WRAM, 0xb817); unsigned short addr, n, val;
_write_direct(SCI_WRAM, 0x3e14); addr = patch_data[i++];
_write_direct(SCI_WRAM, 0xf812); n = patch_data[i++];
_write_direct(SCI_WRAM, 0x3e01); SPI.transfer(CMD_WRITE);
_write_direct(SCI_WRAM, 0xb811); SPI.transfer(addr & 0XFF);
_write_direct(SCI_WRAM, 0x0007); if (n & 0x8000U) { /* RLE run, replicate n samples */
_write_direct(SCI_WRAM, 0x9717); n &= 0x7FFF;
_write_direct(SCI_WRAM, 0x0020); val = patch_data[i++];
_write_direct(SCI_WRAM, 0xffd2); while (n--) {
_write_direct(SCI_WRAM, 0x0030); SPI.transfer(val >> 8);
_write_direct(SCI_WRAM, 0x11d1); SPI.transfer(val & 0xFF);
_write_direct(SCI_WRAM, 0x3111); _wait();
_write_direct(SCI_WRAM, 0x8024); }
_write_direct(SCI_WRAM, 0x3704); } else { /* Copy run, copy n samples */
_write_direct(SCI_WRAM, 0xc024); while (n--) {
_write_direct(SCI_WRAM, 0x3b81); val = patch_data[i++];
_write_direct(SCI_WRAM, 0x8024); SPI.transfer(val >> 8);
_write_direct(SCI_WRAM, 0x3101); SPI.transfer(val & 0xFF);
_write_direct(SCI_WRAM, 0x8024); _wait();
_write_direct(SCI_WRAM, 0x3b81); }
_write_direct(SCI_WRAM, 0x8024); }
_write_direct(SCI_WRAM, 0x3f04); }
_write_direct(SCI_WRAM, 0xc024);
_write_direct(SCI_WRAM, 0x2808);
_write_direct(SCI_WRAM, 0x4800);
_write_direct(SCI_WRAM, 0x36f1);
_write_direct(SCI_WRAM, 0x9811);
_write_direct(SCI_WRAMADDR, 0x8028);
_write_direct(SCI_WRAM, 0x2a00);
_write_direct(SCI_WRAM, 0x040e);
SPI.endTransaction(); SPI.endTransaction();
_spi->select_vs1053_xcs(false); _spi->select_vs1053_xcs(false);
DEBUG("Patch sent.\n");
} }
void Player::_write_data(uint8_t* buffer) { void Player::_write_data(uint8_t* buffer) {
@ -683,6 +694,7 @@ bool Player::loop() {
if (_state == recording) { if (_state == recording) {
uint16_t samples_available = _read_control_register(SCI_HDAT1); uint16_t samples_available = _read_control_register(SCI_HDAT1);
//DEBUG("Samples available: %d\n", samples_available);
if (samples_available >= 500) { if (samples_available >= 500) {
unsigned long sum = 0; unsigned long sum = 0;
for (int i=0; i<500; i++) { for (int i=0; i<500; i++) {