Hi all,
For a project I need to start a SPI master transfer from a ISR. There are 2 devices on the bus and it is oke to wait for a transfer of the other device to complete. So spi_device_queue_trans should do the trick. Transfers to these devices are not synchronized and use a limited bandwidth of the spi bus.
A transfer to a device is a kind of trigger for doing a analog/digital conversion. And should be done with as liitle jitter as possible (but waiting for a transfer of the other device is oke).
And yes, it works with spi_device_queue_trans in a ISR (and transfer functions in IRAM).
But: spi_device_queue_trans is using the xQueueSend function from the FreeRTOS and this should not be called from an ISR.
So, it is asking for trouble.
Is there another way?
Best,
Erik Claij
SPI master starting transfer for ISR
-
- Posts: 9708
- Joined: Thu Nov 26, 2015 4:08 am
Re: SPI master starting transfer for ISR
The canonical way would be use a semaphore or something that wakes a (in your case super-high-priority) task, which then will send the SPI transfer.
Re: SPI master starting transfer for ISR
Hi ESP_Sprite,
Thank you for your response.
Yes that would be some kind of a solution. But with 1 ms timing and other important things to do it is getting difficult. The other way is a combination of vTaskSuspend() and vTaskResume(). This is probably a little faster.
Would it be possible to just change the xQueueSend() function in spi_device_queue_trans() to xQueueSendFromISR()? But maybe other things can block this. Maybe I'am going to fork the esp-idf and try some things out. Like using the ISR version if ticks_to_wait is zero. Some function in spi_master.c are static so not usable from user program.
Or maybe write something to put data directly into queue?
But I don't like the idea of adapting the IDF.
Best,
Erik
Thank you for your response.
Yes that would be some kind of a solution. But with 1 ms timing and other important things to do it is getting difficult. The other way is a combination of vTaskSuspend() and vTaskResume(). This is probably a little faster.
Would it be possible to just change the xQueueSend() function in spi_device_queue_trans() to xQueueSendFromISR()? But maybe other things can block this. Maybe I'am going to fork the esp-idf and try some things out. Like using the ISR version if ticks_to_wait is zero. Some function in spi_master.c are static so not usable from user program.
Or maybe write something to put data directly into queue?
But I don't like the idea of adapting the IDF.
Best,
Erik
-
- Posts: 9708
- Joined: Thu Nov 26, 2015 4:08 am
Re: SPI master starting transfer for ISR
Are you sure about the time it takes? A semaphore may not sound like the most efficient way (and it's not, things like task notifications seemingly are quicker), but on a fast CPU like the ESP32 it certainly is not 1ms-order-size slow. E.g. I used it here and I seem to be happily getting a response in the order of 0.02ms.
Re: SPI master starting transfer for ISR
Hi,
Thanks for your response.
No I am not sure it take's a lot of time, but if timing is getting critical you want the best. In my current project I have a very strict timing but with only one device on a SPI bus (and register level coding of the SPI bus). It is amazing how little you need to do to make a low level spi transfer.
So this is fast, but it misses some functionality. The goal is to make a SPI class as fast as the current one but without the register level coding, and allowing more devices on the bus with async transfers.
More deivces and async transfers make strict timing impossible. But it would help if spi_device_queue_trans() was possible from a ISR.
But I will try your idea so I don't have to rewrite the IDF.
Erik
Thanks for your response.
No I am not sure it take's a lot of time, but if timing is getting critical you want the best. In my current project I have a very strict timing but with only one device on a SPI bus (and register level coding of the SPI bus). It is amazing how little you need to do to make a low level spi transfer.
So this is fast, but it misses some functionality. The goal is to make a SPI class as fast as the current one but without the register level coding, and allowing more devices on the bus with async transfers.
More deivces and async transfers make strict timing impossible. But it would help if spi_device_queue_trans() was possible from a ISR.
But I will try your idea so I don't have to rewrite the IDF.
Erik
Who is online
Users browsing this forum: No registered users and 61 guests