2b5391467bea2ee2047eb087a27850e9e875da0b
[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
32
33 //! Set up the pins for SPI mode.
34 unsigned char spisetup(){
35   P5DIR|=MOSI+SCK+SS;
36   P5DIR&=~MISO;
37   P5OUT|=SS;
38 }
39
40 //! Read and write an SPI bit.
41 unsigned char spitrans8(unsigned char byte){
42   unsigned int bit;
43   //This function came from the SPI Wikipedia article.
44   //Minor alterations.
45   
46   P5OUT&=~SS;
47   
48   for (bit = 0; bit < 8; bit++) {
49     /* write MOSI on trailing edge of previous clock */
50     if (byte & 0x80)
51       SETMOSI;
52     else
53       CLRMOSI;
54     byte <<= 1;
55  
56     /* half a clock cycle before leading/rising edge */
57     SPIDELAY(SPISPEED/2);
58     SETCLK;
59  
60     /* half a clock cycle before trailing/falling edge */
61     SPIDELAY(SPISPEED/2);
62  
63     /* read MISO on trailing edge */
64     byte |= READMISO;
65     CLRCLK;
66   }
67   
68   P5OUT|=SS;
69  
70   return byte;
71 }
72
73 //! Handles a monitor command.
74 void spihandle(unsigned char app,
75                unsigned char verb,
76                unsigned char len){
77   switch(verb){
78     //PEEK and POKE might come later.
79   case READ:
80   case WRITE:
81     cmddata[0]=spitrans8(cmddata[0]);
82     txdata(app,verb,1);
83     break;
84   case SETUP:
85     spisetup();
86     txdata(app,verb,0);
87     break;
88   }
89 }