cancel
Showing results for 
Search instead for 
Did you mean: 

I2C always reports ''busy'', SR2->BERR

Philip Lane
Associate II
Posted on May 30, 2018 at 18:02

I'm using an STM8L051F3 chip as slave and a STM32L476 as master, but the STM8L refuses to respond, it keeps reporting a SR2->BERR aka busy error.

I know the STM32 code is ok as I had two of them working on an I2C link without any problems, but when I use an STM8 as a slave it fails.

The clock and data lines look ok on a scope, nice and square. I have compared the signals from 32-32 and 32-8, in the 32-8 the 'ACK' pulse remains high instead of being pulled low.

STM8L code pasted below

--- I2C setup : ---

void Init_I2C(void)

{

CLK->CKDIVR = 0; // sys clock /1

CLK->PCKENR1 |= 0x08; // enable I2C peripheral clk

// Init GPIO for I2C use

GPIOC->DDR |= 0x03; // Output mode

GPIOC->CR1 &= 0xFC; // Output with Open drain

GPIOC->CR2 |= 0x03; // Fast

// --- SET BEFORE PE = 1 ---

I2C1->TRISER = 2;

// Set the clock control register (CCR)

I2C1->CCRL = 0x50; // Provides an output clock of 100kHz...

I2C1->CCRH = (u8)0; // ...at 50% duty cycle

// Cannot change I2C1 parameters if it is not active !

I2C1->CR1 = 0x01; // Enable I2C peripheral

I2C1->CR2 = 0x04; // Enable I2C acknowledgement

I2C1->FREQR = 16; // Set I2C Freq value (16MHz)

I2C1->OARL = (SLAVE_ADDRESS << 1) ; // set slave address (put 0xA2 for the register dues to7bit address)

I2C1->OARH = 0x40; // Set 7bit address mode

I2C1->ITR = 0x07; // all I2C interrupt enable

}

--- Interrupt ---

@far @interrupt void I2C_Slave_check_event(void)

{

static u8 sr1;

static u8 sr2;

static u8 sr3;

// save the I2C registers configuration

sr1 = I2C1->SR1;

sr2 = I2C1->SR2;

sr3 = I2C1->SR3;

// Communication error?

if (sr2 & I2C_SR2_WUFH)

{

I2C1->CR2 |= I2C_CR2_STOP; // stop communication - release the lines

I2C1->SR2 = 0; // clear all error flags

}

else if (sr2 & I2C_SR2_OVR)

{

I2C1->CR2 |= I2C_CR2_STOP; // stop communication - release the lines

I2C1->SR2 = 0; // clear all error flags

}

else if (sr2 & I2C_SR2_BERR)

{

// ---- ALWAYS GET THIS FLAG SET ----

I2C1->CR2 |= I2C_CR2_STOP; // stop communication - release the lines

I2C1->SR2 = 0; // clear all error flags

}

// More bytes received ?

if ((sr1 & (I2C_SR1_RXNE | I2C_SR1_BTF)) == (I2C_SR1_RXNE | I2C_SR1_BTF))

{

I2C_byte_received(I2C1->DR);

}

// Byte received ?

if (sr1 & I2C_SR1_RXNE)

{

I2C_byte_received(I2C1->DR);

}

// NAK? (=end of slave transmit comm)

if (sr2 & I2C_SR2_AF)

{

I2C1->SR2 &= ~I2C_SR2_AF; // clear AF

I2C_transaction_end();

}

// Stop bit from Master (= end of slave receive comm)

if (sr1 & I2C_SR1_STOPF)

{

I2C1->CR2 |= I2C_CR2_ACK; // CR2 write to clear STOPF

I2C_transaction_end();

}

// Slave address matched (= Start Comm)

if (sr1 & I2C_SR1_ADDR)

{

I2C_transaction_begin();

}

// More bytes to transmit ?

if ((sr1 & (I2C_SR1_TXE | I2C_SR1_BTF)) == (I2C_SR1_TXE | I2C_SR1_BTF))

{

I2C1->DR = I2C_byte_write();

}

// Byte to transmit ?

if (sr1 & I2C_SR1_TXE)

{

I2C1->DR = I2C_byte_write();

}

}

#stm8l051f3 #i2c-busy
2 REPLIES 2

Sorry, bumping old zombie unanswered threads off my feed

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
JCui
Associate

Hi!Have you found a solution to the problem? I also encountered the same problem.