POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * PS/2 protocol busywait version
+ */
+
#include <stdbool.h>
-#include <util/delay.h>
+#include "wait.h"
#include "ps2.h"
+#include "ps2_io.h"
#include "debug.h"
-/*
- * PS/2 protocol busywait version
- */
-
#define WAIT(stat, us, err) do { \
if (!wait_##stat(us)) { \
ps2_error = err; \
} \
} while (0)
+
uint8_t ps2_error = PS2_ERR_NONE;
void ps2_host_init(void)
{
+ clock_init();
+ data_init();
+
// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
- _delay_ms(2500);
+ wait_ms(2500);
inhibit();
}
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
+ wait_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);
+ wait_us(15);
if (data&(1<<i)) {
parity = !parity;
data_hi();
WAIT(clock_hi, 50, 2);
WAIT(clock_lo, 50, 3);
}
- /* parity [10] */
- _delay_us(15);
+
+ /* Parity bit */
+ wait_us(15);
if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5);
- /* stop bit [11] */
- _delay_us(15);
+
+ /* Stop bit */
+ wait_us(15);
data_hi();
- /* ack [12] */
+
+ /* Ack */
WAIT(data_lo, 50, 6);
WAIT(clock_lo, 50, 7);
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
- res = ps2_host_recv_response();
+ inhibit();
+ 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)
{
- // TODO:
- // 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 = 200;
- while (try-- && (data = ps2_host_recv())) ;
+ uint8_t try = 250;
+ do {
+ data = ps2_host_recv();
+ } while (try-- && ps2_error);
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)
{
return data;
ERROR:
if (ps2_error > PS2_ERR_STARTBIT3) {
- printf("x%02X\n", ps2_error);
+ xprintf("x%02X\n", ps2_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);
+}