PDA

View Full Version : reducing shiftout clock freq and PS2/PC interfacing ....



wireless magic
- 26th January 2008, 02:20
I'm working on a wireless optical keyboard using the PS2 caple and I'm working on it with my friends step by step and we start to try sending a single character. And through our searching we found that we need to satisfy some conditions :

11 bit outputs , sycronous comm. with host should be done , and clock frequency with range 10KHz and 16.7KHz and the data recivied to the host ( PC ) should be read on the falling edge of the clock signal.

ok we wrote a simple prog. using shiftout to make an " A " appears on the screen but when we make so the computer get frozen and we have to restart it from the power switch.

and what we think is the clock freq ia the problem and we use a 4MHz osc and we don't know if we should make a pause after using the shiftout ! and how "DEFINE SHIFT_PAUSEUS 100" exactlly works !!and how it can hepl us to reduce the freq of clock and 4M => 50KHz

and in the documents they say 50kHz depend on the osc how ??!!

and why the computer get frozen ? and if any one worked on the connecting the Pic with the computer throgh PS2 caple please tell me if there are some point that we should take on our consideration or if there is some steps ore configrations that we might missed

Thanks and I really nead your help to make this project !! and I'm still in the 1st step !!

iugmoh
- 26th January 2008, 10:06
Hi all , I have some experience with PS/2 and PIC since I made interfacing between keyboard or barcode reader PS/2 and PIC microcontrollers, you may take these considrations in your work:

1) PS/2 have two signals to communicate with it , clock and data
2) clock generated and data sends at every falling edge of the clock
3) each character represented with 33 bits ( make code , break code , make code)
4) each 11 bits is consist of ( 1 start bit , 8 data bits , 1 parity bit , 1 stop bit)
5) low level of clock duration is about 50 microsecond

you can search on google for PS/2 keyboard interface for more specification

I don't know the way how you use optical wireless but if you attach the schematic will be better

wireless magic
- 26th January 2008, 18:29
hello iugmoh

thanks GOD to find someone to help

ok lets see from your points what I might have a problem with is points : 2,5

2) clock generated and data sends at every falling edge of the clock

ok I read this befor in a document some where but the question is how can this point implemented is there any speacial instruction that can make an affect on the clock generated from shiftout instruction ?

OR

does the shiftout already takes this point in the consideration ??!! oh boy this one !

5) low level of clock duration is about 50 microsecond

hmmm there I think it can be between 30 - 50 us but the problem how can I achive this if I use an osc = 4MHz and shiftout gives freq of clock = 50kHz

which means low level of clock duration is about 10 microsecond , true ?!!

so how did you solve those problems ? ( using the PICBasic )

or should I use other IC's to help me in !!

thanks and waiting for your replay and to see your experiance on that.

thanks again

sayzer
- 28th January 2008, 08:00
I am sure this link is somewhere in this forum.

http://www.computer-engineering.org/ps2protocol/

wireless magic
- 29th January 2008, 23:55
hello sayzer

actually I know this protocolle befor the problem how can I emplement it and make an "A"
appears on the notepad or microsoftword using pic 16f877A

I used shiftout ...., ..... , 5 [% 010100110/11]

but it not working how can I control the clock frequency I want it between 10 - 16.7 KHz !

please give me some help.

sayzer
- 30th January 2008, 07:52
May be it would be much better if you write your own routine.

You can control Clock and Data lines with more accuracy and thus play with Clock frequency as you like.

Example:


<font color="#000000">
Temp = <font color="#FF0000"><b>$15 </b></font><font color="#000080"><i>' Send &quot;q&quot; as an example.

</i></font>DatTime = <font color="#FF0000"><b>10 </b></font><font color="#000080"><i>' Data Pause Time.
</i></font>ClkTime = <font color="#FF0000"><b>50 </b></font><font color="#000080"><i>' Clock Pause time.

</i><b>OUTPUT </b></font>TxCLK <font color="#000080"><i>' Before you send anything, assign the pins as output pins.
</i><b>OUTPUT </b></font>TxDAT

TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = STARTBit <font color="#000080"><i>' Start bit is always zero.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime

TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>0 </b></font><font color="#000080"><i>' Bit 0.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>1 </b></font><font color="#000080"><i>' Bit 1.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>2 </b></font><font color="#000080"><i>' Bit 2.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>3 </b></font><font color="#000080"><i>' Bit 3.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>4 </b></font><font color="#000080"><i>' Bit 4.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>5 </b></font><font color="#000080"><i>' Bit 5.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>6 </b></font><font color="#000080"><i>' Bit 6.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Temp.<font color="#FF0000"><b>7 </b></font><font color="#000080"><i>' Bit 7.
</i><b>PAUSEUS </b></font>DatTime
TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = Parity <font color="#000080"><i>' Parity Bit.
</i><b>PAUSEUS </b></font>DatTime <font color="#000080"><i>' You must calculate Parity bit_
</i></font>TxCLK = <font color="#FF0000"><b>0 </b></font><font color="#000080"><i>'in somewhere before putting it here.
</i><b>PAUSEUS </b></font>ClkTime


TxCLK = <font color="#FF0000"><b>1
</b></font><font color="#000080"><b>PAUSEUS </b></font>DatTime
TxDAT = StopBit <font color="#000080"><i>' Stop bit is always 1.
</i><b>PAUSEUS </b></font>DatTime <font color="#000080"><i>' Have a variable named StopBit and make it 1.
</i></font>TxCLK = <font color="#FF0000"><b>0
</b></font><font color="#000080"><b>PAUSEUS </b></font>ClkTime

<font color="#000080"><b>INPUT </b></font>TxCLK <font color="#000080"><i>' when you are done with sending a byte,
</i><b>INPUT </b></font>TxDAT <font color="#000080"><i>'assign the pins as input pins.


</i></font>


This routine works fine.
But I am having issues with different computers.
Thus, you will have to play with Data and Clock pauses.
Also, you will have to have a Delay between each "SEND".

wireless magic
- 31st January 2008, 00:02
ok actually I tried your code with little midifications :

as follow:


device 16f877a


INPUT portb.1 ' when you are done with sending a byte,
INPUT portb.0 'assign the pins as input pins.
input portd.2
StopBit var bit
StartBit var bit
Parity var bit
Temp var byte
DatTime var byte
ClkTime var byte




stopbit = 1
startbit = 0
Parity = 0 'for q parity=0

Temp = $15 ' Send "q" as an example.

DatTime = 10 ' Data Pause Time.
ClkTime = 50 ' Clock Pause time.

main:

if portd.2=1 then sendQ
goto main



end

sendQ:

OUTPUT portb.1 ' Before you send anything, assign the pins as output pins.
OUTPUT portb.0

portb.1 = 1
PAUSEUS DatTime
portb.0 = STARTBit ' Start bit is always zero.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime

portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.0 ' Bit 0.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.1 ' Bit 1.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.2 ' Bit 2.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.3 ' Bit 3.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.4 ' Bit 4.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.5 ' Bit 5.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.6 ' Bit 6.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Temp.7 ' Bit 7.
PAUSEUS DatTime
portb.1 = 0
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = Parity ' Parity Bit.
PAUSEUS DatTime ' You must calculate Parity bit_
portb.1 = 0 'in somewhere before putting it here.
PAUSEUS ClkTime


portb.1 = 1
PAUSEUS DatTime
portb.0 = StopBit ' Stop bit is always 1.
PAUSEUS DatTime ' Have a variable named StopBit and make it 1.
portb.1 = 0
PAUSEUS ClkTime

INPUT portb.1 ' when you are done with sending a byte,
INPUT portb.0 'assign the pins as input pins.


goto main




______________________________

and it still not working ,nothing appears on the screan and if I used the 5V supply from the PC , the PC became freezing and nothing will work , if I used an auxiliarysupply the character " q " will not appear also as in the first case but the computer will not freezing !

now:

1) I thought it might be the DataTime and ClkTime values so I think to chnge them to dataTime = 18 , ClkTime=37 by using those values the period of logic one = 37us and logic zero period = 37us ( for the clock ) !! then the T=74us -> f=1/T =13.513KHz in the required range. but I didn't try it yet

2) the second reason I was thinking about (it may look crazy - but I get missed of reasons)
ok what I think:
in all the cases ever the PS/2 cable that we are use was goten from a mouse " a mouse
PS/2 cable - green - " was conntected to our Pic microcontroller !!



so do you think that one of those might be the reason of making the PC freezing and the character not appears.




AMAZING THAT AN ENGINEERES CAN'T MAKE A HARDWARE TO SHOW A SINGLE CHARACTER ON THE COMPUTER NOTEPAD

and this is still the first step on my project .

by the way thanks sayzer for your tring and for your help !! waitting to see your replay and what Ideas do you have in your mind !

skimask
- 31st January 2008, 00:21
As noted in Post #2, to get a key to be read by a PS/2 port, you have to send a MAKE and a BREAK scan code.
Looking at your code, I only see 8 data bits, some timing, etc. being sent.
Sayzer gave you good code to work with, but that's only half the battle.
And besides, shiftout should work just fine, as long as you send the right codes (see first line of this post)...

Also, you can shorten that up by quite a bit: (yes, here I go with my colons again!)



device 16f877a
input portb.1:input portb.0:input portd.2:stopbit var bit:startbit var bit
parity var bit:temp var byte:dattime var byte:clktime var byte
tempbit var bit:stopbit=1:startbit=0:parity=0:Temp=$15:DatTime =10
ClkTime=50
main: if portd.2=0 then main
output portb.1:output portb.0:tempbit=startbit:gosub sendbit:tempbit=temp.0
gosub sendbit:tempbit=temp.1:gosub sendbit:tempbit=temp.2:gosub sendbit
tempbit=temp.3:gosub sendbit:tempbit=temp.4:gosub sendbit:tempbit=temp.5
gosub sendbit:tempbit=temp.6:gosub sendbit:tempbit=temp.7:gosub sendbit
tempbit=parity:gosub sendbit:tempbit=stopbit:gosub sendbit
INPUT portb.1:INPUT portb.0:goto main
sendbit: portb.1=1:pauseus dattime:portb.0=tempbit:pauseus dattime:portb.1=0
pauseus clktime:return
END

sayzer
- 31st January 2008, 07:49
Wireless,

Freezing computer seems to be having Data and Clk lines reversed.

Either in your code, or in your hardware, change them.

Also, make sure, you remove your PS/2 Keyboard while testing this. Some people try to use them in parallel as I do not understand how they expect it to work??

Also, as Skimask stated, it is a code to work on.
If you like to send 'q' then you should send $15,$F0,$15.
$15 is 'q' as pressed Key.
$F0,$15 is 'q' as released Key.

You should consider this procedure in your code.

wireless magic
- 31st January 2008, 21:00
skimask
I made what you said by inserting a break code after the make but the two problems are still there :

1- the Computer still freezing !!! <-- why is that ?
" and the computer give a note that no keyboard exict " !!!

2- the character still not appears .

is it a hardware problem !!!

by the way thanks for your tring and I hope you can find an answer for me :)

Archangel
- 31st January 2008, 21:16
Hello Wireless Magic,
to save yourself some agravation of having Windoze lock, have you tried booting to a command prompt only? Even better use a DOS startup disk. If your hardware is off it likely will not lock up it just won't work.

wireless magic
- 31st January 2008, 21:26
sayzer

1st thanks becouse you are still tring with me and didn't give up , really thanks.

ok lets see there , Clock and data reversed hmmm I looked at it and nothing wrong neither in the code or hardware !

and I have inserted the break code after the make and still :

" freezing and the 'q' didn't appears "


I don't think the problem is from the code "software"

but I'm not sure if those problem due hardware

hmmmm..is there any hardware issues should be token in our consideration !!!

still need any information that can help me to make a single character appears on the screan !!!

I should change my name into keyboard magic looooooooool .

Darrel Taylor
- 31st January 2008, 21:30
It takes more than just sending keystrokes via the PS2 protocol.

When the PC is booting, the keyboard must send and receive several commands to tell the PC what it is, what mode it's using, etc.

Go to the link Sayzer gave in post #4, then click on "PS/2 Keyboard Interface".
Look at the Command Set/Initialization sections at the bottom.

It's possible to place the device in parallel with an existing keyboard, so the keyboard does all the initializing.
But if you don't want the keyboard, you'll need to do it all yourself.

Not as easy as just toggling a couple pins with the right timing.
<br>

skimask
- 31st January 2008, 21:43
When the PC is booting, the keyboard must send and receive several commands to tell the PC what it is, what mode it's using, etc.
Ahhhhhhhh.......
The O/P didn't state specifically if he/she was using the keyboard alone or in parallel...good point...
However (we've been down this road before somewhere), there should be a setting in BIOS called something like 'Halt on All Disk/Keyboard' errors or something like that and it can usually be shut off. Should take care of the freezing problem. But since the keyboard hasn't been recognized, it still won't work :)

mister_e
- 31st January 2008, 22:52
I confirm what Darrel's said. There's a lot of things to do before it work as expect.

I already suggested awhile back to build a PS-2 sniffer and log the whole data exchange from the boot... to the end. It's more than a stupid BIOS setting. In fact.. you have to confirm your Keyboard is there, and it's self test is passed.

Not that hard.. not that easy.

If you have any protocol analyzer or digital storage scope (PoScope, Bitcope, USBee) that will be easier.

For safety sake, you can't use Shiftin/Shiftout AS-IS. You need to toggle TRIS instead of trashing a pin to high or low.

Note: A PC may work slightly different from a Laptop.

This said.. this should be enough food for thought ;)

wireless magic
- 31st January 2008, 23:22
ok , what we have until now is :

The code works almost perfectly when booting to a command prompt only (DOS). in BIOS i made it not to halt on keyboard errors, but this only removed the ( No keyboard or keyboard error) that appears when switching on. But still it FREEZES when trying to send a character in notepad ( in windows). why is it working over DOS but windows Freezes?

in the code i made no initialization (When the PC is booting, the keyboard must send and receive several commands to tell the PC what it is, what mode it's using, etc.) and still the DOS recognizes the data sent to the PS/2 port by the PIC.

what to do so that windows doesn't freeze?

thanks again

Archangel
- 23rd February 2008, 07:51
Question:
Are you sending data from 1 p/c (notepad ) through the serial port to the PIC and then to a second P/C ? I ask, as today I was working setting up the COM link between a PC and A CNC mill and the serial software by default sends a CR and LF with every line, and you can disable that, maybe your serial program is sending that and the P/C is not expecting it. Just thinking out loud.
JS

sayzer
- 23rd February 2008, 10:01
ok , what we have until now is :

The code works almost perfectly when booting to a command prompt only (DOS). in BIOS i made it not to halt on keyboard errors, but this only removed the ( No keyboard or keyboard error) that appears when switching on. But still it FREEZES when trying to send a character in notepad ( in windows). why is it working over DOS but windows Freezes?

in the code i made no initialization (When the PC is booting, the keyboard must send and receive several commands to tell the PC what it is, what mode it's using, etc.) and still the DOS recognizes the data sent to the PS/2 port by the PIC.

what to do so that windows doesn't freeze?

thanks again


It seems we will have to look at the hardware side!
Unplug mouse, and boot with KB only.
Open notepad and unplug KB, plug PIC circuit.
Send data.
IF still freezing, then post the schematic.

P.S. - Assuming (and also hoping) that after each send, you are setting your Clk and Data pins to be input pins and putting a delay like 10mS.

wireless magic
- 26th February 2008, 20:15
thank u ,
we tried it and no more freezing, and it works perfectly on notepad.
how can we avoid freezing? ( how to boot with the PIC circuit and make windows recognize it?)
i tried some initialization codes but still freezes.
is the initialization code for windows to recognize the "PIC keyboard" or for the PC to boot initially with the "PIC keyboard" connected ??