Page 1 of 1

ISR and semaphore not working

Posted: Wed Mar 06, 2024 7:09 am
by ssklive
I am trying to get a transaction from SPI (later send it over wifi). This transaction is to be done with an interrupt on a GPOI.
I am using ESP32C6miniDev kit
ESP-IDF 5.1.2
Here is my approach
Create a function to handle semaphore

Code: Select all

SemaphoreHandle_t sem_mutex=NULL;
void IRAM_ATTR GOPIisr_handler(void* arg) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR(sem_mutex, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
Initialize SPI:

Code: Select all

void configure_spi() {
    spi_bus_config_t bus_config = {
        .miso_io_num = 2,  
        .mosi_io_num = -1, // MOSI not used
        .sclk_io_num = 6,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
    };
    spi_device_interface_config_t dev_config = {
        .clock_speed_hz = SCLK_FREQ,
        .mode = 0, // SPI mode 1
        .spics_io_num = CS_PIN, //this is actually not needed
        .queue_size = 1,
    };
    spi_bus_initialize(SPI_BUS, &bus_config, SPI_DMA_CH_AUTO);
    spi_bus_add_device(SPI_BUS, &dev_config, &spi);
}
Initialize the GPIO on which I want the interrupt:

Code: Select all

void initialize_IntrGPIO() {

    gpio_config_t io_conf = {};
    io_conf.pin_bit_mask = (1ULL <<Intr_GPIO);
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.intr_type = GPIO_INTR_NEGEDGE;
    io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
    gpio_config(&io_conf);
    
}
The task:

Code: Select all

void task_SPIsampler(void *pvParameters) {
    
    while (1) {
        for (int i = 0; i < PacketSize; i++){

            xSemaphoreTake(sem_mutex, portMAX_DELAY);  // Wait for DRDY interrupt

            gpio_set_level(CS_PIN, 0);
         spi_transaction_t t;
            memset(&t, 0, sizeof(t));
            t.length = 24;  
            t.tx_buffer = NULL;
            t.rx_buffer = &(SPI_data[buffer_index]);
            spi_device_transmit(spi, &t);
            gpio_set_level(CS_PIN, 1);
            buffer_index += 3;          
        }
            // Send data over UDP
            ESP_LOGI("UDP", "packet is ready");
            //will send to UDP
            ESP_LOGI("UDP", "sent");
            buffer_index = 0;

        }        
}
and the app_main() is:

Code: Select all

void app_main() {
    esp_err_t ret = nvs_flash_init();
    ESP_ERROR_CHECK(ret);

    sem_mutex = xSemaphoreCreateMutex();
    ESP_ERROR_CHECK(gpio_install_isr_service(0));

    initialize_IntrGPIO();
    
    configure_spi();

    gpio_intr_enable(Intr_GPIO); 
    gpio_isr_handler_add(Intr_GPIO, GOPIisr_handler, (void*)0);
    
    xTaskCreate(task_SPIsampler, "task_SPIsampler", configMINIMAL_STACK_SIZE + 8192, NULL, 2, NULL);
}

The problem is that if there is no interrupt on the pin, the code just sits there waiting for the interrupt. However, as soon as it sees a falling edge on Intr_GPIO, the code exits without an error message.
I have no idea what is going on and why would it exit without a warning or a message.

Kind regards
Ssk

Re: ISR and semaphore not working

Posted: Thu Mar 07, 2024 3:03 am
by ESP_Sprite
What specifically do you mean with 'exits'?

Re: ISR and semaphore not working

Posted: Thu Mar 07, 2024 7:49 am
by ssklive
It immediately restarts and does nothing.

Re: ISR and semaphore not working

Posted: Thu Mar 07, 2024 8:35 am
by ESP_Sprite
Hm, on initial glance I see nothing wrong with your code. Can you pin down a bit more what causes the restarts? For instance, does it still do that when you comment out the spi_device_transmit, or the xSemaphoreGiveFromISR?