#include <io.h>
#include <iomacros.h>
-#include <spi.h>
+#include "spi.h"
//This could be more accurate.
//Does it ever need to be?
//! Read and write an SPI byte.
unsigned char spitrans8(unsigned char byte){
- unsigned int bit;
+ register unsigned int bit;
//This function came from the SPI Wikipedia article.
//Minor alterations.
CLRMOSI;
byte <<= 1;
- /* half a clock cycle before leading/rising edge */
- SPIDELAY(SPISPEED/2);
SETCLK;
-
- /* half a clock cycle before trailing/falling edge */
- SPIDELAY(SPISPEED/2);
-
+
/* read MISO on trailing edge */
byte |= READMISO;
CLRCLK;
SETSS; //Raise !SS to end transaction.
}
-
//! Read a block to a buffer.
void spiflash_pokeblock(unsigned long adr,
unsigned char *buf,
unsigned int len){
- unsigned char i;
+ unsigned int i;
SETSS;
+ //if(len!=0x100)
+ // debugstr("Non-standard block size.");
+
+ while(spiflash_status()&0x01);//minor performance impact
+
spiflash_setstatus(0x02);
spiflash_wrten();
+ //Are these necessary?
+ //spiflash_setstatus(0x02);
+ //spiflash_wrten();
+
CLRSS; //Drop !SS to begin transaction.
spitrans8(0x02); //Poke command.
spitrans8(buf[i]);
SETSS; //Raise !SS to end transaction.
- while(spiflash_status()&0x01);
-
+ while(spiflash_status()&0x01);//minor performance impact
return;
}
+//! Write many blocks to the SPI Flash.
+void spiflash_pokeblocks(unsigned long adr,
+ unsigned char *buf,
+ unsigned int len){
+ long off=0;//offset of this block
+ int blen;//length of this block
+ SETSS;
+
+ while(off<len){
+ //calculate block length
+ blen=(len-off>0x100?0x100:len-off);
+ //write the block
+ spiflash_pokeblock(adr+off,
+ buf+off,
+ blen);
+ //add offset
+ off+=blen;
+ }
+}
+
+
+
//! Peek some blocks.
void spiflash_peek(unsigned char app,
unsigned char verb,
- unsigned char len){
- register char blocks=(len>3?cmddata[3]:1);
- unsigned char i;
-
+ unsigned long len){
+ unsigned int i;
P5OUT&=~SS; //Drop !SS to begin transaction.
spitrans8(0x03);//Flash Read Command
len=3;//write 3 byte pointer
spitrans8(cmddata[i]);
//Send reply header
- len=0x80;//128 byte chunk, repeated for each block
- serial_tx(app);
- serial_tx(verb);
- serial_tx(len); //multiplied by block count.
+ len=0x1000;
+ txhead(app,verb,len);
+
+ while(len--)
+ serial_tx(spitrans8(0));
- while(blocks--){
- for(i=0;i<len;i++)
- serial_tx(spitrans8(0));
-
- /* old fashioned
- for(i=0;i<len;i++)
- cmddata[i]=spitrans8(0);
- txdata(app,verb,len);
- */
- }
P5OUT|=SS; //Raise !SS to end transaction.
}
+
+//! Erase a sector.
+void spiflash_erasesector(unsigned long adr){
+ //debugstr("Erasing a 4kB sector.");
+
+ //Write enable.
+ spiflash_wrten();
+
+ //Begin
+ CLRSS;
+
+ //Second command.
+ spitrans8(0x20);
+ //Send address
+ spitrans8((adr&0xFF0000)>>16);
+ spitrans8((adr&0xFF00)>>8);
+ spitrans8(adr&0xFF);
+
+ SETSS;
+ while(spiflash_status()&0x01);//while busy
+ //debugstr("Erased.");
+}
+
+
//! Handles a monitor command.
void spihandle(unsigned char app,
unsigned char verb,
- unsigned char len){
- unsigned char i;
+ unsigned long len){
+ unsigned long i;
//Raise !SS to end transaction, just in case we forgot.
P5OUT|=SS;
case POKE://Poke up bytes from an SPI Flash ROM.
- spiflash_setstatus(0x02);
- spiflash_wrten();
-
- P5OUT&=~SS; //Drop !SS to begin transaction.
- spitrans8(0x02); //Poke command.
-
- //First three bytes are address, then data.
- for(i=0;i<len;i++)
- spitrans8(cmddata[i]);
- P5OUT|=SS; //Raise !SS to end transaction.
+ spiflash_pokeblocks(cmddatalong[0],//adr
+ cmddata+4,//buf
+ len-4);//len
-
-
- while(spiflash_status()&0x01)
- P1OUT^=1;
-
- P1OUT&=~1;
-
- txdata(app,verb,len);
+ txdata(app,verb,0);
break;
spitrans8(0xC7);//Chip Erase
P5OUT|=SS; //Raise !SS to end transaction.
-
+
while(spiflash_status()&0x01)//while busy
P1OUT^=1;
P1OUT&=~1;