@freddydw @ptillisch - side note, most other boards I have worked with in the past will allow you to do things like Serial.write ... inside of things like interrupts.
They allow it, as the data you write out is typically put into a buffer that will be transferred later. The main exception to this is when you completely fill up the transfer buffers. Which I believe is why Arduino addeded the availableForWrite() method:
Serial.availableForWrite() - Arduino Reference
Unfortunately in some of the more recent core implementations, Arduino has not implemented and/or used buffered serial output...
I could be wrong, but I don't belite this is also totally accurate. That is the STM32H7 processors have a Nested Vectored Interrupt Controller (NVIC) (Chapter 20 of the RM). So unless something unusual has been setup, a higher priority Interrupt ( I believe lower numbers have higher priority).
16 programmable priority levels (4 bits of interrupt priority are used)
The RM does not give a whole lot of details on the NVIC, but refer you to reference manuals for M7 and M4 processros.
You will find some places in the code that update some interrupts to their non-default priority, for example in the camera library:
NVIC_SetPriority(DCMI_DMA_IRQ, DCMI_DMA_IRQ_PRI);
HAL_NVIC_EnableIRQ(DCMI_DMA_IRQ);
and the H7 Video (dsi.cpp)
/** @brief NVIC configuration for LTDC interrupt that is now enabled */
HAL_NVIC_SetPriority(LTDC_IRQn, 0x0F, 0);
HAL_NVIC_EnableIRQ(LTDC_IRQn);
/** @brief NVIC configuration for DMA2D interrupt that is now enabled */
HAL_NVIC_SetPriority(DMA2D_IRQn, 0x0F, 0);
HAL_NVIC_EnableIRQ(DMA2D_IRQn);
/** @brief NVIC configuration for DSI interrupt that is now enabled */
HAL_NVIC_SetPriority(DSI_IRQn, 0x0F, 0);
HAL_NVIC_EnableIRQ(DSI_IRQn);
As for Timer interrupts. I know they are doable. When I needed something like that, I cheated and did a quick dirty and instead created a thread, or the like that waited for a timeout.
Specific example: I implemented a USBHost Serial device that implements the buffering and has a timeout, that if the buffer is not filled within a certain time after the last write, it then triggers to flush whatever data it has in the queue.
My object contains an mbed::Timeout object
that when I receive I new output to the queue I reset the timeout timer:
inline void startWriteTimeout() {
writeTO_.attach(mbed::callback(this, &USBHostSerialDevice::processTXTimerCB), std::chrono::microseconds(write_timeout_));}
The timeout callback sends an event to my objects mailbox:
void USBHostSerialDevice::processTXTimerCB() {
USBHostSerialDevice::message_t * serobj_msg = mail_serobj_event.try_alloc();
if (serobj_msg) {
serobj_msg->event_id = LATENCY_TIMEOUT_MSG;
mail_serobj_event.put(serobj_msg);
} else {
startWriteTimeout();
}
}
And the thread that I created for this device is then awakened and process the timeout:
There are probably cleaner/simpler ways to accomplish this. But that is what I using right now.
If you want to see it in more details it is up in:
KurtE/GIGA_USBHostMBed5_devices: Some USB Host device extension to Arduino_USBHostMBed5 library (github.com)
In the USBHostSerialDevice files.
Not sure if that helps you or not.
Good luck