cancel
Showing results for 
Search instead for 
Did you mean: 

What am I missing in this attempt to make STM32F103 act as I2C Slave?

pilot
Associate III

This code, partially generated by Copilot, does only print "="

At the same time, I do see that the device PB6(SCL) and PB7(SDA) recieves packets adressed to it, requestng data.

 

#include <Arduino.h>

#define I2C_ADDRESS 0x0B

volatile int x = 0;
volatile int y = 0;
volatile int add = 0;

void setup() {
  Serial.begin(115200);

  // Initialize LED pin
  pinMode(PC13, OUTPUT);

  // Enable clock for I2C1
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;

  // Configure PB6 and PB7 as alternate function open-drain
  GPIOB->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6 | GPIO_CRL_MODE7 | GPIO_CRL_CNF7);
  GPIOB->CRL |= (GPIO_CRL_CNF6_1 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_1 | GPIO_CRL_CNF7_0);

  // Reset I2C1
  I2C1->CR1 = I2C_CR1_SWRST;
  I2C1->CR1 = 0;

  // Configure I2C1
  I2C1->CR2 = 36; // APB1 clock frequency in MHz
  I2C1->CCR = 180; // Standard mode, 100kHz
  I2C1->TRISE = 37; // Maximum rise time

  // Set I2C address
  I2C1->OAR1 = (I2C_ADDRESS << 1) | I2C_OAR1_ADDMODE;

  // Enable I2C1
  I2C1->CR1 = I2C_CR1_PE;

  // Enable ACK and POS
  I2C1->CR1 |= I2C_CR1_ACK | I2C_CR1_POS;

  // Enable I2C1 interrupts
  I2C1->CR2 |= I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN | I2C_CR2_ITERREN;

  // Enable I2C1 event interrupt in NVIC
  NVIC_EnableIRQ(I2C1_EV_IRQn);  //  Enable I2C1 event interrupt address mached etc
  NVIC_EnableIRQ(I2C1_ER_IRQn); // Enable I2C1 error interrupt.
}

void loop() {
  static unsigned long lastPrint = 0;
  if (millis() - lastPrint >= 1000) {
    lastPrint = millis();
    Serial.println("=");
  }


  if (add != 0) {
    Serial.print("U:0x");
    Serial.println(add, HEX);
    add = 0;
    digitalWrite(PC13, !digitalRead(PC13));
  }


  if (x != 0) {
    Serial.print("U:0x");
    Serial.println(x, HEX);
    x = 0;
    digitalWrite(PC13, !digitalRead(PC13));
  }

  if (y != 0) {
    Serial.println("V");
    y = 0;
  }
}

extern "C" void I2C1_EV_IRQHandler(void) {
  if (I2C1->SR1 & I2C_SR1_ADDR) {
    // Address matched
    (void)I2C1->SR1;
    (void)I2C1->SR2;
    add = 1;
  } else if (I2C1->SR1 & I2C_SR1_RXNE) {
    // Data received
    x = I2C1->DR;
  } else if (I2C1->SR1 & I2C_SR1_TXE) {
    // Data requested
    I2C1->DR = y;
    //Serial.println(y); // Print the value of y
    y = 1;
  } else if (I2C1->SR1 & I2C_SR1_STOPF) {
    // Stop condition detected
    (void)I2C1->SR1;
    I2C1->CR1 |= I2C_CR1_PE;
  }
}

extern "C" void I2C1_ER_IRQHandler(void) {
  // Handle I2C errors
  if (I2C1->SR1 & I2C_SR1_BERR) {
    I2C1->SR1 &= ~I2C_SR1_BERR;
  }
  if (I2C1->SR1 & I2C_SR1_ARLO) {
    I2C1->SR1 &= ~I2C_SR1_ARLO;
  }
  if (I2C1->SR1 & I2C_SR1_AF) {
    I2C1->SR1 &= ~I2C_SR1_AF;
  }
  if (I2C1->SR1 & I2C_SR1_OVR) {
    I2C1->SR1 &= ~I2C_SR1_OVR;
  }
  if (I2C1->SR1 & I2C_SR1_PECERR) {
    I2C1->SR1 &= ~I2C_SR1_PECERR;
  }
}
0 REPLIES 0