uNav INS

the events is there to check if theres any messages from queue, if its not called, the master wouldnt know items are available. an empty queue sends a notmal 4 dword confirmation message back to master to drop line
if you have another suggestion, let me know. If you want a dedicated GPIO for an "interrupt" simulation, sortof, we could have the slave signal a line HIGH that master sees theres data, and it will stay high until all of its items dequeue, then events() could stop processing until the line goes HIGH again, the interrupt would be on master, but i do believe you dont need an "interrupt" as you could poll that pin in normal loop. However, If we do add "interrupt" capability, we could also have pass-through interrupts some way or another from the slave's IO pins, a design decision will need to go into that before we start writing the code

Also, I think we should set the queue array limit same as

Code:
#define DATA_BUFFER_MAX 200

so:
Code:
    static                  Circular_Buffer<uint16_t, 12, DATA_BUFFER_MAX> mtsca;
    static                  Circular_Buffer<uint16_t, 12, DATA_BUFFER_MAX> stmca;

Why stop there, heres the update:
Code:
#define DATA_BUFFER_MAX 200
#define QUEUE_SLOTS 12

Code:
    static                  Circular_Buffer<uint16_t, QUEUE_SLOTS, DATA_BUFFER_MAX> mtsca;
    static                  Circular_Buffer<uint16_t, QUEUE_SLOTS, DATA_BUFFER_MAX> stmca;
 
Tony: 100 ms default seems reasonable - on correctly conditioned ( :rolleyes: ) code for entry sounds good. I only did one quick test ... and didn't look close.

I could see 5 or 8 buffers of 200 ? I put 12 to make sure - but that will be a lot of RAM wasted - TWICE over - especially with no programmed use of Sl > Ma transfers.

Mike: Yes, that IMU_init is where I traced into the MPU9250 code to find the errors were not helpful - it was a hardware fail because of the F_BUS speed as noted.

>> .events is .available .... Master has to PING the Slave to find out if it has anything to send.

TONY:: the SLAVE telling the Master 'ACK no event pending' and 'ACK event pending' could be updated when we do the pinToggle and then the Master would KNOW that there is something .available() and we could then call .events()?
 
Was just thinking out loud. Question on interrupts is, since you brought it up, is it useful of other things than events so it would make it worth it to implement?

BTW - nice update on the buffer sizes :)

EDIT: OK we need to stop typing at the same time. Can the T3.5 F_BUS speed be changed - missed something somewhere....
 
I guess during ACK's yes, but all the methods would need to be "adapted" to an extra field. Then theres also the slave -> master transfers which send the entire array without adding overhead...
I could probably sneak it in somewhere, like the CRC validation, where it sends a "special" byte before the continue byte, and the master would capture that before continuing it's own course..

example:

Code:
bool SPI_MSTransfer::command_ack_response(uint16_t *data, uint32_t len) {
  uint8_t resend_count = 0; uint32_t timeout = micros(); uint16_t _crc = 0;
  while ( 1 ) {
    _crc = spi_port->transfer16(0xFFFF);
    if ( _crc == 0xF00D ) {
     [COLOR="#FF0000"] spi_port->transfer16(0xBEEF); break; // <-- this means CRC passed and the slave is ready for next action for switch statement[/COLOR]
    }
    else if ( _crc == 0xBAAD ) {
      [COLOR="#FF0000"]spi_port->transfer16(0xBEEF); SPI_deassert(); return 0;  // <-- this means CRC was bad, and the master exits[/COLOR]
    }

[COLOR="#FF0000"]    else if ( _crc == 0xBABA ) {
      // set a variable saying theres data available // <------ it would capture HERE before F00D is returned
    }[/COLOR]


    if ( micros() - timeout > 1000 ) {
      resend_count++;
      if ( resend_count > 3 ) {
        if ( debugSerial != nullptr ) {
          Serial.print("DBG: [S_CS "); Serial.print(chip_select);
          Serial.print("] FAIL_RES #"); Serial.print(resend_count);
          Serial.print(" Tx ABORT. "); delay(1000);
        }
        break;
      }
      if ( debugSerial != nullptr ) {
        Serial.print("FAIL_Res #"); Serial.print(resend_count);
        Serial.print(" RETRY..."); delay(1000);
      }
      timeout = micros();
    }
  }
  return 1;
}
 
Rushing to lunch here ... catch me up if I miss anything.

Tony: I was thinking the Slave when it had stuff queued to send on command with ACK BYTE could send an alternate ACK_A value - we already do pinToggle so that would cover us. Otherwise we could just call .events()

I think a short value for timeout? - maybe conditional on SPI_SPEED - like I added in the sample slave? At 30 MHz there is no reason to wait more than 10 uS between transfers to call it failed

Mike: With i2c_t3 I don't think the alternate F_BUS is required - and it was fine at 180 MHz - only showed at 240 - so may not be an issue on T_3.5 - esp with i2c_t3.

Not sure what else is ready to help with interrupt? IMU and SerialRx I wrote are covered. Anything else appropriate? The SPI_MST is on request from Master and an isr() already on Slave.
 
Tim, I just wrote up a quick one that wont touch any functions, pinToggle passes by the CRC routine so no need to verify. I have it working via the CRC validation before the commands are issued on slave, so it'll work for ALL non-F&F functions
the master events() loop is blocked from running 100% until the flag is set, which releases it to do its code, upon completion and no other data, the events is currently blocked until new data is ready

H
https://github.com/tonton81/SPI_MSTransfer/commit/668d394beb29a5637bc0e6170672db62938cbe76

CPP
https://github.com/tonton81/SPI_MSTransfer/commit/a587411daf2440dc0333434218769406eeadc2c4

This is actually more efficient and makes the events timer actually useless (well not really, it can space those events apart evenly)
 
Last edited:
Guys, I'm not getting the demo example to work for SPI_Transfer either. I'm getting this error message on the Master side

DBG: [S_CS 15] FAIL_RES #4 Tx Abort. F&F
FAIL_Res #1 RETRY...FAIL_Res #2

and a blank screen on the slave side. I've tried multiple recompiles and different settings with now luck. My hardware setup is

MasterT36 - SlaveT36
GND - GND
11 - 12
12 - 11
15 - 2 (tried 15 - 15 also)
14 - 14

Any suggestions? Probably doing something stupid but not figuring it out...

Don
 
slave 12,11,2,14 are correct and hardcoded

since ur using spi0 on the master, you need to assign SPI.setSCK(14) and SPI.setCS(15)
they must also be set in your config.h, which you should normally have SPI.begin() as well in setup()

the TV demos Tim posted are the ones i use for testing on the repo
 
Don: looking into your config's entries they look right. If you have the last from Mike ( and my updated main.ino ) it should work if the wires are good and right? Double count and check them against the T_3.6 Teensy Card?

I see NAN's again! I caught them with my code to assert() - but focusing on coding this part 'compiler' approved:: "if ( std::isnan( MST_PrintVals[jj] ) )" , inadvertently bypassed the HALT so any debug context is lost and scrolled off! All I can say is that the MST_PrintVals[ [1] to [16] coming in to serialPrint() tested as NaN's! It takes some minutes/hours to get there with unit sitting untouched.

I've not seen usable assert() code for Teensy? - but I wrote something that works I'll clean up for this context so it can be dropped closer to the possible error source to catch it.

Tony: That looks like a good simple change! I am not set up to test this, but that looks like it will solve the problem without 'wasted' messages when the Slave is offline - or has no messages - so .events() won't be nutty, the Master seeing ACK==0xADD0 will know after that to allow .events() to make the call to process.
>> Should the 0xADD0 case do the "spi_port->transfer16(0xBEEF);" ?
>> And when ACK== 0xF00D you might set _slave_data_available = 0; ? Assuming after resolving the first pending Message from Slave, if there are more the ACK==0xADD0 will set it again?
>> Is there a 'PING' like 'doNothing' but connect and get ACK command ?
 
no the case shouldnt do anything but capture, the other switch statement will handle BEEF, this because its sent as a signal before the CRC validation. but yeah every flag will be set from the link and unset when events sees no more queues, so two things will happen, 1st stage is events() is permitted to run, 2nd stage itll space the runs 100ms aparts unless otherwise specified, until the events clear, then and only then will events() unset the flag to block itself.
 
no the case shouldnt do anything but capture, the other switch statement will handle BEEF, this because its sent as a signal before the CRC validation. but yeah every flag will be set from the link and unset when events sees no more queues, so two things will happen, 1st stage is events() is permitted to run, 2nd stage itll space the runs 100ms aparts unless otherwise specified, until the events clear, then and only then will events() unset the flag to block itself.

With this "if ( !_slave_data_available ) return 0; " limiter to messages waiting on Slave to identify - the time check is not needed? If called repeatedly it should quickly pull and process all Slave message?

Just wondered "where's the 0xBEEF" :) , and wanted to be sure _slave_data_available was always set/unset for all cases.
 
master unsets it when queue is invalidated (0)

your events() timer functions as a gap between the queueues

if theres 5 queues, events will process all 5 with a 100ms gap until a no queue signal is sent from events(), at which point, the entire events() goes to sleep until a signal wakes it back up
 
Don,
I know this may sound silly but make sure your configuration is set in the a_configs tab and not mine or Tim's. That one kept biting me in the past.

Mike
 
master unsets it when queue is invalidated (0)

your events() timer functions as a gap between the queueues

if theres 5 queues, events will process all 5 with a 100ms gap until a no queue signal is sent from events(), at which point, the entire events() goes to sleep until a signal wakes it back up

In that case a default faster than 100ms may be better. It won't ever call too fast with the check for nothing _available, but if Slave has messages ( for those that use them ) not seeing them for 100ms might be too long - user can always set down - but it can't do what it was before to the poor GPS now.

Mike/Don: No update on NaN capture yet . . . so far the numbers are numbers. I haven't looked to see what the number mean - they may be drifting out of range? I have not done Calibration recently so I may have bias in there?

Mike: I don't know about dtostrf() using float or double? It is taking doubles and getting '10,10' resolution from 6 of them? If only float precision is needed - then that would save transmit and resolve time.
 
"No update on NaN capture yet . . . so far the numbers are numbers." - I just woke up so back at it. I am going to let the T3.5s run for awhile and see if I get NaNs and will let you.

Don: Do we really need to dump doubles or would float's suffice. The only values I would think needed doubles would be lat and long but for testing think floats would suffice.
 
yup, if slave is never sending data then events() will be eternally in sleep mode
im testing the latest github copy running the tvviewer while slave is sending data to master and it seems to be running pretty well with the 100ms and 0 OT’s
 
"No update on NaN capture yet . . . so far the numbers are numbers." - I just woke up so back at it. I am going to let the T3.5s run for awhile and see if I get NaNs and will let you.

Don: Do we really need to dump doubles or would float's suffice. The only values I would think needed doubles would be lat and long but for testing think floats would suffice.

If it helps you can try the NaN tester I'm waiting on to catch failed ASSERT: View attachment C_serialPrint.ino
I modified use so the jj index could be printed - in case only one goes out first. It will HALT the MASTER so the debug and TViewer output will freeze in place in case that can lead to context.
Until I saw the fails on the SerMon - as posted ALL WERE NaN's - even Lat and Lon - which makes no sense?
 
Tim
Haven't had a problem with NaNs, but I have to admit never tried running over night. I just incorporated your assert code to see if I can catch any.
Mike
 
Mike,
The doubles were in Brian's code. I think his thought was to convert all the internal parms to double, and I think he's headed that direction. Some are still floats in the EKF. My guess is floats are probably fine for now, but may be necessary for RTK. Would have to study it more to be sure.

Tim,
I went back and re-wired my board, and tested with the pre-SPI code, and data streams to serial just fine. But when I try to run your main.ino with mike's other tabs, and using the TVslaveDK he sent me, I get the following. Still can't figure it out. I suppose I need to fall back to the pre-SPI 15-State and try re-inserting things, don't know what would be best.


Serial Initialized

Loading Accel and Mag Biases and Scale Factors
Accel and Mag Biases and Scale Factors Loaded

Accel Biases and Scale Factors:
-0.043603, 1.001250
-0.043603, 1.000263
-0.340763, 0.994053

Mag Biases and Scale Factors:
16.742832, 1.019413
43.921291, 1.090688
-24.235130, 0.907284

Gyro Calibration Underway
Gyro Calibration Complete

Setup Complete
FAIL_Res #1 RETRY...FAIL_Res #2 RETRY...FAIL_Res #3 RETRY...DBG: [S_CS 15] FAIL_RES #4 Tx ABORT. WARNING: Apparent loss of IMU data !!
 
Don
What boards are you using? I am having similar problems now. I am beginning to think sending that much data without two 3.6's is giving me headaches. I am toying with the idea to break it up into 2 packets and reassemble on the slave.

Don/Tim what do you think?
 
Mike,
I'm using two T3.6s setup like this still:

MasterT36 - SlaveT36
GND - GND
11 - 12
12 - 11
15 - 2
14 - 14

One thing that seems weird is the "WARNING: Apparent loss of IMU data" warning. I don't get that when running the pre-SPI code, so why would IMU data not refresh?

FAIL_Res #1 RETRY...FAIL_Res #2 RETRY...FAIL_Res #3 RETRY...DBG: [S_CS 15] FAIL_RES #4 Tx ABORT. WARNING: Apparent loss of IMU data !!

Don
 
If you are using Tim's code uncomment coutD and make it Serial. He has GPS debug code to see the number of satellites. It could be your numSV is below 6.
 
Tony. Actually think I could use 1 call back with just the MessageID changed. So if the second message is 56 vs 55 I test for last message 55 and do a strcat.
 
Don, try to load maybe one of the TVmaster/slave demo from the repo, they do work so we can narrow the issue down to wiring/config.h issues

using that demo its still running without errors for several hours using a t3.5 & t3.6
also make sure the library is up to date, modifications were added recently for efficiency
 
Back
Top