I am using a pair of Wixels to create a wireless link between an accelerometer (measuring vibrations up to 1KHz of a system) and an oscilloscope for a lab on my campus. The idea is that one Wixel will sample the accelerometer (at around 5KHz), fill up an internal packet buffer, and send the data to the receiver Wixel. I set up timer 3 to overflow and call an ISR every 200us (5KHz frequency, 5x the maximum input frequency I expect) in which I sample the accelerometer (using adcRead() 12-bit resolution) and add the sample to the packet buffer (I encode 2 12-bit readings and place them in 3 8-bit buffers of the packet, and when I receive the data on the other Wixel, I decode the original sample). When the packet buffer is full, I set a flag in the ISR, and my main loop catches that flag and calls my sendPacket() function (I wrote a new radio protocol library, which optomized the system to dedicate one wixel as the transmitter and one as the receiver).
The receiver Wixel is connected to a DAC which uses the I2C protocol to update its analog output voltage (it is a 12-bit resolution DAC). The problem that I am having is this: I am using the same timer (timer 3) to call an ISR in my receiver Wixel. When the ISR fires, the Wixel sends the next sample to the DAC (in essence, I am repeating the samples that were sent over on the radio at the same rate they were sampled, but with a delay). I am worried that using I2C to transfer the data to the DAC is too slow. I set the I2C frequency to the highest setting (500KHz), but it appears that I am spending nearly the whole 200us inside of the ISR. I suspect this is the case because after I added the i2c function calls in my ISR, my main loop is not running quickly enough to call usbComService() often enough to let me get into bootloader mode from a usb command. Before I added the i2c function calls, I was able to start the Wixel in bootloader mode every time from the Wixel Configuration Utility. What I suspect is happening is that the i2c function calls added too much overhead to my ISR, and now I am spending nearly the entire 200us inside of my ISR, and nearly no time in my main loop.
I tested the I2C code trying to find the root of the problem, and found that if I only call i2cStart() immediately followed by i2cStop() (this is within the ISR), the code runs as expected. However, as soon as I add one or more calls to i2cWriteByte(uint8 byte), I get the problem where I am not calling usbComService() often enough in my main loop to get into bootloader from the Wixel Configuration Utility.
My theory is that there is a serious difference between the i2c frequency set and the actual frequency the i2c library communicates with peripherals is. Can anyone answer if this is the case? If so, is there is any way to speed up the i2c library, or do I need to implement a new i2c library which optomizes the system for the set up I have so that the i2c communication speed is improved?
As a first guess, I saw that the i2c library calls the setDigitalInput() and setDigitalOutput() functions quite often. In the gpio library, it mentions that these calls take ~3.2us to complete. I am using 3 i2cWriteByte() calls in my ISR, could this be the source of the delay in communication speed? (if each call to setDigital…() takes 3.2us, but the bus frequency is 400KHz = 2.5us per clock tick, could this be the problem?)
Thank you tremendously for your help. I understand the post here was long but I wanted to appropriately educate the reader on the set-up I am trying to implement so I may get the best help.