2 \author Travis Goodspeed
4 This is an implementation of the SPI protocol
5 for the GoodFET project.
8 //Higher level left to client application.
19 //This could be more accurate.
20 //Does it ever need to be?
26 //! Set up the pins for SPI mode.
32 //Begin a new transaction.
38 //! Read and write an SPI byte.
39 unsigned char spitrans8(unsigned char byte){
41 //This function came from the SPI Wikipedia article.
44 for (bit = 0; bit < 8; bit++) {
45 /* write MOSI on trailing edge of previous clock */
52 /* half a clock cycle before leading/rising edge */
56 /* half a clock cycle before trailing/falling edge */
59 /* read MISO on trailing edge */
68 //! Enable SPI writing
69 void spiflash_wrten(){
71 P5OUT&=~SS; //Drop !SS to begin transaction.
72 spitrans8(0x04);//Write Disable
73 P5OUT|=SS; //Raise !SS to end transaction.
74 P5OUT&=~SS; //Drop !SS to begin transaction.
75 spitrans8(0x06);//Write Enable
76 P5OUT|=SS; //Raise !SS to end transaction.
80 //! Grab the SPI flash status byte.
81 unsigned char spiflash_status(){
83 P5OUT|=SS; //Raise !SS to end transaction.
84 P5OUT&=~SS; //Drop !SS to begin transaction.
85 spitrans8(0x05);//GET STATUS
87 P5OUT|=SS; //Raise !SS to end transaction.
92 //! Grab the SPI flash status byte.
93 void spiflash_setstatus(unsigned char c){
95 CLRSS; //Drop !SS to begin transaction.
96 spitrans8(0x01);//SET STATUS
98 SETSS; //Raise !SS to end transaction.
103 //! Read a block to a buffer.
104 void spiflash_peekblock(unsigned long adr,
110 CLRSS; //Drop !SS to begin transaction.
111 spitrans8(0x03);//Flash Read Command
114 spitrans8((adr&0xFF0000)>>16);
115 spitrans8((adr&0xFF00)>>8);
120 SETSS; //Raise !SS to end transaction.
124 //! Read a block to a buffer.
125 void spiflash_pokeblock(unsigned long adr,
132 spiflash_setstatus(0x02);
135 CLRSS; //Drop !SS to begin transaction.
136 spitrans8(0x02); //Poke command.
139 spitrans8((adr&0xFF0000)>>16);
140 spitrans8((adr&0xFF00)>>8);
145 SETSS; //Raise !SS to end transaction.
147 //while(spiflash_status()&0x01);
153 //! Peek some blocks.
154 void spiflash_peek(unsigned char app,
157 register char blocks=(len>3?cmddata[3]:1);
160 P5OUT&=~SS; //Drop !SS to begin transaction.
161 spitrans8(0x03);//Flash Read Command
162 len=3;//write 3 byte pointer
164 spitrans8(cmddata[i]);
167 len=0x80;//128 byte chunk, repeated for each block
170 serial_tx(len); //multiplied by block count.
174 serial_tx(spitrans8(0));
178 cmddata[i]=spitrans8(0);
179 txdata(app,verb,len);
182 P5OUT|=SS; //Raise !SS to end transaction.
185 //! Handles a monitor command.
186 void spihandle(unsigned char app,
191 //Raise !SS to end transaction, just in case we forgot.
196 //PEEK and POKE might come later.
199 P5OUT&=~SS; //Drop !SS to begin transaction.
201 cmddata[i]=spitrans8(cmddata[i]);
202 P5OUT|=SS; //Raise !SS to end transaction.
203 txdata(app,verb,len);
207 case SPI_JEDEC://Grab 3-byte JEDEC ID.
208 P5OUT&=~SS; //Drop !SS to begin transaction.
212 cmddata[i]=spitrans8(cmddata[i]);
213 txdata(app,verb,len);
214 P5OUT|=SS; //Raise !SS to end transaction.
218 case PEEK://Grab 128 bytes from an SPI Flash ROM
219 spiflash_peek(app,verb,len);
223 case POKE://Poke up bytes from an SPI Flash ROM.
224 spiflash_setstatus(0x02);
227 P5OUT&=~SS; //Drop !SS to begin transaction.
228 spitrans8(0x02); //Poke command.
230 //First three bytes are address, then data.
232 spitrans8(cmddata[i]);
233 P5OUT|=SS; //Raise !SS to end transaction.
236 while(spiflash_status()&0x01)//while busy
240 txdata(app,verb,len);
244 case SPI_ERASE://Erase the SPI Flash ROM.
246 P5OUT&=~SS; //Drop !SS to begin transaction.
247 spitrans8(0xC7);//Chip Erase
248 P5OUT|=SS; //Raise !SS to end transaction.
251 while(spiflash_status()&0x01)//while busy