Page 1 of 3

Issue with I2C2 and SPI2

Posted: Fri Jan 17, 2014 9:39 am
by cruz_91
Hi,
I've got a problem with using I2C2 and SPI2 on STM32F103 MCU. I2C2 before using SPI2 work good, but when I use SPI2, I2C2 stops working. I know that Chibios use DMA to work with this peripherials and I remember to use start() and stop() functions:

Code: Select all

read_and_print_temp_I2C(); //print temperature, good result, any problems
spiStart(&SPID2, &ls_spicfg);
spiStop(&SPID2);
read_and_print_temp_I2C(); //here i've got problems


Code in function read_and_print_temp_I2C() call to transmit function contains i2cMasterTransmitTimeout function.
Temperature sensor -> MCP9800.
I also remeber to read at least 2 bytes from I2C.

Code: Select all


i2cflags_t errors;
msg_t res;
i2cInit();
i2cStart(i2cdrv, i2ccfg);
OPERATION_DELAY;
i2cAcquireBus(i2cdrv);
res = i2cMasterTransmitTimeout(i2cdrv, addr, txbuf, txbytes, rxbuf, rxbytes, timeout);
if (res != RDY_OK) {
   if (res == RDY_TIMEOUT) {
      error("I2C timeout!");
   }
   errors = i2cGetErrors(i2cdrv);
   if(errors != 0){
      error("errors from I2C: %x", errors);
   }
}

i2cReleaseBus(i2cdrv);
i2cStop(i2cdrv);



I've got RDY_TIMEOUT in res after this line:

Code: Select all

res = i2cMasterTransmitTimeout(i2cdrv, addr, txbuf, txbytes, rxbuf, rxbytes, timeout);


I used Chibios 2.4.2 for this project. When I comment dmaStreamAllocate function (file os/hal/platforms/STM32/spi_lld.c lines 246-257):

Code: Select all

      /*bool_t b;
      b = dmaStreamAllocate(spip->dmarx,
                            STM32_SPI_SPI2_IRQ_PRIORITY,
                            (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
                            (void *)spip);
      chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated");
      b = dmaStreamAllocate(spip->dmatx,
                            STM32_SPI_SPI2_IRQ_PRIORITY,
                            (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
                            (void *)spip);
      chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated");
      rccEnableSPI2(FALSE);*/


and dmaStreamSetPeripherial few lines below:

Code: Select all

    /* DMA setup.*/
    /*dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
    dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);*/


I2C2 works good with any errors.
So I think there's problem with dmaStreamRelease in spi_lld_stop.
Maybe someone can help me resolve this problem :)

Re: Issue with I2C2 and SPI2

Posted: Fri Jan 17, 2014 10:10 am
by Giovanni
Hi,

Looking at your code:

Code: Select all

read_and_print_temp_I2C(); //print temperature, good result, any problems
spiStart(&SPID2, &ls_spicfg);
spiStop(&SPID2);
read_and_print_temp_I2C(); //here i've got problems


Do you perform an i2cStart() after spiStop()? this is not evident in the above code. The I2C needs to reallocate the DMA channels.

Another note, never call i2cInit() or any other xxxInit() function. It is already done in halInit() and the functions are not meant to be called twice.

Giovanni

Re: Issue with I2C2 and SPI2

Posted: Fri Jan 17, 2014 10:24 am
by cruz_91
Hi,

Do you perform an i2cStart() after spiStop()? this is not evident in the above code. The I2C needs to reallocate the DMA channels.

Yes, I always perform i2cStart() after spiStop(). I do it in transmit function before i2cMasterTransmitTimeout().

Another note, never call i2cInit() or any other xxxInit() function. It is already done in halInit() and the functions are not meant to be called twice.

I based my code on i2c test from testhal where i2cInit() is used.

Re: Issue with I2C2 and SPI2

Posted: Sat Jan 18, 2014 2:12 pm
by cruz_91
For temporary solution I rewrite I2C driver to use interrupt mode and communication with mcp9800 sensors working good.
Giovanni, have you ever meant about rewrite peripherials drivers to use DMA and Interrupt modes?
I know that DMA is the best solution, but in STM32F1 Interrupt mode allows to use SPI2 and I2C2 without problems.

Re: Issue with I2C2 and SPI2

Posted: Sat Jan 18, 2014 2:40 pm
by Giovanni
I the code I see nothing obviously wrong, the I2C should be able to work after SPI but I am unable to test this scenario right now. My idea is the SPI data-request line is not properly disabled in spiStop() and then interferes with I2C operations but I cannot test this hypothesis.

I have considered to implement an IRQ-only mode but the development bandwidth is limited and there are more urgent things in my list.

Giovanni

Re: Issue with I2C2 and SPI2

Posted: Sat Jan 18, 2014 4:51 pm
by part1zan_
So I cannot use SPI2 with I2C2, and that's how it should be? Will that be fixed further?

Re: Issue with I2C2 and SPI2

Posted: Sun Jan 19, 2014 3:55 pm
by wbober
@part1zan_

You can but not both at the same time since they share DMA channel. The issue we have is that when you switch off SPI and switch on I2C the later doesn't work properly. To deal with the problem we decided to modify the driver and use IRQs instead of DMA.

It would be nice if someone could try to reproduce the problem. An I2C device is enough to reproduce the problem. For us it was sufficient to call spiStart()/spiStop to broke further communication on i2c bus. I'm not convinced that the problem is in the spi driver though.

Re: Issue with I2C2 and SPI2

Posted: Sun Jan 19, 2014 4:00 pm
by Giovanni
I don't have an I2C device to plug to an F103, I will try to reproduce it when I will be able to.

Of course any help would be very welcome.

Giovanni

Re: Issue with I2C2 and SPI2

Posted: Mon Jan 20, 2014 9:53 pm
by mukululul
Hi Giovanni,
I am using I2C2 and SPI1 and discovering the same problem like I have seen before with SPI2. I can see on the scope that sending works ok but I do not see a response from the device.
This happens only when I enable SPI, without SPI I2C works perfectly.

What do you think, shouldn't I2C2 and SPI1 with DMA a the same time work?

Thanks.

Michael

Re: Issue with I2C2 and SPI2

Posted: Wed Jan 22, 2014 9:52 pm
by part1zan_
Hm, I've got (plenty of) i2c devices, a built-in spi device and an external one. Could you please give me the exact steps to reproduce the issue, and all of the data you need for debug?