We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
Memory overflow occurs when receiving 2 bytes using the driver. Works fine for 1 byte.
Here is a code to simulate the problem:
ARM_DRIVER_I2C *I2Cdrv = &Driver_I2C1; uint8_t buf[2]; uint32_t n; I2Cdrv->MasterReceive(0x55, buf, 2, false); osDelay(50); n = I2Cdrv->GetDataCount(); // n = 544
I2C_STM32F4xx.c has an I2C Event Interrupt handler (I2C_EV_IRQHandler). Inside of this function there is a code to process such case (when 2 bytes remaining to receive):
if (sr1 & I2C_SR1_RXNE) { /* End master receiver operation */ if ((rx->num == 2U) || (rx->cnt == (rx->num - 2U))) { /* Two bytes remaining */ if (tr->ctrl & XFER_CTRL_XPENDING) { i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN; } else { i2c->reg->CR1 |= I2C_CR1_STOP; } /* Read data N-1 and N */ rx->data[rx->cnt++] = (uint8_t)i2c->reg->DR; rx->data[rx->cnt++] = (uint8_t)i2c->reg->DR; tr->status.busy = 0U; tr->status.mode = 0U; i2c->reg->CR1 &= ~I2C_CR1_POS; if (tr->cb_event) { tr->cb_event (ARM_I2C_EVENT_TRANSFER_DONE); } } else { /* Three bytes remaining */ i2c->reg->CR1 &= ~I2C_CR1_ACK; /* Read data N-2 */ rx->data[rx->cnt++] = (uint8_t)i2c->reg->DR; } }
But it never executed. Instead this code (in I2C_EV_IRQHandler) executes again and again, causing memory overflow:
if (sr1 & I2C_SR1_RXNE) { /* Master receiver */ rx->data[rx->cnt++] = (uint8_t)i2c->reg->DR; if (rx->num == 1U) { /* Single byte transfer completed */ i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN; if (tr->ctrl & XFER_CTRL_XPENDING) { i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN; } /* (STOP was already sent during ADDR phase) */ tr->status.busy = 0U; tr->status.mode = 0U; if (tr->cb_event) { tr->cb_event (ARM_I2C_EVENT_TRANSFER_DONE); } } else { if (rx->cnt == (rx->num - 3U)) { /* N > 2 byte reception, begin N-2 data reception */ i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN; /* Wait for BTF */ } } }
This driver comes with Keil STM32F4xx_DFP v2.14.0.
Best regards,
Eugene