Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflict with SPI sdcard driver (InstrFetchProhibited) #5

Closed
ghost opened this issue May 6, 2022 · 5 comments
Closed

Conflict with SPI sdcard driver (InstrFetchProhibited) #5

ghost opened this issue May 6, 2022 · 5 comments

Comments

@ghost
Copy link

ghost commented May 6, 2022

I've ported part of the IRQ handling code from https://github.com/bkgoodman/esp-idf-lora, to your implementation. However, I'm seeing a conflict with both the IRQ handling and the SPI bus initialization:

    esp_err_t err = ESP_OK;

#ifdef LED_PIN
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
#endif

#if CONFIG_I2C_INTERFACE
    int i2c_sda = CONFIG_SDA_GPIO;
    int i2c_sclk = CONFIG_SCL_GPIO;
    int reset_pin = CONFIG_RESET_GPIO;

	ESP_LOGI(TAG, "INTERFACE is i2c");
	ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
	ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
	ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);

    i2c_config_t i2c_config = {
		.mode = I2C_MODE_MASTER,
		.sda_io_num = i2c_sda,
		.scl_io_num = i2c_sclk,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ
	};

	ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config));
	ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0));

    if (reset_pin >= 0) {
		//gpio_pad_select_gpio(reset);
		gpio_reset_pin(reset_pin);
		gpio_set_direction(reset_pin, GPIO_MODE_OUTPUT);
		gpio_set_level(reset_pin, 0);
		vTaskDelay(50 / portTICK_PERIOD_MS);
		gpio_set_level(reset_pin, 1);
	}

#ifdef HAS_OLED_DISPLAY
    ssd1306_init(&ssd1306_dev, 128, 64);
    ssd1306_clear_screen(&ssd1306_dev, false);
	ssd1306_contrast(&ssd1306_dev, 0xff);
#endif
#endif // CONFIG_I2C_INTERFACE

#ifdef USE_SDCARD
    spi_bus_config_t bus_cfg = {
        .mosi_io_num = SDCARD_MOSI,
        .miso_io_num = SDCARD_MISO,
        .sclk_io_num = SDCARD_SCK,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 4000,
    };
    ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_HOST);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize bus.");
        return ret;
    }
#endif

    err = lora_setup(cfg);
    if (err != ESP_OK)
        ESP_LOGW(TAG, "RF communications not functional. Missing component?");

My SD card code is identical to:

https://raw.githubusercontent.com/espressif/esp-idf/a82e6e63d98bb051d4c59cb3d440c537ab9f74b0/examples/storage/sd_card/sdspi/main/sd_card_example_main.c

My TTGO LORA32 board configuration:

#define OLED_RST    -1
#define OLED_SDA    21
#define OLED_SCL    22

#define CONFIG_SDA_GPIO OLED_SDA
#define CONFIG_SCL_GPIO OLED_SCL
#define CONFIG_RESET_GPIO OLED_RST

#define SDCARD_SCK      14
#define SDCARD_MOSI     15
#define SDCARD_MISO     2
#define SDCARD_CS       13

#define LORA_MOSI       27
#define LORA_MISO       19
#define LORA_SCLK       5
#define LORA_CS         18
#define LORA_RST        23
#define LORA_DIO0       26
#define LORA_ISR        LORA_DIO0

#define CONFIG_LORA_CS_GPIO  LORA_CS
#define CONFIG_LORA_RST_GPIO LORA_RST
#define CONFIG_LORA_MISO_GPIO LORA_MISO
#define CONFIG_LORA_MOSI_GPIO LORA_MOSI
#define CONFIG_LORA_SCK_GPIO LORA_SCLK
#define CONFIG_LORA_IRQ_GPIO LORA_ISR

LORA setup:

esp_err_t lora_init(void)
{
   esp_err_t ret;

   /*
    * Configure CPU hardware to communicate with the radio chip
    */
   gpio_pad_select_gpio(CONFIG_LORA_RST_GPIO);
   gpio_set_direction(CONFIG_LORA_RST_GPIO, GPIO_MODE_OUTPUT);

   gpio_reset_pin(CONFIG_LORA_CS_GPIO);
   gpio_pad_select_gpio(CONFIG_LORA_CS_GPIO);
   gpio_set_direction(CONFIG_LORA_CS_GPIO, GPIO_MODE_OUTPUT);
   gpio_set_level(CONFIG_LORA_CS_GPIO, 1);


   spi_bus_config_t bus = {
      .miso_io_num = CONFIG_LORA_MISO_GPIO,
      .mosi_io_num = CONFIG_LORA_MOSI_GPIO,
      .sclk_io_num = CONFIG_LORA_SCK_GPIO,
      .quadwp_io_num = -1,
      .quadhd_io_num = -1,
      .max_transfer_sz = 0
   };
   
   ret = spi_bus_initialize(SPI_HOST_ID, &bus, SPI_DMA_CH_AUTO);
   if (ret != ESP_OK)
      return ret;

   spi_device_interface_config_t dev = {
      .clock_speed_hz = 9000000,
      .mode = 0,
      .spics_io_num = CONFIG_LORA_CS_GPIO,
      .queue_size = 7,
      .flags = 0,
      .pre_cb = NULL
   };

   ret = spi_bus_add_device(SPI_HOST_ID, &dev, &__spi);
   if (ret != ESP_OK)
      return ret;

   /*
    * Perform hardware reset.
    */
   lora_reset();

   /*
    * Check version.
    */
   uint8_t version;
   uint8_t i = 0;
   while(i++ < TIMEOUT_RESET) {
      version = lora_read_reg(REG_VERSION);
      if(version == 0x12) break;
      vTaskDelay(2);
   }
   assert(i <= TIMEOUT_RESET + 1); // at the end of the loop above, the max value i can reach is TIMEOUT_RESET + 1

   /*
    * Default configuration.
    */
   lora_sleep();
   lora_write_reg(REG_FIFO_RX_BASE_ADDR, 0);
   lora_write_reg(REG_FIFO_TX_BASE_ADDR, 0);
   lora_write_reg(REG_LNA, lora_read_reg(REG_LNA) | 0x03);
   lora_write_reg(REG_MODEM_CONFIG_3, 0x04);
   lora_set_tx_power(17);

   lora_idle();
   return ESP_OK;
}

I've been trying to follow the steps described here:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdspi_share.html

Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x00000000  PS      : 0x00060030  A0      : 0x00000000  A1      : 0x3ffbc510  
A2      : 0x3ffb9750  A3      : 0x00000000  A4      : 0x3ffb4610  A5      : 0x3ffb4620  
A6      : 0x00000001  A7      : 0x00000060  A8      : 0x8008cec4  A9      : 0x3ffbc4f0  
A10     : 0x3ffb9750  A11     : 0x00000092  A12     : 0x00000091  A13     : 0x00000060  
A14     : 0x00000000  A15     : 0x00000001  SAR     : 0x00000000  EXCCAUSE: 0x00000014  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  

I'm happy to send you the entire lora.c file. Thank you for your excellent work again, your repositories are an absolute time saver and great reference.

@ghost
Copy link
Author

ghost commented May 6, 2022

An update: spi: spi_bus_initialize(628): SPI bus already initialized.␛[0 this is possibly related to not using the right bus (I do not know yet how to force use of software SPI bus).

We might want to use VSPI_HOST for LORA, and HSPI_HOST for the sdcard.

@nopnop2002
Copy link
Owner

nopnop2002 commented May 8, 2022

SDSPI initialize

sdmmc_host_t host = SDSPI_HOST_DEFAULT();

SDSPI_HOST_DEFAULT is here.
https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/sdspi_host.h

SDSPI_HOST_DEFAULT () has the following contents.

#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#define SDSPI_DEFAULT_HOST HSPI_HOST
#define SDSPI_DEFAULT_DMA  SDSPI_DEFAULT_HOST
#else
#define SDSPI_DEFAULT_HOST SPI2_HOST
#define SDSPI_DEFAULT_DMA  SPI_DMA_CH_AUTO
#endif

/**
 * @brief Default sdmmc_host_t structure initializer for SD over SPI driver
 *
 * Uses SPI mode and max frequency set to 20MHz
 *
 * 'slot' should be set to an sdspi device initialized by `sdspi_host_init_device()`.
 */
#define SDSPI_HOST_DEFAULT() {\
    .flags = SDMMC_HOST_FLAG_SPI | SDMMC_HOST_FLAG_DEINIT_ARG, \
    .slot = SDSPI_DEFAULT_HOST, \
    .max_freq_khz = SDMMC_FREQ_DEFAULT, \
    .io_voltage = 3.3f, \
    .init = &sdspi_host_init, \
    .set_bus_width = NULL, \
    .get_bus_width = NULL, \
    .set_bus_ddr_mode = NULL, \
    .set_card_clk = &sdspi_host_set_card_clk, \
    .do_transaction = &sdspi_host_do_transaction, \
    .deinit_p = &sdspi_host_remove_device, \
    .io_int_enable = &sdspi_host_io_int_enable, \
    .io_int_wait = &sdspi_host_io_int_wait, \
    .command_timeout_ms = 0, \
}

HSPI_HOST / SPI2_HOST cannot be used on other devices.
Conflicts when using HSPI_HOST / SPI2_HOST on other devices..

#ifdef USE_SDCARD
    spi_bus_config_t bus_cfg = {
        .mosi_io_num = SDCARD_MOSI,
        .miso_io_num = SDCARD_MISO,
        .sclk_io_num = SDCARD_SCK,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 4000,
    };
    ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_HOST); ---> host.slot is HSPI_HOST/SPI2_HOST
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize bus.");
        return ret;
    }
#endif

LoRa Initialize

When using SDSPI, HSPI_HOST / SPI2_HOST cannot be used for SPI_HOST_ID.

#ifdef CONFIG_IDF_TARGET_ESP32
#define SPI_HOST_ID HSPI_HOST  --> Must be change
#elif defined CONFIG_IDF_TARGET_ESP32S2
#define SPI_HOST_ID SPI2_HOST --> Must be change
#elif defined CONFIG_IDF_TARGET_ESP32S3
#define SPI_HOST_ID SPI2_HOST --> Must be change
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define SPI_HOST_ID SPI2_HOST --> Must be change
#endif



   ret = spi_bus_initialize(SPI_HOST_ID, &bus, SPI_DMA_CH_AUTO);
   if (ret != ESP_OK)
      return ret;

@nopnop2002
Copy link
Owner

I've ported part of the IRQ handling code from https://github.com/bkgoodman/esp-idf-lora, to your implementation.

I want to know more details.

@nopnop2002
Copy link
Owner

I found this code no longer meaningful:
ESP32 has SPI2_HOST/SPI3_HOST.

#ifdef CONFIG_IDF_TARGET_ESP32
#define LCD_HOST HSPI_HOST
#elif defined CONFIG_IDF_TARGET_ESP32S2
#define LCD_HOST SPI2_HOST
#elif defined CONFIG_IDF_TARGET_ESP32S3
#define LCD_HOST SPI2_HOST
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define LCD_HOST SPI2_HOST
#endif

I am considering making it possible to select SPI2_HOST / SPI3_HOST.

@nopnop2002
Copy link
Owner

nopnop2002 commented May 12, 2022

You can now select SPI2_HOST / SPI3_HOST.

Set to SPI3_HOST when using with SDSPI.

We might want to use VSPI_HOST for LORA, and HSPI_HOST for the sdcard.

ESP32S2 / S3 / C3 / H2 / C2 does not have VSPI_HOST.

In ESP32S2 / S3 / C3 / H2 / C2, VSPI_HOST has changed to SPI3_HOST.

config-lora-3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant