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.

CC2564B with bluez on big endian machine

Hi,


I am trying to get the CC256xEM to work with a Freescale MPC5125 (ppc, big endian), kernel 2.6.35 and bluez 4.84

The first hurdle was that the oscillator in the schematics was not actually mounted. So I provided a 32.768 KHz slow clock, and the module now starts. This is confirmed by seeing that HCI_RTS goes low according to http://processors.wiki.ti.com/index.php/CC256x_Testing_Guide#Required_Voltage_Rail_and_Signal_Sequence

Copied bluetooth_init_cc2564B_1.0_BT_Spec_4.0.bts to /lib/firmware

Made a symlink to get the name correct:

#ln -sf bluetooth_init_cc2564B_1.0_BT_Spec_4.0.bts TIInit_6.7.16.bts

Changed the timeout in hciattach_ti.c according to  http://e2e.ti.com/support/wireless_connectivity/f/660/t/375766.aspx?pi310978=2

I then tried the hciattach, and got the following output.

-----------------------------------------------------------------------------------------------------------------------------------------------------

# strace /usr/sbin/hciattach ttyPSC3 texas

execve("/usr/sbin/hciattach", ["/usr/sbin/hciattach", "ttyPSC3", "texas"], [/* 12 vars */]) = 0
brk(0)                                  = 0x2033c000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4801e000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/var/run/ld.so.cache", O_RDONLY)  = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=3214, ...}) = 0
mmap(NULL, 3214, PROT_READ, MAP_PRIVATE, 3, 0) = 0x4801f000
close(3)                                = 0
open("/usr/lib/libbluetooth.so.3", O_RDONLY) = 3
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\24\0\0\0\1\0\0c|\0\0\0004"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=100172, ...}) = 0
mmap(0x2007c000, 165800, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2007c000
mprotect(0x20093000, 65536, PROT_NONE)  = 0
mmap(0x200a3000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x200a3000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\24\0\0\0\1\0\1\355\204\0\0\0004"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1392996, ...}) = 0
mmap(0x1ff06000, 1463216, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x1ff06000
mprotect(0x20054000, 65536, PROT_NONE)  = 0
mmap(0x20064000, 20480, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14e000) = 0x20064000
mmap(0x20069000, 9136, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x20069000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x48020000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x48021000
mprotect(0x20064000, 4096, PROT_READ)   = 0
munmap(0x4801f000, 3214)                = 0
rt_sigaction(SIGALRM, {0x200b8a24, [], SA_NOCLDSTOP}, NULL, 8) = 0
alarm(10)                               = 0
open("/dev/ttyPSC3", O_RDWR|O_NOCTTY)   = 3
ioctl(3, TCFLSH, 0x2)                   = 0
ioctl(3, TCGETS, {B115200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCSETS, {B115200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCSETS, {B115200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCFLSH, 0x2)                   = 0
write(3, "\1\1\20\0", 4)                = 4
read(3, "\4", 1)                        = 1
read(3, "\16\f", 2)                     = 2
read(3, "\1\1\20\0\6\0\0\6\r\0\220\33", 12) = 12
write(2, "Found a Texas Instruments' chip!"..., 33Found a Texas Instruments' chip!
) = 33
write(2, "Firmware file : /lib/firmware/TI"..., 48Firmware file : /lib/firmware/TIInit_6.7.16.bts
) = 48
brk(0)                                  = 0x2033c000
brk(0x2035d000)                         = 0x2035d000
open("/lib/firmware/TIInit_6.7.16.bts", O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=7093, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4801f000
read(4, "BTSB\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
write(2, "/lib/firmware/TIInit_6.7.16.bts "..., 61/lib/firmware/TIInit_6.7.16.bts not a legal TI firmware file
) = 61
close(4)                                = 0
munmap(0x4801f000, 4096)                = 0
write(2, "Warning: cannot find BTS file: /"..., 63Warning: cannot find BTS file: /lib/firmware/TIInit_6.7.16.bts
) = 6

-----------------------------------------------------------------------------------------------------------------------------------------------------

After inspection of the tools/hciattach_ti.c I saw that use of the "#define FILE_HEADER_MAGIC    0x42535442" was not endian safe. So I changed the define to big endian and now the hciattach command recognizes the file but fails since the use of all structs seem to be implemented without regarding that the endian may be big endian, not little.

I also checked at kernel.org and the code in hciattach_ti.c seems to have the same problem even on the master branch on the bluez git.


So my question is, does there exist a tool to change endianness of the firmware file or some other solution to use the service packs on big endian machines with bluez.

The change in the hciattach_ti.c to correct for endianness is some work, which I can manage, but I do not want to do it if there exists a solution already.


Regards

Jonas

  • Hi,

    I don't think we support this configuration. 

    Anyway let me check it internally and confirm it to you.

  • Please look into it.

    I thought that this stated that the CC2564B could be used with bluez on linux?

    http://e2e.ti.com/support/wireless_connectivity/f/660/t/357895.aspx

    If I do the changes in hciattach_ti.c should that be enough or does this go much deeper than that?

    Best regards

    Jonas

  • Hi,

    I was referring to endianism.

    Please see the response i have received internally.

    This is pure host, our interface is HCI where everything (including endianism) is predefined (to little endian).

    I am not sure exactly where your problem is, but If you needs to store the bts (or c array) differently I guess it can be done (create a c array and re-order everything any way you wants it) but the way it comes out on the UART must be "unchanged" little endian.

  • Thanks Sundeep.

    Yes it is a pure host problem, the problem is that constructs like these found in hciattach_ti.c:

    struct bts_header {
        uint32_t    magic;
        uint32_t    version;
        uint8_t    future[24];
        uint8_t    actions[0];
    }__attribute__ ((packed));

    These are not portable across machines with different endians without changing the byte order when read from file. magic and version will in this case be reversed and thus not match the defines that are expected. Ordinary c-arrays are not a problem as long as we don't take a uintt8_t pointer and cast it to e.g. uint32_t pointer, which is done in several places in this code.


    I will try to fix the broken endanness code. I know that the rest of the bluez stack works with big endian, I have had it run before on the same host with another bluetooth chip, from another vendor.

    Is there a specification to be found on the format used for the service packs?

    Regards

    Jonas

  • I have managed to get the module to start.

    I still have not seen any documentation on the format used by the service packs without that information it is not possible to say if the patch is complete or not. Is there any information to be found?

    The patch is attached if anyone should be interested.

    Regards

    Jonas

    3201.bluez-utils-4.84-fix-cc2564B-endian.diff
    ## This patch is to make hciattach work for texas cc2564b on big endian machines.
    ## It has been tested on an MPC5125. The test included pairing of the cc2564b
    ## with a headset. It has not yet been tested on little endian machines.
    ##
    ## There is no good documentation on the format of the texas service packs so
    ## the changes made are tested with just one service pack. The root cause of
    ## the problem was that the format is little endian and assumes that the
    ## hciattach is also run on a little endian machine. A timeout has also been
    ## changed so that the module have time to answer.
    ##
    ## The original discussion can be found here:
    ## http://e2e.ti.com/support/wireless_connectivity/f/660/t/381616.aspx
    ## 
    ## Signed-off-by: Jonas Rydow <jrydow@gmail.com> on behalf of Stoneridge Electronics
    
    --- bluez-4.84_orig/tools/hciattach_ti.c	2014-11-17 16:08:33.000000000 +0100
    +++ bluez-4.84/tools/hciattach_ti.c	2014-11-18 09:48:23.000000000 +0100
    @@ -126,6 +126,8 @@ static FILE *bts_load_script(const char*
     		perror("can't read firmware file");
     		goto errclose;
     	}
    +	header.magic = htobl(header.magic);
    +	header.version = htobl(header.version);
     
     	if (header.magic != FILE_HEADER_MAGIC) {
     		fprintf(stderr, "%s not a legal TI firmware file\n", file_name);
    @@ -156,6 +158,9 @@ static unsigned long bts_fetch_action(FI
     	if (1 != fread(&action_hdr, sizeof(struct bts_action), 1, fp))
     		return 0;
     
    +	action_hdr.type = htobs(action_hdr.type);
    +	action_hdr.size = htobs(action_hdr.size);
    + 
     	if (action_hdr.size > buf_size) {
     		fprintf(stderr, "bts_next_action: not enough space to read next action\n");
     		return 0;
    @@ -241,6 +246,7 @@ static int brf_send_command_socket(int f
     {
     	char response[1024] = {0};
     	hci_command_hdr *cmd = (hci_command_hdr *) send_action->data;
    +	cmd->opcode = htobs(cmd->opcode);
     	uint16_t opcode = cmd->opcode;
     
     	struct hci_request rq;
    @@ -253,7 +259,7 @@ static int brf_send_command_socket(int f
     	rq.rparam = response;
     	rq.rlen   = sizeof(response);
     
    -	if (hci_send_req(fd, &rq, 15) < 0) {
    +	if (hci_send_req(fd, &rq, 150) < 0) {
     		perror("Cannot send hci command to socket");
     		return -1;
     	}
    @@ -327,10 +333,13 @@ static int brf_do_action(uint16_t brf_ty
     		break;
     	case ACTION_SERIAL:
     		DPRINTF("S");
    +		((struct bts_action_serial *) brf_action)->baud = htobl(((struct bts_action_serial *) brf_action)->baud);
    +		((struct bts_action_serial *) brf_action)->flow_control = htobl(((struct bts_action_serial *) brf_action)->flow_control);
     		ret = brf_set_serial_params((struct bts_action_serial *) brf_action, fd, ti);
     		break;
     	case ACTION_DELAY:
     		DPRINTF("D");
    +		((struct bts_action_delay *) brf_action)->msec = htobl(((struct bts_action_delay *) brf_action)->msec);
     		brf_delay((struct bts_action_delay *) brf_action);
     		break;
     	case ACTION_REMARKS:
    

  • Hi,

    Service pack (.bts) is a binary file.

  • Hi,

    I know that it is a binary file but even though it is a binary file it has a format. It is not binary blob that is loaded to the module. If it were a binary blob only, I would not have had any problems with endian. The bts file contains, among other things, HCI commands to configure the CC2564B module. There are other commands that configure the serial port of the host from what I can see in the code.

    Without knowledge of the actual format of the file how can one assure that parser does what it should? How do I for example change the use of hardware handshaking or add initializations for PCM link into the bts file?

    The binary file is parsed in hciattach_ti.c so it is possible to deduce parts of the format from there. It would however be easier to have a specification of the format rather than reverse engineer it from the parser.


    Best regards

    Jonas

  • On what kind of setup with bluez on little endian have you guys at TI had the CC2664B working?

    And the answer "we have customers running bluez on linux" is not enough, I would like to know what version of linux, bluez, service pack used, what kind of module was used (PAN1326, cc256xEM or something else), real serial port or USB serial.

    According to http://e2e.ti.com/support/wireless_connectivity/f/660/t/357895.aspx the CC256X could be used with bluez. It would be very helpful with a step by step guide... I have gotten the answer previously, that bluez was not supported on big endian machines, how about little endian? If that is not supported I'm a little confused on how exactly bluez is supposed to be used with the CC2564B.

    I have now managed to get the CC256XEM to start on big endian. To be able to put the support into the mainline bluez I would need to get the chip started on a PC, little endian machine, for this I have a PAN1326B module. This is claimed to be supported previously in this thread. But it does not currently work, see: http://e2e.ti.com/support/wireless_connectivity/f/660/p/375766/1353473.aspx#1353473 This thread is still unresolved after being initiated over a month ago. Would someone, please, look into it, maybe even try to do the setup and see why it does not work. Not having the information on how the service pack is supposed to work makes it impossible to debug why it does not work

    I now have the chip supporting big endian with bluez but I cannot get the PAN1323ETU started on a linux PC. This means that, since I cannot test the stack on little endian, I cannot contribute the changes back bluez.

    Are the people at TI at all interested in supporting anything else but its promoted bluetoopia stack? There are quite a lot of machines running linux with bluez and I offer to integrate the changes needed to support bluez on big endian machines, but come on guys I need a little help! (I do this free of charge, fixing something that was supposed to work in the first place...)

    Best Regards

    Jonas

  • Hi,

    Can you provide your Mail ID