Buzz
« And we decided to do things our way... | Main | Arduino and the SeaWolf III (Pressure/Depth Sensing) »
Wednesday
Feb182009

Making the Arduino Speak SPI (and talk to a BlackFin)

One of our big secret wepons this year.... is a big secret weapon that does signal processing using a BlackFin. (I'm not giving more than that away...). We're using an Ez-Lite BlackFin development board for time time being and needed a way to firstly get the thing booted (didn't want to use the usual route and boot it off EEPROM because we wanted to maintain SPI serial access for debugging and possibly for command sending purposes down the road). Thankfully Analog Devices does a good job of documenting how their products work (erm... even if it is midly cryptic at times.. I'll try and explain at least the way we did it a bit more clearly than the official doc manages too).

There are two types of files we will be sending over the lines, first there is the .LDR which will act as the boot loader for the blackfin, and then secondly there is the .DXEs which are executables that the BlackFin actually runs.

To allow us to boot the board over SPI, send the .DXE's and maintain a serial connection we opted to allow Arduino to manage the SPI operations. Essentially here's the idea:

  1. BlackFin is hard reset, looks for boot loader.
  2. Arduino is configured to operate in SPI master mode Black fin in slave.
  3. Adruino checks the PFx line, if it's high, the BlackFin is saying don't transmit, if not we can start chucking bits.
  4. Arduino asks the computer for the .ldr boot loader file and caches the first byte
  5. If PFx remains low, transmit cached bit.
  6. Request next byte from computer.
  7. If we don't get an end of file indicator from the computer, loop back to step 5
  8. If we do.. start kicking out some .DXE... in much the same manner we got the .LDR on there.

Here's a little PDF on our simplification of the documentation related to what SPI communication looks like on the BlackFin and what needs to be done to actually make it work.

As an aside.. when transmitting the DXE's vs. LDR's the computer (or Arduino) will need to calculate the .DXE size + the 10 byte header for that first header and transmit it bit by bit big indian style. The LDRs already have this information contained in the binary and don't need to be computed.

So how do we make the arduino speak the right language? Well sadly, while the hardware the arduino is based on fully supports the SPI protocol... the software environment does a bit of falling flat on it's face. You are forced to use a bit of creative register hacking to get it to work. Essentially the documentation provided by ADI (found at the bottom of this document as a .PDF) tells us what mode needs to be set.

But before we dig too deep into the software side of things there is the question of hardware, how to we actually connect the Arduino to the BlackFin? The digital pinout for using SPI on the Arduino is given as follows:

  • Pin 9 (or any other digital pin actually... 9 just groups nicely.): FPx
  • Pin 10: SS
  • Pin 11: MOSI
  • Pin 12: MISO
  • Pin 13: SCK

Writing this up as a few #Defines for the start of the program:

#define DATAOUT 11//MOSI
#define DATAIN 12//MISO
#define SPICLOCK 13//sck
#define SLAVESELECT 10//ss
#define FPx 9//FPx

From the Arduino Playground we are given the organization of the of the register regaurding the SPI protocol for the Arduino as

SPCR
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| SPIE | SPE | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |

SPIE - Enables the SPI interrupt when 1
SPE - Enables the SPI when 1
DORD - Sends data least Significant Bit First when 1,
most Significant Bit first when 0
MSTR - Sets the Arduino in master mode when 1, slave
mode when 0
CPOL - Sets the data clock to be idle when high if set
to 1, idle when low if set to 0
CPHA - Samples data on the falling edge of the data
clock when 1, rising edge when 0
SPR1 and SPR0 - Sets the SPI speed, 00 is fastest
(4MHz) 11 is slowest (250KHz)

For communicating with the BlackFin the following options must be set on the arduino: interrupt enabled, spi enabled, msb 1st, master, clk low when idle, sample on leading edge of clk, system clock/4 rate (slow) or assign the SPCR a value of 11010011.

To do this, we use the following code durring the setup loop:

SPCR = (1<<SPIE)(1<<SPE)|(1<<MSTR)(1<<SPR1)(1<<SPR0);
clr=SPSR;
clr=SPDR;
delay(10);

So, that's basically the "strange" stuff. From here on out it's just basic coding, if you would like to see my example feel free to pull my Arduino sketch located at the bottom of the document. Hope this helps someone!

Blackfin Technical Document

SPI.pde

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
All HTML will be escaped. Hyperlinks will be created for URLs automatically.