Jump to content

Search the Community

Showing results for tags 'keyboard'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • News
    • Announcements
    • Suggestions
    • New users say Hi!
  • Spotlight!
    • Sponsor Spotlight
    • Sponsor Giveaways
  • Energia
    • Energia - MSP
    • Energia - TivaC/CC3XXX
    • Energia - C2000
    • Energia Libraries
  • MSP Technical Forums
    • General
    • Compilers and IDEs
    • Development Kits
    • Programmers and Debuggers
    • Code vault
    • Projects
    • Booster Packs
    • Energia
  • Tiva-C, Hercules, CCXXXX ARM Technical Forums
    • General
    • SensorTag
    • Tiva-C, Hercules, CC3XXX Launchpad Booster Packs
    • Code Vault
    • Projects
    • Compilers and IDEs
    • Development Kits and Custom Boards
  • Beagle ARM Cortex A8 Technical Forums
    • General
    • Code Snippets and Scripts
    • Cases, Capes and Plugin Boards
    • Projects
  • General Electronics Forum
    • General Electronics
    • Other Microcontrollers
  • Connect
    • Embedded Systems/Test Equipment Deals
    • Buy, Trade and Sell
    • The 43oh Store
    • Community Projects
    • Fireside Chat
  • C2000 Technical Forums
    • General
    • Development Kits
    • Code Vault
    • Projects
    • BoosterPacks

Calendars

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Location


Interests


Sparkfun


Github

Found 3 results

  1. I am looking to get the MSP430F5529 to act as a usb keyboard using Energia interface. It is supported in hardware but I haven't seen any supporting libraries.
  2. Strangely enough, there aren't a lot of PS/2 mouse codes available for MSP430. The following code allows you to communicate with your PS/2 mouse by remote mode and stream mode (require interrupts). TrackPoint is a mouse module used in ThinkPad keyboards. It uses the PS/2 protocol with some proprietary commands. Keyboards are pretty much the same as mouse, only their reports are simpler. PS2.h /* * PS2.h * * Created on: 14/11/2013 * Author: CONG (rampADC) */ #ifndef PS2_H_ #define PS2_H_ #include "msp430.h" #include "stdint.h" //4MHz XT2 #define delay_us(x) __delay_cycles(x * 4) #define CLOCK 0xCC #define CLOCK_DIR P4DIR #define CLOCK_OUT P4OUT #define CLOCK_IN P4IN #define CLOCK_REN P4REN #define CLOCK_IFG 0 #define CLOCK_IE 0 #define CLOCK_IES 0 #define CLOCK_PIN BIT7 #define DATA 0xDA #define DATA_DIR P4DIR #define DATA_OUT P4OUT #define DATA_IN P4IN #define DATA_REN P4REN #define DATA_PIN BIT6 #define RESET 0xEE #define RESET_DIR P4DIR #define RESET_OUT P4OUT #define RESET_PIN BIT5 #define REMOTE_MODE 0xF0 #define STREAM_MODE 0xEA #define RESET_MODE 0xFF #define READ_DATA 0xEB #define DISABLE_REPORT 0xF5 #define SET_DEFAULTS 0xF6 #define ENABLE_REPORT 0xF4 #define SET_SAMPLE_RATE 0xF3 #define GET_ID 0xF2 #define STATUS_REQUEST 0xE9 #define SET_RESOLUTION 0xE8 #define SET_SCALING_2 0xE7 #define SET_SCALING_1 0xE6 #define TIMING_ERROR 50000 #define LOW 0 #define HIGH 1 typedef struct { uint8_t state; int8_t x; int8_t y; } PS2Data_t; typedef struct { uint8_t state; int8_t x; int8_t y; int8_t z; } USB_MOUSE_REPORT_t; void PS2_initialize(void); void PS2_transmit(uint8_t data); uint8_t PS2_receive(void); uint8_t PS2_getBit(); uint8_t PS2_setMode(uint8_t mode); PS2Data_t PS2_getData(void); void PS2_setupClockLine(void); int PS2_dataAvailable(void); PS2Data_t PS2_streamGetData(void); USB_MOUSE_REPORT_t PS2_getUSBReport(void); //trackpoint specific void Trackpoint_writeToRAM(uint8_t location, uint8_t data); void Trackpoint_setSensitivity(uint8_t sensitivityFactor); #endif /* PS2_H_ */ PS2.c /* * PS2.c * * Created on: 14/11/2013 * Author: CONG (rampADC) */ #include "PS2.h" #include "string.h" #include "..///printf.h" void setLine(uint8_t, uint8_t); uint8_t readLine(uint8_t); static int dataAvailable = 0; static int counter = 0; static PS2Data_t ps2MouseData; static USB_MOUSE_REPORT_t usbMouseData; static volatile uint8_t bitcount = 0; static volatile uint8_t incoming = 0; static volatile uint8_t incomingParity = 0; static volatile uint8_t onesCounter = 0; static volatile uint8_t calculatedParity = 0; static volatile uint8_t parityOk = 0; static volatile uint8_t parityChecks[3] = {0,0,0}; uint8_t n, val; USB_MOUSE_REPORT_t PS2_getUSBReport(void) { ps2MouseData = PS2_getData(); usbMouseData.x = ps2MouseData.x; usbMouseData.y = -ps2MouseData.y; //by default, ps/2 mouse y-value is opposite to direction moving to usbMouseData.state = ps2MouseData.state & 0x07; //only least significant three bits are transferred //use middle button to scroll if(ps2MouseData.state & BIT2) { usbMouseData.z = ps2MouseData.y; } return usbMouseData; } int Trackpoint_isConnected(void) { PS2_transmit(0xE1); //read secondary data if(PS2_receive() != 0x01) return 0; //first byte needs to always be 0x01 uint8_t secondByte = PS2_receive(); //assuming there will be newer revisions, let's second byte may not be important return 1; } void Trackpoint_writeToRAM(uint8_t location, uint8_t data) { //refer to "Trackpoint System Version 4.0 Engineering Specification" pg. 20 PS2_transmit(0xE2); PS2_receive(); //ACK PS2_transmit(0x81); PS2_receive(); //ACK PS2_transmit(location); PS2_receive(); //ACK PS2_transmit(data); PS2_receive(); //ACK } void Trackpoint_setSensitivity(uint8_t sensitivityFactor) { Trackpoint_writeToRAM(0x4A, sensitivityFactor); } int PS2_dataAvailable(void) { if(dataAvailable) return 1; else return 0; } PS2Data_t PS2_streamGetData(void) { return ps2MouseData; } void PS2_initialize(void) { //printf("Initializing...\r\n"); setLine(CLOCK, HIGH); setLine(DATA, HIGH); //printf("Clock, data idle\r\n"); } void PS2_transmit(uint8_t data) { //printf("Transmitting: %x\r\n",data); uint8_t parity = 1; // uint8_t data_bak = data; uint8_t i; setLine(DATA, HIGH); setLine(CLOCK, HIGH); delay_us(300); setLine(CLOCK, LOW); delay_us(300); setLine(DATA, LOW); delay_us(10); setLine(CLOCK, HIGH); while(readLine(CLOCK) == HIGH); for(i = 0; i < 8; i++) { if(data & BIT0) { setLine(DATA, HIGH); } else { setLine(DATA, LOW); } while(readLine(CLOCK) == LOW); while(readLine(CLOCK) == HIGH); parity ^= (data & BIT0); data >>= 1; } if(parity) { setLine(DATA, HIGH); } else { setLine(DATA, LOW); } while(readLine(CLOCK) == LOW); while(readLine(CLOCK) == HIGH); setLine(DATA, HIGH); delay_us(50); while(readLine(CLOCK) == HIGH); while(readLine(CLOCK) == LOW || readLine(DATA) == LOW); setLine(CLOCK, LOW); //printf("Host: %x\r\n",data_bak); } //Get incoming data bit during interrupt caused by CLOCK change uint8_t PS2_getBit(void) { parityOk = 0; dataAvailable = 0; val = ((DATA_IN & DATA_PIN) ? 1 : 0); n = bitcount-1; if(n <= 7) { incoming |= (val << n); if(val) onesCounter++; } else if(n == 8) { incomingParity = val; } bitcount++; if(bitcount == 11) { if(onesCounter % 2) { calculatedParity = 0; //not divisible by 2 thus ODD, keep it odd (odd parity) } else { calculatedParity = 1; } if(calculatedParity == incomingParity) { parityOk = 1; } switch(counter) { case 0: parityChecks[0] = parityOk; ps2MouseData.state = incoming; counter++; break; case 1: parityChecks[1] = parityOk; ps2MouseData.x = incoming; counter++; break; case 2: parityChecks[2] = parityOk; ps2MouseData.y = -incoming; counter = 0; if(parityChecks[0] && parityChecks[1] && parityChecks[2]) dataAvailable = 1; //reset parities memset(&parityChecks, 0, 3); break; } bitcount = 0; incoming = 0; onesCounter = 0; calculatedParity = 0; incomingParity = 0; parityOk = 0; } return val; } uint8_t PS2_receive(void) { //printf("Receiving...\r\n"); uint8_t data = 0; uint8_t i; uint8_t bit = 0x01; setLine(CLOCK, HIGH); setLine(DATA, HIGH); delay_us(50); while(readLine(CLOCK) == HIGH); delay_us(5); while(readLine(CLOCK) == LOW); for(i = 0; i < 8; i++) { while(readLine(CLOCK) == HIGH); if(DATA_IN & DATA_PIN) { data |= bit; } while(readLine(CLOCK) == LOW); bit <<= 1; } while(readLine(CLOCK) == HIGH); while(readLine(CLOCK) == LOW); while(readLine(CLOCK) == HIGH); while(readLine(CLOCK) == LOW); setLine(CLOCK, LOW); //printf("Mouse: %x\r\n",data); return data; } /* * Comment out when clock line does support interrupts */ void PS2_setupClockLine(void) { //setup interrupts CLOCK_DIR &= ~CLOCK_PIN; //set direction to input CLOCK_REN |= CLOCK_PIN; //enable pull-up CLOCK_OUT |= CLOCK_PIN; //enable pull-up CLOCK_IES |= CLOCK_PIN; //falling CLOCK_IFG &= ~CLOCK_PIN; //interrupt flag cleared CLOCK_IE |= CLOCK_PIN; //interrupt enable for clock } uint8_t PS2_setMode(uint8_t mode) { uint8_t success = 0; switch(mode) { case REMOTE_MODE: PS2_transmit(REMOTE_MODE); PS2_receive(); break; case STREAM_MODE: //setup mouse PS2_transmit(STREAM_MODE); PS2_receive(); PS2_transmit(ENABLE_REPORT); PS2_receive(); break; case RESET_MODE: //TrackPoint has a reset pin, need to use it. RESET_OUT |= RESET_PIN; RESET_DIR |= RESET_PIN; delay_us(2000000); RESET_OUT &= ~RESET_PIN; //For normal PS/2 devices, this should be enough PS2_transmit(RESET_MODE); PS2_receive(); PS2_receive(); PS2_receive(); break; } return success; } PS2Data_t PS2_getData(void) { PS2_transmit(READ_DATA); PS2_receive(); ps2MouseData.state = PS2_receive(); ps2MouseData.x = PS2_receive(); ps2MouseData.y = PS2_receive(); return ps2MouseData; } //private functions uint8_t readLine(uint8_t line) { if(line == CLOCK) { if(CLOCK_IN & CLOCK_PIN) { return 1; } else { return 0; } } else { if(DATA_IN & DATA_PIN) { return 1; } else { return 0; } } } void setLine(uint8_t line, uint8_t state) { if(line == CLOCK) { if(state == LOW) { CLOCK_DIR |= CLOCK_PIN; //set direction to output CLOCK_OUT &= ~CLOCK_PIN; //set output to low } else { CLOCK_DIR &= ~CLOCK_PIN; //set direction to input CLOCK_REN |= CLOCK_PIN; //enable pull-up CLOCK_OUT |= CLOCK_PIN; //enable pull-up } } else { if(state == LOW) { DATA_DIR |= DATA_PIN; //set direction to output DATA_OUT &= ~DATA_PIN; //set output to low } else { DATA_DIR &= ~DATA_PIN; //set direction to input DATA_OUT |= DATA_PIN; //enable pull-up DATA_REN |= DATA_PIN; //enable pull-up } } } To use this, you need to: Change CLOCK and DATA ports definitions in PS2.h. I have attempted to use pointers but it was too messy. Comment PS2_setupClockLine() if your clock line does not support interrupt. Use an accurate clock. PS/2 timing is strict. Change the delay multiplier accordingly to your clock frequency. I am still finding a way so the compiler automatically substitute in the correct value. #define delay_us(x) __delay_cycles(x * 4) //4MHz is used in PS2.h. Find this line, and change it the number '4' if needed. Test code: UART Remote mode - works great. Tested with oPossum's tiny printf code. In this example, I am using an external 4MHz crystal. Tested with MSP430F5510 #include <msp430.h> #include "PS2.h" #include "Printf.h" void initClocksXT2(void); void initUART(void); static USB_MOUSE_REPORT_t data; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer initClocksXT2(); initUART(); PS2_initialize(); PS2_setMode(RESET_MODE); PS2_setMode(REMOTE_MODE); while(1) { data = PS2_getUSBReport(); printf("x: %i, y: %i, z: %i, LMR: %i%i%i\r\n",data.x,data.y,data.z,data.state & BIT0,data.state & BIT2,data.state & BIT1); } } void initClocksXT2(void) { ///XT2 as MCLK and SMCLK P5SEL |= BIT2+BIT3; // Port select XT2 UCSCTL6 &= ~XT2OFF; // Enable XT2 UCSCTL3 |= SELREF_2; // FLLref = REFO // Since LFXT1 is not used, // sourcing FLL with LFXT1 can cause // XT1OFFG flag to set UCSCTL4 |= SELA_2; // ACLK=REFO,SMCLK=DCO,MCLK=DCO // Loop until XT1,XT2 & DCO stabilizes - in this case loop until XT2 settles do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~XT2DRIVE0; // Decrease XT2 Drive according to // expected frequency UCSCTL4 |= SELS_5 + SELM_5; // SMCLK=MCLK=XT2 } void initUART() { //4MHz 9600 P4SEL = BIT4; UCA1CTL1 |= UCSWRST; // **Put state machine in reset** UCA1CTL1 |= UCSSEL_2; // SMCLK UCA1BR0 = 0xA0; UCA1BR1 = 0x01; UCA1MCTL = UCBRS_5 + UCBRF_0; // over sampling UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** } UART - Stream mode. Tested on the MSP430F5529LP. Using crystal as clock source. #include <msp430.h> #include "Printf.h" #include "PS2.h" PS2Data_t mouseData; uint8_t left = 0; uint8_t mid = 0; uint8_t right = 0; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer //Testing pins P1OUT &= ~BIT0; P1DIR |= BIT0; P6OUT &= BIT5; P6DIR |= BIT5; P3OUT &= ~BIT4; P3DIR |= BIT4; initClocks(); //code stored in another file. just XT2 at 4MHz initUART(); //code stored in another file. 4MHz at 9600 baud. PS2_initialize(); PS2_setMode(RESET_MODE); PS2_setMode(STREAM_MODE); PS2_setupClockLine(); //set up interrupt on clock line printf("UART's working fine\r\n"); while(1) { //_BIS_SR(LPM0_bits + GIE); if(PS2_dataAvailable()) { left = PS2_streamGetData().state & BIT0 == BIT0; right = PS2_streamGetData().state & BIT1 == BIT1; mid = PS2_streamGetData().state & BIT2 == BIT2; printf("LEFT: %i, MID: %i, RIGHT: %i ", left, mid, right); printf("(%i, %i)\r\n", PS2_streamGetData().x, PS2_streamGetData().y); } } } //CLOCK on P1.4 #pragma vector = PORT1_VECTOR __interrupt void P1ISR(void) { if(CLOCK_IFG & CLOCK_PIN) { PS2_getBit(); CLOCK_IFG &= ~CLOCK_PIN; //_BIC_SR_IRQ(LPM0_bits); } } This PS/2 stream code does not work well with USB. Synchronization errors appears. I am still trying to fix this. Use PS2_getUSBReport() to get the report needed for a USB HID mouse. UPDATE 11/03/2014 To use remote mode with USB, put the mouse reading-report-converting block into a timer interrupt block and set the timer to interrupt I'd say at least 6ms, which is the time it takes for the PS/2 mouse to communicate with my 430 chip. My PS/2 mouse clock operates at 14kHz. Yours may range from 10kHz to 16kHz so increase the time interval if it doesn't work. Better yet, probe it with a logic analyzer to determine the time. void initTimers() { //set TA0CCR0 to time 7ms, assuming 4MHz clock TA0CCR0 = 27999; //ENABLE CAPTURE/COMPARE INTERRUPT (FOR WHEN TA0CCR0 IS REACHED) TA0CCTL0 = CCIE; //SMCLK, UP, /1 TA0CTL = TASSEL_2 + MC_0 + ID_0; //stop it first } case ST_ENUM_ACTIVE: PS2_setMode(RESET_MODE); PS2_setMode(REMOTE_MODE); Trackpoint_setSensitivity(0xC0); TA0CTL |= MC_1; //start timer while(1) { __bis_SR_register(LPM0_bits + GIE); } break; #pragma vector = TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) { ps2Data = PS2_getData(); usbData.x = ps2Data.x; usbData.y = -ps2Data.y; //by default, ps/2 mouse y-value is opposite to direction moving to usbData.state = ps2Data.state & 0x07; //only least significant three bits are transferred //use middle button to scroll if(ps2Data.state & BIT2) { usbData.z = ps2Data.y; } USBHID_sendReport((void *) &usbData, HID_MOUSE); }
  3. i have been sucessful(somewhat) in interfacing a PS2 keyboard with MSP430. usually for about ~25 keystrokes it works perfectly. after that parity error occurs in data and data after the corrupt-data is also corrupt. im supply keyboard 5V from external source and using POT to convert 5V to 3V. communication with keyboard is at 20-25Khz and MSP430 is running at 16Mhz. thing i tried (and didnt worked :-( ): tried another keyboard. circular queue to store temp data and then timer A1 to extract and decode. note: if im able to get first n data's then why is their a problem after that. im having 4 more interrupts going on (usci0_rx (@ 9600 baud, 4Mhz), usci_tx, timerA0 ( @ 7Hz), timerA1 ( @ 500Khz )). i have a MSP430G2553IN2. text data bss dec hex filename 6604 6 342 6952 1b28 build/diy-vt100.elf total code(see below) is in diy-vt100.tar.gz i had to remove doc/ , .git/ (size was ~100MB's) schematics are not according to project right now. ps2-scancode-en.c ps2.c port2.c port2.h ps2.h diy-vt100.tar.gz
×
×
  • Create New...