/* by flabbergast: * usb_keyboard_service_write() * internal function * take care of sending keypresses until the whole text is sent */ void usb_keyboard_service_write(void) { // check if sending and the last keypress has been sent if(!usb_keyboard_sending_string_GLOBAL || usb_keyboard_send_current_data_GLOBAL) return; // check if enough time elapsed since the last keypress if( (millis10()-usb_keyboard_last_keypress_time) < USB_KEYBOARD_KEYPRESS_DELAY ) return; // take the next char and send it or end the process uint8_t ch = *(usb_keyboard_text_ptr++); if(ch == 0) { usb_keyboard_sending_string_GLOBAL = false; return; } if(ch == '\n' || ch == '\r') { usb_keyboard_press(HID_KEYBOARD_SC_ENTER,0); } else if (ch >= 32 && ch <= 126) { uint8_t key = pgm_read_byte( usb_keyboard_translate_table_US + 2*(ch-32) ); uint8_t mod = pgm_read_byte( usb_keyboard_translate_table_US + 2*(ch-32) + 1); usb_keyboard_press(key,mod); } else { return; } // update time when sent usb_keyboard_last_keypress_time = millis10(); return; }
int main(void) { usb_init(); while(!usb_configured()); CPU_PRESCALE(0); MCUCR |= 0x80; MCUCR |= 0x80; // Init keyboard struct pin input_pins[3] = INPUT_PINS; struct pin output_pins[3] = OUTPUT_PINS; for(int i=0; i<3; i++) { *input_pins[i].ddr = *input_pins[i].ddr & ~input_pins[i].bits; *input_pins[i].port = *input_pins[i].port | input_pins[i].bits; *output_pins[i].ddr = *output_pins[i].ddr | output_pins[i].bits; *output_pins[i].port = *output_pins[i].port & ~output_pins[i].bits; } sei(); // Start looping for(;;) { // usb_keyboard_press(KEY_A+name[i], 0); bool test = false; for(uint8_t r = 0, k = 0; r < NUMBER_OF_ROWS; r++) { ROW_PORT = (ROW_PORT & ~ROW_MASK) | row_bits[r]; _delay_us(1); // pull row r; for(uint8_t c = 0; c < NUMBER_OF_COLUMNS; c++, k++) { if( (*column_pins[c].pin & column_pins[c].bit) == 0 ) { // probe column c; usb_keyboard_press(alp_index[r], 0); usb_keyboard_press(num_index[c], 0); usb_keyboard_press(KEY_SPACE, 0); test = true; } } } if(test) usb_keyboard_press(KEY_ENTER, 0); leds = mask - leds; update_leds(leds); _delay_ms(500); } }
void out(char * s) { while(*s) { // gotta be a better way for this if(*s < 123 && *s > 96) { usb_keyboard_press((*s - 97) + 4, 0); } else if(*s == 32) { usb_keyboard_press(KEY_SPACE, 0); } else if(*s == 58) { usb_keyboard_press(KEY_SEMICOLON, KEY_SHIFT); } else if(*s == 48) { usb_keyboard_press(KEY_0, 0); } else if(*s > 48 && *s < 58) { usb_keyboard_press((*s - 19), 0); } s++; }; usb_keyboard_press(KEY_SPACE, 0); usb_keyboard_press(KEY_SLASH, 0); usb_keyboard_press(KEY_SPACE, 0); };
void jump_bootloader(void) { usb_keyboard_press(0,0); //Make sure there are no stuck keys. _delay_ms(5); //It takes a while for changes to propgate. cli(); UDCON = 1; USBCON = (1<<FRZCLK); // disable USB UCSR1B = 0; _delay_ms(5); // ATmega32u2 #if defined(__AVR_ATmega32U2__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; DDRB = 0; DDRC = 0; DDRD = 0; PORTB = 0; PORTC = 0; PORTD = 0; // ATmega32u4, Teensy 2.0 #elif defined(__AVR_ATmega32U4__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; // AT90USB162, Teensy 1.0 #elif defined(__AVR_AT90USB162__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; DDRB = 0; DDRC = 0; DDRD = 0; PORTB = 0; PORTC = 0; PORTD = 0; // AT90USB646, Teensy++ 1.0 #elif defined(__AVR_AT90USB646__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; // AT90USB1286, Teensy++ 2.0 #elif defined(__AVR_AT90USB1286__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; #endif asm volatile(__BOOTLOADER_JUMP); }
// Step #4: do each keystroke // static void write_key(KEYCODE_TYPE keycode) { /* uint8_t key, modifier=0; #ifdef SHIFT_MASK if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT; #endif #ifdef ALTGR_MASK if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT; #endif #ifdef RCTRL_MASK if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL; #endif key = keycode & 0x3F; #ifdef KEY_NON_US_100 if (key == KEY_NON_US_100) key = 100; #endif usb_keyboard_press(key, modifier); */ usb_keyboard_press(keycode_to_key(keycode), keycode_to_modifier(keycode)); }
int main(void) { uint8_t i,j; CLKPR = 0x80; CLKPR = 0; usb_init(); while(!usb_configured()) _delay_ms(1000); for(;;) { // _delay_ms(1024); for(i=0; i<pin_count; i++) { DDRA = DDRB = DDRC = DDRD = DDRE = DDRF = 0x00; PORTA = PORTB = PORTC = PORTD = PORTE = PORTF = 0x00; *reg[i] = bit[i]; _delay_ms(1); for(j=0; j<pin_count; j++) { if(i==j) continue; *port[j] = bit[j]; _delay_ms(1); if(!(*pin[j] & bit[j])) { usb_keyboard_press(KEY_A+name[i], 0); usb_keyboard_press(KEY_1+bitnum[i], 0); usb_keyboard_press(KEY_SPACE, 0); usb_keyboard_press(KEY_A+name[j], 0); usb_keyboard_press(KEY_1+bitnum[j], 0); usb_keyboard_press(KEY_ENTER, 0); } *port[j] = 0x00; } } } }
void send_keys(uint8_t* state) { // Report all currently pressed keys to the host. This function // will be called when a change of state has been detected. uint8_t local = 0; uint8_t caps_lock_pressed = 0; const uint8_t* keymap = keymap_normal; retry: // If we detect that we are in f-mode, we need to translate the // pressed keys with the f-mode translation table. Detection of // f-mode happens while decoding the shift register. When the // f-mode key is detected as being pressed, the translation table is // switched and the decoding process is restarted. { uint8_t key_index = 0; uint8_t map_index = 0; keyboard_modifier_keys = 0; memset(keyboard_keys, 0, sizeof keyboard_keys); for (int i = 0; i < 16; i++) { uint8_t buf = state[i]; for (int j = 0; j < 8; j++, map_index++) { uint8_t mapped = pgm_read_byte(&keymap[map_index]); uint8_t pressed = (buf & 1); #if defined(DEBUG) if (pressed) { print("key "); phex(map_index - 1); print(" pressed, mapped to "); phex(mapped); print("\n"); } #endif // Handle firmware update key combination Local+Abort if (pressed) { if (map_index == 0x01) { local = 1; // Local key is pressed } else if (map_index == 0x1e && local) { jump_to_loader(); // Abort key is pressed } } if (pressed && mapped) { if (mapped & 0x80) { int num = mapped & 0x7F; switch (num) { case NUM_KEY_LEFT_CTRL: case NUM_KEY_LEFT_SHIFT: case NUM_KEY_LEFT_ALT: case NUM_KEY_LEFT_GUI: case NUM_KEY_RIGHT_CTRL: case NUM_KEY_RIGHT_SHIFT: case NUM_KEY_RIGHT_ALT: case NUM_KEY_RIGHT_GUI: keyboard_modifier_keys |= 1 << num; break; case NUM_KEY_F_MODE: if (keymap == keymap_normal) { keymap = keymap_f_mode; goto retry; } break; case NUM_KEY_CAPS_LOCK: caps_lock_pressed = 1; break; } } else { if (key_index < sizeof keyboard_keys) { keyboard_keys[key_index++] = mapped; } } } buf >>= 1; } } } #if !defined(DEBUG) usb_keyboard_send(); #endif { // Process caps lock key. This key is a switch on the Symbolics // keyboard, so we must make sure that the current switch setting // always matches the caps lock state of the host. // If the host set LED 2, it indicates that caps lock has been // pressed. If the caps lock state reported by the host does not // match the caps lock key state of the Symbolics keyboard, send a // "caps lock" key press and release to the host to make the two // match. As a result, if caps lock is depressed on another // keyboard connected to the host, it will quickly be cleared // again. uint8_t prev_caps_lock_pressed = (keyboard_leds & 2) ? 1 : 0; if (caps_lock_pressed ^ prev_caps_lock_pressed) { usb_keyboard_press(KEY_CAPS_LOCK, 0); } } }
int main(void) { uint8_t b, d, mask, i, reset_idle; uint8_t b_prev=0xFF, d_prev=0xFF; // set for 16 MHz clock CPU_PRESCALE(0); // Configure all port B and port D pins as inputs with pullup resistors. // See the "Using I/O Pins" page for details. // http://www.pjrc.com/teensy/pins.html DDRD = 0x00; DDRB = 0x00; PORTB = 0xFF; PORTD = 0xFF; // Initialize the USB, and then wait for the host to set configuration. // If the Teensy is powered without a PC connected to the USB port, // this will wait forever. usb_init(); while (!usb_configured()) /* wait */ ; // Wait an extra second for the PC's operating system to load drivers // and do whatever it does to actually be ready for input _delay_ms(1000); // Configure timer 0 to generate a timer overflow interrupt every // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock // This demonstrates how to use interrupts to implement a simple // inactivity timeout. TCCR0A = 0x00; TCCR0B = 0x05; TIMSK0 = (1<<TOIE0); print("Begin keyboard example program\n"); print("All Port B or Port D pins are inputs with pullup resistors.\n"); print("Any connection to ground on Port B or D pins will result in\n"); print("keystrokes sent to the PC (and debug messages here).\n"); while (1) { // read all port B and port D pins b = PINB; d = PIND; // check if any pins are low, but were high previously mask = 1; reset_idle = 0; for (i=0; i<8; i++) { //need to add if statements here if (((b & mask) == 0) && (b_prev & mask) != 0) { if (i == 0) usb_keyboard_press(KEY_1, 0); if (i == 1) usb_keyboard_press(KEY_2, 0); if (i == 2) usb_keyboard_press(KEY_3, 0); if (i == 3) usb_keyboard_press(KEY_4, 0); if (i == 4) usb_keyboard_press(KEY_5, 0); if (i == 5) usb_keyboard_press(KEY_6, 0); if (i == 6) usb_keyboard_press(KEY_7, 0); if (i == 7) usb_keyboard_press(KEY_8, 0); reset_idle = 1; } if (((d & mask) == 0) && (d_prev & mask) != 0) { if (i == 0) usb_keyboard(KEY_9, 0); if (i == 1) usb_keyboard(KEY_PERIOD, 0); if (i == 2) usb_keyboard(KEY_0, 0); if (i == 3) usb_keyboard(KEYPAD_ENTER) reset_idle = 1; } mask = mask << 1; } // if any keypresses were detected, reset the idle counter if (reset_idle) { // variables shared with interrupt routines must be // accessed carefully so the interrupt routine doesn't // try to use the variable in the middle of our access cli(); idle_count = 0; sei(); } // now the current pins will be the previous, and // wait a short delay so we're not highly sensitive // to mechanical "bounce". b_prev = b; d_prev = d; _delay_ms(2); } }
void usbsend(void) { usb_keyboard_press(drop().i, keyboard_modifier_keys); };