logo elektroda
logo elektroda
X
logo elektroda

ESP32-WROOM-32E resets when ESP-Prog unplugged, stable only with serial monitor on

NIXIE_123 114 0
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 21804635
    NIXIE_123
    Level 34  
    Hello

    The ESP32-WROOM-32E with a simple program works reliably when it has the serial monitor on, but when the device is running with the ESP-Prog programmer unplugged, then once in a while it stops working and resets after about 3 seconds coming back to life.
    This causes me to be unable to read the reason for the reset.
    How to approach such an issue?
    I have ruled out the power supply by substituting a workshop power supply as the source.

    The program sends 64 bits every second with one MOSI pin via SPI at 8MHz. It is not receiving anything.

    Doesn't help:
    -lowering fCLK
    -unplugging the pre and post transfer callback
    -replacing spi_device_polling_transmit() with spi_device_queue_trans()
    -addition of spi_device_acquire_bus() and spi_device_release_bus()

    Helps:
    -enabling serial monitor

    ESP32-WROOM-E schematic showing power, RESET, EN, and GPIO connections

    Code:
    #define PIN_NUM_OE 19
    #define SPI SPI2_HOST
    #define PIN_NUM_MOSI 18
    #define PIN_NUM_CLK 5
    
    DMA_ATTR uint64_t spi_buf;
    DRAM_ATTR spi_device_handle_t spi = NULL;
    
    i2c_master_bus_handle_t bus_handle;
    i2c_master_dev_handle_t dev_handle;
    struct RTCDateTime_t dane_z_ds3231;
    
    
    //This function is called (in irq context!) just before a transmission starts.
    void IRAM_ATTR spi_pre_transfer_callback(spi_transaction_t *t)
    {
        gpio_set_level(PIN_NUM_OE, 0);
    }
    
    //This function is called (in irq context!) just after a transmission ends.
    void IRAM_ATTR spi_post_transfer_callback(spi_transaction_t *t)
    {
        gpio_set_level(PIN_NUM_OE, 1);
    }
    
    void IRAM_ATTR spi_send()
    {
    	spi_transaction_t trans;
    	memset(&trans, 0, sizeof(trans));
    	trans.length = 8 * sizeof(spi_buf);
    	trans.tx_buffer = &spi_buf;
    	
    	esp_err_t ret;
        ret = spi_device_polling_transmit(spi, &trans);
    	assert(ret == ESP_OK);
    }
    
    void spi_init()
    {
    	esp_err_t ret;
        spi_bus_config_t buscfg = {
    		.flags = 0,
    		.miso_io_num = -1,
            .mosi_io_num = PIN_NUM_MOSI,
            .sclk_io_num = PIN_NUM_CLK,
            .quadwp_io_num = -1,
            .quadhd_io_num = -1,
            .max_transfer_sz = 8,	//Maximum transfer size in bytes
            .data_io_default_level = 0
        };
        spi_device_interface_config_t devcfg = {
    		.flags = 0,
            .clock_speed_hz = 8 * 1000 * 1000,     	//Clock out at 8 MHz
            .mode = 1,                              //SPI mode 1
            .queue_size = 1,                        //We want to be able to queue 1 transactions at a time
            .pre_cb = spi_pre_transfer_callback, 	//Specify pre-transfer callback to handle OE line
            .post_cb = spi_post_transfer_callback, 	//Specify post-transfer callback to handle OE line
            .spics_io_num = -1						//CS pin not used
        };
        
        //Initialize the SPI bus
        ret = spi_bus_initialize(SPI, &buscfg, SPI_DMA_CH_AUTO);
        ESP_ERROR_CHECK(ret);
        //Attach the handle to the SPI bus
        ret = spi_bus_add_device(SPI, &devcfg, &spi);
        ESP_ERROR_CHECK(ret);
    }
    void spi_buf_write(uint8_t a,
    		   uint8_t b,
    		   uint8_t c, 
    		   uint8_t d, 
    		   uint8_t e, 
    		   uint8_t f
    		   )
    {
    	spi_buf = 0;
    	
    	uint8_t code_a[10] = {57, 58, 59, 61, 49, 48, 63, 62, 60, 56};
    	spi_buf |= ((uint64_t)1 << code_a[a]);
    	
    	uint8_t code_b[10] = {40, 42, 43, 55, 51, 50, 52, 53, 41, 54};
    	spi_buf |= ((uint64_t)1 << code_b[b]);
    	
    	uint8_t code_c[10] = {35, 36, 37, 45, 33, 32, 47, 46, 38, 34};
    	spi_buf |= ((uint64_t)1 << code_c[c]);
    	
    	uint8_t code_d[10] = {25, 26, 27, 29, 17, 16, 31, 30, 28, 24};
    	spi_buf |= ((uint64_t)1 << code_d[d]);
    	
    	uint8_t code_e[10] = {8, 23, 22, 21, 20, 19, 18, 11, 10, 9};
    	spi_buf |= ((uint64_t)1 << code_e[e]);
    	
    	uint8_t code_f[10] = {4, 3, 2, 1, 0, 15, 14, 13, 6, 5};
    	spi_buf |= ((uint64_t)1 << code_f[f]);
    }

    A procedure is called every second:
    
    			spi_buf_write((dane_z_ds3231.Hours)/10,
    					  	(dane_z_ds3231.Hours)%10,
    					  	(dane_z_ds3231.Minutes)/10, 
    					  	(dane_z_ds3231.Minutes)%10, 
    					  	(dane_z_ds3231.Seconds)/10, 
    					  	(dane_z_ds3231.Seconds)%10);    
        		spi_send();	

    The data structure looks like this:
    struct RTCDateTime_t
    {
    	uint8_t Seconds;
    	uint8_t Minutes;
    	uint8_t Hours;
    	uint8_t Day;
    	uint8_t Date;
    	uint8_t Month;
    	uint8_t Year;
    };

    sdkconfig:
    Place transmitting functions of SPI master into IRAM: yes
    Place GPIO control functions into IRAM: yes

    esp-idf v5.5.1
  • ADVERTISEMENT
ADVERTISEMENT