I2C implementation for STM32

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Location: Minsk, Belarus
Been thanked: 7 times

Re: I2C implementation for STM32

Postby barthess » Mon Dec 05, 2011 1:20 pm

Forgot something. Example of I2C configuration from my mcucong.h

Code: Select all

#define STM32_I2C_USE_I2C1                  FALSE
#define STM32_I2C_USE_I2C2                  TRUE
#define STM32_I2C_USE_I2C3                  FALSE
#define STM32_I2C_I2C1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 0)
#define STM32_I2C_I2C1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 6)
#define STM32_I2C_I2C2_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C2_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C3_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C3_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 4)
#define STM32_I2C_I2C1_IRQ_PRIORITY         6
#define STM32_I2C_I2C2_IRQ_PRIORITY         6
#define STM32_I2C_I2C3_IRQ_PRIORITY         6
#define STM32_I2C_I2C1_DMA_PRIORITY         1
#define STM32_I2C_I2C2_DMA_PRIORITY         1
#define STM32_I2C_I2C3_DMA_PRIORITY         1
#define STM32_I2C_I2C1_DMA_ERROR_HOOK()     chSysHalt()
#define STM32_I2C_I2C2_DMA_ERROR_HOOK()     chSysHalt()
#define STM32_I2C_I2C3_DMA_ERROR_HOOK()     chSysHalt()

User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Location: Minsk, Belarus
Been thanked: 7 times

Re: I2C implementation for STM32

Postby barthess » Mon Dec 05, 2011 6:33 pm

Rev. 3553
Added support of I2C1 and I2C3. They may contain errors because I does not have possibility to test they.

matis
Posts: 53
Joined: Fri Jul 01, 2011 1:46 pm

Re: I2C implementation for STM32

Postby matis » Tue Dec 06, 2011 11:28 am

Thanks for adding support for I2C1 :)

When I try to compile the OS I get errors on the i2c_lld.h file; It tells me that "invalid DMA stream associated to USART1 RX", "invalid DMA stream associated to USART1 TX" and for I2C2 too.
I copied the mcuconf.h like you stated above, but then it tells me STM32_I2C_I2C1_RX_DMA_STREAM is redefined.
My F103 doesn't have STM32_ADVANCED_DMA so I therefore the STM32_I2C_I2C1_RX_DMA_STREAM TX and I2C2 are static and doesn't need to be defined in my project-specific mcuconf.h ; So that gets me rid of the redefinition warning.

Unfortunately, the fixed non-advance DMA STM32_I2C_I2C1_RX_DMA_STREAM seems to be invalid by default, where the comment around tells me different.

Is this an f103 issue or a little bug in the i2c_lld files? When you need more info, please let me know!

Edit The testhal/STM32F1xx/I2C on the other hand builds fine.

User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Location: Minsk, Belarus
Been thanked: 7 times

Re: I2C implementation for STM32

Postby barthess » Tue Dec 06, 2011 2:46 pm

matis wrote:When I try to compile the OS I get errors on the i2c_lld.h file; It tells me that "invalid DMA stream associated to USART1 RX", "invalid DMA stream associated to USART1 TX" and for I2C2 too.

Yea, there was lots of copypaste errors. Try to check out fresh code (rev. 3560). It also contain updated testhal\STM32F1xx\I2C
Thankfully to clean and abstract Giovanni's DMA code driver works without changes both on stm32f103 and stm32f407 (other untested, but I hope works too).
Any feedbacks and error reports are welcome.

matis
Posts: 53
Joined: Fri Jul 01, 2011 1:46 pm

Re: I2C implementation for STM32

Postby matis » Tue Dec 06, 2011 3:56 pm

barthess,

I updated to rev 3560, but the problem still seems to be there. I still get the error: #error "invalid DMA stream associated to USART1 RX" in /os/hal/platforms/STM32/i2c_lld.h:200 and for the TX and I2C2.
I also have CAN, SPI and SERIAL enabled in the halconf and mcuconf.

Is there anything I should check that is different from the 2.3.4 tag, because that version builds fine?

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: I2C implementation for STM32

Postby Giovanni » Tue Dec 06, 2011 4:29 pm

Probably the problem is in the hal_lld_xxxxxxx.h files, those have additional attributes related to the DMA association, see the SPI attributes for example.

Giovanni

matis
Posts: 53
Joined: Fri Jul 01, 2011 1:46 pm

Re: I2C implementation for STM32

Postby matis » Tue Dec 06, 2011 4:37 pm

I think I found a I2C bug in the original 2.3.4 I2C error handling.
When read through write to a non-exisiting I2C node, my system crashed into a "lockup after double fault".

When stepping through the code, I ended up at chevents.c (/os/kernel/src/) on line 244 (elp = esp->es_next;) comming fron the i2c_serve_error_interrupt()

elp becomes NULL, but the elp->el_listner and elp->el_mask are valid pointers.

When stepping into the chEvtSignalFlagsI() the chDbgCheck doesn't assert, but within the /* Test on the AND/OR conditions wait states.*/ the system crashes.

All the tp->* seems to be valid but when I try to fold open the variable tp, OpenOCD gives me the following error:

Code: Select all

target halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08006ba0 msp: 0x20000400
Error: JTAG-DP STICKY ERROR
Error: MEM_AP_CSW 0x23000052, MEM_AP_TAR 0x4f491c4c
Error: JTAG-DP STICKY ERROR
Error: MEM_AP_CSW 0x23000052, MEM_AP_TAR 0x4f491c4c
Warn : Block read error address 0x4f491c48, count 0x2


This is the content of tp at the moment of crash:

Code: Select all

tp   0x08006ba1   
   p_next   0x844c20b6   
   p_prev   0x4f8809f3   
   p_prio   2214855408   
   p_ctx   {...}   
   p_newer   0x038f6ff3   
   p_older   0x1bfe54f0   
   p_name   0x4f491c48   
   p_stklimit   0xff3255f0   
   p_state   247   
   p_flags   214   
   p_refs   255   
   p_time   1330190152   
   p_u   {...}   
   p_waiting   {...}   
   p_msgqueue   {...}   
   p_msg   82904160   
   p_epending   82904324   
   p_mtxlist   0x9c4b1605   
   p_realprio   366212674   
   p_mpool   0x4f491648


Can anyone reproduce this problem?

matis
Posts: 53
Joined: Fri Jul 01, 2011 1:46 pm

Re: I2C implementation for STM32

Postby matis » Tue Dec 06, 2011 4:40 pm

Giovanni wrote:Probably the problem is in the hal_lld_xxxxxxx.h files, those have additional attributes related to the DMA association, see the SPI attributes for example.

Giovanni

I don't have an altered hal_lld_STM32F1xx I use the one provided with the i2c_dev branch.

User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Location: Minsk, Belarus
Been thanked: 7 times

Re: I2C implementation for STM32

Postby barthess » Tue Dec 06, 2011 7:27 pm

matis
Fixed. Check out rev. 3561.
If you want to handle situations of communicating with non-exisiting I2C node use error callback, for example:

Code: Select all

static void i2c_tmp75_error_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
  (void)i2cscfg;
  if (i2cp->errors & I2CD_ACK_FAILURE){
    while(TRUE); // wrong address
  }
}


Giovanni
I observe some strange behavior of DMA in exceptional situations.
1. I configure DMA channel from transaction starter code:

Code: Select all

  mode = STM32_DMA_CR_DIR_P2M;
  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
  dmaStreamSetMode(i2cp->dmarx, ((i2cp->dmamode) | mode));

but not set DMAEN bit (set it only if ACK from slave received).
2. Begin transaction. If slave not acknowlege code jumps to error interrupt handler. There I first of all disable DMA:

Code: Select all

  chSysLockFromIsr();
  dmaStreamClearInterrupt(i2cp->dmatx);
  dmaStreamClearInterrupt(i2cp->dmarx);
  dmaStreamDisable(i2cp->dmatx);
  dmaStreamDisable(i2cp->dmarx);
  chSysUnlockFromIsr();

3. Do some error conditioning and exit from error handler.
All looks good, BUT code anyway jumps to DMA transmission end handler. What I do wrong?

All guys
Please say on what MCU you observe errors, because code and behavior not 100% identical for F4 and F1 series.

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: I2C implementation for STM32

Postby Giovanni » Tue Dec 06, 2011 8:03 pm

Hi,

It is strange, try to disable the stream first and THEN do the clearing, it an interrupt is triggered between the clearing and the disable it would remain pending. It looks like a subtle race condition.

Giovanni


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 47 guests