Jump to content
43oh

rampadc

Members
  • Content Count

    141
  • Joined

  • Last visited

  • Days Won

    2

Reputation Activity

  1. Like
    rampadc got a reaction from Fred in Mailbag   
    Sure, they're gonna be used as a substitute for an actual TagConnect TC2050 No Leg connector. Shops in Australia doesn't seem to stock these and shipping from the TC's website increases the total cost of 1 cable to $85, which is quite a bit much. 
     
    I'm using pogo pins model P50-J1 from Aliexpress. The mounting holes of the actual TC2050 has a diameter of 0.991mm. It's very specific and I'm not sure where to get those from so for the time being, I'm getting 0.9mm carbide drill bits for now, which is very cheap in packs of 10 from eBay. If they don't fit into the footprint of a TC2050 snugly enough, maybe some taping would do. Two boards make up 1 adapter. They are stacked vertically to ensure the pins are straight. The two larger holes on the sides are for M3 10mm height standoffs. I shall post some details later if this works out fine.
     
    PS: Just found out about these 0.99mm rods from eBay.
  2. Like
    rampadc got a reaction from bluehash in E-Ink display with bluetooth   
    For EPD displays, Aimonen wrote some instructions on interfacing with the cheap ED060SC4 (http://www.essentialscrap.com/eink/software.html). He discusses different rendering mode and some workarounds for microcontrollers due to their lower clock speed and RAM space. Though keep in mind, he's using a STM32L, which has a lot more RAM space and pins than a G2553 in general.
  3. Like
    rampadc reacted to abecedarian in DIY PCB Cutting Jig   
    "I love the smell of burning fiberglass in the morning."
  4. Like
    rampadc reacted to oPossum in Daylight Saving Time detection and adjustment   
    This code quickly determines if a date is within daylight savings time (DST). A companion function adjusts the date and time if necessary.
     
    There are many ways to determine if a date is within DST. This code begins by checking large time spans (months) and works down to shorter time spans (hours) as necessary. So for most of the year the decision is made very quickly. The worst cases occur on the days of the transition.
     
    BCD representation is used for compatibility with most hardware RTC chips. The day of week (T_RTC.dow) must be set properly for this code to work. Day of week is a value of 1 (Sunday) to 8 (Saturday).
     
     

    typedef struct { // RTC data structure uint8_t sec; // uint8_t min; // uint8_t hour; // uint8_t dow; // uint8_t day; // uint8_t month; // uint8_t year; // } T_RTC; // // Starting in 2007, most of the United States and Canada observe DST from the second Sunday in March to the first Sunday in November int rtc_is_dst(T_RTC const * const rtc) // --- Check if time & date are within DST { // if((rtc->month > 0x03) && (rtc->month < 0x11)) return 1; // After March and before November is DST if((rtc->month < 0x03) || (rtc->month > 0x11)) return 0; // Before March or after November is not DST if(rtc->month == 0x03) { // March if(rtc->day > 0x15) return 1; // After second week, is DST if(rtc->day < 0x08) return 0; // Before second week, is not DST const int d = ((rtc->day >> 4) * 10) + (rtc->day & 0x0F); // Integer day of month int s = d - rtc->dow + 1; // Current or previous Sunday as day of month if(s < 8) s += 7; // Make sure Sunday is in second week if(d < s) return 0; // Before Sunday, is not DST if(d > s) return 1; // After Sunday, is DST if((rtc->hour & 0x3F) < 0x02) return 0; // Before 2:00, is not DST return 1; // 2:00 or after, is DST } else { // rtc->month == 0x11 // November if(rtc->day > 0x07) return 0; // After first week, not DST const int d = ((rtc->day >> 4) * 10) + (rtc->day & 0x0F); // Integer day of month int s = d - rtc->dow + 1; // Current or previous Sunday as day of month if(s < 0) s += 7; // Make sure Sunday is in first week if(d < s) return 1; // Before Sunday, is DST if(d > s) return 0; // After Sunday, is not DST if((rtc->hour & 0x3F) < 0x02) return 1; // Before 2:00, is DST return 0; // 2:00 or after, is not DST } // } // // void rtc_adjust_dst(T_RTC * const rtc) // --- Correct RTC structure for DST if necessary { // static const uint8_t dm[19] = { 0, 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0, 0, 0, 0, 0, 0, 0x31, 0x30, 0x31 }; if(rtc_is_dst(rtc)) { // If DST ++rtc->hour; // Increment hour if((rtc->hour & 0x0F) > 9) rtc->hour += 6; // Adjust for BCD if(rtc->hour > 0x23) { // If next day rtc->hour = 0; // Set hour to 0 ++rtc->dow; // Increment day of week if(rtc->dow > 7) rtc->dow = 1; // Adjust for wrap around ++rtc->day; // Increment day of month if((rtc->day & 0x0F) > 9) rtc->day += 6; // Adjust for BCD if(rtc->day > dm[rtc->month]) { // Check if next month rtc->day = 0x01; // Wrap to first day of next month ++rtc->month; // Increment month if((rtc->month & 0x0F) > 9) rtc->month += 6; // Adjust for BCD } // } // } // } //
  5. Like
    rampadc reacted to bluehash in Scan Interface Applications - Five Members Win A Target Board And An MSP-FET   
    -------------------- Please make sure you are in the list --------------------------------
    I believe I have all entries:
     
    @@abecedarian -: Water supply usage
    @@chicken -------: Resistive touchscreen pattern detector
    @@Fred -----------: Laser cutter coolant and temperature monitor
    @@greeeg --------: Fitness monitor
    @@bobnova -------:Digital tachometer, speedometer, and intelligent shift light.
    @@Automate ------:Single-Point Sensing of Whole-Home Water Activity
    @@pjkim ------------: Speed Controller
     
    @@rampadc, your entry was been withdrawn as per your request. 5 will be selected, 5 get goodies. 1 goes to TI's blog. I'm sure the other's will get special mentions.
  6. Like
    rampadc reacted to bluehash in Scan Interface Applications - Five Members Win A Target Board And An MSP-FET   
    @@rampadc Added your entry to the first post.
  7. Like
    rampadc got a reaction from bluehash in Scan Interface Applications - Five Members Win A Target Board And An MSP-FET   
    Okay, so this is going to be my entry:
     
    An improved central heating controller/interface for my home. The current controller measures the temperature in kitchen and use it to govern the temperature for the rest of the house. It sets the fan speed and temperature based on user input for each day. The current controller is hooked up to the mains and has a RJ-45 connector. What I would like to do is for the 430 to collect temperature data from each room then control fan speed and temperature, I probably will also put in some sort of heat flow diversion mechanism into the tubes so it can control the temperatures a bit better. 
     
    If it's possible, maybe develop apps for phones to switch the heating on/off and input temperatures and fan speed manually. 
  8. Like
    rampadc reacted to SixSixSevenSeven in Altimeter questions.   
    Normally you should factor in the air temperature too but the BMP180 does feature temperature sensing already so you're fine on that front, just needs a slight code alteration. But for your purposes the formula given within the datasheet (which only uses current pressure and a pre-recorded pressure at sea level) should suffice.
    Looking at it, the maths is indeed pretty complex to go from raw pressure data to an altitude.
    Altitude = 44330 * ( 1 - (p/p0) ^ (1 / 5.255))
    Altitude in meters. p = current pressure in hPa (which the sensor returns). p0 = pressure at sea level in hPa.
     
    As it stands right there you have 2 divisions, a multiplication, a subtraction and raising a number to a power, and all in floating point. The G2553 isn't great at maths, it cannot do floating point and instead does it in a much slower software implementation. You can define a constant in your program for 1/ 5.255, then it will only need calculating once and in future the code can fall back on this precalculated value to save time, I'd highly advise that if you were to go down the route of calculating the altitude on the aircraft instead of @@chicken's method.
     
    It apparently takes 7.5ms for the sensor itself to get a reading, so your MSP430 does have that long to calculate an altitude if you really want to and you probably don't need to retrieve the altitude at much more than 1 or 2Hz anyway. The maths will be slow, but you don't need it to be executed particularly fast.
    There is this thing in embedded electronics on whether or not you need to optimise your code for fastest performance, smallest memory footprint or "pure accuracy" (or a better way of saying neither). All depends on the application. I'd say the memory footprint of this thing will be small anyway leaving you with speed vs accuracy. Upto you.
     
    Oh, very good writeup on maths on microcontrollers and processors in general here: http://letsmakerobots.com/content/help-your-robot-do-its-math-homework
  9. Like
    rampadc reacted to jpnorair in Oversampling, averaging and getting confused.   
    In radio modulation, which is a course of study with a mountain of research behind it, there is this thing called SNR (signal to noise ratio).  If I decrease the data rate, not only do I increase the amount of energy per bit (the bit is longer, hence it is a bigger pulse), but I also can reduce the amount of noise because the signal is narrower.  So I get bigger SNR.
     
    This is like increasing the duration of the sample.  For the most part, it works great.
     
    In certain cases, however, you will find that there is *frequency dependent interference*.  In other terms, spurious readings you can't avoid, no matter how hard you try.  In RF there is this thing called DSSS (direct sequence spread spectrum) which is really just a way to do controlled sampling and averaging.  However, DSSS has been studied deeply.  Amazingly, it seems to work better than does decreasing the data rate, despite the free space advantage of the latter.  This is simply an artifact of the *real world.*  Granted, DSSS is not simply averaging, it is correlation, but the idea is the same.
     
    Anyway, two cents.
  10. Like
    rampadc got a reaction from abecedarian in Scan Interface Applications - Five Members Win A Target Board And An MSP-FET   
    These can probably be done cheaper using other microcontrollers but how about:
     
    1. Absolute positioning servomotors with hobby brushless motors 
    2. Another smart thermostat, the controller unit that came with my house's heater is doesn't handle temperatures in different rooms very well. The right side of the house is always hotter than the left side.
  11. Like
    rampadc reacted to ILAMtitan in Vetinari's Clock   
    I figured you guys might be interested in some of my tinkering with the Launchpad.  Hopefully by putting a few of my projects up here it will also keep me accountable for finishing them.
     
    This is one a cobbled together a few months ago.  It's been up on the MCU projects page on E2E, so you might have already seen it: http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/664670.aspx
     
     
    PROJECT OVERVIEW
    The Vetinari clock is from a book series known as Discworld, where Lord Verinari has a clock in his waiting room which has an irregular tick. The idea of the clock is to add a sense of unease and anxiety to anyone in the waiting room since their brain doesn't filter out the ticks like a normal clock. Here's a video to get a better idea of the result.  The tick is actually a lot louder in person.
     


     
    SOFTWARE DESIGN
    To accomplish this task on a 430, we create an array of possible time frames to tick the clock, and parse through it at 4Hz. The array is 32 entries long, so it equates to 32 seconds in the real world. By randomly setting 32 of the elements high, we create a timing sequence. A high element will generate a tick of the clock. This means a second on the clock can be as little as 250ms, or as long as 24 seconds, and still keep accurate time.  Check the attached software too see how it's all done; I did my best to comment it up.  main.c
     
    HARDWARE DESIGN
    The clock coil is driven via an alternating polarity pulse.  The easiest way to change a load's polarity with an MCU is using an h-bridge.
     

     
    The schematic shown is a simple implementation using two NPN and two PNP transistors.  I had the transistors and drive resistors laying around, so this part was easy to cobble together (along with the half used battery holder).  It would be easy to use a single IO pin per side of the bridge, but the transistors fit better onto the launchpad, as shown in the image.  To add the driving resistors in series, I cut a small gap in the traces, scrapped off the solder mask on either side to make pads, and put down a small SMA resistor.  It's not pretty, but it works.
     

     
    In the clock mechanism, there is a small control board with a crystal and epoxy glob IC that normally runs the clock.  I just ripped that out and directly attached the coil to the h-bridge.
     

     
    The resulting clock is actually more maddening than I expected in a quiet environment.  By using 3V rather than the 1.5V that the original movement used, the ticks are much more pronounced and do an excellent job of ruining a person's calm.
  12. Like
    rampadc reacted to jpnorair in F550x Breakout Boards   
    BTW: I have a handful of MSP430F5503's in the QFN48... 50 I think.  I'll sell the lot for $100 if you are interested.
     
     
    The best-practice here is to put a 100nF cap next to each Vcc pin to suppress voltage transients.  You can additionally put the 4.7uF cap near any one of the Vcc input pins.
     
    Near AVcc, sometimes they like you to provide an additional capacitance for noise suppression.  It should be near the AVcc pin.
  13. Like
    rampadc got a reaction from reaper7 in F550x Breakout Boards   
    Yup... and that one looks a lot better too.
     
    Regarding DVCC, AVCC, do you know why there are so many capacitors between them? (Schematic from the page)
     

  14. Like
    rampadc got a reaction from tingo in F550x Breakout Boards   
    Here you go: http://flashandrc.wordpress.com/2014/06/07/thinkpad-keyboard-project-its-over/ and http://www.instructables.com/id/A-Better-ThinkPad-USB-Keyboard-Adapter/?ALLSTEPS.
     
    And RobG helped me with the caps questions so no worries. 
  15. Like
    rampadc got a reaction from reaper7 in Mailbag   
    High resolution is quite hard to get with my phone camera
    :
     
    and here's a close-up on the QFN pad: 

  16. Like
    rampadc got a reaction from jazz in Mailbag   
    High resolution is quite hard to get with my phone camera
    :
     
    and here's a close-up on the QFN pad: 

  17. Like
    rampadc got a reaction from jazz in Mailbag   
    PCBs from DirtyPCB.com arrive today. It's just like Elecrow, but $2 cheaper.
     

  18. Like
    rampadc reacted to RobG in Program data at a fixed location   
    That's because F5510's memory starts at 0x8000 and F5502's at 0xA000
    Try this:
    //F5510 #pragma LOCATION(m1, 0x8000); #pragma LOCATION(m2, 0x8080); //F5502 #pragma LOCATION(m1, 0xA000); #pragma LOCATION(m2, 0xA080); If you want something universal for all F550x chips, you can use 0xF000. Your out file will then look similar to this:
    @8000 2A 14 3F 40 00 00 3F 90 01 00 23 28 3F 40 00 00 3F 90 01 00 1E 28 3A 40 00 00 3A 80 00 00 3A 50 ... ... F8 23 10 01 32 D0 10 00 FD 3F 1C 43 10 01 03 43 FF 3F @f000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ... ... E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF @ffd2 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 D4 80 A4 80 q
  19. Like
    rampadc reacted to Gulam in Project f-Spell: Now you can type even without Keyboard!   
    It all started with an aim of improving communication between speech & hearing impaired and normal people. But it has now almost become an alternative input device for any computing device!
     
    So what is it all about? It's a cyber glove that recognizes sign language gestures and convert them into ASCII. Voila! We can throw away our keyboards and start using this glove. Right? After all, our keyboard does the same thing.
     
    Don't try too hard to visualize this peculiar device! This is how it will be!!
     

    And Technically it will be something like this
     
    And more technically the flow of data will be like this

     
     
    Got a overall picture? Okay. Let's see how this is implemented. The sensor boards which are mounted on the finger tips is a custom PCB (see attachements schema_acc_board.png & pcb_footprint_acc_board.pdf) which houses the accelerometer (in our case MMA7361L). Those accelerometers will be connected MSP430 Launchpad and Launchpad will then be connected to Bluetooth Module as shown below. (BT boosterpack from iTeadStudio is used here)
     

     
    Wondering why not all axes of accelerometers are utilized? Well we have to do some trade-off between resolution and no. of ADC channels available :-( 
     
    That's all. Find the code as attachment (code.zip)
     
    Here are few pics of the setup & output...
     
     
     



     
    Attempts have been made to miniaturize the whole setup into one glove. The FET Debugger is not able to recognize the custom board. But I'm not sure whether the problem is with Schema or PCB footprint.  I've attached the unverified schema and footprint also with this post. Interested are welcome to give a try! If you come up with a better design you are welcome to share it with me at any time ;-)
     
     
    pcb_footprint_acc_board.pdf

    code.zip
    pcb_1_NOT_VERIFIED.pdf
    pcb_2_NOT_VERIFIED.pdf
    pcb_3_NOT_VERIFIED.pdf
    schema_NOT_VERIFIED.pdf
  20. Like
    rampadc got a reaction from bluehash in MSP430G2553 MicroSD .wav Music Player   
    @chicong Pretty sure this is an English forum. Pin 1 on your SD card would be the CD pin in his setup. (Google Translate)
     
    http://elasticsheep.com/2010/01/reading-an-sd-card-with-an-atmega168/
     
    Sent from my Nexus 7 using Tapatalk
     
     
  21. Like
    rampadc got a reaction from igor in PS/2 Mouse for any MSP430   
    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); }
  22. Like
    rampadc got a reaction from bluehash in PS/2 Mouse for any MSP430   
    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); }
  23. Like
    rampadc reacted to Rickta59 in New Tool for Code Composer and MSP430   
    http://i.imgur.com/25aVQTB.png
     
    http://processors.wiki.ti.com/index.php/MSP430_FAQ#How_to_find_out_the_memory_size_of_the_MSP430_application_in_CCSTUDIO.3F
  24. Like
    rampadc got a reaction from bluehash in Mailbag   
    Revision 5 of my ThinkPad T6x keyboard adapter First time ordered from Elecrow. The routing is probably pretty bad, it works so far. I probably need to downsize those vias.
     
  25. Like
    rampadc got a reaction from LariSan in New MSP430F5529 USB Launchpad Released   
    Did you guys notice TI's selling their new MSP430F5529 USB Launchpad board? I found an old announcement back in 2012 on 43oh main page that TI's working on it but haven't seen any on it being sold. I just found out today and apparently it's sold out. :-(
     
    TI also changed the descriptor tool by making the interface a bit prettier but they removed the definition USB_MCLK_FREQ which will break all the code in their last USB API so now there's a new USB API 4.0 that requires CCS 5.5 to be installed, though there are workarounds so it will work with existing CCS. 
×
×
  • Create New...