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 */
62 //! Enable SPI writing
63 void spiflash_wrten(){
66 CLRSS; //Drop !SS to begin transaction.
67 spitrans8(0x04);//Write Disable
68 SETSS; //Raise !SS to end transaction.
70 CLRSS; //Drop !SS to begin transaction.
71 spitrans8(0x06);//Write Enable
72 SETSS; //Raise !SS to end transaction.
76 //! Grab the SPI flash status byte.
77 unsigned char spiflash_status(){
79 SETSS; //Raise !SS to end transaction.
80 CLRSS; //Drop !SS to begin transaction.
81 spitrans8(0x05);//GET STATUS
83 SETSS; //Raise !SS to end transaction.
88 //! Grab the SPI flash status byte.
89 void spiflash_setstatus(unsigned char c){
91 CLRSS; //Drop !SS to begin transaction.
92 spitrans8(0x01);//SET STATUS
94 SETSS; //Raise !SS to end transaction.
99 //! Read a block to a buffer.
100 void spiflash_peekblock(unsigned long adr,
106 CLRSS; //Drop !SS to begin transaction.
107 spitrans8(0x03);//Flash Read Command
110 spitrans8((adr&0xFF0000)>>16);
111 spitrans8((adr&0xFF00)>>8);
116 SETSS; //Raise !SS to end transaction.
119 //! Read a block to a buffer.
120 void spiflash_pokeblock(unsigned long adr,
128 // debugstr("Non-standard block size.");
130 while(spiflash_status()&0x01);//minor performance impact
132 spiflash_setstatus(0x02);
135 //Are these necessary?
136 //spiflash_setstatus(0x02);
139 CLRSS; //Drop !SS to begin transaction.
140 spitrans8(0x02); //Poke command.
143 spitrans8((adr&0xFF0000)>>16);
144 spitrans8((adr&0xFF00)>>8);
149 SETSS; //Raise !SS to end transaction.
151 while(spiflash_status()&0x01);//minor performance impact
156 //! Write many blocks to the SPI Flash.
157 void spiflash_pokeblocks(unsigned long adr,
160 long off=0;//offset of this block
161 int blen;//length of this block
165 //calculate block length
166 blen=(len-off>0x100?0x100:len-off);
168 spiflash_pokeblock(adr+off,
178 //! Peek some blocks.
179 void spiflash_peek(unsigned char app,
183 CLRSS; //Drop !SS to begin transaction.
184 spitrans8(0x03);//Flash Read Command
185 len=3;//write 3 byte pointer
187 spitrans8(cmddata[i]);
191 txhead(app,verb,len);
194 serial_tx(spitrans8(0));
196 SETSS; //Raise !SS to end transaction.
201 void spiflash_erasesector(unsigned long adr){
202 //debugstr("Erasing a 4kB sector.");
213 spitrans8((adr&0xFF0000)>>16);
214 spitrans8((adr&0xFF00)>>8);
218 while(spiflash_status()&0x01);//while busy
219 //debugstr("Erased.");
223 //! Handles a monitor command.
224 void spihandle(unsigned char app,
229 //Raise !SS to end transaction, just in case we forgot.
234 //PEEK and POKE might come later.
237 CLRSS; //Drop !SS to begin transaction.
239 cmddata[i]=spitrans8(cmddata[i]);
240 SETSS; //Raise !SS to end transaction.
241 txdata(app,verb,len);
245 case SPI_JEDEC://Grab 3-byte JEDEC ID.
246 CLRSS; //Drop !SS to begin transaction.
248 len=3; //Length is variable in some chips, 3 minimum.
250 cmddata[i]=spitrans8(cmddata[i]);
251 txdata(app,verb,len);
252 SETSS; //Raise !SS to end transaction.
256 case PEEK://Grab 128 bytes from an SPI Flash ROM
257 spiflash_peek(app,verb,len);
261 case POKE://Poke up bytes from an SPI Flash ROM.
262 spiflash_pokeblocks(cmddatalong[0],//adr
270 case SPI_ERASE://Erase the SPI Flash ROM.
272 CLRSS; //Drop !SS to begin transaction.
273 spitrans8(0xC7);//Chip Erase
274 SETSS; //Raise !SS to end transaction.
277 while(spiflash_status()&0x01)//while busy