Burst I2C read

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to port an Arduino library to use with AVR-IOT development board. I am using MPLAB X IDE.

I am able to use "i2c_simple_master.h" to do I2C read and write. But I have following snippet (in Arduino) which I am not able to rewrite:

    Wire.beginTransmission(slaveAddress);
    Wire.write(regAddress); // FIFO Data register
    Wire.endTransmission(false);
    for (uint8_t i = 0; i < 8; i++) {
        Wire.requestFrom(slaveAddress, 32);
        if (Wire.available()) {
            data[0] = Wire.read();
            data[1] = Wire.read();
            data[2] = Wire.read();
            data[3] = Wire.read();
            // read up to 32
        }
    }

 

 Basically I want to read FIFO data in chunks of 32 or less. How can I imitate it in avr?  Can all 256 bytes be read in single i2c read?

 

Naveen

Last Edited: Mon. Jan 4, 2021 - 10:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Microchip Studio can import an Arduino "sketch" - this turns it into just a plain, ordinary C++ Project.

 

https://www.avrfreaks.net/forum/microchip-trying-wean-people-arduino-atmel-studio

 

From there, you could go to MPLAB ... ?

 

Alternatively, there are plenty of well-established "raw C" I2C libraries; eg, Fleury

 

https://www.avrfreaks.net/commen...

 

EDIT

 

This: https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/EV15R70A ?

 

 

Does it not come with examples?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jan 4, 2021 - 10:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your reply. I am trying to use the Arduino library in one of the existing AVR-IOT WA Sensor Node project. This is my first time with this development board and environment. I am wondering if changing to C++ project would mess up with the existing project. 

 

EDIT:

 

This is the same board as you mentioned in the link. I am able to use simple I2C code. But there is no example how to do burst read as shown in the Arduino code snippet.

Naveen

Last Edited: Mon. Jan 4, 2021 - 10:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh,  I hate this Forum.   If you press the wrong key you lose all the message that you have just typed.

 

The Master and Slave roles are significant.   The Master knows what she wants and the Slave does whatever he is told.

 

You request a certain number of bytes.   The Wire.h library tells you how many were successfully received via the Wire.available() method.

 

Your Arduino code appears to request 256 bytes in 8 chunks of 32 bytes.   The Wire buffer is only 32 bytes.   So you can't request anything larger than 32.

 

I suggest that you request the correct number of bytes in Arduino code.   And return an error if you don't receive the correct number.

Likewise,  request the correct number of bytes in an C or C++ library call.   And return an error if you don't receive the correct number.

 

Note that I2C hardware chips might behave differently.    I2C just controls the bus traffic.

An I2C chip might differentiate between i2c_stop, i2c_start and an i2c_restart.   A 24Cxx eeprom will not ACK its Slave address when it is busy doing a Page Write.  

 

David.

Last Edited: Mon. Jan 4, 2021 - 11:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now I am using the code below. I am not getting any error but I wanted to confirm if I2C in the AVR-IOT WA can read up to 290 bytes in a single call and I am not receiving any bad data.

#include "i2c_simple_master.h"

uint16_t bytesToRead = 290;
uint8_t data[bytesToRead];
i2c_readDataBlock(slaveAddress, regAddress, data, bytesToRead);

   

What is the maximum number of bytes that can be read safely using i2c_readDataBlock()?

Naveen

Last Edited: Mon. Jan 4, 2021 - 01:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Please post a link to the library

"i2c_simple_master.h"

The documentation will say whether there are limits.

The Wire.h library uses a system buffer that is only 32 bytes.

Most libraries would expect you to provide the buffer and that it is big enough.   i.e. your responsibility.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yokonav wrote:
I wanted to confirm if I2C in the AVR-IOT WA can read up to 290 bytes in a single call

Well the 4808 has plenty of sram for buffer space, so that is not a problem, the question you should be asking is will the slave provide that much data, but you have not said what the slave device is.

That answer will be found in its data sheet....  

 

Jim

 

 

 

FF = PI > S.E.T

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The slave is Maxim Integrated MAX30105. I am reading the FIFO DATA which can have maximum 32 samples, each sample can be 9 bytes long (max 288 bytes).

Naveen

Last Edited: Mon. Jan 4, 2021 - 01:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please find attached source code for i2c driver.

Attachment(s): 

Naveen

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Please post a link to the library

It would still be good to have a link to where you got it from, because:

as david.prentice wrote:
The documentation will say whether there are limits.

So have you checked that documentation to see what it says?

 

david.prentice wrote:
Most libraries would expect you to provide the buffer and that it is big enough

 

There is some documentation in the source code you posted; eg,

/**
 *  \ingroup doc_driver_i2c_code
 *  \brief Function to read block of data from a register location
 *  
 *  \param [in] address [type]i2c_address_t Slave address
 *         [in] reg     [type]uint8_t The register address to be read
 *         [out] data   [type]void* The read data block
 *         [in] len     [type]size_t The size of data block
 *  
 *  \return None
 */
void i2c_readDataBlock(twi0_address_t address, uint8_t reg, void *data, size_t len)

So the library does, indeed, expect you to provide the buffer

 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have downloaded the code from the Atmel Start existing examples "AVR IOT WG Sensor Node". 

https://start.atmel.com/#example...

Naveen

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I could not find any online documentation. But it seems the I2C driver library does not impose any limitation for reading data. I can read as much as the available SRAM allows.

Naveen

Last Edited: Mon. Jan 4, 2021 - 02:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your library function says:

/**
 *  \ingroup doc_driver_i2c_code
 *  \brief Function to read block of data from a register location
 *  
 *  \param [in] address [type]i2c_address_t Slave address
 *         [in] reg     [type]uint8_t The register address to be read
 *         [out] data   [type]void* The read data block
 *         [in] len     [type]size_t The size of data block
 *  
 *  \return None
 */
void i2c_readDataBlock(twi0_address_t address, uint8_t reg, void *data, size_t len)

There is no mention of any size limit on len.  If it was less than 256 they would have used a uint8_t argument.

So it looks as if you can legally request 290 bytes.   But obviously only if you have a big enough bucket to to store the data.

 

I would expect some human readable HTML or PDF doc.   But if the H file is all you have got,  you just have to do some guesswork.

 

Read the documentation for your Slave device.    It is not much good if you have to busy-wait for data to arrive.    But it might be to your advantage.

 

For example,   a Serial Terminal might have a hardware FIFO.   Which means that you can be emptying the FIFO as fast as the bytes are arriving.    You never have to wait or even pause.     A USART probably only has a 16-byte FIFO.   The ISR() can empty it without worrying too much about latency,  overruns, ...

Yet you can comfortably handle many 10000s bytes without dropping a single bit.

 

The moral of the story is :  Read the Slave docs.   Read the library docs (if HTML / PDF exists)

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I would expect some human readable HTML or PDF doc. 

Indeed.

 

However, such documentation is usually just auto-generated by Brief from those source code comments - so it often won't tell you anything more than what's in the source code comments.

 

frown

 

The moral of the story is :  Read the Slave docs.   Read the library docs

Absolutely! 

 

EDIT

 

The board has a built-in debugger - so you can also step through the code to see what's happening; whether there are any length checks/limits, etc ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jan 4, 2021 - 03:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Arduino wire.h library (which handles I2C in ArduinoLand) has five buffers of 32 bytes each.

The function:  Wire.requestFrom(SlaveAddress,32);   will do a START: a SLA/read transfer, and 32 data byte transfers, then STOP.