diff --git a/stm/lib/usb_dcd_int.c b/stm/lib/usb_dcd_int.c index 32984e610..abdb686c6 100644 --- a/stm/lib/usb_dcd_int.c +++ b/stm/lib/usb_dcd_int.c @@ -675,6 +675,16 @@ static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) ep->xfer_buff += len; ep->xfer_count += len; + // this code turns off the "empty interrupt" + // without it the USB is subject to perpetual interrupts + // see my.st.com, "Yet another STM32F105/7 USB OTG driver issue (VCP device)" + // this code might also work if put in DCD_HandleInEP_ISR + if (ep->xfer_count >= ep->xfer_len) { + uint32_t fifoemptymsk = 1 << ep->num; + USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); + break; + } + txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS); } diff --git a/stm/lib/usbd_cdc_vcp.c b/stm/lib/usbd_cdc_vcp.c index b7330d9f6..985b0b4fd 100644 --- a/stm/lib/usbd_cdc_vcp.c +++ b/stm/lib/usbd_cdc_vcp.c @@ -212,7 +212,8 @@ static uint16_t VCP_DataTx (const uint8_t* Buf, uint32_t Len) * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL */ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) { - //printf("%.*s", (int)Len, Buf); + extern void usb_vcp_receive(uint8_t *buf, uint32_t len); + usb_vcp_receive(Buf, Len); return USBD_OK; } diff --git a/stm/lib/usbd_pyb_core.c b/stm/lib/usbd_pyb_core.c index 5d6e6d9b9..f388361aa 100644 --- a/stm/lib/usbd_pyb_core.c +++ b/stm/lib/usbd_pyb_core.c @@ -73,7 +73,8 @@ #include "usbd_msc_bot.h" #include "usbd_msc_mem.h" -#define USB_PYB_CONFIG_DESC_SIZ (98) +#define USB_PYB_CONFIG_DESC_SIZ (98) // for both CDC VCP and MSC interfaces +//#define USB_PYB_CONFIG_DESC_SIZ (67) // for only CDC VCP interfaces #define MSC_EPIN_SIZE MSC_MAX_PACKET #define MSC_EPOUT_SIZE MSC_MAX_PACKET diff --git a/stm/main.c b/stm/main.c index 90421d598..660f42cb3 100644 --- a/stm/main.c +++ b/stm/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -182,6 +183,80 @@ static void board_info() { } } +char *readline(const char *prompt) { + printf("a\n"); + led_state(PYB_LED_R1, 1); + printf("b\n"); + usb_vcp_send_str(prompt); + for (;;) { + printf("c\n"); + led_state(PYB_LED_R2, 1); + char c = usb_vcp_rx_get(); + led_state(PYB_LED_R2, 0); + usb_vcp_send_strn(&c, 1); + led_state(PYB_LED_G1, 1); + sys_tick_delay_ms(100); + led_state(PYB_LED_G1, 0); + } + return NULL; +} + +extern char rx_buf[]; +extern int rx_buf_out; +void do_repl() { + int i = 0; + for (;;) { + usb_vcp_send_str("Micro Python\r\n"); + printf("%d %d %c\n", i++, usb_vcp_rx_any(), rx_buf[rx_buf_out]); + sys_tick_delay_ms(1000); + } + + for (;;) { + char *line = readline(">>> "); + if (line == NULL) { + // EOF + return; + } + /* + if (is_compound_stmt(line)) { + for (;;) { + char *line2 = readline("... "); + if (line2 == NULL || strlen(line2) == 0) { + break; + } + char *line3 = str_join(line, '\n', line2); + m_free(line); + m_free(line2); + line = line3; + } + } + */ + + py_lexer_str_buf_t sb; + py_lexer_t *lex = py_lexer_new_from_str_len("", line, strlen(line), false, &sb); + py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT); + py_lexer_free(lex); + + if (pn != PY_PARSE_NODE_NULL) { + bool comp_ok = py_compile(pn, true); + if (comp_ok) { + py_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != py_const_none) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + rt_call_function_0(module_fun); + nlr_pop(); + } else { + // uncaught exception + py_obj_print((py_obj_t)nlr.ret_val); + printf("\n"); + } + } + } + } + } +} + int main() { // TODO disable JTAG @@ -294,7 +369,7 @@ int main() { //sys_tick_delay_ms(1000); // Python! - if (1) { + if (0) { //const char *pysrc = "def f():\n x=x+1\nprint(42)\n"; const char *pysrc = // impl01.py @@ -441,6 +516,8 @@ int main() { } } + do_repl(); + // benchmark C version of impl02.py if (0) { led_state(PYB_LED_G1, 1); diff --git a/stm/printf.c b/stm/printf.c index cec7c3e5c..39d902d21 100644 --- a/stm/printf.c +++ b/stm/printf.c @@ -214,7 +214,7 @@ void usb_vcp_send(const char* str, int len); void stdout_print_strn(void *data, const char *str, unsigned int len) { // send stdout to LCD and USB CDC VCP lcd_print_strn(str, len); - usb_vcp_send(str, len); + //usb_vcp_send(str, len); } static const pfenv_t pfenv_stdout = {0, stdout_print_strn}; diff --git a/stm/usb.c b/stm/usb.c index fd32c8425..6ac2392a1 100644 --- a/stm/usb.c +++ b/stm/usb.c @@ -1,23 +1,70 @@ +#include + #include "usb_core.h" #include "usbd_core.h" #include "usbd_cdc_core.h" #include "usbd_pyb_core.h" #include "usbd_usr.h" #include "usbd_desc.h" + +#include "misc.h" #include "usb.h" extern CDC_IF_Prop_TypeDef VCP_fops; int is_enabled = 0; USB_OTG_CORE_HANDLE USB_OTG_dev; +char rx_buf[64]; +int rx_buf_in; +int rx_buf_out; void usb_init() { USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb); + rx_buf_in = 0; + rx_buf_out = 0; is_enabled = 1; } -void usb_vcp_send(const char* str, int len) { - if (is_enabled) { - //VCP_fops.pIf_DataTx((const uint8_t*)str, len); +void usb_vcp_receive(const char *buf, uint32_t len) { + for (int i = 0; i < len; i++) { + rx_buf[rx_buf_in++] = buf[i]; + if (rx_buf_in >= sizeof(rx_buf)) { + rx_buf_in = 0; + } + if (rx_buf_in == rx_buf_out) { + rx_buf_out = rx_buf_in + 1; + if (rx_buf_out >= sizeof(rx_buf)) { + rx_buf_out = 0; + } + } + } +} + +int usb_vcp_rx_any() { + if (rx_buf_in >= rx_buf_out) { + return rx_buf_in - rx_buf_out; + } else { + return rx_buf_in + sizeof(rx_buf) - rx_buf_out; + } +} + +char usb_vcp_rx_get() { + while (rx_buf_out == rx_buf_in) { + } + char c = rx_buf[rx_buf_out]; + rx_buf_out += 1; + if (rx_buf_out >= sizeof(rx_buf)) { + rx_buf_out = 0; + } + return c; +} + +void usb_vcp_send_str(const char *str) { + usb_vcp_send_strn(str, strlen(str)); +} + +void usb_vcp_send_strn(const char *str, int len) { + if (is_enabled) { + VCP_fops.pIf_DataTx((const uint8_t*)str, len); } } diff --git a/stm/usb.h b/stm/usb.h index c5060a010..14a0345c1 100644 --- a/stm/usb.h +++ b/stm/usb.h @@ -1,2 +1,5 @@ void usb_init(); -void usb_vcp_send(const char* str, int len); +int usb_vcp_rx_any(); +char usb_vcp_rx_get(); +void usb_vcp_send_str(const char* str); +void usb_vcp_send_strn(const char* str, int len);