Top Banner
Chapter 12 Chapter 12 Capturing Input Capturing Input
16

Chapter 12 Capturing Input

Jan 16, 2016

Download

Documents

Conner

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) { - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Chapter 12  Capturing Input

Chapter 12 Chapter 12 Capturing InputCapturing Input

Page 2: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

Change Notification ModuleChange Notification Module

Page 3: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

Using CN to Capture Keyboard Using CN to Capture Keyboard InputsInputs

Page 4: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

CN - ISRCN - ISRvoid __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 

Page 5: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

I/O Polling (Timer based)I/O Polling (Timer based)

Page 6: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

I/O Polling State Machine I/O Polling State Machine

Page 7: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

I/O Polling - ISRI/O Polling - ISRvoid __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

Page 8: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

I/O Polling w/TimeoutI/O Polling w/Timeout

Page 9: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

I/O Polling w/Timeout - ISRI/O Polling w/Timeout - ISRvoid __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

Page 10: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

SwitchSwitch 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

Page 11: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

InitKBDInitKBD

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

Page 12: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

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

Page 13: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

Keyboard BufferingKeyboard Buffering

A Circular Buffer

// circular bufferunsigned char KCB[ KB_SIZE]; // head and tail or write and read pointersvolatile int KBR, KBW; 

Page 14: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

Using the Circular BufferUsing 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

Page 15: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

KeyCodes DecodingKeyCodes 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 }; 

Page 16: Chapter 12  Capturing Input

Di Jasio - Programming 32-bit Microcontrollers in C

getc()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