Open h1aji opened 1 year ago
I tried my best. will you be able to point me anything i am missing?
#include <string.h>
#include <driver/spi.h>
#include <driver/gpio.h>
#include "esp_log.h"
#include "vs1053.h"
#define CONFIG_GPIO_CS 0
#define CONFIG_GPIO_DCS 16
#define CONFIG_GPIO_DREQ 9
#define CONFIG_GPIO_RESET 10
#define TAG "VS1053"
static const char* LOG_TAG = "VS1053";
//#define SLEEP_MS(X_MS) vTaskDelay(((X_MS >= 10) ? X_MS : 10) / portTICK_PERIOD_MS)
void vs1053_init() {
esp_err_t ret;
//CS, DCS, RESET GPIOs
gpio_set_direction( CONFIG_GPIO_CS, GPIO_MODE_OUTPUT );
gpio_set_direction( CONFIG_GPIO_DCS, GPIO_MODE_OUTPUT );
gpio_set_direction( CONFIG_GPIO_RESET, GPIO_MODE_OUTPUT );
gpio_set_direction( CONFIG_GPIO_DREQ, GPIO_MODE_INPUT );
//DREQ GPIO as input
gpio_config_t dreq_gpio_conf;
dreq_gpio_conf.mode = GPIO_MODE_INPUT;
dreq_gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE;
dreq_gpio_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
dreq_gpio_conf.intr_type = GPIO_INTR_DISABLE;
dreq_gpio_conf.pin_bit_mask = ((uint64_t)(((uint64_t)1)<<CONFIG_GPIO_DREQ));
ESP_ERROR_CHECK(gpio_config(&dreq_gpio_conf));
spi_config_t spi_config;
spi_config.interface.val = SPI_DEFAULT_INTERFACE;
spi_config.intr_enable.val = SPI_MASTER_DEFAULT_INTR_ENABLE;
spi_config.interface.cs_en = 0;
spi_config.interface.miso_en = 1;
spi_config.interface.bit_tx_order = SPI_BIT_ORDER_LSB_FIRST;
spi_config.interface.byte_tx_order = SPI_BYTE_ORDER_MSB_FIRST;
spi_config.mode = SPI_MASTER_MODE;
spi_config.clk_div = SPI_2MHz_DIV;
spi_config.event_cb = NULL; //spi_event_callback;
spi_init(HSPI_HOST, &spi_config);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_SPICS2);
SLEEP_MS(20);
gpio_set_level(CONFIG_GPIO_CS, 1);
gpio_set_level(CONFIG_GPIO_DCS, 1);
gpio_set_level(CONFIG_GPIO_RESET, 0);
SLEEP_MS(5);
gpio_set_level(CONFIG_GPIO_RESET, 1);
uint16_t reg_data = vs1053_read_sci(SCI_MODE);
if(reg_data != (SM_LINE1 | SM_SDINEW)) {
////LOG_INFO("%d", reg_data);
ESP_LOGI(TAG, "Setting mode");
vs1053_write_sci(SCI_MODE, (SM_LINE1 | SM_SDINEW));
}
reg_data = 0;
reg_data = vs1053_read_sci(SCI_MODE);
if(reg_data != (SM_LINE1 | SM_SDINEW)) {
ESP_LOGI(TAG, "Setting mode");
vs1053_write_sci(SCI_MODE, (SM_LINE1 | SM_SDINEW));
}
reg_data = vs1053_read_sci(SCI_AUDATA);
//LOG_INFO("SCI_AUDATA - %d", reg_data);
reg_data = vs1053_read_sci(SCI_CLOCKF);
//LOG_INFO("SCI_CLOCKF - %d", reg_data);
vs1053_write_sci(SCI_AUDATA, 44101); // 44.1kHz stereo
// The next clocksetting allows SPI clocking at 5 MHz, 4 MHz is safe then.
vs1053_write_sci(SCI_CLOCKF, 6 << 12); // Normal clock settings multiplyer 3.0 = 12.2 MHz
//vs1053_set_volume(100);
//vs1053_write_sci(0x0B, 0x0000);
reg_data = vs1053_read_sci(SCI_AUDATA);
//LOG_INFO("SCI_AUDATA - %d", reg_data);
reg_data = vs1053_read_sci(SCI_CLOCKF);
//LOG_INFO("SCI_CLOCKF - %d", reg_data);
//reg_data = vs1053_read_sci(0x0B);
////LOG_INFO("SCI_VOL - %d", reg_data);
reg_data = vs1053_read_sci(SCI_MODE);
if(reg_data != (SM_LINE1 | SM_SDINEW)) {
//LOG_INFO("%d", reg_data);
ESP_LOGI(TAG, "High speed - Setting mode");
vs1053_write_sci(SCI_MODE, (SM_LINE1 | SM_SDINEW));
}
}
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void vs1053_write_sci(uint8_t addr, uint16_t data) {
uint8_t d = 2;
spi_trans_t trans;
esp_err_t ret;
while(!gpio_get_level(CONFIG_GPIO_DREQ)); //Wait until DREQ is high
gpio_set_level(CONFIG_GPIO_CS, 0);
memset( &trans, 0, sizeof( spi_trans_t ) );
trans.cmd = d;
trans.addr = addr;
trans.mosi[0] = (data >> 8) & 0xFF;
trans.mosi[1] = (data & 0xFF);
trans.bits.mosi = 16;
ret = spi_trans(HSPI_HOST, &trans);
assert(ret==ESP_OK);
gpio_set_level(CONFIG_GPIO_CS, 1);
}
uint16_t vs1053_read_sci(uint8_t addr) {
uint16_t res;
uint8_t d = 3;
spi_trans_t trans;
esp_err_t ret;
while(!gpio_get_level(CONFIG_GPIO_DREQ)); //Wait until DREQ is high
gpio_set_level(CONFIG_GPIO_CS, 0);
memset( &trans, 0, sizeof( spi_trans_t ) );
trans.bits.miso=16;
trans.cmd = d;
trans.addr = addr;
ret = spi_trans(HSPI_HOST, &trans);
assert(ret==ESP_OK);
res = (((trans.miso[0]&0xFF)<<8) | ((trans.miso[1])&0xFF)) ;
gpio_set_level(CONFIG_GPIO_CS, 1);
return res;
}
//Sending MP3 raw bytes. Max 32 bytes at time without checking DREQ each time
void vs1053_write_sdi(uint8_t *data, uint8_t bytes) {
if(bytes > 32) {
return;//Error - too many bytes to transfer
}
while(!gpio_get_level(CONFIG_GPIO_DREQ)); //Wait until DREQ is high
spi_trans_t trans;
esp_err_t ret;
gpio_set_level(CONFIG_GPIO_DCS, 0);
memset( &trans, 0, sizeof( spi_trans_t ) );
trans.bits.mosi = bytes * 8;
trans.mosi = data;
ret = spi_trans(HSPI_HOST, &trans);
assert(ret==ESP_OK);
gpio_set_level(CONFIG_GPIO_DCS, 1);
}
void vs1053_set_volume(uint8_t vol) {
// Set volume. Both left and right.
// Input value is 0..100. 100 is the loudest.
uint16_t value; // Value to send to SCI_VOL
value = map(vol, 0, 100, 0x20, 0x00); // 0..100% to one channel
if (value == 0x20)
{
value = 0xFE;
}
value = (value << 8) | value;
vs1053_write_sci(SCI_VOL, value); // Volume left and right
uint16_t reg_data = vs1053_read_sci(SCI_VOL);
//LOG_INFO("SCI_VOL - %d", reg_data);
}
@h1aji check if the SPI bus is already used for the onboard SPI flash memory or something else. I have never used ESP8266 and not familiar with it so I will not be able guide you.
And also it's not recommended to use ESP8266 by espressif. You should use ESP8684
Hi, nice job, but i was looking for a driver for ESP8266. Unfortunately, I am struggling to modify init part I am using this manual https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/api-reference/peripherals/spi.html
Do you have any plans to make version for esp8266?
Thanks