Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2C slave: enable matching any configured slave address #1801

Merged
merged 3 commits into from
Aug 30, 2022

Conversation

deltaford
Copy link
Contributor

@deltaford deltaford commented Aug 13, 2022

I2C slave: Enable multi slave address onReceive/onRequest handling.

Currently the I2C slave onRequest/onReceive events are only triggered if matching OwnAddress1.
With this proposed change the events are triggered for any configured, enabled and matching slave address.

I2C slave: Enable multi slave address onReceive/onRequest handling.
@deltaford deltaford changed the title Enable multi slave address handling I2C slave: Enable multi slave address handling Aug 15, 2022
@fpistm fpistm requested a review from ABOSTM August 22, 2022 15:48
@ABOSTM
Copy link
Contributor

ABOSTM commented Aug 23, 2022

Hi @deltaford,
I am not sure about the interest of this change:
On STM32, in I2C slave mode, I2C hardware will filter on I2C Addresses configured in the hardware registers.
2 addresses are configurable (See reference manual I2C_OAR1 and I2C_OAR2).
But in stm32duino, only 1 address is configured, OwnAddress1:

handle->Init.OwnAddress1 = ownAddress;

Note that OwnAddress2 is systematically set to 0

So AFAICS, this change will not help enabling multi slave address.
Did you make some testing with your patch? does it change the behavior ?
(does it really answer to several I2C addresses ?)

That said, the software check against OwnAddress1 seems useless to me, because I2C hardware should already check that.
So I would be in favor of removing the check onn AddrMatchCode.

@deltaford
Copy link
Contributor Author

Hi @ABOSTM
This change do not provide stm32duino capability to configure multiple i2c slave addresses, ideal that should also be implemented instead of OA2 being zeroed out as it is now. But that was too big of a bite for myself to implement.
Configuring multiple addresses is fairly easy from user code by modifying the I2C_OAR2 register.
My proposed change enable stm32duino to handle events (onReceive/onRequest) for multiple slave addresses on same i2c.
Also as you mentioned, the AddrMatchCode check is redundant since the code would not execute unless i2c hardware already matched configured addresses. Removing it completely would optimize the code and enable multi address handling at the same time.
With OA1, OA2 and OA2MSK i2c can be configured to match 1, 2 or more up to all possible addresses (except reserved).
With this change it is possible to handle slave events on multiple addresses and also different handling depending on what address matched.
I have tested the patch and I'm using it in a project where the functionality was required.

Here is also a small example

// STM32 Multi address slave example - I2C1 (Slave: #2, #3), I2C2 (Master), externally connected and with external pullups

#include <Wire.h>
TwoWire Wire1(PB7, PB6);
TwoWire Wire2(PB11, PB10);

uint8_t I2C1_ADDR1 = 2, I2C1_ADDR2 = 3, tmpin = 0, OA2MASK = 0 ; 

void setup(){
  Serial2.begin(115200);           
  delay(50);  
  Wire1.begin(I2C1_ADDR1);         
  Wire1.onRequest(requestEvent); 
  Wire1.onReceive(receiveEvent); 
  MODIFY_REG(I2C1->OAR2, I2C_OAR2_OA2 , (I2C1_ADDR2 << 1) | (OA2MASK << 10));  // Configure OwnAddress2 
  SET_BIT(I2C1->OAR2, I2C_OAR2_OA2EN);      // Dual addressing mode enable
  Wire2.begin();
}
void loop(){
  delay(1000);
  Wire2.beginTransmission(I2C1_ADDR1);
  Wire2.write(7);
  delay(1000);
  Wire2.endTransmission();  
  Wire2.beginTransmission(I2C1_ADDR2);
  Wire2.write(8);
  Wire2.endTransmission();  
  tmpin = Wire2.requestFrom(I2C1_ADDR1,(uint8_t) 1);
  tmpin = Wire2.requestFrom(I2C1_ADDR2,(uint8_t) 1);  
}
void receiveEvent(int howMany){
  Serial2.print("Slave receive. AddrMatch: "); Serial2.println((I2C1->ISR & I2C_ISR_ADDCODE) >> 17); ;
  int x = Wire1.read();        // receive byte as an integer
}
void requestEvent(){
  Serial2.print("Slave request. AddrMatch: "); Serial2.println((I2C1->ISR & I2C_ISR_ADDCODE) >> 17); 
  Wire1.write(4);  // respond 
}

@ABOSTM
Copy link
Contributor

ABOSTM commented Aug 26, 2022

Ok, thanks for your detailed explanation.
So would you mind updating your PR to fully remove the check ?

Enable handling of multiple I2C slave addresses by removing redundant AddrMatchCode check.
@deltaford
Copy link
Contributor Author

It's now updated and the check is removed.

@ABOSTM
Copy link
Contributor

ABOSTM commented Aug 26, 2022

@deltaford
Thanks for the update, there is an astyle issue about indentation (see CI error)
Could you fix it please.
If needed: https://github.com/stm32duino/wiki/wiki/Astyle

@deltaford
Copy link
Contributor Author

Should be fixed now

Copy link
Contributor

@ABOSTM ABOSTM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@fpistm fpistm added this to In progress in STM32 core based on ST HAL via automation Aug 30, 2022
@fpistm fpistm added this to the 2.4.0 milestone Aug 30, 2022
@fpistm fpistm merged commit 0d6720c into stm32duino:main Aug 30, 2022
STM32 core based on ST HAL automation moved this from In progress to Done Aug 30, 2022
@fpistm fpistm changed the title I2C slave: Enable multi slave address handling I2C slave: enable matching any configured slave address Aug 30, 2022
cparata pushed a commit to cparata/Arduino_Core_STM32 that referenced this pull request Jan 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

None yet

3 participants