├── README.md └── xyz_dv_eprom.ino /README.md: -------------------------------------------------------------------------------- 1 | Da Vinci 3D Printer Filament EEPROM Reset Arduino Sketch 2 | ============================== 3 | 4 | [http://voltivo.com/forum/davinci](More info here) 5 | 6 | -------------------------------------------------------------------------------- /xyz_dv_eprom.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Da Vinci EEPROM update Copyright (C) 2014 by Oliver Fueckert 4 | Increment Serial code - contributed by Matt 5 | UNI/O Library Copyright (C) 2011 by Stephen Early 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | "Software"), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25 | 26 | /************************************************************ 27 | 28 | Pinout looking at the pads on the EEPROM board 29 | 30 | -------------------\ 31 | | \ 32 | | GND SCIO +5V \ 33 | | | 34 | ---------------------- 35 | 36 | *************************************************************/ 37 | #ifndef _NANODEUNIO_LIB_H 38 | #define _NANODEUNIO_LIB_H 39 | 40 | #if ARDUINO >= 100 41 | #include // Arduino 1.0 42 | #else 43 | #include // Arduino 0022 44 | #endif 45 | 46 | #define NANODE_MAC_DEVICE 0xa0 47 | #define NANODE_MAC_ADDRESS 0xfa 48 | 49 | #define CODE 0x00 //1 Byte 50 | #define MATERIAL 0x01 //1 Byte 51 | #define COLOR 0x02 //2 Bytes 52 | #define DATE 0x05 //4 Bytes 53 | #define TOTALLEN 0x08 //4 Bytes 54 | #define NEWLEN 0x0C //4 Bytes 55 | #define HEADTEMP 0x10 //2 Bytes 56 | #define BEDTEMP 0x12 //2Bytes 57 | #define MLOC 0x14 //2 Bytes 58 | #define DLOC 0x16 //2 Bytes 59 | #define SN 0x18 //12 Bytes 60 | #define CRC 0x24 //2 Bytes 61 | #define LEN2 0x34 //4 Bytes 62 | 63 | void IncrementSerial(unsigned char * cArray, long lAddress, long lSize) 64 | { 65 | unsigned char szTempBuffer[20] = {0}; 66 | memcpy(szTempBuffer,&cArray[lAddress],lSize); 67 | long lSerial = atol((char *)szTempBuffer); 68 | lSerial++; 69 | sprintf((char *)szTempBuffer,"%04d",lSerial); 70 | memcpy(&cArray[lAddress],szTempBuffer,lSize); 71 | } 72 | 73 | class NanodeUNIO { 74 | private: 75 | byte addr; 76 | public: 77 | NanodeUNIO(byte address); 78 | 79 | boolean read(byte *buffer,word address,word length); 80 | boolean start_write(const byte *buffer,word address,word length); 81 | boolean enable_write(void); 82 | boolean disable_write(void); 83 | boolean read_status(byte *status); 84 | boolean write_status(byte status); 85 | boolean await_write_complete(void); 86 | boolean simple_write(const byte *buffer,word address,word length); 87 | }; 88 | 89 | #endif /* _NANODEUNIO_LIB_H */ 90 | 91 | #define UNIO_STARTHEADER 0x55 92 | #define UNIO_READ 0x03 93 | #define UNIO_CRRD 0x06 94 | #define UNIO_WRITE 0x6c 95 | #define UNIO_WREN 0x96 96 | #define UNIO_WRDI 0x91 97 | #define UNIO_RDSR 0x05 98 | #define UNIO_WRSR 0x6e 99 | #define UNIO_ERAL 0x6d 100 | #define UNIO_SETAL 0x67 101 | 102 | #define UNIO_TSTBY 600 103 | #define UNIO_TSS 10 104 | #define UNIO_THDR 5 105 | #define UNIO_QUARTER_BIT 10 106 | #define UNIO_FUDGE_FACTOR 5 107 | 108 | #if defined(__AVR__) 109 | #define UNIO_OUTPUT() do { DDRD |= 0x80; } while (0) 110 | #define UNIO_INPUT() do { DDRD &= 0x7f; } while (0) 111 | #else 112 | #define UNIO_PIN 10 113 | #define UNIO_OUTPUT() pinMode(UNIO_PIN, OUTPUT) 114 | #define UNIO_INPUT() pinMode(UNIO_PIN, INPUT); 115 | 116 | void sei() { 117 | enableInterrupts(); 118 | } 119 | void cli() { 120 | disableInterrupts(); 121 | } 122 | #endif 123 | 124 | static void set_bus(boolean state) { 125 | #if defined(__AVR__) 126 | PORTD=(PORTD&0x7f)|(!!state)<<7; 127 | #else 128 | digitalWrite(UNIO_PIN, state); 129 | #endif 130 | } 131 | 132 | static boolean read_bus(void) { 133 | #if defined(__AVR__) 134 | return !!(PIND&0x80); 135 | #else 136 | return digitalRead(UNIO_PIN); 137 | #endif 138 | } 139 | static void unio_inter_command_gap(void) { 140 | set_bus(1); 141 | delayMicroseconds(UNIO_TSS+UNIO_FUDGE_FACTOR); 142 | } 143 | 144 | static void unio_standby_pulse(void) { 145 | set_bus(0); 146 | UNIO_OUTPUT(); 147 | delayMicroseconds(UNIO_TSS+UNIO_FUDGE_FACTOR); 148 | set_bus(1); 149 | delayMicroseconds(UNIO_TSTBY+UNIO_FUDGE_FACTOR); 150 | } 151 | 152 | static volatile boolean rwbit(boolean w) { 153 | boolean a,b; 154 | set_bus(!w); 155 | delayMicroseconds(UNIO_QUARTER_BIT); 156 | a=read_bus(); 157 | delayMicroseconds(UNIO_QUARTER_BIT); 158 | set_bus(w); 159 | delayMicroseconds(UNIO_QUARTER_BIT); 160 | b=read_bus(); 161 | delayMicroseconds(UNIO_QUARTER_BIT); 162 | return b&&!a; 163 | } 164 | 165 | static boolean read_bit(void) { 166 | boolean b; 167 | UNIO_INPUT(); 168 | b=rwbit(1); 169 | UNIO_OUTPUT(); 170 | return b; 171 | } 172 | 173 | static boolean send_byte(byte b, boolean mak) { 174 | for (int i=0; i<8; i++) { 175 | rwbit(b&0x80); 176 | b<<=1; 177 | } 178 | rwbit(mak); 179 | return read_bit(); 180 | } 181 | 182 | static boolean read_byte(byte *b, boolean mak) { 183 | byte data=0; 184 | UNIO_INPUT(); 185 | for (int i=0; i<8; i++) { 186 | data = (data << 1) | rwbit(1); 187 | } 188 | UNIO_OUTPUT(); 189 | *b=data; 190 | rwbit(mak); 191 | return read_bit(); 192 | } 193 | 194 | static boolean unio_send(const byte *data,word length,boolean end) { 195 | for (word i=0; i>8); 225 | cmd[3]=(byte)(address&0xff); 226 | unio_standby_pulse(); 227 | cli(); 228 | unio_start_header(); 229 | if (!unio_send(cmd,4,false)) fail(); 230 | if (!unio_read(buffer,length)) fail(); 231 | sei(); 232 | return true; 233 | } 234 | 235 | boolean NanodeUNIO::start_write(const byte *buffer,word address,word length) { 236 | byte cmd[4]; 237 | if (((address&0x0f)+length)>16) return false; // would cross page boundary 238 | cmd[0]=addr; 239 | cmd[1]=UNIO_WRITE; 240 | cmd[2]=(byte)(address>>8); 241 | cmd[3]=(byte)(address&0xff); 242 | unio_standby_pulse(); 243 | cli(); 244 | unio_start_header(); 245 | if (!unio_send(cmd,4,false)) fail(); 246 | if (!unio_send(buffer,length,true)) fail(); 247 | sei(); 248 | return true; 249 | } 250 | 251 | boolean NanodeUNIO::enable_write(void) { 252 | byte cmd[2]; 253 | cmd[0]=addr; 254 | cmd[1]=UNIO_WREN; 255 | unio_standby_pulse(); 256 | cli(); 257 | unio_start_header(); 258 | if (!unio_send(cmd,2,true)) fail(); 259 | sei(); 260 | return true; 261 | } 262 | 263 | boolean NanodeUNIO::disable_write(void) { 264 | byte cmd[2]; 265 | cmd[0]=addr; 266 | cmd[1]=UNIO_WRDI; 267 | unio_standby_pulse(); 268 | cli(); 269 | unio_start_header(); 270 | if (!unio_send(cmd,2,true)) fail(); 271 | sei(); 272 | return true; 273 | } 274 | 275 | boolean NanodeUNIO::read_status(byte *status) { 276 | byte cmd[2]; 277 | cmd[0]=addr; 278 | cmd[1]=UNIO_RDSR; 279 | unio_standby_pulse(); 280 | cli(); 281 | unio_start_header(); 282 | if (!unio_send(cmd,2,false)) fail(); 283 | if (!unio_read(status,1)) fail(); 284 | sei(); 285 | return true; 286 | } 287 | 288 | boolean NanodeUNIO::write_status(byte status) { 289 | byte cmd[3]; 290 | cmd[0]=addr; 291 | cmd[1]=UNIO_WRSR; 292 | cmd[2]=status; 293 | unio_standby_pulse(); 294 | cli(); 295 | unio_start_header(); 296 | if (!unio_send(cmd,3,true)) fail(); 297 | sei(); 298 | return true; 299 | } 300 | 301 | boolean NanodeUNIO::await_write_complete(void) { 302 | byte cmd[2]; 303 | byte status; 304 | cmd[0]=addr; 305 | cmd[1]=UNIO_RDSR; 306 | unio_standby_pulse(); 307 | do { 308 | unio_inter_command_gap(); 309 | cli(); 310 | unio_start_header(); 311 | if (!unio_send(cmd,2,false)) fail(); 312 | if (!unio_read(&status,1)) fail(); 313 | sei(); 314 | } while (status&0x01); 315 | return true; 316 | } 317 | 318 | boolean NanodeUNIO::simple_write(const byte *buffer,word address,word length) { 319 | word wlen; 320 | while (length>0) { 321 | wlen=length; 322 | if (((address&0x0f)+wlen)>16) { 323 | wlen=16-(address&0x0f); 324 | } 325 | if (!enable_write()) return false; 326 | if (!start_write(buffer,address,wlen)) return false; 327 | if (!await_write_complete()) return false; 328 | buffer+=wlen; 329 | address+=wlen; 330 | length-=wlen; 331 | } 332 | return true; 333 | } 334 | 335 | static void status(boolean r) 336 | { 337 | if (r) Serial.println("(success)"); 338 | else Serial.println("(failure)"); 339 | } 340 | 341 | static void dump_eeprom(word address,word length) 342 | { 343 | byte buf[128]; 344 | char lbuf[80]; 345 | char *x; 346 | int i,j; 347 | 348 | NanodeUNIO unio(NANODE_MAC_DEVICE); 349 | 350 | memset(buf,0,128); 351 | status(unio.read(buf,address,length)); 352 | 353 | for (i=0; i<128; i+=16) { 354 | x=lbuf; 355 | sprintf(x,"%02X: ",i); 356 | x+=4; 357 | for (j=0; j<16; j++) { 358 | sprintf(x,"%02X",buf[i+j]); 359 | x+=2; 360 | } 361 | *x=32; 362 | x+=1; 363 | for (j=0; j<16; j++) { 364 | if (buf[i+j]>=32 && buf[i+j]<127) *x=buf[i+j]; 365 | else *x=46; 366 | x++; 367 | } 368 | *x=0; 369 | Serial.println(lbuf); 370 | } 371 | } 372 | 373 | int led = LED_BUILTIN; 374 | 375 | /* 376 | These are the values to be written to the EEPROM 377 | Make sure only one is uncommented. 378 | By default its set for the starter ABS cartdridge with 120m of filament 379 | 380 | Verified with firmware 1.1.I 381 | */ 382 | 383 | // Value to write to the EEPROM for remaining filament lenght 384 | // Default Starter Cartdridge is 120m 385 | char x[] = {0xc0,0xd4,0x01,0x00}; //120m 386 | //char x[] = {0x80,0xa9,0x03,0x00}; //240m 387 | //char x[] = {0x80,0x1a,0x06,0x00}; //400m 388 | 389 | // extruder temp, default is 210 C for ABS 390 | char et[] = {0xd2,0x00}; // 210 C 391 | //char et[] = {0xe6,0x00}; // 230 C 392 | //char et[] = {0xf5,0x00}; // 245 C 393 | //char et[] = {0xfa,0x00}; // 250 C 394 | 395 | // bed temp 90 degrees, default ABS 396 | char bt[] = {0x5a,0x00}; //90C 397 | //char bt[] = {0x32,0x00}; //50C 398 | //char bt[] = {0x28,0x00}; //40C 399 | 400 | //Materials 401 | 402 | //char mt[] = {0x41}; //ABS 403 | //char mt[] = {0x50}; //PLA 404 | char mt[] = {0x46}; //Flex 405 | 406 | 407 | byte sr; 408 | NanodeUNIO unio(NANODE_MAC_DEVICE); 409 | 410 | void setup() { 411 | pinMode(led, OUTPUT); 412 | Serial.begin(115200); 413 | while(!Serial); 414 | delay(250); 415 | } 416 | 417 | void loop() { 418 | 419 | do { 420 | digitalWrite(led, LOW); 421 | Serial.println("Testing connection to Da Vinci EEPROM CHIP\n"); 422 | delay(100); 423 | digitalWrite(led, HIGH); 424 | } while(!unio.read_status(&sr)); 425 | 426 | Serial.println("Da Vinci EEPROM found..."); 427 | Serial.println("Reading the Davinci EEPROM Contents..."); 428 | dump_eeprom(0,128); 429 | //dump_eeprom(116,4); 430 | 431 | //Read the serial number - added by Matt 432 | byte buf[20]; 433 | memset(buf,0,20); 434 | status(unio.read(buf,SN,12)); 435 | //Increment the serial number 436 | IncrementSerial(&buf[0], 0, 12); 437 | 438 | Serial.println("Press enter to update EEPROM..."); 439 | while(!Serial.available()); 440 | while(Serial.available()) Serial.read(); 441 | 442 | Serial.println("Updating EEPROM..."); 443 | status(unio.simple_write((const byte *)x,TOTALLEN,4)); 444 | status(unio.simple_write((const byte *)x,NEWLEN,4)); 445 | status(unio.simple_write((const byte *)et,HEADTEMP,2)); // extruder temp 446 | status(unio.simple_write((const byte *)bt,BEDTEMP,2)); // bed temp 447 | status(unio.simple_write((const byte *)mt,MATERIAL,1)); // Material 448 | 449 | //Write the serial number 450 | status(unio.simple_write((const byte *)buf,SN,12)); //Serial Number 451 | status(unio.simple_write((const byte *)x,LEN2,4)); 452 | // same block from offset 0 is offset 64 bytes 453 | status(unio.simple_write((const byte *)x,64 + TOTALLEN,4)); 454 | status(unio.simple_write((const byte *)x,64 + NEWLEN,4)); 455 | status(unio.simple_write((const byte *)et,64 + HEADTEMP,2)); // extruder temp 456 | status(unio.simple_write((const byte *)bt,64 + BEDTEMP,2)); // bed temp 457 | status(unio.simple_write((const byte *)mt,64 + MATERIAL,1)); // Material 458 | //Write the serial number 459 | status(unio.simple_write((const byte *)buf,64 + SN,12)); //Serial Number 460 | status(unio.simple_write((const byte *)x,64 + LEN2,4)); 461 | 462 | Serial.println("Dumping Content after modification..."); 463 | dump_eeprom(0,128); 464 | 465 | digitalWrite(led, HIGH); // turn the LED on 466 | delay(10000); // wait for ten seconds 467 | } 468 | 469 | --------------------------------------------------------------------------------