summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stmhal/modpyb.c8
-rw-r--r--stmhal/qstrdefsport.h1
-rw-r--r--stmhal/usart.c80
-rw-r--r--stmhal/usart.h14
-rw-r--r--stmhal/usbd_cdc_interface.c10
-rw-r--r--tools/pyboard.py36
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')