2018-05-30 09:02 AM
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 linesI2C1->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-busy2018-08-10 09:35 AM
Sorry, bumping old zombie unanswered threads off my feed
2018-11-15 01:17 AM
Hi!Have you found a solution to the problem? I also encountered the same problem.