libopencm3
libopencm3 copied to clipboard
I2c v2 enable ack
Judging from their reference manual, stm32 i2c-v1 peripherals immediately start receiving as soon as their OAR1 address is matched; however, they may refrain from sending an ACK if the i2C_CR1 "ACK" bit is not set. Hence, a "i2c_enable_ack()" function starts slave reception and i2c_disable_ack() stops it.
The i2c-v2 peripherals have an "OA1EN: Own Address 1 enable" bit to enable or disable ACKing the slave address. This bit does have a definition in i2c_common_v2.h (I2C_OAR1_OA1EN_DISABLE and ..._ENABLE), but there is no "I2C_OAR1(I2C1) |= I2C_OAR1_OA1EN_ENABLE" in the v2 code. This effectively makes the slave in v2 inoperable.
A proper way to set this up may be to just add the "i2c_enable_ack()" and "i2c_disable_ack()" calls to the v2 code, changing these calls to implement I2C_OAR1(I2C1) |= I2C_OAR1_OA1EN_ENABLE, which is what I did. Tested on a stm32f030f4p6. Without enabling OA1EN, there is no slave reception; using i2c_enable_ack, receiving works as intended.
this is something you need onyl for i2c slaves right? do you have some example code to help test this? pretty please? :)
Yes, this is for slave reception only, the OA1EN bit makes the slave ACK to its' slave address - essentially saying "yes, I'm here". It is defined in the STM32F030/070 Reference manual on page 584: "Bit 15 OA1EN: Own Address 1 enable / 0: Own address 1 disabled. The received slave address OA1 is NACKed. / 1: Own address 1 enabled. The received slave address OA1 is ACKed." (Please note that the NACK that is mentioned is a bit confusing; NACK in I2C is the absence of an ACK, i.e. do not react, don't do anything.) This function is essential to make the F030/F070 receive i2c-info as a slave receiver on the bus. If the slave doesn't ACK to its' own address, the master won't know there is a slave and it won't send anything. Regarding an example: any i2c slave program for STM32 F1 of F3 will do. (Should I write one? What should it do? Receive a byte - and then, what?)
Here is - rather random - I2C slave code for stm32f1: https://github.com/amitesh-singh/i2c-slave-stm32f1/blob/master/main.cpp - it's easily portable to f0; but it will only work if you actually add the i2c_enable_ack() function. Without it, (i.e. if you just leave it out), f0 will not start slave reception.