2 \author Travis Goodspeed
6 //Higher level left to client application.
17 //This could be more accurate.
18 //Does it ever need to be?
20 #define SPIDELAY(x) delay(x)
23 //! Set up the pins for SPI mode.
26 P5DIR|=MOSI+SCK+BIT0; //BIT0 might be SS
30 //Begin a new transaction.
38 //! Read and write an SPI byte.
39 unsigned char spitrans8(unsigned char byte){
40 register unsigned int bit;
41 //This function came from the SPI Wikipedia article.
44 for (bit = 0; bit < 8; bit++) {
45 /* write MOSI on trailing edge of previous clock */
56 /* read MISO on trailing edge */
64 //! Enable SPI writing
65 void spiflash_wrten(){
68 CLRSS; //Drop !SS to begin transaction.
69 spitrans8(0x04);//Write Disable
70 SETSS; //Raise !SS to end transaction.
72 CLRSS; //Drop !SS to begin transaction.
73 spitrans8(0x06);//Write Enable
74 SETSS; //Raise !SS to end transaction.
78 //! Grab the SPI flash status byte.
79 unsigned char spiflash_status(){
81 SETSS; //Raise !SS to end transaction.
82 CLRSS; //Drop !SS to begin transaction.
83 spitrans8(0x05);//GET STATUS
85 SETSS; //Raise !SS to end transaction.
90 //! Grab the SPI flash status byte.
91 void spiflash_setstatus(unsigned char c){
93 CLRSS; //Drop !SS to begin transaction.
94 spitrans8(0x01);//SET STATUS
96 SETSS; //Raise !SS to end transaction.
101 //! Read a block to a buffer.
102 void spiflash_peekblock(unsigned long adr,
108 CLRSS; //Drop !SS to begin transaction.
109 spitrans8(0x03);//Flash Read Command
112 spitrans8((adr&0xFF0000)>>16);
113 spitrans8((adr&0xFF00)>>8);
118 SETSS; //Raise !SS to end transaction.
121 //! Read a block to a buffer.
122 void spiflash_pokeblock(unsigned long adr,
130 // debugstr("Non-standard block size.");
132 while(spiflash_status()&0x01);//minor performance impact
134 spiflash_setstatus(0x02);
137 //Are these necessary?
138 //spiflash_setstatus(0x02);
141 CLRSS; //Drop !SS to begin transaction.
142 spitrans8(0x02); //Poke command.
145 spitrans8((adr&0xFF0000)>>16);
146 spitrans8((adr&0xFF00)>>8);
151 SETSS; //Raise !SS to end transaction.
153 while(spiflash_status()&0x01);//minor performance impact
158 //! Write many blocks to the SPI Flash.
159 void spiflash_pokeblocks(unsigned long adr,
162 long off=0;//offset of this block
163 int blen;//length of this block
167 //calculate block length
168 blen=(len-off>0x100?0x100:len-off);
170 spiflash_pokeblock(adr+off,
180 //! Peek some blocks.
181 void spiflash_peek(unsigned char app,
185 CLRSS; //Drop !SS to begin transaction.
186 spitrans8(0x03);//Flash Read Command
187 len=3;//write 3 byte pointer
189 spitrans8(cmddata[i]);
193 txhead(app,verb,len);
196 serial_tx(spitrans8(0));
198 SETSS; //Raise !SS to end transaction.
203 void spiflash_erasesector(unsigned long adr){
204 //debugstr("Erasing a 4kB sector.");
215 spitrans8((adr&0xFF0000)>>16);
216 spitrans8((adr&0xFF00)>>8);
220 while(spiflash_status()&0x01);//while busy
221 //debugstr("Erased.");
225 //! Wake an EM260 Radio
227 //debugstr("Waking EM260.");
236 //debugstr("EM260 is now awake.");
237 delay(1024); //DO NOT REMOVE, fails without.
239 //! Handle an EM260 exchange.
240 void spi_rw_em260(u8 app, u8 verb, u32 len){
244 P4DIR=0; //TODO ASAP remove P4 references.
248 //See GoodFETEM260.py for details.
249 //The EM260 requires that the host wait for the client.
253 debugstr("Detected HOST_INT.");
259 SETMOSI; //Autodetected SPI mode.
260 CLRSS; //Drop !SS to begin transaction.
261 //Host to slave. Ignore data.
263 lastin=spitrans8(cmddata[i]);
265 //debugstr("EM260 transmission interrupted.");
270 //debugstr("Finished transmission to EM260.");
272 //Wait for nHOST_INT to drop.
281 while((cmddata[0]=spitrans8(0xFF))==0xFF
285 debugstr("Gave up on host interrupt.");
290 (cmddata[len++]=spitrans8(0xFF))!=0xA7
293 while(len<cmddata[1]+3)
294 cmddata[len++]=spitrans8(0xFF);
295 SETSS; //Raise !SS to end transaction.
297 txdata(app,verb,len);
301 //! Handles a monitor command.
302 void spihandle(unsigned char app,
308 //Raise !SS to end transaction, just in case we forgot.
313 //PEEK and POKE might come later.
316 CLRSS; //Drop !SS to begin transaction.
318 cmddata[i]=spitrans8(cmddata[i]);
319 SETSS; //Raise !SS to end transaction.
320 txdata(app,verb,len);
323 case SPI_RW_EM260: //SPI exchange with an EM260
324 spi_rw_em260(app,verb,len);
327 case SPI_JEDEC://Grab 3-byte JEDEC ID.
328 CLRSS; //Drop !SS to begin transaction.
330 len=3; //Length is variable in some chips, 3 minimum.
332 cmddata[i]=spitrans8(cmddata[i]);
333 txdata(app,verb,len);
334 SETSS; //Raise !SS to end transaction.
337 case PEEK://Grab 128 bytes from an SPI Flash ROM
338 spiflash_peek(app,verb,len);
342 case POKE://Poke up bytes from an SPI Flash ROM.
343 spiflash_pokeblocks(cmddatalong[0],//adr
351 case SPI_ERASE://Erase the SPI Flash ROM.
353 CLRSS; //Drop !SS to begin transaction.
354 spitrans8(0xC7);//Chip Erase
355 SETSS; //Raise !SS to end transaction.
358 while(spiflash_status()&0x01)//while busy