+ All Categories
Home > Documents > Chapter 12 Capturing Input. Di Jasio - Programming 32-bit Microcontrollers in C Change Notification...

Chapter 12 Capturing Input. Di Jasio - Programming 32-bit Microcontrollers in C Change Notification...

Date post: 01-Apr-2015
Category:
Upload: ean-eckley
View: 219 times
Download: 1 times
Share this document with a friend
Popular Tags:
16
Chapter 12 Chapter 12 Capturing Input Capturing Input
Transcript
Page 1: Chapter 12 Capturing Input. Di Jasio - Programming 32-bit Microcontrollers in C Change Notification Module.

Chapter 12 Chapter 12 Capturing InputCapturing Input

Page 2: Chapter 12 Capturing Input. Di Jasio - Programming 32-bit Microcontrollers in C Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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 Change Notification Module.

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


Recommended