Yeah, it’s not a feature exposed in Python. The RT1062 does have this exposed in Python.
You can manually set the bit to invert the TX/RX polarities though via the stm.mem32[] operation. Import the stm module. You can also do memory access via the machine module.
See the reference manual for the STM32H743VIT6, section 48.8.3, USART control register 2 (USART_CR2).
You’ll need to compute the base address of the peripheral and then add the register offset to that base address, and then you can turn tx/rx inversion on. You’ll want to do this after initializing the peripheral in python.
The base address can be found in section, 2.3.2. Scroll down until you see the USART you are controlling. Note, you need to know which UART you are setting up which will be in the constructor call to it.
Thanks for the super quick reply! Exceptional customer service!
Unfortunately, I have not yet been able to test your suggestion, as I turned my camera into a brick Well … I can upload the new boot loader … but then still does not work. I’ll post a new post for this, so that the forum stays easily searchable.
I’ll get back to you on the invert UART aspect soon as I’ll be doing at least conceptual implementation today.
USART_CR2 is a register in the specific UART. It’s not the UART peripheral itself.
The particular UART you are using is based on the number you passed to pyb.UART() when you were constructing the object. I don’t know if its the USART1 or UART1. One of them if you try to modify won’t work and will probably crash the system. So, don’t save the script to the OpenMV Cam until you figure out which one. If the peripheral is not initialized, then writing to its register space will cause a processor exception, leading to a system reset.
Anyway, just try both and one should work (talking about the USART or UART base address).
…
It looks like there’s only USART1. So, try that base address.
Thank you for your help so far!
I am getting closer in the SBus protocol …
I should not have started from the existing code, I found online … because I believe it is fundamentally flawed.
They do not take into consideration that the package come in burst:
3 ms data, 6 ms silence, 3 ms data, 6 ms silence …
And this is the primary way of finding the start and end of a package (not scanning for package HEADER or FOOTER in the concatinated stream of data, which does not take into account timing).
All that is needed, is an interrupt or timer, that listens for ‘silence’ on the uart rx.
...
poll_data_bound = partial_method(self.poll_data, self)
timProve = pyb.Timer(2)
timProve.init(period=1, callback=poll_data_bound) # every 1ms
...
def poll_data(self): # must be called every 1 millisecond
if self.uart.any() > 0:
self.readBytes += self.uart.read()
self.last_frame_received_ticks_ms = time.ticks_ms()
if self.readBytes[0] == 0x0F and self.readBytes[24] == 0x00:
self.lastFrame = self.readBytes
self.readBytes = bytearray()
if self.last_frame_received_ticks_ms is None or time.ticks_diff(time.time_ms(), self.last_frame_received_ticks_ms) > 3:
# Clear buffer if no data received for 3 ms
# SBUS is expected to come in frames, and then silence
# 3ms of data, 6ms of silence, 3ms of data, 6ms of silence, ...
self.readBytes = bytearray()
Am I allowed to do a ‘heavy’ operation, such as reading uart, or dynamically, allocating structures in a timer or interupt call back? Is my approach acceptable way, to use the timing information on the bus?
You can’t allocate memory in timer callbacks. You are allowed to read data from the UART through and write it to a buffer. As long as you don’t create any new objects you are fine.
So, the setting the readBytes to bytearray() is something you’d want to avoid as this is clearing an object. Maybe instead use a variable to signal state like a length variable. Also, keep the readBytes array fixed in size. You can use readInto or just manual set bytes in it to avoid any memory allocations.
The reason for not being able to allocate memory is that the heap isn’t reentrant. The timer callback is an interrupt.