0
\$\begingroup\$

hope y'all are well and safe.

I am back again! Woooo!

Problem: The sound produced is really glitchy and the audio can be barley made.

Setup: I have an ESP32 using the A2DP profile as a BT sink to transmit data via I2S bus into the STM32 from there the STM32 then transmits the data to a DAC.

schematic

simulate this circuit – Schematic created using CircuitLab

Trouble shooting:

  • Have tested the ESP32 A2DP sink in master mode connected directly to the DAC and works perfectly
  • Oscilloscope'd the STM32 to make sure it was producing the 44.41kHz Fs and all other signals

Hunch:

  • I believe this is coming from a misconfiguration of the I2S Protocol which i dont understand how, used the same setting as the inline one (which works perfectly) but just changed the sampling rate and the bits as in A2DP its limited to 44.41kHz and 16bits.

Datasheets:

Here's the code for the ESP32:

// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_log.h"

#include "esp_bt.h"
#include "bt_app_core.h"
#include "bt_app_av.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_bt_api.h"
#include "esp_a2dp_api.h"
#include "esp_avrc_api.h"
#include "driver/i2s.h"

/* event for handler "bt_av_hdl_stack_up */
enum {
    BT_APP_EVT_STACK_UP = 0,
};

/* handler for bluetooth stack enabled events */
static void bt_av_hdl_stack_evt(uint16_t event, void *p_param);


void app_main(void)
{
    /* Initialize NVS — it is used to store PHY calibration data */
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);

    i2s_config_t i2s_config = {

        .mode = I2S_MODE_SLAVE | I2S_MODE_TX,                                  // Only TX
        .sample_rate = 44100,
        .bits_per_sample = 16,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
        .communication_format = I2S_COMM_FORMAT_STAND_I2S,
        .dma_buf_count = 6,
        .dma_buf_len = 60,
        .intr_alloc_flags = 0,        
        //.use_apll = true,                                        //Default interrupt priority
        .tx_desc_auto_clear = true                                              //Auto clear tx descriptor on underflow
    };

    i2s_driver_install(0, &i2s_config, 0, NULL);

    i2s_pin_config_t pin_config = {
        .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN,
        .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN,
        .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN,
        .data_in_num = -1                                                       //Not used
    };

    

    i2s_set_pin(0, &pin_config);
    REG_WRITE(PIN_CTRL, 0xFF0);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
        ESP_LOGE(BT_AV_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(err));
        return;
    }

    if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
        ESP_LOGE(BT_AV_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(err));
        return;
    }

    if ((err = esp_bluedroid_init()) != ESP_OK) {
        ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(err));
        return;
    }

    if ((err = esp_bluedroid_enable()) != ESP_OK) {
        ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(err));
        return;
    }

    /* create application task */
    bt_app_task_start_up();

    /* Bluetooth device name, connection mode and profile set up */
    bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);

#if (CONFIG_BT_SSP_ENABLED == true)
    /* Set default parameters for Secure Simple Pairing */
    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
#endif

    /*
     * Set default parameters for Legacy Pairing
     * Use fixed pin code
     */
    esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
    esp_bt_pin_code_t pin_code;
    pin_code[0] = '1';
    pin_code[1] = '2';
    pin_code[2] = '3';
    pin_code[3] = '4';
    esp_bt_gap_set_pin(pin_type, 4, pin_code);

}

void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
    switch (event) {
    case ESP_BT_GAP_AUTH_CMPL_EVT: {
        if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
            ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name);
            esp_log_buffer_hex(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
        } else {
            ESP_LOGE(BT_AV_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
        }
        break;
    }

#if (CONFIG_BT_SSP_ENABLED == true)
    case ESP_BT_GAP_CFM_REQ_EVT:
        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
        esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
        break;
    case ESP_BT_GAP_KEY_NOTIF_EVT:
        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
        break;
    case ESP_BT_GAP_KEY_REQ_EVT:
        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
        break;
#endif

    case ESP_BT_GAP_MODE_CHG_EVT:
        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode:%d", param->mode_chg.mode);
        break;

    default: {
        ESP_LOGI(BT_AV_TAG, "event: %d", event);
        break;
    }
    }
    return;
}
static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
{
    ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
    switch (event) {
    case BT_APP_EVT_STACK_UP: {
        /* set up device name */
        char *dev_name = "Night Rider Amplifier";
        esp_bt_dev_set_device_name(dev_name);

        esp_bt_gap_register_callback(bt_app_gap_cb);

        /* initialize AVRCP controller */
        esp_avrc_ct_init();
        esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
        /* initialize AVRCP target */
        assert (esp_avrc_tg_init() == ESP_OK);
        esp_avrc_tg_register_callback(bt_app_rc_tg_cb);

        esp_avrc_rn_evt_cap_mask_t evt_set = {0};
        esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE);
        assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK);

        /* initialize A2DP sink */
        esp_a2d_register_callback(&bt_app_a2d_cb);
        esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
        esp_a2d_sink_init();

        /* set discoverable and connectable mode, wait to be connected */
        esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
        break;
    }
    default:
        ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
        break;
    }
}

STM32: I2S Driver:

void init_I2S_Bluetooth(int * RxBuff_bluetooth, int * TxBuff_bluetooth) {

    //Setting Clock for 45.1584MHz
        //N = 28
        //P = 10
        //M = 4
        //FRACT = 1835

        // RCC_PLL2DIVR
        // MASKING:
        RCC -> PLL2DIVR &= ~RCC_PLL2DIVR_P2;
        RCC -> PLL2DIVR &= ~RCC_PLL2DIVR_N2;
        // WRITING:
        RCC -> PLL2DIVR |= RCC_PLL2DIVR_P2_DIV10; // P
        RCC -> PLL2DIVR |= RCC_PLL2DIVR_N2_MULT28; // N

        // RCC_PLLCKSELR
        // MASKING:
        RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM2;
        // WRITING:
        RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM2_DIV4; // M

        // RCC_PLL2FRACR
        // MASKING:
        RCC -> PLL2FRACR &= ~RCC_PLL2FRACR_FRACN2;
        // WRITING:
        RCC -> PLL2FRACR |= RCC_PLL2FRACR_FRACN_1835; // FRAC

        // RCC_PLLCFGR
        // MASKING:
        RCC -> PLLCFGR &= ~RCC_PLLCFGR_DIVP2EN;
        RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL2RGE;
        RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL2VCOSEL;
        RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL2FRACEN;
        // WRITING:
        RCC -> PLLCFGR |= RCC_PLLCFGR_DIVP2EN;
        RCC -> PLLCFGR |= RCC_PLLCFGR_PLL2RGE_8_16;
        RCC -> PLLCFGR |= RCC_PLLCFGR_PLL2VCOSEL_192_836;
        RCC -> PLLCFGR |= RCC_PLLCFGR_PLL2FRACEN;

        // RCC_CR
        // MASKING:
        RCC -> CR &= ~RCC_CR_PLL2ON;
        // WRITING:
        RCC -> CR |= RCC_CR_PLL2ON;
        // WAITING:
        while (((RCC -> CR) & (RCC_CR_PLL2RDY)) == 0){};

        // ENALBING CLOCKS

        // RCC_AHB4ENR
        // MASKING:
        RCC -> AHB4ENR &= ~ RCC_AHB4ENR_GPIOBEN;
        RCC -> AHB4ENR &= ~ RCC_AHB4ENR_GPIOCEN;

        // WRITING:
        RCC -> AHB4ENR |= RCC_AHB4ENR_GPIOBEN;
        RCC -> AHB4ENR |= RCC_AHB4ENR_GPIOCEN;

        // RCC_APB2ENR
        // MASKING:
        RCC ->APB1LENR &= ~RCC_APB1LENR_SPI2EN;
        // WRITING:
        RCC -> APB1LENR |= RCC_APB1LENR_SPI2EN;

        // CHANGING CLOCKS OF PERIPHERALS
        // RCC_D2CCIP1R
        // MASKING;
        RCC -> D2CCIP1R &= ~RCC_D2CCIP1R_SPI123SEL;
        // WRITING:
        RCC -> D2CCIP1R |=  RCC_D2CCIP1R_SPI123SEL_PLL2_P_CK;

        // CHANGING GPIO PINS TO ALETERNATIVE
            // GPIOx_MODER
            // MASKING
            GPIOB -> MODER &= ~GPIO_MODER_MODE12;
            GPIOB -> MODER &= ~GPIO_MODER_MODE13;
            GPIOB -> MODER &= ~GPIO_MODER_MODE14;
            GPIOB -> MODER &= ~GPIO_MODER_MODE15;
            GPIOC -> MODER &= ~GPIO_MODER_MODE6;

            // WRITING:
            GPIOB -> MODER |= GPIO_MODER_MODE12_ALT;
            GPIOB -> MODER |= GPIO_MODER_MODE13_ALT;
            GPIOB -> MODER |= GPIO_MODER_MODE14_ALT;
            GPIOB -> MODER |= GPIO_MODER_MODE15_ALT;
            GPIOC -> MODER |= GPIO_MODER_MODE6_ALT;

            //SETTING ALT FUNCTIONS TO PINS
            // GPIOx_AFRL
            // MASKING:
            GPIOB -> AFR[1] &= ~GPIO_AFRH_AFSEL12;
            GPIOB -> AFR[1] &= ~GPIO_AFRH_AFSEL13;
            GPIOB -> AFR[1] &= ~GPIO_AFRH_AFSEL14;
            GPIOB -> AFR[1] &= ~GPIO_AFRH_AFSEL15;
            GPIOC -> AFR[0] &= ~GPIO_AFRL_AFSEL6;

            // WRITING;
            GPIOB -> AFR[1] |= GPIO_AFRH_AFSEL12_AF5;
            GPIOB -> AFR[1] |= GPIO_AFRH_AFSEL13_AF5;
            GPIOB -> AFR[1] |= GPIO_AFRH_AFSEL14_AF5;
            GPIOB -> AFR[1] |= GPIO_AFRH_AFSEL15_AF5;
            GPIOC -> AFR[0] |= GPIO_AFRL_AFSEL6_AF5;

            // ENABLING DMA1
                // RCC_AHB1ENR
                // MASKING:
                RCC -> AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
                // WRITING:
                RCC -> AHB1ENR |= RCC_AHB1ENR_DMA1EN;

                // MASKING:
                  DMAMUX1_Channel4 -> CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
                  DMAMUX1_Channel5 -> CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
                  // WRITING:
                  DMAMUX1_Channel4 -> CCR |= DMAMUX_CxCR_DMAREQ_ID_SPI2_Rx; //Rx
                  DMAMUX1_Channel5 -> CCR |= DMAMUX_CxCR_DMAREQ_ID_SPI2_Tx; //Tx

                  // DMA1_Stream0_CR
                        // DMA1_Stream1_CR
                        // MASKING:
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_CT;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_PL;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_MSIZE;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_PSIZE;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_MINC;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_CIRC;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_DIR;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_PFCTRL;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_TCIE;
                        DMA1_Stream4 -> CR &= ~DMA_SxCR_HTIE;

                        DMA1_Stream5 -> CR &= ~DMA_SxCR_CT;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_PL;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_MSIZE;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_PSIZE;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_MINC;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_CIRC;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_DIR;
                        DMA1_Stream5 -> CR &= ~DMA_SxCR_PFCTRL;
                        // WRITING:
                        DMA1_Stream4 -> CR |= DMA_SxCR_CT_MEM0;
                        DMA1_Stream4 -> CR |= DMA_SxCR_PL_Very_High;
                        DMA1_Stream4 -> CR |= DMA_SxCR_MSIZE_32BIT;
                        DMA1_Stream4 -> CR |= DMA_SxCR_PSIZE_32BIT;
                        DMA1_Stream4 -> CR |= DMA_SxCR_MINC;
                        DMA1_Stream4 -> CR |= DMA_SxCR_CIRC;
                        DMA1_Stream4 -> CR |= DMA_SxCR_DIR_P_TO_M;
                        DMA1_Stream4 -> CR |= DMA_SxCR_PFCTRL_DMAFLOW;
                        DMA1_Stream4 -> CR |= DMA_SxCR_TCIE;
                        DMA1_Stream4 -> CR |= DMA_SxCR_HTIE;

                        DMA1_Stream5 -> CR |= DMA_SxCR_CT_MEM0;
                        DMA1_Stream5 -> CR |= DMA_SxCR_PL_Very_High;
                        DMA1_Stream5 -> CR |= DMA_SxCR_MSIZE_32BIT;
                        DMA1_Stream5 -> CR |= DMA_SxCR_PSIZE_32BIT;
                        DMA1_Stream5 -> CR |= DMA_SxCR_MINC;
                        DMA1_Stream5 -> CR |= DMA_SxCR_CIRC;
                        DMA1_Stream5 -> CR |= DMA_SxCR_DIR_M_TO_P;
                        DMA1_Stream5 -> CR |= DMA_SxCR_PFCTRL_DMAFLOW;

                        // DMA_SxNDTR
                        // WRITING:
                        DMA1_Stream4 -> NDTR = 0x4;
                        DMA1_Stream5 -> NDTR = 0x4;

                        // DMA_SxPAR
                        // WRITING:
                        DMA1_Stream4 -> PAR = (int) & SPI2 -> RXDR;
                        DMA1_Stream5 -> PAR = (int) & SPI2 -> TXDR;

                        // DMA_SxM0AR
                        // WRITING:
                        DMA1_Stream4 -> M0AR = (int) RxBuff_bluetooth;
                        DMA1_Stream5 -> M0AR = (int) TxBuff_bluetooth;

                        // DMA_SxCR
                        // WRITING:
                        DMA1_Stream4 -> CR |= DMA_SxCR_EN;
                        DMA1_Stream5 -> CR |= DMA_SxCR_EN;

                        // Setting up the SPI/I2S Peripheral
                           // MASKING:
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_MCKOE;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_ODD;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_I2SDIV;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_DATFMT;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_WSINV;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_DATLEN;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_CHLEN;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_CKPOL;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_I2SSTD;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_I2SCFG;
                           SPI2 -> I2SCFGR &= ~SPI_I2SCFGR_I2SMOD;
                           SPI2 -> CFG1    &= ~SPI_CFG1_RXDMAEN;
                           SPI2 -> CFG1    &= ~SPI_CFG1_TXDMAEN;
                           SPI2 -> CFG1    &= ~SPI_CFG1_FTHLV;

                           // WRITING:
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_MCKOE;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_ODD_MULT2;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_I2SDIV_2;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_WSINV_I2S;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_DATALEN_16BIT;
                           //SPI2 -> I2SCFGR |= SPI_I2SCFGR_FIXCH;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_CKPOL_FALL_RISE;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_I2SSTD_I2STAND;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_CHNEL_16BIT_WIDE;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_I2SCFG_MASTER_FULLDUPLEX;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_I2SMOD_I2S_PCM_MODE;
                           SPI2 -> I2SCFGR |= SPI_I2SCFGR_DATFMT_LAlign;
                           //SPI1 -> I2SCFGR |= SPI_CFG1_FTHLV_2_Data;
                           SPI2 -> CFG1 |= SPI_CFG1_RXDMAEN;
                           SPI2 -> CFG1 |= SPI_CFG1_TXDMAEN;
                           SPI2 ->  CR1 |= SPI_CR1_SPE;
                           SPI2 ->  CR1 |= SPI_CR1_CSTART;


}

UPDATE 1: Diagram enter image description here

UPDATE 2: How the half and complete callbacks are being done, for bluetooth samples

void prcoess_bluetooth_halfSample(int * RxBuff_bluetooth, int * TxBuff_bluetooth, float * inSample_bluetooth, float * outSample_bluetooth, float scaleFactor, uint8_t volumeCurrent, arm_biquad_casd_df1_inst_f32 * audioStream, float inputcompensator) {

        for (int i = 0; i < 2; i++) {
        inSample_bluetooth[i] = (float) RxBuff_bluetooth[i] * (scaleFactor * (float) volumeCurrent) * inputcompensator;
      }

        arm_biquad_cascade_df1_f32(audioStream, inSample_bluetooth, outSample_bluetooth, 2);

        for (int i = 0; i < 2; i++) {
        TxBuff_bluetooth[i] = (int)outSample_bluetooth[i];
      }
}

void prcoess_bluetooth_CompleteSample(int * RxBuff_bluetooth, int * TxBuff_bluetooth, float * inSample_bluetooth, float * outSample_bluetooth, float scaleFactor, uint8_t volumeCurrent, arm_biquad_casd_df1_inst_f32 * audioStream, float inputcompensator) {

        for (int i = 2; i < 4; i++) {
        inSample_bluetooth[i] = (float) RxBuff_bluetooth[i] * (scaleFactor * (float) volumeCurrent) * inputcompensator;
      }

        arm_biquad_cascade_df1_f32(audioStream, &inSample_bluetooth[2], &outSample_bluetooth[2], 2);

        for (int i = 2; i < 4; i++) {
        TxBuff_bluetooth[i] = (int)outSample_bluetooth[i];
      }
}

UPDATE 3:

Did further testing and discovered the issue is lying in the STM32 doesn't want to transmit anything, theres no output on the pin checking with the oscilloscope. Addition adding the DAC input pin to the STM32 crashes the stm32

\$\endgroup\$
1
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – Voltage Spike
    Nov 20 '20 at 20:39
1
\$\begingroup\$

Solution was using SPI3 instead of SPI2 I cant forsure say why SPI2 was not working, I tried every pin associated with SPI2 and didnt work.

UPDATE 1: Figured out the real reasoning. The ESP32 needed to be grounded as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.