1 / 16

Chapter 12 Capturing Input

Chapter 12 Capturing Input. Change Notification Module. Using CN to Capture Keyboard Inputs. 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) {

conner
Download Presentation

Chapter 12 Capturing Input

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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; break; case PS2PARITY: if ( PS2DAT) // verify parity KParity ^= 0x80; if ( KParity & 0x80) // if parity odd, continue PS2State = PS2STOP; else PS2State = PS2START; break; 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 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 else { // 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 else { // 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; break; case PS2PARITY: if ( d) // PS2DAT == 1 KParity ^= 0x80; if ( KParity & 0x80) // parity odd, continue PS2State = PS2STOP; else PS2State = PS2START; break; case PS2STOP: if ( d) // PS2DAT == 1 { KBDCode = KBDBuf; // write in the buffer KBDReady = 1; } PS2State = PS2START; break; } // 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, 0 //78 }; const char keySCodes[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','!', 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 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, 0 //78 };

  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 KBDReady = 0; // wait for the next key while ( !KBDReady); } // check for special keys if ( KBDCode == L_SHFT) { CapsFlag = 1; KBDReady = 0; } else if ( KBDCode == CAPS) { CapsFlag = !CapsFlag; KBDReady = 0; } 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

More Related