diff --git a/stmhal/Makefile b/stmhal/Makefile
index aeddca480286b2e46095dab796a1dd53552b7986..6f90a953506c6563f81f92dfa8a813cce31dd647 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -103,6 +103,8 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\
 	stm32f4xx_hal_gpio.c \
 	stm32f4xx_hal_pcd.c \
 	stm32f4xx_hal_rcc.c \
+	stm32f4xx_hal_tim.c \
+	stm32f4xx_hal_tim_ex.c \
 	stm32f4xx_hal_uart.c \
 	stm32f4xx_ll_usb.c \
 	)
diff --git a/stmhal/main.c b/stmhal/main.c
index 2c82cf030b8ebe3d8000f120cdb4b13f0807090c..fc5689c4a0657b6b7055cea8ecd1682ba494df23 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -251,15 +251,15 @@ int main(void) {
     pendsv_init();
     led_init();
 
+    // turn on LED to indicate bootup
+    led_state(PYB_LED_GREEN, 1);
+
 #if 0
 #if MICROPY_HW_ENABLE_RTC
     rtc_init();
 #endif
 #endif
 
-    // turn on LED to indicate bootup
-    led_state(PYB_LED_G1, 1);
-
 #if 0
     // more sub-system init
 #if MICROPY_HW_HAS_SDCARD
@@ -454,7 +454,7 @@ soft_reset:
     }
 
     // turn boot-up LED off
-    led_state(PYB_LED_G1, 0);
+    led_state(PYB_LED_GREEN, 0);
 
 #if 0
 #if MICROPY_HW_HAS_SDCARD
@@ -481,21 +481,6 @@ soft_reset:
     pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC);
 #endif
 
-#if 0
-    // test USB CDC
-    extern uint8_t UserTxBuffer[];/* Received Data over UART (CDC interface) are stored in this buffer */
-    extern uint32_t UserTxBufPtrOut; /* Increment this pointer or roll it back to
-                                        start address when data are sent over USB */
-    for (;;) {
-        UserTxBuffer[UserTxBufPtrOut++] = 'a';
-        UserTxBuffer[UserTxBufPtrOut++] = 'b';
-        UserTxBuffer[UserTxBufPtrOut++] = 'c';
-        UserTxBuffer[UserTxBufPtrOut++] = 'd';
-        HAL_Delay(500);
-        led_toggle(PYB_LED_BLUE);
-    }
-#endif
-
 #if 0
     // run main script
     {
diff --git a/stmhal/printf.c b/stmhal/printf.c
index acd9816a5532758bbf40672a07a982767806fcd1..6fd06508ea698b2a7605237eeca3f675cd7c36bf 100644
--- a/stmhal/printf.c
+++ b/stmhal/printf.c
@@ -12,9 +12,7 @@
 #include "lcd.h"
 #endif
 #include "usart.h"
-#if 0
 #include "usb.h"
-#endif
 
 #if MICROPY_ENABLE_FLOAT
 #include "formatfloat.h"
@@ -273,12 +271,10 @@ void stdout_print_strn(void *data, const char *str, unsigned int len) {
         usart_tx_strn_cooked(pyb_usart_global_debug, str, len);
         any = true;
     }
-#if 0
     if (usb_vcp_is_enabled()) {
         usb_vcp_send_strn_cooked(str, len);
         any = true;
     }
-#endif
     if (!any) {
 #if 0
 #if MICROPY_HW_HAS_LCD
diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c
index 4f2e3dd9d58e03b01342524fa49714437cc06313..75709bb6a98c98b893748f8e01e0142e3c735b3b 100644
--- a/stmhal/pyexec.c
+++ b/stmhal/pyexec.c
@@ -22,8 +22,8 @@
 #include "pyexec.h"
 #if 0
 #include "storage.h"
-#include "usb.h"
 #endif
+#include "usb.h"
 #include "usart.h"
 
 static bool repl_display_debugging_info = 0;
@@ -35,9 +35,7 @@ void stdout_tx_str(const char *str) {
 #if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
     lcd_print_str(str);
 #endif
-#if 0
     usb_vcp_send_str(str);
-#endif
 }
 
 int stdin_rx_chr(void) {
@@ -51,12 +49,9 @@ int stdin_rx_chr(void) {
         }
 #endif
 #endif
-#if 0
         if (usb_vcp_rx_any() != 0) {
             return usb_vcp_rx_get();
-        } else
-#endif
-        if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) {
+        } else if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) {
             return usart_rx_char(pyb_usart_global_debug);
         }
         HAL_Delay(1);
@@ -80,13 +75,6 @@ char *str_dup(const char *str) {
 
 static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
 
-#if 0
-#else
-#define VCP_CHAR_CTRL_A (1)
-#define VCP_CHAR_CTRL_C (3)
-#define VCP_CHAR_CTRL_D (4)
-#endif
-
 int readline(vstr_t *line, const char *prompt) {
     stdout_tx_str(prompt);
     int len = vstr_len(line);
@@ -173,21 +161,15 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
     bool ret;
     uint32_t start = HAL_GetTick();
     if (nlr_push(&nlr) == 0) {
-#if 0
         usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); // allow ctrl-C to interrupt us
-#endif
         rt_call_function_0(module_fun);
-#if 0
         usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt
-#endif
         nlr_pop();
         ret = true;
     } else {
         // uncaught exception
         // FIXME it could be that an interrupt happens just before we disable it here
-#if 0
         usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt
-#endif
         mp_obj_print_exception((mp_obj_t)nlr.ret_val);
         ret = false;
     }
diff --git a/stmhal/stm32f4xx_hal_msp.c b/stmhal/stm32f4xx_hal_msp.c
index 55bf62463a0d8b8f89f84fb1015b03438251f1b2..6ab992a63ceb17decd49d60fe705ec9e46cc6c33 100644
--- a/stmhal/stm32f4xx_hal_msp.c
+++ b/stmhal/stm32f4xx_hal_msp.c
@@ -47,6 +47,8 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f4xx_hal.h"
+#include "usbd_cdc.h"
+#include "usbd_cdc_interface.h"
 
 /** @addtogroup STM32F4xx_HAL_Driver
   * @{
@@ -73,11 +75,11 @@
   * @param  None
   * @retval None
   */
-void HAL_MspInit(void)
-{
-  /* NOTE : This function is generated automatically by MicroXplorer and eventually  
-            modified by the user
-   */ 
+void HAL_MspInit(void) {
+    // set up the timer for USBD CDC
+    USBD_CDC_TIMx_CLK_ENABLE();
+    HAL_NVIC_SetPriority(USBD_CDC_TIMx_IRQn, 6, 0);
+    HAL_NVIC_EnableIRQ(USBD_CDC_TIMx_IRQn);
 }
 
 /**
@@ -85,11 +87,10 @@ void HAL_MspInit(void)
   * @param  None  
   * @retval None
   */
-void HAL_MspDeInit(void)
-{
-  /* NOTE : This function is generated automatically by MicroXplorer and eventually  
-            modified by the user
-   */
+void HAL_MspDeInit(void) {
+    // reset USBD CDC timer
+    USBD_CDC_TIMx_FORCE_RESET();
+    USBD_CDC_TIMx_RELEASE_RESET();
 }
 
 /**
diff --git a/stmhal/stm32f4xx_it.c b/stmhal/stm32f4xx_it.c
index 89764f07d63d7b4d48df2a83a9d9ee4098903f99..9100d63a2a4fc22b22ecf2807fd0f8548249c39e 100644
--- a/stmhal/stm32f4xx_it.c
+++ b/stmhal/stm32f4xx_it.c
@@ -64,6 +64,7 @@
 
 extern void fatality();
 extern PCD_HandleTypeDef hpcd;
+extern TIM_HandleTypeDef USBD_CDC_TimHandle;
 
 /* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
@@ -348,4 +349,9 @@ void RTC_WKUP_IRQHandler(void) {
     Handle_EXTI_Irq(EXTI_RTC_WAKEUP);
 }
 
+void TIM3_IRQHandler(void) {
+    // USBD CDC timer is TIM3
+    HAL_TIM_IRQHandler(&USBD_CDC_TimHandle);
+}
+
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usb.c b/stmhal/usb.c
index 8cfb0e7dfdf76c03a3a9b3a76157fea071b9ffa5..e6e994a0fafb49b6a4d789697bd883d59c0307c6 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -15,20 +15,15 @@
 #include "mpconfig.h"
 #include "qstr.h"
 #include "obj.h"
-#include "pendsv.h"
+//#include "pendsv.h"
 #include "usb.h"
 
 #ifdef USE_DEVICE_MODE
-//extern CDC_IF_Prop_TypeDef VCP_fops;
 USBD_HandleTypeDef hUSBDDevice;
 #endif
 
 static int dev_is_enabled = 0;
 uint32_t APP_dev_is_connected = 0; /* used by usbd_cdc_vcp */
-static char rx_buf[64];
-static int rx_buf_in;
-static int rx_buf_out;
-static int interrupt_char = VCP_CHAR_NONE;
 mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL;
 
 void pyb_usb_dev_init(int usb_dev_type) {
@@ -52,9 +47,6 @@ void pyb_usb_dev_init(int usb_dev_type) {
                 break;
         }
     }
-    rx_buf_in = 0;
-    rx_buf_out = 0;
-    interrupt_char = VCP_CHAR_NONE;
     dev_is_enabled = 1;
 
     // create an exception object for interrupting by VCP
@@ -72,54 +64,19 @@ bool usb_vcp_is_connected(void) {
 
 void usb_vcp_set_interrupt_char(int c) {
     if (dev_is_enabled) {
-        interrupt_char = c;
-    }
-}
-
-void usb_vcp_receive(const char *buf, uint32_t len) {
-    if (dev_is_enabled) {
-        for (int i = 0; i < len; i++) {
-
-            // catch special interrupt character
-            if (buf[i] == interrupt_char) {
-                // raise exception when interrupts are finished
-                mp_obj_exception_clear_traceback(mp_const_vcp_interrupt);
-                pendsv_nlr_jump(mp_const_vcp_interrupt);
-                interrupt_char = VCP_CHAR_NONE;
-                continue;
-            }
-
-            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;
-                }
-            }
+        if (c != VCP_CHAR_NONE) {
+            mp_obj_exception_clear_traceback(mp_const_vcp_interrupt);
         }
+        USBD_CDC_SetInterrupt(c, mp_const_vcp_interrupt);
     }
 }
 
 int usb_vcp_rx_any(void) {
-    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;
-    }
+    return USBD_CDC_RxAny();
 }
 
 char usb_vcp_rx_get(void) {
-    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;
+    return USBD_CDC_RxGet();
 }
 
 void usb_vcp_send_str(const char *str) {
@@ -129,39 +86,22 @@ void usb_vcp_send_str(const char *str) {
 void usb_vcp_send_strn(const char *str, int len) {
 #ifdef USE_DEVICE_MODE
     if (dev_is_enabled) {
-        #if 0
-        USBD_CDC_fops.pIf_DataTx((const uint8_t*)str, len);
-        #endif
+        USBD_CDC_Tx(str, len);
     }
 #endif
 }
 
-#include "usbd_conf.h"
-
-/* These are external variables imported from CDC core to be used for IN 
-   transfer management. */
-#ifdef USE_DEVICE_MODE
-extern uint8_t UserRxBuffer[];/* Received Data over USB are stored in this buffer */
-extern uint8_t UserTxBuffer[];/* Received Data over UART (CDC interface) are stored in this buffer */
-extern uint32_t BuffLength;
-extern uint32_t UserTxBufPtrIn;/* Increment this pointer or roll it back to
-                                  start address when data are received over USART */
-extern uint32_t UserTxBufPtrOut; /* Increment this pointer or roll it back to
-                                    start address when data are sent over USB */
-#endif
-
 void usb_vcp_send_strn_cooked(const char *str, int len) {
 #ifdef USE_DEVICE_MODE
-    #if 0
-    for (const char *top = str + len; str < top; str++) {
-        if (*str == '\n') {
-            APP_Rx_Buffer[APP_Rx_ptr_in] = '\r';
-            APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) & (APP_RX_DATA_SIZE - 1);
+    if (dev_is_enabled) {
+        for (const char *top = str + len; str < top; str++) {
+            if (*str == '\n') {
+                USBD_CDC_Tx("\r\n", 2);
+            } else {
+                USBD_CDC_Tx(str, 1);
+            }
         }
-        APP_Rx_Buffer[APP_Rx_ptr_in] = *str;
-        APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) & (APP_RX_DATA_SIZE - 1);
     }
-    #endif
 #endif
 }
 
diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c
index cb1c41f24f5c2eb1fed3865b40055f5354193934..49f108ffd3016d33a5d8b58c252aad15c1fd7422 100644
--- a/stmhal/usbd_cdc_interface.c
+++ b/stmhal/usbd_cdc_interface.c
@@ -26,8 +26,12 @@
   */
 
 /* Includes ------------------------------------------------------------------*/
+#include <stdbool.h>
 #include "stm32f4xx_hal.h"
+#include "usbd_cdc.h"
 #include "usbd_cdc_interface.h"
+#include "pendsv.h"
+#include "usb.h"
 
 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
   * @{
@@ -40,33 +44,32 @@
 
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
-#define APP_RX_DATA_SIZE  2048
-#define APP_TX_DATA_SIZE  2048
+#define APP_RX_DATA_SIZE  2048 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE
+#define APP_TX_DATA_SIZE  2048 // I think this can be any value
 
 /* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-USBD_CDC_LineCodingTypeDef LineCoding =
-  {
-    115200, /* baud rate*/
-    0x00,   /* stop bits-1*/
-    0x00,   /* parity - none*/
-    0x08    /* nb. of bits 8*/
-  };
 
 uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */
+uint32_t UserRxBufLen; // counts number of valid characters in UserRxBuffer
+
 uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */
-uint32_t BuffLength;
 uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to
                                start address when data are received over USART */
 uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to
                                  start address when data are sent over USB */
 
+static int user_interrupt_char = VCP_CHAR_NONE;
+static void *user_interrupt_data = NULL;
+
+#if 0
 /* UART handler declaration */
 UART_HandleTypeDef UartHandle;
+#endif
 /* TIM handler declaration */
-TIM_HandleTypeDef    TimHandle;
+TIM_HandleTypeDef USBD_CDC_TimHandle;
 /* USB handler declaration */
-extern USBD_HandleTypeDef  hUSBDDevice;
+extern USBD_HandleTypeDef hUSBDDevice;
 
 /* Private function prototypes -----------------------------------------------*/
 static int8_t CDC_Itf_Init     (void);
@@ -75,8 +78,8 @@ static int8_t CDC_Itf_Control  (uint8_t cmd, uint8_t* pbuf, uint16_t length);
 static int8_t CDC_Itf_Receive  (uint8_t* pbuf, uint32_t *Len);
 
 static void Error_Handler(void);
-static void ComPort_Config(void);
-//static void TIM_Config(void);
+//static void ComPort_Config(void);
+static void TIM_Config(void);
 
 USBD_CDC_ItfTypeDef USBD_CDC_fops = 
 {
@@ -126,23 +129,27 @@ static int8_t CDC_Itf_Init(void)
     /* Transfer error in reception process */
     Error_Handler();
   }
+#endif
   
   /*##-3- Configure the TIM Base generation  #################################*/
   TIM_Config();
   
   /*##-4- Start the TIM Base generation in interrupt mode ####################*/
   /* Start Channel1 */
-  if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
+  if(HAL_TIM_Base_Start_IT(&USBD_CDC_TimHandle) != HAL_OK)
   {
     /* Starting Error */
     Error_Handler();
   }
-#endif
   
   /*##-5- Set Application Buffers ############################################*/
   USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
   USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
+  UserRxBufLen = 0;
   
+    user_interrupt_char = VCP_CHAR_NONE;
+    user_interrupt_data = NULL;
+
   return (USBD_OK);
 }
 
@@ -198,6 +205,7 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
     break;
 
   case CDC_SET_LINE_CODING:
+    #if 0
     LineCoding.bitrate    = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\
                             (pbuf[2] << 16) | (pbuf[3] << 24));
     LineCoding.format     = pbuf[4];
@@ -206,9 +214,11 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
     
     /* Set the new configuration */
     ComPort_Config();
+    #endif
     break;
 
   case CDC_GET_LINE_CODING:
+    #if 0
     pbuf[0] = (uint8_t)(LineCoding.bitrate);
     pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8);
     pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16);
@@ -216,8 +226,16 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
     pbuf[4] = LineCoding.format;
     pbuf[5] = LineCoding.paritytype;
     pbuf[6] = LineCoding.datatype;     
+    #endif
     
     /* Add your code here */
+    pbuf[0] = (uint8_t)(115200);
+    pbuf[1] = (uint8_t)(115200 >> 8);
+    pbuf[2] = (uint8_t)(115200 >> 16);
+    pbuf[3] = (uint8_t)(115200 >> 24);
+    pbuf[4] = 0; // stop bits (1)
+    pbuf[5] = 0; // parity (none)
+    pbuf[6] = 8; // number of bits (8)
     break;
 
   case CDC_SET_CONTROL_LINE_STATE:
@@ -271,6 +289,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
   }
 }
 
+#if 0
 /**
   * @brief  Rx Transfer completed callback
   * @param  huart: UART handle
@@ -290,21 +309,91 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
   /* Start another reception: provide the buffer pointer with offset and the buffer size */
   HAL_UART_Receive_IT(huart, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
 }
+#endif
 
 /**
   * @brief  CDC_Itf_DataRx
-  *         Data received over USB OUT endpoint are sent over CDC interface 
-  *         through this function.
-  * @param  Buf: Buffer of data to be transmitted
+  *         Data received over USB OUT endpoint is processed here.
+  * @param  Buf: Buffer of data received
   * @param  Len: Number of data received (in bytes)
   * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+  * @note   The buffer we are passed here is just UserRxBuffer, so we are
+  *         free to modify it.
   */
-static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len)
-{
-  HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
-  return (USBD_OK);
+static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) {
+#if 0
+    // this sends the data over the UART using DMA
+    HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
+#endif
+
+    if (user_interrupt_char == VCP_CHAR_NONE) {
+        // no special interrupt character
+        UserRxBufLen = *Len;
+
+    } else {
+        // filter out sepcial interrupt character from the buffer
+        bool char_found = false;
+        uint8_t *dest = Buf;
+        uint8_t *src = Buf;
+        uint8_t *buf_top = Buf + *Len;
+        for (; src < buf_top; src++) {
+            if (*src == user_interrupt_char) {
+                char_found = true;
+            } else {
+                if (char_found) {
+                    *dest = *src;
+                }
+                dest++;
+            }
+        }
+
+        // set length of remaining characters
+        UserRxBufLen = dest - Buf;
+
+        if (char_found) {
+            // raise exception when interrupts are finished
+            user_interrupt_char = VCP_CHAR_NONE;
+            pendsv_nlr_jump(user_interrupt_data);
+        }
+    }
+
+    if (UserRxBufLen == 0) {
+        // initiate next USB packet transfer now that UserRxBuffer has been drained
+        USBD_CDC_ReceivePacket(&hUSBDDevice);
+    }
+
+    return (USBD_OK);
+}
+
+void USBD_CDC_SetInterrupt(int chr, void *data) {
+    user_interrupt_char = chr;
+    user_interrupt_data = data;
+}
+
+void USBD_CDC_Tx(const char *str, uint32_t len) {
+    for (int i = 0; i < len; i++) {
+        UserTxBuffer[UserTxBufPtrIn] = str[i];
+        UserTxBufPtrIn = (UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1);
+    }
+}
+
+int USBD_CDC_RxAny(void) {
+    return UserRxBufLen;
+}
+
+int USBD_CDC_RxGet(void) {
+    while (UserRxBufLen == 0) {
+        __WFI();
+    }
+    int c = UserRxBuffer[--UserRxBufLen];
+    if (UserRxBufLen == 0) {
+        // initiate next USB packet transfer now that UserRxBuffer has been drained
+        USBD_CDC_ReceivePacket(&hUSBDDevice);
+    }
+    return c;
 }
 
+#if 0
 /**
   * @brief  Tx Transfer completed callback
   * @param  huart: UART handle
@@ -398,17 +487,17 @@ static void ComPort_Config(void)
   /* Start reception: provide the buffer pointer with offset and the buffer size */
   HAL_UART_Receive_IT(&UartHandle, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
 }
+#endif
 
 /**
   * @brief  TIM_Config: Configure TIMx timer
   * @param  None.
   * @retval None.
   */
-#if 0
 static void TIM_Config(void)
 {  
   /* Set TIMx instance */
-  TimHandle.Instance = TIMx;
+  USBD_CDC_TimHandle.Instance = USBD_CDC_TIMx;
   
   /* Initialize TIM3 peripheral as follow:
        + Period = 10000 - 1
@@ -416,18 +505,18 @@ static void TIM_Config(void)
        + ClockDivision = 0
        + Counter direction = Up
   */
-  TimHandle.Init.Period = (CDC_POLLING_INTERVAL*1000) - 1;
-  TimHandle.Init.Prescaler = 84-1;
-  TimHandle.Init.ClockDivision = 0;
-  TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
-  if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
+  USBD_CDC_TimHandle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
+  USBD_CDC_TimHandle.Init.Prescaler = 84-1;
+  USBD_CDC_TimHandle.Init.ClockDivision = 0;
+  USBD_CDC_TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
+  if(HAL_TIM_Base_Init(&USBD_CDC_TimHandle) != HAL_OK)
   {
     /* Initialization Error */
     Error_Handler();
   }
 }
-#endif
 
+#if 0
 /**
   * @brief  UART error callbacks
   * @param  UartHandle: UART handle
@@ -438,6 +527,7 @@ void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
   /* Transfer error occured in reception and/or transmission process */
   Error_Handler();
 }
+#endif
 
 /**
   * @brief  This function is executed in case of error occurrence.
diff --git a/stmhal/usbd_cdc_interface.h b/stmhal/usbd_cdc_interface.h
index 140ea06f16140ad136f0088685353024d2123699..cabd68c1e0a079ad3407c73ac2afb532110ba1eb 100644
--- a/stmhal/usbd_cdc_interface.h
+++ b/stmhal/usbd_cdc_interface.h
@@ -30,55 +30,29 @@
 #define __USBD_CDC_IF_H
 
 /* Includes ------------------------------------------------------------------*/
-#include "usbd_cdc.h"
-
 /* Exported types ------------------------------------------------------------*/
 /* Exported constants --------------------------------------------------------*/
-/* User can use this section to tailor USARTx/UARTx instance used and associated 
-   resources */
-/* Definition for USARTx clock resources */
-#define USARTx                           USART3
-#define USARTx_CLK_ENABLE()              __USART3_CLK_ENABLE();
-#define DMAx_CLK_ENABLE()                __DMA1_CLK_ENABLE()
-#define USARTx_RX_GPIO_CLK_ENABLE()      __GPIOC_CLK_ENABLE()
-#define USARTx_TX_GPIO_CLK_ENABLE()      __GPIOC_CLK_ENABLE() 
-
-#define USARTx_FORCE_RESET()             __USART3_FORCE_RESET()
-#define USARTx_RELEASE_RESET()           __USART3_RELEASE_RESET()
-
-/* Definition for USARTx Pins */
-#define USARTx_TX_PIN                    GPIO_PIN_10
-#define USARTx_TX_GPIO_PORT              GPIOC  
-#define USARTx_TX_AF                     GPIO_AF7_USART3
-#define USARTx_RX_PIN                    GPIO_PIN_11
-#define USARTx_RX_GPIO_PORT              GPIOC 
-#define USARTx_RX_AF                     GPIO_AF7_USART3
-
-/* Definition for USARTx's NVIC: used for receiving data over Rx pin */
-#define USARTx_IRQn                      USART3_IRQn
-#define USARTx_IRQHandler                USART3_IRQHandler
-
-/* Definition for USARTx's DMA: used for transmitting data over Tx pin */
-#define USARTx_TX_DMA_CHANNEL            DMA_CHANNEL_4
-#define USARTx_TX_DMA_STREAM             DMA1_Stream3  
-#define USARTx_DMA_TX_IRQHandler         DMA1_Stream3_IRQHandler
-#define USARTx_DMA_TX_IRQn               DMA1_Stream3_IRQn
 
 /* Definition for TIMx clock resources */
-#define TIMx                             TIM3
-#define TIMx_CLK_ENABLE                  __TIM3_CLK_ENABLE
-#define TIMx_FORCE_RESET()               __USART3_FORCE_RESET()
-#define TIMx_RELEASE_RESET()             __USART3_RELEASE_RESET()
+#define USBD_CDC_TIMx                             TIM3
+#define USBD_CDC_TIMx_CLK_ENABLE                  __TIM3_CLK_ENABLE
+#define USBD_CDC_TIMx_FORCE_RESET()               __USART3_FORCE_RESET()
+#define USBD_CDC_TIMx_RELEASE_RESET()             __USART3_RELEASE_RESET()
 
 /* Definition for TIMx's NVIC */
-#define TIMx_IRQn                        TIM3_IRQn
-#define TIMx_IRQHandler                  TIM3_IRQHandler
+#define USBD_CDC_TIMx_IRQn                        TIM3_IRQn
+//#define USBD_CDC_TIMx_IRQHandler                  TIM3_IRQHandler // this is hard coded in stm32f4xx_it.c
 
 /* Periodically, the state of the buffer "UserTxBuffer" is checked.
-   The period depends on CDC_POLLING_INTERVAL */
-#define CDC_POLLING_INTERVAL             5 /* in ms. The max is 65 and the min is 1 */
+   The period depends on USBD_CDC_POLLING_INTERVAL */
+#define USBD_CDC_POLLING_INTERVAL             10 /* in ms. The max is 65 and the min is 1 */
+
+extern USBD_CDC_ItfTypeDef USBD_CDC_fops;
 
-extern USBD_CDC_ItfTypeDef  USBD_CDC_fops;
+void USBD_CDC_SetInterrupt(int chr, void *data);
+void USBD_CDC_Tx(const char *str, uint32_t len);
+int USBD_CDC_RxAny(void);
+int USBD_CDC_RxGet(void);
 
 /* Exported macro ------------------------------------------------------------*/
 /* Exported functions ------------------------------------------------------- */