Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 12 Capturing Input

Similar presentations


Presentation on theme: "Chapter 12 Capturing Input"— Presentation transcript:

1 Chapter 12 Capturing Input

2 Change Notification Module

3 Using CN to Capture Keyboard Inputs

4 CN - ISR void __ISR( _CHANGE_NOTICE_VECTOR, ipl1) CNInterrupt( void)
{ // change notification interrupt service routine // 1. make sure it was a falling edge if ( PS2CLK == 0) { switch( PS2State){ default: case PS2START: // verify start bit if ( ! PS2DAT) KCount = 8; // init bit counter KParity = 0; // init parity check PS2State = PS2BIT; } break; case PS2BIT: KBDBuf >>=1; // shift in data bit if ( PS2DAT) KBDBuf += 0x80; KParity ^= KBDBuf; // update parity if ( --KCount == 0) // if all bit read, move on PS2State = PS2PARITY; case PS2PARITY: if ( PS2DAT) // verify parity KParity ^= 0x80; if ( KParity & 0x80) // if parity odd, continue PS2State = PS2STOP; else PS2State = PS2START; case PS2STOP: if ( PS2DAT) // verify stop bit { KBDCode = KBDBuf; // save code in mail box KBDReady = 1; // set flag, code available } PS2State = PS2START; break; } // switch state machine } // if falling edge // clear interrupt flag mCNClearIntFlag(); } // CN Interrupt

5 I/O Polling (Timer based)

6 I/O Polling State Machine

7 I/O Polling - ISR else { // state 0 if ( k) // PS2CLK == 1
void __ISR( _TIMER_4_VECTOR, ipl1) T4Interrupt( void) { int d, k; // sample the inputs clock and data at the same time d = PS2DAT; k = PS2CLK; // keyboard state machine if ( KState) { // previous time clock was high KState 1 if ( !k) // PS2CLK == 0 { // falling edge detected, KState = 0; // transition to State0 <<<< insert data state machine here >>>> } // falling edge else { // clock still high, remain in State1 } // clock still high } // state 1 else { // state 0 if ( k) // PS2CLK == 1 { // rising edge, transition to State1 KState = 1; } // rising edge { // clocl still low, remain in State0 } // clock still low } // state 0 // clear the interrupt flag mT4ClearIntFlag(); } // T4 Interrupt

8 I/O Polling w/Timeout

9 I/O Polling w/Timeout - ISR
void __ISR( _TIMER_4_VECTOR, ipl1) T4Interrupt( void) { int d, k; // sample the inputs clock and data at the same time d = PS2DAT; k = PS2CLK; // keyboard state machine if ( KState) { // previous time clock was high KState 1 if ( !k) // PS2CLK == 0 { // falling edge detected, KState = 0; // transition to State0 KTimer = KMAX; // restart the counter <<<< insert data state machine here >>>> } // falling edge else { // clock still high, remain in State1 KTimer--; if ( KTimer ==0) // Timeout PS2State = PS2START; // Reset data SM } // clock still high } // Kstate 1 else { // Kstate 0 if ( k) // PS2CLK == 1 { // rising edge, transition to State1 KState = 1; } // rising edge { // clocl still low, remain in State0 KTimer--; if ( KTimer == 0) // Timeout PS2State = PS2START; // Reset data SM } // clock still low } // Kstate 0 // clear the interrupt flag mT4ClearIntFlag(); } // T4 Interrupt

10 Switch switch( PS2State){ default: case PS2START:
if ( !d) // PS2DAT == 0 { KCount = 8; // init bit counter KParity = 0; // init parity check PS2State = PS2BIT; } break; case PS2BIT: KBDBuf >>=1; // shift in data bit if ( d) // PS2DAT == 1 KBDBuf += 0x80; KParity ^= KBDBuf; // calculate parity if ( --KCount == 0) // all bit read PS2State = PS2PARITY; case PS2PARITY: KParity ^= 0x80; if ( KParity & 0x80) // parity odd, continue PS2State = PS2STOP; else PS2State = PS2START; case PS2STOP: KBDCode = KBDBuf; // write in the buffer KBDReady = 1; } // switch

11 InitKBD void initKBD( void) { // init I/Os
ODCGbits.ODCG13 = 1; // make RG13 open drain (PS2clk) _TRISG13 = 1; // make RG13 an input pin (for now) _TRISG12 = 1; // make RG12 an input pin // clear the kbd flag KBDReady = 0; // configure Timer4 PR4 = 25*TPS - 1; // 25 us T4CON = 0x8000; // T4 on, prescaler 1:1 mT4SetIntPriority( 1); // lower priority mT4ClearIntFlag(); // clear interrupt flag mT4IntEnable( 1); // enable interrupt } // init KBD

12 Efficiency Evaluation
void __ISR(..) T4Interrupt( void) { _RA2 = 1; // flag up, inside the ISR <<< Interrupt service routine here >> _RA2 = 0; // flag down, back to the main }

13 Keyboard Buffering A Circular Buffer // circular buffer
unsigned char KCB[ KB_SIZE]; // head and tail or write and read pointers volatile int KBR, KBW;

14 Using the Circular Buffer
Insertion: case PS2STOP: if ( PS2IN & DATMASK) // verify stop bit { KCB[ KBW] = KBDBuf; // write in the buffer // check if buffer full if ( (KBW+1)%KB_SIZE != KBR) KBW++; // else increment ptr KBW %= KB_SIZE; // wrap around } PS2State = PS2START; break; Extraction: int getKeyCode( char *c) { if ( KBR == KBW) // buffer empty return FALSE; // else buffer contains at least one key code *c = KCB[ KBR++]; // extract the first key code KBR %= KB_SIZE; // wrap around the pointer return TRUE; } // getKeyCode

15 KeyCodes Decoding // PS2 keyboard codes (standard set #2)
const char keyCodes[128]={ 0, F9, 0, F5, F3, F1, F2, F12, //00 0, F10, F8, F6, F4, TAB, '`', 0, //08 0, 0,L_SHFT, 0,L_CTRL,'q','1', 0, //10 0, 0, 'z', 's', 'a', 'w', '2', 0, //18 0, 'c', 'x', 'd', 'e', '4', '3', 0, //20 0, ' ', 'v', 'f', 't', 'r', '5', 0, //28 0, 'n', 'b', 'h', 'g', 'y', '6', 0, //30 0, 0, 'm', 'j', 'u', '7', '8', 0, //38 0, ',', 'k', 'i', 'o', '0', '9', 0, //40 0, '.', '/', 'l', ';', 'p', '-', 0, //48 0, 0,'\'', 0, '[', '=', 0, 0, //50 CAPS, R_SHFT,ENTER, ']', 0,0x5c, 0, 0, //58 0, 0, 0, 0, 0, 0, BKSP, 0, //60 0, '1', 0, '4', '7', 0, 0, 0, //68 0, '.', '2', '5', '6', '8', ESC, NUM, //70 F11, '+', '3', '-', '*', '9', 0, //78 }; const char keySCodes[128] = { 0, F10, F8, F6, F4, TAB, '~', 0, //08 0, 0,L_SHFT, 0,L_CTRL,'Q','!', 0, //10 0, 0, 'Z', 'S', 'A', 'W', 0, //18 0, 'C', 'X', 'D', 'E', '$', '#', 0, //20 0, ' ', 'V', 'F', 'T', 'R', '%', 0, //28 0, 'N', 'B', 'H', 'G', 'Y', '^', 0, //30 0, 0, 'M', 'J', 'U', '&', '*', 0, //38 0, '<', 'K', 'I', 'O', ')', '(', 0, //40 0, '>', '?', 'L', ':', 'P', '_', 0, //48 0, 0,'\"', 0, '{', '+', 0, 0, //50 CAPS, R_SHFT,ENTER, '}', 0, '|', 0, 0, //58

16 getc() char getC( void) { unsigned char c; while( 1)
while( !KBDReady); // wait for a key pressed // check if it is a break code while (KBDCode == 0xf0) { // consume the break code KBDReady = 0; // wait for a new key code while ( !KBDReady); // check if the shift button is released if ( KBDCode == L_SHFT) CapsFlag = 0; // and discard it // wait for the next key } // check for special keys CapsFlag = 1; else if ( KBDCode == CAPS) CapsFlag = !CapsFlag; else // translate into an ASCII code { if ( CapsFlag) c = keySCodes[KBDCode%128]; else c = keyCodes[KBDCode%128]; break; } // consume the current character KBDReady = 0; return ( c); } // getC


Download ppt "Chapter 12 Capturing Input"

Similar presentations


Ads by Google