static int call_dupterm_read(void) { if (MP_STATE_PORT(term_obj) == NULL) { return -1; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_obj_t readinto_m[3]; mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_readinto, readinto_m); readinto_m[2] = MP_STATE_PORT(dupterm_arr_obj); mp_obj_t res = mp_call_method_n_kw(1, 0, readinto_m); if (res == mp_const_none) { nlr_pop(); return -2; } if (res == MP_OBJ_NEW_SMALL_INT(0)) { mp_uos_deactivate("dupterm: EOF received, deactivating\n", MP_OBJ_NULL); nlr_pop(); return -1; } mp_buffer_info_t bufinfo; mp_get_buffer_raise(MP_STATE_PORT(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ); nlr_pop(); if (*(byte*)bufinfo.buf == interrupt_char) { mp_keyboard_interrupt(); return -2; } return *(byte*)bufinfo.buf; } else { mp_uos_deactivate("dupterm: Exception in read() method, deactivating: ", nlr.ret_val); } return -1; }
// Call this function to raise a pending exception during an interrupt. // It will first try to raise the exception "softly" by setting the // mp_pending_exception variable and hoping that the VM will notice it. // If this function is called a second time (ie with the mp_pending_exception // variable already set) then it will force the exception by using the hardware // PENDSV feature. This will wait until all interrupts are finished then raise // the given exception object using nlr_jump in the context of the top-level // thread. void pendsv_kbd_intr(void) { if (MP_STATE_VM(mp_pending_exception) == MP_OBJ_NULL) { mp_keyboard_interrupt(); } else { MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; pendsv_object = &MP_STATE_VM(mp_kbd_exception); SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; } }
void uart_rx_irq(void) { if (!ubit_serial.readable()) { return; } int c = ubit_serial.getc(); if (c == mp_interrupt_char) { mp_keyboard_interrupt(); } else { uint16_t next_head = (uart_rx_buf_head + 1) % UART_RX_BUF_SIZE; if (next_head != uart_rx_buf_tail) { // only store data if room in buf uart_rx_buf[uart_rx_buf_head] = c; uart_rx_buf_head = next_head; } } }