Advertisement
The_Stick

RasPi I2C Slave Bit-Bashing

Mar 27th, 2015
548
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.60 KB | None | 0 0
  1. void *beginListening(void* blank) {
  2.    
  3. #ifdef __linux__
  4.     pthread_mutex_lock(&screenLock);
  5.     mvprintw(2, 1, "Listening...");
  6.     mvprintw(3, 1, "Awaiting addressing...   ");
  7.     mvprintw(4, 1, "                  ");
  8.     refresh();
  9.     pthread_mutex_unlock(&screenLock);
  10. #endif
  11.  
  12.     byte bits = 0;
  13.     unsigned int bytes = 0, xfers = 0;
  14.     byte rxByte = 0;
  15.     byte rxData[512] = {};
  16.     bool readCl = true, pReadCl = true, readDa = true, pReadDa = true;
  17.     bool shouldListen = false;
  18.  
  19.     while(alive) {
  20.         readDa = readPin(DataPin);
  21.         readCl = readPin(ClockPin);
  22.  
  23.         // Need to look for a Start Bit
  24.         if(!readDa && pReadDa & readCl) {  // Falling Data during a High Clock, that's our Start.
  25.            
  26.             // Now wait for a Stop Bit
  27.             while(alive) {
  28.                 readDa = readPin(DataPin);
  29.                 readCl = readPin(ClockPin);
  30.                
  31.                 if(readDa & !pReadDa & readCl) {  // Rising Data during a High Clock, that's the Stop.
  32.                     break;
  33.                 } if(!readDa && pReadDa & readCl) {  // Falling Data during a High Clock, it's a Repeated Start.
  34.                     bits = 0; // Quickly clean up and reset
  35.                     rxByte = 0;
  36.                     bytes = 0; // Don't worry about zeroing the scratch half-a-kilo
  37.  
  38.                     shouldListen = false;
  39.  
  40.                     pReadCl = readCl;
  41.                     pReadDa = readDa;
  42.  
  43.                     continue;
  44.                 } else if(!pReadCl && readCl) {  // Rising Clock, Sample!
  45.                     if(bits < 8) {  // Bits 0 - 7, should be recording
  46.                         rxByte = (rxByte << 1);
  47.                         if(readDa) {
  48.                             rxByte++;
  49.                         }
  50.                     } // Otherwise, this is bit 8, where we should be sending a specific value.
  51.                       // Master should be sampling our Acknolwedge.
  52.                     bits++;
  53.                 } else if(pReadCl && !readCl) {  // Falling Clock, Change!
  54.                     if(bits = 8) { // This is bit 8.  We got a whole byte.
  55.                         if(shouldListen || rxByte & 0xFE == 0x66) { // If the Master's trying to address us, 0x66... (or if we were addressed previously)
  56.                             driveDown(DataPin); // Send the Master an ACK.
  57.                             if(!shouldListen) { // We've just been addressed.
  58.                                 shouldListen = true; // Always ACK until a Repeated Start or Stop Bit.
  59.                             } else {
  60.                                 rxData[bytes++] = rxByte; // Save the byte we just got - overwrites any previous value held
  61.                             }
  62.                         } else {
  63. #ifdef __linux__
  64.                             pthread_mutex_lock(&screenLock);
  65.                             mvprintw(5, 1, "%3i: Message for 0x%02x.", ++xfers, rxByte & 0xFE);
  66.                             move(2, 13);
  67.                             refresh();
  68.                             pthread_mutex_unlock(&screenLock);
  69. #endif
  70.                             break; // Stop listening, this message isn't for us.  Look for another Start Bit.
  71.                         }
  72.                     } else if(bits = 9) { // This is the end of bit 8.  Reaching this code means that we've been addressed.
  73.                         release(DataPin); // We've sent our ACK, let it go.
  74.                         driveDown(ClockPin); // Hold the clock low until we're ready for another byte.
  75.                        
  76. #ifdef __linux__
  77.                         pthread_mutex_lock(&screenLock);
  78.                         mvprintw(3, 1, "Incoming data...         ");
  79.                         mvprintw(4, 1, "%3i bytes given.    ", bytes);
  80.                         mvprintw(5, 1, "                         ");
  81.                         move(2, 13);
  82.                         refresh();
  83.                         pthread_mutex_unlock(&screenLock);
  84. #endif
  85.  
  86.                         release(ClockPin);
  87.                     } // Otherwise, the master should be changing bits now.
  88.                    
  89.                 }
  90.  
  91.                 pReadCl = readCl;
  92.                 pReadDa = readDa;
  93.             }
  94.  
  95.             shouldListen = false;
  96.  
  97.             bits = 0;  rxByte = 0;  bytes = 0; // Don't worry about zeroing the scratch half-a-kilo
  98.  
  99.             // Do things with the obtained data here.
  100.  
  101. #ifdef __linux__
  102.             pthread_mutex_lock(&screenLock);
  103.             mvprintw(3, 1, "Awaiting addressing...   ");
  104.             move(2, 13);
  105.             refresh();
  106.             pthread_mutex_unlock(&screenLock);
  107.         } else {
  108.             usleep(500);
  109. #endif
  110.         }
  111.  
  112.         pReadCl = readCl;
  113.         pReadDa = readDa;
  114.     }
  115.  
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement