Forum Rule: Always post complete source code & details to reproduce any issue!
Page 51 of 73 FirstFirst ... 41 49 50 51 52 53 61 ... LastLast
Results 1,251 to 1,275 of 1823

Thread: Project: SPI_MSTransfer

  1. #1251
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    yes setClock is there already before this

  2. #1252
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Cool, just as I was beginning to figure out what we are doing now for I2C and Serial

    Maybe I am just confusing my self here. So with the SPI support you added I can run everything on the master side and just access the bus/CS pin and that's it. Just like we did for I2C.

    What we are doing now with packet transfers still work I am assuming

    Mike

  3. #1253
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    yes everything else is unaffected
    these features are additional

  4. #1254
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Great - I thought so but I had to ask - too many changes too fast

  5. #1255
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Mike, can you guess what I'm working on?

    Code:
      W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      W0.onReceive(hello);
    }
    void hello(size_t count, AsyncMST info) {
      Serial.print("Size: "); Serial.print(count);
      Serial.print(" Slave: "); Serial.print(info.slave);
      Serial.print(" Port: "); Serial.println(info.port);
    
    }
    Output:
    Code:
    Size: 4 Slave: 43 Port: 0
    Other than the callback overload, how EXACT is i2c_t3 calls?

    I have master loop writing to slave in 1 sec intervals:
    Code:
      static uint32_t wire_write_timer = millis();
      if ( millis() - wire_write_timer >= 1000 ) {
        wire_write_timer = millis();
        Wire.beginTransmission(0x22);
        Wire.write('T');
        Wire.write('o');
        Wire.write('n');
        Wire.write('y');
        Wire.endTransmission();
      }
    All 4 Wire(0,1,2,3) are supported (multi-slave too, provided you track the info.slave as the identifier

  6. #1256
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    I2C Slave callback firing, and printing from within callback:
    Code:
      W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      W0.onReceive(hello);
    }
    void hello(size_t count, AsyncMST info) {
      Serial.print("Size: "); Serial.print(count);
      Serial.print(" Slave: "); Serial.print(info.slave);
      Serial.print(" Port: "); Serial.println(info.port);
    
      for ( uint16_t i = 0; i < count; i++ ) {
        Serial.print((char)W0.read());
      } Serial.println();
    }
    Output:
    Code:
    Size: 4 Slave: 43 Port: 0
    Tony
    or you can simply write single packet buffers:
    Code:
      if ( millis() - wire_write_timer >= 1000 ) {
        wire_write_timer = millis();
        Wire.beginTransmission(0x22);
        char text[] = "Hello Mike, this is a test...\n";
        Wire.write(text, sizeof(text));
        char text1[] = "From SPI_MSTransfer...";
        Wire.write(text1, sizeof(text1));
        Wire.endTransmission();
      }
    Code:
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test...
     From SPI_MSTransfer...

  7. #1257
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Here's test sketches running the slave demo, obviously run master after the slave boots so the master calls the slave setup routine and it hits the slave properly


    Master sketch:
    Code:
    #include <SPI.h>
    
    #include "A_ConfigDefines.h"
    #include <SPI_MSTransfer.h>
    #include "TeensyThreads.h"
    #include <EventResponder.h>
    EventResponder  eresp;
    
    
    //0x99BB, 0x0003, 0x99B8
    Threads::Mutex MST_QUEUE;
    
    
    #include "circular_buffer.h"
    
    //#define SPI_SPEED 30500
    #define SPI_SPEED 30000000
    #define OT_CALC   100*(30000000/SPI_SPEED)
    
    SPI_MSTransfer teensy_gpio = SPI_MSTransfer("Serial", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    SPI_MSTransfer W0 = SPI_MSTransfer("Wire", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    SPI_MSTransfer W1 = SPI_MSTransfer("Wire1", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    SPI_MSTransfer sSPI1 = SPI_MSTransfer("SPI1", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    
    
    
    
    void I2Cscan(SPI_MSTransfer &port) {
      SPI_MSTransfer* thePort;
      thePort = &port;
      // scan for i2c devices
      byte error, address;
      int nDevices;
    
      Serial.println("Scanning...");
      nDevices = 0;
      for (address = 1; address < 127; address++ ) {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        thePort->beginTransmission(address);
        error = thePort->endTransmission();
    
        if (error == 0) {
          Serial.print("I2C device found at address 0x");
          if (address < 16) Serial.print("0");
          Serial.print(address, HEX);
          Serial.println("  !");
          nDevices++;
        }
        else if (error == 4) {
          Serial.print("Unknow error at address 0x");
          if (address < 16) Serial.print("0");
          Serial.println(address, HEX);
        }
      }
      if (nDevices == 0) {
        Serial.println("No I2C devices found\n");
        while (1) {};
      } else {
        Serial.println("done\n");
      }
    }
    
    
    
    void myCallback8(uint8_t *buffer, uint16_t length, AsyncMST info) {
      Serial.print("PacketID: "); Serial.println(info.packetID);
      Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
    }
    void myCallback(uint16_t *buffer, uint16_t length, AsyncMST info) {
      //return;
      Serial.print("PacketID: "); Serial.println(info.packetID);
      Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
    }
    uint32_t OverTime = 0;
    
    
    void setup() {
    
      //  SPI_MSTransfer::mtsca._init();
      Serial.begin(115200);
      while (!Serial && millis() < 2000 ) {}
      Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
      teensy_gpio.onTransfer(myCallback);
      teensy_gpio.onTransfer(myCallback8);
    
    
    #ifdef SPI_MST_SCK
      SPI_MST_BUS.setSCK( SPI_MST_SCK );
    #endif
      SPI_MST_BUS.begin();
      //  delay(2000);
      threads.addThread(SPI_MST_Thread);
      Circular_Buffer<double, 16> myFloats;
      myFloats.push_back(3.14159);
      myFloats.push_back(12.3456);
      myFloats.push_back(78.91234);
      myFloats.push_back(7.91234);
      myFloats.push_back(11.91234);
      myFloats.push_back(58.91234);
      myFloats.push_back(18.91234);
      //  myFloats.push_back(2.91234);
    
      Serial.print("SUM: "); Serial.println(myFloats.sum(), 5);
      Serial.print("MIN: "); Serial.println(myFloats.min(), 5);
      Serial.print("MAX: "); Serial.println(myFloats.max(), 5);
      Serial.print("MEDIAN: "); Serial.println(myFloats.median(1), 5);
    
      uint8_t blah[5];
      //  qsort(blah, 5, sizeof(uint8_t), *(uint8_t*)a - *(uint8_t*)b);
      Serial.print("AVG: "); Serial.println(myFloats.average(), 5);
      uint8_t _size = myFloats.size();
      Serial.print("Deviation: "); Serial.println(myFloats.deviation(), 8);
      for ( uint8_t i = 0; i < _size; i++ ) {
        Serial.print(myFloats.pop_front(), 5); Serial.print(" ");
      } Serial.println();
    
      //  while(1);
    
    
      //uint16_t v = 1010;
      //
      //v--;
      //v |= v >> 1;
      //v |= v >> 2;
      //v |= v >> 4;
      //v |= v >> 8;
      //v |= v >> 16;
      //v++;
      //
      //Serial.println(v);
      //uint16_t v = 300;
    
    
    
    
    
      //  Serial.println(v);
    
      // Circular_Buffer<uint16_t, 4> cb2;
    
    
      //  I2Cscan(W0);
      Serial.println(SPI_MSTransfer::stmca.capacity());
      Serial.println(SPI_MSTransfer::stmca.max_size());
      //  teensy_gpio.debug(Serial);
    
      threads.setTimeSlice(0, 1);
      threads.setTimeSlice(1, 10);
    
    
      Wire.begin();
    
      delay(2000);
      //  W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      W0.onReceive(hello);
    }
    void hello(size_t count, AsyncMST info) {
      Serial.print("Size: "); Serial.print(count);
      Serial.print(" Slave: "); Serial.print(info.slave);
      Serial.print(" Port: "); Serial.println(info.port);
    
      for ( uint16_t i = 0; i < count; i++ ) {
        Serial.print((char)W0.read());
      } Serial.println();
    }
    
    
    
    
    
    void SPI_MST_Thread() {
      while (1) {
        { Threads::Scope scope(MST_QUEUE);
          teensy_gpio.events(0);
        }
        threads.yield();
      }
    }
    
    void loop() {
      static uint32_t wire_write_timer = millis();
      if ( millis() - wire_write_timer >= 1000 ) {
        wire_write_timer = millis();
        //    return;
        Wire.beginTransmission(0x22);
        char text[] = "Hello Mike, this is a test...\n";
        Wire.write(text, sizeof(text));
        char text1[] = "From SPI_MSTransfer...";
        Wire.write(text1, sizeof(text1));
        Wire.sendTransmission();
      }
      //  return;
      static bool runonce = 1;
      if ( runonce ) {
        runonce = 0;
      }
      //  teensy_gpio.events(1);
      static uint32_t _timer = micros();
      static uint32_t led_timer = millis();
      if ( millis() - led_timer >= 100 )  {
        led_timer = millis();
        teensy_gpio.pinToggle(LED_BUILTIN);
        //    Serial.println("LED TOGGLE!");
        //    delay(1);
      }
      //  return;
      if ( micros() - _timer >= 1000 ) {
        _timer = micros();
    
        uint8_t bufff[24];
        for (uint8_t i = 0; i < sizeof(bufff); i++) bufff[i] = i;
        //    teensy_gpio.transfer(bufff, sizeof(bufff), 69, 2);
    
        //uint16_t notify = 0xAD00;
    
        //Serial.println(notify |= 1 << 0,HEX);
    
        // set:  notify |= 1 << 7;
        // unset:  notify &= ~(1 << 7);
    
        //    Serial.println(millis());
    
        //    W0.beginTransmission(0x20);
        //    uint8_t ibuffer[3] = { 0x0C, 0xFF, 0xFF };
        //    W0.write(ibuffer, 3); // set pullups
        //    W0.endTransmission();
        //
        //    W0.beginTransmission(0x20);
        //    W0.write(0x12); // set bankA to read
        //    W0.endTransmission();
        //
        //    W0.requestFrom(0x20, 2); // read bankA and bankB
        //    Serial.print(W0.read()); Serial.print(":"); Serial.println(W0.read());
    
    
    
        //    Serial.println( W0.requestFrom(0x48, 1, 1));
    
    
        //    uint8_t buffer[48];
        //
        //    for ( uint8_t i = 0; i < sizeof(buffer); i++ ) {
        //      buffer[i] = i;
        //    }
        //    uint32_t ___time = micros();
        //    teensy_gpio.transfer(buffer, sizeof(buffer), 10750,1);
        //    Serial.print("T: "); Serial.println(micros() - ___time);
        uint32_t _time = micros();
        //    SPIClass teensy_gpio;
        //SPI3 = (SPIClass)teensy_gpio;
        uint16_t *buf;
        double MST_PrintVals[12];
        buf = (uint16_t *)MST_PrintVals;
        int ii = 0;
        static uint16_t __count = 0;
        static uint16_t __countB = 0;
        for ( uint32_t i = 0; i < sizeof(MST_PrintVals) / sizeof( MST_PrintVals[0]  ); i++ ) MST_PrintVals[i] = __count++;
        //    Serial.print("F&F (OT=");
        //    Serial.print( OverTime );
        //    Serial.print(")");
        _time = micros();
        __countB++;
        if ( __countB % 25 ) {
          //      Serial.println();
          //      Serial.print("ACK PacketID 60: ");
          uint32_t t1 = micros();
          { Threads::Scope scope(MST_QUEUE);
            teensy_gpio.transfer16((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 60, 2); // DEBUGHACK output
          }
          //      Serial.print(micros() - t1);
          //      Serial.println("uS");
        }
        else {
          //      Serial.println();
          //      Serial.print("F&F PacketID 55: ");
          uint32_t t2 = micros();
          { Threads::Scope scope(MST_QUEUE);
            teensy_gpio.transfer16((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 55, 2);
          }
          //      Serial.print(micros() - t2);
          //      Serial.println("uS");
        }
        return;
        //    _time = micros() - _time;
        //    Serial.print(" OT_CALC==");
        //    Serial.print(OT_CALC);
        //    Serial.print("  micros() _time==");
        //    Serial.println(_time);
        if ( _time > OT_CALC ) OverTime++;
        //    teensy_gpio.events();
      }
    }
    Slave sketch:
    Code:
    #include <SPI_MSTransfer.h>
    #include <i2c_t3.h>
    SPI_MSTransfer slave = SPI_MSTransfer("SLAVE", "STANDALONE");
    
    void myCallback8(uint8_t *buffer, uint16_t length, AsyncMST info) {
      Serial.print("PacketID: "); Serial.println(info.packetID);
      Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
    }
    void setup() {
      Serial.begin(115200);
      while (!Serial && millis() < 5000 )
      { Serial.print( "Teensy NOT Online @ millis=" );
        Serial.println( millis() );
        delay(30);
      }
      Serial.print( "Teensy Online @ millis=" );
      Serial.println( millis() );
      Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
    
      if ( ARM_DWT_CYCCNT == ARM_DWT_CYCCNT ) {
        Serial.print( "Cycle Counter Not Enabled :" );
        Serial.println( ARM_DWT_CYCCNT );
      }
      if ( ARM_DWT_CYCCNT == ARM_DWT_CYCCNT ) {
        // Enable CPU Cycle Count
        ARM_DEMCR |= ARM_DEMCR_TRCENA;
        ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
      }
      if ( ARM_DWT_CYCCNT != ARM_DWT_CYCCNT ) {
        Serial.print( "Cycle Counter Enabled! :" );
        Serial.println( ARM_DWT_CYCCNT );
      }
      SPI1.begin();
      SPI2.begin();
      SPI1.setSCK(20); SPI1.setMOSI(21); SPI1.setMISO(5); SPI1.begin();
      SPI2.setSCK(46); SPI2.setMOSI(44); SPI2.setMISO(45); SPI2.begin();
      SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); // default speed
      SPI2.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); // default speed
    
      slave.begin( );
      slave.onTransfer(myCallback);
      slave.onTransfer(myCallback8);
    //  slave.debug(Serial); // SPI_MST Debug error tracking
    //  Wire.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    }
    
    
    void led() {
      digitalWrite(13, !digitalRead(13));
    }
    
    void loop() {
      slave.events();
    //      return;
      static uint32_t retry = millis();
      if ( millis() - retry > 100 ) {
        retry = millis();
        uint16_t buf[96];
        for (uint16_t i = 0; i < sizeof(buf) / 2; i++) buf[i] = i;
        slave.transfer16(buf, sizeof(buf) / 2, 69);
      }
    }
    
    static uint16_t last_packetID = 0;
    elapsedMillis TogClk;
    uint32_t TogCnt = 0;
    uint32_t FaFCnt = 0;
    void myCallback(uint16_t *buffer, uint16_t length, AsyncMST info) {
      //  Serial.print("PacketID: "); Serial.println(info.packetID);
      //  Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
      return;
      if ( 55 == info.packetID ) {
        if ( 48 != length ) {
          Serial.print("Bad Length: "); Serial.println(length); // If this shows then the SPI Passed array size is nor wrong
        }
        else if ( 0 != info.error ) {
          Serial.println("\nBad CRC: ");
        }
        else {
          double* MST_PrintVals;
          MST_PrintVals = (double *)buffer;
    
          {
            //trig conversions
            float rad2deg = 180.0f / PI;
            float deg2rad = PI / 180.0f;
            int  textLength = 12 * 31;
            char text[textLength];
    
            char utcText[30];
            char tsIMUText[30];
            char tsGPSText[30];
    
            // KF parameters
            char latText[30];
            char lonText[30];
            char altText[30];
            char pk1xText[30];
            char pk1yText[30];
            char pk1zText[30];
            char nuk1xText[30];
            char nuk1yText[30];
            char nuk1zText[30];
    
            int ii = 0;
            dtostrf( MST_PrintVals[ii] , 10, 6, utcText);
            ii++;
            dtostrf( MST_PrintVals[ii] * 0.000001f, 10, 4, tsIMUText);
            ii++;
            dtostrf( MST_PrintVals[ii] * 0.000001f, 10, 4, tsGPSText);
            ii++;
            dtostrf( MST_PrintVals[ii] *rad2deg, 10, 6, latText);
            ii++;
            dtostrf( MST_PrintVals[ii] *rad2deg, 10, 6, lonText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, altText);
            ii++;
            dtostrf(sqrt( MST_PrintVals[ii] ), 10, 4, pk1xText);
            ii++;
            dtostrf(sqrt( MST_PrintVals[ii] ), 10, 4, pk1yText);
            ii++;
            dtostrf(sqrt( MST_PrintVals[ii] ), 10, 4, pk1zText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, nuk1xText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, nuk1yText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, nuk1zText);
    
            // Create single text parameter and print it
            snprintf(text, textLength, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
                     utcText, tsIMUText, tsGPSText,
                     latText, lonText, altText,
                     pk1xText, pk1yText, pk1zText,
                     nuk1xText, nuk1yText, nuk1zText);
            Serial.println(text);
            //Serial.send_now();
          }
        }
      }
      else if ( 60 == info.packetID ) {
        if ( 48 != length ) {
          Serial.print("Bad Length: "); Serial.println(length); // If this shows then the SPI Passed array size is nor wrong
        }
        else if ( 0 != info.error ) {
          Serial.println("\nBad CRC: ");
        }
        else {
          double* MST_PrintVals;
          MST_PrintVals = (double *)buffer;
    
          // This provides a terse output with error checked based on MASTER output to the 12 DOUBLE value Array
          {
            static uint16_t TogLast = 0;
            static uint16_t TogHz = 0;
            static uint16_t FaFHz = 0;
            static double LastVal = 100000;
            static uint32_t ChkErr = 0;
            static uint32_t CBcount = 0;
            if ( digitalReadFast( LED_BUILTIN) != TogLast ) {
              TogLast = !TogLast;
              TogCnt++;
            }
            if ( TogClk >= 1000 ) {
              TogClk -= 1000;
              TogHz = TogCnt;
              TogCnt = 0;
              FaFHz = FaFCnt;
              FaFCnt = 0;
            }
            if ( last_packetID != info.packetID ) {
              LastVal += 12;
              if ( LastVal > 65536 && LastVal < 100000 ) LastVal -= 65536;
            }
            elapsedMillis LastCB;
            double DiffMiss = 0;
            uint32_t ErrSeen = 0;
            CBcount++;
            FaFCnt++;
            for ( uint32_t ii = 0; ii < 12; ii++ ) {
              LastVal++;
              if ( 65536 == LastVal ) LastVal = 0;
              if ( LastCB > 10 || 100001 == LastVal || 100013 == LastVal ) LastVal = MST_PrintVals[ii];
              if ( LastVal != MST_PrintVals[ii] ) {
                DiffMiss = LastVal - MST_PrintVals[ii];
                ChkErr++;
                Serial.print("\nBad LASTVAL TEST INCREMENT <<<<<<<<<<<<<<<<<<<< DIFF OF> ");
                Serial.println( DiffMiss );
                LastVal = MST_PrintVals[ii];
                ErrSeen++;
              }
              if ( 0 != ErrSeen || 1 > ii ) {
                Serial.print( MST_PrintVals[ii] );
                Serial.print(",");
              }
              else {
                Serial.print(" #,");
              }
            }
            Serial.print( CBcount );
            Serial.print(",");
            Serial.print( ChkErr );
            Serial.print(" [");
            Serial.print( FaFHz );
            Serial.print(" ,");
            Serial.print( TogHz );
            Serial.println();
            LastCB = 0;
          }
        }
      }
      else {
        Serial.print("PacketID: ");
        Serial.println(info.packetID);
      }
      last_packetID = info.packetID;
    }
    You'd have to wire up I2C0 from master and slave together with pullups for the Wire test to work..

  8. #1258
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    I2C_T3 has non-block read/write for master mode, very interesting, I added them to SPI_MST:

    Code:
        virtual void            sendTransmission(i2c_stop sendStop = I2C_STOP); // I2C
        virtual void            sendRequest(uint8_t addr, size_t len, i2c_stop sendStop = I2C_STOP); // I2C
    You would use them instead of the usual requestFrom and endTransmission...

    Example for master mode:

    Code:
        W1.begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
        W1.beginTransmission();
        W1.write(0x55);
        W1.sendTransmission();
    Added more:
    Code:
        virtual void            setDefaultTimeout(uint32_t timeout); // I2C
        virtual uint8_t         getSCL(); // I2C
        virtual uint8_t         getSDA(); // I2C
    Code:
    getSCL: 37
    getSDA: 38
    getSCL: 37
    getSDA: 38
    getSCL: 37
    getSDA: 38
    getSCL: 37
    Last edited by tonton81; 04-15-2018 at 07:36 PM.

  9. #1259
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Nice Tony. You are giving me more work to do. Already spent the day soldering up some new toys.

  10. #1260
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Its funny how we have a slave bus running off a slave

    All the 4 busses should work into the same handler, the packet info will give you the slave ID and wire port it came from
    really getting crazy now

    It was a good idea to recycle the slave's callback buffer, its working with the MSTPrintvals demo i posted

  11. #1261
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    I'll give it a try after I play around with uNAVIns a little more. There are a couple of test cases I want to go through on that. I still want to get back and figure out to best use the SPI_MSTransfer with the other project, ESP linkage.

  12. #1262
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Yup, it's nice we can receive from the slave, but I have no idea what to do about the onRequest event, where that outside master requests bytes from slave, I doubt the endpoint would accept a long wait

    currently this is how onReceive works:

    another MCU master ---> I2C slave port of MSTSLAVE --> MSTMASTER controller

    the data from "another MCU" writes trigger the i2c_t3 callback, the library puts it in the slave's queue system, and the master pulls it via events()

    Although it's nice to "receive" from the i2c slave, I don't think we can do much about the requests to send back out...

  13. #1263
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Tim, Mike, I decided to take a rest from I2C, I'm overkilling it.

    I just added a new feature to SPI_MST that I think you guys would like. It involved "slave reset state".
    If the slave reboots, or is plugged in last after the master, a lambda function binded to one of the slave's objects would "re-set the port settings" as needed.
    There is a grace period of 100 events loop stability before the lambda function finally fires, setting up all your slave settings, and once the lambda exits, the library sends a flag reset signal back to the slave

    Every time I hot plug the slave while master is polling it, this lambda will run after the 1st 100 events() of reset flag being set
    Code:
      teensy_gpio.onDetect([](AsyncMST info) {
        W1.begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
        W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
        W0.onReceive(hello);
        sSerial1.begin(115200);
      }); // end of onDetect callback
    So every time you reboot the slave, 2 I2C busses are set, Serial1 baud is set, and a callback function for the I2C slave is set!

    The beauty is all your slave settings go there at init, and when you power down and power up the slave, the settings are restored

    What you say now guys?
    Last edited by tonton81; 04-15-2018 at 11:51 PM.

  14. #1264
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    To better illustrate the behaviour you may test this out:

    The library:
    Master sketch:
    Code:
    //#include "FastLED.h"
    #include <SPI.h>
    #include <i2c_t3.h>
    #include "A_ConfigDefines.h"
    #include <SPI_MSTransfer.h>
    #include "TeensyThreads.h"
    #include <EventResponder.h>
    EventResponder  eresp;
    
    
    //0x99BB, 0x0003, 0x99B8
    Threads::Mutex MST_QUEUE;
    
    
    #include "circular_buffer.h"
    
    //#define SPI_SPEED 30500
    #define SPI_SPEED 30000000
    #define OT_CALC   100*(30000000/SPI_SPEED)
    
    SPI_MSTransfer teensy_gpio = SPI_MSTransfer("Serial", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    SPI_MSTransfer W0 = SPI_MSTransfer("Wire", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    SPI_MSTransfer W1 = SPI_MSTransfer("Wire1", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    SPI_MSTransfer sSPI1 = SPI_MSTransfer("SPI1", SPI_MST_CS, &SPI_MST_BUS, SPI_SPEED ); // bad with default timeouts
    
    
    
    
    void I2Cscan(SPI_MSTransfer &port) {
      SPI_MSTransfer* thePort;
      thePort = &port;
      // scan for i2c devices
      byte error, address;
      int nDevices;
    
      Serial.println("Scanning...");
      nDevices = 0;
      for (address = 1; address < 127; address++ ) {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        thePort->beginTransmission(address);
        error = thePort->endTransmission();
    
        if (error == 0) {
          Serial.print("I2C device found at address 0x");
          if (address < 16) Serial.print("0");
          Serial.print(address, HEX);
          Serial.println("  !");
          nDevices++;
        }
        else if (error == 4) {
          Serial.print("Unknow error at address 0x");
          if (address < 16) Serial.print("0");
          Serial.println(address, HEX);
        }
      }
      if (nDevices == 0) {
        Serial.println("No I2C devices found\n");
        while (1) {};
      } else {
        Serial.println("done\n");
      }
    }
    
    
    
    void myCallback8(uint8_t *buffer, uint16_t length, AsyncMST info) {
      Serial.print("PacketID: "); Serial.println(info.packetID);
      Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
    }
    void myCallback(uint16_t *buffer, uint16_t length, AsyncMST info) {
      //return;
      Serial.print("PacketID: "); Serial.println(info.packetID);
      Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
    }
    uint32_t OverTime = 0;
    
    
    void setup() {
    
      //  SPI_MSTransfer::mtsca._init();
      Serial.begin(115200);
      while (!Serial && millis() < 2000 ) {}
      Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
      teensy_gpio.onTransfer(myCallback);
      teensy_gpio.onTransfer(myCallback8);
    
    
    #ifdef SPI_MST_SCK
      SPI_MST_BUS.setSCK( SPI_MST_SCK );
    #endif
      SPI_MST_BUS.begin();
      //  delay(2000);
      threads.addThread(SPI_MST_Thread);
      Circular_Buffer<double, 16> myFloats;
      myFloats.push_back(3.14159);
      myFloats.push_back(12.3456);
      myFloats.push_back(78.91234);
      myFloats.push_back(7.91234);
      myFloats.push_back(11.91234);
      myFloats.push_back(58.91234);
      myFloats.push_back(18.91234);
      //  myFloats.push_back(2.91234);
    
      Serial.print("SUM: "); Serial.println(myFloats.sum(), 5);
      Serial.print("MIN: "); Serial.println(myFloats.min(), 5);
      Serial.print("MAX: "); Serial.println(myFloats.max(), 5);
      Serial.print("MEDIAN: "); Serial.println(myFloats.median(1), 5);
    
      uint8_t blah[5];
      //  qsort(blah, 5, sizeof(uint8_t), *(uint8_t*)a - *(uint8_t*)b);
      Serial.print("AVG: "); Serial.println(myFloats.average(), 5);
      uint8_t _size = myFloats.size();
      Serial.print("Deviation: "); Serial.println(myFloats.deviation(), 8);
      for ( uint8_t i = 0; i < _size; i++ ) {
        Serial.print(myFloats.pop_front(), 5); Serial.print(" ");
      } Serial.println();
    
      //  while(1);
    
    
      //uint16_t v = 1010;
      //
      //v--;
      //v |= v >> 1;
      //v |= v >> 2;
      //v |= v >> 4;
      //v |= v >> 8;
      //v |= v >> 16;
      //v++;
      //
      //Serial.println(v);
      //uint16_t v = 300;
    
    
    
    
    
      //  Serial.println(v);
    
      // Circular_Buffer<uint16_t, 4> cb2;
    
    
      //  I2Cscan(W0);
      Serial.println(SPI_MSTransfer::stmca.capacity());
      Serial.println(SPI_MSTransfer::stmca.max_size());
      //  teensy_gpio.debug(Serial);
    
      threads.setTimeSlice(0, 1);
      threads.setTimeSlice(1, 10);
    
    //  W1.begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
    //  W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    //  W0.onReceive(hello);
    
      teensy_gpio.onDetect([](AsyncMST info) {
        W1.begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
        W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
        W0.onReceive(hello);
      }); // end of onDetect callback
    
    
      Wire.begin();
    
      delay(2000);
      //  W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    }
    void hello(size_t count, AsyncMST info) {
      Serial.print("Size: "); Serial.print(count);
      Serial.print(" Slave: "); Serial.print(info.slave);
      Serial.print(" Port: "); Serial.println(info.port);
    
      for ( uint16_t i = 0; i < count; i++ ) {
        Serial.print((char)W0.read());
      } Serial.println();
    }
    
    
    
    
    
    void SPI_MST_Thread() {
      while (1) {
        { Threads::Scope scope(MST_QUEUE);
          teensy_gpio.events(0);
        }
        threads.yield();
      }
    }
    
    void loop() {
      static uint32_t wire_write_timer = millis();
      if ( millis() - wire_write_timer >= 1000 ) {
        wire_write_timer = millis();
        Serial.println(millis());
    //return;
        //    return;
        //    Serial.println(W1.done());
        //    Serial.println(W1.finish());
        //    return;
        //
    //    Wire.setDefaultTimeout(1);
        //
        //    Serial.print("getSDA: "); Serial.println(W1.getSDA());
        //    Serial.print("getSCL: "); Serial.println(W1.getSCL());
        //
        //    //    W1.sendRequest(0x33, 2, I2C_STOP);
        //    return;
        Wire.beginTransmission(0x22);
        char text[] = "Hello Mike, this is a test...\n";
        Wire.write(text, sizeof(text));
        char text1[] = "From SPI_MSTransfer...";
        Wire.write(text1, sizeof(text1));
        Wire.sendTransmission();
      }
    //  return;
      static bool runonce = 1;
      if ( runonce ) {
        runonce = 0;
      }
      //  teensy_gpio.events(1);
      static uint32_t _timer = micros();
      static uint32_t led_timer = millis();
      if ( millis() - led_timer >= 100 )  {
        led_timer = millis();
        teensy_gpio.pinToggle(LED_BUILTIN);
        //    Serial.println("LED TOGGLE!");
        //    delay(1);
      }
      //  return;
      if ( micros() - _timer >= 1000 ) {
        _timer = micros();
    
        uint8_t bufff[24];
        for (uint8_t i = 0; i < sizeof(bufff); i++) bufff[i] = i;
        //    teensy_gpio.transfer(bufff, sizeof(bufff), 69, 2);
    
        //uint16_t notify = 0xAD00;
    
        //Serial.println(notify |= 1 << 0,HEX);
    
        // set:  notify |= 1 << 7;
        // unset:  notify &= ~(1 << 7);
    
        //    Serial.println(millis());
    
        //    W0.beginTransmission(0x20);
        //    uint8_t ibuffer[3] = { 0x0C, 0xFF, 0xFF };
        //    W0.write(ibuffer, 3); // set pullups
        //    W0.endTransmission();
        //
        //    W0.beginTransmission(0x20);
        //    W0.write(0x12); // set bankA to read
        //    W0.endTransmission();
        //
        //    W0.requestFrom(0x20, 2); // read bankA and bankB
        //    Serial.print(W0.read()); Serial.print(":"); Serial.println(W0.read());
    
    
    
        //    Serial.println( W0.requestFrom(0x48, 1, 1));
    
    
        //    uint8_t buffer[48];
        //
        //    for ( uint8_t i = 0; i < sizeof(buffer); i++ ) {
        //      buffer[i] = i;
        //    }
        //    uint32_t ___time = micros();
        //    teensy_gpio.transfer(buffer, sizeof(buffer), 10750,1);
        //    Serial.print("T: "); Serial.println(micros() - ___time);
        uint32_t _time = micros();
        //    SPIClass teensy_gpio;
        //SPI3 = (SPIClass)teensy_gpio;
        uint16_t *buf;
        double MST_PrintVals[12];
        buf = (uint16_t *)MST_PrintVals;
        int ii = 0;
        static uint16_t __count = 0;
        static uint16_t __countB = 0;
        for ( uint32_t i = 0; i < sizeof(MST_PrintVals) / sizeof( MST_PrintVals[0]  ); i++ ) MST_PrintVals[i] = __count++;
        //    Serial.print("F&F (OT=");
        //    Serial.print( OverTime );
        //    Serial.print(")");
        _time = micros();
        __countB++;
        if ( __countB % 25 ) {
          //      Serial.println();
          //      Serial.print("ACK PacketID 60: ");
          uint32_t t1 = micros();
          { Threads::Scope scope(MST_QUEUE);
            teensy_gpio.transfer16((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 60, 2); // DEBUGHACK output
          }
          //      Serial.print(micros() - t1);
          //      Serial.println("uS");
        }
        else {
          //      Serial.println();
          //      Serial.print("F&F PacketID 55: ");
          uint32_t t2 = micros();
          { Threads::Scope scope(MST_QUEUE);
            teensy_gpio.transfer16((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 55, 2);
          }
          //      Serial.print(micros() - t2);
          //      Serial.println("uS");
        }
        return;
        //    _time = micros() - _time;
        //    Serial.print(" OT_CALC==");
        //    Serial.print(OT_CALC);
        //    Serial.print("  micros() _time==");
        //    Serial.println(_time);
        if ( _time > OT_CALC ) OverTime++;
        //    teensy_gpio.events();
      }
    }
    Slave sketch:
    Code:
    #include <SPI_MSTransfer.h>
    //#include "FastLED.h"
    #include <i2c_t3.h>
    SPI_MSTransfer slave = SPI_MSTransfer("SLAVE", "STANDALONE");
    //#define NUM_LEDS 10
    void myCallback8(uint8_t *buffer, uint16_t length, AsyncMST info) {
      Serial.print("PacketID: "); Serial.println(info.packetID);
      Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
    }
    //#define DATA_PIN 35
    //#define CLOCK_PIN 13
    //CRGB leds[NUM_LEDS];
    
    void setup() {
      Serial.begin(115200);
    //FastLED.addLeds<WS2812B, DATA_PIN>(leds, NUM_LEDS);
      while (!Serial && millis() < 5000 )
      { Serial.print( "Teensy NOT Online @ millis=" );
        Serial.println( millis() );
        delay(30);
      }
      Serial.print( "Teensy Online @ millis=" );
      Serial.println( millis() );
      Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
    
      if ( ARM_DWT_CYCCNT == ARM_DWT_CYCCNT ) {
        Serial.print( "Cycle Counter Not Enabled :" );
        Serial.println( ARM_DWT_CYCCNT );
      }
      if ( ARM_DWT_CYCCNT == ARM_DWT_CYCCNT ) {
        // Enable CPU Cycle Count
        ARM_DEMCR |= ARM_DEMCR_TRCENA;
        ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
      }
      if ( ARM_DWT_CYCCNT != ARM_DWT_CYCCNT ) {
        Serial.print( "Cycle Counter Enabled! :" );
        Serial.println( ARM_DWT_CYCCNT );
      }
      SPI1.begin();
      SPI2.begin();
      SPI1.setSCK(20); SPI1.setMOSI(21); SPI1.setMISO(5); SPI1.begin();
      SPI2.setSCK(46); SPI2.setMOSI(44); SPI2.setMISO(45); SPI2.begin();
      SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); // default speed
      SPI2.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); // default speed
    
      slave.begin( );
      slave.onTransfer(myCallback);
      slave.onTransfer(myCallback8);
    //  Wire1.begin();
    //  slave.debug(Serial); // SPI_MST Debug error tracking
    //  Wire.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    }
    
    
    void led() {
      digitalWrite(13, !digitalRead(13));
    }
    
    void loop() {
     
    //    leds[0] = CRGB::Red;
    //  FastLED.show();
    //  delay(500);
    //  // Now turn the LED off, then pause
    //  leds[0] = CRGB::Black;
    //  FastLED.show();
    //  delay(500);
      
      slave.events();
    //      return;
      static uint32_t retry = millis();
      if ( millis() - retry > 200 ) {
        retry = millis();
        uint16_t buf[96];
        for (uint16_t i = 0; i < sizeof(buf) / 2; i++) buf[i] = i;
        slave.transfer16(buf, sizeof(buf) / 2, 69);
      }
    }
    
    static uint16_t last_packetID = 0;
    elapsedMillis TogClk;
    uint32_t TogCnt = 0;
    uint32_t FaFCnt = 0;
    void myCallback(uint16_t *buffer, uint16_t length, AsyncMST info) {
      //  Serial.print("PacketID: "); Serial.println(info.packetID);
      //  Serial.print("Length: "); Serial.println(length);
      for ( uint16_t i = 0; i < length; i++ ) {
        Serial.print(buffer[i], HEX); Serial.print(" ");
      }
      Serial.println();
      return;
      if ( 55 == info.packetID ) {
        if ( 48 != length ) {
          Serial.print("Bad Length: "); Serial.println(length); // If this shows then the SPI Passed array size is nor wrong
        }
        else if ( 0 != info.error ) {
          Serial.println("\nBad CRC: ");
        }
        else {
          double* MST_PrintVals;
          MST_PrintVals = (double *)buffer;
    
          {
            //trig conversions
            float rad2deg = 180.0f / PI;
            float deg2rad = PI / 180.0f;
            int  textLength = 12 * 31;
            char text[textLength];
    
            char utcText[30];
            char tsIMUText[30];
            char tsGPSText[30];
    
            // KF parameters
            char latText[30];
            char lonText[30];
            char altText[30];
            char pk1xText[30];
            char pk1yText[30];
            char pk1zText[30];
            char nuk1xText[30];
            char nuk1yText[30];
            char nuk1zText[30];
    
            int ii = 0;
            dtostrf( MST_PrintVals[ii] , 10, 6, utcText);
            ii++;
            dtostrf( MST_PrintVals[ii] * 0.000001f, 10, 4, tsIMUText);
            ii++;
            dtostrf( MST_PrintVals[ii] * 0.000001f, 10, 4, tsGPSText);
            ii++;
            dtostrf( MST_PrintVals[ii] *rad2deg, 10, 6, latText);
            ii++;
            dtostrf( MST_PrintVals[ii] *rad2deg, 10, 6, lonText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, altText);
            ii++;
            dtostrf(sqrt( MST_PrintVals[ii] ), 10, 4, pk1xText);
            ii++;
            dtostrf(sqrt( MST_PrintVals[ii] ), 10, 4, pk1yText);
            ii++;
            dtostrf(sqrt( MST_PrintVals[ii] ), 10, 4, pk1zText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, nuk1xText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, nuk1yText);
            ii++;
            dtostrf( MST_PrintVals[ii] , 10, 4, nuk1zText);
    
            // Create single text parameter and print it
            snprintf(text, textLength, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
                     utcText, tsIMUText, tsGPSText,
                     latText, lonText, altText,
                     pk1xText, pk1yText, pk1zText,
                     nuk1xText, nuk1yText, nuk1zText);
            Serial.println(text);
            //Serial.send_now();
          }
        }
      }
      else if ( 60 == info.packetID ) {
        if ( 48 != length ) {
          Serial.print("Bad Length: "); Serial.println(length); // If this shows then the SPI Passed array size is nor wrong
        }
        else if ( 0 != info.error ) {
          Serial.println("\nBad CRC: ");
        }
        else {
          double* MST_PrintVals;
          MST_PrintVals = (double *)buffer;
    
          // This provides a terse output with error checked based on MASTER output to the 12 DOUBLE value Array
          {
            static uint16_t TogLast = 0;
            static uint16_t TogHz = 0;
            static uint16_t FaFHz = 0;
            static double LastVal = 100000;
            static uint32_t ChkErr = 0;
            static uint32_t CBcount = 0;
            if ( digitalReadFast( LED_BUILTIN) != TogLast ) {
              TogLast = !TogLast;
              TogCnt++;
            }
            if ( TogClk >= 1000 ) {
              TogClk -= 1000;
              TogHz = TogCnt;
              TogCnt = 0;
              FaFHz = FaFCnt;
              FaFCnt = 0;
            }
            if ( last_packetID != info.packetID ) {
              LastVal += 12;
              if ( LastVal > 65536 && LastVal < 100000 ) LastVal -= 65536;
            }
            elapsedMillis LastCB;
            double DiffMiss = 0;
            uint32_t ErrSeen = 0;
            CBcount++;
            FaFCnt++;
            for ( uint32_t ii = 0; ii < 12; ii++ ) {
              LastVal++;
              if ( 65536 == LastVal ) LastVal = 0;
              if ( LastCB > 10 || 100001 == LastVal || 100013 == LastVal ) LastVal = MST_PrintVals[ii];
              if ( LastVal != MST_PrintVals[ii] ) {
                DiffMiss = LastVal - MST_PrintVals[ii];
                ChkErr++;
                Serial.print("\nBad LASTVAL TEST INCREMENT <<<<<<<<<<<<<<<<<<<< DIFF OF> ");
                Serial.println( DiffMiss );
                LastVal = MST_PrintVals[ii];
                ErrSeen++;
              }
              if ( 0 != ErrSeen || 1 > ii ) {
                Serial.print( MST_PrintVals[ii] );
                Serial.print(",");
              }
              else {
                Serial.print(" #,");
              }
            }
            Serial.print( CBcount );
            Serial.print(",");
            Serial.print( ChkErr );
            Serial.print(" [");
            Serial.print( FaFHz );
            Serial.print(" ,");
            Serial.print( TogHz );
            Serial.println();
            LastCB = 0;
          }
        }
      }
      else {
        Serial.print("PacketID: ");
        Serial.println(info.packetID);
      }
      last_packetID = info.packetID;
    }
    connect both Wire0 busses from slave and master together, with pullups

    if you reset the slave, unplug, or plug in, you will see within few secs a sync appear, and the lambda has ran, at that point you will start seeing Wire messages comming back from the slave.

    This DEMO is running MSPrintVALs by Tim while receiving slave callback buffer of 96 dwords, and receiving 54 wire bytes from the slave when the callback fires.

    It's amazing how well it's being handled

    Master output:
    Code:
    157811
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    158887
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    159949
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    161011
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    162074
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    163145
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    acketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    164199
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    165255
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    166339
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    167397
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    168456
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    169481
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    170531
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    Size: 54 Slave: 43 Port: 0
    Hello Mike, this is a test... .From SPI_MSTransfer....
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 
    PacketID: 69
    Length: 96
    0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
    If you reset master, or slave, doesnt matter which, the config will remain when the callback is fired for a sync

    This is VERY useful especially with pinmode states when a slave is connected, the configuration is passed to set them up
    Last edited by tonton81; 04-15-2018 at 11:52 PM.

  15. #1265
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Hey Tony - that one is easy to test. You just fixed the one thing that would always drive me crazy

    Mike

  16. #1266
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Yup, the lambda is created in setup (or wherever you call it) and is binded to the object (lets say teensy_gpio). So it survives the lifetime of the object, not the scope.
    After creation, it self-fires to run the items within it before continuing the rest of the sketch.
    The slave has a reset bool that is only set at startup to 1 and is persistant through the current events() status calls. When the status bit 2 of the dword is set, it means the slave has been reset, so the events() deasserts the line, fires the lambda, the lambda does what it needs to do, and when lambda is done, events() sends a signal to reset the flag on the slave so it no longer is set on status checks

    the demo above has been running since posted

  17. #1267
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    last night i realized i dont have read buffering support implemented for wire/serial, only writing...
    looks like ive got work to do today!

    its always preferable an entire buffer over a single transmission rather than one byte at a time per transaction
    can you imagine the last demo i posted did 54 transactions in the callback while still running PRINTVALS and toggling led while receiving 96 dwords from the slave!? i just realized a booboo, and im not even home yet, i forgot to mutex wrap Wire callback calls, woops

    oh yeah, mike, hows the onDetect feature

  18. #1268
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Hi Tony. Had to stop last night after I posted was trying to do something but making too many mistakes so I just packed it in. Started going through the sketch and removing most of the commented out lines (just for my clarity) but have a couple of questions - mostly understanding

    Confused about one statement you made - "connect both Wire0 busses from slave and master together, with pullups" Ok. Got that SDAmast to SDA slave and SCKmaster to SCKslave for Wire (pins 18-19).

    Understand the constructs for sSPI1, W0 and W1. But don't understand whey you need them for this example. Don't you just need W0?

    Thanks
    Mike

    Also, here:
    Code:
        W1.begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
        W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    Don't you just need W0?

  19. #1269
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    sorry W1 was just for testing the new Wire methods,, when I test the functions i basically throw them anywhere i can that i know where to start debugging you can clear that

    but yeah, you can see how the library mimics i2ct3 for method calls

    Note, SPI_MSTransfer I2C calls are based on I2C_T3 library, NOT Wire, I *could* add Wire methods to the mix if people prefer Wire.h, although the methods won’t conflict in the scope, the handling at the slave will be totally different, chaotic, and the safest method would be to if/define all the slave i2c_t3 switches and master methods and define other blocks if Wire.h is defined. So rather than making things complex, SPI_MST will be based on I2C_T3, n0x did a good job with his library been using it for years

    PS, if you connect both Wire0 ports, dont forget the pullups(i used 10k since theyre scattered on my desk)

  20. #1270
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Had to ask. I recognized the test sketch and wanted to reduce it to its basic form - easier to understand and not get confused.

    Yeah I noticed how it mimics the library. Going to give it a try today and let you know.

    I have some 10ks laying around here somewhere - I'll try not to forget to add them

    Mike

    EDIT: you see I am picking up one or two things

  21. #1271
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    Mike don't forget about the thread in the demo, if your using it i forgot to wrap the W0 transmission and the led, you can wrap them with the mutex from the other thread running events

    in the meantime ill be working on buffered reads for Wire, and do Serial after
    Last edited by tonton81; 04-16-2018 at 03:03 PM.

  22. #1272
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    yeah I forgot. So I would do:
    Code:
    { Threads::Scope scope(MST_QUEUE);
        Wire.beginTransmission(0x22);
        Wire.write(text, sizeof(text));
        Wire.write(text1, sizeof(text1));
        Wire.sendTransmission();
    }
    and again around led transmission.

    What about the read in the Hello function?

  23. #1273
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    definately, any and all calls that use the SPI_MST interface, MST_QUEUE is just a name i randomly picked, it can be whatever you want, as long as all those calls use the same one

  24. #1274
    Senior Member
    Join Date
    Jul 2014
    Location
    New York
    Posts
    1,680
    Got it. Oh, one more question, where does i2c address 0x22, come in? Reason why I am asking is that I am not getting anything from i2c and trying do some bebugging and SPI transfer is awfully slow?

  25. #1275
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,587
    on the Master, 0x22 is set as a slave, programmed via MASTER -> SLAVE, at beginTransmission, you'll see the MASTER's Wire.* writing to 0x22

    remember, W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000); sets slave up as a slave

    events() is mandatory

    check pullups and SDA/SCL lines

    Also make sure your callback for i2c slave is setup on master:

    W0.onReceive(hello);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •