c2write.ino
· 7.2 KiB · Arduino
Исходник
/**
Based on https://github.com/jaromir-sukuba/efm8prog/
Use his SW to program EFM8 using arduino.
This needs some work though (but it works)
**/
#define C2D 2
#define C2CK 3
#define LED 13
#define INBUSY 0x02
#define OUTREADY 0x01
void c2_send_bits (unsigned char data, unsigned char len);
void c2_pulse_clk (void);
unsigned char c2_read_bits (unsigned char len);
void c2_rst (void);
void c2_write_addr (unsigned char addr);
unsigned char c2_read_addr (void);
unsigned char c2_read_data (void);
void c2_write_data (unsigned char addr);
unsigned char c2_init_PI (void);
unsigned char c2_read_flash_block (unsigned int addr, unsigned char * data, unsigned char len);
unsigned char c2_poll_bit_low (unsigned char mask);
unsigned char c2_poll_bit_high (unsigned char mask);
unsigned char c2_write_flash_block (unsigned int addr, unsigned char * data, unsigned char len);
unsigned char c2_erase_device (void);
void c2_rst() {
digitalWrite(C2CK, LOW);
delayMicroseconds(100);
digitalWrite(C2CK, HIGH);
delayMicroseconds(100);
}
void c2_pulse_clk() {
pinMode(C2CK, OUTPUT);
digitalWrite(C2CK, LOW);
digitalWrite(C2CK, LOW);
digitalWrite(C2CK, LOW);
digitalWrite(C2CK, LOW);
digitalWrite(C2CK, HIGH);
}
unsigned char c2_read_bits (unsigned char len) {
unsigned char i, data, mask;
mask = 0x01 << (len-1);
data = 0;
pinMode(C2D, INPUT);
for (i=0;i<len;i++) {
c2_pulse_clk();
data = data >> 1;
if (digitalRead(C2D) == HIGH) {
data = data | mask;
}
}
pinMode(C2D, OUTPUT);
return data;
}
void c2_send_bits (unsigned char data, unsigned char len) {
unsigned char i;
pinMode(C2D, OUTPUT);
for (i=0;i<len;i++) {
if (data&0x01) {
digitalWrite(C2D, HIGH);
} else {
digitalWrite(C2D, LOW);
}
c2_pulse_clk();
data = data >> 1;
}
}
void c2_write_data (unsigned char data) {
unsigned char retval;
c2_send_bits(0x0, 1);
c2_send_bits(0x1, 2);
c2_send_bits(0x0, 2);
c2_send_bits(data, 8);
retval = 0;
while (retval == 0) {
retval = c2_read_bits(1);
}
c2_send_bits(0x0, 1);
}
unsigned char c2_poll_bit_high (unsigned char mask) {
unsigned char retval;
retval = c2_read_addr();
while ((retval&mask)==0) retval = c2_read_addr();
}
unsigned char c2_poll_bit_low (unsigned char mask) {
unsigned char retval;
retval = c2_read_addr();
while (retval&mask) retval = c2_read_addr();
}
unsigned char c2_read_flash_block (unsigned int addr, unsigned char * data, unsigned char len) {
unsigned char retval,i;
c2_write_addr(0xB4);
c2_write_data(0x06);
c2_poll_bit_low(INBUSY);
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
c2_write_data(addr>>8);
c2_poll_bit_low(INBUSY);
c2_write_data(addr&0xFF);
c2_poll_bit_low(INBUSY);
c2_write_data(len);
c2_poll_bit_low(INBUSY);
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
for (i=0;i<len;i++) {
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
data[i] = retval;
}
return i;
}
unsigned char c2_write_flash_block (unsigned int addr, unsigned char * data, unsigned char len) {
unsigned char retval,i;
c2_write_addr(0xB4);
c2_write_data(0x07);
c2_poll_bit_low(INBUSY);
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
c2_write_data(addr>>8);
c2_poll_bit_low(INBUSY);
c2_write_data(addr&0xFF);
c2_poll_bit_low(INBUSY);
c2_write_data(len);
c2_poll_bit_low(INBUSY);
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
for (i=0;i<len;i++) {
c2_write_data(data[i] );
c2_poll_bit_low(INBUSY);
}
c2_poll_bit_high(OUTREADY);
}
unsigned char c2_erase_device (void) {
unsigned char retval;
c2_write_addr(0xB4);
c2_write_data(0x03);
c2_poll_bit_low(INBUSY);
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
c2_write_data(0xDE);
c2_poll_bit_low(INBUSY);
c2_write_data(0xAD);
c2_poll_bit_low(INBUSY);
c2_write_data(0xA5);
c2_poll_bit_low(INBUSY);
c2_poll_bit_high(OUTREADY);
retval = c2_read_data();
}
unsigned char c2_init_PI (void) {
c2_rst();
c2_write_addr(0x02);
c2_write_data(0x02);
c2_write_data(0x04);
c2_write_data(0x01);
delay(20);
return 0;
}
unsigned char c2_read_data() {
unsigned char retval;
c2_send_bits(0x0, 1);
c2_send_bits(0x0, 2);
c2_send_bits(0x0, 2);
retval = 0;
while (retval == 0) {
retval = c2_read_bits(1);
}
retval = c2_read_bits(8);
c2_send_bits(0x0, 1);
return retval;
}
unsigned char c2_read_addr() {
unsigned char retval;
c2_send_bits(0x0, 1);
c2_send_bits(0x2, 2);
retval = c2_read_bits(8);
c2_send_bits(0x0, 1);
return retval;
}
void c2_write_addr(unsigned char addr) {
c2_send_bits(0x0,1);
c2_send_bits(0x3,2);
c2_send_bits(addr,8);
c2_send_bits(0x0,1);
}
void setup() {
Serial.begin(38400);
pinMode(C2CK, OUTPUT);
pinMode(C2D, OUTPUT);
digitalWrite(LED, LOW);
digitalWrite(C2CK, HIGH);
delay(300);
}
unsigned int i;
unsigned char retval;
unsigned char flash_array[34],flash_array2[34],flash_array3[34];
unsigned char rx_message[250],rx_message_ptr;
unsigned char rx,main_state,bytes_to_receive,rx_state;
unsigned char flash_buffer[130];
unsigned long addr;
unsigned char rx_state_machine (unsigned char state, unsigned char rx_char) {
if (state==0) {
rx_message_ptr = 0;
rx_message[rx_message_ptr++] = rx_char;
return 1;
}
if (state==1) {
bytes_to_receive = rx_char;
rx_message[rx_message_ptr++] = rx_char;
if (bytes_to_receive==0) return 3;
return 2;
}
if (state==2) {
rx_message[rx_message_ptr++] = rx_char;
bytes_to_receive--;
if (bytes_to_receive==0) return 3;
}
return state;
}
void loop() {
if (Serial.available()) {
rx = Serial.read();
rx_state = rx_state_machine(rx_state, rx);
if (rx_state == 3) {
switch (rx_message[0]) {
case 0x01:
c2_init_PI();
Serial.write(0x81);
digitalWrite(LED, HIGH);
rx_state = 0;
break;
case 0x02:
c2_rst();
Serial.write(0x82);
digitalWrite(LED, LOW);
rx_state = 0;
break;
case 0x03:
addr = (((unsigned long)(rx_message[3]))<<16) + (((unsigned long)(rx_message[4]))<<8) + (((unsigned long)(rx_message[5]))<<0);
for (i=0;i<rx_message[2];i++) {
flash_buffer[i] = rx_message[i+6];
}
c2_write_flash_block(addr,flash_buffer,rx_message[2]);
Serial.write(0x83);
rx_state = 0;
break;
case 0x04:
c2_erase_device();
Serial.write(0x84);
rx_state = 0;
break;
case 0x05:
Serial.write(0x85);
addr = (((unsigned long)(rx_message[3]))<<16) + (((unsigned long)(rx_message[4]))<<8) + (((unsigned long)(rx_message[5]))<<0);
c2_read_flash_block(addr,flash_buffer,rx_message[2]);
for (i=0;i<rx_message[2];i++) {
Serial.write(flash_buffer[i]);
}
rx_state = 0;
break;
case 0x06:
c2_write_addr(rx_message[3]);
c2_write_data(rx_message[4]);
Serial.write(0x86);
rx_state = 0;
break;
case 0x07:
c2_write_addr(rx_message[3]);
Serial.write(c2_read_data());
Serial.write(0x87);
rx_state = 0;
break;
}
}
}
}
| 1 | /** |
| 2 | Based on https://github.com/jaromir-sukuba/efm8prog/ |
| 3 | Use his SW to program EFM8 using arduino. |
| 4 | This needs some work though (but it works) |
| 5 | **/ |
| 6 | #define C2D 2 |
| 7 | #define C2CK 3 |
| 8 | #define LED 13 |
| 9 | |
| 10 | #define INBUSY 0x02 |
| 11 | #define OUTREADY 0x01 |
| 12 | |
| 13 | void c2_send_bits (unsigned char data, unsigned char len); |
| 14 | void c2_pulse_clk (void); |
| 15 | unsigned char c2_read_bits (unsigned char len); |
| 16 | |
| 17 | void c2_rst (void); |
| 18 | void c2_write_addr (unsigned char addr); |
| 19 | unsigned char c2_read_addr (void); |
| 20 | unsigned char c2_read_data (void); |
| 21 | void c2_write_data (unsigned char addr); |
| 22 | |
| 23 | unsigned char c2_init_PI (void); |
| 24 | unsigned char c2_read_flash_block (unsigned int addr, unsigned char * data, unsigned char len); |
| 25 | unsigned char c2_poll_bit_low (unsigned char mask); |
| 26 | unsigned char c2_poll_bit_high (unsigned char mask); |
| 27 | unsigned char c2_write_flash_block (unsigned int addr, unsigned char * data, unsigned char len); |
| 28 | unsigned char c2_erase_device (void); |
| 29 | |
| 30 | |
| 31 | void c2_rst() { |
| 32 | digitalWrite(C2CK, LOW); |
| 33 | delayMicroseconds(100); |
| 34 | digitalWrite(C2CK, HIGH); |
| 35 | delayMicroseconds(100); |
| 36 | } |
| 37 | |
| 38 | void c2_pulse_clk() { |
| 39 | pinMode(C2CK, OUTPUT); |
| 40 | digitalWrite(C2CK, LOW); |
| 41 | digitalWrite(C2CK, LOW); |
| 42 | digitalWrite(C2CK, LOW); |
| 43 | digitalWrite(C2CK, LOW); |
| 44 | digitalWrite(C2CK, HIGH); |
| 45 | } |
| 46 | |
| 47 | unsigned char c2_read_bits (unsigned char len) { |
| 48 | unsigned char i, data, mask; |
| 49 | mask = 0x01 << (len-1); |
| 50 | data = 0; |
| 51 | pinMode(C2D, INPUT); |
| 52 | for (i=0;i<len;i++) { |
| 53 | c2_pulse_clk(); |
| 54 | data = data >> 1; |
| 55 | if (digitalRead(C2D) == HIGH) { |
| 56 | data = data | mask; |
| 57 | } |
| 58 | } |
| 59 | pinMode(C2D, OUTPUT); |
| 60 | |
| 61 | return data; |
| 62 | } |
| 63 | |
| 64 | void c2_send_bits (unsigned char data, unsigned char len) { |
| 65 | unsigned char i; |
| 66 | pinMode(C2D, OUTPUT); |
| 67 | for (i=0;i<len;i++) { |
| 68 | if (data&0x01) { |
| 69 | digitalWrite(C2D, HIGH); |
| 70 | } else { |
| 71 | digitalWrite(C2D, LOW); |
| 72 | } |
| 73 | c2_pulse_clk(); |
| 74 | data = data >> 1; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | void c2_write_data (unsigned char data) { |
| 79 | unsigned char retval; |
| 80 | c2_send_bits(0x0, 1); |
| 81 | c2_send_bits(0x1, 2); |
| 82 | c2_send_bits(0x0, 2); |
| 83 | c2_send_bits(data, 8); |
| 84 | retval = 0; |
| 85 | while (retval == 0) { |
| 86 | retval = c2_read_bits(1); |
| 87 | } |
| 88 | c2_send_bits(0x0, 1); |
| 89 | } |
| 90 | |
| 91 | unsigned char c2_poll_bit_high (unsigned char mask) { |
| 92 | unsigned char retval; |
| 93 | retval = c2_read_addr(); |
| 94 | while ((retval&mask)==0) retval = c2_read_addr(); |
| 95 | } |
| 96 | |
| 97 | unsigned char c2_poll_bit_low (unsigned char mask) { |
| 98 | unsigned char retval; |
| 99 | retval = c2_read_addr(); |
| 100 | while (retval&mask) retval = c2_read_addr(); |
| 101 | } |
| 102 | |
| 103 | unsigned char c2_read_flash_block (unsigned int addr, unsigned char * data, unsigned char len) { |
| 104 | unsigned char retval,i; |
| 105 | c2_write_addr(0xB4); |
| 106 | c2_write_data(0x06); |
| 107 | c2_poll_bit_low(INBUSY); |
| 108 | c2_poll_bit_high(OUTREADY); |
| 109 | retval = c2_read_data(); |
| 110 | c2_write_data(addr>>8); |
| 111 | c2_poll_bit_low(INBUSY); |
| 112 | c2_write_data(addr&0xFF); |
| 113 | c2_poll_bit_low(INBUSY); |
| 114 | c2_write_data(len); |
| 115 | c2_poll_bit_low(INBUSY); |
| 116 | c2_poll_bit_high(OUTREADY); |
| 117 | retval = c2_read_data(); |
| 118 | for (i=0;i<len;i++) { |
| 119 | c2_poll_bit_high(OUTREADY); |
| 120 | retval = c2_read_data(); |
| 121 | data[i] = retval; |
| 122 | } |
| 123 | return i; |
| 124 | } |
| 125 | |
| 126 | unsigned char c2_write_flash_block (unsigned int addr, unsigned char * data, unsigned char len) { |
| 127 | unsigned char retval,i; |
| 128 | c2_write_addr(0xB4); |
| 129 | c2_write_data(0x07); |
| 130 | c2_poll_bit_low(INBUSY); |
| 131 | c2_poll_bit_high(OUTREADY); |
| 132 | retval = c2_read_data(); |
| 133 | c2_write_data(addr>>8); |
| 134 | c2_poll_bit_low(INBUSY); |
| 135 | c2_write_data(addr&0xFF); |
| 136 | c2_poll_bit_low(INBUSY); |
| 137 | c2_write_data(len); |
| 138 | c2_poll_bit_low(INBUSY); |
| 139 | c2_poll_bit_high(OUTREADY); |
| 140 | retval = c2_read_data(); |
| 141 | for (i=0;i<len;i++) { |
| 142 | c2_write_data(data[i] ); |
| 143 | c2_poll_bit_low(INBUSY); |
| 144 | } |
| 145 | c2_poll_bit_high(OUTREADY); |
| 146 | } |
| 147 | |
| 148 | unsigned char c2_erase_device (void) { |
| 149 | unsigned char retval; |
| 150 | c2_write_addr(0xB4); |
| 151 | c2_write_data(0x03); |
| 152 | c2_poll_bit_low(INBUSY); |
| 153 | c2_poll_bit_high(OUTREADY); |
| 154 | retval = c2_read_data(); |
| 155 | c2_write_data(0xDE); |
| 156 | c2_poll_bit_low(INBUSY); |
| 157 | c2_write_data(0xAD); |
| 158 | c2_poll_bit_low(INBUSY); |
| 159 | c2_write_data(0xA5); |
| 160 | c2_poll_bit_low(INBUSY); |
| 161 | c2_poll_bit_high(OUTREADY); |
| 162 | retval = c2_read_data(); |
| 163 | } |
| 164 | |
| 165 | unsigned char c2_init_PI (void) { |
| 166 | c2_rst(); |
| 167 | c2_write_addr(0x02); |
| 168 | c2_write_data(0x02); |
| 169 | c2_write_data(0x04); |
| 170 | c2_write_data(0x01); |
| 171 | delay(20); |
| 172 | return 0; |
| 173 | } |
| 174 | |
| 175 | unsigned char c2_read_data() { |
| 176 | unsigned char retval; |
| 177 | c2_send_bits(0x0, 1); |
| 178 | c2_send_bits(0x0, 2); |
| 179 | c2_send_bits(0x0, 2); |
| 180 | retval = 0; |
| 181 | while (retval == 0) { |
| 182 | retval = c2_read_bits(1); |
| 183 | } |
| 184 | retval = c2_read_bits(8); |
| 185 | c2_send_bits(0x0, 1); |
| 186 | return retval; |
| 187 | } |
| 188 | |
| 189 | unsigned char c2_read_addr() { |
| 190 | unsigned char retval; |
| 191 | c2_send_bits(0x0, 1); |
| 192 | c2_send_bits(0x2, 2); |
| 193 | retval = c2_read_bits(8); |
| 194 | c2_send_bits(0x0, 1); |
| 195 | return retval; |
| 196 | } |
| 197 | |
| 198 | void c2_write_addr(unsigned char addr) { |
| 199 | c2_send_bits(0x0,1); |
| 200 | c2_send_bits(0x3,2); |
| 201 | c2_send_bits(addr,8); |
| 202 | c2_send_bits(0x0,1); |
| 203 | } |
| 204 | |
| 205 | void setup() { |
| 206 | Serial.begin(38400); |
| 207 | pinMode(C2CK, OUTPUT); |
| 208 | pinMode(C2D, OUTPUT); |
| 209 | digitalWrite(LED, LOW); |
| 210 | digitalWrite(C2CK, HIGH); |
| 211 | delay(300); |
| 212 | } |
| 213 | |
| 214 | unsigned int i; |
| 215 | unsigned char retval; |
| 216 | unsigned char flash_array[34],flash_array2[34],flash_array3[34]; |
| 217 | unsigned char rx_message[250],rx_message_ptr; |
| 218 | unsigned char rx,main_state,bytes_to_receive,rx_state; |
| 219 | unsigned char flash_buffer[130]; |
| 220 | unsigned long addr; |
| 221 | |
| 222 | unsigned char rx_state_machine (unsigned char state, unsigned char rx_char) { |
| 223 | if (state==0) { |
| 224 | rx_message_ptr = 0; |
| 225 | rx_message[rx_message_ptr++] = rx_char; |
| 226 | return 1; |
| 227 | } |
| 228 | if (state==1) { |
| 229 | bytes_to_receive = rx_char; |
| 230 | rx_message[rx_message_ptr++] = rx_char; |
| 231 | if (bytes_to_receive==0) return 3; |
| 232 | return 2; |
| 233 | } |
| 234 | if (state==2) { |
| 235 | rx_message[rx_message_ptr++] = rx_char; |
| 236 | bytes_to_receive--; |
| 237 | if (bytes_to_receive==0) return 3; |
| 238 | } |
| 239 | return state; |
| 240 | } |
| 241 | |
| 242 | void loop() { |
| 243 | if (Serial.available()) { |
| 244 | rx = Serial.read(); |
| 245 | rx_state = rx_state_machine(rx_state, rx); |
| 246 | if (rx_state == 3) { |
| 247 | switch (rx_message[0]) { |
| 248 | case 0x01: |
| 249 | c2_init_PI(); |
| 250 | Serial.write(0x81); |
| 251 | digitalWrite(LED, HIGH); |
| 252 | rx_state = 0; |
| 253 | break; |
| 254 | case 0x02: |
| 255 | c2_rst(); |
| 256 | Serial.write(0x82); |
| 257 | digitalWrite(LED, LOW); |
| 258 | rx_state = 0; |
| 259 | break; |
| 260 | case 0x03: |
| 261 | addr = (((unsigned long)(rx_message[3]))<<16) + (((unsigned long)(rx_message[4]))<<8) + (((unsigned long)(rx_message[5]))<<0); |
| 262 | for (i=0;i<rx_message[2];i++) { |
| 263 | flash_buffer[i] = rx_message[i+6]; |
| 264 | } |
| 265 | c2_write_flash_block(addr,flash_buffer,rx_message[2]); |
| 266 | Serial.write(0x83); |
| 267 | rx_state = 0; |
| 268 | break; |
| 269 | case 0x04: |
| 270 | c2_erase_device(); |
| 271 | Serial.write(0x84); |
| 272 | rx_state = 0; |
| 273 | break; |
| 274 | case 0x05: |
| 275 | Serial.write(0x85); |
| 276 | addr = (((unsigned long)(rx_message[3]))<<16) + (((unsigned long)(rx_message[4]))<<8) + (((unsigned long)(rx_message[5]))<<0); |
| 277 | c2_read_flash_block(addr,flash_buffer,rx_message[2]); |
| 278 | for (i=0;i<rx_message[2];i++) { |
| 279 | Serial.write(flash_buffer[i]); |
| 280 | } |
| 281 | rx_state = 0; |
| 282 | break; |
| 283 | case 0x06: |
| 284 | c2_write_addr(rx_message[3]); |
| 285 | c2_write_data(rx_message[4]); |
| 286 | Serial.write(0x86); |
| 287 | rx_state = 0; |
| 288 | break; |
| 289 | case 0x07: |
| 290 | c2_write_addr(rx_message[3]); |
| 291 | Serial.write(c2_read_data()); |
| 292 | Serial.write(0x87); |
| 293 | rx_state = 0; |
| 294 | break; |
| 295 | } |
| 296 | } |
| 297 | } |
| 298 | } |