The Godfather talking
You can run, but you can't hide.
Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
April 19, 2024, 05:29:26 17:29


Login with username, password and session length


Pages: [1]
Print
Author Topic: PS2 interface and UART on Atmega88  (Read 10292 times)
0 Members and 1 Guest are viewing this topic.
jeniusj
Junior Member
**
Offline Offline

Posts: 38

Thank You
-Given: 11
-Receive: 7


« on: July 28, 2008, 07:48:48 07:48 »

I am currently working on the project related to robot vehicle in which I am trying to use optical mouse as position sensor.......for that purpose I have to interface the PS2 mouse using Atmega88..........I have successfully implement it (making the use of PS2 library available at www.avrfreaks.net by Jan Pieter de Ruiter )by the Grace of God....but when I am trying to send this data serially.......UART does not work......and also mouse do not initializes but the routine for PS2 interface and for UART works fine individually.............I have modified the librararies as per my requirement...........
my code is as follows..........although the following code uses the polling based transmission of UART but i have also tried interrupt based transmission,but all in vain..............
All useful comments and material is being warm welcomed...........
my code is as follows
Code:
/*************************************************************************************
 Title:     C include file for the PS/2 mouse library (ps2mouse.c)
 Author:    Jan Pieter de Ruiter <[email protected]>
 Date:      13-Jun-2002
 Software:  AVR-GCC with AvrStudio
 Target:    Any AVR device

 DESCRIPTION
       Advanced routines for implementing the ps/2 protocol for a mouse.
       I think the function names speaks for themselve.
       They return 1 if the function succeeds, 0 if they fail.
       You can get the errorcode (RESEND or ERROR) with ps2_GetError() if a function fails.
       I found that some mice does not work with these functions, so use these functions
       at your own risk

**************************************************************************************/

#ifndef __PS2MOUSE_H_
#define __PS2MOUSE_H_ 1

#define STREAM 0
#define REMOTE 1


#define STANDARDMOUSE    0x00

#define ONECOUNT_MM   0
#define TWOCOUNT_MM   1
#define FOURCOUNT_MM  2
#define EIGHTCOUNT_MM 3

#define SCALING1_1 0
#define SCALING2_1 1

#define RESEND 0xFE
#define ERROR  0xFC

int lasterror;
int MouseID;
int MouseMode;
int oldMouseMode;

struct MouseData
{
int Xmovement;
int Ymovement;
};

struct MouseStatus
{
int mode;
int reportenabled;
int scaling;
int resolution;
int samplerate;
};

int ps2_GetError(void);
int ps2_Init(void);
int ps2_Reset(void);
int ps2_Resend(void);
int ps2_SetDefault(void);
int ps2_SetSampleRate(int rate);
int ps2_GetID(void);
int ps2_SetRemoteMode(void);
int ps2_ReadData(struct MouseData *data);
int ps2_SetStreamMode(void);
int ps2_GetStatus(struct MouseStatus *status);
int ps2_SetResolution(int resolution);
int ps2_SetScaling(int scaling);

#endif
 
/*************************************************************************************
 Title:     C include file for the PS/2 library (ps2.c)
 Author:    Jan Pieter de Ruiter <[email protected]>
 Date:      13-Jun-2002
 Software:  AVR-GCC with AvrStudio
 Target:    Any AVR device

 DESCRIPTION
       Basic routines for implementing the ps/2 protocol (for a mouse, keyboard etc.)

**************************************************************************************/
#ifndef __PS2_H_
#define __PS2_H_ 1

#include <avr/io.h>

#define _BV(bit)   (1 << (bit))
#define INB(sfr)   _SFR_BYTE(sfr)
#define SBI(x,y) (x |= (1<<y)); /* set bit y in byte x */
#define CBI(x,y) (x &= (~(1<<y))); /* clear bit y in byte x */
#define BIT_IS_SET(sfr, bit)   (INB(sfr) & _BV(bit))
#define BIT_IS_CEAR(sfr, bit)   (!(INB(sfr) & _BV(bit)))
#define LOOP_UNTIL_BIT_IS_SET(sfr, bit)   do {asm volatile ("nop"::);} while (BIT_IS_CEAR(sfr, bit))
#define LOOP_UNTIL_BIT_IS_CLEAR(sfr, bit)   do {asm volatile ("nop"::);} while (BIT_IS_SET(sfr, bit))

/* Select ports for the CLK and DATA lines here **************/
#define CLKPORT PORTC  // port for CLK line
#define DATAPORT PORTC // port for DATA line
#define CLK 0    // pin on CLKPORT for CLK line
#define DATA 1        // pin on DATAPORT for DATA line

#define CLKDDR DDRC
#define CLKPIN PINC
#define DATADDR DDRC
#define DATAPIN PINC
/*******************************************/

void Delay(long Microseconds);   // Function for internal usage
int Read_ps2data(void);          // Receives a data byte from a device
void Write_ps2data(int data);    // Sends a data byte to a device

#endif
///////////////////////////////////////////////////////////////////////////////
//
// Project :PS2 Mouse Interface
// Designers :Jibran Ahmed
//
//
///////////////////////////////////////////////////////////////////////////////

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/iom88.h>
#include <util/delay.h>
#include <util/parity.h>
#include <string.h>
#include "ps2.h"
#include "ps2mouse.h"
#define ATMEGA_88

void UART0_Init(void);
void Init(void);


int main(void)
{
int mouseinf;
int deltax;
int deltay;
int posx = 0;
int posy = 0;

Init();
// UART0_Init();

while(1)             // Loop forever
{
// while(!(UCSR0A & 0x20 )); //wait for UDRE flag
// UDR0 = 'a';//(unsigned char)(posx);
mouseinf=Read_ps2data();
deltax=Read_ps2data();
deltay=Read_ps2data();
if(mouseinf&0x10)deltax-=0x100; // Add sign bit to deltax
if(mouseinf&0x20)deltay-=0x100; // Add sign bit to deltay
posx  += deltax;   // Absolute X position
posy+=deltay;   // Absolute Y position
}
}


void Delay(long microseconds)
{
while (microseconds)
microseconds--; //Wait about ____ microseconds
}

int Read_ps2data(void)
{
int d[8];
int i,Parity;
int f    = 1;
int Data = 0;
CBI (CLKDDR,CLK) ; //Make CLK input
CBI (DATADDR,DATA); //Make DATA input
CBI (CLKPORT,CLK); //Make CLK Open
CBI (DATAPORT,DATA); //Make Data Open

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK); //Ignore StartBit
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK); //Ignore StartBit

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK); //Recieve First Data Bit
if(BIT_IS_SET(DATAPIN,DATA)) d[0] = 1;
else d[0] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK); //Recieve 2nd Data Bit
if(BIT_IS_SET(DATAPIN,DATA)) d[1] = 1;
else d[1] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) d[2] = 1;
else d[2] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) d[3] = 1;
else d[3] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) d[4] = 1;
else d[4] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) d[5] = 1;
else d[5] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) d[6] = 1;
else d[6] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) d[7] = 1;
else d[7] = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if(BIT_IS_SET(DATAPIN,DATA)) Parity = 1;
else Parity = 0;
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK); //Ignore Stop Bit
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK); //Ignore Stop Bit

for (i = 0; i <8 ; i++) //Convert to Decimal
{
Data += d[i]*f;
f    *= 2;
}

if(((Parity==0)&&(parity_even_bit(Data)==0))||((Parity!=0)&&(parity_even_bit(Data)!=0)))
return Data;   // Return data if received data is OK
else
{
Write_ps2data(0xFE);      // Send the "ReSend" command
return Read_ps2data();    // Receive data again
}
return 0;
}
void Write_ps2data(int data)
{
CBI(DATADDR,DATA);       // Make DATA input
CBI(DATAPORT,DATA);      // Make DATA open
SBI(CLKDDR,CLK);         // Make CLK output
CBI(CLKPORT,CLK);        // Make CLK open

CBI(CLKPORT,CLK);        // Cancel the mouse (if transmitting)
// Delay(25);
SBI(DATADDR,DATA);       // Make DATA output
CBI(DATAPORT,DATA);      // Generate startbit
// Delay(25);
CBI(CLKDDR,CLK);         // Make CLK input
CBI(CLKPORT,CLK);        // Make CLK open

LOOP_UNTIL_BIT_IS_CLEAR (CLKPIN,CLK);     // Send first data bit
if((data&0x01)==0) { CBI ( DATAPORT,DATA ); }
else SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);     // Send Second data bit
if((data&0x02)==0)  { CBI (DATAPORT,DATA); }
else SBI ( DATAPORT,DATA );
LOOP_UNTIL_BIT_IS_SET( CLKPIN,CLK );

LOOP_UNTIL_BIT_IS_CLEAR( CLKPIN,CLK );     // etc.
if((data&0x04)==0){CBI(DATAPORT,DATA); }
else SBI (DATAPORT,DATA );
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if((data&0x08)==0) { CBI ( DATAPORT,DATA ); }
else SBI ( DATAPORT,DATA );
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if((data&0x10)==0){CBI(DATAPORT,DATA);}
else SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if((data&0x20)==0){CBI(DATAPORT,DATA);}
else SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if((data&0x40)==0){CBI(DATAPORT,DATA);}
else SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);
if((data&0x80)==0){CBI(DATAPORT,DATA);}
else SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);             // Send parity bit
if(parity_even_bit(data)==0){CBI(DATAPORT,DATA);}
else SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);         // Send stop bit
SBI(DATAPORT,DATA);
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);

CBI(DATADDR,DATA);
CBI(DATAPORT,DATA);
CBI(CLKDDR,CLK);
CBI(CLKPORT,CLK);
LOOP_UNTIL_BIT_IS_CLEAR(CLKPIN,CLK);    // Ignore acknowledge bit
LOOP_UNTIL_BIT_IS_SET(CLKPIN,CLK);
}

void UART0_Init(void)
{
    PRR = PRR & 0b11111101; //Enable USART0, Enable ADC
SREG = 0x80; //Enabling All Interupts

UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x02;
UCSR0C = 0x06;
UBRR0L = 0x0C; //set baud rate lo 0x67 for 8MHz 0x0C for 1MHz
UBRR0H = 0x00; //set baud rate hi
UCSR0B = 0x18;
}

void Init()
{           
DDRB = 0xFF; //PORTB as output
DDRC = 0xFF; //PORTC as output
           
Write_ps2data(0xFF); //Reset mouse    
                     
// wait for codes
while( Read_ps2data() != 0xfa); //Acknowledge
while( Read_ps2data() != 0xaa); //Self test passed
while( Read_ps2data() != 0x00); //Mouse ID

Write_ps2data(0xF4); // enable data reporting
while( Read_ps2data() != 0xfa);
}

/*
ISR ( USART_TX_vect )
{
//USART Transmission complete routine
}

ISR ( USART_RX_vect )
{

}

ISR ( USART_UDRE_vect )
{

}*/

« Last Edit: July 31, 2008, 10:07:09 10:07 by jeniusj » Logged
hate
Hero Member
*****
 Warned
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #1 on: July 28, 2008, 08:10:40 08:10 »

What do you mean by 'UART does not work'? Does UART send any data or not at all or send the same data repeatedly? Try making the UART work by trying to send something not releated with the mouse. Maybe something mixed with UART and mouse?

Regards...
Logged

Regards...
jeniusj
Junior Member
**
Offline Offline

Posts: 38

Thank You
-Given: 11
-Receive: 7


« Reply #2 on: July 28, 2008, 11:21:39 11:21 »

UART does not work means it does not send any data..
yes I have done it already by sending the known character to the UART
this character would not recieve until and unless i exclude the code regarding PS2 interface
both PS2 routines and UART woks fine individually
Logged
hate
Hero Member
*****
 Warned
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #3 on: July 29, 2008, 10:35:08 10:35 »

I gave a look at your code. The line

Code:
Data += d*f;

in the

Code:
   for (i = 0; i <8 ; i++) //Convert to Decimal
      {
         Data += d*f;
         f    *= 2;
      }

loop doesn't look likely to compile! If it does, 'd' as used in here the address of the pointer 'd' is multiplied by 'f' and added to 'Data' integer. This number won't be anything as expected, I guess it should be

Code:
Data += d[i]*f;

And just wondering how do you know the PS/2 routines work? By toggling a LED at the end of each line in the 'Init()' routine or by some other way?

Regards...
Logged

Regards...
jeniusj
Junior Member
**
Offline Offline

Posts: 38

Thank You
-Given: 11
-Receive: 7


« Reply #4 on: July 31, 2008, 09:46:57 09:46 »

Thanks for giving the Look at my code but in my code it is as
Code:
Data += d[i]*f
and not like this
Code:
Data += d*f 
as I am simply copy paste the code while submitting the topic
Code:
d[i]
is shown as only
Code:
d
yes I do check the initialization of mouse by connecting it to the PC and then check the waveforms on Clock and Data pins,(Data changes as mouse is being moved)
and the same thing happens when I am moving the mouse and observing the same waveforms on Clock pin as well as on data pin .............thats why I am saying that mouse is initializing
Logged
hate
Hero Member
*****
 Warned
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #5 on: August 01, 2008, 07:40:48 07:40 »

Ok then last thing I can suggest without having an actual hardware to test is changing the function order of

Code:
	Init();
UART0_Init();

The line

Code:
PRR = PRR & 0b11111101;	//Enable USART0, Enable ADC

looks a little suspicous to me, maybe it corrupts the initialization of the PS/2 routines by writing the 'PRR' register. You may also try to initialize UART line by line by commenting out all lines and trying to progress line by line to see what makes PS/2 routines mulfunction. Forget about the UART first and try to see what's the problem with PS/2!

Regards...
Logged

Regards...
jeniusj
Junior Member
**
Offline Offline

Posts: 38

Thank You
-Given: 11
-Receive: 7


« Reply #6 on: August 01, 2008, 11:06:09 11:06 »

thanks again,
the first thing u say ,I have already done it,(i.e.) change the order of function.....
the second thing u say, is not checked yet, i will check this routines Insha Allah on monday and will post the results
Regards....


Logged
jeniusj
Junior Member
**
Offline Offline

Posts: 38

Thank You
-Given: 11
-Receive: 7


« Reply #7 on: August 04, 2008, 08:25:50 08:25 »

Code:
PRR = PRR & 0b11111101;	//Enable USART0, Enable ADC
have no effect on the malfunctioning of PS2 Code,but now PS2 code works but still UART hangs and not sends any data or sometimes send garbage data
« Last Edit: August 04, 2008, 08:29:10 08:29 by jeniusj » Logged
hate
Hero Member
*****
 Warned
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #8 on: August 04, 2008, 01:57:21 13:57 »

So did you work out which expression in 'UART0_Init' function corrupts the PS/2 routines or just tried commenting out the expression with 'PRR'? This maybe a compiler bug by the way!

Regards...
Logged

Regards...
kathir
Junior Member
**
 Muted
Offline Offline

Posts: 35

Thank You
-Given: 1
-Receive: 7


« Reply #9 on: August 04, 2008, 05:00:59 17:00 »

while programing  previous  fuse setting shuld be cleared. If any fuses set THE UART WONOT WORK BECAUSE BAUD RATE MAY BE NOT SAME AS THE SET VALUE.I ENCOUNTERED THIS PROBLEM.USING  SETTING AND CONIGURATION BITS FACILITY IN  PONYPROG2000 SOFTWARE I CLEARED   PREVIOUS SETTING AND WORKS FINE
Logged
jeniusj
Junior Member
**
Offline Offline

Posts: 38

Thank You
-Given: 11
-Receive: 7


« Reply #10 on: August 04, 2008, 06:01:06 18:01 »

Hate>>
Thanks friend..........As I have got time I will work on the debugging.......do you ever used in sytem one wire debugging from Atmel
Kathir>>Thanks friend,I have done it already,
I am running my program on 1MHz and for this fuse setting is appropriately done as I have send and recive data from UART in individual routines
Logged
hate
Hero Member
*****
 Warned
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #11 on: August 04, 2008, 08:58:50 20:58 »

No, I didn't use it, I think my stk500 clone will be slow as hell for 1-wire debugging so I'm waiting for someone to clone jtagice mkII to try 1-wire!

Regards...
Logged

Regards...
Mega32
Active Member
***
Offline Offline

Posts: 179

Thank You
-Given: 183
-Receive: 37


« Reply #12 on: August 25, 2008, 09:43:19 21:43 »

Hate>>
Thanks friend..........As I have got time I will work on the debugging.......do you ever used in sytem one wire debugging from Atmel
Kathir>>Thanks friend,I have done it already,
I am running my program on 1MHz and for this fuse setting is appropriately done as I have send and recive data from UART in individual routines

1Mhz implies that you are using the internal oscillator.
This is not a good idea when using UART comm's , as the internal osc is unprecise (especially if you didn't use/set the osccal byte) and it's temperature dependant. Do use an Xtal instead.

Mega32
Logged
Kabron
Active Member
***
Offline Offline

Posts: 196

Thank You
-Given: 63
-Receive: 139



« Reply #13 on: August 28, 2008, 02:00:01 14:00 »

The tolerance of internal RC gen is about 1%(and it can be adjusted) while RS232 requires 3%. So nothing dangerous to use internal oscillator.
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC