b0b5323aa516e937cdc0ca09b80f5831c8eef77a
[goodfet] / firmware / apps / spi / spi.c
1 //GoodFET SPI Application
2 //Handles basic I/O
3
4 //Higher level left to client application.
5
6 #include "platform.h"
7 #include "command.h"
8
9 #include <signal.h>
10 #include <io.h>
11 #include <iomacros.h>
12
13
14 //Pins and I/O
15 #define SS   BIT0
16 #define MOSI BIT1
17 #define MISO BIT2
18 #define SCK  BIT3
19
20 //This could be more accurate.
21 //Does it ever need to be?
22 #define SPISPEED 0
23 #define SPIDELAY(x) delay(x)
24
25 #define SETMOSI P5OUT|=MOSI
26 #define CLRMOSI P5OUT&=~MOSI
27 #define SETCLK P5OUT|=SCK
28 #define CLRCLK P5OUT&=~SCK
29 #define READMISO (P5IN&MISO?1:0)
30
31 //! Set up the pins for SPI mode.
32 unsigned char spisetup(){
33   P5DIR|=MOSI+SCK+SS;
34   P5DIR&=~MISO;
35 }
36
37 //! Read and write an SPI bit.
38 unsigned char spitrans8(unsigned char byte){
39   unsigned int bit;
40   //This function came from the SPI Wikipedia article.
41   //Minor alterations.
42  
43   for (bit = 0; bit < 8; bit++) {
44     /* write MOSI on trailing edge of previous clock */
45     if (byte & 0x80)
46       SETMOSI;
47     else
48       CLRMOSI;
49     byte <<= 1;
50  
51     /* half a clock cycle before leading/rising edge */
52     SPIDELAY(SPISPEED/2);
53     SETCLK;
54  
55     /* half a clock cycle before trailing/falling edge */
56     SPIDELAY(SPISPEED/2);
57  
58     /* read MISO on trailing edge */
59     byte |= READMISO;
60     CLRCLK;
61   }
62  
63   return byte;
64 }
65
66 //! Handles a monitor command.
67 void spihandle(unsigned char app,
68                unsigned char verb,
69                unsigned char len){
70   switch(verb){
71     //PEEK and POKE might come later.
72   case READ:
73   case WRITE:
74     cmddata[0]=spitrans8(cmddata[0]);
75     txdata(app,verb,1);
76     break;
77   case SETUP:
78     spisetup();
79     txdata(app,verb,0);
80     break;
81   }
82 }