Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 10th, 2012  |  syntax: C  |  size: 5.99 KB  |  hits: 11  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #define F_CPU 14745600
  2.  
  3. #include <stdio.h>
  4. #include <math.h>
  5.  
  6. #include <avr/io.h>
  7. #include <avr/interrupt.h>
  8. #include <avr/pgmspace.h>
  9. #include <avr/delay.h>
  10. #include <inttypes.h>
  11.  
  12. #include "../libnerdkits/uart.h"
  13.  
  14. unsigned int GetBitValue(unsigned char* array, int position);
  15. void SetBitValue(unsigned char* array, int position, unsigned int value);
  16. void SendZeroAndSyncPulse();
  17. void SendOneAndSyncPulse();
  18.  
  19. #define COMMS_PIN PD3
  20. #define PIN PIND
  21. #define PINDIRECTION DDRD
  22. #define INTPIN PCINT19
  23.  
  24. //defines to make things look a bit like the arduino sketch
  25. #define delay(x) _delay_us(x)
  26. #define pullLow() PINDIRECTION |= (1<<COMMS_PIN)
  27. #define pullHigh() PINDIRECTION &= ~(1<<COMMS_PIN)
  28. #define DELAYSYNC 18
  29. #define ONELENGTH 10
  30. #define BUFSIZE 25
  31.  
  32. unsigned char buf[BUFSIZE];
  33.  
  34. //bits to send to the door
  35. unsigned char dbits[] = {0,0,0,0,0,0xA3,0xE0,0x21,0x13,0};
  36.  
  37. //door open bits that get populated with site code and checksum after reply from read memory
  38. //organised in groups as that's how the lock wants them - even though we mostly index into these
  39. //as if they're linear. Note that the groups vary in length so we have to take that into account later
  40. unsigned char bits[][18] = {
  41.   {0,0,0,0,0,0xA2,0x62, 0x34, 0xBC, 0x38, 0xEF, 0xFC, 0, 0, 0, 0, 0, 0 },
  42.   {0,0,0,0,0,0,0},
  43.   {0,0,0,0,0,0,0},
  44.   {0,0,0,0,0,0,0},  
  45.   {0,0,0,0,0,0,0},
  46.   {0,0,0,0,0,0,0},
  47.   {0,0,0,0,0,0,0},
  48.   {0,0,0,0,0,0,0},
  49.   {0,0,0,0,0,0,0},
  50.   {0,0,0,0,0,0,0},
  51.   {0,0,0,0,0,0x9A, 0xF2, 0x80}
  52. };
  53.  
  54. //make sure PC4 does all the work
  55. void digitialInit() {  
  56.   //make PC3 output pin - just for an led
  57.   DDRC |= (1<<PC3);
  58.  
  59.   //make pc5 an input pin - we'll use this to start the unlock process
  60.   DDRC &= ~(1<<PC5); // set PC5 as input
  61.  
  62.   //turn on the pull up on pc5 so we'll ground it when we're good to go
  63.   PORTC |= (1<<PC5); // turn on internal pull up resistor for PC0
  64.  
  65.   //we're using the external interrupt 1
  66.   EIMSK |= (1<<INT1);
  67.  
  68.   //we need to trigger on the falling edge for external int 1
  69.   EICRA &= ~(1 << ISC10);
  70.   EICRA |= (1 << ISC11);
  71.  
  72.   sei();
  73. }
  74.  
  75. volatile unsigned char bval;
  76.  
  77. //interrupt handler for getting data back from the lock
  78. //we're just going to set a volatile variable to 0 or 1
  79. //for the data stream
  80. ISR(INT1_vect){
  81.   bval = 1;
  82. }
  83.  
  84. int main() {
  85.   //init the i/o pin
  86.   digitialInit();
  87.  
  88.   //init the usart so we can monitor stuff
  89.   uart_init();
  90.   FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  91.   stdin = stdout = &uart_stream;
  92.  
  93.   //wait for PC5 to get pulled down - ground it to skip this
  94.   while((PINC & (1<<PC5)) >> PC5) {}
  95.  
  96.   int i,j ,n;
  97.  
  98.   for(i=0;i<sizeof(buf)*8;++i)
  99.     printf_P(PSTR("%d"), GetBitValue(buf, i));
  100.  
  101.   printf_P(PSTR("\n\nSending data to the lock..\n"));
  102.  
  103.   //bang data to door to read memory for site id
  104.   for(i=0 ; i < 76; ++i) {
  105.     unsigned int bit = GetBitValue(dbits, i);
  106.     if(bit>0) {
  107.       SendOneAndSyncPulse();
  108.     }
  109.     else {
  110.       SendZeroAndSyncPulse();
  111.     }
  112.   }
  113.    
  114.   pullLow();
  115.   delay(DELAYSYNC);
  116.   pullHigh();
  117.  
  118.   printf_P(PSTR("\n\nWaiting for reply...\n"));
  119.   bval = 0;
  120.  
  121.   //wait for the lock to pull us low to say somethings happening
  122.   while((PIN & (1<<COMMS_PIN))) {}
  123.  
  124.   //use the interrupt to get the data back - bval will be changed by the ISR
  125.   PORTC |= (1<<PC3);
  126.   delay(DELAYSYNC);
  127.   for(i = 0; i < 164; ++i) {
  128.     SetBitValue(buf, i, 0);
  129.     pullLow();
  130.     delay(8);
  131.     pullHigh();
  132.     bval = 0;
  133.     delay(194);
  134.     SetBitValue(buf, i, bval);
  135.     printf_P(PSTR("%d"),bval);
  136.   }
  137.  
  138.   printf_P(PSTR("\n\nCalculating reply and checksum\n"));
  139.  
  140.   //add the site code
  141.   for(i = 0; i < 32+3; ++i) {
  142.     SetBitValue(bits, 50+i, GetBitValue(buf, 22+i));
  143.     printf_P(PSTR("%d"), GetBitValue(buf, 22+i));
  144.   }
  145.  
  146.   //compute checksum
  147.   for(i = 0; i < 8; ++i) {
  148.     SetBitValue(bits, 86+i, GetBitValue(bits, 50+i) ^ GetBitValue(bits, 50+9+i) ^ GetBitValue(bits, 50+18+i) ^ GetBitValue(bits, 50+27+i));
  149.   }
  150.  
  151.   SetBitValue(bits, 86, GetBitValue(bits, 86) ^ 1);
  152.   SetBitValue(bits, 87, GetBitValue(bits, 87) ^ 0);
  153.   SetBitValue(bits, 88, GetBitValue(bits, 88) ^ 1);
  154.   SetBitValue(bits, 89, GetBitValue(bits, 89) ^ 1);
  155.   SetBitValue(bits, 90, GetBitValue(bits, 90) ^ 1);
  156.   SetBitValue(bits, 91, GetBitValue(bits, 91) ^ 0);
  157.   SetBitValue(bits, 92, GetBitValue(bits, 92) ^ 1);
  158.   SetBitValue(bits, 93, GetBitValue(bits, 93) ^ 1);
  159.  
  160.   printf_P(PSTR("\n\nSending unlock code\n\n"));
  161.  
  162.   delay(100);
  163.  
  164.   //open the door (hopefully)
  165.   //take the varying group lengths into account
  166.   for(j = 0; j < 11; ++j) {
  167.     if(j == 0) {
  168.       n = 144;
  169.     }
  170.     else if(j == 10) {
  171.       n = 58;
  172.     }
  173.     else {
  174.       n = 49;
  175.     }
  176.  
  177.     //access the bits to send by 2d array and base the length on knowing some
  178.     //stuff about row length because it's static data
  179.     for(i = 0; i < n; ++i) {
  180.       if(GetBitValue(bits[j], i) == 0) {
  181.         SendZeroAndSyncPulse();
  182.       }
  183.       else {
  184.         SendOneAndSyncPulse();
  185.       }
  186.     }
  187.  
  188.     printf_P(PSTR("\n"));
  189.     delay(2500);
  190.   }
  191.  
  192.   printf_P(PSTR("\n\nOpen Sasame?..."));
  193.  
  194.   while(1){};
  195. }
  196.  
  197. //given an array of chars which store bit flags grab a specific bit
  198. unsigned int GetBitValue(unsigned char* array, int position) {
  199.   int idx = position / 8 ;
  200.   unsigned char bits = array[idx];
  201.   int bitIdx = 7 - position % 8;
  202.   unsigned char mask = 1u << bitIdx;
  203.  
  204.   return (bits & mask)>0?1:0 ;
  205. }
  206.  
  207. void SetBitValue(unsigned char* array, int position, unsigned int value) {
  208.   int idx = position / 8 ;
  209.   int bitIdx = 7 - position % 8;
  210.   unsigned char mask = value==0?0:1 << bitIdx;
  211.  
  212.   array[idx] |= mask;
  213. }
  214.  
  215. void SendZeroAndSyncPulse() {
  216.   pullLow();
  217.   delay(DELAYSYNC);
  218.   pullHigh();
  219.   delay(194); //rest of delay before next sync
  220.   printf_P(PSTR("0"));
  221. }
  222.  
  223. void SendOneAndSyncPulse() {
  224.   pullLow();
  225.   delay(DELAYSYNC);
  226.   pullHigh();
  227.   delay(58); //write 1 bit
  228.   pullLow();
  229.   delay(ONELENGTH);
  230.   pullHigh();
  231.   delay(132-ONELENGTH); //rest of delay before next sync
  232.   printf_P(PSTR("1"));
  233. }