Skip to content

Instantly share code, notes, and snippets.

@sonyhome
Last active April 28, 2016 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sonyhome/446faaddd46c59bfdf803cfbbd6dd911 to your computer and use it in GitHub Desktop.
Save sonyhome/446faaddd46c59bfdf803cfbbd6dd911 to your computer and use it in GitHub Desktop.
While trying to bitbang all 8 pins of a port to speed up ws2812b display, I run out of time extracting each bit to push on each port. I have to create a byte where each bit comes from a different part of the array. Below is code that works, using 2 pins. Adding a 3rd one breaks.
template<FAB_TDEF>
inline void
avrBitbangLedStrip<FAB_TVAR>::eightWireSoftwareSendBytes(const uint16_t count, const uint8_t * array)
{
const uint16_t blockSize = count/2;
for(uint16_t pos = 0; pos < blockSize; pos++) {
for(int8_t bit = 7; bit >= 0; bit--) {
const uint8_t mask = 1 << bit;
// overlap bits set to 1 to save time. generating the boolean seems to take the longest.
const bool bitHigh5 = array[0*blockSize + pos] & mask;
if (bitHigh5) SET_PORT_HIGH(dataPortId, dataPortPin);
const bool bitHigh6 = array[1*blockSize + pos] & mask;
if (bitHigh6) SET_PORT_HIGH(clockPortId, clockPortPin);
// bits set to zero must cycle hi-lo fast so no overlap
if (!bitHigh5) {
SET_PORT_HIGH(dataPortId, dataPortPin);
//DELAY_CYCLES(high0 - sbiCycles);
DELAY_CYCLES(0);
SET_PORT_LOW(dataPortId, dataPortPin);
}
if (!bitHigh6) {
SET_PORT_HIGH(clockPortId, clockPortPin);
//DELAY_CYCLES(high0 - sbiCycles);
DELAY_CYCLES(0);
SET_PORT_LOW(clockPortId, clockPortPin);
}
// normally I put delay loops but it's not needed at 16mhz
DELAY_CYCLES(0);
// I could set low only bits that are one, but i just set low all the bits to reduce instruction count.
SET_PORT_LOW(dataPortId, dataPortPin);
SET_PORT_LOW(clockPortId, clockPortPin);
DELAY_CYCLES(0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment