Skip to content

Commit edfa05f

Browse files
committed
Adding i2cWriteMultiple to speed up I2C transfers
1 parent bf65a26 commit edfa05f

File tree

4 files changed

+111
-17
lines changed

4 files changed

+111
-17
lines changed

keywords.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ draw KEYWORD2
6060
drawFace KEYWORD2
6161
checkComm KEYWORD2
6262

63+
setI2CTransactionSize KEYWORD2
64+
getI2CTransactionSize KEYWORD2
65+
6366
#######################################
6467
# Constants (LITERAL1)
6568
#######################################
@@ -70,5 +73,3 @@ NORM LITERAL1
7073
XOR LITERAL1
7174
PAGE LITERAL1
7275
ALL LITERAL1
73-
74-

src/SFE_MicroOLED.cpp

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,18 @@ void MicroOLED::clear(uint8_t mode)
365365
{
366366
setPageAddress(i);
367367
setColumnAddress(0);
368-
for (int j = 0; j < 0x80; j++)
368+
if (interface == MODE_I2C)
369369
{
370-
data(0);
370+
uint8_t zeros[0x80];
371+
memset(zeros, 0, 0x80);
372+
i2cWriteMultiple(i2c_address, (uint8_t *)&zeros, 0x80);
373+
}
374+
else
375+
{
376+
for (int j = 0; j < 0x80; j++)
377+
{
378+
data(0);
379+
}
371380
}
372381
}
373382
}
@@ -391,9 +400,18 @@ void MicroOLED::clear(uint8_t mode, uint8_t c)
391400
{
392401
setPageAddress(i);
393402
setColumnAddress(0);
394-
for (int j = 0; j < 0x80; j++)
403+
if (interface == MODE_I2C)
404+
{
405+
uint8_t zeros[0x80];
406+
memset(zeros, c, 0x80);
407+
i2cWriteMultiple(i2c_address, (uint8_t *)&zeros, 0x80);
408+
}
409+
else
395410
{
396-
data(c);
411+
for (int j = 0; j < 0x80; j++)
412+
{
413+
data(c);
414+
}
397415
}
398416
}
399417
}
@@ -438,9 +456,21 @@ void MicroOLED::display(void)
438456
{
439457
setPageAddress(i);
440458
setColumnAddress(0);
441-
for (j = 0; j < 0x40; j++)
459+
if (interface == MODE_I2C)
442460
{
443-
data(screenmemory[i * 0x40 + j]);
461+
uint8_t store[0x40];
462+
for (j = 0; j < 0x40; j++)
463+
{
464+
store[j] = screenmemory[i * 0x40 + j];
465+
}
466+
i2cWriteMultiple(i2c_address, (uint8_t *)&store, 0x40);
467+
}
468+
else
469+
{
470+
for (j = 0; j < 0x40; j++)
471+
{
472+
data(screenmemory[i * 0x40 + j]);
473+
}
444474
}
445475
}
446476
}
@@ -1099,4 +1129,17 @@ void MicroOLED::drawIcon(uint8_t offsetX, uint8_t offsetY, uint8_t iconWidth, ui
10991129
columnNumber = offsetX;
11001130
}
11011131
}
1102-
}
1132+
}
1133+
1134+
//Sets the global size for I2C transactions
1135+
//Most platforms use 32 bytes (the default) but this allows users to increase the transaction
1136+
//size if the platform supports it
1137+
//Note: If the transaction size is set larger than the platforms buffer size, bad things will happen.
1138+
void MicroOLED::setI2CTransactionSize(uint8_t transactionSize)
1139+
{
1140+
i2cTransactionSize = transactionSize;
1141+
}
1142+
uint8_t MicroOLED::getI2CTransactionSize(void)
1143+
{
1144+
return (i2cTransactionSize);
1145+
}

src/SFE_MicroOLED.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/******************************************************************************
1+
/******************************************************************************
22
SFE_MicroOLED.h
33
Header file for the MicroOLED Arduino Library
44
@@ -21,9 +21,9 @@ Arduino Pro 3.3V
2121
Micro OLED Breakout v1.0
2222
2323
This code was heavily based around the MicroView library, written by GeekAmmo
24-
(https://github.com/geekammo/MicroView-Arduino-Library), and released under
25-
the terms of the GNU General Public License as published by the Free Software
26-
Foundation, either version 3 of the License, or (at your option) any later
24+
(https://github.com/geekammo/MicroView-Arduino-Library), and released under
25+
the terms of the GNU General Public License as published by the Free Software
26+
Foundation, either version 3 of the License, or (at your option) any later
2727
version.
2828
2929
This program is distributed in the hope that it will be useful,
@@ -202,6 +202,13 @@ class MicroOLED : public Print
202202
void flipVertical(boolean flip);
203203
void flipHorizontal(boolean flip);
204204

205+
//Control the size of the internal I2C transaction amount
206+
void setI2CTransactionSize(uint8_t bufferSize);
207+
uint8_t getI2CTransactionSize(void);
208+
209+
//Set the max number of bytes set in a given I2C transaction
210+
uint8_t i2cTransactionSize = 32; //Default to ATmega328 limit
211+
205212
private:
206213
uint8_t csPin, dcPin, rstPin;
207214
uint8_t wrPin, rdPin, dPins[8];
@@ -220,6 +227,7 @@ class MicroOLED : public Print
220227
void spiSetup();
221228
void i2cSetup();
222229
void i2cWrite(byte address, byte control, byte data);
230+
boolean i2cWriteMultiple(byte address, uint8_t *dataBytes, size_t numDataBytes);
223231
void parallelSetup();
224232
void parallelWrite(byte data, byte dc);
225233
};

src/hardware.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/******************************************************************************
1+
/******************************************************************************
22
hardware.cpp
33
MicroOLED Arduino Library Hardware Interface
44
@@ -20,9 +20,9 @@ Arduino Pro 3.3V
2020
Micro OLED Breakout v1.0
2121
2222
This code was heavily based around the MicroView library, written by GeekAmmo
23-
(https://github.com/geekammo/MicroView-Arduino-Library), and released under
24-
the terms of the GNU General Public License as published by the Free Software
25-
Foundation, either version 3 of the License, or (at your option) any later
23+
(https://github.com/geekammo/MicroView-Arduino-Library), and released under
24+
the terms of the GNU General Public License as published by the Free Software
25+
Foundation, either version 3 of the License, or (at your option) any later
2626
version.
2727
2828
This program is distributed in the hope that it will be useful,
@@ -97,6 +97,48 @@ void MicroOLED::i2cWrite(byte address, byte dc, byte data)
9797
Wire.endTransmission();
9898
}
9999

100+
/** \brief Write multiple data bytes over I2C
101+
102+
Write multiple bytes to I2C device _address_.
103+
Returns true if all numDataBytes were pushed successfully
104+
**/
105+
boolean MicroOLED::i2cWriteMultiple(uint8_t address, uint8_t *dataBytes, size_t numDataBytes)
106+
{
107+
// I2C: split the data up into packets of i2cTransactionSize
108+
size_t bytesLeftToWrite = numDataBytes;
109+
size_t bytesWrittenTotal = 0;
110+
111+
while (bytesLeftToWrite > 0)
112+
{
113+
size_t bytesToWrite; // Limit bytesToWrite to i2cTransactionSize
114+
if (bytesLeftToWrite > (i2cTransactionSize - 1))
115+
bytesToWrite = i2cTransactionSize - 1;
116+
else
117+
bytesToWrite = bytesLeftToWrite;
118+
119+
Wire.beginTransmission(address);
120+
Wire.write(I2C_DATA);
121+
size_t bytesWritten = Wire.write(dataBytes, bytesToWrite); // Write the bytes
122+
123+
bytesWrittenTotal += bytesWritten; // Update the totals
124+
bytesLeftToWrite -= bytesToWrite;
125+
dataBytes += bytesToWrite; // Point to fresh data
126+
127+
if (bytesLeftToWrite > 0)
128+
{
129+
if (Wire.endTransmission(false) != 0) //Send a restart command. Do not release bus.
130+
return (false); //Sensor did not ACK
131+
}
132+
else
133+
{
134+
if (Wire.endTransmission() != 0) //We're done. Release bus.
135+
return (false); //Sensor did not ACK
136+
}
137+
}
138+
139+
return (bytesWrittenTotal == numDataBytes);
140+
}
141+
100142
/** \brief Set up Parallel Interface
101143
102144
This function initializes all of the pins used in the

0 commit comments

Comments
 (0)