atmel/samd: Support CTRL-C on USB. This won't escape native code but it will cause Python code to stop.
This commit is contained in:
parent
ccb309bd5c
commit
eff137a5f5
|
@ -81,7 +81,43 @@ endif
|
|||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -ggdb
|
||||
else
|
||||
CFLAGS += -Os -DNDEBUG
|
||||
# was -Os
|
||||
CFLAGS += -O1 -ggdb -DNDEBUG
|
||||
# CFLAGS += -O0 \
|
||||
# -ftree-ter \
|
||||
# -ftree-sra \
|
||||
# -ftree-slsr \
|
||||
# -ftree-sink \
|
||||
# -ftree-pta \
|
||||
# -ftree-fre \
|
||||
# -ftree-dse \
|
||||
# -ftree-dominator-opts \
|
||||
# -ftree-dce \
|
||||
# -ftree-copyrename \
|
||||
# -ftree-copy-prop \
|
||||
# -ftree-ch \
|
||||
# -ftree-ccp \
|
||||
# -ftree-bit-ccp \
|
||||
# -fsplit-wide-types \
|
||||
# -fshrink-wrap \
|
||||
# -fsection-anchors \
|
||||
# -fsched-pressure \
|
||||
# -fomit-frame-pointer \
|
||||
# -fmove-loop-invariants \
|
||||
# -fmerge-constants \
|
||||
# -fipa-reference \
|
||||
# -fipa-pure-const \
|
||||
# -fipa-profile \
|
||||
# -finline-functions-called-once \
|
||||
# -fif-conversion \
|
||||
# -fif-conversion2 \
|
||||
# -fguess-branch-probability \
|
||||
# -fforward-propagate \
|
||||
# -fdefer-pop \
|
||||
# -fcprop-registers \
|
||||
# -fcompare-elim \
|
||||
# -fcombine-stack-adjustments \
|
||||
# -fbranch-count-reg
|
||||
endif
|
||||
|
||||
LIBS =
|
||||
|
|
|
@ -34,7 +34,8 @@ extern void mp_cdc_disable(uint8_t port);
|
|||
#define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE
|
||||
#define UDI_CDC_DEFAULT_DATABITS 8
|
||||
|
||||
#define UDI_CDC_RX_NOTIFY(port)
|
||||
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
|
||||
void usb_rx_notify(void);
|
||||
#define UDI_CDC_SET_CODING_EXT(port,cfg)
|
||||
#define UDI_CDC_SET_DTR_EXT(port,set)
|
||||
#define UDI_CDC_SET_RTS_EXT(port,set)
|
||||
|
|
|
@ -34,7 +34,8 @@ extern void mp_cdc_disable(uint8_t port);
|
|||
#define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE
|
||||
#define UDI_CDC_DEFAULT_DATABITS 8
|
||||
|
||||
#define UDI_CDC_RX_NOTIFY(port)
|
||||
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
|
||||
void usb_rx_notify(void);
|
||||
#define UDI_CDC_SET_CODING_EXT(port,cfg)
|
||||
#define UDI_CDC_SET_DTR_EXT(port,set)
|
||||
#define UDI_CDC_SET_RTS_EXT(port,set)
|
||||
|
|
|
@ -59,6 +59,8 @@ int main(int argc, char **argv) {
|
|||
#endif
|
||||
mp_init();
|
||||
|
||||
MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
|
||||
|
||||
pin_init0();
|
||||
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
|
@ -101,6 +103,10 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void mp_keyboard_interrupt(void) {
|
||||
MP_STATE_VM(mp_pending_exception) = MP_STATE_PORT(mp_kbd_exception);
|
||||
}
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ extern const struct _mp_obj_module_t utime_module;
|
|||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8]; \
|
||||
vstr_t *repl_line; \
|
||||
mp_obj_t mp_kbd_exception; \
|
||||
mp_obj_t pin_class_mapper; \
|
||||
mp_obj_t pin_class_map_dict; \
|
||||
|
||||
|
|
|
@ -7,8 +7,29 @@
|
|||
#include "py/mpstate.h"
|
||||
|
||||
#include "mpconfigboard.h"
|
||||
#include "mphalport.h"
|
||||
|
||||
// Store received characters on our own so that we can filter control characters
|
||||
// and act immediately on CTRL-C for example.
|
||||
// This is adapted from asf/thirdparty/wireless/addons/sio2host
|
||||
|
||||
// Receive buffer
|
||||
static uint8_t usb_rx_buf[USB_RX_BUF_SIZE];
|
||||
|
||||
// Receive buffer head
|
||||
static uint8_t usb_rx_buf_head;
|
||||
|
||||
// Receive buffer tail
|
||||
static uint8_t usb_rx_buf_tail;
|
||||
|
||||
// Number of bytes in receive buffer
|
||||
static volatile uint8_t usb_rx_count;
|
||||
|
||||
static volatile bool mp_cdc_enabled = false;
|
||||
|
||||
void mp_keyboard_interrupt(void);
|
||||
int interrupt_char;
|
||||
|
||||
extern struct usart_module usart_instance;
|
||||
|
||||
bool mp_cdc_enable(uint8_t port)
|
||||
|
@ -22,11 +43,71 @@ void mp_cdc_disable(uint8_t port)
|
|||
mp_cdc_enabled = false;
|
||||
}
|
||||
|
||||
void usb_rx_notify(void)
|
||||
{
|
||||
if (mp_cdc_enabled) {
|
||||
while (udi_cdc_is_rx_ready()) {
|
||||
uint8_t c;
|
||||
c = udi_cdc_getc();
|
||||
|
||||
if (c == interrupt_char) {
|
||||
mp_keyboard_interrupt();
|
||||
// Don't put the interrupt into the buffer, just continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Introducing critical section to avoid buffer corruption.
|
||||
cpu_irq_disable();
|
||||
|
||||
// The count of characters present in receive buffer is
|
||||
// incremented.
|
||||
usb_rx_count++;
|
||||
usb_rx_buf[usb_rx_buf_tail] = c;
|
||||
|
||||
if ((USB_RX_BUF_SIZE - 1) == usb_rx_buf_tail) {
|
||||
// Reached the end of buffer, revert back to beginning of
|
||||
// buffer.
|
||||
usb_rx_buf_tail = 0x00;
|
||||
} else {
|
||||
usb_rx_buf_tail++;
|
||||
}
|
||||
|
||||
cpu_irq_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int receive_usb() {
|
||||
if (0 == usb_rx_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (USB_RX_BUF_SIZE <= usb_rx_count) {
|
||||
// Bytes between head and tail are overwritten by new data. The
|
||||
// oldest data in buffer is the one to which the tail is pointing. So
|
||||
// reading operation should start from the tail.
|
||||
usb_rx_buf_head = usb_rx_buf_tail;
|
||||
|
||||
// This is a buffer overflow case.But still only the number of bytes
|
||||
// equivalent to full buffer size are useful.
|
||||
usb_rx_count = USB_RX_BUF_SIZE;
|
||||
}
|
||||
|
||||
// Copy from head.
|
||||
int data = usb_rx_buf[usb_rx_buf_head];
|
||||
usb_rx_buf_head++;
|
||||
usb_rx_count--;
|
||||
if ((USB_RX_BUF_SIZE) == usb_rx_buf_head) {
|
||||
usb_rx_buf_head = 0;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
#ifdef USB_REPL
|
||||
if (mp_cdc_enabled && udi_cdc_is_rx_ready()) {
|
||||
return udi_cdc_getc();
|
||||
if (mp_cdc_enabled && usb_rx_count > 0) {
|
||||
return receive_usb();
|
||||
}
|
||||
#endif
|
||||
#ifdef UART_REPL
|
||||
|
@ -41,10 +122,6 @@ int mp_hal_stdin_rx_chr(void) {
|
|||
}
|
||||
}
|
||||
|
||||
//void mp_hal_stdout_tx_str(const char *str) {
|
||||
// mp_hal_stdout_tx_strn(str, strlen(str));
|
||||
//}
|
||||
|
||||
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
||||
#ifdef UART_REPL
|
||||
usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len);
|
||||
|
@ -57,6 +134,14 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void mp_hal_set_interrupt_char(int c) {
|
||||
if (c != -1) {
|
||||
mp_obj_exception_clear_traceback(MP_STATE_PORT(mp_kbd_exception));
|
||||
}
|
||||
extern int interrupt_char;
|
||||
interrupt_char = c;
|
||||
}
|
||||
|
||||
void mp_hal_delay_ms(mp_uint_t delay) {
|
||||
delay_ms(delay);
|
||||
}
|
||||
|
|
|
@ -1,2 +1,35 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
|
||||
#define __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
|
||||
|
||||
#define USB_RX_BUF_SIZE 128
|
||||
|
||||
static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; }
|
||||
static inline void mp_hal_set_interrupt_char(char c) {}
|
||||
void mp_hal_set_interrupt_char(int c);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
|
||||
|
|
Loading…
Reference in New Issue