I've recovered a S-35390A I2C RTC chip on an old lexmark printer which I plan to use in a HL1606 LED Strip based MOOD LAMP I'm designing for a Xmas present.
The rev 1.2_00 Datasheet I have shows that this chip uses both MSB (for command) and LSB (for data).
Rev 4.0 is all LSB based as they've barely inverted the order of the command bits from the previous release.
After searching around and finding different options (including table based search) I've created the following code to invert the bits in a byte
using, in this case, two global variables ABCD and its inverted DCBA:
void grab(int ABCD){
for (int i=0 ; i < 8; i++){
bitWrite(DCBA, 7 - i, bitRead(c,i));
}
}
It actually works fine but for my own Arduino code learning I'd like to know if this code is any good performance wise.
It's not obvious from your description whether you need to reverse the bits in the high byte or the low byte. The low byte is what you're actually reversing.
You code does not seem to transfer the content of the high byte at all. Wouldn't it be cleaner to copy the high byte across as-is (assuming you don't want it transformed)?
The reference to global variables is confusing (and sounds fugly). You're actually using an argument to pass in the input value, and returning the result via a global variable. That's not what your description implied. Why not simply return the transformed value and get away from the global variables completely?
Hard to tell. Your approach uses unsigned long multification so it is likely faster on a 32-bit platform than on a 8-bit platform. Look-up table usually is the fastest but least efficient as well.
Some numbers:
On a 1MIPS avr, 1000 reversals took this much time, when compiled in release mode:
for (int i=0 ; i < 8; i++){
bitWrite(DCBA, 7 - i, bitRead(ABCD,i));
}
}
It's not great, but it will work.
The algorithms that use multiply are nice if your CPU has a fast multiply instruction (for longs), but the AVR doesn't.
There's a trivial algorithm (left shift from source to carry flag, right shift from carry flag to destination) that will do 8 bits in 16 instructions (and 16 cycles), in assembler. (not counting the overhead of moving things into correct registers.)
Wiring:
D0 to A5
D1 to A4
D2 to A3
D3 to A2
D4 to A1
D5 to A0
D6 to D9
D7 to D8...
[ Other pins pulled down with resistors so they read low. ]
On the Mega there are lots of uncommited ports to play with where all 8 bits are pins, so just a single port write and single port read needed.
Actually there is another way to do it I think - the UART has an SPI mode, and if you couple that to the hardware SPI port and have one send MSB first and the other LSB first you can probably reverse two bytes simultaneously (well I'm guessing a bit).
This has the advantage of needing fewer pins wired up!
If the problem is simply that the commands are in a different bit order than data
then why can't you simply redefine the commands with the bits flipped and run both in LSB?
And if you want to have the code buildable for both LSB vs MSB ordering on commands,
define a macro that can vary depending on another define.
That way the macro can flip the values or leave them alone.
When the flipping is done, it will be done by the compiler at compile time vs
run time.