STM32F072C8 I2C hal

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

halba
Posts: 18
Joined: Sun May 10, 2015 9:13 am

STM32F072C8 I2C hal

Post by halba »

Hello ChibiOS team,

I am starting to work with your OS v3.0.0p3 on the STM32F072C8 in IAR. So far, everything works well (OS, CAN and SPI are running properly), but now I am trying to get working I2C and I have some problems.

1. When I start the I2C before SPI, SPI do not work:

Code: Select all

  //SPI works
  canStart(&CAND1, &cancfg);
  i2cStart(&I2CD1, &i2cfg1);
  spiStart(&SPID1, &spi1cfg);

  //SPI do not works
  canStart(&CAND1, &cancfg);
  spiStart(&SPID1, &spi1cfg);
  i2cStart(&I2CD1, &i2cfg1);
(I2C behaves in both cases same wrong)

2. I am trying to send 2 bytes to EEPROM (I2C EEPROM address is 0xA0 and two bytes are 0x00, 0xAA). The transfer works well with ST hal (first picture - tek00005), but it sends only one byte with the ChibiOS hal I2C (second picture - tek00006) and the byte (probably I2C address) seems to be also wrong. The HW is for both cases same.
ST hal
ST hal
tek00005.png (18.18 KiB) Viewed 4528 times

ChibiOS hal
ChibiOS hal
tek00006.png (14.29 KiB) Viewed 4528 times

The code for sending the data in ChigiOS is like this:

Code: Select all

uint8_t i2cTxBuffer[2] = {0x00, 0xAA};
uint8_t i2cRxBuffer[8];
uint8_t status = 0;

...

static const I2CConfig i2cfg1 = {
    STM32_TIMINGR_PRESC(0x02) | STM32_TIMINGR_SCLH(0x09) | STM32_TIMINGR_SCLL(0x0E),
    I2C_CR1_PE,
    I2C_CR2_AUTOEND
};

...

  canStart(&CAND1, &cancfg);
  i2cStart(&I2CD1, &i2cfg1);
  spiStart(&SPID1, &spi1cfg);

...

  if(Button[1].flags & BTN_SHORT)
  {
    i2cAcquireBus(&I2CD1);
    status = i2cMasterTransmitTimeout(&I2CD1, 0xA0, i2cTxBuffer, 2, i2cRxBuffer, 8, MS2ST(100));
    i2cReleaseBus(&I2CD1);
    Button[1].flags &= ~(BTN_SHORT);
  }


3. The TIMINGR wasn't set, I must switched the order of the registers initialization in the function i2c_lld_start in os\hal\ports\STM32\LLD\I2Cv2\i2c_lld.c, the TIMINGR before CR1 and CR2:

Code: Select all

  /* Setup I2C parameters.*/
  dp->TIMINGR = i2cp->config->timingr;
 
  /* Reset i2c peripheral, the TCIE bit will be handled separately.*/
  dp->CR1 = i2cp->config->cr1 | I2C_CR1_ERRIE | I2C_CR1_STOPIE |
            I2C_CR1_NACKIE | I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN;

  /* Set slave address field (master mode) */
  dp->CR2 = (i2cp->config->cr2 & ~I2C_CR2_SADD);
Now the register is set properly.

Sorry for bothering you, I am pretty new to your OS so maybe I am just doing something trivial wrongly, but it would be very helpful for me if you can give me some hint at least for the problem number 2 because it is really blocking right now.

Thanks,
halba
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F072C8 I2C hal

Post by Giovanni »

Hi,

It is because I2C and SPI use the same DMA channels so there is a conflict... it is a limitation of the device.

The workaround is to start/stop the colliding drivers and never use them at the same time. The DMA channels are taken by the xxxStart() functions ad freed by the xxxStop() functions.

Giovanni
halba
Posts: 18
Joined: Sun May 10, 2015 9:13 am

Re: STM32F072C8 I2C hal

Post by halba »

Hi Giovanni,

Thank you for the hint, it was really helpful. In fact, this device can run I2C1 also on the DMA channels 6 and 7. Anyway, it was little bit tricky to get it working because the DMA hal for the STM32F0 do not support channels 6 and 7 in default so it was necessarily to extend it and also one bit in SYSCFG->CFGR1 register must be set to remap the I2C1 to different DMA channels. Now both peripherals works independently.

halba
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F072C8 I2C hal

Post by Giovanni »

Hi,

Yes, I forgot, on some devices manual remapping is required because the peripherals default to non-existent DMA channels.

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F072C8 I2C hal

Post by Giovanni »

Hi,

I just added a no-DMA mode for the I2Cv2 driver, you could give it a try.

Giovanni
halba
Posts: 18
Joined: Sun May 10, 2015 9:13 am

Re: STM32F072C8 I2C hal

Post by halba »

Thanks, but I am satisfied with solution with remapping. Maybe later when I will need this DMA channel for another purpose.
DGW
Posts: 47
Joined: Fri May 30, 2014 9:14 am

Re: STM32F072C8 I2C hal

Post by DGW »

Good afternoon.
I have a conflict, DMA for I2C1 and USART1. Add a line in the file STM32F0xx / hal_lld.s (function hal_lld_init (void))
SYSCFG-> CFGR1 | = SYSCFG_CFGR1_I2C1_DMA_RMP;
and changed the file STM32F0xx/stm32_registry.h
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) //3)
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) //2)
It does not work, what else have to change? Thank you.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F072C8 I2C hal

Post by Giovanni »

Hi,

It should be sufficient.

Are those channels already used? (SPI2)
You set the remap bit, is it really set? try doing it from the main after halInit().

Giovanni
DGW
Posts: 47
Joined: Fri May 30, 2014 9:14 am

Re: STM32F072C8 I2C hal

Post by DGW »

I look in the debugger, the bit is set (in SYSCFG-> CFGR1). The project uses USART1 and I2C1, SPI do not use. Hangs on a line (file ARMCMx/ RVCT/vectors.c)
b _unhandled_exception
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F072C8 I2C hal

Post by Giovanni »

I understood the problem.

The DMA driver only supports the first 5 DMA channels, channels 6 and 7 were not present in initial F0 devices. The driver requires an update.

You could copy the missing code in stm32_dma.c from the STM32L1 file (ISRs and missing lines in the DMA streams array).

Giovanni
Post Reply