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
Jepael
PostPosted: Feb 10, 2011 - 06:30 PM
Raving lunatic


Joined: May 24, 2004
Posts: 6280
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: 6280
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: 6280
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