462 lines
12 KiB
C
Executable File
462 lines
12 KiB
C
Executable File
/* Name: main.c
|
|
* Project: hid-mouse, a very simple HID example
|
|
* Author: Christian Starkjohann
|
|
* Creation Date: 2008-04-07
|
|
* Tabsize: 4
|
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
|
* This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $
|
|
*/
|
|
|
|
/*
|
|
This example should run on most AVRs with only little changes. No special
|
|
hardware resources except INT0 are used. You may have to change usbconfig.h for
|
|
different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
|
|
at least be connected to INT0 as well.
|
|
|
|
We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't
|
|
publish any hardware using these IDs! This is for demonstration only!
|
|
*/
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/wdt.h>
|
|
#include <avr/interrupt.h> /* for sei() */
|
|
#include <util/delay.h> /* for _delay_ms() */
|
|
|
|
#include "lcd.h"
|
|
|
|
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
|
#include "usbdrv.h"
|
|
|
|
//ololol
|
|
#include <compat/deprecated.h>
|
|
|
|
/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter
|
|
* 10 Keyboard/Keypad Page for more codes.
|
|
*/
|
|
#define MOD_CONTROL_LEFT (1<<0)
|
|
#define MOD_SHIFT_LEFT (1<<1)
|
|
#define MOD_ALT_LEFT (1<<2)
|
|
#define MOD_GUI_LEFT (1<<3)
|
|
#define MOD_CONTROL_RIGHT (1<<4)
|
|
#define MOD_SHIFT_RIGHT (1<<5)
|
|
#define MOD_ALT_RIGHT (1<<6)
|
|
#define MOD_GUI_RIGHT (1<<7)
|
|
|
|
#define KEY_A 4
|
|
#define KEY_B 5
|
|
#define KEY_C 6
|
|
#define KEY_D 7
|
|
#define KEY_E 8
|
|
#define KEY_F 9
|
|
#define KEY_G 10
|
|
#define KEY_H 11
|
|
#define KEY_I 12
|
|
#define KEY_J 13
|
|
#define KEY_K 14
|
|
#define KEY_L 15
|
|
#define KEY_M 16
|
|
#define KEY_N 17
|
|
#define KEY_O 18
|
|
#define KEY_P 19
|
|
#define KEY_Q 20
|
|
#define KEY_R 21
|
|
#define KEY_S 22
|
|
#define KEY_T 23
|
|
#define KEY_U 24
|
|
#define KEY_V 25
|
|
#define KEY_W 26
|
|
#define KEY_X 27
|
|
#define KEY_Y 28
|
|
#define KEY_Z 29
|
|
#define KEY_1 30
|
|
#define KEY_2 31
|
|
#define KEY_3 32
|
|
#define KEY_4 33
|
|
#define KEY_5 34
|
|
#define KEY_6 35
|
|
#define KEY_7 36
|
|
#define KEY_8 37
|
|
#define KEY_9 38
|
|
#define KEY_0 39
|
|
|
|
#define KEY_F1 58
|
|
#define KEY_F2 59
|
|
#define KEY_F3 60
|
|
#define KEY_F4 61
|
|
#define KEY_F5 62
|
|
#define KEY_F6 63
|
|
#define KEY_F7 64
|
|
#define KEY_F8 65
|
|
#define KEY_F9 66
|
|
#define KEY_F10 67
|
|
#define KEY_F11 68
|
|
#define KEY_F12 69
|
|
|
|
#define KEY_RETURN 40
|
|
#define KEY_UP 82
|
|
#define KEY_DOWN 81
|
|
#define KEY_LEFT 80
|
|
#define KEY_RIGHT 79
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* ----------------------------- USB interface ----------------------------- */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
PROGMEM char usbHidReportDescriptor[63] = {
|
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
|
0x09, 0x06, // USAGE (Keyboard)
|
|
0xa1, 0x01, // COLLECTION (Application)
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
|
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
|
0x75, 0x01, // REPORT_SIZE (1)
|
|
0x95, 0x08, // REPORT_COUNT (8)
|
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
|
0x95, 0x01, // REPORT_COUNT (1)
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
|
0x95, 0x05, // REPORT_COUNT (5)
|
|
0x75, 0x01, // REPORT_SIZE (1)
|
|
0x05, 0x08, // USAGE_PAGE (LEDs)
|
|
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
|
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
|
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
|
0x95, 0x01, // REPORT_COUNT (1)
|
|
0x75, 0x03, // REPORT_SIZE (3)
|
|
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
|
0x95, 0x06, // REPORT_COUNT (6)
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
|
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
|
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
|
0xc0 // END_COLLECTION
|
|
};
|
|
|
|
#define SENDBUFFER_SIZE 32
|
|
char g_SendBuffer[SENDBUFFER_SIZE];
|
|
char *g_SendBufferWritePointer = g_SendBuffer;
|
|
char *g_SendBufferReadPointer = g_SendBuffer;
|
|
|
|
void SendBufferWrite(char Character)
|
|
{
|
|
*g_SendBufferWritePointer = Character;
|
|
g_SendBufferWritePointer++;
|
|
|
|
if (g_SendBufferWritePointer - g_SendBuffer >= SENDBUFFER_SIZE)
|
|
g_SendBufferWritePointer = g_SendBuffer;
|
|
}
|
|
|
|
char SendBufferRead(void)
|
|
{
|
|
if (g_SendBufferWritePointer == g_SendBufferReadPointer)
|
|
return 0;
|
|
|
|
char Character = *g_SendBufferReadPointer;
|
|
g_SendBufferReadPointer++;
|
|
|
|
if (g_SendBufferReadPointer - g_SendBuffer >= SENDBUFFER_SIZE)
|
|
g_SendBufferReadPointer = g_SendBuffer;
|
|
|
|
return Character;
|
|
}
|
|
|
|
void SendString(char *String)
|
|
{
|
|
while (*String != 0)
|
|
{
|
|
char Character = *String;
|
|
String++;
|
|
|
|
SendBufferWrite(Character);
|
|
}
|
|
}
|
|
|
|
typedef struct{
|
|
uchar buttonMask;
|
|
uchar reserved;
|
|
uchar buttons[6];
|
|
}report_t;
|
|
|
|
static report_t reportBuffer;
|
|
static uchar idleRate; /* repeat rate for keyboards, never used for mice */
|
|
|
|
char g_ShouldKeyUp = 0;
|
|
static void SendKeys(void)
|
|
{
|
|
reportBuffer.buttonMask=0;
|
|
reportBuffer.reserved=0;
|
|
|
|
reportBuffer.buttons[0]=0;
|
|
reportBuffer.buttons[1]=0;
|
|
reportBuffer.buttons[2]=0;
|
|
reportBuffer.buttons[3]=0;
|
|
reportBuffer.buttons[4]=0;
|
|
reportBuffer.buttons[5]=0;
|
|
|
|
if (g_ShouldKeyUp)
|
|
{
|
|
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
|
|
g_ShouldKeyUp = 0;
|
|
return;
|
|
}
|
|
g_ShouldKeyUp = 1;
|
|
|
|
char Character = SendBufferRead();
|
|
if (!Character)
|
|
{
|
|
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
|
|
g_ShouldKeyUp = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
if ('a' <= Character && Character <= 'z')
|
|
{
|
|
reportBuffer.buttons[0] = Character - 'a' + KEY_A;
|
|
}
|
|
else if ('A' <= Character && Character <= 'Z')
|
|
{
|
|
reportBuffer.buttons[0] = Character - 'A' + KEY_A;
|
|
// reportBuffer.buttonMask = MOD_SHIFT_LEFT;
|
|
}
|
|
else if ('1' <= Character && Character <= '9')
|
|
{
|
|
reportBuffer.buttons[0] = Character - '1' + KEY_1;
|
|
}
|
|
else if (Character == '0')
|
|
{
|
|
reportBuffer.buttons[0] = KEY_0;
|
|
}
|
|
else if (Character == ' ')
|
|
{
|
|
reportBuffer.buttons[0] = 44;
|
|
}
|
|
else if (Character == '.')
|
|
{
|
|
reportBuffer.buttons[0] = 55;
|
|
}
|
|
else
|
|
{
|
|
g_ShouldKeyUp = 0;
|
|
}
|
|
|
|
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|
{
|
|
usbRequest_t *rq = (void *)data;
|
|
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
|
|
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
|
|
usbMsgPtr = (void *)&reportBuffer;
|
|
return sizeof(reportBuffer);
|
|
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
|
|
usbMsgPtr = &idleRate;
|
|
return 1;
|
|
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
|
|
idleRate = rq->wValue.bytes[1];
|
|
}
|
|
}else{
|
|
/* no vendor specific requests implemented */
|
|
}
|
|
return 0; /* default for not implemented requests: return no data back to host */
|
|
}
|
|
|
|
#define DET_CLOSED(a) (a > 300 ? 1 : 0)
|
|
#define DET_OPEN(a) (a < 250 ? 1 : 0)
|
|
|
|
void PrintNumber(uint32_t Number)
|
|
{
|
|
char Buffer[9];
|
|
snprintf(Buffer, 9, "%03i", Number);
|
|
lcd_puts(Buffer);
|
|
}
|
|
|
|
void PrintTime(uint32_t Delta)
|
|
{
|
|
uint8_t Miliseconds = Delta % 1000;
|
|
Delta /= 1000;
|
|
uint8_t Seconds = Delta % 60;
|
|
Delta /= 60;
|
|
uint8_t Minutes = Delta % 60;
|
|
|
|
char Buffer[4];
|
|
snprintf(Buffer, 3, "%01i", Minutes);
|
|
lcd_puts(Buffer);
|
|
|
|
lcd_puts(":");
|
|
|
|
snprintf(Buffer, 3, "%02i", Seconds);
|
|
lcd_puts(Buffer);
|
|
|
|
lcd_puts(":");
|
|
|
|
snprintf(Buffer, 4, "%03i", Miliseconds);
|
|
lcd_puts(Buffer);
|
|
}
|
|
|
|
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
|
|
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
|
|
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
|
|
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
|
|
#define FRACT_MAX (1000 >> 3)
|
|
|
|
volatile unsigned long timer0_overflow_count = 0;
|
|
volatile unsigned long timer0_millis = 0;
|
|
static unsigned char timer0_fract = 0;
|
|
|
|
SIGNAL(TIMER0_OVF_vect)
|
|
{
|
|
unsigned long m = timer0_millis;
|
|
unsigned char f = timer0_fract;
|
|
|
|
m += MILLIS_INC;
|
|
f += FRACT_INC;
|
|
if (f >= FRACT_MAX) {
|
|
f -= FRACT_MAX;
|
|
m += 1;
|
|
}
|
|
|
|
timer0_fract = f;
|
|
timer0_millis = m;
|
|
timer0_overflow_count++;
|
|
}
|
|
|
|
unsigned long millis()
|
|
{
|
|
unsigned long m;
|
|
uint8_t oldSREG = SREG;
|
|
cli();
|
|
m = timer0_millis;
|
|
SREG = oldSREG;
|
|
|
|
return m;
|
|
}
|
|
|
|
void beepdabeeper(void)
|
|
{
|
|
PORTD |= (1 << 1);
|
|
_delay_ms(200);
|
|
PORTD &= ~(1 << 1);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
uint16_t i;
|
|
wdt_disable();
|
|
DDRD |= (1 << 1);
|
|
beepdabeeper();
|
|
_delay_ms(500);
|
|
beepdabeeper();
|
|
//PORTD |= (1 << 1);
|
|
sei();
|
|
sbi(TCCR0, CS01);
|
|
sbi(TCCR0, CS00);
|
|
sbi(TIMSK, TOIE0);
|
|
|
|
ADMUX=(1<<REFS0)|(1<<REFS1);
|
|
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(ADPS1)|(ADPS0);
|
|
|
|
/* Even if you don't use the watchdog, turn it off here. On newer devices,
|
|
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
|
|
*/
|
|
/* RESET status: all port bits are inputs without pull-up.
|
|
* That's the way we need D+ and D-. Therefore we don't need any
|
|
* additional hardware initialization.
|
|
*/
|
|
|
|
|
|
|
|
lcd_init(LCD_DISP_ON);
|
|
lcd_command(LCD_FUNCTION_4BIT_2LINES );
|
|
lcd_clrscr();
|
|
lcd_gotoxy(3, 0);
|
|
lcd_puts("-> wait <-");
|
|
|
|
uint32_t StartTime = 0;
|
|
for (;;)
|
|
{
|
|
ADCSRA|=(1<<ADSC);
|
|
while(!(ADCSRA & (1<<ADIF)));
|
|
ADCSRA|=(1<<ADIF);
|
|
|
|
if (DET_CLOSED(ADC))
|
|
{
|
|
StartTime = millis();
|
|
break;
|
|
}
|
|
}
|
|
|
|
lcd_clrscr();
|
|
lcd_gotoxy(2, 1);
|
|
lcd_puts("-> pomiar <-");
|
|
//lcd_puts_p(PSTR("Test"));
|
|
uint32_t EndTime = StartTime;
|
|
PORTD |= (1 << 1);
|
|
uint8_t ShouldTurnOff = 1;
|
|
for (;;)
|
|
{
|
|
if (ShouldTurnOff && millis() - StartTime > 200)
|
|
{
|
|
ShouldTurnOff = 0;
|
|
PORTD &= ~(1 << 1);
|
|
}
|
|
//_delay_ms(200);
|
|
//lcd_clrscr();
|
|
lcd_gotoxy(4, 0);
|
|
PrintTime(millis() - StartTime);
|
|
|
|
// start ADC sample...
|
|
ADCSRA|=(1<<ADSC);
|
|
// wait for result...
|
|
while(!(ADCSRA & (1<<ADIF)));
|
|
|
|
ADCSRA|=(1<<ADIF);
|
|
if (DET_OPEN(ADC))
|
|
{
|
|
EndTime = millis();
|
|
break;
|
|
}
|
|
//PrintNumber(ADC);
|
|
}
|
|
beepdabeeper();
|
|
|
|
lcd_clrscr();
|
|
lcd_gotoxy(2, 0);
|
|
lcd_puts("-> wynik: <-");
|
|
lcd_gotoxy(4, 1);
|
|
PrintTime(EndTime - StartTime);
|
|
for (;;) {}
|
|
|
|
/*for (;;) {}
|
|
|
|
wdt_enable(WDTO_1S);
|
|
usbInit();
|
|
usbDeviceDisconnect();
|
|
i = 0b11111111111;
|
|
while(--i){
|
|
wdt_reset();
|
|
_delay_ms(1);
|
|
}
|
|
usbDeviceConnect();
|
|
sei();
|
|
for(;;){
|
|
wdt_reset();
|
|
usbPoll();
|
|
if(usbInterruptIsReady()){
|
|
SendKeys();
|
|
}
|
|
}*/
|
|
return 0;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------- */
|