Stand-alone AVR(328P) writer

Dependencies:   TextLCD mbed

Committer:
ytsuboi
Date:
Thu Dec 09 06:30:51 2010 +0000
Revision:
0:2a70d9d5c487
alpha-version for Make: Tokyo Meeting 06

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ytsuboi 0:2a70d9d5c487 1 // AVR(328P) stand-alone writer.
ytsuboi 0:2a70d9d5c487 2 // Written for Make: Tokyo meeting 06
ytsuboi 0:2a70d9d5c487 3 // by @ytsuboi
ytsuboi 0:2a70d9d5c487 4
ytsuboi 0:2a70d9d5c487 5 #include "mbed.h"
ytsuboi 0:2a70d9d5c487 6 // TextLCD could be found at http://mbed.org/users/simon/libraries/TextLCD/livod0
ytsuboi 0:2a70d9d5c487 7 #include "TextLCD.h"
ytsuboi 0:2a70d9d5c487 8
ytsuboi 0:2a70d9d5c487 9 LocalFileSystem local("local");
ytsuboi 0:2a70d9d5c487 10 TextLCD lcd(p24, p26, p27, p28, p29, p30);
ytsuboi 0:2a70d9d5c487 11 SPI avrspi(p11, p12, p13); // mosi, miso, sck
ytsuboi 0:2a70d9d5c487 12 DigitalOut avrrst(p14);
ytsuboi 0:2a70d9d5c487 13 DigitalIn enable(p10);
ytsuboi 0:2a70d9d5c487 14
ytsuboi 0:2a70d9d5c487 15 int main(void) {
ytsuboi 0:2a70d9d5c487 16 char str[100];
ytsuboi 0:2a70d9d5c487 17
ytsuboi 0:2a70d9d5c487 18 lcd.cls();
ytsuboi 0:2a70d9d5c487 19 // Start screen
ytsuboi 0:2a70d9d5c487 20 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 21 lcd.printf("mbed Stand-Alone");
ytsuboi 0:2a70d9d5c487 22 lcd.locate(5, 1);
ytsuboi 0:2a70d9d5c487 23 lcd.printf("AVR writer");
ytsuboi 0:2a70d9d5c487 24 wait(3);
ytsuboi 0:2a70d9d5c487 25
ytsuboi 0:2a70d9d5c487 26 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 27 lcd.printf("put your AVR and");
ytsuboi 0:2a70d9d5c487 28 lcd.locate(0, 1);
ytsuboi 0:2a70d9d5c487 29 lcd.printf("push to continue");
ytsuboi 0:2a70d9d5c487 30
ytsuboi 0:2a70d9d5c487 31 while(1) {
ytsuboi 0:2a70d9d5c487 32 if(!enable) {
ytsuboi 0:2a70d9d5c487 33 break;
ytsuboi 0:2a70d9d5c487 34 }
ytsuboi 0:2a70d9d5c487 35 wait(0.25);
ytsuboi 0:2a70d9d5c487 36 }
ytsuboi 0:2a70d9d5c487 37
ytsuboi 0:2a70d9d5c487 38 avrrst = 1;
ytsuboi 0:2a70d9d5c487 39 wait_ms(27);
ytsuboi 0:2a70d9d5c487 40 avrrst = 0;
ytsuboi 0:2a70d9d5c487 41 wait_ms(27);
ytsuboi 0:2a70d9d5c487 42
ytsuboi 0:2a70d9d5c487 43 // Setup the spi for 8 bit data, high steady state clock,
ytsuboi 0:2a70d9d5c487 44 // second edge capture, with a 100KHz clock rate
ytsuboi 0:2a70d9d5c487 45
ytsuboi 0:2a70d9d5c487 46 avrspi.format(8,0);
ytsuboi 0:2a70d9d5c487 47 avrspi.frequency(100000);
ytsuboi 0:2a70d9d5c487 48
ytsuboi 0:2a70d9d5c487 49 wait_ms(25);
ytsuboi 0:2a70d9d5c487 50
ytsuboi 0:2a70d9d5c487 51 // enter program mode
ytsuboi 0:2a70d9d5c487 52 avrspi.write(0xAC);
ytsuboi 0:2a70d9d5c487 53 avrspi.write(0x53);
ytsuboi 0:2a70d9d5c487 54 int response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 55 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 56
ytsuboi 0:2a70d9d5c487 57 lcd.cls();
ytsuboi 0:2a70d9d5c487 58 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 59 lcd.printf("Enter Prog mode:");
ytsuboi 0:2a70d9d5c487 60 lcd.locate(9, 1);
ytsuboi 0:2a70d9d5c487 61 if (response == 0x53) {
ytsuboi 0:2a70d9d5c487 62 lcd.printf("Success");
ytsuboi 0:2a70d9d5c487 63 } else {
ytsuboi 0:2a70d9d5c487 64 lcd.printf("Failed");
ytsuboi 0:2a70d9d5c487 65 return -1;
ytsuboi 0:2a70d9d5c487 66 }
ytsuboi 0:2a70d9d5c487 67
ytsuboi 0:2a70d9d5c487 68 wait(2);
ytsuboi 0:2a70d9d5c487 69
ytsuboi 0:2a70d9d5c487 70 // Check Device Sig.
ytsuboi 0:2a70d9d5c487 71 //Vendor Code
ytsuboi 0:2a70d9d5c487 72 avrspi.write(0x30);
ytsuboi 0:2a70d9d5c487 73 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 74 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 75 int sig0 = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 76 //Product Family Code and Flash Size
ytsuboi 0:2a70d9d5c487 77 avrspi.write(0x30);
ytsuboi 0:2a70d9d5c487 78 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 79 avrspi.write(0x01);
ytsuboi 0:2a70d9d5c487 80 int sig1 = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 81 //Part Number
ytsuboi 0:2a70d9d5c487 82 avrspi.write(0x30);
ytsuboi 0:2a70d9d5c487 83 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 84 avrspi.write(0x02);
ytsuboi 0:2a70d9d5c487 85 int sig2 = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 86
ytsuboi 0:2a70d9d5c487 87 lcd.cls();
ytsuboi 0:2a70d9d5c487 88 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 89 sprintf(str, "Device: %02X %02X %02X", sig0, sig1, sig2);
ytsuboi 0:2a70d9d5c487 90 lcd.printf(str);
ytsuboi 0:2a70d9d5c487 91 // lcd.printf("Device:");
ytsuboi 0:2a70d9d5c487 92 lcd.locate(0, 1);
ytsuboi 0:2a70d9d5c487 93 if (sig0==0x1E && sig1==0x95 && sig2==0x0F) {
ytsuboi 0:2a70d9d5c487 94 lcd.printf("ATmega 328P");
ytsuboi 0:2a70d9d5c487 95 } else if (sig0==0x1E) {
ytsuboi 0:2a70d9d5c487 96 lcd.printf("Unsupport Atmel");
ytsuboi 0:2a70d9d5c487 97 return -1;
ytsuboi 0:2a70d9d5c487 98 } else if (sig0==0x00 || sig1==0x01 || sig2==0x02) {
ytsuboi 0:2a70d9d5c487 99 lcd.printf("LOCKED!!");
ytsuboi 0:2a70d9d5c487 100 return -1;
ytsuboi 0:2a70d9d5c487 101 } else if (sig0==0xFF || sig1==0xFF || sig2||0xFF) {
ytsuboi 0:2a70d9d5c487 102 lcd.printf("MISSING!!");
ytsuboi 0:2a70d9d5c487 103 return -1;
ytsuboi 0:2a70d9d5c487 104 } else {
ytsuboi 0:2a70d9d5c487 105 lcd.printf("UNKNOWN!!");
ytsuboi 0:2a70d9d5c487 106 return -1;
ytsuboi 0:2a70d9d5c487 107 }
ytsuboi 0:2a70d9d5c487 108
ytsuboi 0:2a70d9d5c487 109 wait(2);
ytsuboi 0:2a70d9d5c487 110
ytsuboi 0:2a70d9d5c487 111 // Erase Flash
ytsuboi 0:2a70d9d5c487 112 lcd.cls();
ytsuboi 0:2a70d9d5c487 113 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 114 lcd.printf("Erasing Flash...");
ytsuboi 0:2a70d9d5c487 115 avrspi.write(0xAC);
ytsuboi 0:2a70d9d5c487 116 avrspi.write(0x80);
ytsuboi 0:2a70d9d5c487 117 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 118 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 119 wait_ms(9);
ytsuboi 0:2a70d9d5c487 120 //poll
ytsuboi 0:2a70d9d5c487 121 do {
ytsuboi 0:2a70d9d5c487 122 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 123 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 124 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 125 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 126 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 127 //end poll
ytsuboi 0:2a70d9d5c487 128 lcd.locate(10, 1);
ytsuboi 0:2a70d9d5c487 129 lcd.printf("DONE");
ytsuboi 0:2a70d9d5c487 130
ytsuboi 0:2a70d9d5c487 131 wait(2);
ytsuboi 0:2a70d9d5c487 132
ytsuboi 0:2a70d9d5c487 133 // Open binary file
ytsuboi 0:2a70d9d5c487 134 lcd.cls();
ytsuboi 0:2a70d9d5c487 135 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 136 lcd.printf("Opening file...");
ytsuboi 0:2a70d9d5c487 137 FILE *fp = fopen("/local/AVRCODE.bin", "rb");
ytsuboi 0:2a70d9d5c487 138
ytsuboi 0:2a70d9d5c487 139 if (fp == NULL) {
ytsuboi 0:2a70d9d5c487 140 lcd.locate(0, 1);
ytsuboi 0:2a70d9d5c487 141 lcd.printf("Failed to open!!");
ytsuboi 0:2a70d9d5c487 142 return -1;
ytsuboi 0:2a70d9d5c487 143 } else {
ytsuboi 0:2a70d9d5c487 144 lcd.locate(0, 1);
ytsuboi 0:2a70d9d5c487 145 lcd.printf("Opened!!");
ytsuboi 0:2a70d9d5c487 146 wait(2);
ytsuboi 0:2a70d9d5c487 147
ytsuboi 0:2a70d9d5c487 148 lcd.cls();
ytsuboi 0:2a70d9d5c487 149 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 150 lcd.printf("Writing binaries");
ytsuboi 0:2a70d9d5c487 151 // reset AVR
ytsuboi 0:2a70d9d5c487 152 // avrrst = 1;
ytsuboi 0:2a70d9d5c487 153 // wait_ms(27);
ytsuboi 0:2a70d9d5c487 154 // avrrst = 0;
ytsuboi 0:2a70d9d5c487 155 // wait_ms(27);
ytsuboi 0:2a70d9d5c487 156
ytsuboi 0:2a70d9d5c487 157 int pageOffset = 0;
ytsuboi 0:2a70d9d5c487 158 int pageNum = 0;
ytsuboi 0:2a70d9d5c487 159 int n = 0;
ytsuboi 0:2a70d9d5c487 160 int HighLow = 0;
ytsuboi 0:2a70d9d5c487 161
ytsuboi 0:2a70d9d5c487 162 // do programing
ytsuboi 0:2a70d9d5c487 163 while ((n = getc(fp)) != EOF) {
ytsuboi 0:2a70d9d5c487 164 //write loaded page to flash
ytsuboi 0:2a70d9d5c487 165 //Page size of 328P is 64word/page
ytsuboi 0:2a70d9d5c487 166 if (pageOffset == 64) {
ytsuboi 0:2a70d9d5c487 167 avrspi.write(0x4C);
ytsuboi 0:2a70d9d5c487 168 avrspi.write((pageNum >> 2) & 0x3F);
ytsuboi 0:2a70d9d5c487 169 avrspi.write((pageNum & 0x03) << 6);
ytsuboi 0:2a70d9d5c487 170 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 171 wait_ms(5);
ytsuboi 0:2a70d9d5c487 172 //poll
ytsuboi 0:2a70d9d5c487 173 do {
ytsuboi 0:2a70d9d5c487 174 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 175 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 176 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 177 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 178 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 179 //end poll
ytsuboi 0:2a70d9d5c487 180 pageNum++;
ytsuboi 0:2a70d9d5c487 181 // Total page of 328P is 256page
ytsuboi 0:2a70d9d5c487 182 if (pageNum > 256) {
ytsuboi 0:2a70d9d5c487 183 break;
ytsuboi 0:2a70d9d5c487 184 }
ytsuboi 0:2a70d9d5c487 185
ytsuboi 0:2a70d9d5c487 186 pageOffset = 0;
ytsuboi 0:2a70d9d5c487 187 }
ytsuboi 0:2a70d9d5c487 188
ytsuboi 0:2a70d9d5c487 189 // load low byte
ytsuboi 0:2a70d9d5c487 190 if (HighLow == 0) {
ytsuboi 0:2a70d9d5c487 191 avrspi.write(0x40);
ytsuboi 0:2a70d9d5c487 192 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 193 avrspi.write(pageOffset & 0x3F);
ytsuboi 0:2a70d9d5c487 194 avrspi.write(n);
ytsuboi 0:2a70d9d5c487 195
ytsuboi 0:2a70d9d5c487 196 //poll
ytsuboi 0:2a70d9d5c487 197 do {
ytsuboi 0:2a70d9d5c487 198 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 199 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 200 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 201 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 202 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 203 //end poll
ytsuboi 0:2a70d9d5c487 204
ytsuboi 0:2a70d9d5c487 205 HighLow = 1;
ytsuboi 0:2a70d9d5c487 206 }
ytsuboi 0:2a70d9d5c487 207 // load high byte
ytsuboi 0:2a70d9d5c487 208 else {
ytsuboi 0:2a70d9d5c487 209 avrspi.write(0x48);
ytsuboi 0:2a70d9d5c487 210 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 211 avrspi.write(pageOffset & 0x3F);
ytsuboi 0:2a70d9d5c487 212 avrspi.write(n);
ytsuboi 0:2a70d9d5c487 213
ytsuboi 0:2a70d9d5c487 214 //poll
ytsuboi 0:2a70d9d5c487 215 do {
ytsuboi 0:2a70d9d5c487 216 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 217 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 218 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 219 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 220 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 221 //end poll
ytsuboi 0:2a70d9d5c487 222
ytsuboi 0:2a70d9d5c487 223 HighLow = 0;
ytsuboi 0:2a70d9d5c487 224 pageOffset++;
ytsuboi 0:2a70d9d5c487 225 }
ytsuboi 0:2a70d9d5c487 226 }
ytsuboi 0:2a70d9d5c487 227
ytsuboi 0:2a70d9d5c487 228 //close binary file
ytsuboi 0:2a70d9d5c487 229 fclose(fp);
ytsuboi 0:2a70d9d5c487 230
ytsuboi 0:2a70d9d5c487 231 lcd.locate(0, 1);
ytsuboi 0:2a70d9d5c487 232 lcd.printf("DONE!!");
ytsuboi 0:2a70d9d5c487 233 wait(2);
ytsuboi 0:2a70d9d5c487 234 }
ytsuboi 0:2a70d9d5c487 235
ytsuboi 0:2a70d9d5c487 236 //write low fuse bit
ytsuboi 0:2a70d9d5c487 237 lcd.cls();
ytsuboi 0:2a70d9d5c487 238 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 239 lcd.printf("Writing Low Fuse");
ytsuboi 0:2a70d9d5c487 240 avrspi.write(0xAC);
ytsuboi 0:2a70d9d5c487 241 avrspi.write(0xA0);
ytsuboi 0:2a70d9d5c487 242 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 243 avrspi.write(0xE2);
ytsuboi 0:2a70d9d5c487 244 wait_ms(5);
ytsuboi 0:2a70d9d5c487 245 //poll
ytsuboi 0:2a70d9d5c487 246 do {
ytsuboi 0:2a70d9d5c487 247 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 248 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 249 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 250 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 251 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 252 //end poll
ytsuboi 0:2a70d9d5c487 253 lcd.locate(10, 1);
ytsuboi 0:2a70d9d5c487 254 lcd.printf("DONE");
ytsuboi 0:2a70d9d5c487 255 wait(1);
ytsuboi 0:2a70d9d5c487 256
ytsuboi 0:2a70d9d5c487 257 //write high fuse bit
ytsuboi 0:2a70d9d5c487 258 lcd.cls();
ytsuboi 0:2a70d9d5c487 259 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 260 lcd.printf("Writing Hi Fuse");
ytsuboi 0:2a70d9d5c487 261 avrspi.write(0xAC);
ytsuboi 0:2a70d9d5c487 262 avrspi.write(0xA8);
ytsuboi 0:2a70d9d5c487 263 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 264 avrspi.write(0xDA);
ytsuboi 0:2a70d9d5c487 265 wait_ms(5);
ytsuboi 0:2a70d9d5c487 266 //poll
ytsuboi 0:2a70d9d5c487 267 do {
ytsuboi 0:2a70d9d5c487 268 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 269 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 270 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 271 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 272 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 273 //end poll
ytsuboi 0:2a70d9d5c487 274 lcd.locate(10, 1);
ytsuboi 0:2a70d9d5c487 275 lcd.printf("DONE");
ytsuboi 0:2a70d9d5c487 276 wait(1);
ytsuboi 0:2a70d9d5c487 277
ytsuboi 0:2a70d9d5c487 278 //write ext fuse bit
ytsuboi 0:2a70d9d5c487 279 lcd.cls();
ytsuboi 0:2a70d9d5c487 280 lcd.locate(0, 0);
ytsuboi 0:2a70d9d5c487 281 lcd.printf("Writing Ext Fuse");
ytsuboi 0:2a70d9d5c487 282 avrspi.write(0xAC);
ytsuboi 0:2a70d9d5c487 283 avrspi.write(0xA4);
ytsuboi 0:2a70d9d5c487 284 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 285 avrspi.write(0x05);
ytsuboi 0:2a70d9d5c487 286 wait_ms(5);
ytsuboi 0:2a70d9d5c487 287 //poll
ytsuboi 0:2a70d9d5c487 288 do {
ytsuboi 0:2a70d9d5c487 289 avrspi.write(0xF0);
ytsuboi 0:2a70d9d5c487 290 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 291 avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 292 response = avrspi.write(0x00);
ytsuboi 0:2a70d9d5c487 293 } while ((response & 0x01) != 0);
ytsuboi 0:2a70d9d5c487 294 //end poll
ytsuboi 0:2a70d9d5c487 295 lcd.locate(10, 1);
ytsuboi 0:2a70d9d5c487 296 lcd.printf("DONE");
ytsuboi 0:2a70d9d5c487 297 wait(1);
ytsuboi 0:2a70d9d5c487 298
ytsuboi 0:2a70d9d5c487 299 // exit program mode
ytsuboi 0:2a70d9d5c487 300 avrrst = 1;
ytsuboi 0:2a70d9d5c487 301 // end
ytsuboi 0:2a70d9d5c487 302 return 0;
ytsuboi 0:2a70d9d5c487 303 }
ytsuboi 0:2a70d9d5c487 304