Subversion Repositories pentevo

Rev

Rev 75 | Rev 151 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3.  
  4. #include <util/delay.h>
  5.  
  6. #include "mytypes.h"
  7. #include "main.h"
  8. #include "ps2.h"
  9. #include "zx.h"
  10. #include "pins.h"
  11. #include "spi.h"
  12. #include "rs232.h"
  13.  
  14.  
  15. UBYTE ps2_decode(UBYTE count, UWORD shifter)
  16. {
  17.         UBYTE t,byte;
  18.  
  19.         if( count!=0 ) return 0x00; // have nothing received
  20.  
  21.         // check packet:
  22.         //shifter.hi - stp.par.7.6.5.4.3.2
  23.         //shifter.lo - 1.0.strt.x.x.x.x.x
  24.  
  25.         if( !( shifter&0x8000 ) ) return 0x00; // stopbit must be 1
  26.         if( shifter&0x0020 ) return 0x00; // startbit must be 0
  27.  
  28.  
  29.         byte = (UBYTE) ( 0x00FF & (shifter>>6) );
  30.  
  31.         t = byte ^ (byte>>4);
  32.         t = t ^ (t>>2);
  33.         t = t ^ (t>>1); // parity
  34.  
  35.         t = t ^ (UBYTE) ( shifter>>14 ); // compare parities
  36.  
  37.         if( !(t&1) ) return 0x00; // must be different
  38.  
  39.         return byte;
  40. }
  41.  
  42. UWORD ps2_encode(UBYTE byte)
  43. {
  44.         UWORD t;
  45.         t = byte ^ (byte>>4);
  46.         t = t ^ (t>>2);
  47.         t = ~(1 & (t ^ (t>>1))); // parity
  48.  
  49.         t = (((t<<8) + byte)<<1) + 0x0400;
  50.  
  51.         // prepare to shifter:
  52.         //shifter.hi - x.x.x.x.x.stp.par.7
  53.         //shifter.lo - 6.5.4.3.2.1.0.strt
  54.         return t;
  55. }
  56.  
  57. volatile UWORD ps2keyboard_shifter;
  58. volatile UBYTE ps2keyboard_count;
  59. volatile UBYTE ps2keyboard_timeout;
  60.  
  61. void ps2keyboard_task(void)
  62. {
  63.         UBYTE byte;
  64.  
  65.         if( ps2keyboard_count!=0 ) return; // not received anything
  66.  
  67.         byte = ps2_decode(ps2keyboard_count, ps2keyboard_shifter);
  68.         if( byte ) // there is no zero byte in scancode tables so we can ignore and use it as 'nothing received'
  69.         {
  70.                 ps2keyboard_parse(byte);
  71.         }
  72.  
  73.         ps2keyboard_count = 11; // re-init shift counter
  74.  
  75.         //release ps2 receiver (disabled by now)
  76.         EIFR = (1<<INTF4); // clr any spurious int which can happen when we pulldown clock pin
  77.         PS2KBCLK_DDR  &= ~(1<<PS2KBCLK);
  78.         PS2KBCLK_PORT |= (1<<PS2KBCLK);  //release clk pin
  79. }
  80.  
  81. void ps2keyboard_parse(UBYTE recbyte)
  82. {
  83.         static UBYTE was_release = 0;
  84.         static UBYTE was_E0 = 0;
  85.  
  86.         static UBYTE last_scancode = 0;
  87.         static UBYTE last_scancode_E0 = 1;
  88.  
  89.         static UBYTE skipshit = 0;
  90.  
  91. #ifdef LOGENABLE
  92.         char log_ps2keyboard_parse[] = "KB..\r\n";
  93.         log_ps2keyboard_parse[2] = ((recbyte >> 4) <= 9 )?'0'+(recbyte >> 4):'A'+(recbyte >> 4)-10;
  94.         log_ps2keyboard_parse[3] = ((recbyte & 0x0F) <= 9 )?'0'+(recbyte & 0x0F):'A'+(recbyte & 0x0F)-10;
  95.         to_log(log_ps2keyboard_parse);
  96. #endif
  97.  
  98.  
  99.         if( skipshit )
  100.         {
  101.                 skipshit--;
  102.                 return;
  103.         }
  104.  
  105.  
  106.         if( recbyte==0xFA ) return;
  107.         if( recbyte==0xFE ) return;
  108.         if( recbyte==0xEE ) return;
  109.         if( recbyte==0xAA ) return;
  110.  
  111.  
  112.         if( recbyte==0xE0 )
  113.         {
  114.                 was_E0 = 1;
  115.                 return;
  116.         }
  117.  
  118.  
  119.         if( recbyte==0xF0 )
  120.         {
  121.                 was_release = 1;
  122.                 return;
  123.         }
  124.  
  125.         if( recbyte==0xE1 ) // pause pressed
  126.         {
  127.                 skipshit=7;
  128.                 return; // skip next 7 bytes
  129.         }
  130.  
  131.  
  132.         if( (recbyte==last_scancode) && (was_E0==last_scancode_E0) )
  133.         {
  134.                 if( was_release )
  135.                 {
  136.                         last_scancode = 0x00;
  137.                         last_scancode_E0 = 1; // impossible scancode: E0 00
  138.                 }
  139.                 else // was depress
  140.                 {
  141.                         return;
  142.                 }
  143.         }
  144.  
  145.         if( !was_release )
  146.         {
  147.                 last_scancode = recbyte;
  148.                 last_scancode_E0 = was_E0;
  149.         }
  150.  
  151.         if( (recbyte==0x12) && was_E0 ) // skip E0 12
  152.         {
  153.                 was_E0 = 0;
  154.                 was_release = 0;
  155.                 return;
  156.         }
  157.  
  158.  
  159.         to_zx( recbyte, was_E0, was_release ); // send valid scancode to zx decoding stage
  160.  
  161.         was_E0 = 0;
  162.         was_release = 0;
  163.  
  164.         return;
  165. }
  166.  
  167. volatile UWORD ps2mouse_shifter;
  168. volatile UBYTE ps2mouse_count;
  169. volatile UBYTE ps2mouse_timeout;
  170. volatile UBYTE ps2mouse_initstep;
  171. volatile UBYTE ps2mouse_resp_count;
  172.  
  173. UBYTE ps2mouse_init_sequence[] =
  174.         "\xFF"      //
  175.         "\xFF"      // reset
  176.         "\xFF"      //
  177.         "\xF3\xC8"  // set sample rate 200  | switch to
  178.         "\xF3\x64"  // set sample rate 100  |     scroll
  179.         "\xF3\x50"  // set sample rate 80   |         mode
  180.         "\xF2"      // get device type
  181.         "\xF3\x0A"  // set sample rate 10
  182.         "\xF2"      // get device type
  183.         "\xE8\x02"  // set resolution
  184.         "\xE6"      // set scaling 1:1
  185.         "\xF3\x64"  // set sample rate 100
  186.         "\xF4"      // enable
  187.         ;
  188.  
  189. static void ps2mouse_release_clk(void)
  190. {
  191.         ps2mouse_count = 12; //counter reinit
  192.         if( flags_register & FLAG_PS2MOUSE_DIRECTION )
  193.         {
  194.                 PS2MSDAT_DDR &= ~(1<<PS2MSDAT); //ps2 mouse data pin to input mode
  195.                 flags_register &= ~(FLAG_PS2MOUSE_DIRECTION); //clear direction
  196.         }
  197.  
  198.         //release ps2 receiver (disabled by now)
  199.         EIFR = (1<<INTF5); // clr any spurious int which can happen when we pulldown clock pin
  200.         PS2MSCLK_DDR  &= ~(1<<PS2MSCLK); //ps2 mouse clk pin to input mode
  201.         PS2MSCLK_PORT |= (1<<PS2MSCLK);  //release clk pin
  202. }
  203.  
  204. void ps2mouse_send(UBYTE data)
  205. {
  206.         ps2mouse_shifter = ps2_encode(data); //prepare data
  207.         flags_register |= FLAG_PS2MOUSE_DIRECTION; //set send mode
  208.         PS2MSCLK_PORT &= ~(1<<PS2MSCLK); //bring ps2 mouse clk pin -
  209.     PS2MSCLK_DDR  |= (1<<PS2MSCLK);  //generate interruption
  210. }
  211.  
  212. void ps2mouse_task(void)
  213. {
  214.         UBYTE byte;
  215.  
  216.         if ( ( ps2mouse_count == 12 ) &&
  217.                  ( ps2mouse_resp_count == 0) &&
  218.                  ( ps2mouse_init_sequence[ps2mouse_initstep] != 0 ) )
  219.         {
  220.                 //delay need for pause between release and hold clk pin
  221.                 _delay_us(100);
  222.  
  223.                 //initialization not complete
  224.                 //send next command to mouse
  225.                 ps2mouse_send(ps2mouse_init_sequence[ps2mouse_initstep]);
  226.                 ps2mouse_resp_count++;
  227.         }
  228.  
  229.         if ( ( ps2mouse_count<12 ) &&
  230.                  ( ps2mouse_timeout==0 ) )
  231.         {
  232.                 //error due send/receive
  233.                 ps2mouse_release_clk();
  234. #ifdef LOGENABLE
  235.                 to_log("MSerr\r\n");
  236. #endif
  237.                 //disable mouse
  238.                 zx_mouse_reset(0);
  239.  
  240.                 //TODO: ўхЄр фхырЄ№ ўЄюс√ яыєу рэф яырщ с√ы
  241.                 //Єшяр хёыш ьрєё єцх яЁюшэшЎшрышчшЁютрэ Єю шэшЄшЄ№ чрэютю
  242.         }
  243.  
  244.         if ( ps2mouse_count!=0 ) return; // not received anything
  245.  
  246.         if ( !(flags_register&FLAG_PS2MOUSE_DIRECTION) )
  247.         {
  248.                 //receive complete
  249.                 byte = ps2_decode(ps2mouse_count, ps2mouse_shifter);
  250.  
  251. #ifdef LOGENABLE
  252. {
  253.         char log_ps2mouse_parse[] = "MS<..\r\n";
  254.         log_ps2mouse_parse[3] = ((byte >> 4) <= 9 )?'0'+(byte >> 4):'A'+(byte >> 4)-10;
  255.         log_ps2mouse_parse[4] = ((byte & 0x0F) <= 9 )?'0'+(byte & 0x0F):'A'+(byte & 0x0F)-10;
  256.         to_log(log_ps2mouse_parse);
  257. }
  258. #endif
  259.  
  260.                 switch( ps2mouse_init_sequence[ps2mouse_initstep] )
  261.                 {
  262.                         //initialization complete - working mode
  263.                         case 0:
  264.                                 //TODO: send to ZX here
  265.                                 ps2mouse_resp_count++;
  266.                                 switch( ps2mouse_resp_count )
  267.                                 {
  268.                                 case 1:
  269.                                         //byte 1: Y overflow | X overflow | Y sign bit | X sign bit | 1 | Middle Btn | Right Btn | Left Btn
  270.                                         zx_mouse_button = (zx_mouse_button&0xF0) + ((byte^0x07)&0x0F);
  271.                                         break;
  272.                                 case 2:
  273.                                         //byte 2: X movement
  274.                                         zx_mouse_x += byte;
  275.                                         break;
  276.                                 case 3:
  277.                                         //byte 3: Y movement
  278.                                         zx_mouse_y += byte;
  279.                                         if ( !(flags_register&FLAG_PS2MOUSE_TYPE) )
  280.                                         {
  281.                                                 //classical mouse
  282.                                                 ps2mouse_resp_count = 0;
  283.                                                 flags_register |= FLAG_PS2MOUSE_ZX_READY;
  284.                                         }
  285.                                         break;
  286.                                 case 4:
  287.                                         //byte 4: wheel movement
  288.                                         zx_mouse_button += ((byte<<4)&0xF0);
  289.                                         flags_register |= FLAG_PS2MOUSE_ZX_READY;
  290.                                         ps2mouse_resp_count = 0;
  291.                                 }
  292.                                 break;
  293.  
  294.                         //reset command
  295.                         case 0xFF:
  296.                                 if ( ps2mouse_resp_count==1 )
  297.                                 {
  298.                                         //must be acknowledge
  299.                                         if ( byte != 0xFA )
  300.                                         {
  301.                                                 //reset initialization
  302.                                                 ps2mouse_initstep = 0;
  303.                                                 ps2mouse_resp_count = 0;
  304.                                                 break;
  305.                                         }
  306.                                 }
  307.                                 ps2mouse_resp_count++;
  308.                                 if ( ps2mouse_resp_count >= 4 )
  309.                                 {
  310.                                         ps2mouse_resp_count = 0;
  311.                                         ps2mouse_initstep++;
  312.                                 }
  313.                                 break;
  314.  
  315.                         //get device type
  316.                         case 0xF2:
  317.                                 if ( ps2mouse_resp_count==1 )
  318.                                 {
  319.                                         ps2mouse_resp_count++;
  320.                                         //must be acknowledge
  321.                                         if ( byte != 0xFA )
  322.                                         {
  323.                                                 //reset initialization
  324.                                                 ps2mouse_initstep = 0;
  325.                                                 ps2mouse_resp_count = 0;
  326.                                         }
  327.                                         break;
  328.                                 }
  329.                                 else
  330.                                 {
  331.                                         ps2mouse_resp_count = 0;
  332.                                         ps2mouse_initstep++;
  333.  
  334.                                         if ( byte > 0 )
  335.                                         {
  336.                                                 flags_register |= FLAG_PS2MOUSE_TYPE;
  337.                                         }
  338.                                         else
  339.                                         {
  340.                                                 flags_register &= ~(FLAG_PS2MOUSE_TYPE);
  341.                                         }
  342.                                 }
  343.                                 break;
  344.  
  345.                         //other commands
  346.                         default:
  347.                                 if ( ps2mouse_resp_count==1 )
  348.                                 {
  349.                                         //must be acknowledge
  350.                                         if ( byte != 0xFA )
  351.                                         {
  352.                                                 //reset initialization
  353.                                                 ps2mouse_initstep = 0;
  354.                                                 ps2mouse_resp_count = 0;
  355.                                                 break;
  356.                                         }
  357.                                 }
  358.                                 ps2mouse_resp_count = 0;
  359.                                 ps2mouse_initstep++;
  360.                                 break;
  361.                 }
  362.         }
  363. #ifdef LOGENABLE
  364.         else
  365.         {
  366.                 //send complete
  367.                 char log_ps2mouse_parse[] = "MS>..\r\n";
  368.                 byte = ps2mouse_init_sequence[ps2mouse_initstep];
  369.                 log_ps2mouse_parse[3] = ((byte >> 4) <= 9 )?'0'+(byte >> 4):'A'+(byte >> 4)-10;
  370.                 log_ps2mouse_parse[4] = ((byte & 0x0F) <= 9 )?'0'+(byte & 0x0F):'A'+(byte & 0x0F)-10;
  371.                 to_log(log_ps2mouse_parse);
  372.         }
  373. #endif
  374.  
  375.         ps2mouse_release_clk();
  376. }
  377.  
  378.