Skip to content

Commit b18b64b

Browse files
committed
rp2/machine_uart.c: Add an IRQ_BREAK event for UART.irq().
Just for test. Properties: - After a BREAK, a valid character must be received before another break can be detected. - Each break puts a 0xff character into the input buffer. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent 1aa5e31 commit b18b64b

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

ports/rp2/machine_uart.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
#define UART_HWCONTROL_CTS (1)
8282
#define UART_HWCONTROL_RTS (2)
8383
// OR-ed IRQ flags which are allowed to be used by the user
84-
#define MP_UART_ALLOWED_FLAGS (UART_UARTMIS_RTMIS_BITS | UART_UARTMIS_TXMIS_BITS)
84+
#define MP_UART_ALLOWED_FLAGS (UART_UARTMIS_RTMIS_BITS | UART_UARTMIS_TXMIS_BITS | UART_UARTMIS_BEMIS_BITS)
8585
#define UART_FIFO_SIZE_RX (32)
8686
#define UART_FIFO_TRIGGER_LEVEL_RX (UART_FIFO_SIZE_RX / 2)
8787

@@ -198,20 +198,24 @@ static void uart_fill_tx_fifo(machine_uart_obj_t *self) {
198198
static inline void uart_service_interrupt(machine_uart_obj_t *self) {
199199
self->mp_irq_flags = uart_get_hw(self->uart)->mis & (UART_UARTMIS_RXMIS_BITS | UART_UARTMIS_RTMIS_BITS);
200200
if (self->mp_irq_flags) { // rx interrupt?
201-
// clear all interrupt bits but tx
202-
uart_get_hw(self->uart)->icr = UART_UARTICR_BITS & (~UART_UARTICR_TXIC_BITS);
201+
// clear all interrupt bits but tx and break
202+
uart_get_hw(self->uart)->icr = UART_UARTICR_BITS & ~(UART_UARTICR_TXIC_BITS | UART_UARTICR_BEIC_BITS);
203203
uart_drain_rx_fifo(self, UART_FIFO_TRIGGER_LEVEL_RX - 1);
204204
}
205205
if (uart_get_hw(self->uart)->mis & UART_UARTMIS_TXMIS_BITS) { // tx interrupt?
206-
// clear all interrupt bits but rx
207-
uart_get_hw(self->uart)->icr = UART_UARTICR_BITS & ~(UART_UARTICR_RXIC_BITS | UART_UARTICR_RTIC_BITS);
206+
// clear all interrupt bits but rx and break
207+
uart_get_hw(self->uart)->icr = UART_UARTICR_BITS & ~(UART_UARTICR_RXIC_BITS | UART_UARTICR_RTIC_BITS | UART_UARTICR_BEIC_BITS);
208208
if (ringbuf_avail(&self->write_buffer) == 0) {
209209
self->mp_irq_flags |= UART_UARTMIS_TXMIS_BITS;
210210
} else {
211211
uart_fill_tx_fifo(self);
212212
}
213213
}
214-
214+
if (uart_get_hw(self->uart)->mis & UART_UARTMIS_BEMIS_BITS) { // break interrupt?
215+
// CLear the event
216+
hw_set_bits(&uart_get_hw(self->uart)->icr, UART_UARTICR_BEIC_BITS);
217+
self->mp_irq_flags |= UART_UARTMIS_BEMIS_BITS;
218+
}
215219
// Check the flags to see if the user handler should be called
216220
if (self->mp_irq_trigger & self->mp_irq_flags) {
217221
mp_irq_handler(self->mp_irq_obj);
@@ -236,6 +240,7 @@ static void uart1_irq_handler(void) {
236240
{ MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \
237241
{ MP_ROM_QSTR(MP_QSTR_IRQ_RXIDLE), MP_ROM_INT(UART_UARTMIS_RTMIS_BITS) }, \
238242
{ MP_ROM_QSTR(MP_QSTR_IRQ_TXIDLE), MP_ROM_INT(UART_UARTMIS_TXMIS_BITS) }, \
243+
{ MP_ROM_QSTR(MP_QSTR_IRQ_BREAK), MP_ROM_INT(UART_UARTMIS_BEMIS_BITS) }, \
239244

240245
static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
241246
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -429,6 +434,9 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
429434

430435
// Enable the uart irq; this macro sets the rx irq level to 4.
431436
uart_set_irq_enables(self->uart, true, true);
437+
// Enable the break Interrupt
438+
hw_write_masked(&uart_get_hw(self->uart)->imsc, 1 << UART_UARTIMSC_BEIM_LSB,
439+
UART_UARTIMSC_BEIM_BITS);
432440
// Set the RX trigger level to FIFO_size / 2
433441
hw_write_masked(&uart_get_hw(self->uart)->ifls, 0b010 << UART_UARTIFLS_RXIFLSEL_LSB,
434442
UART_UARTIFLS_RXIFLSEL_BITS);

0 commit comments

Comments
 (0)