2 \author Travis Goodspeed
6 //Higher level left to client application.
17 //This could be more accurate.
18 //Does it ever need to be?
24 //! Set up the pins for SPI mode.
27 P5DIR|=MOSI+SCK+BIT0; //BIT0 might be SS
31 //Begin a new transaction.
37 //! Read and write an SPI byte.
38 unsigned char spitrans8(unsigned char byte){
39 register unsigned int bit;
40 //This function came from the SPI Wikipedia article.
43 for (bit = 0; bit < 8; bit++) {
44 /* write MOSI on trailing edge of previous clock */
53 /* read MISO on trailing edge */
61 //! Enable SPI writing
62 void spiflash_wrten(){
65 CLRSS; //Drop !SS to begin transaction.
66 spitrans8(0x04);//Write Disable
67 SETSS; //Raise !SS to end transaction.
69 CLRSS; //Drop !SS to begin transaction.
70 spitrans8(0x06);//Write Enable
71 SETSS; //Raise !SS to end transaction.
75 //! Grab the SPI flash status byte.
76 unsigned char spiflash_status(){
78 SETSS; //Raise !SS to end transaction.
79 CLRSS; //Drop !SS to begin transaction.
80 spitrans8(0x05);//GET STATUS
82 SETSS; //Raise !SS to end transaction.
87 //! Grab the SPI flash status byte.
88 void spiflash_setstatus(unsigned char c){
90 CLRSS; //Drop !SS to begin transaction.
91 spitrans8(0x01);//SET STATUS
93 SETSS; //Raise !SS to end transaction.
98 //! Read a block to a buffer.
99 void spiflash_peekblock(unsigned long adr,
105 CLRSS; //Drop !SS to begin transaction.
106 spitrans8(0x03);//Flash Read Command
109 spitrans8((adr&0xFF0000)>>16);
110 spitrans8((adr&0xFF00)>>8);
115 SETSS; //Raise !SS to end transaction.
118 //! Read a block to a buffer.
119 void spiflash_pokeblock(unsigned long adr,
127 // debugstr("Non-standard block size.");
129 while(spiflash_status()&0x01);//minor performance impact
131 spiflash_setstatus(0x02);
134 //Are these necessary?
135 //spiflash_setstatus(0x02);
138 CLRSS; //Drop !SS to begin transaction.
139 spitrans8(0x02); //Poke command.
142 spitrans8((adr&0xFF0000)>>16);
143 spitrans8((adr&0xFF00)>>8);
148 SETSS; //Raise !SS to end transaction.
150 while(spiflash_status()&0x01);//minor performance impact
155 //! Write many blocks to the SPI Flash.
156 void spiflash_pokeblocks(unsigned long adr,
159 long off=0;//offset of this block
160 int blen;//length of this block
164 //calculate block length
165 blen=(len-off>0x100?0x100:len-off);
167 spiflash_pokeblock(adr+off,
177 //! Peek some blocks.
178 void spiflash_peek(unsigned char app,
182 CLRSS; //Drop !SS to begin transaction.
183 spitrans8(0x03);//Flash Read Command
184 len=3;//write 3 byte pointer
186 spitrans8(cmddata[i]);
190 txhead(app,verb,len);
193 serial_tx(spitrans8(0));
195 SETSS; //Raise !SS to end transaction.
200 void spiflash_erasesector(unsigned long adr){
201 //debugstr("Erasing a 4kB sector.");
212 spitrans8((adr&0xFF0000)>>16);
213 spitrans8((adr&0xFF00)>>8);
217 while(spiflash_status()&0x01);//while busy
218 //debugstr("Erased.");
222 //! Wake an EM260 Radio
224 //debugstr("Waking EM260.");
233 //debugstr("EM260 is now awake.");
234 delay(1024); //DO NOT REMOVE, fails without.
237 //! Handles a monitor command.
238 void spihandle(unsigned char app,
244 //Raise !SS to end transaction, just in case we forgot.
249 //PEEK and POKE might come later.
252 CLRSS; //Drop !SS to begin transaction.
254 cmddata[i]=spitrans8(cmddata[i]);
255 SETSS; //Raise !SS to end transaction.
256 txdata(app,verb,len);
259 case SPI_RW_EM260: //SPI exchange with an EM260
260 P4DIR=0; //TODO ASAP remove P4 references.
264 //See GoodFETEM260.py for details.
265 //The EM260 requires that the host wait for the client.
269 debugstr("Detected HOST_INT.");
276 SETMOSI; //Autodetected SPI mode.
277 CLRSS; //Drop !SS to begin transaction.
278 //Host to slave. Ignore data.
280 spitrans8(cmddata[i]);
282 //debugstr("Finished transmission to EM260.");
284 //Wait for nHOST_INT to drop.
292 while((cmddata[0]=spitrans8(0xFF))==0xFF
296 debugstr("Gave up on host interrupt.");
300 (cmddata[len++]=spitrans8(0xFF))!=0xA7
304 SETSS; //Raise !SS to end transaction.
305 txdata(app,verb,len);
309 case SPI_JEDEC://Grab 3-byte JEDEC ID.
310 CLRSS; //Drop !SS to begin transaction.
312 len=3; //Length is variable in some chips, 3 minimum.
314 cmddata[i]=spitrans8(cmddata[i]);
315 txdata(app,verb,len);
316 SETSS; //Raise !SS to end transaction.
319 case PEEK://Grab 128 bytes from an SPI Flash ROM
320 spiflash_peek(app,verb,len);
324 case POKE://Poke up bytes from an SPI Flash ROM.
325 spiflash_pokeblocks(cmddatalong[0],//adr
333 case SPI_ERASE://Erase the SPI Flash ROM.
335 CLRSS; //Drop !SS to begin transaction.
336 spitrans8(0xC7);//Chip Erase
337 SETSS; //Raise !SS to end transaction.
340 while(spiflash_status()&0x01)//while busy