/* Project: DS1992 memory iButton dumper Author: Florian Jung (flo@windfisch.org) Copyright: (c) 2015 by Florian Jung License: GNU GPL v3 (see LICENSE) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . This project is based on the code for the AVR ATtiny USB Tutorial at http://codeandlife.com/ by Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi, which is in turn based on the V-USB example code by Christian Starkjohann (Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH) */ #include #include #include #include #include #include #include "usbdrv/usbdrv.h" #include "1wire.h" #define LED_BLUE (1<<5) #define LED_RED (1<<4) #define LED_GREEN (1<<3) #define FUNC_READ 0x42 #define FUNC_WRITE 0x21 #define FUNC_START_BOOTLOADER 30 #define FUNC_GET_TYPE 0xFE volatile int got_data = 0; // set to 1, if we get data to write from the PC volatile int recvd_data_len = 0; void jump_to_bootloader(void) { cli(); wdt_enable(WDTO_15MS); while (1); } static uchar replyBuffer[130]="Hello world initial"; static uchar buf[33]; usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *) data; int len = 1; switch (rq->bRequest) { case FUNC_GET_TYPE: replyBuffer[0]=10; len = 1; break; case FUNC_START_BOOTLOADER: jump_to_bootloader(); len = 0; break; case FUNC_READ: recvd_data_len = 0; return USB_NO_MSG; case FUNC_WRITE: PORTC ^= LED_RED; //strcpy(replyBuffer, "Hello world"); //len = strlen(replyBuffer)+1; len = 130; break; } usbMsgPtr = replyBuffer; return len; } volatile int count = 5; uchar usbFunctionWrite(uint8_t * data, uchar len) { memcpy(replyBuffer+recvd_data_len,data,len); recvd_data_len+=len; if (recvd_data_len >= 33) got_data = 1; //replyBuffer[len]='\0'; return len; } void usb_disconnect() { USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT); usbDeviceDisconnect(); } void usb_reconnect() { cli(); usbDeviceDisconnect(); // enforce re-enumeration for (int i = 0; i < 250; i++) { // wait 500 ms wdt_reset(); // keep the watchdog happy _delay_ms(10); } usbDeviceConnect(); USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); sei(); } int main(void) { uint32_t c = 0; DDRC = 0x38; // LEDs as output PORTC |= LED_BLUE | LED_RED | LED_GREEN; DDRD &= ~0xF3; // connector ports as input DDRB &= ~0x3C; PORTD &= ~0xF3; // disable pullups for unused ports PORTB &= ~0x0C; PORTB |= 0x30; // enable pullups for PB4 and 5 replyBuffer[129] = 0; cli(); wdt_enable(WDTO_1S); // enable 1s watchdog timer usbInit(); usbDeviceDisconnect(); // enforce re-enumeration for (int i = 0; i < 250; i++) { // wait 500 ms wdt_reset(); // keep the watchdog happy _delay_ms(10); } usbDeviceConnect(); sei(); // Enable interrupts after re-enumeration uint8_t error = 0; while (1) { wdt_reset(); // keep the watchdog happy usbPoll(); if (++c % (error ? 12000 : got_data ? 1000 : 3000) == 0) { PORTC^=LED_BLUE; PORTC |= LED_RED | LED_GREEN; } if (c % 12000 == 0) { if (!got_data) // we want to read the token { uint8_t result = w1_reset(); if (result == 0) // device detected { PORTC &= ~LED_GREEN; ds1992_read(0, replyBuffer, 128); } else if (result == 1) // no presence pulse == no device detected PORTC &= ~LED_RED; else // short circuit detected PORTC &= ~(LED_RED | LED_GREEN); } else // we want to WRITE the token (*shudder*!) { uint8_t result = w1_reset(); if (result == 0) // device detected { PORTC &= ~LED_GREEN; cli(); memcpy(buf, replyBuffer, 33); got_data = 0; sei(); uint16_t writepos = ((uint16_t)buf[32]) * 32; ds1992_scratch_write(writepos, buf, 32); result = w1_reset(); if (result != 0) { replyBuffer[0] = 0x01; error = 1; goto write_failed; } uint8_t es_reg; result = ds1992_scratch_verify(writepos, buf, 32, &es_reg); if (result != 0) { replyBuffer[0] = 0x02; error = 1; goto write_failed; } replyBuffer[0] = 0xFF; // success error = 0; write_failed: 1; } else if (result == 1) // no presence pulse == no device detected PORTC &= ~LED_RED; else // short circuit detected PORTC &= ~(LED_RED | LED_GREEN); } } } jump_to_bootloader(); return 0; }