Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
snickersnee
PostPosted: Feb 08, 2011 - 05:37 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


The attached Codevision code is for an Atmega32a-based accelerometer mouse that interfaces to the computer via PS/2 protocol. (Notice this is not PlayStation2, it's this: http://www.computer-engineering.org/ps2protocol/)
I have been able to show that the ADC portion works, which is dataFromMouse(), however I'm still not getting any mouse movement. All the outputs of the uC remain at +5V (idle state) all the time.
I honestly don't have a clue where to start debugging this huge program, other than putting LED lighting commands in strategic places. If anyone has any prior experience with this, I would greatly appreciate any suggestions on how to approach this.
Thanks in advance.

I've attached the file with the code, as well as the schematic.
Some differences in my setup:
* Instead of a crystal, I'm using int.RC 8 MHz.
* Not using the buffers.
* AREF has a 100nF capacitor to GND

Also I should mention I don't have an LCD, though there's code for it.
I got a PS/2 cable from an old mouse and am using it to go directly from the uC to the computer. (I don't think the cable is the problem, I made sure the mouse worked before I cannibalized it.) I was able to match the wires to the pins. No converter should be needed in this case. This is an HID device and the Windows built-in driver is supposed to recognize it.
When I google, all I get is PlayStation2, unfortunately that's not what I'm looking for. Confused

(As an aside, when I click on the Msg Icon or Smiles buttons under the quick reply box, I get a window that says "Hacking attempt1".)
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 01:56 AM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Here is my understanding of what this code is supposed to do. Rather than regular PS/2, which has 3-byte packets, this uC is emulating a Microsoft Intellimouse, with 4-byte packets. Packet is shown here:
http://www.microsoft.com/whdc/archive/mcompat.mspx#ECF

A PS/2 byte has 11 bits:
0 - - - - - - - - 1
start,(8 bits of data, LSB first),stop

Rx/Tx: 4 states

(1) Idle: outputs float high
(This is where I'm stuck at, all the time)
*Mouse has something to send? Go to (2)

(2) Busy: -set flags (Rx or Tx)
-Host inhibit: pull clk low for >100 us
(clk period=80us, that is, 12.5 kHz)
* Mouse checks for this condition by seeing if clk. output is high but reading low. If true, go to (3)

(3) Inhibit: -Stop all xmit
-clk,data=1
-(If byte interrupted, resend later)
*Host request to send (pull data line low after inhibit; this tells the mouse to start the clock (high first)). Go to (4)

(4) Request: -will go back to Busy in 1 clock cycle
-Clock low: host send PS/2 byte (11 bits)
-High: mouse send ACK (0xFA) after stop bit
-Low: Host reads ACK

* State changes are caused by timer 1 interrupt.
 
 View user's profile Send private message  
Reply with quote Back to top
kk6gm
PostPosted: Feb 09, 2011 - 03:34 AM
Raving lunatic


Joined: Sep 12, 2009
Posts: 2655
Location: Sacramento, CA

As a general approach, I'd write the simplest code possible to output some fixed mouse movement (e.g. up and to the left, repeat). Get that working before moving on to anything else.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 09, 2011 - 04:09 AM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

snickersnee where'd you get the code / circuit from ( No access to explanation of the design ? ) ? You're trying to build a PS/2 mouse from the ground up ? HOW do you KNOW this design even works ?

Like I said in your previous topic, you can't debug if you don't understand it. So ask yourself how much of this code you get,and verify it works up to there. Understand it step by step. I'd get the usart code to work so you can confirm correct PS/2 codes are generated before hooking up to PS/2 port.

There's a PS/2 KEYBOARD effort in pjt. forum. Atmel has app. notes on this.

May help:
http://instruct1.cit.cornell.edu/course ... index.html

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 03:14 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Quote:
I'd get the usart code to work


There's usart code in it? I didn't see that

Let me find where I got the code from, hold on.

The hardware design is an open-collector interface as discussed in the link in my first post. However, this version is simplified; instead of transistors, it uses 600 ohm resistors.
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 04:52 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Here's the page where the code/circuit are from:


http://courses.cit.cornell.edu/ee476/FinalProjects/s2004/cel27/ece476web2/index.html
 
 View user's profile Send private message  
Reply with quote Back to top
MurMan
PostPosted: Feb 09, 2011 - 05:23 PM
Hangaround


Joined: Jan 14, 2011
Posts: 156


snickersnee wrote:
There's usart code in it? I didn't see that.
The usart is implemented in code. (Hardware usart isn't used.)

Look at the ISR clockGenNrecvNtrans(void) and you'll see the data clocked out on DATA_OUT, defined as PORTD.6.

Take the advice from IndianaJones. You really need to understand how this code works in order to debug it.

Your idea of using spare pins to give debug info is good, but you'll need to manage the flash duration if you want to see the LED flash. If you have a logic probe with pulse detection, you could turn a pin on then off immediately without regard for duration.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 09, 2011 - 06:07 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

Sorry about the uart ref. ( ok it's code to emulate the PS/2's DATA / CLK ), then use the lcd to verify vars.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
Lennart
PostPosted: Feb 09, 2011 - 06:40 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2758
Location: Sweden

Having a scope to reveal what's happening on the data and clock lines would help.
If you don't have one this might be an easy way to get a good enough one for your needs.
http://www.zeitnitz.de/Christian/scope_en
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 07:24 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Port D.1 (output clock) is also the TXD pin for the USART, but I don't see any USART initialization such as UBRR, UCSRB, etc. That's why I'm confused that you guys keep talking about USART.


Quote:
use the lcd to verify vars


I noticed the lcd code commented out...Ordered one, don't have it yet.
 
 View user's profile Send private message  
Reply with quote Back to top
Jepael
PostPosted: Feb 09, 2011 - 08:22 PM
Raving lunatic


Joined: May 24, 2004
Posts: 6275
Location: Tampere, Finland

Are you sure you got the data transfer directions right? When you describe your state machine, it looks like what the HOST does, not the MOUSE. A bit. It is confusing.

Okay, first of all, the mouse should report only standard 3-byte packets, unless the HOST sends the mouse the correct magic sequence which the mouse recognises and switches to the extended 4-byte protocol.

But even before that, mouse should be in a mode it will not transmit movement packets, unless it receives a command that allows it to enable movement packet transmissions.

Nevertheless, 3 or 4 byte responses from mouse, bytes are sent alike.

1) if both lines are high, mouse can start transmission if there is something to send. Mouse is always the device that drives the clock pulses to transmit bits, no matter which direction the bits are transmitted.

2) if HOST pulls clock low, then, mouse is not able to start transmission until HOST lets clock high again. This is the inhibit state.

3) if HOST pulls data low, it is a sign of request and then mouse must start clocking data out from the host.

Now there is a catch, the HOST may just do a request by setting data pin low without inhibit, or, it may first set clock low to inhibit mouse, then set data low, and release clock, so the mouse sees request when coming out of inhibit mode.

And also I honestly don't understand why put 600 ohm resistors there. It will work without any series resistors, or to be safe, something max 100 ohms should be put there. Pulling the clock/data lines through 600 ohms may not be strong enough to pull the voltage to sane logic low level of about 0.6V.

Speaking of logic levels, what kind of pull-ups you have on the clock/data lines (if any?). If you have something between 2k and 15k you should be fine.

Are you sure you drive the clock and data pins in open-collector mode, not push-pull mode? You are never ever allowed to set the pins as high outputs, only inputs or low outputs.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 09, 2011 - 09:21 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

OP wrote:
That's why I'm confused that you guys keep talking about USART.
NO USART code after all, see my previous post.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 09:53 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Lennart wrote:
Having a scope to reveal what's happening on the data and clock lines would help.


I have pictures and video from the scope which I will upload ASAP, as soon as I can get a hold of my card reader. Basically, Data remains high except a downward spike to 0 that I don't understand (screen looks the same all the time), and Clock is mostly high but actually goes low in a square wave once in a while, which is nice.

----
Update: See later post for picture and video in zip file.



Quote:
Speaking of logic levels, what kind of pull-ups you have on the clock/data lines (if any?). If you have something between 2k and 15k you should be fine.

Are you sure you drive the clock and data pins in open-collector mode, not push-pull mode? You are never ever allowed to set the pins as high outputs, only inputs or low outputs.


I have 10K pullups. (Yay, I did something right) It's supposed to be open-collector, but let me look up push-pull mode and get back to you.


Last edited by snickersnee on Feb 10, 2011 - 02:28 AM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 10:01 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Jepael wrote:


Okay, first of all, the mouse should report only standard 3-byte packets, unless the HOST sends the mouse the correct magic sequence which the mouse recognises and switches to the extended 4-byte protocol.



I think the code does have the mouse recognizing the sequence from the host. See below:
(this code is in the processCommand function)

Code:

    if(settingSampleRateFlag) {
        settingSampleRateFlag = 0;


        if(hostCommand >= 10 && hostCommand <= 200) {
            lastlastSampleRate = lastSampleRate;
            lastSampleRate = sampleRate;
            sampleRate = hostCommand;
            if((lastlastSampleRate == 200) && (lastSampleRate == 100) && (sampleRate == 80)) {
                deviceID = 0x03; // enter MS intellimouse mode
            }
            if(deviceID == 0x03 && lastlastSampleRate == 200 && lastSampleRate == 200 && sampleRate == 80) {
                deviceID = 0x03; // enter MS 5-button mouse mode
            }
        } else { // bad sample rate, output an error
            queuePut(ERROR);


Quote:
And also I honestly don't understand why put 600 ohm resistors there. It will work without any series resistors


This is fine with me, the simpler the better. I'll try a low resistor as well as nothing, but then again why would anyone bother with transistors (the classic open-collector interface), or resistors if they weren't needed?

Anyway thanks for the help.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 09, 2011 - 10:14 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

snickersnee wrote:
I'll try a low resistor as well as nothing, but then again why would anyone bother with transistors (the classic open-collector interface), or resistors if they weren't needed?
You better double check with the PS/2 "spec." that you might not need anything on those MCU pins.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 10:35 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Here is the function implementing the four PS/2 states as described previously. In all of them, the uC is monitoring the mouse clock state as well as CLK_IN from the host.
Code:

void clockStateNow(void)
{
    switch (myState)
    { 
    case BUSY:
        //if the clock being hold low when the clock should've been high.
        //Transition to inhibit state
        if ((clockState == HIGH || clockState == RISING) && CLK_IN == 0)
        {         
            inhibited = TRUE;
            myState = INHIBIT;
            clockState = LOW;
            transmitting = 0;
            receiving = 0;   
            count2 = 0;
        }
        else if ( !(transmitting || receiving) ) //if not doing anything, then we go back to idle
            myState = IDLE;
        else myState = BUSY;
        break;
   
    case IDLE:
        //if the clock being hold low when the clock should've been high.
        //Transition to inhibit state
        if ((clockState == HIGH || clockState == RISING) && CLK_IN == 0)
        {   
            inhibited = TRUE;
            myState = INHIBIT;
            clockState = LOW;
            transmitting = 0;
            receiving = 0; 
            count2 = 0;
        }   
        //if there is data in the queue waiting to be sent
        //transition to BUSY state
        else if(queueEmpty == FALSE)
        {
            myState = BUSY;
            transmitting=1;
            nextClockState=RISING;
            position = 0;
        }
        else
        {
            myState = IDLE;
        }
        break;

    case INHIBIT:   
        //if the computer inhibit before we finishing sending the byte
        //we need to resend the byte
        if(position != 0 && position < 10)
        {
            resendFlag = TRUE;
        }
        position = 0;

        //right after the clock get out of inhibit state
        //we need to check if the computer have hold down the data.
        //If the computer pulls low the data line, then the mouse goes into
        //REQUEST state.
        if (outInhibit == TRUE)
        {
            if(DATA_IN == 0)
            {
                //The computer is request to send some data to the mouse
                myState = REQUEST;
                clockState = RISING;
            }
            else
            {
                //If the data line wasn't low.
                //then the computer must have put the mouse into inhibit
                //for processing data.
                myState = IDLE;
                clockState = RISING;               
            }
            outInhibit = FALSE;
        }
        //if the clock high, meaning the computer has released clock line
        if(CLK_IN == 1)
        {
            outInhibit = TRUE;
        }
        else
        {     
            inhibited = TRUE;
            myState = INHIBIT;
            transmitting = 0;
            clockState = LOW;
            receiving = 0;
            outInhibit = FALSE;
        }
        break;

    case REQUEST: 
        position = 0;
        receiving = 1;
        nextClockState = FALLING;

        //if the clock being hold low when the clock should've been high.
        //Transition to inhibit state
        if ((clockState == HIGH || clockState == RISING) && CLK_IN == 0)           
        {       
            inhibited = TRUE;
            myState = INHIBIT;
            clockState = LOW;
            transmitting = 0;
            receiving = 0;
            count2 = 0;
        }
        else if ( transmitting || receiving)
            myState = BUSY;
        else
            myState = REQUEST;
        break; 

    }//end switch

}


Also, a correction to what I said above:
(I was missing the parity bit)
Quote:
A PS/2 byte has 11 bits:
0 - - - - - - - - - 1
start,(8 bits of data, LSB first),odd parity bit, stop

(Odd parity bit=1 when # of 1's is even)


Last edited by snickersnee on Feb 10, 2011 - 02:13 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 09, 2011 - 10:59 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


indianajones11 wrote:
You better double check with the PS/2 "spec." that you might not need anything on those MCU pins.


The PS/2 "spec" has transistors (see diagram below), I presume that's why it's called an "open-collector interface," but no one actually uses transistors. This project uses 600 ohm resistors instead of transistors, I've seen another similar one that uses 300 ohm resistors, but jepael is telling me both are too high, it should be 100 ohms max, or nothing.

 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 10, 2011 - 02:25 AM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Here are the scope pictures I mentioned.
(well, it's a picture and two movies)

In the attachment (scope.zip):
IMG_6103.jpg is output of the data line
MVI_6104.avi is the clock line

(Separate attachment, MVI_6101.zip):
MVI_6101.avi is output of one of the blinking LEDs on Port B (these were to test the ADC)

----
Update to this: I'm now using a better probe, and in all these configurations all 4 output pins stay on +5V all the time. I could attach those pictures, but I think you can imagine how it looks. I previously described the clock line going down once in a while, however I'm not seeing that now and I have a better probe now. It's all just flat +5V. I think what I was seeing before was due to a lousy probe.


Last edited by snickersnee on Feb 11, 2011 - 12:43 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
Jepael
PostPosted: Feb 10, 2011 - 08:52 AM
Raving lunatic


Joined: May 24, 2004
Posts: 6275
Location: Tampere, Finland

snickersnee wrote:

This is fine with me, the simpler the better. I'll try a low resistor as well as nothing, but then again why would anyone bother with transistors (the classic open-collector interface), or resistors if they weren't needed?


Different chips have different kind of outputs and different driving capability. If the microcontroller only has push-pull outputs, you must put something there to make it compatible with open-collector. Same applies even if microcontroller supports open-collector directly, but if the internal transistor is too weak.

The external components may also protect the controller from destructive voltage spikes etc.

So 20 years ago microcontrollers were different and thus some external components were needed. Nowadays you can get keyboard encoder chips with everything built-in so direct connection is enough.

Edit: the website that has the picture you posted is almost 10 years old, and it says the picture is an example of the interface, and it also says you can use a single pin on a PIC microcontroller instead.
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 10, 2011 - 04:33 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Thanks for the explanation.
Quote:
it also says you can use a single pin on a PIC microcontroller instead

Not sure if it matters, but I'm using AVR. And it shouldn't matter that I'm using Atmega32a and the project calls for Atmega32, right? There are plenty of pins, I might as well use different ones for input and output so I won't have to keep changing DDR. Here is the schematic:



(It shows up too small here, it's also in the attachment.)

Another thing I've thought about is in theory I should be able to power the circuit with the computer, from the +5V pin of the PS/2 cable. However, I rarely get the full voltage from this wire; it's usually more like 2V or 4V or something. This is probably just a consequence of the computer not recognizing the setup as a mouse, but I just thought I'd mention it.

----
Things to try:
-Play with resistor values.
-When compiling it under an older version of Codevision, a lot fewer warnings show up. So I'll try loading this version onto the chip.


Last edited by snickersnee on Feb 11, 2011 - 05:16 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
Jepael
PostPosted: Feb 10, 2011 - 06:30 PM
Raving lunatic


Joined: May 24, 2004
Posts: 6275
Location: Tampere, Finland

But you HAVE to use DDR to make AVR simulate open-collector output. No matter if you use separate input and output pin.
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 10, 2011 - 07:22 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Yes I understand that, hopefully if they are separate the direction wouldn't have to be changed, as opposed to using one pin, and changing the direction. Besides, that's the way the code is written, and so I'll stick with that.
 
 View user's profile Send private message  
Reply with quote Back to top
Jepael
PostPosted: Feb 10, 2011 - 07:51 PM
Raving lunatic


Joined: May 24, 2004
Posts: 6275
Location: Tampere, Finland

snickersnee wrote:
Yes I understand that, hopefully if they are separate the direction wouldn't have to be changed, as opposed to using one pin, and changing the direction. Besides, that's the way the code is written, and so I'll stick with that.


But I just said it is impossible even if the pins are separate. On an AVR, the pin has to be an output when you pull low, but you are not allowed to pull high on the bus, so you have to change the pin direction to input.

(On an ARM though, you can just configure the pin as open-collector output, so it can't pull high, so data register is used to control it).
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 10, 2011 - 08:23 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


I'm looking at the function for generating the packet. Right now I'm only considering pointer movement, not scroll or buttons, so those have been omitted from the code sample below. I'm trying to figure out what this code is saying to do. Can anyone please help me interpret it? Just to check it to see if it's doing what it's supposed to. To me, what's confusing is the >> and <<.

Code:
   
///Generate a standard 4 byte Microsoft IntelliMouse: left, middle, right, x, y, z packet.
void packetGen(void)
{       

    unsigned char btnPacket=0x08;
    //the first byte is at least 0x08, because the third bit is always 1

//scroll and button parts taken out
//for now only looking at movement

 else if(realMoveFlag == TRUE)
    {
        btnPacket = btnPacket | (((movement[Y_AXIS]>>7)&0x1)<<5) | (((movement[X_AXIS]>>7)&0x1)<<4) | ((middleBtn&0x1) <<2) | ((rightBtn&0x1)<<1) | (leftBtn&0x1);                             
        queuePut(btnPacket);
        queuePut(movement[X_AXIS] << resolution);   
        queuePut(movement[Y_AXIS] << resolution);   
        queuePut(0x00);
        //queuePut((movement[Z_AXIS]<2 && movement[Z_AXIS]>-2)?0:movement[Z_AXIS]&0x0f);

    }




X_AXIS, Y_AXIS, and Z_AXIS are the indices, which were declared as follows:

Code:
enum{X_AXIS=0, Y_AXIS, Z_AXIS};


If interested, here's the function that sets the realMoveFlag:

Code:
//Obtain x, y, z movements.
void getMovement(void)
{   
    unsigned char i=0;   
    //position conversion formula.
    // xxxxxxxOLD (int)(voltage - first voltage(when not moving) * 100)
    // ADC reading - init adc reading(calibrating data)

    curPosition[X_AXIS] = (signed char)(xADC - xCal);
    curPosition[Y_AXIS] = (signed char)(yADC - yCal);
    curPosition[Z_AXIS] = (signed char)(zADC - zCal);

    //only when the mouse has significent movement we generate a packet

    //get the difference between the previous position and current position
    for(i=0;i<3;i++)
    {
        movement[i] = curPosition[i];// - lastPosition[i] ;

        //only check x and y movements       
        if(i<2)
        {                             
            if(!(movement[i] < 3 || movement[i] > -3))
                realMoveFlag = TRUE;               
            /*
            if(movement[i] > 3 || movement[i] < -3)
            realMoveFlag = TRUE;
            */
        }

    }                   
}




Here's the packet format:
Microsoft "3-Button" IntelliMouse Z-Mode Report Format
A Microsoft IntelliMouse 3-Button Z-mode motion report consists of a 4-byte packet defined as shown in Table 2.
Table 2. PS/2 4-Byte Mouse Packets

Code:
       D7  D6   D5  D4  D3  D2  D1 D0
Byte 1 Yov Xov Y8   X8   1  MB  RB  LB
Byte 2 X7   X6   X5   X4 X3  X2  X1  X0
Byte 3 Y7   Y6   Y5   Y4 Y3  Y2  Y1  Y0
Byte 4 Zse Zse  Zse Zse  Zs  Z2  Z1  Z0


Symbol definition:
LB: State of the left button. Pressed = 1.
RB: State of the right button. Pressed = 1.
MB: State of the middle button. Pressed = 1.
Xov, Yov: Overflow. Indicates more than 9 bits of movement detected. X8-X0 or Y8-Y0 should be set to maximum magnitude in the appropriate direction.
X8-X0: 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission. A positive value indicates motion to the right; a negative value indicates motion to the left.
Y8-Y0: Same as X8-X0. A positive value indicates device motion upward; a negative value indicates motion downward.
Z2-Z0: Z-wheel motion. Twos complement with Z3, the sign bit (+7 and -8 counts maximum).
Zs: Z-wheel twos complement sign bit.
Zse: Z-wheel sign extension bits. Always the same as Z3. Used for compatibility with old drivers.
MS Extension: Many Microsoft mice use 8-bit internal counters and sign extend the values into X8 and Y8. Microsoft mice do not use the Yov or Xov bits, and they set them to 0.


Last edited by snickersnee on Feb 11, 2011 - 05:17 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 10, 2011 - 08:36 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Quote:
But I just said it is impossible even if the pins are separate. On an AVR, the pin has to be an output when you pull low, but you are not allowed to pull high on the bus, so you have to change the pin direction to input.


OK, I'll check to make sure the pin directions are being changed. The quote below is from someone else's thread but I posted it here because it seems to be the same thing you're explaining. This other poster is using Atmega128. The info applies to 32a as well?



Quote:
> ..., but I am also interested to know how open drains/ collectors work

Instead of having both, "push" and "pull" output transistors (one
going to the GND and one to the Vcc rail), you only have a single one
to GND. Combined with an external resistor, this allows for simply
connecting a number of these together, forming a simple bus. Of
course, the rise time is determined by the total capacity of the
wiring, multiplied by the pull-up resistor, and the smaller you make
the resistor, the more current you are drawing at logic low level.

This is occasionally called a "wired OR" logic.

As the AVR doesn't feature open-drain outputs at all, you simply have
to emulate them by toggling an IO pin between input and output (with
low level). Other controllers (like the classical 8051 design) did
not have push-pull outputs, but always used open-drain outputs (with a
weak internal pullup resistor).



-------

Updates:
-I tried the hex file from the older compiler, and it seems to behave exactly the same.
-Instead of 600-ohm resistors, I tried having just wires connecting the data and clock pins, but that doesn't help either. I also tried 70-ohm resistors.
-Also, as noted in the post with the scope pictures, in all these configurations all 4 output pins stay on +5V all the time. I could attach those pictures, but I think you can imagine how it looks. I previously described the clock line going down once in a while, however I'm not seeing that now and I have a better probe now. It's all just flat +5V. I think what I was seeing before was due to a lousy probe.

----

Anyone know how to translate statements like
(((movement[Y_AXIS]>>7)&0x1)<<5)
into words?
If someone just does one of them please, that would help me figure out the rest.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 13, 2011 - 09:26 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

Code:
(((movement[Y_AXIS]>>7)&0x1)<<5)


Assume movement[Y_AXIS] = 0xC7. Those are logical shift operators, and ( value >> #_shifts ) means that var. value shifts RIGHT by #_shifts.

So, 0xC7 >> 7 = 0x01 ( basically get value of MSB ), then (( 0x01 )& 0x01) = 0x01 = 0x1

finally ( 0x01 << 5 ) = 0x20. Expression is getting value of MSBit of the array, and placing it in bit position 5 of btnPacket. So 1st two values in that expression are:
Code:
btnPacket = btnPacket | 0x20 |...

I suggest you copy the btnPacket expression, make a quick pjt that you'll use to simulate it, give those arrays valid values and see how it gets final number based on what i just gave you. Also, a good C book will be a BIG help.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1


Last edited by indianajones11 on Feb 13, 2011 - 09:36 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 13, 2011 - 09:35 PM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Thank you for the explanation, it was the << and >> that was mysterious. I took a C class, they didn't cover it.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 13, 2011 - 09:40 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

Much help below and there's a tut. on bit manipulations:
http://www.avrfreaks.net/index.php?name ... mp;t=22514

Snickersnee, that C class teacher gets a "C" for not covering it ( and whatever else teacher didn't cover ) !

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
Jepael
PostPosted: Feb 13, 2011 - 10:23 PM
Raving lunatic


Joined: May 24, 2004
Posts: 6275
Location: Tampere, Finland

What kind of C class did not cover those?
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Feb 13, 2011 - 11:44 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3896
Location: San Diego, Ca

Since the design, s.ware / h.ware , is supposed to work, I wouldn't change the resistor values. Use the LCD to output X- ONLY values. Drag it show L - R and R - L. Do you get reasonable values ? Repeat for Y. Now you can test that all 4 bytes are reasonable by displaying them to LCD.

You shouldn't connect it to the PC's PS/2 port until you verify operation of / understand its main sections. Instead connect the 2 output lines to 2 leds, different colors if you have them. Comment out the code that sets the send time and copy that code but with send values that are in seconds so you can see the leds flash. Are they flashing the correct 4 packet ? What voltages in range for the host to detect 1s and 0s ?

So you'd have the LCD showing the 4 pack ( tests code ) and at same time leds to show that your O.C. I/F and sending code are working. Base where to the debug on what functions are called in main().

Main sequential steps in code:

1) adc()
2) get_movement()
3) blah blah
4) send_packet()

4) doesn't work, is it 'cause of something in 4), before it or both ? TEST each major section, like I've showed above and find out. It's all about divide & conquer, but don't divide TOO much until you find the function(s) that being a headache.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 21, 2011 - 04:43 AM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Hi, sorry for the delayed response. Thanks so much for being there. I wonder if I should start a new thread? This one is probably buried already.

I put an LED for each of the four states (with delay so I could see it) and I also put an LCD on Port C (buttons will have to go somewhere else once I get there), but buttons and scroll aren't a big priority right now. Just trying to get pointer movement. The LCD displays the value of xADC. This worked fine with the original 4 LEDs (which indicated the status of ADCL and ADCH). However, adding the new LEDs makes the LCD display x=0 all the time, even though I didn't touch that part of the code at all except for having it also display the value of curPosition[X_AXIS]. I'll try taking that off and see what happens. Nothing wrong with the accelerometer.

Anyway, using a scope I was able to find that the micro does generate clock pulses, frequency approx. 12.2 kHz where it's supposed to be 12.5, I guess this is due to using internal RC 8 MHz? This corresponds to a period of 82us instead of 80, this isn't enough to throw everything off is it? Anyway, if I put Data=1 while putting a probe on clock, that is when it will start generating pulses. Other findings of note include that if D=C=1, the lights for ADCL, ADC!=0, and idle go on. If D=0 and C=1, ADC!=0 and idle lights go on. D=C=0 cause a reset, it seems. (All LEDs stay on, LCD screen initializes then is blank.) I'm going to try other conditions, but I think there is something wrong with this micro, let me find another one. One of the pins got really badly bent, but it didn't break, I straightened it but it still got messed up I think.

Note: The extra LEDs went into the while(1)loop in main(), and for the LCD changes displayAxis(-,-,-) was modified. The original comments had stuff like PORTB=~0x20; but I changed it to stuff like PORTB.4=1; just because ~ is another thing I'm not sure the meaning of. I think it means "not".
Yeah, I know what you're going to say,
Quote:
What kind of C class did not cover those?

An American one I guess? I know there was some kind of international standardized test and Finland did the best and the US was on par with like Slovakia or something, lol. I think this is what I'm talking about: http://www.npr.org/2011/01/28/133301331/the-new-republic-the-u-s-could-learn-from-finland I risk derailing yet another thread though.


Last edited by snickersnee on Feb 21, 2011 - 06:08 AM; edited 7 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
snickersnee
PostPosted: Feb 21, 2011 - 04:55 AM
Wannabe


Joined: Nov 07, 2010
Posts: 52


Here's what happens sometimes. When I power on, first all LEDs will light, then it will go through a sort of startup sequence. The ADC light will go on, the idle light will blink four times, and then the inhibit light goes on. Everything freezes, then I get it out of this state by putting the data line to ground. Then the busy/transmitting light will light, but with the scope I really don't see any data being transmitted, and when I connect this to the computer (through a USB adapter), no movement occurs. I've got to play with it some more to try to duplicate this behavior. Honestly, I can't take this anymore. I've been messing with this for quite a while as you guys know, and I'm running out of time. If someone could get this working, I would seriously pay them. Crying or Very sad
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits