kattaliraees / VS1053-ESP32-IDF

VS1053 Driver using ESP-IDF for ESP32 SoCs
MIT License
10 stars 0 forks source link

Version for ESP8266 RTOS SDK #1

Open h1aji opened 8 months ago

h1aji commented 8 months ago

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

h1aji commented 8 months 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);
}
kattaliraees commented 8 months ago

@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

Screenshot 2023-10-31 at 8 14 51 AM Screenshot 2023-10-31 at 8 17 44 AM