You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.2 KiB
125 lines
3.2 KiB
/*
|
|
* This code is based on seveal VUSB-Examples the
|
|
* HID was taken from the CapsLocker code from macetech
|
|
* http://macetech.com/blog/?q=node/46
|
|
*
|
|
*/
|
|
#include "main.h"
|
|
|
|
#define MSG "what do ya want for nothing?"
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/wdt.h>
|
|
#include <avr/eeprom.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <util/delay.h>
|
|
#include <stdlib.h>
|
|
|
|
uint8_t reportBuffer[2]; /* buffer for HID reports */
|
|
uint8_t idleRate;
|
|
|
|
static uint8_t kbd_event_state=0;
|
|
|
|
uint32_t get_cnt(){
|
|
void* p=(void*)eeprom_read_word(CNTPOS_PTR);
|
|
return eeprom_read_dword(p);
|
|
}
|
|
|
|
uint8_t inc_cnt(){
|
|
uint32_t cnt;
|
|
void* p=(void*)eeprom_read_word(CNTPOS_PTR);
|
|
cnt=eeprom_read_dword(p);
|
|
if(cnt==UINT32_MAX){
|
|
eeprom_write_word(CNTPOS_PTR,ERROR);
|
|
return 0;
|
|
}
|
|
eeprom_write_dword(p,cnt+1);
|
|
|
|
retry:
|
|
if(eeprom_read_dword(p)!=cnt+1){
|
|
eeprom_write_dword(p,cnt+1);
|
|
if(eeprom_read_dword(p)!=cnt+1){
|
|
/*Probabbly the EEPROM position is bad, try an other*/
|
|
p+=4;
|
|
if(p+4>(void*)EEPROM_SIZE){
|
|
eeprom_write_word(CNTPOS_PTR,ERROR);
|
|
return 0;
|
|
}
|
|
eeprom_write_word(CNTPOS_PTR,(uint16_t)p);
|
|
|
|
/* I know some people don't like goto because of dijkstra's
|
|
legendary article "goto considered harmfull". The truth is he
|
|
didn't want us to stop using goto at all, but to think if it
|
|
is appropriate. The alternative here would be a loop around
|
|
this whole block and some well-placed "break" and "continue"
|
|
kbd_event_statements - I think that would be even worse than the goto*/
|
|
|
|
goto retry;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void buildReport(uint8_t mod, uint8_t key){
|
|
reportBuffer[0] = mod;
|
|
reportBuffer[1] = key;
|
|
}
|
|
|
|
|
|
int main(void){
|
|
#ifdef CALIB
|
|
uint8_t calibrationValue;
|
|
#endif
|
|
|
|
uint8_t sec[SECLEN]=SECRET;
|
|
uint32_t cnt;
|
|
|
|
#ifdef CALIB
|
|
/* oszillator calibration */
|
|
calibrationValue = eeprom_read_byte(0); /* calibration value from last time */
|
|
if(calibrationValue != 0xff){
|
|
OSCCAL = calibrationValue;
|
|
}
|
|
#endif //CALLIB
|
|
|
|
usbDeviceDisconnect();
|
|
_delay_ms(300); /* mustn't be that exact */
|
|
usbDeviceConnect();
|
|
|
|
wdt_enable(WDTO_500MS);
|
|
|
|
writeToBuffer(USB_KEY_NOP);
|
|
writeToBuffer(USB_KEY_NOP);
|
|
|
|
if( eeprom_read_word(CNTPOS_PTR)==ERROR ){
|
|
writeToBuffer(USB_KEY_E);
|
|
writeToBuffer(USB_KEY_R);
|
|
writeToBuffer(USB_KEY_R);
|
|
writeToBuffer(USB_KEY_O);
|
|
writeToBuffer(USB_KEY_R);
|
|
}else{
|
|
cnt = get_cnt();
|
|
buffer_unum(get_otp_from_cnt(cnt,8,sec,SECLEN));
|
|
//inc_cnt();
|
|
}
|
|
|
|
usbInit();
|
|
sei();
|
|
for(;;){
|
|
wdt_reset();
|
|
usbPoll();
|
|
/* we can send another key */
|
|
if(usbInterruptIsReady()){
|
|
kbd_event_state=!kbd_event_state;
|
|
if(kbd_event_state && !buff_empty){
|
|
buildReport(0x00, readBuffer());
|
|
}else{
|
|
buildReport(0x00, 0x00);
|
|
}
|
|
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|