Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  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. //if want Log than comment next string
  15. #undef LOGENABLE
  16.  
  17. UBYTE ps2_decode(UBYTE count, UWORD shifter)
  18. {
  19.         UBYTE t,byte;
  20.  
  21.         if( count!=0 ) return 0x00; // have nothing received
  22.  
  23.         // check packet:
  24.         //shifter.hi - stp.par.7.6.5.4.3.2
  25.         //shifter.lo - 1.0.strt.x.x.x.x.x
  26.  
  27.         if( !( shifter&0x8000 ) ) return 0x00; // stopbit must be 1
  28.         if( shifter&0x0020 ) return 0x00; // startbit must be 0
  29.  
  30.  
  31.         byte = (UBYTE) ( 0x00FF & (shifter>>6) );
  32.  
  33.         t = byte ^ (byte>>4);
  34.         t = t ^ (t>>2);
  35.         t = t ^ (t>>1); // parity
  36.  
  37.         t = t ^ (UBYTE) ( shifter>>14 ); // compare parities
  38.  
  39.         if( !(t&1) ) return 0x00; // must be different
  40.  
  41.         return byte;
  42. }
  43.  
  44. UWORD ps2_encode(UBYTE byte)
  45. {
  46.         UWORD t;
  47.         t = byte ^ (byte>>4);
  48.         t = t ^ (t>>2);
  49.         t = ~(1 & (t ^ (t>>1))); // parity
  50.  
  51.         t = (((t<<8) + byte)<<1) + 0x0400;
  52.  
  53.         // prepare to shifter:
  54.         //shifter.hi - x.x.x.x.x.stp.par.7
  55.         //shifter.lo - 6.5.4.3.2.1.0.strt
  56.         return t;
  57. }
  58.  
  59. volatile UWORD ps2keyboard_shifter;
  60. volatile UBYTE ps2keyboard_count;
  61. volatile UBYTE ps2keyboard_timeout;
  62. volatile UBYTE ps2keyboard_cmd_count;
  63. volatile UBYTE ps2keyboard_cmd;
  64.  
  65. static void ps2keyboard_release_clk(void)
  66. {
  67.         ps2keyboard_count = 12; //counter reinit
  68.         if( flags_register & FLAG_PS2KEYBOARD_DIRECTION )
  69.         {
  70.                 PS2KBDAT_DDR &= ~(1<<PS2KBDAT); //ps2 keyboard data pin to input mode
  71.                 flags_register &= ~(FLAG_PS2KEYBOARD_DIRECTION); //set to receive mode
  72.         }
  73.  
  74.         //release ps2 receiver (disabled by now)
  75.         EIFR = (1<<INTF4); // clr any spurious int which can happen when we pulldown clock pin
  76.         PS2KBCLK_DDR  &= ~(1<<PS2KBCLK); //ps2 keyboard clk pin to input mode
  77.         PS2KBCLK_PORT |= (1<<PS2KBCLK);  //release clk pin
  78. }
  79.  
  80. void ps2keyboard_send(UBYTE data)
  81. {
  82. #ifdef LOGENABLE
  83. {
  84.         char log_ps2kb_parse[] = "KB>..\r\n";
  85.         UBYTE b = data;
  86.         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  87.         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  88.         to_log(log_ps2kb_parse);
  89. }
  90. #endif
  91.         ps2keyboard_shifter = ps2_encode(data); //prepare data
  92.         flags_register |= FLAG_PS2KEYBOARD_DIRECTION; //set send mode
  93.         PS2KBCLK_PORT &= ~(1<<PS2KBCLK); //bring ps2 keyboard clk pin -
  94.     PS2KBCLK_DDR  |= (1<<PS2KBCLK);  //generate interruption
  95. }
  96.  
  97. void ps2keyboard_task(void)
  98. {
  99.         UBYTE b;
  100.  
  101.         if ( ( ps2keyboard_count == 12 ) &&
  102.                  ( ps2keyboard_cmd != 0) &&
  103.                  ( ps2keyboard_cmd_count != 0 ) )
  104.         {
  105.                 //delay need for pause between release and hold clk pin
  106.                 _delay_us(100);
  107.  
  108.                 //if need send command on current stage
  109.                 if ( ((ps2keyboard_cmd_count == 4)&&(ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)) ||
  110.                      ((ps2keyboard_cmd_count == 3)&&(ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)) )
  111.                 {
  112.                         ps2keyboard_send(ps2keyboard_cmd);
  113.                         ps2keyboard_cmd_count--;
  114.                 }
  115.                 else
  116.                 //if need send led data on current stage
  117.                 if ( ((ps2keyboard_cmd_count == 2)&&(ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)) )
  118.                 {
  119.                         b = PS2KEYBOARD_LED_SCROLLOCK&modes_register;
  120.                         ps2keyboard_send(b);
  121.                         ps2keyboard_cmd_count--;
  122.                 }
  123.         }
  124.  
  125.         if ( ( ps2keyboard_count<12 ) &&
  126.                  ( ps2keyboard_timeout==0 ) )
  127.         {
  128.                 //error due send/receive
  129.                 ps2keyboard_release_clk();
  130. #ifdef LOGENABLE
  131.                 to_log("KBerr\r\n");
  132. #endif
  133.                 //TODO: ўхЄр фхырЄ№
  134.  
  135.                 //reset command
  136.                 ps2keyboard_cmd_count = 0;
  137.                 ps2keyboard_cmd = 0;
  138.  
  139.                 //reset buffer
  140.                 zx_clr_kb();
  141.         }
  142.  
  143.         if ( ps2keyboard_count!=0 ) return; // not received anything
  144.  
  145.         if ( !(flags_register&FLAG_PS2KEYBOARD_DIRECTION) )
  146.         {
  147.                 //receive complete
  148.                 b = ps2_decode(ps2keyboard_count, ps2keyboard_shifter);
  149. #ifdef LOGENABLE
  150. {
  151.         char log_ps2kb_parse[] = "KB<..\r\n";
  152.         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  153.         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  154.         to_log(log_ps2kb_parse);
  155. }
  156. #endif
  157.                 if ( ps2keyboard_cmd )
  158.                 {
  159.                         //wait for 0xFA on current stage
  160.                         if ( ((ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)&&(ps2keyboard_cmd_count == 3 || ps2keyboard_cmd_count == 1)) ||
  161.                              ((ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)&&(ps2keyboard_cmd_count == 2)) )
  162.                         {
  163.                                 if( b != 0xFA )
  164.                                 {
  165.                                         ps2keyboard_cmd_count = 0;
  166.                                         //if non FA - may be scan code received
  167.                                         if ( b ) ps2keyboard_parse(b);
  168.                                 }
  169.                                 else ps2keyboard_cmd_count--;
  170.  
  171.                                 if ( ps2keyboard_cmd_count == 0 ) ps2keyboard_cmd = 0;
  172.                         }
  173.                         else
  174.                         //wait for 0xAA on current stage
  175.                         if ( ((ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)&&(ps2keyboard_cmd_count == 1)) )
  176.                         {
  177.                                 if ( b != 0xAA )
  178.                                 {
  179.                                         //if non AA - may be scan code received
  180.                                         if ( b ) ps2keyboard_parse(b);
  181.                                 }
  182.                                 ps2keyboard_cmd_count = 0;
  183.                                 ps2keyboard_cmd = 0;
  184.                         }
  185.                 }
  186.                 else
  187.                 if ( b ) // there is no zero byte in scancode tables so we can ignore and use it as 'nothing received'
  188.                 {
  189.                         ps2keyboard_parse(b);
  190.                 }
  191.         }
  192.  
  193.         ps2keyboard_release_clk();
  194. }
  195.  
  196. void ps2keyboard_send_cmd(UBYTE cmd)
  197. {
  198.         if ( ps2keyboard_cmd == 0 )
  199.         {
  200.                 ps2keyboard_cmd = cmd;
  201.                 switch ( cmd )
  202.                 {
  203.                 case PS2KEYBOARD_CMD_RESET:
  204.                         ps2keyboard_cmd_count = 3;
  205.                         break;
  206.                 case PS2KEYBOARD_CMD_SETLED:
  207.                         ps2keyboard_cmd_count = 4;
  208.                         break;
  209.                 default:
  210.                         ps2keyboard_cmd = 0;
  211.                 }
  212.         }
  213. }
  214.  
  215. void ps2keyboard_parse(UBYTE recbyte)
  216. {
  217.         static UBYTE was_release = 0;
  218.         static UBYTE was_E0 = 0;
  219.  
  220.         static UBYTE last_scancode = 0;
  221.         static UBYTE last_scancode_E0 = 1;
  222.  
  223.         static UBYTE skipshit = 0;
  224.  
  225. #ifdef LOGENABLE
  226.         char log_ps2keyboard_parse[] = "KB..\r\n";
  227.         if ( skipshit ) log_ps2keyboard_parse[1] = skipshit + '0';
  228.         log_ps2keyboard_parse[2] = ((recbyte >> 4) <= 9 )?'0'+(recbyte >> 4):'A'+(recbyte >> 4)-10;
  229.         log_ps2keyboard_parse[3] = ((recbyte & 0x0F) <= 9 )?'0'+(recbyte & 0x0F):'A'+(recbyte & 0x0F)-10;
  230.         to_log(log_ps2keyboard_parse);
  231. #endif
  232.  
  233.  
  234.         if( skipshit )
  235.         {
  236.                 skipshit--;
  237.                 return;
  238.         }
  239.  
  240.  
  241.         if( recbyte==0xFA ) return;
  242.         if( recbyte==0xFE ) return;
  243.         if( recbyte==0xEE ) return;
  244.         if( recbyte==0xAA ) return;
  245.  
  246.  
  247.         if( recbyte==0xE0 )
  248.         {
  249.                 was_E0 = 1;
  250.                 return;
  251.         }
  252.  
  253.  
  254.         if( recbyte==0xF0 )
  255.         {
  256.                 was_release = 1;
  257.                 return;
  258.         }
  259.  
  260.         if( recbyte==0xE1 ) // pause pressed
  261.         {
  262.                 skipshit=7;
  263.                 return; // skip next 7 bytes
  264.         }
  265.  
  266.  
  267.         if( (recbyte==last_scancode) && (was_E0==last_scancode_E0) )
  268.         {
  269.                 if( was_release )
  270.                 {
  271.                         last_scancode = 0x00;
  272.                         last_scancode_E0 = 1; // impossible scancode: E0 00
  273.                 }
  274.                 else // was depress
  275.                 {
  276.                         return;
  277.                 }
  278.         }
  279.  
  280.         if( !was_release )
  281.         {
  282.                 last_scancode = recbyte;
  283.                 last_scancode_E0 = was_E0;
  284.         }
  285.  
  286.         if( (recbyte==0x12) && was_E0 ) // skip E0 12
  287.         {
  288.                 was_E0 = 0;
  289.                 was_release = 0;
  290.                 return;
  291.         }
  292.  
  293.  
  294.         to_zx( recbyte, was_E0, was_release ); // send valid scancode to zx decoding stage
  295.  
  296.         was_E0 = 0;
  297.         was_release = 0;
  298.  
  299.         return;
  300. }
  301.  
  302. volatile UWORD ps2mouse_shifter;
  303. volatile UBYTE ps2mouse_count;
  304. volatile UBYTE ps2mouse_timeout;
  305. volatile UBYTE ps2mouse_initstep;
  306. volatile UBYTE ps2mouse_resp_count;
  307.  
  308. UBYTE ps2mouse_init_sequence[] =
  309.         "\xFF"      //
  310.         "\xFF"      // reset
  311.         "\xFF"      //
  312.         "\xF3\xC8"  // set sample rate 200  | switch to
  313.         "\xF3\x64"  // set sample rate 100  |     scroll
  314.         "\xF3\x50"  // set sample rate 80   |         mode
  315.         "\xF2"      // get device type
  316.         "\xF3\x0A"  // set sample rate 10
  317.         "\xF2"      // get device type
  318.         "\xE8\x02"  // set resolution
  319.         "\xE6"      // set scaling 1:1
  320.         "\xF3\x64"  // set sample rate 100
  321.         "\xF4"      // enable
  322.         ;
  323.  
  324. static void ps2mouse_release_clk(void)
  325. {
  326.         ps2mouse_count = 12; //counter reinit
  327.         if( flags_register & FLAG_PS2MOUSE_DIRECTION )
  328.         {
  329.                 PS2MSDAT_DDR &= ~(1<<PS2MSDAT); //ps2 mouse data pin to input mode
  330.                 flags_register &= ~(FLAG_PS2MOUSE_DIRECTION); //set to receive mode
  331.         }
  332.  
  333.         //release ps2 receiver (disabled by now)
  334.         EIFR = (1<<INTF5); // clr any spurious int which can happen when we pulldown clock pin
  335.         PS2MSCLK_DDR  &= ~(1<<PS2MSCLK); //ps2 mouse clk pin to input mode
  336.         PS2MSCLK_PORT |= (1<<PS2MSCLK);  //release clk pin
  337. }
  338.  
  339. void ps2mouse_send(UBYTE data)
  340. {
  341.         ps2mouse_shifter = ps2_encode(data); //prepare data
  342.         flags_register |= FLAG_PS2MOUSE_DIRECTION; //set send mode
  343.         PS2MSCLK_PORT &= ~(1<<PS2MSCLK); //bring ps2 mouse clk pin -
  344.     PS2MSCLK_DDR  |= (1<<PS2MSCLK);  //generate interruption
  345. }
  346.  
  347. void ps2mouse_task(void)
  348. {
  349.         UBYTE b;
  350.  
  351.         if ( ( ps2mouse_count == 12 ) &&
  352.                  ( ps2mouse_resp_count == 0) &&
  353.                  ( ps2mouse_init_sequence[ps2mouse_initstep] != 0 ) )
  354.         {
  355.                 //delay need for pause between release and hold clk pin
  356.                 _delay_us(200);
  357.  
  358.                 //initialization not complete
  359.                 //send next command to mouse
  360.                 ps2mouse_send(ps2mouse_init_sequence[ps2mouse_initstep]);
  361.                 ps2mouse_resp_count++;
  362.         }
  363.  
  364.         if ( ( ps2mouse_count<12 ) &&
  365.                  ( ps2mouse_timeout==0 ) )
  366.         {
  367. #ifdef LOGENABLE
  368.                 char log_ps2mouse_err[] = "MS.err.\r\n";
  369.                 if( flags_register&FLAG_PS2MOUSE_DIRECTION ) log_ps2mouse_err[2]='S';   else log_ps2mouse_err[2]='R';
  370.                 if( ps2mouse_count<10 ) log_ps2mouse_err[6]='0'+ps2mouse_count;  else log_ps2mouse_err[6]='A'+ps2mouse_count-10;
  371.                 to_log(log_ps2mouse_err);
  372. #endif
  373.                 //error due exchange data with PS/2 mouse
  374.  
  375.                 //get direction
  376.                 b = flags_register&FLAG_PS2MOUSE_DIRECTION;
  377.  
  378.                 //reset pins and states
  379.                 ps2mouse_release_clk();
  380.  
  381.                 //analizing error
  382.                 if( b && (ps2mouse_initstep==0) )
  383.                 {
  384.                         //error due send first init byte - mouse not connected to PS/2
  385.  
  386.                         //disable mouse
  387.                         zx_mouse_reset(0);
  388.                 }
  389.                 else
  390.                 {
  391.                         //error due receive or send non first byte - mouse connected to PS/2
  392.  
  393.                         //re-init mouse
  394.                         ps2mouse_initstep = 0;
  395.                 }
  396.         }
  397.  
  398.         if ( ps2mouse_count!=0 ) return; // not received anything
  399.  
  400.         if ( !(flags_register&FLAG_PS2MOUSE_DIRECTION) )
  401.         {
  402.                 //receive complete
  403.                 b = ps2_decode(ps2mouse_count, ps2mouse_shifter);
  404.  
  405. #ifdef LOGENABLE
  406. {
  407.         char log_ps2mouse_parse[] = "MS<..\r\n";
  408.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  409.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  410.         to_log(log_ps2mouse_parse);
  411. }
  412. #endif
  413.  
  414.                 switch( ps2mouse_init_sequence[ps2mouse_initstep] )
  415.                 {
  416.                         //initialization complete - working mode
  417.                         case 0:
  418.                                 //TODO: send to ZX here
  419.                                 ps2mouse_resp_count++;
  420.                                 switch( ps2mouse_resp_count )
  421.                                 {
  422.                                 case 1:
  423.                                         //byte 1: Y overflow | X overflow | Y sign bit | X sign bit | 1 | Middle Btn | Right Btn | Left Btn
  424.                                         zx_mouse_button = (zx_mouse_button&0xF0) + ((b^0x07)&0x0F);
  425.                                         break;
  426.                                 case 2:
  427.                                         //byte 2: X movement
  428.                                         zx_mouse_x += b;
  429.                                         break;
  430.                                 case 3:
  431.                                         //byte 3: Y movement
  432.                                         zx_mouse_y += b;
  433.                                         if ( !(flags_register&FLAG_PS2MOUSE_TYPE) )
  434.                                         {
  435.                                                 //classical mouse
  436.                                                 ps2mouse_resp_count = 0;
  437.                                                 flags_register |= FLAG_PS2MOUSE_ZX_READY;
  438.                                         }
  439.                                         break;
  440.                                 case 4:
  441.                                         //byte 4: wheel movement
  442.                                         zx_mouse_button += ((b<<4)&0xF0);
  443.                                         flags_register |= FLAG_PS2MOUSE_ZX_READY;
  444.                                         ps2mouse_resp_count = 0;
  445.                                 }
  446.                                 break;
  447.  
  448.                         //reset command
  449.                         case 0xFF:
  450.                                 if ( ps2mouse_resp_count==1 )
  451.                                 {
  452.                                         //must be acknowledge
  453.                                         if ( b != 0xFA )
  454.                                         {
  455.                                                 //reset initialization
  456.                                                 ps2mouse_initstep = 0;
  457.                                                 ps2mouse_resp_count = 0;
  458.                                                 break;
  459.                                         }
  460.                                 }
  461.                                 ps2mouse_resp_count++;
  462.                                 if ( ps2mouse_resp_count >= 4 )
  463.                                 {
  464.                                         ps2mouse_resp_count = 0;
  465.                                         ps2mouse_initstep++;
  466.                                 }
  467.                                 break;
  468.  
  469.                         //get device type
  470.                         case 0xF2:
  471.                                 if ( ps2mouse_resp_count==1 )
  472.                                 {
  473.                                         ps2mouse_resp_count++;
  474.                                         //must be acknowledge
  475.                                         if ( b != 0xFA )
  476.                                         {
  477.                                                 //reset initialization
  478.                                                 ps2mouse_initstep = 0;
  479.                                                 ps2mouse_resp_count = 0;
  480.                                         }
  481.                                         break;
  482.                                 }
  483.                                 else
  484.                                 {
  485.                                         ps2mouse_resp_count = 0;
  486.                                         ps2mouse_initstep++;
  487.  
  488.                                         if ( b > 0 )
  489.                                         {
  490.                                                 flags_register |= FLAG_PS2MOUSE_TYPE;
  491.                                         }
  492.                                         else
  493.                                         {
  494.                                                 flags_register &= ~(FLAG_PS2MOUSE_TYPE);
  495.                                         }
  496.                                 }
  497.                                 break;
  498.  
  499.                         //other commands
  500.                         default:
  501.                                 if ( ps2mouse_resp_count==1 )
  502.                                 {
  503.                                         //must be acknowledge
  504.                                         if ( b != 0xFA )
  505.                                         {
  506.                                                 //reset initialization
  507.                                                 ps2mouse_initstep = 0;
  508.                                                 ps2mouse_resp_count = 0;
  509.                                                 break;
  510.                                         }
  511.                                 }
  512.                                 ps2mouse_resp_count = 0;
  513.                                 ps2mouse_initstep++;
  514.                                 break;
  515.                 }
  516.         }
  517. //#ifdef LOGENABLE
  518. //      else
  519. //      {
  520. //              //send complete
  521. //              char log_ps2mouse_parse[] = "MS>..\r\n";
  522. //              b = ps2mouse_init_sequence[ps2mouse_initstep];
  523. //              log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  524. //              log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  525. //              to_log(log_ps2mouse_parse);
  526. //      }
  527. //#endif
  528.  
  529.         ps2mouse_release_clk();
  530. }
  531.