c86711dec017f558c53a9fa0366af1b2f6e59707
[goodfet] / firmware / apps / avr / avr.c
1 /*! \file avr.c
2   \author Travis Goodspeed
3   \brief AVR SPI Programmer
4 */
5
6 #include "platform.h"
7 #include "command.h"
8
9 #include <signal.h>
10 #include <io.h>
11 #include <iomacros.h>
12
13 #include "avr.h"
14
15 //! Setup the AVR pins.
16 void avrsetup(){
17   spisetup();
18 }
19
20 //! Initialized an attached AVR.
21 void avrconnect(){
22   register int i;
23   avrsetup();//set I/O pins
24   
25   //Pulse !RST (SS) at least twice while CLK is low.
26   CLRCLK;
27   CLRSS;
28
29   SETSS;
30   CLRCLK;
31   delay(500);
32   CLRSS;
33   delay(500);
34   
35   //Enable programming
36   avr_prgen();
37 }
38
39 //! Read and write an SPI byte.
40 unsigned char avrtrans8(unsigned char byte){
41   register unsigned int bit;
42   //This function came from the SPI Wikipedia article.
43   //Minor alterations.
44   
45   for (bit = 0; bit < 8; bit++) {
46     /* write MOSI on trailing edge of previous clock */
47     if (byte & 0x80)
48       SETMOSI;
49     else
50       CLRMOSI;
51     byte <<= 1;
52     
53     delay(2);
54     SETCLK;
55   
56     /* read MISO on trailing edge */
57     byte |= READMISO;
58     delay(2);
59     CLRCLK;
60   }
61   
62   return byte;
63 }
64
65 //! Perform a 4-byte exchange.
66 u8 avrexchange(u8 a, u8 b, u8 c, u8 d){
67   avrtrans8(a);
68   avrtrans8(b);
69   if(avrtrans8(c)!=b){
70     debugstr("AVR sync error, b not returned as c.");
71   }else{
72     debugstr("Synced properly.");
73   }
74   return avrtrans8(d);
75 }
76
77 //! Enable AVR programming mode.
78 void avr_prgen(){
79   avrexchange(0xAC, 0x53, 0, 0);
80 }
81
82 //! Read AVR device code.
83 u8 avr_devicecode(){
84   return avrexchange(0x30, //Read signature byte
85               0x00,
86               0x00, //&0x03 is sig adr
87               0x00 //don't care.
88               );
89 }
90
91 //! Handles an AVR command.
92 void avrhandle(unsigned char app,
93                unsigned char verb,
94                unsigned long len){
95   unsigned long i;
96   
97   
98   switch(verb){
99   case READ:
100   case WRITE:
101     for(i=0;i<len;i++)
102       cmddata[i]=spitrans8(cmddata[i]);
103     txdata(app,verb,len);
104     break;
105   case SETUP:
106     avrsetup();
107     txdata(app,verb,0);
108     break;
109   case START://returns device code
110     avrconnect();
111     //no break here
112   case AVR_PEEKSIG:
113     cmddata[0]=avr_devicecode();
114     txdata(app,verb,1);
115     break;
116   case PEEK:
117   case POKE:
118   default:
119     debugstr("Verb unimplemented in AVR application.");
120     txdata(app,NOK,0);
121     break;
122   }
123 }
124