1
0
Fork 0

Add ps2_interrupt.c

This commit is contained in:
tmk 2013-11-28 14:20:00 +09:00
parent 532e100450
commit 4eb27ee890
4 changed files with 124 additions and 310 deletions

View file

@ -35,16 +35,16 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
* PS/2 protocol busywait version
*/
#include <stdbool.h>
#include <util/delay.h>
#include "ps2.h"
#include "debug.h"
/*
* PS/2 protocol busywait version
*/
#define WAIT(stat, us, err) do { \
if (!wait_##stat(us)) { \
ps2_error = err; \
@ -52,6 +52,7 @@ POSSIBILITY OF SUCH DAMAGE.
} \
} while (0)
uint8_t ps2_error = PS2_ERR_NONE;
@ -65,18 +66,19 @@ void ps2_host_init(void)
uint8_t ps2_host_send(uint8_t data)
{
uint8_t res = 0;
bool parity = true;
ps2_error = PS2_ERR_NONE;
/* terminate a transmission if we have */
inhibit();
_delay_us(200); // at least 100us
_delay_us(100); // 100us [4]p.13, [5]p.50
/* start bit [1] */
/* 'Request to Send' and Start bit */
data_lo();
clock_hi();
WAIT(clock_lo, 20000, 10); // may take 15ms at most until device starts clocking
/* data [2-9] */
WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
/* Data bit */
for (uint8_t i = 0; i < 8; i++) {
_delay_us(15);
if (data&(1<<i)) {
@ -88,15 +90,18 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 2);
WAIT(clock_lo, 50, 3);
}
/* parity [10] */
/* Parity bit */
_delay_us(15);
if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5);
/* stop bit [11] */
/* Stop bit */
_delay_us(15);
data_hi();
/* ack [12] */
/* Ack */
WAIT(data_lo, 50, 6);
WAIT(clock_lo, 50, 7);
@ -105,17 +110,16 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(data_hi, 50, 9);
inhibit();
res = ps2_host_recv_response();
return ps2_host_recv_response();
ERROR:
inhibit();
return res;
return 0;
}
/* receive data when host want else inhibit communication */
uint8_t ps2_host_recv_response(void)
{
// Command might take 20ms to response([3]p.21)
// TrackPoint might take 25ms ([5]2.7)
// Command may take 25ms/20ms at most([5]p.46, [3]p.21)
// 250 * 100us(wait for start bit in ps2_host_recv)
uint8_t data = 0;
uint8_t try = 250;
@ -125,14 +129,6 @@ uint8_t ps2_host_recv_response(void)
return data;
}
/* send LED state to keyboard */
void ps2_host_set_led(uint8_t led)
{
ps2_host_send(0xED);
ps2_host_send(led);
}
/* called after start bit comes */
uint8_t ps2_host_recv(void)
{
@ -180,3 +176,10 @@ ERROR:
inhibit();
return 0;
}
/* send LED state to keyboard */
void ps2_host_set_led(uint8_t led)
{
ps2_host_send(0xED);
ps2_host_send(led);
}