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
Thanks for reporting this issue, Eugene. Please open a corresponding Support Ticket according to:
http://www2.keil.com/support/silver
and we will trigger an investigation.