`// reworked to 7 as the first bite is insignificant, and the second should be 0 so that command mode is 0;</p><br />
<p>spi.write((cmode << 7 | b >>4));<br />
spi.write((b << 4 | r >>6));<br />
spi.write((r << 2 | g >> 8));<br />
spi.write(g); `
You probably don't want to do this.
As I read the example at http://docs.macetech.com/doku.php/shiftbrite the top two bits are command, so I would try to be consistent and allow it to be two bits. If cmode it is 0, then set it to 0. I wasted time trying to figure out whether you had made a mistake. Hence:
int cmode = 0;
spi.write((cmode << 6) | (b >>4));
spi.write((b << 4 | r >>6));
spi.write((r << 2 | g >> 8));
spi.write(g);
Also, for clarity, because int's are 32 bits, and to be explicit, you might consider trimming the bits to be the ones required:
spi.write( (cmode << 6)&0b11000000 | (b >>4)&0b00111111);
I might write some macros or inline functions to do this stuff:
#define MAKE_SHIFTBRIGHT_DATA(command, red, green, blue) (((command)&0b11)<<30 \
| ((blue)&0x3FF)<<20 | ((red)&0x3FF)<<10 | ((green)&0x3FF)
#define SHIFTBRIGHT_BYTE0(val) ((unsigned char)((val)>>24)&0xFF)
#define SHIFTBRIGHT_BYTE1(val) ((unsigned char)((val)>>16)&0xFF)
#define SHIFTBRIGHT_BYTE2(val) ((unsigned char)((val)>>8)&0xFF)
#define SHIFTBRIGHT_BYTE3(val) ((unsigned char)((val)>>0)&0xFF)
and do:
uint32 val = MAKE_SHIFTBRIGHT_DATA(cmode, r, g, b);
spi.write(SHIFTBRIGHT_BYTE0(val));
spi.write(SHIFTBRIGHT_BYTE1(val));
spi.write(SHIFTBRIGHT_BYTE2(val));
spi.write(SHIFTBRIGHT_BYTE3(val));
This has the small advantage that it is easy to print out the values over USB that are also being written via SPI.
1. when you writre "shiftleft or shiftright functions", so I assume you mean the left and right shift operators, '<<' and '>>'.
The shift operators yield the same type as their left operand, so if the operand is a 16 bit signed int, the result will be a 16 bit signed int. An 'int' is 32 bits on an ARM with gcc, not 16 bits.
The type the shift operators yield can not override the result type, which is truncated (high bits are thrown away)
So:
1023 << 4;
is binary 000000000000000000011111111110000 (I hope I counted the 32 bits correctly there :-)
when this is assigned to an 'int8' yields binary 11110000, or answer a)
I've tried SerialUSB sending the result but I get a blank line.
With these sort of things 'the devil is in the detail' so it would be helpful if you gave the code that is being used.
I assume the code is trying to print the int8 variable rshifted, which has a decimal value of 240.
There is no ASCII value, so the terminal program may have no visible glyph to print for that code, and uses space in lieu of one.
instead, cast the value to be an (unsigned int) and see what it prints.
2. Please provide the code for the whole program. What happens in any particular case depends on how the peripheral is setup.
Assuming everything is simple and vanilla, then SPI write will send 8 bits. It is irrelevant what is contained in the 8 bits, so when sending 1, it will send eight bits, seven 0's and one 1.
3. In SPI's begin(frequency, bitOrder, mode); what exactly is the mode?
Very good question! I went digging through the Maple IDE source files, and found this:
`/**<br />
* @brief SPI mode configuration.<br />
*<br />
* Determines a combination of clock polarity (CPOL), which determines<br />
* idle state of the clock line, and clock phase (CPHA), which<br />
* determines which clock edge triggers data capture.<br />
*/<br />
typedef enum spi_mode {<br />
SPI_MODE_0, /**< Clock line idles low (0), data capture on first<br />
clock transition. */<br />
SPI_MODE_1, /**< Clock line idles low (0), data capture on second<br />
clock transition */<br />
SPI_MODE_2, /**< Clock line idles high (1), data capture on first<br />
clock transition. */<br />
SPI_MODE_3 /**< Clock line idles high (1), data capture on<br />
second clock transition. */<br />
} spi_mode;`
but it would be nice to have this in the documentation.
The linked page you gave doesn't give explicit information to be sure which mode is correct, but the datasheet for the Allegro A6281 will likely say what it expects.
I tried to work it out by reading the ATmega to understand what mode the setup puts its SPI peripheral into.
The linked code has:
SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0);
SPE bit enables the SPI peripheral (not relevant)
MSTR bit sets it in master mode (I assume your set up doesn't change this)
SPR1 and SPR2 set the clock rate (clock / 4, or 4MHz). I assume your setup code does the same frequency
So CPOL = 0 which means the clock signal is 'idle low'
and CPCHA = 0, which means data is setup on the trailing edge of the clock, and sampled on the leading edge.
This looks like SPI_MODE_0, but you could try 0 and 1 (or even all 4), and see if there are any differences in results.
This is covered on page 679 of the RM0008 STM32F manual.
(full disclosure: I am not a member of LeafLabs staff.)