TI E2E Community
Low Power RF & Wireless Connectivity
Changing UART Speeds in the Stellaris Bluetopia Stack
I have been trying to increase the speed of my PAN1315 radio hooked up to my LM3S9B96 using a modified version of the SPP example.
It seems like it would be possible to change the 115200 setting in bluetooth.c:
// Configure the UART Parameters and Initialize the Bluetooth Stack.
HCI_DRIVER_SET_COMM_INFORMATION(&sDriverInformation, 1, 115200,
However if I change it to 921600, 460800, 230400 or 57600 the whole Bluetooth module fails to initalize.
I did verify using my scope that the UART is outputting at 230400 when I have it programmed to that. Any ideas on what I can do differently to support faster baud rates? I would like to operate at 921600 baud as my application needs 432000 baud through the bluetooth link. I was able to get about half that using the MSP430 solution, i was hoping to get much better throughput with the Stellaris part. Thus far however I have not seen any throughput data, is that available somewhere?
So after some more reading I found that the radio comes up at a speed of 115200. So I guess what I am looking for is how to increase the baud rate after configuration and can the stack support these high bandwidth baud rates?
Yes, you are right. The radio does come up at 115200. So we must talk to it at that Baud rate during initialization. Once it is initialized we change the Baud rate to 921600 so the communication is at 921600 when the application starts talking to the radio.
So although the function that you mentioned says 115200 (and it can be only that for the above mentioned reason), with no modifications, the application is really running at 921600.
If you wish to communicate at a different baud rate with the radio, you can use the following API once the stack is initialized.
e.g. to communicate at 460800, you can use VS_Update_UART_Baud_Rate(StackID, 460800);
This API is documented in BTVSAPI.h
Please let us know if you have further questions.
Thanks, I was having a hard time tracking down that VS_Update_UART_Baud_Rate(BluetoothStackID, BaudRate); part!
As far as the second half of my question, do you have any data about how fast data can be sent through the Bluetopia stack to another Bluetooth device? Will I be able to get a datarate of 460800 over the RFCOMM/SPP layer?
Looking at the Bluetopia® Protocol Stack API Reference Manual I see it only shows the SPP going to 230400 baud
page 531 says:
BaudRate can be one of the following values:
Will using the SPP_BAUD_RATE_MAXIMUM allow me to surpass 230400 baud using a Stellaris part clocked at 80MHz? I plan on requiring the customers to use a Windows based computer with a 2.X EDR radio attached. The windows computer will initiate the connection and the Stellaris will be the device side of the link.
Thanks for your prompt response!
Yes, Our loop-back tests at 921600 that we performed with this release resulted in the data rate of 575Kbps-640Kbps.
This is with the default parameters and at baud rate of 921600.
Please use the VS_Update_UART_Baud_Rate API with a Baud rate number that you want to try. The SPP_BAUD_RATE_MAXIMUM number is used internally and you may not want to use that in the application code.
Please let us know if you have any questions about your throughput observation.
Hi there! I am continuing on with Ben's work. What I am trying to figure out is how to get SPP to communicate at 921600 to the Windows Bluetooth Stack.
I have opened an SPP server port on the Dev Kit using SPP_Open_Server_Port() and registered it with the SDP using SPP_Register_SDP_Record().
Using PuTTY, I am able to communicate with this Bluetooth COM Port in Windows at 115200. I cannot get it to communicate at any other speed (both higher (e.g. 921600, 460800, 230400) and lower (e.g. 9600, 57600)).
How can I get the Windows COM port to negotiate a different rate of transfer? When I look at the COM Port settings in Windows Device Manager, I see a max listed speed of 128000.
The rate at which you talk to the Bluetooth virtual port may not effect the transfer rate over Bluetooth.
You can choose the setting that works and then try to exchange data with the modified SPP example that is operating at a higher baud rate (as mentioned earlier in the thread). At that time you can check the throughput and let us know if it looks like it is getting limited by the baud rate chosen for the windows Bluetooth serial port rate.
The Windows Bluetooth serial port should just bridge the data in both directions between the client and Bluetooth as quickly as it gets it. Please let me know if you think it is getting limited by the 115200 that you are choosing.
I was hoping that it acted more like a bridge. Before I can verify the above though, I've run into another issue. I need to send about 54 bytes every millisecond over the bluetooth channel. I currently have a 1ms timer set up to be run by the bluetooth kernel.
However, if I attempt to send that much data, I quickly start to get Alloc Failed: <some number> on the Dev Kit serial connection.
I have tried changing the transmit buffer size, but I seem to be limited there. If I try to change the buffer size to 1024 or anything higher, then I receive an Alloc Failed message on start up for that size (1024). The function I am using is SPP_Change_Buffer_Size().
Could you please explain what is causing the Alloc Failed messages? How might I avoid getting in to this situation? Do I need to further buffer the data going out?
Thanks for your help and prompt replies!
Try increasing the value of MEMORY_BUFFER_SIZE in bt_ucfg.h and see if you still get failures/get them little later than earlier.
That worked very well.
So, I'm hopefully down to my last issue here. I am unable to achieve the throughput that you have detailed several posts above. I seem to be limited to ~42KB/sec or 328kbps in one direction (Dev Kit to PC). I don't have data going from the PC application to the Dev Kit. The Dev Kit is just blasting data as fast as possible to the PC COM Port. I have increased the Maximum frame size for the RFCOMM connection and I have increased the clock speed of the Stellaris part (though, I'm not sure that either of these make a difference).
What settings might I change to help increase the transmit speed? I'm looking to achieve about 54KB/sec and I'm not quite there yet, but I can't determine how to best effect the rate.
*Update* - I have been able to verify that we are writing all of the packets (542 bytes in size) to the SPP controller and the SPP_Data_Write function is returning the correct number of bytes written for all calls. We are also correlating the packet sent with an ID. On the received side (PC) we are missing packets here and there. Is this possibly a QoS issue? What is the default QoS? Is it possible that we are losing packets due to a Best Effort setup? If so, how can we change it to Guaranteed?
Also, is there a way to verify that the bytes SPP_Data_Write says that it wrote were actually sent out by the radio?
We are looking into this. We should have an answer for you by tomorrow.
It is possible to achieve the required data rate reliably in this release but there is a dependency on user configurable parameters (explained below) in this release.
The dependency is between the queuing parameters and SPP configuration parameters.
1. We have queuing parameters that user can change to control the amount of RAM used by the application.
These can be controlled by int BTPSAPI SPP_Set_ Queuing_Parameters(unsigned int BluetoothStackID, unsigned int MaximumNumberDataPackets, unsigned int QueuedDataPacketsThreshold)
The default values of MaximumNumberDataPackets and QueuedDataPacketsThreshold are 6 and 2.
2. You can also change the Frame Size and Transmit Buffer size using SPP_Set_Configuration_Parameters(unsigned int BluetoothStackID, SPP_Configuration_Params_t *SPPConfigurationParams)
The constraint that I mentioned earlier is the max number of frames in Transmit Buffer have to be less than or equal to (MaximumNumberDataPackets - QueuedDataPacketsThreshold).
e.g. for (MaximumNumberDataPackets, QueuedDataPacketsThreshold) as (6,2)
if you set the Frame Size as 1000 then the Transmit buffer should be less than or equal to 4000. [ (4000/1000) <= (6-2) ]
If you want a bigger transmit buffer, say 5000 with a frame size of 1000, then the queue parameters can be (6,1) (6,0) (7,2).
We have made changes to remove this dependency and it will be available in the next release.
In the meanwhile, we recommend the following set as a start and let us know if you were able to achieve satisfactory results with these values. (If not, you can tweak the values and let us know the values used if your application is unable to achieve the data rate. We recommend Framesize to be 1000 and Transmit buffer size to be atleast 1024.)
Starting Recommendation: MaximumNumberDataPackets and QueuedDataPacketsThreshold to be the default of 6 and 2.
Frame Size, Transmit Buffer Size and Receive Buffer Size to be 1000, 4000 and 6000.
(The receive Buffer size can be tweaked independently if the remote device is not sending a lot of data back)
Please do not hesitate to let us know if something is not clear. As mentioned earlier, we have removed this dependency to make it much easier to tweak values and it will be available in the next release.
I have updated my code to use your proposed changes and I am now getting the reliability at the lower data rate I need. I have not yet been able to verify it at a higher data rate as I'm working out a few other issues. I'll let you know if I have any further issues in this regard.
Thanks for your help! I greatly appreciate the prompt responses.
I am able to achieve my data rate and reliablity. However, in watching the output of the number of bytes SPP_Data_Write is writing, there are times where it is returning that it wrote less than the number of bytes I have requested (sometimes even 0). I've increased the RFCOMM transmit buffer size to 32000 (while keeping the maximum frame size balanced with the queuing parameters as mentioned in the previous post). However, I cannot seem to make sure that all of the bytes I need to send are getting sent. Is there another adjustment I can make to help this?
There may be cases where SPP_Data_Write function is unable to send all the specified data if the transmit buffer is full. In such a case, it will return the number of bytes that it was able to write.
From the API document: "If this function is unable to send all of the data that was specified (via the DataLength parameter) because of a full Transmit Buffer condition, this function will return the number of bytes that were actually sent (zero or more, but less than the DataLength parameter value). When this happens (and only when this happens), the user can expect to be notified when the Serial Port is able to send data again via the the etPort_Transmit_Buffer_Empty_Indication SPP Event. This will allow the user a mechanism to know when the Transmit Buffer is empty so that more data can be sent."
Please refer to the description of et Port_Transmit_Buffer_Empty_Indication as well in the API document for more details on how this is handled.
I have implemented the above recommendations however I am still unable to achieve the high data rate mentioned in the earlier post (575kbps). Also, I am quickly getting a lot of transmit buffer full situations. I have tried raising the size of both the SPP Transmit Buffer and the UART buffer going to the radio. Neither of these seem to have any effect.
I can only seem to get about 49KB/sec (392kbps) and I'm still seeing a small about of data loss (about .002%). This may be normal, I'm not sure.
To handle the buffer full situation, if I SPP_Data_Write returns less bytes than I wanted to write, I'm putting the left over bytes back in my buffer and setting a tx busy flag. I don't clear the flag until I get a etPort_Transmit_Buffer_Empty_Indication.
There are times where the buffer stays full for 60ms. This seems like a lot to me if I should be able to hit 575kbps.
I have the following setup for the SPP Parameters:
Max Frame Size: 2000
TX Buffer Size: 8000
Max Data Packets: 8
Queued Data Packets: 2
I have tried sending data more often (once every 10ms) and less often (once every 50ms). If I try to wait longer than that, I hit a point where the transmit buffer is NEVER empty.
I'm not sure what else to try at this point and am hoping you might have some suggestions.
Thanks for your help!
All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.
TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs andembedded processors, along with software, tools and the industry’s largest sales/support staff.