Subversion Repositories pentevo

Rev

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