← index #1642PR #3854
Related · high · value 0.273
QUERY · ISSUE

stm32: Implement Asynchronous UART TX

openby ryannathansopened 2015-11-24updated 2018-02-17
enhancementport-stm32

I am attempting to write large blocks (eg: 2048 bytes) of data to the UART at low baudrates whilst attempting to execute other code. I've discovered that the UART TX is actually blocking until the write is completed. This is a bit of a pain...

This issue is for creating an asynchronous write option for UART. Related to #1533

Probably either interrupt or DMA driven. Should ideally behave like the UART RX does, with a definable buffer in python code, or block as it currently does.

Reading related issues it seems like #1422 has had some success using DMA. Personally, I don't require the callback as I'm not streaming from a file, just an existing bytearray in memory.

I haven't had a chance to read the huge threads on some of the issues I've found so I'm not 100% up to date yet...

CANDIDATE · PULL REQUEST

[ports/stm32]: Added generic MP IRQ callback and example for UART.

closedby tobbadopened 2018-06-10updated 2018-07-22

Reworked see #3971

Aim of PR

At several locations in the stm32/port (maybe in other ports too) there is a call from the interrupt context to a user defined micropython routine/method. As a result we have some duplicated code (see Handle_EXTI_Irq, timer_handle_irq_channel) and some ToDo (se eg. pin_irq method). Further the way in timer the callback is set-up should be unified to the way it is done elsewhere.

There are some discussions in the forum on this topic(Event/IRQ callback):
https://forum.micropython.org/viewtopic.php?f=2&t=1448
https://forum.micropython.org/viewtopic.php?f=6&t=4414
https://forum.micropython.org/viewtopic.php?f=6&t=1312
https://forum.micropython.org/viewtopic.php?f=2&t=194

Issues #1642 and the discussion in the Hardware API (https://github.com/micropython/micropython/wiki/Hardware-API) on IRQ

My proposed MP irq module tries to keep close to the API of pin.irq.

Example implementation of IDLE IRQ for UART

See implementation in the 2nd commit. To use this feature create a class:

import micropython

class UART_IDLE:
    
    def __init__(self, uart):
        self._uart = uart
        self._uart.write("Hi there\n\r")
        self._buffer = bytearray(64)
        self._answer = b"Ready \r\n"
        self._normal_context_ref = self.normal_context
        
    def set_up_cb(self):
        self._uart.irq(self.irq_idle_callback, self._uart.RX_IDLE_IRQ)
        
    def irq_idle_callback(self, other):
        print("IRQ ", self._uart.irq().flags())
        micropython.schedule(self._normal_context_ref, 0)
    
    def normal_context(self, value):
        print("Get UART data in normal context")
        cnt=self._uart.readinto(self._buffer)
        data = "".join([chr(i) if 32<=i<128 else "."  for i in self._buffer[:cnt] ])
        self._uart.write("Received: \"%s\"\r\n" % data)
    

and instantiate it:

uart = pyb.UART(2, baudrate = 115200, timeout=1)
dut=UART_IDLE(uart)
dut.set_up_cb()
callback= uart.irq()
callback()    # call the callback
print("Trigger flag %d " % uart.irq().trigger()) # Print active set triggers

The idle callback is fired on my L476Disco every time when after the start of a transfer there is no data on the UART RX for one character.

Cons

I know that @Damien once said he does not like the idea (https://forum.micropython.org/viewtopic.php?f=17&t=3747&p=21669&hilit=Event+callback#p21669). However we would like to have a fast reacting system which returns within a few ms an answer on the UART. I could imaging as well to automatically schedule the callback in the normal context (as in the class shown with micropython.schedule) but within the C code (Don't know yet how to do it, but it is probably possible).

@dhylands (https://forum.micropython.org/viewtopic.php?f=2&t=194&p=825&hilit=IRQ+callback#p925)

I would be happy for any feedback to improve this PR to make it merge-able.

Further steps

I would be glad to adapt other (can, timer .. which?) modules with this modification.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied