]> git.cryptolib.org Git - labortage2013badge.git/blobdiff - firmware/main.c
a bit smaller
[labortage2013badge.git] / firmware / main.c
index 45026555b0d114f4ee6fa650345ab83b56b08759..d5f555d9b5b9d407c2823f4eb434e883a131e564 100644 (file)
@@ -159,7 +159,7 @@ static char token[10];
 
 #define UNI_BUFFER_SIZE 36
 
-static union {
+static union __attribute__((packed)) {
        uint8_t  w8[UNI_BUFFER_SIZE];
        uint16_t w16[UNI_BUFFER_SIZE/2];
        uint32_t w32[UNI_BUFFER_SIZE/4];
@@ -187,11 +187,13 @@ static uchar key_state = STATE_WAIT;
 volatile static uchar LED_state = 0xff; // received from PC
 /* ------------------------------------------------------------------------- */
 
+static
 void memory_clean(void) {
     memset(secret, 0, 32);
     secret_length_b = 0;
 }
 
+static
 uint8_t secret_set(void){
     uint8_t r;
     union {
@@ -222,6 +224,7 @@ uint8_t secret_set(void){
     return 0;
 }
 
+static
 void token_generate(void) {
     percnt_inc(0);
     eeprom_busy_wait();
@@ -231,6 +234,7 @@ void token_generate(void) {
     memory_clean();
 }
 
+static
 void counter_reset(void) {
     uint8_t reset_counter;
     eeprom_busy_wait();
@@ -240,6 +244,7 @@ void counter_reset(void) {
     eeprom_write_byte(&reset_counter_ee, reset_counter + 1);
 }
 
+static
 void counter_init(void) {
     eeprom_busy_wait();
     if (eeprom_read_byte(&reset_counter_ee) == 0) {
@@ -248,6 +253,7 @@ void counter_init(void) {
     percnt_init(0);
 }
 
+static
 void buildReport(uchar send_key) {
     keyboard_report.modifier = 0;
 
@@ -270,26 +276,26 @@ void buildReport(uchar send_key) {
     }
 }
 
-uint8_t read_button(void){
-       uint8_t t,v=0;
-       t = DDRB;
-       DDRB &= ~(1<<BUTTON_PIN);
-       PORTB |= 1<<BUTTON_PIN;
-       PORTB &= ~(1<<BUTTON_PIN);
-       v |= PINB;
-       DDRB |= t&(1<<BUTTON_PIN);
-       PORTB &= ~(t&(1<<BUTTON_PIN));
-       v >>= BUTTON_PIN;
-       v &= 1;
-       v ^= 1;
-       return v;
+static
+int8_t button_get_debounced(volatile uint8_t debounce_count) {
+    uint8_t v;
+    v = PINB & _BV(BUTTON_PIN);
+    while (debounce_count-- && v == (PINB & _BV(BUTTON_PIN))) {
+        ;
+    }
+    if (debounce_count) {
+        return -1;
+    }
+    return v ? 0 : 1;
 }
 
+static
 void init_temperature_sensor(void){
        ADMUX = 0x8F;
        ADCSRA = 0x87;
 }
 
+static
 uint16_t read_temperture_sensor(void){
        ADCSRA |= 0x40;
        while(ADCSRA & 0x40)
@@ -362,7 +368,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
             return 1;
        case CUSTOM_RQ_GET_TOKEN:
            token_generate();
-           usbMsgPtr = token;
+           usbMsgPtr = (usbMsgPtr_t)token;
            return strlen(token);
 
        case CUSTOM_RQ_PRESS_BUTTON:
@@ -399,7 +405,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
                        soft_reset((uint8_t)(rq->wValue.word));
                        break;
                case CUSTOM_RQ_READ_BUTTON:
-                       uni_buffer.w8[0] = read_button();
+                       uni_buffer.w8[0] = button_get_debounced(25);
                        usbMsgPtr = uni_buffer.w8;
                        return 1;
                case CUSTOM_RQ_READ_TMPSENS:
@@ -524,12 +530,10 @@ void usbEventResetReady(void)
 
 /* ------------------------------------------------------------------------- */
 
-char key_seq[] = "Hello World";
-
 int main(void)
 {
-       uchar  i;
        size_t idx = 0;
+       int8_t i = 0, last_stable_button_state = 0;
 
     wdt_enable(WDTO_1S);
     /* Even if you don't use the watchdog, turn it off here. On newer devices,
@@ -540,17 +544,16 @@ int main(void)
      * additional hardware initialization.
      */
 
+    DDRB &= ~_BV(BUTTON_PIN); /* make button pin input */
+    PORTB |= _BV(BUTTON_PIN); /* turn on pull-up resistor */
     init_temperature_sensor();
     usbInit();
     usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
-    i = 0;
     while(--i){             /* fake USB disconnect for ~512 ms */
         wdt_reset();
         _delay_ms(2);
     }
     usbDeviceConnect();
-    LED_PORT_DDR |= _BV(R_BIT) | _BV(G_BIT) | _BV(B_BIT);   /* make the LED bit an output */
-
        
     sei();
 
@@ -558,16 +561,24 @@ int main(void)
         wdt_reset();
         usbPoll();
 
+        i = button_get_debounced(25);
+        if (i != -1) {
+            if (last_stable_button_state == 0 && i == 1) {
+                key_state = STATE_SEND_KEY;
+            }
+            last_stable_button_state = i;
+        }
+
         if(usbInterruptIsReady() && key_state != STATE_WAIT){
             switch(key_state) {
             case STATE_SEND_KEY:
-                buildReport(key_seq[idx]);
+                buildReport(token[idx]);
                 key_state = STATE_RELEASE_KEY; // release next
                 break;
             case STATE_RELEASE_KEY:
                 buildReport(0);
                 ++idx;
-                if (key_seq[idx] == '\0') {
+                if (token[idx] == '\0') {
                     idx = 0;
                     key_state = STATE_WAIT;
                 } else {