If you want to learn the protocol, please read on.
Architecture
Protocol is adapted to BlueCore3-MM processor features and limitations:
- Basic data type is unsigned 16-bit word in big endian format
- The maximum size of request or response can be 1024 bytes.
- Protocol uses bulk USB transfer mode.
General request and response packet structure
Request packet generaly consist of sequence of commands. First command must be predecessed with null byte, any other with 2 bytes of any value. This is a little bit confusing, but I think it has something to do with switching from 24 bit to 16 bit data mode. Remember, this device and accompanied libraries were designed with audio standards in mind. So, to be more clear, here is the basic structure:
Size in bytes | Field |
---|---|
1 | Null byte |
2*N | Command |
2 | Don't care |
2*M | Command |
... | ... |
The overall packet length should not be bigger than 1024 bytes. Also it shouldn't generate a response packet bigger than 1024 bytes.
Response packet is somewhat simpler:
Size in bytes | Field |
---|---|
2*N | Command |
2*X | Result |
2*M | Command |
2*Y | Result |
... | ... |
In response packet there is no padding bytes. Some command don't have response at all and some can have command code increased by one, which indicates an error. If this is the case, result is the same length as if the command executed succesfuly, however, it should be ignored.
Detailed commands descriptions
There is 18 different commands:
Command code | Command description |
---|---|
0x0100 | Read data |
0x0200 | Write data |
0x0300 | Set speed |
0x0400 | Is processor stopped? |
0x0500 | Get speed |
0x0600 | Go to programmer's firmware update mode |
0x0700 | Get programmer's serial number |
0x0800 | Get firmware version |
0x0900 | Set mode (SPI or JTAG) |
0x0A00 | ??? |
0x0B00 | ??? |
0x0C00 | ??? |
0x0D00 | ??? |
0x0E00 | Set multiple devices (unused) |
0x0F00 | Set additional read/write command bits |
0x4000 | Init BCCMD protocol |
0x4100 | Send BCCMD command |
0x5000 | ??? |
Read data
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0100 |
1 | 1 | Read start address |
2 | 1 | Number of words to read |
Response format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0100 |
1 | 1 | Read start address |
2 | 1 | Number of words to read |
3 | Req. number | Readed data |
Comment: This is one of those commands which can fail.
Write data
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0200 |
1 | 1 | Write start address |
2 | 1 | Number of words to write |
3 | Req. number | Data to write |
Response format:
There is no response.
Comment: None
Set speed
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0300 |
1 | 1 | Delay value |
Response format:
There is no response.
Comment: This command sets communication speed of SPI or JTAG interface, whichever is currently set. For SPI mode, 4 should represent approximately 1 MHz and 393 should represent 20 kHz, which are upper and lower limits. I found this formula in code: speed in kHz = 1000000 / (126 * value + 434). However, I didn't do any actual measurements to check correctness of the formula.
Is processor stopped?
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0400 |
Response format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0400 |
1 | 1 | Status |
Comment: 1 means that processor is stopped and 0 means that processor is running.
Get speed
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0500 |
Response format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0500 |
1 | 1 | Delay value |
Comment: Look at "Set speed" command for details.
Go to programmer firmware update mode
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0600 |
Response format:
There is no response.
Comment: This command resets programmer and boots to bootloader, so you can update firmware on it.
Get programmer's serial number
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0700 |
Response format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0700 |
1 | 3 | Serial number |
Comment: This command is used for differentiating between programmers, when there is more than one plugged in. It returns a value of PSKEY_MODULE_ID. This command can fail.
Get firmware version
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0800 |
Response format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0800 |
1 | 1 | Version |
Comment: BlueSuite tools check version to see which commands are supported. Latest version is 0x119.
Set mode
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0900 |
1 | 1 | Mode |
Response format:
There is no response.
Comment: Value of 0xFFFF means JTAG, any other, usually 0, means SPI.
Set multiple devices
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0E00 |
1 | 1 | Unused |
Response format:
There is no response.
Comment: Not used, probably only for compatibility with older versions of protocol.
Set additional read/write command bits
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x0F00 |
1 | 1 | Which bits |
2 | 1 | Value |
Response format:
There is no response.
Comment: If "Which bits" is 0, read command bits will be set, write bits otherwise. For BlueCore4, these values should always be 0.
Init BCCMD protocol
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x4100 |
1 | 1 | Unknown1 |
2 | 1 | Unknown2 |
Response format:
There is no response.
Comment: Actually I didn't figured out meanings of these values yet. This command must be called before first BCCMD packet is sent.
Send BCCMD packet
Request format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x4100 |
1 | 1 | Size of BCCMD packet |
2 | 1 | BCCMD packet |
Response format:
Offset in words | Size in words | Field description |
---|---|---|
0 | 1 | Command code - 0x4100 |
1 | 1 | Size of BCCMD packet |
2 | ? | Response |
Comment: I didn't figure out full format of this command yet, but it is very useful. It can be used to set PS keys, for example. Full BCCMD protocol description can be found on csrsupport.com.
If you want to see a few examples how to implement this protocol, you can take a look at csrprogrammer's source code.
Hey Jernej,
ReplyDeleteGreat work on reverse engineering this on the PC side, and great work on finding out how to repurpose a BlueCore 3 as a CSR USB<>SPI device :)
It's a shame finding one of those BC3 chips is pretty much impossible :(
I've been trying to emulate the CSR SPI protocol with a TI Stellaris Launchpad, and I got it to recognize it as the CSR SPI protocol, but it doesn't actually receive any information in the bulk interface, so I'm afraid there's some initialization bits I should mimic too.
Any chance you could attach an USB sniffer and get a log from plug-in to reading out some info ?
On another subject, if you need any more info on the SPI protocol the CSR chips are using, feel free to take a look at my reverse engineering effort on the LPT drivers:
https://github.com/Frans-Willem/CsrSpiDrivers
And finally, is there any way to reach you directly so we can help eachother ?
Hi Jernej,
ReplyDeleteGreat work! Thank you very much.
Do you know some datasheet or other source of information about this processor used by CSR? Broadcom uses ARM for theses BCM43xx, but I don't know why CSR didn't the same.
They're using their own architecture known as XAP. Specifically, BC4 uses XAP2, but AFAIK the newest iteration is XAP5.
DeleteI couldn't find any detailed datasheet, but you can find assembler and disassembler on the internet if that helps you somehow.
Have you saw this piece of code???
ReplyDeletehttps://github.com/lorf/csr-spi-ftdi