2 \author Travis Goodspeed
6 //Higher level left to client application.
21 #define SPIAPPLICATION
25 //! Handles a monitor command.
26 void spi_handle_fn( uint8_t const app,
30 // define the spi app's app_t
31 app_t const spi_app = {
43 "\tThe SPI app handles the SPI bus protocol, turning\n"
44 "\tyour GoodFET into a USB-to-SPI adapter.\n"
47 //This could be more accurate.
48 //Does it ever need to be?
50 #define SPIDELAY(x) delay(x)
53 //! Set up the pins for SPI mode.
56 SPIDIR|=MOSI+SCK+BIT0; //BIT0 might be SS
60 //Begin a new transaction.
67 //! Read and write an SPI byte.
68 unsigned char spitrans8(unsigned char byte){
69 register unsigned int bit;
70 //This function came from the SPI Wikipedia article.
73 for (bit = 0; bit < 8; bit++) {
74 /* write MOSI on trailing edge of previous clock */
85 /* read MISO on trailing edge */
93 //! Enable SPI writing
94 void spiflash_wrten(){
97 CLRSS; //Drop !SS to begin transaction.
98 spitrans8(0x04);//Write Disable
99 SETSS; //Raise !SS to end transaction.
101 CLRSS; //Drop !SS to begin transaction.
102 spitrans8(0x06);//Write Enable
103 SETSS; //Raise !SS to end transaction.
107 //! Grab the SPI flash status byte.
108 unsigned char spiflash_status(){
110 SETSS; //Raise !SS to end transaction.
111 CLRSS; //Drop !SS to begin transaction.
112 spitrans8(0x05);//GET STATUS
114 SETSS; //Raise !SS to end transaction.
119 //! Grab the SPI flash status byte.
120 void spiflash_setstatus(unsigned char c){
122 CLRSS; //Drop !SS to begin transaction.
123 spitrans8(0x01);//SET STATUS
125 SETSS; //Raise !SS to end transaction.
130 //! Read a block to a buffer.
131 void spiflash_peekblock(unsigned long adr,
137 CLRSS; //Drop !SS to begin transaction.
138 spitrans8(0x03);//Flash Read Command
141 spitrans8((adr&0xFF0000)>>16);
142 spitrans8((adr&0xFF00)>>8);
147 SETSS; //Raise !SS to end transaction.
150 //! Read a block to a buffer.
151 void spiflash_pokeblock(unsigned long adr,
159 // debugstr("Non-standard block size.");
161 while(spiflash_status()&0x01);//minor performance impact
163 spiflash_setstatus(0x02);
166 //Are these necessary?
167 //spiflash_setstatus(0x02);
170 CLRSS; //Drop !SS to begin transaction.
171 spitrans8(0x02); //Poke command.
174 spitrans8((adr&0xFF0000)>>16);
175 spitrans8((adr&0xFF00)>>8);
180 SETSS; //Raise !SS to end transaction.
182 while(spiflash_status()&0x01);//minor performance impact
187 //! Write many blocks to the SPI Flash.
188 void spiflash_pokeblocks(unsigned long adr,
191 long off=0;//offset of this block
192 int blen;//length of this block
196 //calculate block length
197 blen=(len-off>0x100?0x100:len-off);
199 spiflash_pokeblock(adr+off,
209 //! Peek some blocks.
210 void spiflash_peek(unsigned char app,
214 CLRSS; //Drop !SS to begin transaction.
215 spitrans8(0x03);//Flash Read Command
216 len=3;//write 3 byte pointer
218 spitrans8(cmddata[i]);
222 txhead(app,verb,len);
225 serial_tx(spitrans8(0));
227 SETSS; //Raise !SS to end transaction.
232 void spiflash_erasesector(unsigned long adr){
233 //debugstr("Erasing a 4kB sector.");
244 spitrans8((adr&0xFF0000)>>16);
245 spitrans8((adr&0xFF00)>>8);
249 while(spiflash_status()&0x01);//while busy
250 //debugstr("Erased.");
254 //! Wake an EM260 Radio
256 //debugstr("Waking EM260.");
265 //debugstr("EM260 is now awake.");
266 delay(1024); //DO NOT REMOVE, fails without.
268 //! Handle an EM260 exchange.
269 void spi_rw_em260(u8 app, u8 verb, u32 len){
273 P4DIR=0; //TODO ASAP remove P4 references.
277 //See GoodFETEM260.py for details.
278 //The EM260 requires that the host wait for the client.
282 debugstr("Detected HOST_INT.");
288 SETMOSI; //Autodetected SPI mode.
289 CLRSS; //Drop !SS to begin transaction.
290 //Host to slave. Ignore data.
292 lastin=spitrans8(cmddata[i]);
294 //debugstr("EM260 transmission interrupted.");
299 //debugstr("Finished transmission to EM260.");
301 //Wait for nHOST_INT to drop.
310 while((cmddata[0]=spitrans8(0xFF))==0xFF
314 debugstr("Gave up on host interrupt.");
319 (cmddata[len++]=spitrans8(0xFF))!=0xA7
322 while(len<cmddata[1]+3)
323 cmddata[len++]=spitrans8(0xFF);
324 SETSS; //Raise !SS to end transaction.
326 txdata(app,verb,len);
330 //! Handles a monitor command.
331 void spi_handle_fn( uint8_t const app,
337 //Raise !SS to end transaction, just in case we forgot.
345 CLRSS; //Drop !SS to begin transaction.
347 cmddata[i]=spitrans8(cmddata[i]);
348 SETSS; //Raise !SS to end transaction.
349 txdata(app,verb,len);
352 case SPI_RW_EM260: //SPI exchange with an EM260
353 spi_rw_em260(app,verb,len);
356 case SPI_JEDEC://Grab 3-byte JEDEC ID.
357 CLRSS; //Drop !SS to begin transaction.
359 l=3; //Length is variable in some chips, 3 minimum.
360 for(i = 0; i < l; i++)
361 cmddata[i]=spitrans8(cmddata[i]);
362 txdata(app,verb,len);
363 SETSS; //Raise !SS to end transaction.
366 case PEEK://Grab 128 bytes from an SPI Flash ROM
367 spiflash_peek(app,verb,len);
370 case POKE://Poke up bytes from an SPI Flash ROM.
371 spiflash_pokeblocks(cmddatalong[0],//adr
377 case SPI_ERASE://Erase the SPI Flash ROM.
379 CLRSS; //Drop !SS to begin transaction.
380 spitrans8(0xC7);//Chip Erase
381 SETSS; //Raise !SS to end transaction.
383 while(spiflash_status()&0x01)//while busy