diff options
-rw-r--r-- | stmhal/modpyb.c | 8 | ||||
-rw-r--r-- | stmhal/qstrdefsport.h | 1 | ||||
-rw-r--r-- | stmhal/usart.c | 80 | ||||
-rw-r--r-- | stmhal/usart.h | 14 | ||||
-rw-r--r-- | stmhal/usbd_cdc_interface.c | 10 | ||||
-rw-r--r-- | tools/pyboard.py | 36 |
6 files changed, 108 insertions, 41 deletions
diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c index c564a0f19..288008108 100644 --- a/stmhal/modpyb.c +++ b/stmhal/modpyb.c @@ -132,6 +132,13 @@ STATIC mp_obj_t pyb_udelay(mp_obj_t usec) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay); +STATIC mp_obj_t pyb_wfi(void) { + __WFI(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_wfi_obj, pyb_wfi); + #if 0 STATIC void SYSCLKConfig_STOP(void) { /* After wake-up from STOP reconfigure the system clock */ @@ -221,6 +228,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_gc), (mp_obj_t)&pyb_gc_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj }, diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h index 546b5b143..0dd8c2b61 100644 --- a/stmhal/qstrdefsport.h +++ b/stmhal/qstrdefsport.h @@ -6,6 +6,7 @@ Q(info) Q(sd_test) Q(present) Q(power) +Q(wfi) Q(stop) Q(standby) Q(source_dir) diff --git a/stmhal/usart.c b/stmhal/usart.c index 3cf8da6de..247ab629d 100644 --- a/stmhal/usart.c +++ b/stmhal/usart.c @@ -19,7 +19,7 @@ struct _pyb_usart_obj_t { pyb_usart_obj_t *pyb_usart_global_debug = NULL; -void usart_init(pyb_usart_obj_t *usart_obj, uint32_t baudrate) { +bool usart_init(pyb_usart_obj_t *usart_obj, uint32_t baudrate) { USART_TypeDef *USARTx=NULL; uint32_t GPIO_Pin=0; @@ -27,50 +27,74 @@ void usart_init(pyb_usart_obj_t *usart_obj, uint32_t baudrate) { GPIO_TypeDef* GPIO_Port=NULL; switch (usart_obj->usart_id) { - case PYB_USART_NONE: - return; - + // USART1 is on PA9/PA10, PB6/PB7 case PYB_USART_1: USARTx = USART1; + GPIO_AF_USARTx = GPIO_AF7_USART1; +#if defined(PYBV10) + GPIO_Port = GPIOB; + GPIO_Pin = GPIO_PIN_6 | GPIO_PIN_7; +#else GPIO_Port = GPIOA; - GPIO_AF_USARTx = GPIO_AF7_USART1; GPIO_Pin = GPIO_PIN_9 | GPIO_PIN_10; +#endif __USART1_CLK_ENABLE(); break; + +#if !defined(PYBV10) + // USART2 is on PA2/PA3, PD5/PD6 case PYB_USART_2: USARTx = USART2; + GPIO_AF_USARTx = GPIO_AF7_USART2; GPIO_Port = GPIOD; - GPIO_AF_USARTx = GPIO_AF7_USART2; GPIO_Pin = GPIO_PIN_5 | GPIO_PIN_6; __USART2_CLK_ENABLE(); break; +#endif + + // USART3 is on PB10/PB11, PC10/PC11, PD8/PD9 case PYB_USART_3: USARTx = USART3; + GPIO_AF_USARTx = GPIO_AF7_USART3; -#if defined(PYBV3) || defined(PYBV4) +#if defined(PYBV3) || defined(PYBV4) | defined(PYBV10) GPIO_Port = GPIOB; - GPIO_AF_USARTx = GPIO_AF7_USART3; GPIO_Pin = GPIO_PIN_10 | GPIO_PIN_11; #else GPIO_Port = GPIOD; - GPIO_AF_USARTx = GPIO_AF7_USART3; GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9; #endif __USART3_CLK_ENABLE(); break; + + // USART4 is on PA0/PA1, PC10/PC11 + case PYB_USART_4: + USARTx = UART4; + GPIO_AF_USARTx = GPIO_AF8_UART4; + + GPIO_Port = GPIOA; + GPIO_Pin = GPIO_PIN_0 | GPIO_PIN_1; + + __UART4_CLK_ENABLE(); + break; + + // USART6 is on PC6/PC7 case PYB_USART_6: USARTx = USART6; + GPIO_AF_USARTx = GPIO_AF8_USART6; GPIO_Port = GPIOC; - GPIO_AF_USARTx = GPIO_AF8_USART6; GPIO_Pin = GPIO_PIN_6 | GPIO_PIN_7; __USART6_CLK_ENABLE(); break; + + default: + return false; } // Initialize USARTx @@ -94,6 +118,8 @@ void usart_init(pyb_usart_obj_t *usart_obj, uint32_t baudrate) { uh->Init.HwFlowCtl = UART_HWCONTROL_NONE; uh->Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(uh); + + return true; } bool usart_rx_any(pyb_usart_obj_t *usart_obj) { @@ -148,17 +174,35 @@ STATIC mp_obj_t usart_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, con nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Usart accepts 2 arguments")); } - if (mp_obj_get_int(args[0]) > PYB_USART_MAX) { - return mp_const_none; - } - + // create object pyb_usart_obj_t *o = m_new_obj(pyb_usart_obj_t); o->base.type = &pyb_usart_type; - o->usart_id = mp_obj_get_int(args[0]); - o->is_enabled = true; - /* init USART */ - usart_init(o, mp_obj_get_int(args[1])); + // work out port + o->usart_id = 0; + if (MP_OBJ_IS_STR(args[0])) { + const char *port = mp_obj_str_get_str(args[0]); + if (strcmp(port, "XA") == 0) { + o->usart_id = PYB_USART_XA; + } else if (strcmp(port, "XB") == 0) { + o->usart_id = PYB_USART_XB; + } else if (strcmp(port, "YA") == 0) { + o->usart_id = PYB_USART_YA; + } else if (strcmp(port, "YB") == 0) { + o->usart_id = PYB_USART_YB; + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Usart port %s does not exist", port)); + } + } else if (MP_OBJ_IS_INT(args[0])) { + o->usart_id = mp_obj_get_int(args[0]); + } + + // init USART (if it fails, it's because the port doesn't exist) + if (!usart_init(o, mp_obj_get_int(args[1]))) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Usart port %d does not exist", o->usart_id)); + } + + o->is_enabled = true; return o; } diff --git a/stmhal/usart.h b/stmhal/usart.h index 02464080b..e7db1db3d 100644 --- a/stmhal/usart.h +++ b/stmhal/usart.h @@ -3,13 +3,17 @@ typedef enum { PYB_USART_1 = 1, PYB_USART_2 = 2, PYB_USART_3 = 3, - PYB_USART_6 = 4, - PYB_USART_MAX = 4, + PYB_USART_4 = 4, + PYB_USART_5 = 5, + PYB_USART_6 = 6, - //PYB_USART_XA = // USART4 on X1, X2 = PA0, PA1 +#if defined(PYBV10) + PYB_USART_XA = 4, // USART4 on X1, X2 = PA0, PA1 PYB_USART_XB = 1, // USART1 on X9, X10 = PB6, PB7 - PYB_USART_YA = 4, // USART6 on Y1, Y2 = PC6, PC7 + PYB_USART_YA = 6, // USART6 on Y1, Y2 = PC6, PC7 PYB_USART_YB = 3, // USART3 on Y9, Y10 = PB10, PB11 +#endif + } pyb_usart_t; typedef struct _pyb_usart_obj_t pyb_usart_obj_t; @@ -17,7 +21,7 @@ typedef struct _pyb_usart_obj_t pyb_usart_obj_t; extern pyb_usart_obj_t *pyb_usart_global_debug; extern const mp_obj_type_t pyb_usart_type; -void usart_init(pyb_usart_obj_t *usart_obj, uint32_t baudrate); +bool usart_init(pyb_usart_obj_t *usart_obj, uint32_t baudrate); bool usart_rx_any(pyb_usart_obj_t *usart_obj); int usart_rx_char(pyb_usart_obj_t *usart_obj); void usart_tx_str(pyb_usart_obj_t *usart_obj, const char *str); diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c index 81f541df4..c6b6cf23f 100644 --- a/stmhal/usbd_cdc_interface.c +++ b/stmhal/usbd_cdc_interface.c @@ -60,7 +60,7 @@ static uint16_t UserRxBufLen = 0; // counts number of valid characters in UserRx static uint8_t UserTxBuffer[APP_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer static uint16_t UserTxBufPtrIn = 0; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available -static uint16_t UserTxBufPtrOut = 0; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained +static __IO uint16_t UserTxBufPtrOut = 0; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained static int user_interrupt_char = VCP_CHAR_NONE; static void *user_interrupt_data = NULL; @@ -265,6 +265,14 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void) { } buffptr = UserTxBufPtrOut; + + // dpgeorge: For some reason that I don't understand, a packet size of 64 bytes + // (CDC_DATA_FS_MAX_PACKET_SIZE) does not get through to the USB host until the + // next packet is sent. To work around this, we just make sure that we never + // send a packet 64 bytes in length. + if (buffsize == CDC_DATA_FS_MAX_PACKET_SIZE) { + buffsize -= 1; + } USBD_CDC_SetTxBuffer(&hUSBDDevice, (uint8_t*)&UserTxBuffer[buffptr], buffsize); diff --git a/tools/pyboard.py b/tools/pyboard.py index 902a93c15..d5b3237ca 100644 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -32,13 +32,27 @@ class Pyboard: def close(self): self.serial.close() + def read_until(self, min_num_bytes, ending, timeout=10): + data = self.serial.read(min_num_bytes) + timeout_count = 0 + while True: + if self.serial.inWaiting() > 0: + data = data + self.serial.read(self.serial.inWaiting()) + time.sleep(0.01) + timeout_count = 0 + elif data.endswith(ending): + break + else: + timeout_count += 1 + if timeout_count >= 10 * timeout: + break + time.sleep(0.1) + return data + def enter_raw_repl(self): self.serial.write(b'\r\x01') # ctrl-A: enter raw REPL self.serial.write(b'\x04') # ctrl-D: soft reset - data = self.serial.read(1) - while self.serial.inWaiting() > 0: - data = data + self.serial.read(self.serial.inWaiting()) - time.sleep(0.1) + data = self.read_until(1, b'to exit\r\n>') if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'): print(data) raise PyboardError('could not enter raw repl') @@ -60,19 +74,7 @@ class Pyboard: data = self.serial.read(2) if data != b'OK': raise PyboardError('could not exec command') - data = self.serial.read(2) - timeout = 0 - while True: - if self.serial.inWaiting() > 0: - data = data + self.serial.read(self.serial.inWaiting()) - timeout = 0 - elif data.endswith(b'\x04>'): - break - else: - timeout += 1 - if timeout > 100: - break - time.sleep(0.1) + data = self.read_until(2, b'\x04>') if not data.endswith(b'\x04>'): print(data) raise PyboardError('timeout waiting for EOF reception') |