atmel-samd: Support ampy get and fix USB dropping characters.
Fixes #2.
This commit is contained in:
parent
33b796ed3a
commit
0e1fd9a12c
@ -160,6 +160,11 @@ SRC_C = \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c
|
||||
|
||||
STM_SRC_C = $(addprefix stmhal/,\
|
||||
pybstdio.c \
|
||||
input.c \
|
||||
)
|
||||
|
||||
# TODO(tannewt): Use this sed line to extract the RST docs from these sources:
|
||||
# sed': sed -n 's+^//|++p' ../api/machine.c
|
||||
#
|
||||
@ -176,9 +181,10 @@ SRC_AUTOGEN = \
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_ASF:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_AUTOGEN:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_BINDINGS_EXPANDED:.c=.o))
|
||||
|
||||
SRC_QSTR += $(SRC_C) $(SRC_BINDINGS_EXPANDED)
|
||||
SRC_QSTR += $(SRC_C) $(SRC_BINDINGS_EXPANDED) $(STM_SRC_C)
|
||||
|
||||
all: $(BUILD)/firmware.bin
|
||||
|
||||
|
@ -27,7 +27,8 @@
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
//#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL)
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
|
||||
#define MICROPY_PY_ASYNC_AWAIT (0)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
|
||||
@ -71,6 +72,8 @@
|
||||
#define MICROPY_HW_ENABLE_DAC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (1)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (1)
|
||||
#define MICROPY_PY_SYS_STDFILES (1)
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
|
@ -18,10 +18,10 @@
|
||||
static uint8_t usb_rx_buf[USB_RX_BUF_SIZE];
|
||||
|
||||
// Receive buffer head
|
||||
static uint8_t usb_rx_buf_head;
|
||||
static volatile uint8_t usb_rx_buf_head;
|
||||
|
||||
// Receive buffer tail
|
||||
static uint8_t usb_rx_buf_tail;
|
||||
static volatile uint8_t usb_rx_buf_tail;
|
||||
|
||||
// Number of bytes in receive buffer
|
||||
static volatile uint8_t usb_rx_count;
|
||||
@ -46,25 +46,26 @@ void mp_cdc_disable(uint8_t port)
|
||||
|
||||
void usb_rx_notify(void)
|
||||
{
|
||||
irqflags_t flags;
|
||||
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;
|
||||
// Introduce a critical section to avoid buffer corruption. We use
|
||||
// cpu_irq_save instead of cpu_irq_disable because we don't know the
|
||||
// current state of IRQs. They may have been turned off already and
|
||||
// we don't want to accidentally turn them back on.
|
||||
flags = cpu_irq_save();
|
||||
// If our buffer is full, then don't get another character otherwise
|
||||
// we'll lose a previous character.
|
||||
if (usb_rx_count >= USB_RX_BUF_SIZE) {
|
||||
cpu_irq_restore(flags);
|
||||
break;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
uint8_t current_tail = usb_rx_buf_tail;
|
||||
// Pretend we've received a character so that any nested calls to
|
||||
// this function have to consider the spot we've reserved.
|
||||
if ((USB_RX_BUF_SIZE - 1) == usb_rx_buf_tail) {
|
||||
// Reached the end of buffer, revert back to beginning of
|
||||
// buffer.
|
||||
@ -72,35 +73,53 @@ void usb_rx_notify(void)
|
||||
} else {
|
||||
usb_rx_buf_tail++;
|
||||
}
|
||||
// The count of characters present in receive buffer is
|
||||
// incremented.
|
||||
usb_rx_count++;
|
||||
// WARNING(tannewt): This call can call us back with the next
|
||||
// character!
|
||||
c = udi_cdc_getc();
|
||||
|
||||
cpu_irq_enable();
|
||||
if (c == interrupt_char) {
|
||||
// We consumed a character rather than adding it to the rx
|
||||
// buffer so undo the modifications we made to count and the
|
||||
// tail.
|
||||
usb_rx_count--;
|
||||
usb_rx_buf_tail = current_tail;
|
||||
cpu_irq_restore(flags);
|
||||
mp_keyboard_interrupt();
|
||||
// Don't put the interrupt into the buffer, just continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
// We put the next character where we expected regardless of whether
|
||||
// the next character was already loaded in the buffer.
|
||||
usb_rx_buf[current_tail] = c;
|
||||
|
||||
cpu_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int receive_usb() {
|
||||
if (0 == usb_rx_count) {
|
||||
if (usb_rx_count == 0) {
|
||||
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.
|
||||
cpu_irq_disable();
|
||||
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;
|
||||
}
|
||||
cpu_irq_enable();
|
||||
|
||||
// Call usb_rx_notify if we just emptied a spot in the buffer.
|
||||
if (usb_rx_count == USB_RX_BUF_SIZE - 1) {
|
||||
usb_rx_notify();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user