This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BLE capability without use of RTOS in CC2650

Other Parts Discussed in Thread: CC2650, CC2640, MSP430F5340

Hi all,

I am new to the CC2650 programming and I would like to ask if we are able to use CC2650 without the use of RTOS.
I mean that we can use only the low level drivers in CC26xxWare driver library.
I have seen that the TI's examples, after BLE stack installation, use the RTOS.

Thank you in advance,

Regards,
Yiannis

  • Hello Yiannis,

    You will need to build with the TI-RTOS but you can do an empty TI-RTOS project (see empty project examples) and write your code without calling BIOS_start(). However, you will not be able to enabled Power Management without the TI-RTOS.

    Best wishes
  • Thank you very much for your answer.

    Because I have just realized that my post may was unclear, the question was about the use of Bluetooth stack without the TI-RTOS.

    I have managed to debug with CC26xxWare libraries without RTOS very well but I do not know if I could use BLE stack without RTOS.

    Is still the answer that I should build RTOS, in order to use somehow the BLE, but never start it with the BIOS_start()?

    Thank you in advance.

    Regards,
    Yiannis

  • I'd also be interested in hearing an answer to this. :)
  • Yes, you still need to build BLE stack with TI-RTOS.
  • May I ask a question, why don't you use TI-RTOS? If you don't like TI-RTOS then you can choose other RTOS. Or, do you just like to program in "main-loop + ISR" style?

    The answer to your question is YES. It is always possible to design a program without OS. But, most of time, it just makes the system inefficient and difficult to maintain. And you have to cook the whole system by yourself.

    Personally I don't use TI-RTOS at all. But I still use my own RTOS on CC2640. RTOS provides multi-tasking so that you don't need to put everything in a single main-loop. This is even more important for communication. Take UART for example, if your system needs to check if other device sends a message to your system then you have to check the UART port periodically. It is very easy to do it in a task without affecting main-loop or other tasks.

    You may say, well, I can do it in a timer ISR. But dealing with communication protocol usually requires timeout mechanism. If you wait for timeout in timer ISR then it will just block CPU and waste CPU time. The system will become very inefficient and other interrupts will get blocked.

    I am not TI employee. But according to my programming experience over 20 years, I would recommend you to use RTOS. It will make your projects easy to develop and maintain. If you are not familiar with RTOS, learn it and enjoy it.
  • Finally, I used TI-RTOS for our application.
  • It is a personal preference and has nothing to do with TI-RTOS but with RTOS in general.
    I would like to have full control and responsibility of my application.
    I understand that maintenance is difficult.
    The use of RTOS has its advantages and drawbacks.
    I believe that one disadvantage is that we should select a more powerfull microcontroller for an application when it must run RTOS than what we need.
    But from the programmer point of view, I aggree, it is a spectacular platform to build applications.

    Yiannis
  • Yes, RTOS has overhead. But the overhead is pretty small. I have a project running my RTOS on MSP430F5340 at 8MHz only. The system runs very smoothly. I can't imagine how to design the system without using RTOS since it has to do a lot of tasks. CC2640 runs at 48Hz, the overhead of my RTOS on CC2640 is usually less than 0.1%. My RTOS kernel also supports tick-suppression scheduling, this is why the overhead is so small.

    I agree with you for "have full control and responsibility of my application". This is why I don't use TI-RTOS and BLE Stack at all. I design the whole system from scratch.
  • Did you implement your own BLE stack? How did you do that?
  • Hi Venemo,

    Yes, I implement BLE stack by myself. The first step would be to study TRM Chapter 23 Radio. The Doorbell module is the handshake mechanism between M3 and M0 (RFC). You can send a command to M0 by writing command parameters in Doorbell register, then wait for the status register to be updated, read it to know the execution result. For this, I use Doorbell interrupt with semaphore to prevent from wasting CPU time while waiting.

    So far, I am still building the stack and I expect to complete the design within couple of weeks.
  • Cool! Yep, I've seen that section in the reference manual (by the way the cc26xxware driverlib also implements all the RF commands), but it seems to be quite tedious to work with it at this level, because there are no examples (at least I haven't found any).
  • Yes, it is never an easy task to cook the stack (framework) from scratch.

    But, another reason for me to do it is to build the entire framework in C++. Personally, I have used C++ in embedded systems for several years. And I found C++ is pretty useful if you can accept some overheads. The code will be much easier to understand and maintain.

    In order to fully utilise the power of C++, I also make C++ native to my RTOS. That means, it is possible to create a C++ class with task's event-loop directly. For example,

    class MyTask: public pos::Task
    {
    private:
        pos::Mutex mutex;
        ...
    
    public:
        MyTask();
        ~MyTask();
        void run();
        ...
    };
    
    MyTask::run()
    {
        while(1){
            mutex.lock();
            ...
            mutex.unlock();
           ...
        }
    }

    pos is namespace of my RTOS. Task is the class directly supported in my RTOS. run() is the event-loop function to be overwritten by user. As you can see, mutex (and semaphore) is also directly supported in C++.

    So, in my system, you can organise everything in "object-oriented" way.

  • Robert,


    how did you go building the BLE stack?

    I was able to get a hacked up Zigbee stack going OK but am struggling with BLE.

    I am able to advertise and receive a CONNECT_REQ,  swap channels and issue the TI radio command CMD_BLE_SLAVE. I get half of the first LL packet from the Master before the Slave times out.

    Changing the slave timeout and end time seems to make no difference - the timeout still occurs almost straight away and then the master is disconnected before I can transmit anything.

  • It is great to know your ZigBee stack is working.

    My schedule of building BLE stack is delayed due to my customer decided to sell a simplified version of the product (without BLE) at first. So, I am pretty busy on making a simplified version of the project and put it into mass production in the past weeks. For production, I also need to spend time on designing flash programming tooling at first.

    Anyway, I have completed all BLE structures' definition and command req mechanism. But no time to do further development so far. The good news is I have done 20 pieces working sample yesterday for my client to test and go for 250 pcs trial-run. So, I can continue to build BLE now.

    We all know that TI doesn't provide BLE stack source code. But I just found that TI contributes some source files for contiki project. So, my suggestion is to download the full contiki source code from github and dig out all CC26xx/BLE related codes. This might be helpful to you and me.
  • I've actually taken a look at Contiki's source code. It doesn't do much, it just has the ability to send out non-connectable advertisements. I haven't yet found a proper implementation of the BLE state machine yet.
  • There seems to be no information at all about the BLE stack. Its really unfortunate.

    I had hoped to have a custom "Zigbee" stack and a custom "BLE" stack running on the device so you could press a button to configure the device/monitor readings using BLE and a smartphone or switch it back to Zigbee to transmit back to a base.

    The "Zigbee" side is all good and I can sort of make the BLE work using the Manufacturer data in the advertisement and the data in the scan response. However it is far from ideal.

    The things I noticed which may be of uses to someone with a better understanding of the CC2650 and feels like a challenge are:

    1. If I use the Contiki overrides when configuring the radio in BLE mode all is good. If I use the TI driver overrides I sending the advertisement fails.

    2. After receiving the CONNECT_REQ I was able to swap to the requested channel and connect briefly before the CC2650 timed out.

    3. Applying the TI patches causes the connection to end unexpectedly rather than time out.

    Anyway after several weeks of trying all sorts of things I have come to the conclusion that it is a pointless exercise and will probably just use an external BLE module.

    Please TI surprise me and release some more information to make BLE possible without using the full blown stack.

  • As I know, it's TI policy to run Zigbee or BLE stack based on TI RTOS. There's no alternative.
  • Hi Sholto,

    As stated, the full BLE stack with connectivity requires TI-RTOS, there are no plans to make a non-RTOS based BLE stack.

    Look for some standalone beacon-only examples coming soon that will use the RF-Driver in the 2.18+ TI-RTOS release. Although the TI-RTOS empty project is used, it is possible to run this with or without a task.

    Best wishes
  • Hi ,

    Oh... it is a pity that Contiki source code doesn't help.
    Hope that TI can release the BLE stack source code for us to customize.
  • Hey guys,

    It turns out that it's relatively simple to create a broadcaster (scannable / non-connectable advertiser) with just the cc26xxware driverlib. I created such a program to quickly create test app which I could use to measure the RF performance of the chip on my board. I can share the source code with you guys if you want.

    However, anything more (ie. any application that would require a connection) seems somewhat more complex as you would need to basically implement the whole BLE link layer for yourself. This may not be so hard if you read the radio documentation in detail, but then you still have to make a GAP, ATT, GATT, etc. implementation for yourself. So it might be a nice exercise for someone looking for a challenge, but not something that could be done easily.

    For me, advertising works really well using the appropriately chosen overrides that come from TI. (Depending on what kind of RF front-end configuration and TX power you wanna use.) Like I said, if you're interested, I can share my code.
  • Hi ,

    Yes, it is a challenge to re-design the BLE stack without TI-RTOS.

    For me, there are many reasons to give up TI BLE stack. One of them is that it takes too much flash memory space. I do have many projects to do with CC26xx/CC13xx. So, I will (and have to) overcome this issue in the near future.

    It would be great if you can share the source code of a broadcaster using driverlib. That will help me a lot.
  • Hey

    I've pushed my code to this github repo: github.com/.../cc2640-ble-broadcaster
    This is some very basic example code, but I think it demonstrates the point well. If you have any questions about it, we can continue to discuss it in this thread. :)

    Hope this helps,
    Timur
  • Hi ,

    Thanks a lot for sharing the broadcaster source code.
    I will test it on my board to see if it can work.
  • It works for me on a CC2640 (RGZ package, differential mode, with internal bias). You need to change the code if you use a different RF front-end. I wrote it up in the readme how you need to change it.
  • Hi Robert, Hi Venemo,
    may I point you to my BLE stack? github.com/.../bluetoe

    Currently, only nrf51/52 is supported, but I think it wouldn't be too hard to port it to an cc2650. There is one interface called a scheduled radio that would have to be implemented on cc2650 (github.com/.../scheduled_radio.hpp).

    Bluetoe does not support the full BLE functionality, but before you start to write a BLE stack from scratch, it might be easier to start with Bluetoe.

    cheers,
    Torsten
  • Hey thank you for the link! For now, I've managed to get a grip on TI's BLE stack (so that's what I'm gonna use with my application), but I believe your project will be a useful starting point for . :)
  • I definitely will look into your implementation. Bluetoe is a good start for me.
  • Hi Venemo (4403184),

    After trying to design my own BLE stack on CC2640 for several months, the ADVERTISING mode is working well. iOS App can receive the advertisement from my device. But there is a strange issue: The radio CPU will block if the overrides is assigned when executing CMD_RADIO_SETUP. If it is not assigned (set pRegOverride=NULL) then CMD_RADIO_SETUP works well. I have tested this issue on both my customized board and CC2650 LaunchPad. The result is the same.

    Do you know what could be the reason?

    Now I try to make CONNECTION mode work. OK, I let CC2640 to send advertisement over channels 37, 38, 39 every second. So, I get three TX_DONE interrupts for every second. By designing an iOS App (using Swift language) to discover the CC2640 device. When it is discovered, try to connect to the device as shown in the following code snippet.

    // Connect to the discovered peripheral
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    	print(#function)
    	print("  " + peripheral.description)
    	print("  RSSI = " + RSSI.stringValue)
    	connectingPeripheral = peripheral
    	connectingPeripheral.delegate = self
    	centralManager.connect(connectingPeripheral, options: nil)
    }

    I can see the print() log messages. At the same time, CC2640 gets RX_ENTRY_DONE and RX_DONE interrupts. Then, I try to read RX buffer entry which is in FINISHED state. I expect to get the CONNECT_REQ PDU in this entry. But what I got is an empty entry, length=0, type=ADV_NC_IND and channel=38 from the status byte.

    From the advOutput data structure, nRxConnectReq=1. So I know the CONNECT_REQ PDU is already received by radio CPU. But how can I get it in system CPU?

    The CONNECT_REQ PDU contains accessAddress which must be assigned in the CMD_SLAVE command to enter slave role. So, I am stuck here.

    I think you may have studied and done experiments on CC2640 RFC. Hope that you can help me on this.