001 #define CYBER_DDR   DDRC
002 #define CYBER_PORT  PORTC
003 #define CYBER_PIN   PINC
004 
005 #define CYBER_LH_BIT    (1 << 4)
006 #define CYBER_ACK_BIT   (1 << 5)
007 #define CYBER_REQ_BIT   (1 << 6)
008 #define CYBER_REQ_OFF   CYBER_PORT &= ~CYBER_REQ_BIT
009 #define CYBER_REQ_ON    CYBER_PORT |= CYBER_REQ_BIT
010 
011 #define CYBER_TIMEOUT   32767
012 
013 void InitCyberStick(void) {
014   CYBER_DDR |= CYBER_REQ_BIT;
015   CYBER_REQ_ON;
016 
017   return; 
018 }
019 
020 int GetCyberStick(char data[]) {
021   int cnt;
022   int timer;
023   char temp[12], *ptr;
024 
025   CYBER_REQ_OFF;
026 
027   ptr = temp;
028   for(cnt = 0; cnt < 6; cnt++) {
029     timer = CYBER_TIMEOUT;
030     while(CYBER_PIN & CYBER_LH_BIT) { // Wait until LH goes Low.
031       if(--timer == 0) {
032         return(-1);
033       }
034     }
035 
036     timer = CYBER_TIMEOUT;
037     while(CYBER_PIN & CYBER_ACK_BIT) { // Wait until ACK goes Low.
038       if(--timer == 0) {
039         return(-1);
040       }
041     }
042     *ptr++ = CYBER_PIN & 0x0f;
043 
044     if(cnt == 0) { // Set transfer speed as Fastest mode.
045       CYBER_REQ_ON;
046     }
047 
048     timer = CYBER_TIMEOUT;
049     while(!(CYBER_PIN & CYBER_LH_BIT)) { // Wait until LH goes High.
050       if(--timer == 0) {
051         return(-1);
052       }
053     }
054     timer = CYBER_TIMEOUT;
055     while(CYBER_PIN & CYBER_ACK_BIT) { // Wait until ACK goes Low.
056       if(--timer == 0) {
057         return(-1);
058       }
059     }
060     *ptr++ = CYBER_PIN & 0x0f;
061   }
062 
063   *data++ = ~((temp[0] << 4) | temp[1]);        // Button A B C D E1 E2 F G
064   *data++ = ((temp[2] << 4) | temp[6]) - 0x80;  // Stick Y
065   *data++ = ((temp[3] << 4) | temp[7]) - 0x80;  // Stick X
066   *data++ = ((temp[4] << 4) | temp[8]) - 0x80;  // Throttle
067   *data++ = ((temp[5] << 4) | temp[9]) - 0x80;  // Option
068   *data++ = ~((temp[10] << 4) | 0x0f);          // Button A B A' B' - - - -
069 
070   return(0);
071 }