|
45 | 45 |
|
46 | 46 | #include "samd/sercom.h"
|
47 | 47 |
|
| 48 | +#include "common-hal/busio/SPI.h" // for never_reset_sercom |
| 49 | + |
48 | 50 | #define UART_DEBUG(...) (void)0
|
49 | 51 | // #define UART_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
|
50 | 52 |
|
@@ -152,16 +154,22 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
152 | 154 |
|
153 | 155 | if (rx && receiver_buffer_size > 0) {
|
154 | 156 | self->buffer_length = receiver_buffer_size;
|
155 |
| - // Initially allocate the UART's buffer in the long-lived part of the |
156 |
| - // heap. UARTs are generally long-lived objects, but the "make long- |
157 |
| - // lived" machinery is incapable of moving internal pointers like |
158 |
| - // self->buffer, so do it manually. (However, as long as internal |
159 |
| - // pointers like this are NOT moved, allocating the buffer |
160 |
| - // in the long-lived pool is not strictly necessary) |
161 |
| - self->buffer = (uint8_t *)gc_alloc(self->buffer_length * sizeof(uint8_t), false, true); |
162 |
| - if (self->buffer == NULL) { |
163 |
| - common_hal_busio_uart_deinit(self); |
164 |
| - mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), self->buffer_length * sizeof(uint8_t)); |
| 157 | + if (NULL != receiver_buffer) { |
| 158 | + self->buffer = receiver_buffer; |
| 159 | + } |
| 160 | + else { |
| 161 | + // Initially allocate the UART's buffer in the long-lived part of the |
| 162 | + // heap. UARTs are generally long-lived objects, but the "make long- |
| 163 | + // lived" machinery is incapable of moving internal pointers like |
| 164 | + // self->buffer, so do it manually. (However, as long as internal |
| 165 | + // pointers like this are NOT moved, allocating the buffer |
| 166 | + // in the long-lived pool is not strictly necessary) |
| 167 | + |
| 168 | + self->buffer = (uint8_t *)gc_alloc(self->buffer_length * sizeof(uint8_t), false, true); |
| 169 | + if (self->buffer == NULL) { |
| 170 | + common_hal_busio_uart_deinit(self); |
| 171 | + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), self->buffer_length * sizeof(uint8_t)); |
| 172 | + } |
165 | 173 | }
|
166 | 174 | } else {
|
167 | 175 | self->buffer_length = 0;
|
@@ -246,6 +254,21 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
246 | 254 | usart_async_enable(usart_desc_p);
|
247 | 255 | }
|
248 | 256 |
|
| 257 | +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { |
| 258 | + for (size_t i = 0; i < MP_ARRAY_SIZE(sercom_insts); i++) { |
| 259 | + const Sercom *sercom = sercom_insts[i]; |
| 260 | + Sercom *hw = (Sercom *)(self->usart_desc.device.hw); |
| 261 | + |
| 262 | + // Reserve pins for active UART only |
| 263 | + if (sercom == hw) { |
| 264 | + never_reset_sercom(hw); |
| 265 | + never_reset_pin_number(self->rx_pin); |
| 266 | + never_reset_pin_number(self->tx_pin); |
| 267 | + } |
| 268 | + } |
| 269 | + return; |
| 270 | +} |
| 271 | + |
249 | 272 | bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
|
250 | 273 | return self->rx_pin == NO_PIN && self->tx_pin == NO_PIN;
|
251 | 274 | }
|
|
0 commit comments