2 \author Travis Goodspeed
6 //Higher level left to client application.
17 #define SPIAPPLICATION
21 //! Handles a monitor command.
22 void spi_handle_fn( uint8_t const app,
26 // define the spi app's app_t
27 app_t const spi_app = {
39 "\tThe SPI app handles the SPI bus protocol, turning\n"
40 "\tyour GoodFET into a USB-to-SPI adapter.\n"
43 //This could be more accurate.
44 //Does it ever need to be?
46 #define SPIDELAY(x) delay(x)
49 //! Set up the pins for SPI mode.
52 SPIDIR|=MOSI+SCK+BIT0; //BIT0 might be SS
56 //Begin a new transaction.
63 //! Read and write an SPI byte.
64 unsigned char spitrans8(unsigned char byte){
65 register unsigned int bit;
66 //This function came from the SPI Wikipedia article.
69 for (bit = 0; bit < 8; bit++) {
70 /* write MOSI on trailing edge of previous clock */
81 /* read MISO on trailing edge */
89 //! Enable SPI writing
90 void spiflash_wrten(){
93 CLRSS; //Drop !SS to begin transaction.
94 spitrans8(0x04);//Write Disable
95 SETSS; //Raise !SS to end transaction.
97 CLRSS; //Drop !SS to begin transaction.
98 spitrans8(0x06);//Write Enable
99 SETSS; //Raise !SS to end transaction.
103 //! Grab the SPI flash status byte.
104 unsigned char spiflash_status(){
106 SETSS; //Raise !SS to end transaction.
107 CLRSS; //Drop !SS to begin transaction.
108 spitrans8(0x05);//GET STATUS
110 SETSS; //Raise !SS to end transaction.
115 //! Grab the SPI flash status byte.
116 void spiflash_setstatus(unsigned char c){
118 CLRSS; //Drop !SS to begin transaction.
119 spitrans8(0x01);//SET STATUS
121 SETSS; //Raise !SS to end transaction.
126 //! Read a block to a buffer.
127 void spiflash_peekblock(unsigned long adr,
133 CLRSS; //Drop !SS to begin transaction.
134 spitrans8(0x03);//Flash Read Command
137 spitrans8((adr&0xFF0000)>>16);
138 spitrans8((adr&0xFF00)>>8);
143 SETSS; //Raise !SS to end transaction.
146 //! Read a block to a buffer.
147 void spiflash_pokeblock(unsigned long adr,
155 // debugstr("Non-standard block size.");
157 while(spiflash_status()&0x01);//minor performance impact
159 spiflash_setstatus(0x02);
162 //Are these necessary?
163 //spiflash_setstatus(0x02);
166 CLRSS; //Drop !SS to begin transaction.
167 spitrans8(0x02); //Poke command.
170 spitrans8((adr&0xFF0000)>>16);
171 spitrans8((adr&0xFF00)>>8);
176 SETSS; //Raise !SS to end transaction.
178 while(spiflash_status()&0x01);//minor performance impact
183 //! Write many blocks to the SPI Flash.
184 void spiflash_pokeblocks(unsigned long adr,
187 long off=0;//offset of this block
188 int blen;//length of this block
192 //calculate block length
193 blen=(len-off>0x100?0x100:len-off);
195 spiflash_pokeblock(adr+off,
205 //! Peek some blocks.
206 void spiflash_peek(unsigned char app,
210 CLRSS; //Drop !SS to begin transaction.
211 spitrans8(0x03);//Flash Read Command
212 len=3;//write 3 byte pointer
214 spitrans8(cmddata[i]);
218 txhead(app,verb,len);
221 serial_tx(spitrans8(0));
223 SETSS; //Raise !SS to end transaction.
228 void spiflash_erasesector(unsigned long adr){
229 //debugstr("Erasing a 4kB sector.");
240 spitrans8((adr&0xFF0000)>>16);
241 spitrans8((adr&0xFF00)>>8);
245 while(spiflash_status()&0x01);//while busy
246 //debugstr("Erased.");
250 //! Wake an EM260 Radio
252 //debugstr("Waking EM260.");
261 //debugstr("EM260 is now awake.");
262 delay(1024); //DO NOT REMOVE, fails without.
264 //! Handle an EM260 exchange.
265 void spi_rw_em260(u8 app, u8 verb, u32 len){
269 P4DIR=0; //TODO ASAP remove P4 references.
273 //See GoodFETEM260.py for details.
274 //The EM260 requires that the host wait for the client.
278 debugstr("Detected HOST_INT.");
284 SETMOSI; //Autodetected SPI mode.
285 CLRSS; //Drop !SS to begin transaction.
286 //Host to slave. Ignore data.
288 lastin=spitrans8(cmddata[i]);
290 //debugstr("EM260 transmission interrupted.");
295 //debugstr("Finished transmission to EM260.");
297 //Wait for nHOST_INT to drop.
306 while((cmddata[0]=spitrans8(0xFF))==0xFF
310 debugstr("Gave up on host interrupt.");
315 (cmddata[len++]=spitrans8(0xFF))!=0xA7
318 while(len<cmddata[1]+3)
319 cmddata[len++]=spitrans8(0xFF);
320 SETSS; //Raise !SS to end transaction.
322 txdata(app,verb,len);
326 //! Handles a monitor command.
327 void spi_handle_fn( uint8_t const app,
333 //Raise !SS to end transaction, just in case we forgot.
341 CLRSS; //Drop !SS to begin transaction.
343 cmddata[i]=spitrans8(cmddata[i]);
344 SETSS; //Raise !SS to end transaction.
345 txdata(app,verb,len);
348 case SPI_RW_EM260: //SPI exchange with an EM260
349 spi_rw_em260(app,verb,len);
352 case SPI_JEDEC://Grab 3-byte JEDEC ID.
353 CLRSS; //Drop !SS to begin transaction.
355 l=3; //Length is variable in some chips, 3 minimum.
356 for(i = 0; i < l; i++)
357 cmddata[i]=spitrans8(cmddata[i]);
358 txdata(app,verb,len);
359 SETSS; //Raise !SS to end transaction.
362 case PEEK://Grab 128 bytes from an SPI Flash ROM
363 spiflash_peek(app,verb,len);
366 case POKE://Poke up bytes from an SPI Flash ROM.
367 spiflash_pokeblocks(cmddatalong[0],//adr
373 case SPI_ERASE://Erase the SPI Flash ROM.
375 CLRSS; //Drop !SS to begin transaction.
376 spitrans8(0xC7);//Chip Erase
377 SETSS; //Raise !SS to end transaction.
379 while(spiflash_status()&0x01)//while busy