Any way to make USB stack working without the HCIParser?

I want to use the USB stack provided with the CC2540 sample HostTestRelease without the HCI/serial parser from that project. I want to have other USB communication, not HCI.

The only issue which stops me doing this is the typedef void (*halUARTCBack_t) (uint8 port, uint8 event); function which is used in the HalUARTOpen/HalUARTOpenUSB config parameter (halUARTCBack_t      callBackFunc;).

This is defined in TI's precompiled code (lib), there is no documentation about it (or at least I couldn't find any), I can only see from debugger that it's called from HCI_init function (no source provided, TI lib code).

Anyone managed to make it work, has a sample or at least has a description of the possible events from that callback?

It's really annoying to have the UART USB initialization mixed up in the precompiled BLE stack.

I understand that TI does not want to give source code for the BLE stack but also doesn't want to let us using the USB port as we want to? The USB stack is already written, I would prefer to not write a new one ...


  • The "single-chip" BLE libraries do not use the UART (virtual or physical) for the HCI. You should be able to create a project that uses one of these libraries along with the USB stack.

  • In reply to Willis1:


    I have to reject Your answer since it does in one point - and that point is crucial enough to make the whole USB stack unusable without it.


    Here it is the callstack:








    As you can see the HalUARTOpen is called from HCI_Init and what is bad for us that 0x029b parameter is a structure which contains a CALLBACK function entry address. 


    This callback function has the type of void (*halUARTCBack_t) (uint8 port, uint8 event); and it is implemented somewhere in the HCI code which is inside the BLE bin's. Therefore we cannot know what events can appear in that callback, how they should be treated to make the whole USB stack working.


    That callback is saved inside the halUARTCBack_t uartCB; variable from _hal_uart_usb.c and it's called from a few places inside the _hal_uart_usb.c with some events like HAL_UART_RX_ABOUT_FULL, HAL_UART_RX_TIMEOUT, HAL_UART_TX_EMPTY etc.


    Is there any description about this callback and what should do with those events?

    I've found some examples in the Z-Stack devkit (MT_UartProcessZAppData, SerialApp_CallBack, npUartCback) but it's not too helpfull since none of them are USB related. 




  • In reply to Brown59592:

    As a test I added empty callback there and seems to work.

    I would still be very pleased to see a description of those HAL_UART_RX, TX events.

    They are RX,TX buffer status which should be handled in some cases to avoid overruns and timeouts?


  • In reply to Brown59592:

    Which project are you using where you see that call stack? As I mentioned before, if you use the "single-chip" libraries and not the "network processor" libraries HCI_Init will not call HALUARTOpen. The "SimpleBLEPeripheral" project uses the "ble_single_chip_slave_pm_on.lib" library, but but does not use the USB stack. The "HostTestRelease" project uses the "network processor" library and uses the USB stack for the HCI. If you want to write a non-network processor application that uses the USB stack, you will need to create a project that uses one of the "single chip" libraries, and add the USB stack source code to the project. Your application can then initialize the USB stack like this:

      halUARTCfg_t uartConfig;

      // configure UART
      uartConfig.configured           = TRUE;
      uartConfig.baudRate             = HCI_UART_BR;
      uartConfig.flowControl          = HCI_UART_FC;
      uartConfig.flowControlThreshold = HCI_UART_FC_THRESHOLD;
      uartConfig.rx.maxBufSize        = HCI_UART_RX_BUF_SIZE;
      uartConfig.tx.maxBufSize        = HCI_UART_TX_BUF_SIZE;
      uartConfig.idleTimeout          = HCI_UART_IDLE_TIMEOUT;
      uartConfig.intEnable            = HCI_UART_INT_ENABLE;
      uartConfig.callBackFunc         = callbackFn;             // you would need to define this callback function

      // start UART
      (void)HalUARTOpen (HCI_UART_PORT, &uartConfig);

  • In reply to Willis1:

    HostTestRelase project. As far as I know it's the only one CC2540 sample with USB stack.

    uartConfig.callBackFunc         = callbackFn;             // you would need to define this callback function

    This is the part for what I couldn't find description or sample.

    I don't know what events could occur in that callback and what's their role. Looking into the Zigbee sdk (cc2531 kit) I've found some examples for serial communication callbacks but none for USB.

    I managed to make a simple loopback USB with empty callbackFn but those events are not treated this way which might end in bugs.


    This approach may not be strickly 'by-the-book' but I was able to implement the usb stack for my peripheral device application. I brought in the entire class_cdc and library folders from the HostTestRelease reference design. Then I modified the halUartPollRx() function (in _hal_uart_usb.c)  to send a message (osal_msg_send) to my task whenever the <CR> character is detected. This works for incomming usb messages and for outgoing, I just defined the  HAL_UART compiler preprocessor flag and  use HalUARTTx to write to the usb channel. On the hardware side, I needed a pull-up on the D+ signal.  I used one of the I/O pins so that I could initialize my system before enabling the usb channel. I still use the HostTestRelease firmware and dongle to communicate with the PC.




  • In reply to Dan Dupree:

    Would you give me some more input, Dan? I try the same, using USB/CDC in my Peripheral-Project but my Computer says "Unknown USB-Device..."

  • In reply to Seso:

    Hey all,

    I tried running the SimpleBLEPeripheral project in a similar fashion on the CC2540USB dongle, and augmented it with the recommended UART setup described above. I found that I got a "USB device not recognized" error just like Dan described.

    Well, it turned out that the error has nothing to do with USB! Stepping through in the debugger revealed it was in a tight loop inside LL_Init -- specifically in a function waiting for an oscillator to stabilise, or so its name suggested. Another thread suggested that was caused by using the power managed libraries with the USB dongle -- indeed I was using ble_single_chip_slave_pm_on.lib as SimpleBLEPeripheral does by default. I switched that to ble_single_chip_slave_pm_off.lib and voila -- the device makes it through LL_Init and the USB device is properly recognised (and works as intended!) I'd guess the device-not-recognized error was because OSAL was not getting around to servicing USB traffic, and the host controller eventually timed the device out.

    In summary, with the pm_off.lib library and SimpleBLEPeripheral modified to use the Target subtree for CC2540USB as referenced in HostTestApp, I've got a USB dongle acting like a BLE peripheral and reporting some ancillary information via the USB UART.