1     #include <Mega32.h>
2     #include <delay.h>
3     #include <math.h>
4     #include <stdlib.h>
5     #include <stdio.h>
6     #include "mmc.c"
7
8     void initialize(void);  //all the usual mcu stuff 
9
10    //RXC ISR variables                       
11    unsigned char r_index;      //current string index
12    unsigned char r_buffer[16]; //input string 
13    unsigned char r_ready;      //flag for receive done
14    unsigned char r_char;       //current character
15    unsigned char r_count;      // wait until r_count chars received
16    unsigned char buffer[512];  // read in 512 bytes (256 instructions) at a time
17
18    void gets_int(int count);
19
20    void main(void)
21    {
22        register int i, j, offset;
23        char c;
24        int nInst, inst;
25        DDRC = 0xFF;
26        initialize();
27
28        PORTC = 0xFF;
29
30        r_count = 15;
31        offset = 0;
32
33        for (j = 0; j < 512; j++)
34        {
35           buffer[j] = 0;
36        }
37
38        MmcInit();
39
40        while (1)
41        {
42            // get the hello
43            gets_int(1);
44
45            // respond
46            putchar('!');
47
48            // get the # of instructions
49            gets_int(2);
50
51            nInst = ((int)r_buffer[0] << 8) | (r_buffer[1] << 0);
52
53            // respond
54            putchar('!');
55
56            j = 1;
57
58            buffer[0] = nInst >> 7;
59            buffer[1] = nInst << 1;
60
61            // ignore the first instruction
62            // it is 0x0000
63            gets_int(2);
64
65            // respond OK
66            putchar('+');
67
68            for (i = 1; i < nInst+1; i++)
69            {
70                // get an instruction
71                gets_int(2);
72                inst = ((int)r_buffer[0] << 8) | (r_buffer[1] << 0);
73
74                // put it in the buffer
75                buffer[(j << 1) + 0] = r_buffer[0];
76                buffer[(j << 1) + 1] = r_buffer[1];
77
78                // if we have received 256 instructions
79                // write them to flash
80                if (++j == 256)
81                {
82                    // write the buffer to the memcard
83                    mmc_write_sector(offset, buffer);
84
85                    // zero out the buffer
86                    for (j = 0; j < 512; j++)
87                    {
88                       buffer[j] = 0;
89                    }
90                    j = 0;
91                    offset += 512;
92                }
93
94                // respond OK
95                putchar('+');
96            }
97            if (j != 0)
98            {
99                // Write any instructions that didnt fully fill at 512byte buffer
100               mmc_write_sector(offset, buffer);
101
102               // zero out the buffer
103               for (j = 0; j < 512; j++)
104               {
105                   buffer[j] = 0;
106               }
107           }
108
109           // get terminating bytes
110           gets_int(2);
111
112           // Signal that you are ready for more
113           PORTC = 0b01010101;
114       }
115   }
116
117   void initialize(void)
118   {
119       //serial setup for debugging using printf, etc.     
120       UCSRB = 0x18;
121
122       // we run at 19200 instead of the slow 9600
123       UBRRL = 51;
124
125       #asm("sei");
126   }
127
128   void gets_int(int count)
129   {
130       r_ready=0;
131       r_index=0;
132       UCSRB.7=1;
133       r_count = count;
134       while (r_index != r_count);
135   }
136
137
138   /*
139     Interrupts
140   */
141   //UART character-ready ISR
142   interrupt [USART_RXC] void uart_rec(void)
143   {
144       r_char = UDR;    //get a char
145       //build the input string
146       r_buffer[r_index++] = r_char;
147       if (r_index == r_count)
148       {
149           r_buffer[r_index] = 0x00;
150           r_ready = 1;
151           UCSRB.7 = 0;
152       }
153   }