BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
arduino_i2c_keyboard
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
arduino_i2c_keyboard
Commits
e5e9f225
Commit
e5e9f225
authored
Jul 18, 2018
by
Forest Godfrey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add initial key handling. Can now track key status and send I2C interrupts.
parent
76c6fe42
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
210 additions
and
8 deletions
+210
-8
ai2c_interface.h
arduino_sketch/ai2c_interface.h
+5
-0
arduino_sketch.ino
arduino_sketch/arduino_sketch.ino
+205
-8
No files found.
arduino_sketch/ai2c_interface.h
View file @
e5e9f225
...
...
@@ -79,6 +79,11 @@
#define AI2C_REGISTER_MAX 0x53
/* Must be set to the max register address */
/*
* Commands
*/
#define AI2C_CMD_CMD_COMPLETE 0x00
/* Previous command completed - must be read back */
/*
* Device ID
*/
#define AI2C_ID 0x4242
...
...
arduino_sketch/arduino_sketch.ino
View file @
e5e9f225
...
...
@@ -22,27 +22,107 @@
*/
#include <Wire.h>
/*
* Project Includes
*/
#include "ai2c_interface.h"
#include "Timer.h"
//#define DEBUG_KEYS 1
#ifndef DEBUG_KEYS
#define KEY_CHECK_INTERVAL 10
#else
#define KEY_CHECK_INTERVAL 5000
uint16_t
keytest
=
0
;
#endif
#define INTERRUPT_PIN 10
typedef
struct
{
int8_t
pin
;
bool
enable_pullup
;
}
key_pin_t
;
#define INTERRUPT_PIN 9
#define MAX_KEY_COUNT 16
static
key_pin_t
keypins
[
MAX_KEY_COUNT
]
=
{
{
9
,
true
},
/* 0 - Up */
{
7
,
true
},
/* 1 - Down */
{
8
,
true
},
/* 2 - Left */
{
6
,
true
},
/* 3 - Right */
{
4
,
true
},
/* 4 - "A" */
{
5
,
true
},
/* 5 - "B" */
{
1
,
true
},
/* 6 - Select */
{
0
,
true
},
/* 7 - Start */
{
11
,
true
},
/* 8 - Screen On/Off */
{
-
1
,
false
},
/* 9 - Unused */
{
-
1
,
false
},
/* 10 - Unused */
{
-
1
,
false
},
/* 11 - Unused */
{
-
1
,
false
},
/* 12 - Unused */
{
-
1
,
false
},
/* 13 - Unused */
{
-
1
,
false
},
/* 14 - Unused */
{
-
1
,
false
},
/* 15 - Unused */
};
/*
* Interrupt to host generation
*/
bool
intr_running
;
bool
send_intr
;
/* Test Code */
unsigned
long
next_send_intr
;
int
current_intr_val
;
/*
* The I2C read routine read/write routines come directly out of the register file.
*/
unsigned
char
register_file
[
AI2C_REGISTER_MAX
];
/*
* Interval timers
*/
Timer
*
keytimer
=
new
Timer
(
KEY_CHECK_INTERVAL
);
Timer
*
intrtimer
=
new
Timer
(
2
);
void
i2cRequest
(
void
)
{
unsigned
char
shadow_register_file
[
AI2C_REGISTER_MAX
];
int
addr
=
register_file
[
AI2C_REGISTER_READ_ADDR
];
int
len
=
register_file
[
AI2C_REGISTER_READ_BYTES
];
if
(
addr
>=
AI2C_REGISTER_MAX
)
addr
=
0
;
if
(
len
>=
(
AI2C_REGISTER_MAX
-
addr
))
len
=
1
;
Wire
.
write
(
&
(
register_file
[
addr
]),
len
);
//noInterrupts();
memcpy
(
shadow_register_file
,
register_file
,
sizeof
(
shadow_register_file
));
/*
* Deal with read/clear registers.
*/
switch
(
addr
)
{
case
AI2C_REGISTER_KEY_DOWN_LOW
:
case
AI2C_REGISTER_KEY_DOWN_HIGH
:
case
AI2C_REGISTER_KEY_UP_LOW
:
case
AI2C_REGISTER_KEY_UP_HIGH
:
register_file
[
addr
]
=
0
;
break
;
default:
/* No-op */
break
;
}
//interrupts();
Wire
.
write
(
&
(
shadow_register_file
[
addr
]),
len
);
#if 1
Serial
.
print
(
"Read addr = 0x"
);
Serial
.
print
(
addr
,
HEX
);
Serial
.
print
(
" len = "
);
Serial
.
print
(
len
);
Serial
.
print
(
" First byte = 0x"
);
Serial
.
println
(
shadow_register_file
[
addr
],
HEX
);
#endif
}
void
...
...
@@ -67,11 +147,12 @@ i2cReceive(int bytes) {
char
c
=
Wire
.
read
();
// receive byte as a character
Serial
.
print
(
c
);
// print the character
}
Serial
.
print
(
"I2C Write: addr = "
);
Serial
.
print
(
addr
);
Serial
.
print
(
" data = "
);
Serial
.
println
(
data
);
#if 1
Serial
.
print
(
"I2C Write: addr = 0x"
);
Serial
.
print
(
addr
,
HEX
);
Serial
.
print
(
" data = 0x"
);
Serial
.
println
(
data
,
HEX
);
#endif
switch
(
addr
)
{
case
AI2C_REGISTER_CAMERA_FRAC_LOW
:
...
...
@@ -94,9 +175,77 @@ i2cReceive(int bytes) {
}
}
/*
* handleKeys: Check current key status. Set bits for any keys pressed or released.
* Triggers an interrupt when necessary.
*/
void
handleKeys
(
void
)
{
bool
needintr
;
int
i
;
uint32_t
current_keys
;
uint8_t
keys_low
,
keys_high
;
current_keys
=
0
;
#ifndef DEBUG_KEYS
for
(
i
=
0
;
i
<
MAX_KEY_COUNT
;
i
++
)
{
uint32_t
val
;
if
(
keypins
[
i
].
pin
<
0
)
continue
;
val
=
digitalRead
(
keypins
[
i
].
pin
);
val
&=
1
;
current_keys
|=
val
<<
i
;
}
#else
keytest
=
keytest
<<
1
;
if
(
!
keytest
)
keytest
=
1
;
current_keys
=
keytest
;
Serial
.
print
(
"Current keys: 0x"
);
Serial
.
println
(
current_keys
,
HEX
);
#endif
keys_low
=
current_keys
&
0xff
;
keys_high
=
(
current_keys
>>
8
)
&
0xff
;
/*
* This needs to be an atomic update so we need to shut off interrupts.
*/
//noInterrupts();
/*
* All keys that have changed AND with current keys that are currently up is keys that have been released.
*/
register_file
[
AI2C_REGISTER_KEY_UP_LOW
]
|=
(
register_file
[
AI2C_REGISTER_KEY_STATUS_LOW
]
^
keys_low
)
&
keys_low
;
register_file
[
AI2C_REGISTER_KEY_UP_HIGH
]
|=
(
register_file
[
AI2C_REGISTER_KEY_STATUS_HIGH
]
^
keys_high
)
&
keys_high
;
/*
* All keys that have changed AND with keys that were release is all keys that have been pressed.
*/
register_file
[
AI2C_REGISTER_KEY_DOWN_LOW
]
|=
(
register_file
[
AI2C_REGISTER_KEY_STATUS_LOW
]
^
keys_low
)
&
register_file
[
AI2C_REGISTER_KEY_STATUS_LOW
];
register_file
[
AI2C_REGISTER_KEY_DOWN_HIGH
]
|=
(
register_file
[
AI2C_REGISTER_KEY_STATUS_HIGH
]
^
keys_high
)
&
register_file
[
AI2C_REGISTER_KEY_STATUS_HIGH
];
/* Set the current key status */
needintr
=
(
register_file
[
AI2C_REGISTER_KEY_STATUS_LOW
]
!=
keys_low
)
||
(
register_file
[
AI2C_REGISTER_KEY_STATUS_HIGH
]
!=
keys_high
);
register_file
[
AI2C_REGISTER_KEY_STATUS_LOW
]
=
keys_low
;
register_file
[
AI2C_REGISTER_KEY_STATUS_HIGH
]
=
keys_high
;
/* Re-enable interrupts */
//interrupts();
if
(
needintr
)
send_intr
=
true
;
}
/*
* sendInterruptDone: Callback on interrupt->host completion.
*/
void
sendInterruptDone
(
void
)
{
digitalWrite
(
INTERRUPT_PIN
,
1
);
intr_running
=
false
;
}
void
setup
()
{
// Initialize console
delay
(
5000
);
Serial
.
begin
(
9600
);
Serial
.
println
(
"Arduino I2C Keyboard Driver Built "
__DATE__
" "
__TIME__
);
...
...
@@ -122,10 +271,48 @@ setup() {
snprintf
(
&
(
register_file
[
AI2C_REGISTER_VERS_STR
]),
AI2C_VER_STR_LEN
,
"AI2C Built: "
__DATE__
" "
__TIME__
);
register_file
[
AI2C_REGISTER_READ_BYTES
]
=
1
;
/*
* Set up key pins
*/
#if 1
for
(
int
i
=
0
;
i
<
MAX_KEY_COUNT
;
i
++
)
{
int
pinmode
=
keypins
[
i
].
enable_pullup
?
INPUT_PULLUP
:
INPUT
;
if
(
keypins
[
i
].
pin
<
0
)
continue
;
pinMode
(
keypins
[
i
].
pin
,
pinmode
);
}
#endif
/*
* Set up timers
*/
keytimer
->
setOnTimer
(
handleKeys
);
keytimer
->
Start
();
intrtimer
->
setOnTimer
(
sendInterruptDone
);
intrtimer
->
setSingleShot
(
true
);
intr_running
=
false
;
}
/*
* sendInterrupt: Send an interrupt to the host. Interrupts are falling edge triggered.
*/
void
sendInterrupt
(
void
)
{
Serial
.
println
(
"Sending interrupt..."
);
digitalWrite
(
INTERRUPT_PIN
,
0
);
send_intr
=
false
;
intr_running
=
true
;
intrtimer
->
Resume
();
}
void
loop
()
{
/* Test Code */
#if 0
if (millis() > next_send_intr) {
current_intr_val = current_intr_val ? 0 : 1;
digitalWrite(INTERRUPT_PIN, current_intr_val);
...
...
@@ -133,7 +320,17 @@ loop() {
Serial.print("Interupt pin now ");
Serial.println(current_intr_val);
}
delay
(
10
);
#endif
if
(
send_intr
&
!
intr_running
)
{
Serial
.
print
(
"Keys: 0x"
);
Serial
.
print
(
register_file
[
AI2C_REGISTER_KEY_STATUS_HIGH
],
HEX
);
Serial
.
println
(
register_file
[
AI2C_REGISTER_KEY_STATUS_LOW
],
HEX
);
sendInterrupt
();
}
keytimer
->
Update
();
intrtimer
->
Update
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment