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 P5DIR|=MOSI+SCK+BIT0; //BIT0 might be SS
52 //Begin a new transaction.
60 //! Read and write an SPI byte.
61 unsigned char spitrans8(unsigned char byte){
62 register unsigned int bit;
63 //This function came from the SPI Wikipedia article.
66 for (bit = 0; bit < 8; bit++) {
67 /* write MOSI on trailing edge of previous clock */
78 /* read MISO on trailing edge */
86 //! Enable SPI writing
87 void spiflash_wrten(){
90 CLRSS; //Drop !SS to begin transaction.
91 spitrans8(0x04);//Write Disable
92 SETSS; //Raise !SS to end transaction.
94 CLRSS; //Drop !SS to begin transaction.
95 spitrans8(0x06);//Write Enable
96 SETSS; //Raise !SS to end transaction.
100 //! Grab the SPI flash status byte.
101 unsigned char spiflash_status(){
103 SETSS; //Raise !SS to end transaction.
104 CLRSS; //Drop !SS to begin transaction.
105 spitrans8(0x05);//GET STATUS
107 SETSS; //Raise !SS to end transaction.
112 //! Grab the SPI flash status byte.
113 void spiflash_setstatus(unsigned char c){
115 CLRSS; //Drop !SS to begin transaction.
116 spitrans8(0x01);//SET STATUS
118 SETSS; //Raise !SS to end transaction.
123 //! Read a block to a buffer.
124 void spiflash_peekblock(unsigned long adr,
130 CLRSS; //Drop !SS to begin transaction.
131 spitrans8(0x03);//Flash Read Command
134 spitrans8((adr&0xFF0000)>>16);
135 spitrans8((adr&0xFF00)>>8);
140 SETSS; //Raise !SS to end transaction.
143 //! Read a block to a buffer.
144 void spiflash_pokeblock(unsigned long adr,
152 // debugstr("Non-standard block size.");
154 while(spiflash_status()&0x01);//minor performance impact
156 spiflash_setstatus(0x02);
159 //Are these necessary?
160 //spiflash_setstatus(0x02);
163 CLRSS; //Drop !SS to begin transaction.
164 spitrans8(0x02); //Poke command.
167 spitrans8((adr&0xFF0000)>>16);
168 spitrans8((adr&0xFF00)>>8);
173 SETSS; //Raise !SS to end transaction.
175 while(spiflash_status()&0x01);//minor performance impact
180 //! Write many blocks to the SPI Flash.
181 void spiflash_pokeblocks(unsigned long adr,
184 long off=0;//offset of this block
185 int blen;//length of this block
189 //calculate block length
190 blen=(len-off>0x100?0x100:len-off);
192 spiflash_pokeblock(adr+off,
202 //! Peek some blocks.
203 void spiflash_peek(unsigned char app,
207 CLRSS; //Drop !SS to begin transaction.
208 spitrans8(0x03);//Flash Read Command
209 len=3;//write 3 byte pointer
211 spitrans8(cmddata[i]);
215 txhead(app,verb,len);
218 serial_tx(spitrans8(0));
220 SETSS; //Raise !SS to end transaction.
225 void spiflash_erasesector(unsigned long adr){
226 //debugstr("Erasing a 4kB sector.");
237 spitrans8((adr&0xFF0000)>>16);
238 spitrans8((adr&0xFF00)>>8);
242 while(spiflash_status()&0x01);//while busy
243 //debugstr("Erased.");
247 //! Wake an EM260 Radio
249 //debugstr("Waking EM260.");
258 //debugstr("EM260 is now awake.");
259 delay(1024); //DO NOT REMOVE, fails without.
261 //! Handle an EM260 exchange.
262 void spi_rw_em260(u8 app, u8 verb, u32 len){
266 P4DIR=0; //TODO ASAP remove P4 references.
270 //See GoodFETEM260.py for details.
271 //The EM260 requires that the host wait for the client.
275 debugstr("Detected HOST_INT.");
281 SETMOSI; //Autodetected SPI mode.
282 CLRSS; //Drop !SS to begin transaction.
283 //Host to slave. Ignore data.
285 lastin=spitrans8(cmddata[i]);
287 //debugstr("EM260 transmission interrupted.");
292 //debugstr("Finished transmission to EM260.");
294 //Wait for nHOST_INT to drop.
303 while((cmddata[0]=spitrans8(0xFF))==0xFF
307 debugstr("Gave up on host interrupt.");
312 (cmddata[len++]=spitrans8(0xFF))!=0xA7
315 while(len<cmddata[1]+3)
316 cmddata[len++]=spitrans8(0xFF);
317 SETSS; //Raise !SS to end transaction.
319 txdata(app,verb,len);
323 //! Handles a monitor command.
324 void spi_handle_fn( uint8_t const app,
330 //Raise !SS to end transaction, just in case we forgot.
338 CLRSS; //Drop !SS to begin transaction.
340 cmddata[i]=spitrans8(cmddata[i]);
341 SETSS; //Raise !SS to end transaction.
342 txdata(app,verb,len);
345 case SPI_RW_EM260: //SPI exchange with an EM260
346 spi_rw_em260(app,verb,len);
349 case SPI_JEDEC://Grab 3-byte JEDEC ID.
350 CLRSS; //Drop !SS to begin transaction.
352 l=3; //Length is variable in some chips, 3 minimum.
353 for(i = 0; i < l; i++)
354 cmddata[i]=spitrans8(cmddata[i]);
355 txdata(app,verb,len);
356 SETSS; //Raise !SS to end transaction.
359 case PEEK://Grab 128 bytes from an SPI Flash ROM
360 spiflash_peek(app,verb,len);
363 case POKE://Poke up bytes from an SPI Flash ROM.
364 spiflash_pokeblocks(cmddatalong[0],//adr
370 case SPI_ERASE://Erase the SPI Flash ROM.
372 CLRSS; //Drop !SS to begin transaction.
373 spitrans8(0xC7);//Chip Erase
374 SETSS; //Raise !SS to end transaction.
376 while(spiflash_status()&0x01)//while busy