Commit Graph

24 Commits

Author SHA1 Message Date
robert-hh
4dfee50a0b samd/machine_uart: Fix lock-up in loopback mode if read buffer is full.
Signed-off-by: robert-hh <robert@hammelrath.com>
2025-03-27 11:39:02 +11:00
robert-hh
6db7b47ab9 samd/machine_uart: Fix unintended UART buffer allocation on init().
The buffer was be reset on every call to uart.init().  If no sizes were
given, the buffer was set to the default size 256.  That made problems
e.g. with PPP.

This commit fixes it, keeping the buffer size if not deliberately changed
and allocating new buffers only if the size was changed.  Cater for changes
of the bits value, which requires a change to the buffer size.

Signed-off-by: robert-hh <robert@hammelrath.com>
2025-03-27 11:38:31 +11:00
robert-hh
daef1c1d14 samd/machine_uart: Support default instance and TX/RX pin values.
If a board configures a default UART instance and/or TX/RX pins then the
user can create a default UART object using `machine.UART()`.

Signed-off-by: robert-hh <robert@hammelrath.com>
2025-03-03 10:59:26 +11:00
robert-hh
5a70850b30 samd/machine_uart: Add full support for 9-bit data.
Prior to this commit, 9-bit UART data could be specified in the constructor
and was transmitted, but the 9th bit was set to 0 when sending, and ignored
when receiving.  This commit completes 9-bit support in that the 9th bit is
taken from the data.

9-bit data has to be provided with `uart.write()` and and read with
`uart.read()` as two bytes for each transmitted item, low order byte first.
The data length supplied with `uart.write()` and requested by `uart.read()`
has to be even, which is checked.  The size of the UART buffers will be
transparently doubled to cater for 9-bit data.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-11-18 23:05:46 +11:00
robert-hh
ef69d0f2d3 samd/machine_uart: Implement UART.IRQ_RXIDLE based on the softtimer.
With the softtimer the minimal delay between the end of a message and the
trigger is 2 ms.  For baud rates <= 9600 baud it's three character times.
Tested with baud rates up tp 115200 baud.  The timer used for RXIDLE is
running only during UART receive, saving execution cycles when the timer is
not needed.

The irq.flags() value is changed only with an expected event.  Do not
change it otherwise.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-08-29 16:27:43 +10:00
robert-hh
8e1123b25b samd/machine_uart: Implement a Python UART IRQ handler.
Supported for all SAMD51 devices and SAMD21 with external flash.  For
interrupt events, IRQ_RX and IRQ_TXIDLE are provided.

IRQ_RX is called for every received byte.  This may not be useful for high
data rates, but can be used to build a wrapper class providing an
IRQ_RXIDLE event or to signal just the first byte of a message.

IRQ_TXIDLE is called only when messages are longer than 5 bytes and
triggers when still 5 bytes are due to be sent.

The SAMD hardware does not support implementing IRQ_RXIDLE.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-08-29 16:27:43 +10:00
Angus Gratton
decf8e6a8b all: Remove the "STATIC" macro and just use "static" instead.
The STATIC macro was introduced a very long time ago in commit
d5df6cd44a.  The original reason for this was
to have the option to define it to nothing so that all static functions
become global functions and therefore visible to certain debug tools, so
one could do function size comparison and other things.

This STATIC feature is rarely (if ever) used.  And with the use of LTO and
heavy inline optimisation, analysing the size of individual functions when
they are not static is not a good representation of the size of code when
fully optimised.

So the macro does not have much use and it's simpler to just remove it.
Then you know exactly what it's doing.  For example, newcomers don't have
to learn what the STATIC macro is and why it exists.  Reading the code is
also less "loud" with a lowercase static.

One other minor point in favour of removing it, is that it stops bugs with
`STATIC inline`, which should always be `static inline`.

Methodology for this commit was:

1) git ls-files | egrep '\.[ch]$' | \
   xargs sed -Ei "s/(^| )STATIC($| )/\1static\2/"

2) Do some manual cleanup in the diff by searching for the word STATIC in
   comments and changing those back.

3) "git-grep STATIC docs/", manually fixed those cases.

4) "rg -t python STATIC", manually fixed codegen lines that used STATIC.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-03-07 14:20:42 +11:00
robert-hh
59afeb056a samd/machine_uart: Add machine_uart_set_baudrate() function.
Changing the baudrate requires a complete re-configuration of the Sercom
device, which is put into a separate rather large function.  This new
machine_uart_set_baudrate() function will be useful for future drivers such
as Bluetooth.

Signed-off-by: robert-hh <robert@hammelrath.com>
2023-11-06 11:10:11 +11:00
Jim Mussared
4d568a5bd7 samd/boards/make-pins.py: Update to use tools/boardgen.py.
This replaces the previous make-pin-table.py with an implementation based
on boardgen.py.

- MICROPY_PY_MACHINE_PIN_BOARD_CPU macro is removed. This isn't optional
  on other ports, so no need for it to be optional on SAMD.
- pin_af_table is removed, and lookups just search the cpu dict instead
  (this saves N*wordsize bytes of firmware size to have this extra table).
- pins.csv is now BOARD,CPU to match other ports.

This work was funded through GitHub Sponsors.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2023-11-03 14:18:32 +11:00
Damien George
5b4a2baff6 extmod/machine_uart: Factor ports' UART Python bindings to common code.
This is a code factoring to have the Python bindings in one location, and
all the ports use those same bindings.  For all ports except the two listed
below there is no functional change.

The nrf port has UART.sendbreak() removed, but this method previously did
nothing.

The zephyr port has the following methods added:
- UART.init(): supports setting timeout and timeout_char.
- UART.deinit(): does nothing, just returns None.
- UART.flush(): raises OSError(EINVAL) because it's not implemented.
- UART.any() and UART.txdone(): raise NotImplementedError.

Signed-off-by: Damien George <damien@micropython.org>
2023-10-26 10:46:42 +11:00
robert-hh
20fd22edad samd/machine_uart: Add support for UART hardware flow control.
By specifying rts=pin(x) and/or cts=Pin(x) in the constructor.  The pad
numbers for the UART pins are fix in this case: TX must be at pad 0, RX at
pad 1, RTS at pad 2 and CTS at pad 3.

repr(uart) shows the pin names for rts and cts, if set.  In case of a RX
overflow, the rx interrupt will be disabled instead of just discarding the
data.  That allows RTS to act.

If RTS is inactive, still 2 bytes can be buffered in the FIFO.

Signed-off-by: robert-hh <robert@hammelrath.com>
2023-05-23 09:53:24 +10:00
robert-hh
47fa723586 samd/modmachine: Make some machine classes configurable by #defines.
These include ADC, DAC, I2C, SoftI2C, SPI, SoftI2C, PWM, UART, pulse.  This
is useful for devices like the Adafruit Trinket series which have almost no
accessible GPIO pins.

Signed-off-by: robert-hh <robert@hammelrath.com>
2023-05-22 18:39:07 +10:00
Damien George
b1229efbd1 all: Fix spelling mistakes based on codespell check.
Signed-off-by: Damien George <damien@micropython.org>
2023-04-27 18:03:06 +10:00
robert-hh
a73dcb3d22 samd/machine_uart: Fix uart.deinit() and save some RAM.
Changes in this commit:
- Do not deinit IRQ when uart.deinit() is called with an inactive object.
- Remove using it for the finaliser.  There is another machanism for soft
  reset, and it is not needed otherwise.
- Do not tag the UART buffers with MP_STATE_PORT, it is not required.
2022-12-14 12:46:20 +11:00
robert-hh
f78dd25a2c samd/machine_uart: Check the UART TX pin assignment.
Check, if TX is at Pad 0 (SAMD51), or Pad 0 or 2 (SAMD21).
2022-12-14 12:45:51 +11:00
robert-hh
5b1fd8802a samd/machine_uart: Simplify machine_uart_any() and machine_uart_read().
Remove the call to uart_drain_rx_fifo().  It is not required, and may cause
a race condition.
2022-12-14 12:43:34 +11:00
robert-hh
4199f986ad samd/machine_uart: Fix IRQ flag setting and clearing.
Clearing the DRE flag for the transmit interrupt at the end of a
uart.write() also cleared the RXC flag disabling the receive interrupt.

This commit also changes the flag set/clear mechanism in the driver for SPI
as well, even if it did not cause a problem there.  But at least it saves a
few bytes of code.
2022-12-14 12:42:34 +11:00
robert-hh
a1eebc507e samd/machine_spi: Register SerCom objects as root pointers.
Protect SerCom (UART, SPI, I2C) objects from getting freed by the GC when
they go out of scope without being deinitialized.  Otherwise the ISR of a
Sercom may access an invalid data structure.
2022-10-25 23:48:37 +11:00
robert-hh
9c2bc379f1 samd/machine_uart: Use a finaliser to tidy up UART on soft reset.
And use the common sercom_table, saving a few bytes of RAM.
2022-10-25 23:44:49 +11:00
robert-hh
2251cb774b samd/machine_uart: Implement uart.txdone() and uart.flush().
Using the stream method for uart.flush().

uart.txdone() returns True, if the uart not busy, False otherwise.

uart.flush() waits until all bytes have been transmitted or a timeout
triggers.  The timeout is determined by the buffer size and the baud rate.

Also fix two inconsistencies when not using txbuf:
- Report in ioctl as being writeable if there is room in the tx buffer,
  only if it is configured.
- Print the txbuf size if configured.
2022-10-25 23:11:57 +11:00
robert-hh
d9338aabc5 samd: Change the symbol names for the peripheral clocks.
From APB_FREQ to DFLL48M_FREQ, and from apb_freq to peripheral_freq.
2022-10-06 23:10:08 +11:00
robert-hh
9a567b04e7 samd/machine_uart: Support buffered TX for UART.
It can be enabled/disabled by a configuration switch.  The code size
increase is 308 bytes, but it requires RAM space for buffers, the larger
UART object and root pointers.
2022-10-06 22:57:37 +11:00
robert-hh
3625388d8c samd/samd_isr: Change the way a Sercom ISR is registered and called.
Code size diff: +12 Bytes
BSS diff: -12 Bytes
RAM usage: +16 Bytes
Speed increase: a few clock cycles per call
Style improvement: ++
2022-10-06 22:52:10 +11:00
robert-hh
b33f204529 samd/machine_uart: Add the machine.UART class.
All board pins that have UART's assigned can be used.  Baud rate range is
75 Baud to ~2 MBaud.

No flow control yet, and only RX is buffered.  TX buffer and flow control
may be added later for SAMD51 with its larger RAM and Flash.
2022-10-06 22:48:12 +11:00