I'm integrating MPU9250 sensor into spark and run into the issue when requests for 1 byte would hang I2C.
And after I found a fix and planned to raise an issue I found it is already here.
Looks like default DMA code will not work as is, so I changed the following in the spark_wiring_i2c.cpp
See //Special handling of the 1 byte read
section
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
system_tick_t _millis;
// clamp to buffer length
if(quantity > BUFFER_LENGTH)
{
quantity = BUFFER_LENGTH;
}
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
_millis = millis();
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
}
/* Send Slave address for read */
I2C_Send7bitAddress(I2C1, address, I2C_Direction_Receiver);
_millis = millis();
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
}
if(quantity == 1) { //Special handling of the 1 byte read
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Test on I2C1 EV7 and clear it */
_millis = millis();
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
{
if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
}
rxBuffer[0] = I2C_ReceiveData(I2C1);
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = 1;
return rxBufferLength;
}
TwoWire_DMAConfig(rxBuffer, quantity, RECEIVER);
/* Enable DMA NACK automatic generation */
I2C_DMALastTransferCmd(I2C1, ENABLE);
/* Enable I2C DMA request */
I2C_DMACmd(I2C1, ENABLE);
/* Enable DMA RX Channel */
DMA_Cmd(DMA1_Channel7, ENABLE);
/* Wait until DMA Transfer Complete */
_millis = millis();
while(!DMA_GetFlagStatus(DMA1_FLAG_TC7))
{
if(EVENT_TIMEOUT < (millis() - _millis)) break;
}
/* Disable DMA RX Channel */
DMA_Cmd(DMA1_Channel7, DISABLE);
/* Disable I2C DMA request */
I2C_DMACmd(I2C1, DISABLE);
/* Clear DMA RX Transfer Complete Flag */
DMA_ClearFlag(DMA1_FLAG_TC7);
/* Send STOP Condition /
if(sendStop == true)
{
/ Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = quantity - DMA_GetCurrDataCounter(DMA1_Channel7);
return rxBufferLength;
}