Add ps2_interrupt.c
This commit is contained in:
		
							parent
							
								
									532e100450
								
							
						
					
					
						commit
						4eb27ee890
					
				
					 4 changed files with 124 additions and 310 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue