Skip to content

Commit 3fe73c0

Browse files
committed
works pretty well
1 parent f514351 commit 3fe73c0

File tree

3 files changed

+122
-44
lines changed

3 files changed

+122
-44
lines changed

prog.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import serial, sys, struct, time
2+
3+
if len(sys.argv) != 3:
4+
print 'usage: %s <serial-port> <firmware.hex>' % sys.argv[0]
5+
sys.exit(1)
6+
7+
ser = serial.Serial(sys.argv[1], 1000000, timeout = 1)
8+
time.sleep(1)
9+
10+
11+
print 'Connected'
12+
13+
f = open(sys.argv[2],'r').readlines()
14+
15+
# init Programming Interface (PI)
16+
ser.write('\x01\x00')
17+
x =struct.unpack('B', ser.read(1))[0]
18+
print 'x:',hex(x)
19+
assert(0x81 == x)
20+
print 'read 2 bytes'
21+
22+
print 'PI initiated'
23+
24+
# erase device
25+
ser.write('\x04\x00')
26+
assert(0x84 == struct.unpack('B', ser.read(1))[0])
27+
28+
print 'Device erased'
29+
30+
# write hex file
31+
total = 0
32+
buf = ''
33+
buf_size = 0
34+
for i in f[1:-1]: # skip first and second lines
35+
assert(i[0] == ':')
36+
size = int(i[1:3],16)
37+
assert(size + 4 < 256)
38+
if buf_size == 0:
39+
addrh = int(i[3:5],16)
40+
addrl = int(i[5:7],16)
41+
assert(i[7:9] == '00')
42+
data = i[9:9 + size*2]
43+
assert(len(data) == size*2)
44+
45+
buf += data
46+
buf_size += size
47+
48+
if buf_size > 175:
49+
#print hex(addrh), hex(addrl), buf
50+
ser.write([0x3, buf_size + 4, buf_size, 0, addrh, addrl])
51+
ser.write(buf.decode('hex'))
52+
assert(0x83 == struct.unpack('B', ser.read(1))[0])
53+
total += buf_size
54+
buf_size = 0
55+
buf = ''
56+
print 'Wrote %d bytes' % total
57+
58+
# reset device
59+
ser.write('\x02\x00')
60+
assert(0x82 == struct.unpack('B', ser.read(1))[0])
61+
62+
print 'Device reset'
63+
64+

prog/prog.ino

+57-44
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,90 @@
22
* Based on https://gist.github.com/racerxdl/c9a592808acdd9cd178e6e97c83f8baf
33
* which was based on: https://github.com/jaromir-sukuba/efm8prog/
44
Use his SW to program EFM8 using arduino.
5-
This needs some work though (but it works)
65
**/
7-
#define C2D 2
8-
#define C2CK 3
9-
#define LED 13 // build in on Mega
6+
7+
// GPIO is manipulated through PORT mappings for better speed.
8+
// Flashes EFM8 at about 10kB/s
9+
// Baud rate: 1000000
10+
11+
// Digital pin 2 on Mega
12+
#define C2D_PORT PORTE
13+
#define C2D_PIN 4
14+
15+
// Digital pin 3 on Mega
16+
#define C2CK_PORT PORTE
17+
#define C2CK_PIN 5
18+
19+
#define LED LED_BUILTIN
1020

1121
#define INBUSY 0x02
1222
#define OUTREADY 0x01
1323

14-
void c2_send_bits (unsigned char data, unsigned char len);
15-
void c2_pulse_clk (void);
16-
unsigned char c2_read_bits (unsigned char len);
24+
static void c2_send_bits (unsigned char data, unsigned char len);
25+
static unsigned char c2_read_bits (unsigned char len);
1726

1827
void c2_rst (void);
1928
void c2_write_addr (unsigned char addr);
20-
unsigned char c2_read_addr (void);
21-
unsigned char c2_read_data (void);
22-
void c2_write_data (unsigned char addr);
29+
static unsigned char c2_read_addr (void);
30+
static unsigned char c2_read_data (void);
31+
static void c2_write_data (unsigned char addr);
2332

2433
unsigned char c2_init_PI (void);
2534
unsigned char c2_read_flash_block (unsigned int addr, unsigned char * data, unsigned char len);
26-
unsigned char c2_poll_bit_low (unsigned char mask);
27-
unsigned char c2_poll_bit_high (unsigned char mask);
35+
static unsigned char c2_poll_bit_low (unsigned char mask);
36+
static unsigned char c2_poll_bit_high (unsigned char mask);
2837
unsigned char c2_write_flash_block (unsigned int addr, unsigned char * data, unsigned char len);
2938
unsigned char c2_erase_device (void);
3039

3140

3241
void c2_rst() {
33-
digitalWrite(C2CK, LOW);
34-
delayMicroseconds(100);
35-
digitalWrite(C2CK, HIGH);
36-
delayMicroseconds(100);
42+
C2CK_PORT &= ~(1<<C2CK_PIN);
43+
delayMicroseconds(50);
44+
C2CK_PORT |= (1<<C2CK_PIN);
45+
delayMicroseconds(50);
3746
}
3847

39-
void c2_pulse_clk() {
40-
pinMode(C2CK, OUTPUT);
41-
digitalWrite(C2CK, LOW);
42-
digitalWrite(C2CK, LOW);
43-
digitalWrite(C2CK, LOW);
44-
digitalWrite(C2CK, LOW);
45-
digitalWrite(C2CK, HIGH);
46-
}
48+
#define c2_pulse_clk()\
49+
C2CK_PORT &= ~(1<<C2CK_PIN); \
50+
C2CK_PORT |= (1<<C2CK_PIN);
51+
4752

48-
unsigned char c2_read_bits (unsigned char len) {
53+
static unsigned char c2_read_bits (unsigned char len) {
4954
unsigned char i, data, mask;
5055
mask = 0x01 << (len-1);
5156
data = 0;
52-
pinMode(C2D, INPUT);
57+
//pinMode(C2D, INPUT);
58+
DDRE &= ~(1<<C2D_PIN);
59+
PINE &= (1<<C2D_PIN);
5360
for (i=0;i<len;i++) {
5461
c2_pulse_clk();
5562
data = data >> 1;
56-
if (digitalRead(C2D) == HIGH) {
63+
if (PINE & (1<<C2D_PIN)) {
5764
data = data | mask;
5865
}
5966
}
60-
pinMode(C2D, OUTPUT);
67+
DDRE |= (1<<C2D_PIN);
68+
//pinMode(C2D, OUTPUT);
6169

6270
return data;
6371
}
6472

65-
void c2_send_bits (unsigned char data, unsigned char len) {
73+
static void c2_send_bits (unsigned char data, unsigned char len) {
6674
unsigned char i;
67-
pinMode(C2D, OUTPUT);
75+
//pinMode(C2D, OUTPUT);
76+
DDRE |= (1<<C2D_PIN);
6877
for (i=0;i<len;i++) {
6978
if (data&0x01) {
70-
digitalWrite(C2D, HIGH);
79+
C2D_PORT |= (1<<C2D_PIN);
7180
} else {
72-
digitalWrite(C2D, LOW);
81+
C2D_PORT &= ~(1<<C2D_PIN);
7382
}
7483
c2_pulse_clk();
7584
data = data >> 1;
7685
}
7786
}
7887

79-
void c2_write_data (unsigned char data) {
88+
static void c2_write_data (unsigned char data) {
8089
unsigned char retval;
8190
c2_send_bits(0x0, 1);
8291
c2_send_bits(0x1, 2);
@@ -89,13 +98,13 @@ void c2_write_data (unsigned char data) {
8998
c2_send_bits(0x0, 1);
9099
}
91100

92-
unsigned char c2_poll_bit_high (unsigned char mask) {
101+
static unsigned char c2_poll_bit_high (unsigned char mask) {
93102
unsigned char retval;
94103
retval = c2_read_addr();
95104
while ((retval&mask)==0) retval = c2_read_addr();
96105
}
97106

98-
unsigned char c2_poll_bit_low (unsigned char mask) {
107+
static unsigned char c2_poll_bit_low (unsigned char mask) {
99108
unsigned char retval;
100109
retval = c2_read_addr();
101110
while (retval&mask) retval = c2_read_addr();
@@ -173,7 +182,7 @@ unsigned char c2_init_PI (void) {
173182
return 0;
174183
}
175184

176-
unsigned char c2_read_data() {
185+
static unsigned char c2_read_data() {
177186
unsigned char retval;
178187
c2_send_bits(0x0, 1);
179188
c2_send_bits(0x0, 2);
@@ -187,7 +196,7 @@ unsigned char c2_read_data() {
187196
return retval;
188197
}
189198

190-
unsigned char c2_read_addr() {
199+
static unsigned char c2_read_addr() {
191200
unsigned char retval;
192201
c2_send_bits(0x0, 1);
193202
c2_send_bits(0x2, 2);
@@ -204,20 +213,20 @@ void c2_write_addr(unsigned char addr) {
204213
}
205214

206215
void setup() {
207-
Serial.begin(38400);
208-
pinMode(C2CK, OUTPUT);
209-
pinMode(C2D, OUTPUT);
216+
Serial.begin(1000000);
217+
218+
DDRE |= (1<<C2D_PIN);
219+
DDRE |= (1<<C2CK_PIN);
220+
C2CK_PORT |= (1<<C2CK_PIN);
221+
210222
digitalWrite(LED, LOW);
211-
digitalWrite(C2CK, HIGH);
212-
delay(300);
213223
}
214224

215225
unsigned int i;
216226
unsigned char retval;
217-
unsigned char flash_array[34],flash_array2[34],flash_array3[34];
218227
unsigned char rx_message[250],rx_message_ptr;
219228
unsigned char rx,main_state,bytes_to_receive,rx_state;
220-
unsigned char flash_buffer[130];
229+
unsigned char flash_buffer[250];
221230
unsigned long addr;
222231

223232
unsigned char rx_state_machine (unsigned char state, unsigned char rx_char) {
@@ -241,11 +250,15 @@ unsigned char rx_state_machine (unsigned char state, unsigned char rx_char) {
241250
}
242251

243252
void loop() {
253+
244254
if (Serial.available()) {
245255
rx = Serial.read();
246256
rx_state = rx_state_machine(rx_state, rx);
247257
if (rx_state == 3) {
248258
switch (rx_message[0]) {
259+
case 0x0:
260+
Serial.write(0x80);
261+
break;
249262
case 0x01:
250263
c2_init_PI();
251264
Serial.write(0x81);

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pyserial

0 commit comments

Comments
 (0)