A fork of mAVRISP by Aaron Berk. This version does not use a local file system to hold the AVR program. Instead it uses a serial connection to a PC and a python script to send the AVR program to the mbed.
Fork of mAVRISP by
main.cpp@4:ceee1eb7062e, 2015-01-31 (annotated)
- Committer:
- jeroenmbed
- Date:
- Sat Jan 31 22:44:09 2015 +0000
- Revision:
- 4:ceee1eb7062e
- Parent:
- 3:df6782d01720
Cleaned up.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
aberk | 0:3066745764a5 | 1 | /** |
aberk | 0:3066745764a5 | 2 | * Program an AVR with an mbed. |
jeroenmbed | 4:ceee1eb7062e | 3 | * The mbed is connected to an ATMEGA328 via ISP. |
jeroenmbed | 4:ceee1eb7062e | 4 | * The PC has a serial connection to the mbed. |
jeroenmbed | 4:ceee1eb7062e | 5 | * The AVR program on the PC is send via the serial connection to the mbed using a python script. |
jeroenmbed | 4:ceee1eb7062e | 6 | * The mbed then programs the ATMEGA328 via ISP. |
aberk | 0:3066745764a5 | 7 | */ |
aberk | 0:3066745764a5 | 8 | |
jeroenmbed | 4:ceee1eb7062e | 9 | #include "AVR910_Serial.h" |
jeroenmbed | 4:ceee1eb7062e | 10 | #include "mbed.h" |
aberk | 0:3066745764a5 | 11 | |
jeroenmbed | 4:ceee1eb7062e | 12 | // serial connection to a pc |
aberk | 0:3066745764a5 | 13 | Serial pc(USBTX, USBRX); |
jeroenmbed | 4:ceee1eb7062e | 14 | // ISP programmer |
jeroenmbed | 3:df6782d01720 | 15 | AVR910 mAVRISP(PB_15, PB_14, PB_13, PB_2); //mosi, miso, sclk, nreset. |
aberk | 0:3066745764a5 | 16 | |
jeroenmbed | 3:df6782d01720 | 17 | int main() |
jeroenmbed | 3:df6782d01720 | 18 | { |
aberk | 0:3066745764a5 | 19 | int success = -1; |
aberk | 0:3066745764a5 | 20 | int response = 0; |
aberk | 1:276f6df4be7a | 21 | |
aberk | 0:3066745764a5 | 22 | //Read the vendor code [0x1E == Atmel]. |
aberk | 0:3066745764a5 | 23 | response = mAVRISP.readVendorCode(); |
jeroenmbed | 4:ceee1eb7062e | 24 | |
aberk | 0:3066745764a5 | 25 | if (response == ATMEL_VENDOR_CODE) { |
aberk | 0:3066745764a5 | 26 | pc.printf("Microcontroller is an Atmel [0x%02x]\n", response); |
aberk | 0:3066745764a5 | 27 | } else if (response == DEVICE_LOCKED) { |
aberk | 0:3066745764a5 | 28 | pc.printf("Device is locked\n"); |
aberk | 0:3066745764a5 | 29 | return -1; |
aberk | 0:3066745764a5 | 30 | } else { |
aberk | 0:3066745764a5 | 31 | pc.printf("Microcontroller is not an Atmel\n"); |
aberk | 0:3066745764a5 | 32 | return -1; |
aberk | 0:3066745764a5 | 33 | } |
aberk | 1:276f6df4be7a | 34 | |
aberk | 0:3066745764a5 | 35 | //Read part family and flash size - see datasheet for code meaning. |
aberk | 0:3066745764a5 | 36 | response = mAVRISP.readPartFamilyAndFlashSize(); |
aberk | 0:3066745764a5 | 37 | |
aberk | 0:3066745764a5 | 38 | if (response == 0xFF) { |
aberk | 0:3066745764a5 | 39 | pc.printf("Device code erased or target missing\n"); |
aberk | 0:3066745764a5 | 40 | } else if (response == 0x01) { |
aberk | 0:3066745764a5 | 41 | pc.printf("Device locked\n"); |
aberk | 0:3066745764a5 | 42 | return -1; |
aberk | 0:3066745764a5 | 43 | } else { |
aberk | 0:3066745764a5 | 44 | pc.printf("Part family and flash size code is: 0x%02x\n", response); |
aberk | 0:3066745764a5 | 45 | } |
aberk | 0:3066745764a5 | 46 | |
aberk | 0:3066745764a5 | 47 | //Read part number. |
aberk | 0:3066745764a5 | 48 | response = mAVRISP.readPartNumber(); |
aberk | 0:3066745764a5 | 49 | |
aberk | 0:3066745764a5 | 50 | if (response == 0xFF) { |
aberk | 0:3066745764a5 | 51 | pc.printf("Device code erased or target missing\n"); |
aberk | 0:3066745764a5 | 52 | } else if (response == 0x02) { |
aberk | 0:3066745764a5 | 53 | pc.printf("Device locked\n"); |
aberk | 0:3066745764a5 | 54 | return -1; |
aberk | 0:3066745764a5 | 55 | } else { |
aberk | 0:3066745764a5 | 56 | pc.printf("Part number code is: 0x%02x\n", response); |
aberk | 0:3066745764a5 | 57 | } |
aberk | 1:276f6df4be7a | 58 | |
jeroenmbed | 4:ceee1eb7062e | 59 | // signal the python script it can start sending the file size |
jeroenmbed | 3:df6782d01720 | 60 | printf("@"); |
jeroenmbed | 4:ceee1eb7062e | 61 | |
jeroenmbed | 3:df6782d01720 | 62 | int hs, ls; |
jeroenmbed | 3:df6782d01720 | 63 | while (!pc.readable()); |
jeroenmbed | 3:df6782d01720 | 64 | hs = pc.getc(); |
jeroenmbed | 3:df6782d01720 | 65 | while (!pc.readable()); |
jeroenmbed | 3:df6782d01720 | 66 | ls = pc.getc(); |
jeroenmbed | 4:ceee1eb7062e | 67 | int dataSize = (hs<<8) + ls; |
aberk | 1:276f6df4be7a | 68 | |
jeroenmbed | 4:ceee1eb7062e | 69 | // signal the python script it can start sending the file |
jeroenmbed | 3:df6782d01720 | 70 | printf("#"); |
jeroenmbed | 4:ceee1eb7062e | 71 | |
jeroenmbed | 3:df6782d01720 | 72 | char *myFile; |
jeroenmbed | 4:ceee1eb7062e | 73 | myFile = new char [dataSize]; |
jeroenmbed | 3:df6782d01720 | 74 | int readChar=0; |
jeroenmbed | 4:ceee1eb7062e | 75 | while (readChar < dataSize) { |
jeroenmbed | 3:df6782d01720 | 76 | if (pc.readable()) { |
jeroenmbed | 3:df6782d01720 | 77 | myFile[readChar]=pc.getc(); |
jeroenmbed | 3:df6782d01720 | 78 | readChar++; |
jeroenmbed | 3:df6782d01720 | 79 | } |
jeroenmbed | 3:df6782d01720 | 80 | } |
jeroenmbed | 3:df6782d01720 | 81 | |
jeroenmbed | 4:ceee1eb7062e | 82 | // program the atmega |
jeroenmbed | 4:ceee1eb7062e | 83 | success = mAVRISP.programData(myFile, dataSize, ATMEGA328P_PAGESIZE, ATMEGA328P_NUM_PAGES); |
aberk | 1:276f6df4be7a | 84 | |
aberk | 1:276f6df4be7a | 85 | if (success < 0) { |
aberk | 0:3066745764a5 | 86 | printf("Programming failed.\n"); |
aberk | 1:276f6df4be7a | 87 | } else { |
aberk | 0:3066745764a5 | 88 | printf("Programming was successful!\n"); |
aberk | 0:3066745764a5 | 89 | } |
jeroenmbed | 4:ceee1eb7062e | 90 | |
jeroenmbed | 4:ceee1eb7062e | 91 | // signal the python script it can stop |
jeroenmbed | 4:ceee1eb7062e | 92 | printf("$"); |
aberk | 1:276f6df4be7a | 93 | |
aberk | 0:3066745764a5 | 94 | } |
jeroenmbed | 3:df6782d01720 | 95 | |
jeroenmbed | 4:ceee1eb7062e | 96 | /* Python script to be run on the pc: |
jeroenmbed | 3:df6782d01720 | 97 | import serial |
jeroenmbed | 3:df6782d01720 | 98 | import sys |
jeroenmbed | 3:df6782d01720 | 99 | import os |
jeroenmbed | 3:df6782d01720 | 100 | |
jeroenmbed | 3:df6782d01720 | 101 | fileName=sys.argv[1] |
jeroenmbed | 3:df6782d01720 | 102 | fileSize=os.path.getsize(fileName) |
jeroenmbed | 3:df6782d01720 | 103 | |
jeroenmbed | 3:df6782d01720 | 104 | serdev='/dev/ttyACM0' |
jeroenmbed | 3:df6782d01720 | 105 | s = serial.Serial(serdev) |
jeroenmbed | 3:df6782d01720 | 106 | |
jeroenmbed | 3:df6782d01720 | 107 | while True: |
jeroenmbed | 3:df6782d01720 | 108 | if s.readable(): |
jeroenmbed | 3:df6782d01720 | 109 | c = s.read() |
jeroenmbed | 3:df6782d01720 | 110 | if '@' in c: |
jeroenmbed | 3:df6782d01720 | 111 | hs = (fileSize>>8) & 0xff |
jeroenmbed | 3:df6782d01720 | 112 | s.write(chr(hs)) |
jeroenmbed | 3:df6782d01720 | 113 | ls = fileSize & 0xff |
jeroenmbed | 3:df6782d01720 | 114 | s.write(chr(ls)) |
jeroenmbed | 4:ceee1eb7062e | 115 | elif '#' in c: |
jeroenmbed | 3:df6782d01720 | 116 | with open(fileName, "rb") as f: |
jeroenmbed | 3:df6782d01720 | 117 | byte = f.read(1) |
jeroenmbed | 3:df6782d01720 | 118 | while byte != "": |
jeroenmbed | 3:df6782d01720 | 119 | s.write(byte) |
jeroenmbed | 3:df6782d01720 | 120 | byte = f.read(1) |
jeroenmbed | 4:ceee1eb7062e | 121 | elif '$' in c: |
jeroenmbed | 4:ceee1eb7062e | 122 | break |
jeroenmbed | 3:df6782d01720 | 123 | else: |
jeroenmbed | 3:df6782d01720 | 124 | sys.stdout.write(c) |
jeroenmbed | 3:df6782d01720 | 125 | */ |
jeroenmbed | 3:df6782d01720 | 126 | |
jeroenmbed | 3:df6782d01720 | 127 | /* avr test file: |
jeroenmbed | 3:df6782d01720 | 128 | #define F_CPU 1000000UL // 1 MHz |
jeroenmbed | 3:df6782d01720 | 129 | #include <avr/io.h> |
jeroenmbed | 3:df6782d01720 | 130 | #include <util/delay.h> |
jeroenmbed | 3:df6782d01720 | 131 | |
jeroenmbed | 3:df6782d01720 | 132 | int main(void) |
jeroenmbed | 3:df6782d01720 | 133 | { |
jeroenmbed | 3:df6782d01720 | 134 | // Set Port D pins as all outputs |
jeroenmbed | 4:ceee1eb7062e | 135 | DDRD = 0xff; |
jeroenmbed | 3:df6782d01720 | 136 | |
jeroenmbed | 3:df6782d01720 | 137 | // Set all Port D pins as HIGH |
jeroenmbed | 4:ceee1eb7062e | 138 | while (1) { |
jeroenmbed | 4:ceee1eb7062e | 139 | PORTD = 0xFF; |
jeroenmbed | 4:ceee1eb7062e | 140 | _delay_ms(500.); |
jeroenmbed | 4:ceee1eb7062e | 141 | PORTD = 0x00; |
jeroenmbed | 4:ceee1eb7062e | 142 | _delay_ms(500.); |
jeroenmbed | 4:ceee1eb7062e | 143 | } |
jeroenmbed | 4:ceee1eb7062e | 144 | return 1; |
jeroenmbed | 3:df6782d01720 | 145 | } |
jeroenmbed | 4:ceee1eb7062e | 146 | |
jeroenmbed | 4:ceee1eb7062e | 147 | The avr test file needs to be compiled, linked (make + make hex) to get a .hex file. |
jeroenmbed | 4:ceee1eb7062e | 148 | This hex needs to be transformed into a .bin file via hex2bin. |
jeroenmbed | 4:ceee1eb7062e | 149 | Make sure the mbed is up and running with the code in this file. |
jeroenmbed | 4:ceee1eb7062e | 150 | Then uploaded the .bin via the python script: python scriptName programName.bin |
jeroenmbed | 4:ceee1eb7062e | 151 | A reset of the mbed board may be needed. |
jeroenmbed | 3:df6782d01720 | 152 | */ |