2 \author Travis Goodspeed
6 //Higher level left to client application.
17 //! Handles a monitor command.
18 void spi_handle_fn( uint8_t const app,
22 // define the spi app's app_t
23 app_t const spi_app = {
35 "\tThe SPI app handles the SPI bus protocol, turning\n"
36 "\tyour GoodFET into a USB-to-SPI adapter.\n"
39 //This could be more accurate.
40 //Does it ever need to be?
42 #define SPIDELAY(x) delay(x)
45 //! Set up the pins for SPI mode.
48 SPIDIR|=MOSI+SCK+BIT0; //BIT0 might be SS
52 //Begin a new transaction.
59 //! Read and write an SPI byte.
60 unsigned char spitrans8(unsigned char byte){
61 register unsigned int bit;
62 //This function came from the SPI Wikipedia article.
65 for (bit = 0; bit < 8; bit++) {
66 /* write MOSI on trailing edge of previous clock */
77 /* read MISO on trailing edge */
85 //! Enable SPI writing
86 void spiflash_wrten(){
89 CLRSS; //Drop !SS to begin transaction.
90 spitrans8(0x04);//Write Disable
91 SETSS; //Raise !SS to end transaction.
93 CLRSS; //Drop !SS to begin transaction.
94 spitrans8(0x06);//Write Enable
95 SETSS; //Raise !SS to end transaction.
99 //! Grab the SPI flash status byte.
100 unsigned char spiflash_status(){
102 SETSS; //Raise !SS to end transaction.
103 CLRSS; //Drop !SS to begin transaction.
104 spitrans8(0x05);//GET STATUS
106 SETSS; //Raise !SS to end transaction.
111 //! Grab the SPI flash status byte.
112 void spiflash_setstatus(unsigned char c){
114 CLRSS; //Drop !SS to begin transaction.
115 spitrans8(0x01);//SET STATUS
117 SETSS; //Raise !SS to end transaction.
122 //! Read a block to a buffer.
123 void spiflash_peekblock(unsigned long adr,
129 CLRSS; //Drop !SS to begin transaction.
130 spitrans8(0x03);//Flash Read Command
133 spitrans8((adr&0xFF0000)>>16);
134 spitrans8((adr&0xFF00)>>8);
139 SETSS; //Raise !SS to end transaction.
142 //! Read a block to a buffer.
143 void spiflash_pokeblock(unsigned long adr,
151 // debugstr("Non-standard block size.");
153 while(spiflash_status()&0x01);//minor performance impact
155 spiflash_setstatus(0x02);
158 //Are these necessary?
159 //spiflash_setstatus(0x02);
162 CLRSS; //Drop !SS to begin transaction.
163 spitrans8(0x02); //Poke command.
166 spitrans8((adr&0xFF0000)>>16);
167 spitrans8((adr&0xFF00)>>8);
172 SETSS; //Raise !SS to end transaction.
174 while(spiflash_status()&0x01);//minor performance impact
179 //! Write many blocks to the SPI Flash.
180 void spiflash_pokeblocks(unsigned long adr,
183 long off=0;//offset of this block
184 int blen;//length of this block
188 //calculate block length
189 blen=(len-off>0x100?0x100:len-off);
191 spiflash_pokeblock(adr+off,
201 //! Peek some blocks.
202 void spiflash_peek(unsigned char app,
206 CLRSS; //Drop !SS to begin transaction.
207 spitrans8(0x03);//Flash Read Command
208 len=3;//write 3 byte pointer
210 spitrans8(cmddata[i]);
214 txhead(app,verb,len);
217 serial_tx(spitrans8(0));
219 SETSS; //Raise !SS to end transaction.
224 void spiflash_erasesector(unsigned long adr){
225 //debugstr("Erasing a 4kB sector.");
236 spitrans8((adr&0xFF0000)>>16);
237 spitrans8((adr&0xFF00)>>8);
241 while(spiflash_status()&0x01);//while busy
242 //debugstr("Erased.");
246 //! Wake an EM260 Radio
248 //debugstr("Waking EM260.");
257 //debugstr("EM260 is now awake.");
258 delay(1024); //DO NOT REMOVE, fails without.
260 //! Handle an EM260 exchange.
261 void spi_rw_em260(u8 app, u8 verb, u32 len){
265 P4DIR=0; //TODO ASAP remove P4 references.
269 //See GoodFETEM260.py for details.
270 //The EM260 requires that the host wait for the client.
274 debugstr("Detected HOST_INT.");
280 SETMOSI; //Autodetected SPI mode.
281 CLRSS; //Drop !SS to begin transaction.
282 //Host to slave. Ignore data.
284 lastin=spitrans8(cmddata[i]);
286 //debugstr("EM260 transmission interrupted.");
291 //debugstr("Finished transmission to EM260.");
293 //Wait for nHOST_INT to drop.
302 while((cmddata[0]=spitrans8(0xFF))==0xFF
306 debugstr("Gave up on host interrupt.");
311 (cmddata[len++]=spitrans8(0xFF))!=0xA7
314 while(len<cmddata[1]+3)
315 cmddata[len++]=spitrans8(0xFF);
316 SETSS; //Raise !SS to end transaction.
318 txdata(app,verb,len);
322 //! Handles a monitor command.
323 void spi_handle_fn( uint8_t const app,
329 //Raise !SS to end transaction, just in case we forgot.
337 CLRSS; //Drop !SS to begin transaction.
339 cmddata[i]=spitrans8(cmddata[i]);
340 SETSS; //Raise !SS to end transaction.
341 txdata(app,verb,len);
344 case SPI_RW_EM260: //SPI exchange with an EM260
345 spi_rw_em260(app,verb,len);
348 case SPI_JEDEC://Grab 3-byte JEDEC ID.
349 CLRSS; //Drop !SS to begin transaction.
351 l=3; //Length is variable in some chips, 3 minimum.
352 for(i = 0; i < l; i++)
353 cmddata[i]=spitrans8(cmddata[i]);
354 txdata(app,verb,len);
355 SETSS; //Raise !SS to end transaction.
358 case PEEK://Grab 128 bytes from an SPI Flash ROM
359 spiflash_peek(app,verb,len);
362 case POKE://Poke up bytes from an SPI Flash ROM.
363 spiflash_pokeblocks(cmddatalong[0],//adr
369 case SPI_ERASE://Erase the SPI Flash ROM.
371 CLRSS; //Drop !SS to begin transaction.
372 spitrans8(0xC7);//Chip Erase
373 SETSS; //Raise !SS to end transaction.
375 while(spiflash_status()&0x01)//while busy