X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Favr%2Favr.c;h=0cc4c0da79842727fd70833ad4dba75b8321400d;hp=47ae68ec8b7d81a5e68321da3e96c10ff4552003;hb=3e4992b4d109f361b42abdda403471860edfeabf;hpb=e2a75fc68bc3cedaadb2db57b9e579a0f4468380 diff --git a/firmware/apps/avr/avr.c b/firmware/apps/avr/avr.c index 47ae68e..0cc4c0d 100644 --- a/firmware/apps/avr/avr.c +++ b/firmware/apps/avr/avr.c @@ -11,6 +11,7 @@ #include #include "avr.h" +//#include "glitch.h" //! Setup the AVR pins. void avrsetup(){ @@ -19,59 +20,144 @@ void avrsetup(){ //! Initialized an attached AVR. void avrconnect(){ - register int i; - avrsetup();//set I/O pins + //set I/O pins + avrsetup(); //Cut this? + + SETSS; + //delay(50); //Pulse !RST (SS) at least twice while CLK is low. + CLRCLK; CLRSS; + //delay(5); + + SETSS; CLRCLK; - - for(i=0;i<5;i++){ - SETSS; - CLRSS; - } + //delay(5); + CLRSS; + //delay(5); //Enable programming avr_prgen(); } +//! Read and write an SPI byte with delays. +u8 avrtrans8(u8 byte){ + register u16 bit; + //This function came from the SPI Wikipedia article. + //Minor alterations. + + for (bit = 0; bit < 8; bit++) { + /* write MOSI on trailing edge of previous clock */ + if (byte & 0x80) + SETMOSI; + else + CLRMOSI; + byte <<= 1; + + delay(2); + SETCLK; + + /* read MISO on trailing edge */ + byte |= READMISO; + delay(2); + CLRCLK; + } + + return byte; +} + //! Perform a 4-byte exchange. u8 avrexchange(u8 a, u8 b, u8 c, u8 d){ - spitrans8(a); - spitrans8(b); - if(spitrans8(c)!=b){ - debugstr("AVR sync error, b not returned as c."); + avrtrans8(a); + avrtrans8(b); + if(avrtrans8(c)!=b){ + //debugstr("AVR sync error, b not returned as c."); + //Reconnect here? } - spitrans8(c); - return spitrans8(d); + return avrtrans8(d); } //! Enable AVR programming mode. void avr_prgen(){ - avrexchange(0xac, 0x53, 0, 0); + avrexchange(0xAC, 0x53, 0, 0); +} + +//! Is the AVR ready or busy? +u8 avr_isready(){ + return avrexchange(0xF0, 0, 0, 0); } //! Read AVR device code. -u8 avr_devicecode(){ +u8 avr_sig(u8 i){ return avrexchange(0x30, //Read signature byte 0x00, - 0x00, //&0x03 is sig adr - 0x00 //don't care. + i&0x03, //sig adr + 0x00 //don't care. ); } +//! Erase an AVR device +void avr_erase(){ + avrexchange(0xAC, 0x80, 0, 0); +} + +//! Read lock bits. +u8 avr_lockbits(){ + return avrexchange(0x58, 0, 0, 0); +} +//! Write lock bits. +void avr_setlock(u8 bits){ + avrexchange(0xAC,0xE0,0x00, + bits); +} + +//! Read a byte of EEPROM. +u8 avr_peekeeprom(u16 adr){ + return avrexchange(0xA0, adr>>8, adr&0xFF, 0); +} +//! Read a byte of EEPROM. +u8 avr_pokeeeprom(u16 adr, u8 val){ + return avrexchange(0xC0, adr>>8, adr&0xFF, val); +} + +//! Read a byte of Flash +u8 avr_peekflash(u16 adr){ + u16 a=adr>>1; + if(adr&1) //high byte + return avrexchange(0x28,a>>8,a&0xff,0); + else //low byte + return avrexchange(0x20,a>>8,a&0xff,0); +} + +void avr_bulk_load(u16 start, u16 len, u8 *data) { + u16 adr; + for (adr = 0; adr < len; adr++) { + u16 a = adr + start; + avrexchange((adr & 1) ? 0x48 : 0x40, + a >> 9, + (a >> 1) & 0xff, + data[adr]); + } +} + //! Handles an AVR command. void avrhandle(unsigned char app, unsigned char verb, unsigned long len){ unsigned long i; + unsigned int at; + /* + if(!avr_isready() && connected) + debugstr("AVR is not yet ready."); + */ switch(verb){ case READ: case WRITE: for(i=0;i2){ + len=(cmddataword[1]);//always even. + }else{ + len=1; + } + txhead(app,verb,len); + for(i=0;i