Page 3 of 4

Re: [STM32] I2C HAL driver problems and fixes

Posted: Wed Aug 08, 2012 7:22 pm
by barthess
Hi all.
I have tested this trick on my F4x and F1x (all I have). Single byte reading works on F4x, but on F1x cause problems. According to reference manuals it will work on any STM32 platform except F1x.

Can any body test trunk rev.4544 on F2x or L1x?

Re: [STM32] I2C HAL driver problems and fixes

Posted: Wed Aug 08, 2012 7:37 pm
by Giovanni
Hi barthess,

I looked at the changes because I was curious about this workaround, just a not, that dummy return should not be necessary, the SR2 register is declared volatile so you could just write: (void)dp->SR2;

Giovanni

Re: [STM32] I2C HAL driver problems and fixes

Posted: Wed Aug 08, 2012 7:43 pm
by barthess
Thanks for hint. Fixed.

Re: [STM32] I2C HAL driver problems and fixes

Posted: Fri Aug 10, 2012 12:16 pm
by barthess
Hi Giovanni,
Can I merge that feature to stable branch? I have run long stability tests on my F4x and F1x. Ranzbak from IRC channel do the same on his F1x. All passed flawlessly.

Re: [STM32] I2C HAL driver problems and fixes

Posted: Fri Aug 10, 2012 12:23 pm
by Giovanni
You are the I2C boss, if you recommend that the driver should be backported then it is OK. Make sure to update the file headers and add a note to the readme.

Giovanni

Re: [STM32] I2C HAL driver problems and fixes

Posted: Fri Aug 10, 2012 1:20 pm
by barthess
Done at rev.4550.

Re: [STM32] I2C HAL driver problems and fixes

Posted: Fri Aug 10, 2012 5:53 pm
by Giovanni
That is not the stable branch, it is the tag of the 2.4.2 release. The stable branch is this one:

https://chibios.svn.sourceforge.net/svn ... able_2.4.x

Please revert the change on the tagged 2.4.2.

Giovanni

Re: [STM32] I2C HAL driver problems and fixes

Posted: Sat Aug 11, 2012 1:48 am
by MartinP
Hi Barthess,

I guess I have found a solution for the STM32F1XX: in RM008 Fig272 on Page 733 they state an Event EV6_1 which says
EV6_1: No associated flag event, used for 1 byte reception only. The Acknowledge disable and STOP condition are made just after EV6, that is after ADDR cleared

I thougt why not try it also in DMA mode and used the following code (first clearing ADDR and then NACK and STOP):

Code: Select all

static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
  I2C_TypeDef *dp = i2cp->i2c;
  uint32_t regSR2 = dp->SR2;
  uint32_t event = dp->SR1;
#if defined(STM32F1XX)
  /* Clear ADDR flag. */
  if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
    (void)dp->SR2;
#endif

  /* Interrupts are disabled just before dmaStreamEnable() because there
     is no need of interrupts until next transaction begin. All the work is
     done by the DMA.*/
  switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
  case I2C_EV5_MASTER_MODE_SELECT:
    dp->DR = i2cp->addr;
    break;
  case I2C_EV6_MASTER_REC_MODE_SELECTED:
    dp->CR2 &= ~I2C_CR2_ITEVTEN;
    dmaStreamEnable(i2cp->dmarx);
    dp->CR2 |= I2C_CR2_LAST;                 /* Needed in receiver mode. */
    if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2) {
      dp->CR1 &= ~I2C_CR1_ACK;
#if defined(STM32F1XX)
      dp->CR1 |= I2C_CR1_STOP;
#endif
    }
    break;
  case I2C_EV6_MASTER_TRA_MODE_SELECTED:
    dp->CR2 &= ~I2C_CR2_ITEVTEN;
    dmaStreamEnable(i2cp->dmatx);
    break;
  case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
    /* Catches BTF event after the end of transmission.*/
    if (dmaStreamGetTransactionSize(i2cp->dmarx) > 0) {
      /* Starts "read after write" operation, LSB = 1 -> receive.*/
      i2cp->addr |= 0x01;
      dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
      return;
    }
    dp->CR2 &= ~I2C_CR2_ITEVTEN;
    dp->CR1 |= I2C_CR1_STOP;
    wakeup_isr(i2cp, RDY_OK);
    break;
  default:
    break;
  }
#if !defined(STM32F1XX)
  /* Clear ADDR flag. */
  if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
    (void)dp->SR2;
#endif
}


after disabling the checks against 1 byte transfer in i2c_lld_master_receive_timeout() and in i2c_lld_master_transmit_timeout() it worked !!

Code: Select all

// #if defined(STM32F1XX)
//   chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
// #endif

On my OLIMEXINO-STM32 (the only stm32f103 I have) I could read 1 byte data from an EEPROM (first reading an array and then reading single bytes to different buffers and comparing against the first buffer)

Code: Select all

  accel_tx_data[0]=16; status = i2cMasterTransmitTimeout(&I2CD1, addr, accel_tx_data, 1, accel_rx_data, 6, tmo);
  accel_tx_data[0]=16; status = i2cMasterTransmitTimeout(&I2CD1, addr, accel_tx_data, 1, accel_rx_data0, 1, tmo);
  accel_tx_data[0]=17; status = i2cMasterTransmitTimeout(&I2CD1, addr, accel_tx_data, 1, accel_rx_data1, 1, tmo);
  accel_tx_data[0]=18; status = i2cMasterTransmitTimeout(&I2CD1, addr, accel_tx_data, 1, accel_rx_data2, 1, tmo);
  accel_tx_data[0]=19; status = i2cMasterTransmitTimeout(&I2CD1, addr, accel_tx_data, 1, accel_rx_data3, 1, tmo);
  accel_tx_data[0]=20; status = i2cMasterTransmitTimeout(&I2CD1, addr, accel_tx_data, 1, accel_rx_data4, 1, tmo);


I could only test it on a HP03 from Hope RF.

Martin

Re: [STM32] I2C HAL driver problems and fixes

Posted: Mon Aug 13, 2012 12:41 am
by barthess
Hi Martin,
I can not gain success with your code. I have tried TMP75 and LIS3 accelerometer on my Olimex STM32-103STK board.

Re: [STM32] I2C HAL driver problems and fixes

Posted: Mon Aug 13, 2012 10:33 am
by MartinP
I can not gain success with your code.


:(

I need to organize more different I2C devices on breakout-boards for testing purposes (which will be due to my vacations earliest in September) .........

regards
Martin

P.S.: I assume you have defined STM32F1XX and neutralized the chDbgCheck() calls in i2c_lld_master_receive_timeout() and in i2c_lld_master_transmit_timeout()