Project: SPI_MSTransfer

Ok.. slave.events is there and I just uncommented the line out in the master for teens_gpio.events. Hoping that was it - have to check sda/scl now. Oh boy, nothing ever works out of the box for me :) but on the other hand I learn from the mistakes.
 
I think for testing, its easier to go thread-less, my sketch stuffing code cant play nice unless mutexes are well placed

i emptied the thread loop and removed mutexes and pushed events into main loop where i can test threadless, for simplicity sake
 
I'll make a very very simple minimal demo for you, gimme a minute, testing wire using buffer method and stripping master code

Slave:
Code:
#include <SPI_MSTransfer.h>

SPI_MSTransfer slave = SPI_MSTransfer("SLAVE", "STANDALONE");

void setup() {
  Serial.begin(115200);
  slave.begin( );
}

void loop() {
   slave.events();
}

Master:
Code:
#include <SPI_MSTransfer.h>

SPI_MSTransfer W0 = SPI_MSTransfer("Wire", 43, &SPI2, 30000000 );

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial && millis() < 2000 );
  W0.onDetect([](AsyncMST info) {
    W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    Wire.beginTransmission(0x22);
    Wire.write("Hello Master!", 13);
    Wire.sendTransmission();
    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);
  uint8_t buf[count] = { 0 };
  W0.read(buf, count);
  for ( uint16_t i = 0; i < count; i++ ) {
    Serial.print((char)buf[i]);
  } Serial.println();
}

void loop() {
  W0.events(0);
  static uint32_t wire_write_timer = millis();
  if ( millis() - wire_write_timer >= 2000 ) {
    wire_write_timer = millis();
    Wire.beginTransmission(0x22);
    char text[] = "Hello Mike, this is a test... ";
    Wire.write(text, sizeof(text));
    char text1[] = "From SPI_MSTransfer...";
    Wire.write(text1, sizeof(text1));
    Wire.sendTransmission();
  }
}

few more secs to upload library update for buffered reading of Wire...

Code:
[ATTACH]13602._xfImport[/ATTACH]
 
Last edited:
Thanks - think I may have found the problem but no guarantee. Have more debugging to do - going to test it on my old reliable setup up that I have been using except I am going to change to wire1 since wire is tied up.
 
May day may day, Not sure if it's i2c_t3 or SPI_MST
the buffer reads are "intermittantly" working, im currently looking into it, use this hello callback temporarily for single reads:
this always works:

Code:
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();
}
 
Cool on the LC's will eventually have to pick a couple up.

Anyway was still in the process of doing debugging - turns out two things - the 3.2 breakout board I put together yesterday I missed some solder joints. Also picked up wrong resistors - only 1k, I usually use 4.7Ks so off finding my resistor box ;)
 
Yeah so use the single read bytes for that simple demo, its working perfectly, i'm still debugging the buffered reads :)
 
Ok Tony all debugging finished, I know my I2C lines work, tested with a MS5637 and a I2CScanner.

Loaded your new version of SPI transfer and using single read bytes.

1. Tried your simplified sketch but didn't work.
2. Reloaded the original version with and with threads but only got the packet transfers. No luck. I2C didn't work.

The only thing I can think of is that I have the wiring wrong. Been checking and rechecking and just don't see it - well back to work on figuring it out.

Oh, BTW I am using a T3.5 as a master at 168 and a T3.2 at 120 for the slave.

EDIT> the only thing I am seeing on master serial are a bunch of numbers:
473472
474692
475912
477132
478352
 
yeah those are loop millis() printing, so i can see if it locks up or not when hot plugging :)
single reads working here with above demo:
Code:
51777
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
52284
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
52794
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
53301
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
53816
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
54326
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
54835
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
55343
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
55856
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
56376
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
56886
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
57402
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
57912
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
58424
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
58940
Size: 50 Slave: 43 Port: 0
Hello World over I2C & SPI from SPI_MSTransfer....
 
Alright I believe I have some results Mike. Noted above, it does work, but:

No idea if it's because the master is sending to the slave i2c bus and pulling back over spi, but slowing down the I2C writes (not events()) seems to be more stable.

For buffer reads, heres what I noticed, as above same principal, less we bother the i2c bus, better it works. Secondly, smaller buffers ("Hello World!") seems to be working better for the buffering.

I can't rule it out to be a master issue or not, probably an external master can send i2c data to the slave and we can get other results.
Due to the design of the I2C protocol, the last entry to the I2C slave is the data & count. If another one comes in, guess what, it's not the same like uart...
Instead, you get a new dataset, and a new count.
So what happens is this, if the outside master gave data to the slave 3 times before the MST picked up, MST would have 3 queues, but only one real dataset & count
I believe the next round of callback event fires the second one with no data available and "boom", underfined behaviour :)

Now I believe it's time to use the replace feature for the Wire I2C Slave, to protect it from dupes. Lucky for me, the * &bus * is in the packet, so we have a good comparator there and it's the most important one :) !
 
Looks like it worked! some debug info:

Code:
dded new!
Added new!
Added new!
Added new!
Added new!
Prevented double!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Prevented double!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!
Added new!

These were the mods for only last transaction to callback:
Code:
void SPI_MSTransfer::receiveEvent0(size_t count) {
  uint16_t data[6], checksum = 0, data_pos = 0;
  data[data_pos] = 0xAA55; checksum ^= data[data_pos]; data_pos++; // HEADER
  data[data_pos] = sizeof(data) / 2; checksum ^= data[data_pos]; data_pos++; // DATA SIZE
  data[data_pos] = 0x0002; checksum ^= data[data_pos]; data_pos++; // SUB SWITCH STATEMENT
  data[data_pos] = 0x0000; checksum ^= data[data_pos]; data_pos++; // I2C PORT
  data[data_pos] = count; checksum ^= data[data_pos]; data_pos++;
  data[data_pos] = checksum;
[COLOR="#FF0000"]  if ( !_slave_pointer->SPI_MSTransfer::stmca.replace(data,5,1,2,3) ) _slave_pointer->SPI_MSTransfer::stmca.push_back((const uint16_t*)data,(uint16_t)data[1]);
[/COLOR]  _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered |= 1 << 0;
}
void SPI_MSTransfer::receiveEvent1(size_t count) {
  uint16_t data[6], checksum = 0, data_pos = 0;
  data[data_pos] = 0xAA55; checksum ^= data[data_pos]; data_pos++; // HEADER
  data[data_pos] = sizeof(data) / 2; checksum ^= data[data_pos]; data_pos++; // DATA SIZE
  data[data_pos] = 0x0002; checksum ^= data[data_pos]; data_pos++; // SUB SWITCH STATEMENT
  data[data_pos] = 0x0001; checksum ^= data[data_pos]; data_pos++; // I2C PORT
  data[data_pos] = count; checksum ^= data[data_pos]; data_pos++;
  data[data_pos] = checksum;
[COLOR="#FF0000"]  if ( !_slave_pointer->SPI_MSTransfer::stmca.replace(data,5,1,2,3) ) _slave_pointer->SPI_MSTransfer::stmca.push_back((const uint16_t*)data,(uint16_t)data[1]);
[/COLOR]  _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered |= 1 << 1;
}
void SPI_MSTransfer::receiveEvent2(size_t count) {
  uint16_t data[6], checksum = 0, data_pos = 0;
  data[data_pos] = 0xAA55; checksum ^= data[data_pos]; data_pos++; // HEADER
  data[data_pos] = sizeof(data) / 2; checksum ^= data[data_pos]; data_pos++; // DATA SIZE
  data[data_pos] = 0x0002; checksum ^= data[data_pos]; data_pos++; // SUB SWITCH STATEMENT
  data[data_pos] = 0x0002; checksum ^= data[data_pos]; data_pos++; // I2C PORT
  data[data_pos] = count; checksum ^= data[data_pos]; data_pos++;
  data[data_pos] = checksum;
[COLOR="#FF0000"]  if ( !_slave_pointer->SPI_MSTransfer::stmca.replace(data,5,1,2,3) ) _slave_pointer->SPI_MSTransfer::stmca.push_back((const uint16_t*)data,(uint16_t)data[1]);
[/COLOR]  _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered |= 1 << 2;
}
void SPI_MSTransfer::receiveEvent3(size_t count) {
  uint16_t data[6], checksum = 0, data_pos = 0;
  data[data_pos] = 0xAA55; checksum ^= data[data_pos]; data_pos++; // HEADER
  data[data_pos] = sizeof(data) / 2; checksum ^= data[data_pos]; data_pos++; // DATA SIZE
  data[data_pos] = 0x0002; checksum ^= data[data_pos]; data_pos++; // SUB SWITCH STATEMENT
  data[data_pos] = 0x0003; checksum ^= data[data_pos]; data_pos++; // I2C PORT
  data[data_pos] = count; checksum ^= data[data_pos]; data_pos++;
  data[data_pos] = checksum;
 [COLOR="#FF0000"] if ( !_slave_pointer->SPI_MSTransfer::stmca.replace(data,5,1,2,3) ) _slave_pointer->SPI_MSTransfer::stmca.push_back((const uint16_t*)data,(uint16_t)data[1]);
[/COLOR]  _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered |= 1 << 3;
}

Obviously this stopped the handler from reading the count the second time after clearing the first :)
indices 1,2,3 can be compared and are unique to the callback system, especially 2nd indice, 3rd being the port, and 1 the size, which never changes
 
I got it working! had to edit the slave's switch statement for dequeue to remove the flag if the queue contained the isr pointer

Code:
      case 0x9712: {
          switch ( data[2] ) {
            case 0x0000: {
                if ( _slave_pointer->SPI_MSTransfer::stmca.size() > 0 ) { // IF QUEUES EXIST, ONE WILL BE DEQUEUED TO MASTER
                  uint16_t buf_pos = 0;
                  while ( !(GPIOD_PDIR & 0x01) ) {
                    if ( SPI0_SR & 0xF0 ) {
                      SPI0_PUSHR_SLAVE = _slave_pointer->SPI_MSTransfer::stmca.front()[ ( buf_pos > _slave_pointer->SPI_MSTransfer::stmca.front()[1] ) ? buf_pos = 0 : buf_pos++];
                      if ( SPI0_POPR == 0xD0D0 ) {
[COLOR="#FF0000"]                        if ( _slave_pointer->SPI_MSTransfer::stmca.front()[2] == 0x0002 ) {
                          if ( _slave_pointer->SPI_MSTransfer::stmca.front()[3] == 0x0000 ) _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered = _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered & 0b11111110;
                          else if ( _slave_pointer->SPI_MSTransfer::stmca.front()[3] == 0x0001 ) _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered = _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered & 0b11111101;
                          else if ( _slave_pointer->SPI_MSTransfer::stmca.front()[3] == 0x0002 ) _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered = _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered & 0b11111011;
                          else if ( _slave_pointer->SPI_MSTransfer::stmca.front()[3] == 0x0003 ) _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered = _slave_pointer->SPI_MSTransfer::_i2c_slave_isr_triggered & 0b11110111;                        }
                        }[/COLOR]
                        _slave_pointer->SPI_MSTransfer::stmca.pop_front();
                        break;
                      }
                    }
                  }
                  SPI0_SR |= SPI_SR_RFDF; return;
                }

now its running at 100ms rates! :)

Code:
1085925
1086025
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1086125
1086225
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1086325
1086426
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1086526
1086627
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1086727
1086828
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1086928
1087028
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1087128
1087229
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1087329
1087430
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1087530
1087631
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1087731
1087832
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1087932
1088033
1088133
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1088233
1088334
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1088434
1088535
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1088635
1088736
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1088836
1088937
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1089037
1089137
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1089237
1089338
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1089438
1089539
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1089639
1089739
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1089839
1089940
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1090040
1090141
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1090241
1090342
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1090442
1090543
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1090643
1090744
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1090844
1090944
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1091044
1091145
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
1091245
1091345
Size: 53 Slave: 43 Port: 0
.....................................................
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.

If you see the log closely, you'll see a double fire, because the isr seemed to hit the dequeue from behind, race condition, delaying it a bit gives enough time to handle it, at 200ms wire slave receiving, the output looks good for a 54 byte wire transfer :)

Code:
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
41038
41238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
41438
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
41638
41838
42038
42238
42438
42638
42838
43038
43238
43438
43638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
43838
44038
44238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
44438
44638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
44838
45038
45238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
45438
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
45638
45838
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
46038
46238
46438
46638
46838
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
47038
47238
47438
47638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
47838
48038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
48238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
48438
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
48638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
48838
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
49038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
49238
49438
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
49638
49838
50038
50238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
50438
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
50638
50838
51038
51238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
51438
51638
51838
52038
52238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
52438
52638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
52838
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
53038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
53238
53438
53638
53838
54038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
54238
54438
54638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
54838
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
55038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
55238
55438
55638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
55838
56038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
56238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
56438
56638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
56838
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
57038
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
57238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
57438
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
57638
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
57838
58038
58238
Size: 53 Slave: 43 Port: 0
Hello World this is a test of long string -- SPI_MST.
 
Last edited:
Oh I bet your wondering... Well... We have a huge buffer, why not use it!?

Just thought of it now?

Ideally, we would hook the Wire.read() calls to a special return, where a "read" would return the byte from the buffer, rather from the slave ISR
This is doable but requires a bit of effort, but would solve all the issues without keeping track of the i2c flag :)

This would essentially not miss any packets that were overiding each other, and wouldnt need to use the replace to keep latest
This sounds logical
 
Hey hey, this is fun :)

Alright, check this:
Code:
  W0.read(buf, count);

is different between normal and in callback.

In normal mode, it requests to read from the slave's port directly

However, if the callback for I2C data is received, and running, it becomes todally different.

I did a nice trick, to detect when the callback is in process, and have other selected methods use that info to run different actions.
Example:

Code:
              else if ( buf[2] == 0x0002 ) {
                spi_port->transfer16(0xD0D0); // send confirmation
                SPI_deassert();
                if ( _wire_onReceivefunc != nullptr ) {
                  AsyncMST info; info.slave = chip_select; info.port = buf[3];
[COLOR="#FF0000"]                  _wire_callback_active = 1;
                  mtsca.push_front(buf,buf[1]);
                  _wire_onReceivefunc(buf[4],info);
                  mtsca.pop_front();
                  _wire_callback_active = 0;[/COLOR]
                }
              }

1) we set the variable before entering the callback
2) we push the captured buffer into the front of the queue system (so other code can access it on a global scale :) )
3) We redirect the buffer read from the ::read function:
Code:
size_t SPI_MSTransfer::read(uint8_t* buffer, size_t size) {
  if ( _slave_access ) return 0;
  if ( wire_port != -1 ) {
[COLOR="#FF0000"]    if ( _wire_callback_active ) {
      for ( uint16_t i = 0; i < size; i++ ) buffer[i] = (uint8_t)mtsca.peek_front()[i+5];
      return 0;
    }[/COLOR]
    uint16_t data[7], checksum = 0, data_pos = 0;
    data[data_pos] = 0x66AA; checksum ^= data[data_pos]; data_pos++; // HEADER
4) the slave runs this in the i2c callback:
Code:
  uint8_t buf[count] = { 0 };
  W0.read(buf, count);
  for ( uint16_t i = 0; i < count; i++ ) {
    Serial.print((char)buf[i]);
  } Serial.println();
5) after the callback exits, the front of the queue is popped out from queue, and the callback flag is unset!

I'm not getting any I2C missed data now! :)

Gonna have to work on the other Wire calls to hook and pick off the CB buffer like I did to the buffered read
 
I got something weird going on between the 3.5 and 3.2 combo. For the hell of it I just tried this: http://www.instructables.com/id/I2C-between-Arduinos/ just as test. No I didn't use pullups. Again 3.5 was master and slave was the 3.2. Didn't work. I tested both i2c lines with the MS5637 and a I2c Scanner as a check and individually they worked.

Do you think its something with the MCU combo or related to you previous posts. My guess its the combo.

Mike

EDIT: I just woke up and still trying to absorb your posts :)
 
Ok now check the ::read() method:

if the callback requests this:
Code:
  for ( uint16_t i = 0; i < count[COLOR="#FF0000"]+2[/COLOR]; i++ ) {
    Serial.print(W0.read()); Serial.print(" ");
  } Serial.println();
Keep in mind the 2 additional pulls past counter, you'll see why during next stage :)
The method hook:
Code:
  if ( wire_port != -1 ) {
    if ( _wire_callback_active ) {
      [COLOR="#FF0000"]if ( _wire_callback_readpos >= mtsca.peek_front()[4] ) return -1;[/COLOR]
      uint8_t value = (uint8_t)mtsca.peek_front()[_wire_callback_readpos+5];
      _wire_callback_readpos++;
      return value;
    }
return -1, as noted with both codes in red, additional buffer reads are "blocked"
Output:
Code:
72 101 108 108 111 32 87 111 114 108 100 32 116 104 105 115 32 105 115 32 97 32 116 101 115 116 32 111 102 32 108 111 110 103 32 115 116 114 105 110 103 32 45 45 32 83 80 73 95 77 83 84 0 [COLOR="#FF0000"]-1 -1 [/COLOR]
Hello World this is a test of long string -- SPI_MST

:)

gonna work on peek() now...
 
Heres the peek() call from within the callback:

Method hijack: (same as read, but no incrementer)
Code:
    if ( _wire_callback_active ) {
      if ( _wire_callback_readpos >= mtsca.peek_front()[4] ) return -1;
      return (uint8_t)mtsca.peek_front()[_wire_callback_readpos+5];
    }

callback code:
Code:
Serial.print((char)W0.[COLOR="#FF0000"]peek[/COLOR]()); Serial.print(" ");
Serial.print((char)W0.[COLOR="#FF0000"]peek[/COLOR]());Serial.print(" ");
Serial.print((char)W0.[COLOR="#008000"]read[/COLOR]());Serial.print(" ");
Serial.print((char)W0.[COLOR="#FF0000"]peek[/COLOR]());Serial.println(" ");

Output:
Code:
[COLOR="#FF0000"]H H[/COLOR] [COLOR="#008000"]H[/COLOR] [COLOR="#FF0000"]e[/COLOR] 
Hello World this is a test of long string -- SPI_MST

::available() hijack was easier:
Code:
    if ( _wire_callback_active ) return mtsca.peek_front()[4] - _wire_callback_readpos;

Mike you missed alot, I'm queueing the entire incomming i2c buffer, so we dont get any losses!
I'm using hijacking methods do give calls dual function, one for callback mode, one for normal mode.
Normally if a device transmits twice to the slave only the last packet can be unloaded, previous one is lost
SPI_MST broke that barrier, where now you can throw anything at the port and it'll be consumed into the queue system :)

The library is getting smarter! lol

EDIT, I think thats it, we hijacked read(), read(buf), peek, available, we wont need to do write, that can run normal even from callback
gonna play with the code now
 
Don't worry mike, i found that pesky bug that makes yours work or not, it turns out one of the calls deasserted and further down it did another SPI dword transfer before deasserting again, because it was already deasserted, the dword sending was causing intermittant problems, ill upload fixed library in a few minutes, just having supper
 
I did manage to finally get it working on 2 T3.5s using Wire1 but was like pulling teeth. Had to remove threads and its still intermittent on startup. Sometimes it would even hang. Now aren't you glad, or not, that I test with different configurations than you all :)

Enjoy diner - just finishing diner here as well.
 
Master:
Code:
#include <SPI_MSTransfer.h>

SPI_MSTransfer W0 = SPI_MSTransfer("Wire", 43, &SPI2, 30000000 );

void setup() {
  Wire.begin(I2C_MASTER, 0, 0, 0, 0, I2C_PULLUP_EXT, 100000, I2C_OP_MODE_IMM);
  Serial.begin(115200);
  while (!Serial && millis() < 2000 );
  W0.onDetect([](AsyncMST info) {
    W0.begin(I2C_SLAVE, 0x22, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
    Wire.beginTransmission(0x22);
    Wire.write("Hello Master!", 13);
    Wire.endTransmission();
    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);

  if ( count > 10 ) {
    uint8_t buf[count] = { 0 };
    W0.read(buf, count);
    for ( uint16_t i = 0; i < count; i++ ) {
      Serial.print((char)buf[i]);
    } Serial.println();
  }
  else {
    Serial.print("Count: "); Serial.println(W0.read());
  }
  Serial.println();
}





void loop() {
  W0.events(1);
  static uint32_t wire_write_timer = millis();
  if ( millis() - wire_write_timer >= 1000 ) {
    wire_write_timer = millis();
    Wire.beginTransmission(0x22);
    char text1[] = "Yellow World -- SPI_MST";
    Wire.write(text1, sizeof(text1));
    Wire.sendTransmission();
    static uint8_t t = 1;
    Wire.beginTransmission(0x22);
    t++;
    Wire.write(t);
    Wire.sendTransmission();
  }
}

Slave:
Code:
#include <SPI_MSTransfer.h>

SPI_MSTransfer slave = SPI_MSTransfer("SLAVE", "STANDALONE");

void setup() {
  Serial.begin(115200);
  slave.begin( );
//   slave.debug(Serial);
}

void loop() {
   slave.events();
}

Code:
[ATTACH]13605._xfImport[/ATTACH]
 
Theres still some timing things to work on for i2c, but at least i got it capturing payloads properly.

I'll work on it tomorrow cuz i need a power nap before work ;P
 
Back
Top