lorf / csr-spi-ftdi

USB SPI programmer/debugger for CSR BlueCore bluetooth chips, based on FTDI USB to UART converter, for Linux and Windows
562 stars 102 forks source link

Programming CSR 8645 over SPI using Raspberry PI GPIO #6

Closed erotavlasme closed 8 years ago

erotavlasme commented 8 years ago

Hi, I'm trying to read the firmware of CSR 8645 over SPI using Raspberry PI GPIO. The connection between the CRS 8645 and Raspberry PI should be right since if I used the file ./spidev_test -D /dev/spidev0.0 from here https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md, I receive back the correct sequence of bit. Hence, I read this http://members.efn.org/~rick/work/rpi.csr.html and I used the provided C file, but it did not work for me. I tried to modify some parameters in the file according to different pin out of CSR 8645 with respect to HC05 BC4 series chip without success. Finally, I found this useful guide. I would avoid to buy a dedicated programmer if I can. I followed the hint "For such chips to be accessible via SPI, SPI_PCM# pin should be pulled up to I/O voltage supply through a 10K resistor". However, for me the behaviour is the opposite. If I connect SPI_PCM# called SPI_EN pin to +VCC through a resistor and I use ./spidev_test -D /dev/spidev0.0 I cannot receive back the correct sequence of bit, it seems to work with opposite logic. My CSR 8645 is contained in a BTM98 v3.1 chip and I'm doing reverse engineering since I do not have the datasheet. I have the datasheet of BTM98 V2.0 and I supposed the same pin out configuration. Any suggestion?

Thank you

P.S. By using the C code of http://members.efn.org/~rick/work/rpi.csr.html I get this sudo ./csrbt -y 150000 -s 500000 -o read -f dump1.bin Reading: addr_offset = 0x0 p_data->offset = 0x0 can't send spi message: Invalid argument while with verbose option sudo ./csrbt -y 150000 -s 500000 -o read -f dump1.bin -v Set realtime priority Thread Attribute init Thread set schedule policy Thread set inherited schedule Poll thread created spi mode: 0 bits per word: 8 max speed: 500000 Hz (500 KHz) Reading: addr_offset = 0x0 p_data->offset = 0x0 gpio now 0x21200900 0x00024009 gpio now 0x24200900 0x00024024 Reading: addr_offset = 0x400 p_data->offset = 0x0 gpio now 0x21200900 0x00024009 gpio now 0x24200900 0x00024024 Reading: addr_offset = 0x800 p_data->offset = 0x0 .. gpio now 0x21200900 0x00024009 gpio now 0x24200900 0x00024024

lorf commented 8 years ago

Hi!

Can You please share what You trying to achieve? CSR8645 is a ROM device, and firmware cannot be updated, AFAIK. There is a internal EEPROM which stores some configuration variables called PS Keys, and they are rather flexible.

On the SPI_PCM# pin - from what I've read, spidev_test is a loopback test for SPI driver testing. If it works, it doesn't mean a working SPI connection, it means that the signal loops back unmodified from MOSI to MISO. Also, from CSR8645 datasheet: spi_pcm

Unfortunately I don't have an RPi, so cannot help with programming. I just need to note that CSR's SPI is non-standard - it requires some initialization before actual transfer (two spare clock cycles on CLK pin while keeping Chip Select deselected). In csrbt this is done in do_one_xfer() function - it first uses bitbanging on SPI pins to initialize CSR's SPI port, then uses standard SPI for transfer.

erotavlasme commented 8 years ago

Hi, thank you for your fast reply. I would like to change the name of Bluetooth device. I know that I can do it by using proprietary software of CSR plus the development board or a third party interface. However, if I can, I would prefer to avoid to buying new item. Yes, I would like to program the external ROM and I think that I can do this via SPI. Yes, you are right regarding the SPI_PCM#. Unfortunately I cannot understand the correct behaviour without the proper datasheet. As I said before, my CSR 8645 is contained in a BTM98 v3.1 chip and I do not have the datasheet. I have the datasheet of BTM98 V2.0 and I supposed the same pin out configuration, this is the main issue. bt4 0 module spec 1 I read the csrbt file and the do_one_xfer() function. This is the main function in which I modified the pin out according to previous datasheet, but without success. However, thank you for your help. I will try again and in the worst case I will buy a third part interface :(.

#define WAIT_LOOP_TIME 10000  /* in ns */
void do_one_xfer(struct USART_DATA *p_data, struct spi_ioc_transfer *tr)
    {
//  gpio_set_pin(p_data, ECSPI1_SS0, 0);  /* hold ECSPI1_SS0 high / low */
    int pin, cntr;
    struct timespec ts = { 0, WAIT_LOOP_TIME };  /* delay in nanoseconds */

  /* first we must reset the CSR 8645 SPI with at least 2 pulses */
    pin = 11;  /* CS0 */
    INP_GPIO(p_data->gpio, pin); // must use INP_GPIO before we can use OUT_GPIO
    OUT_GPIO(p_data->gpio, pin);  /* set as output */
    GPIO_SET(p_data->gpio) = 1 << pin;

    pin = 8;  /* MOSI */
    INP_GPIO(p_data->gpio, pin); // must use INP_GPIO before we can use OUT_GPIO
    OUT_GPIO(p_data->gpio, pin);  /* set as output */
    GPIO_CLR(p_data->gpio) = 1 << pin;

    pin = 10;  /* clock pin */
    INP_GPIO(p_data->gpio, pin); // must use INP_GPIO before we can use OUT_GPIO
    OUT_GPIO(p_data->gpio, pin);  /* set as output */
    GPIO_CLR(p_data->gpio) = 1 << pin;

    if (p_data->verbose)
        printf("gpio now 0x%08x 0x%08x\n", *p_data->gpio, *(p_data->gpio + 1));

    for (cntr = 0; cntr < 6; cntr++)
        {
        GPIO_SET(p_data->gpio) = 1 << pin;
    nanosleep( &ts, NULL);
        GPIO_CLR(p_data->gpio) = 1 << pin;
    nanosleep( &ts, NULL);
        }

    for (pin = 8; pin <= 11; pin++)
        {
        INP_GPIO(p_data->gpio, pin); // must use INP_GPIO before we can use OUT_GPIO
        SET_GPIO_ALT(p_data->gpio, pin, 0);  /* set as alt 0 */
        }
    if (p_data->verbose)
        printf("gpio now 0x%08x 0x%08x\n", *p_data->gpio, *(p_data->gpio + 1));

    if (ioctl(p_data->spifd, SPI_IOC_MESSAGE(1), tr) < 1)
        bail(p_data, "can't send spi message", CSRBT_EXIT_ERR1);

//  gpio_set_pin(p_data, ECSPI1_SS0, 1);  /* hold ECSPI1_SS0 high / low */
    }
lorf commented 8 years ago

Hi!

The device name is kept in PSKEY_DEVICE_NAME (0x0108) PS key contained in internal EEPROM, csrbt will not be able to change an EEPROM, since it needs different procedures to deal with it. So even if You get csrbt working, You will not be able to change the name.

I would suggest You buying cheap FT232RL breakout (<$2 on aliexpress, these contain counterfeit FT232RL chips, but verified to work with csr-spi-ftdi) and using PSTool from CSR BlueSuite with csr-spi-ftdi driver to change the PS key. BlueSuite can be downloaded from csrsupport website freely after registration.

Other options would be to get TI Stellaris Launchpad or Tiva C Launchpad, turn it into CSR programmer with this or this firmware and use that with BlueSuite.

erotavlasme commented 8 years ago

Ok thank you very much for all the information. I think I will buy a FT232RL and I will use CSR BlueSuite.

lorf commented 8 years ago

Almost forgot, if You happen to have a computer with LPT port and 32-bit Windows, You have a chance to try a simple LPT programmer with BlueSuite, as described here, but don't forget about voltage level translation!

erotavlasme commented 8 years ago

Hi, I just tried with FT232RL and CSR BlueSuite and it worked like a charm. Thank you very much. How can I repay you?

lorf commented 8 years ago

Hi! Glad You've got it working! You can donate to me via paypal: dmitry.frolov@gmail.com, a buck or two will suffice, I think. Thank You!

erotavlasme commented 8 years ago

Hi, I have just repaid you with 5 €. Take a beer also for me :)

lorf commented 8 years ago

Received. Thank You!

erotavlasme commented 8 years ago

Hi, I have a brief one more question for you. Is there any key configuration in the EEPROM of CSR 8645 that allows to a connected Bluetooth device to select only the media profile instead of both media and phone profile as default? I'm interested about this because at the moment I have to deselect phone profile in the Bluetooth device manager whenever I receive a phone call. Thank you

lorf commented 8 years ago

Hi, I sent You an email (to the e...@libero.it address) regarding the configuration.