Introduction
A bunch of supported and currently in development targets are equipped with a Bluetooth controller chip. There are several types of them but fortunately, apart specific vendor commands to debug - test - or initialize each specific chip, they share the same middleware (HCI). This is a source of great possibility to build up either from scratch or following specific libraries a functional bluetooth stack. Specifically, on Samsung YP-R1, BCM2070 has the possibility to stream PCM audio through the link and regarding Rockbox, that is a desiderable feature, thinking of portable music speakers and akin.
The process of investigation starts with a list of known chips and the "hosting" target(s). The article continues with experimental basis work on Samsung YP-R1 in detail.
To be noted is that some chips have the possibility or even the need for a firmware to be uploaded, either to be fully functional or to fix some bugs present in the integrated ROM: it is notable that some of them are actually fully-fledged ARM microcontrollers with several
KiB of RAM and ROM. Last but not least, we discuss how a future Bluetooth implementation could be shaped, starting from the low-level driver interface, to higher levels eventually.
Targets and Bluetooth chips
Bluetooth controller |
Target(s) |
Notes |
BCM2070 |
Samsung YP-R1 |
No need a firmware, but patches to be uploaded are present in OF. Bluez has tool to initialize it. |
BCM2048 |
Samsung YP-T10 / P2 |
Bluez has tool to initialize it |
BTTZ0502SA |
|
It embeds CSR-03 / BC352239 |
CSR-41814 |
Cowon S9 |
Bluez has tool to initialize it |
The presented list of controllers are all usable (guesstimation based on hciattach source code) from within Linux either by default (because present in some USB-dongles) or by some magic commands like loading UART/USB drivers and then issuing the hciattach command. An example with BCM2070 is illustrated below.
The case: BCM2070 on hosted (Linux 2.6) Samsung YP-R1
To get the things started, a study of the kernel module, named r1BtPort.ko, has been done. It emerged that it does not hide black magic: it just toggles some GPIO pins in order to electrically initialize the IC. Reset, Wake and Reg_en pins are available. Reset and Reg_en are quite related and they are basically toggling the power, the second is more electrical-related. Wake, instead, is used to tell the controller that it needs to stay awake without the possibility for it to go in sleep mode. It is not clear if it has to stay asserted during transfers, but it is likely to be so. A simple C program was used to do some ioctls to this modules to toggle the chip on and awake for testing. Next, the module won't be used at all but Rockbox GPIO subsystem will be exploited.
BCM2070 uses a UART interface to communicate on this particular target and it is mapped as /dev/ttymxc1 in the system, while ttymxc0 maps to the system's console.
Once up and running, the main issue was related to the firmware. Datasheet doesn't say it must be uploaded for the controller to work nor it states the opposite. Brief disassembling of OF libstack.so revealed that indeed there is a "rampatch", it's internal name, the address destination and its length.
Name (bcm2045_patch_version) |
Address (bcm2045_patch_ram_location) |
libstack.so location |
Length |
BCM2070B0_002.001.032.0255.0260_HCI |
0x8BFE0 |
0x4E818 |
0x5BBE |
Rockbox support will imply the patch to be loaded and uploaded to the controller on the fly from the library, it can be easily accessed.
After this introductory work, some on-device tests have been done without great success. So, to tackle the problem, USB gadget kernel modules + g_serial module in particular - the latter has been built from the Samsung opensource YP-R1 kernel release - has been exploited to create a virtual UART port over USB. Later, with the help of "socat" (
http://www.dest-unreach.org/socat/) it has been managed to "redirect"/"relay" the BCM2070 UART to the one exported on the USB. This adds a great advantage for debugging and basic testing: it has been possible to pair to a phone and transfer some data over the link!! Ladies and gents, a new use case for a portable player
Device code (summarized, adjust on a needs basis)
mknod /tmp/ttyGS0 c 127 0
insmod /lib/modules/arcotg_udc.ko
insmod /lib/modules/gadgetfs
insmod /mnt/media0/g_serial.ko
stty -F /dev/ttymxc1 115200
stty -F /tmp/ttyGS0 115200
/mnt/media0/socat -d -d file:/dev/ttymxc1,raw,echo=0 file:/tmp/ttyGS0,raw,echo=0 &
Big attention to the last line in particular...Compiling socat has been quite a challenge since there are likely bugs when cross compiling. To compile it, download the tar source code and type the following.
wget http://www.dest-unreach.org/socat/download/socat-1.7.1.2.tar.gz
tar xvf socat-1.7.1.2.tar.gz
cd socat-1.7.1.2.tar.gz
./configure --host arm-ypr0-linux-gnueabi
Before typing
please hand-edit the file config.h according to the following content (patches are great and handy, but I'm not sure the config is the same, so manual work is good). Some defines are inexistent or blank: add or edit them accordingly.
#define CRDLY 0003000
#define TABDLY 0014000
#define CSIZE 0000060
#define ISPEED_OFFSET 13
#define CRDLY_SHIFT 9
#define TABDLY_SHIFT 11
#define CSIZE_SHIFT 4
Host code (summarized, adjust on a needs basis)
modprobe usbserial vendor=0x0525 product=0xA4A6 # after this one, /dev/ttyUSBx comes up, after running device code
hciattach -s 115200 /dev/ttyUSB0 bcm2035 115200 noflow
( Don't care about the ridiculous speed, it is more than enough for testing )
This host code first loads the USB serial port module, and later it communicates with BCM2070, initializing it. It can even set a bt_addr if one wishes. Check man pages as homework.
NOTE: these steps are NOT requiring the firmware patch. There is a detail missing for the latter to be accomplished, short term TODO.
Apart from that, everything is easily repeatable on device only (Robkbox side). No problems whatsoever.
Proposals (driver/stack/etc)
UART based controllers (with PCM in/out for audio and auxiliary GPIO for low-level toggling)
TBD
I see different things to be done here as first steps
- GPIO handling (already working on targets for sure. To be refactored on YP-Rx targets.) - DONE
- UART management (write/read). Not a major challenge. - DONE
- HAL for handling Bluetooth basic states (HCI initialization / on / off / reset are the ones I can think of. Similar approach to tuner.h should be okay) - DONE
- Debug screen for bluetooth controllers. State can be read, Chip can be reset, Chip can be used as dongle if permitted from the target. On YP-R1, this will be experimental and hackish without RB usb support. - PARTLY
Next steps, are
- Developer must learn BT stack.
- HCI layer. Scan and whatever it belongs to.
Custom interfaces
TBD
Conclusions
-- LorenzoMiori - 02 Jan 2015
- BCM2070.pdf: The BCM2070 datasheet. Has some information, but no clues on HCI propertary commands nor about firmware upload.
Copyright © by the contributing authors.