Getting the Raspberry Pi set up with SPI was not very difficult, in fact it was so easy I didn’t even think about making a write-up of it. If I remember correctly it was as simple as a click on a menu during the installation of Raspbian.
What was less obvious (because I didn’t pay attention to details in the documentation of wiringPi) was that the linux SPI driver has a default maximum buffer size of 4096 bytes.
Since the TCD1304 has 3694 pixels (dummies included) and the ADC is 12 bit, the total amount of data to transfer is 7388 bytes. So the 4K limit is in fact quite ..limiting.
It was even less obvious how to fix the problem permanently, but fortunately it was not a very difficult fix. Append this:
to the line in the file /boot/cmdline.txt and reboot. Easy peasy.
Next problem is related to endianness. The term cutely has its roots in Gulliver’s Travels, where the Big-Endians cut their soft-boiled eggs on the large end and the Little-Endians cut theirs on the small end.¹
In computer science endianness describes the order of which the bits in a number are read. Big-endian processors read the most significant bit (msb) first and Little-endian processors of course read the least significant bit first.
If you want to get technical take a look in the source code, I’ll only describe the problem briefly here. The Raspberry Pi’s SPI peripheral only allows for 8 bit transfers, so the 12 bit data from the ADC (stored in a 16 bit array) is sent 8 bits at a time. However, since the processor is little-endian² the bits get mixed up like this:
A 16 bit number like this: 0x1122
is transmitted as the two 8 bit numbers: 0x22 and 0x11
and recombined in memory to: 0x2211
Again it’s quite an easy fix. You pretend the two 8 bit numbers are 16 bit. Then you multiply the most significant number with 256 and add them together:
0x11 = 0x0011 and 0x22 = 0x0022
0x0011·0x0100 + 0x0022 = 0x1100 + 0x0022 = 0x1122
Oh and in case you’re wondering, 0x means hexadecimal. A two digit hexnumber like 0x11 corresponds to a single byte of value 00010001.
What else, right the GUI for the spectrometer is starting to take form:
It’s not quite finished. I spent a lot of time figuring out how to use the GTK3 toolkit, and I’m still learning. The program depends on gnuplot for plotting the spectra.
At the moment I’m speculating on how to ensure that data is transferred only between readings. With SPI the data transfer is supposedly running at 16 MHz so it’s less of a concern, as opposed to the rather slow USART protocol. Unfortunately I forgot to borrow an oscilloscope for the x-mas holidays, so everything’s a bit ..speculative.
Let me know if something’s not working..
² In fact ARMs are bi-endian, but I compile with a little-endian flag.