Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 45

Thread: please help w code to NOT initialize variables

  1. #1
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114

    please help w code to NOT initialize variables

    i am trying to write a pgm for Teensy LC that time slices tasks and that part is easy
    via interval timer routine that increments the task number and main code that looks
    to see what the task number is and do that task accordingly. that all works fine.

    then i am trying to make the tasks hang proof without any elapsed time or loop
    count checks inside the task. i have a second interval timer set for slightly longer
    than the first interval timer. if any task takes too long the service routine for IT2
    gets run.

    i would like that event to cause a skip to the next task number in line. when i use
    goto to jump out of the isr and back to main c gets lost.

    so instead the isr for it2 sets a variable and does does a software restart. but
    because the restart causes re-initialization of all of the variables to zero, it loses
    the ability to know why it is starting up - power on or software restart.

    i think i could use eeprom but trying to avoid going there for several reasons, and
    am wondering if anyone knows how to tell the compiler that one or even all global
    variables should NOT get initialized ? best in the c code itself but if elsewhere that
    would be second best.

    or is there a register that i could check to see why a start or re-start occurred ?

    thanks

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    Interesting ... not sure how that can work:
    > On restart there is no state to return to.

    Any compiler controlled or stack objects will be initialized or random.

    Maybe a direct addressed part of RAM would survive under power and not reset on startup? An area outside of heap/stack and all compiler data areas?

    (some) T_3.x's have a few bytes of RAM in the RTC area that survive - though T_LC doesn't have a similar proper RTC and may not have any such bytes?

    With a single line of execution down though the stack - only waiting for it to return or maybe taking control and overtly pushing through that func()'s return address call - but leaving the isr() would seem to want to return to the point of interruption as maintained somewhere in the MCU?

  3. #3
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    Quote Originally Posted by defragster View Post
    Interesting ... not sure how that can work:
    > On restart there is no state to return to.

    Any compiler controlled or stack objects will be initialized or random.

    Maybe a direct addressed part of RAM would survive under power and not reset on startup? An area outside of heap/stack and all compiler data areas?

    (some) T_3.x's have a few bytes of RAM in the RTC area that survive - though T_LC doesn't have a similar proper RTC and may not have any such bytes?

    With a single line of execution down though the stack - only waiting for it to return or maybe taking control and overtly pushing through that func()'s return address call - but leaving the isr() would seem to want to return to the point of interruption as maintained somewhere in the MCU?

    thanks for the feedback

    i have done this before in a small pic. it does not matter what stack pointers or internal registers or hardware get reset/preset
    - it only matters that you write your code knowing that everything could be gone except one or two variables in ram. at the
    very beginning of main you test to see why you are there and act accordingly. in my case maybe just two variables - a flag
    to know if someone ran too long and the task number that did it, so on restart do next task in line. and since power is never
    removed you could know whatever you want if you could keep the compiler from doing its usual make everything zero gag.

    i will look into the rtc and see how many bytes and can i get to them. - actually i think TLC has no rtc but it does have
    a low power timer.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    That part was in response to the initial 'non-restart' efforts with ... ' back to main c gets lost.'

    For restart - I'd see if the 'void' area above code data and below stack survives restart. If there is a known good spot - you could keep a struct there and just hardcode a pointer to it. Not sure if 'names in the .ld' file might tell you were that is?

  5. #5
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    Quote Originally Posted by defragster View Post
    That part was in response to the initial 'non-restart' efforts with ... ' back to main c gets lost.'

    For restart - I'd see if the 'void' area above code data and below stack survives restart. If there is a known good spot - you could keep a struct there and just hardcode a pointer to it. Not sure if 'names in the .ld' file might tell you were that is?
    thanks again - yes now i get what you mean - it would almost have to either get lost or grow the stack to infinity.

    i will look into lptmr and sort thru the ld file.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    Quote Originally Posted by analog&RFmodels View Post
    thanks again - yes now i get what you mean - it would almost have to either get lost or grow the stack to infinity.

    i will look into lptmr and sort thru the ld file.
    Never looked much at .ld files until the 1062 ... the one for T_LC very simple.

    Maybe an edit to bump the stack down in : _estack = ORIGIN(RAM) + LENGTH(RAM);
    Reserve 64 or 256 Bytes there may work with -64 or -256 to that?
    Worth a quick test and where it is will be known - safe above stack. Build will perhaps fail - or maybe the area won't retain values not too hard to test.
    Maybe put a SIG in there and the same in a known EEPROM spot. If the SIG matches it can be used - if not then it is a fresh power up or maybe after upload? It may be all zeroed on any startup ... but that would be extra effort somewhere.

    Seems odd to write code expected to fail to run as well behaved and then punish it ?

  7. #7
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    Quote Originally Posted by defragster View Post

    Seems odd to write code expected to fail to run as well behaved and then punish it ?
    all good deeds must be punished. i had to do this once before w pic w application such that it
    needed to be robust as possible and if a task runs long skip to next one - if the fault heals so
    be it - if not at least run everything else - and do this without having to put overhead inside
    of each task to check if you have waited too long for input or how much time has elapsed.
    this was not so bad for T36 because it can run the TeensyThreads lib but TLC cannot.

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    @analog&RFmodels - would be interesting to see a skeleton of it working. Wondering what these tasks are doing in turn.

    Seems an _isr_timer could set a flag to casually check and bail without much overhead ... depending on how the task workload is cycling.

  9. #9
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    Quote Originally Posted by defragster View Post
    @analog&RFmodels - would be interesting to see a skeleton of it working. Wondering what these tasks are doing in turn.

    Seems an _isr_timer could set a flag to casually check and bail without much overhead ... depending on how the task workload is cycling.
    here is what i have since you suggested trying to use timer register - see comments middle of deck - reading timer does not work ?
    keep in mind that as a programmer i am a duffer

    Code:
    // teensy lc no hang time slice skeleton
    // calls tasks this order 01020103
    //                        ABACABAD
    // 8 slices 4 tasks
    // this case 1 s ea task
    // 8 s = whole pgm
    // task 0 4 times task 1 2 times  task 2 and 3 1 times
    // aborts slices that run too long
    // compile debug for now
    // of course normally tasks would be much shoter
    // time but slow allows debug using only serial
    // monitor 
    
    const int led = 13;
    
    // set time per slice
    volatile int us = 1000000;
    // set slice adder to trigger isr2 = abort long task 
    volatile int lg =  100000;
    
    //__no_init_ volatile int tc;
    
    volatile int tc;
    volatile int tr;
    volatile int tx;
    volatile int n3;
    volatile int rf;
    volatile int xx;
    
      IntervalTimer it1;
      IntervalTimer it2;
    
    // long detect
    void isr2() {
        cli();
        tx=99;
        ++tc;
        if(tc > 7) tc = 0;
        Serial.end();
        rf=1;
    //  this is a software restart
        SCB_AIRCR=0x05FA0004;
        return;
    }
    
    // increment task count via timer
    void isr() {
        cli();
        ++tc;
        if(tc > 7) tc = 0;
        sei();
        return;
    }
    
    void task0(int data) {
    Serial.print ("0");
    delay(500);
    }
    
    void task1(int data) {
    Serial.print ("1");
    delay(500);
    }
    
    void task2(int data) {
    Serial.print ("2");
    // make this delay 5000 to see response
    // to long task
    delay(500);
    }
    
    void task3(int data) {
    Serial.print ("3");
    delay(500);
      }
    
    int main() {
    mainx:
      Serial.begin(9600);
      delay(500);
      Serial.println("tr tc tx rf");
      tr=SCB_AIRCR;
      Serial.printf("%X",tr);
      Serial.println("*");
    // line below is where i am trying to
    // read and print one of the low power
    // timer registers (there are only 16
    // bits that are both read and write)
    // LPTMR0_CMR is at 4004_0008 and altho
    // it is 32 bits only 16 are r/w
    // if you uncomment  this line it still
    // compiles but freezes on that line
    // when you run it
    //  xx = LPTMR0_CMR;
      Serial.println("**");  
      Serial.printf("lptc  ");
      Serial.printf("%X",xx);
      Serial.println(" "); 
      Serial.println(tc);
      Serial.println(tx);
      Serial.println(rf);
      if(rf==1) {rf=0; goto cont;}
      tc=0;
      tx=0;
      rf=0;
      
      pinMode(led, OUTPUT);
      Serial.println("*");
      
    cont:
    
      it1.begin (isr,us);
      it2.begin (isr2,us+lg);
    
    loopm:
        it2.begin (isr2,us+lg);
    
        if (tc==0)  task0(1);
        it2.begin (isr2,us+lg);
    w0:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==0) goto w0;
    
        if (tc==1)  task1(1);
        it2.begin (isr2,us+lg);
    w1:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==1) goto w1;
    
        if (tc==2)  task0(1);
        it2.begin (isr2,us+lg);
    w2:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==2) goto w2;
    
        if (tc==3)  task2(1);
        it2.begin (isr2,us+lg);
    w3:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==3) goto w3;
    
        if (tc==4)  task0(1);
        it2.begin (isr2,us+lg);
    w4:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==4) goto w4;
    
        if (tc==5)  task1(1);
        it2.begin (isr2,us+lg);
    w5:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==5) goto w5;
    
        if (tc==6)  task0(1);
        it2.begin (isr2,us+lg);
    w6:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==6) goto w6;
        
        if (tc==7)  task3(1);
        it2.begin (isr2,us+lg);
    
        Serial.println (" ");
    w7:
        if (tx==99) {tx=0; goto loopm;}
        if (tc==7) goto w7;
    
      goto loopm;
    
    }

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    Not building with IDE? Are you on Windows?

    Accessing the timer unit if not enabled it will fault.

    Was the persistence of 'unused' RAM tested?

  11. #11
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    Quote Originally Posted by defragster View Post
    Not building with IDE? Are you on Windows?

    Accessing the timer unit if not enabled it will fault.

    Was the persistence of 'unused' RAM tested?
    good point - i will enable lptmr first and see if solves, but worry that once enabled it might start incrementing
    every millisecond and destroy my data.
    have not tried unused ram yet - need to figure out how to read and write to an absolute memory address first.
    yes - ide is arduino 1.8.5 under windows

    meanwhile, here is eeprom version - works fine - i will have to look into how many eeprom writes to kill a location
    to see if it really practical - no good if erratic situation requiring many restarts writes the eeprom to death in two
    days. if the time slices are short that could happen often - maybe a scheme that would count writes and spread
    the damage over all 128 locations would make it practical.

    Code:
    // teensy lc no hang time slice skeleton
    // calls tasks this order 01020103
    //                        ABACABAD
    // 8 slices 4 tasks
    // this case 1 s ea task
    // 8 s = whole pgm
    // task 0 4 times task 1 2 times  task 2 and 3 1 times
    // aborts slices that run too long
    // compile debug for now
    // of course normally tasks would be much shoter
    // time but slow allows debug using only serial
    // monitor
    // uses eeprom addr 50 for 0/1 soft restart flag
    // uses eeprom addr 51 for save tc
    
    #include <EEPROM.h>
    
    const int led = 13;
    
    // set time per slice
    volatile int us = 1000000;
    // set slice adder to trigger isr2 = abort long task 
    volatile int lg =  100000;
    
    //__no_init_ volatile int tc;
    
    volatile int tc;
    volatile int tr;
    volatile int tx;
    volatile int n3;
    volatile int rf;
    volatile int xx;
    
      IntervalTimer it1;
      IntervalTimer it2;
    
    // long detect
    void isr2() {
        cli();
        tx=99;
        ++tc;
        if(tc > 7) tc = 0;
        Serial.end();
        EEPROM.write(50,1);
        EEPROM.write(51,tc);
        Serial.println("eeprom write");    
    //  this is a software restart
        SCB_AIRCR=0x05FA0004;
        return;
    }
    
    // increment task count via timer
    void isr() {
        cli();
        ++tc;
        if(tc > 7) tc = 0;
        sei();
        return;
    }
    
    void task0(int data) {
    Serial.print ("0");
    delay(500);
    }
    
    void task1(int data) {
    Serial.print ("1");
    delay(500);
    }
    
    void task2(int data) {
    Serial.print ("2");
    // make this delay 5000 to see response
    // to long task
    delay(500);
    }
    
    void task3(int data) {
    Serial.print ("3");
    delay(500);
      }
    
    int main() {
      Serial.begin(9600);
      delay(500);
      Serial.println("*");
      rf=EEPROM.read(50);
    //  if(rf==1) {rf=0; goto cont;}
      if(rf==1) {
                EEPROM.write(50,0);
                Serial.println("eeprom write");
                tc=EEPROM.read(51);
                goto cont;
                }
      tc=0;
      tx=0;
      rf=0;
      
      pinMode(led, OUTPUT);
    
    cont:
    
      it1.begin (isr,us);
      it2.begin (isr2,us+lg);
    
    loopm:
        it2.begin (isr2,us+lg);
    
        if (tc==0)  task0(1);
        it2.begin (isr2,us+lg);
    w0:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==0) goto w0;
    
        if (tc==1)  task1(1);
        it2.begin (isr2,us+lg);
    w1:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==1) goto w1;
    
        if (tc==2)  task0(1);
        it2.begin (isr2,us+lg);
    w2:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==2) goto w2;
    
        if (tc==3)  task2(1);
        it2.begin (isr2,us+lg);
    w3:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==3) goto w3;
    
        if (tc==4)  task0(1);
        it2.begin (isr2,us+lg);
    w4:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==4) goto w4;
    
        if (tc==5)  task1(1);
        it2.begin (isr2,us+lg);
    w5:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==5) goto w5;
    
        if (tc==6)  task0(1);
        it2.begin (isr2,us+lg);
    w6:
        if (tx>98) {tx=0; goto loopm;}
        if (tc==6) goto w6;
        
        if (tc==7)  task3(1);
        it2.begin (isr2,us+lg);
    
        Serial.println (" ");
    w7:
        if (tx==99) {tx=0; goto loopm;}
        if (tc==7) goto w7;
    
      goto loopm;
    
    }

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    Haven't tried the direct address - but the .ld shows this :: RAM (rwx) : ORIGIN = 0x1FFFF800, LENGTH = 8K

    Assume that is helpful? Make a static int and a stack int and print their addresses - should align with that mathwise?

    Put something large on the stack int foo[500] and print the first and last address of foo? if that is more stack than ever used try the &foo[499] for a pointer value and store something there in a different sketch then check the value after powerup, upload, restart between runs.

    If that works then edit the .ld and use bytes above the stack and repeat the test?

    T_LC EEPROM not as robust as other Teensy given the MCU that makes it LC - good for general usage (some many K writes IIRC) and it will wear level as it can for given elements with the 128 bytes across 4K. But indeed a code spasm could eat that life up.

  13. #13
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    too much work for a duffer - when i set up a pointer to the ram area - either 25 bytes from bottom or
    25 bytes from top, compiles fine, hang on run - must be somebody trying to keep me out. decided
    against the lptmr register because then you would never have lptmr if you wanted it. eeprom does
    not have decent write life. robust apps will have to have something that can run threads unless i
    can somehow force a jump out of the long detect isr back to main, because then there need be
    no soft restart and therefore no initialization free memory.

  14. #14
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,919
    The 3x and 4x have some bytes Battery backed up RAM.
    Or use external static ram with battery backup.

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    @FrankB > post#2 noted battery backed RAM in other Teensy - but this project seems T_LC specific.

    It looks like T_LC flushes ALL RAM in all the restarts I tried:
    Code:
    int bar = 0;
    
    void setup() {
      // put your setup code here, to run once:
      while (!Serial && millis() < 2000) ; // wait
      Serial.println("\n USB SERIAL " __FILE__ " " __DATE__ " " __TIME__);
      //  SerialUSB1.println("\n SerialUSB1 " __FILE__ " " __DATE__ " " __TIME__);
      //  SerialUSB2.println("\n SerialUSB2 " __FILE__ " " __DATE__ " " __TIME__);
      int barA = 0;
      int foo[100];
      int barB = 0;
      Serial.printf("STATIC >> addr &bar %lu \t0x%lX \n", &bar, &bar );
      Serial.printf("addr &barA %lu \t0x%lX \n", &barA, &barA );
      Serial.printf("addr &foo[0] %lu \t0x%lX \n", &foo[0], &foo[0] );
      Serial.printf("addr &foo[99] %lu \t0x%lX \n", &foo[99], &foo[99] );
      Serial.printf("addr &barB %lu \t0x%lX \n", &barB, &barB );
    
      pinMode( 13, OUTPUT );
      digitalWriteFast( 13, !digitalReadFast( 13 ));
      uint32_t *iSurvive = (uint32_t *)0x20001000;
      Serial.printf("addr iSurvive %lu \t0x%lX \n", iSurvive, iSurvive );
    
      Serial.printf("VALUE iSurvive %lu \t0x%lX \n", iSurvive[0], iSurvive[0] );
      if ( iSurvive[0] != 0x12345678 ) {
        iSurvive[0] = 0x12345678;
        Serial.printf("SET VALUE iSurvive %lu \t0x%lX \n", iSurvive[0], iSurvive[0] );
      }
    
    }
    elapsedMillis iBlink;
    void loop() {
      if ( iBlink > 300 ) {
        iBlink = 0;
        digitalWriteFast( 13, !digitalReadFast( 13 ));
      }
      if ( Serial.available() ) {
        _reboot_Teensyduino_();
      }
    
    }
    Even with .ld edit :: _estack = ORIGIN(RAM) + LENGTH(RAM)-256;
    and this :: uint32_t *iSurvive = (uint32_t *)0x200016A0;

    The stack moved down - it compiled - but it doesn't survive a reset.

  16. #16
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    115
    Thinking outside the box, what about writing the task number to 4-bits (or however many bits you need to cover all possible tasks) of a 75HC595 & then just read those outputs from the 74HC595 as inputs whenever a reset (not a fresh power-up) is activated to see which task was last executing. Let a fresh power-up activate the reset on the 74HC595 (via an RC circuit or some other means that does not depend upon the Teensy).

    Mark J Culross
    KD5RXT

  17. #17
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,919
    Quote Originally Posted by kd5rxt-mark View Post
    Thinking outside the box, what about writing the task number to 4-bits (or however many bits you need to cover all possible tasks) of a 75HC595 & then just read those outputs from the 74HC595 as inputs whenever a reset (not a fresh power-up) is activated to see which task was last executing. Let a fresh power-up activate the reset on the 74HC595 (via an RC circuit or some other means that does not depend upon the Teensy).

    Mark J Culross
    KD5RXT
    ...a static spi-ram has more space and may be even easier to use..

    But i'd just a T3x anyway.

  18. #18
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,253
    I agree with Frank, the best solution is to use Teensy 3.2 with a coin cell on VBAT. Then you can store this data in the battery supported RTC memory.

    Another good approach would be to add a FRAM chip. While those technically do have a limit, the write endurance of FRAM is so high and the bandwidth is limited by SPI or I2C speed enough that it would take a lifetime to reach the endurance limit, even if stuck in an infinite loop writing at the maximum possible speed. If a battery is unacceptable and you absolutely must have a highly robust non-volatile memory which can withstand rapid writing, FRAM is the solution.

  19. #19
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,931
    Quote Originally Posted by defragster View Post
    @FrankB > post#2 noted battery backed RAM in other Teensy - but this project seems T_LC specific.
    ...
    If using a T_3.2 or better ... this whole experiment could use TeensyThreads (p#7 ) - for RTC RAM - seems the desire was to use T_LC and make something work there with this prior scheme.

    So yes external storage seems needed - if not using EEPROM for storage - as the T_LC doesn't seem to have any space that survives.

  20. #20
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    defragster, Frank, Mark, Paul - thanks for all the good feedback. i will look at all of the relative cost size etc but i would
    not be surprised if TLC + shift register wins -- one external chip, no coin battery, and if the shift register has a reset
    as the 595 and many do then one rc to the reset pin for POR, 3 wires to TLC (clk, dtaout, datain). also Frank, your
    arm_reset function works well T4 for those cases where time is the only wake up criteria you need and cold start ok,
    only draws 220 ua while it is "gone".

    i even tried Duff's excellent Zilch library (V0.3 that will play w TLC) and it is great, will handle with grace a task that is
    slow, but grinds to a halt with a hung task. and when i look at all the code he wrote to get Zilch going it makes me
    think this is a non trivial pursuit.

    but since the EEPROM version works well it just needs slight mods to use a shift register instead - and right now there
    are only 8 tasks so that is only 3 bits and maybe a forth bit for start-up status.

    thanks again everyone for all of the feedback and i will post here what ends up being the solution used.

    i think maybe i am biased toward TLC because it has such low hibernate current and also because at
    this point it has become personal between me and the TLC.

  21. #21
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    at $0.57 singles and 0.49 10's the TLC + HC595 wins the cost battle - had a 595 in junk box - works fine - using as serial in serial out
    remember that you need to re-write a shift register as you read it or the read is destructive. also - put a pull down on whatever TLC
    pin is used to clock the shift register as all of the io pins go tri-state for a short time during the software restart. i used a 15k pullup
    on the 595 reset pin with a 0.01u to gnd for POR and a 0.1u bypass - whole thing on 2 inch 5 cond ribbon. so with 1 flag bit and 3
    bits for task number there are 4 bits left over for addtl info. this all works out for TLC because you do not have to have anti hang
    code (like preventing death with a hung peripheral or sensor) in any of the tasks which saves much needed code space and makes
    code memory go further.

    thanks again everyone for helping out.

  22. #22
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    115
    Glad everything worked out so well & that this approach satisfies the need !! Quite frankly, my thinking when I proposed the "outside-the-box" idea was to read the outputs from the 75HC595 using more input pins on the Teensy, but your seriial in/serial out approach is ingenious, as it requires only one additional pin !! Very well done, indeed !!

    Mark J Culross
    KD5RXT

  23. #23
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    Quote Originally Posted by kd5rxt-mark View Post
    Glad everything worked out so well & that this approach satisfies the need !! Quite frankly, my thinking when I proposed the "outside-the-box" idea was to read the outputs from the 75HC595 using more input pins on the Teensy, but your seriial in/serial out approach is ingenious, as it requires only one additional pin !! Very well done, indeed !!

    Mark J Culross
    KD5RXT
    Mark,
    you can't have too many unused pins !! gotta admit i went cross-eyed debugging my code for care and feeding of
    serial in/serial out (haven't used a "circular memory" since the 70's). i hate that there is no flag to tell the compiler
    to leave the user ram alone at startup. thanks again for the good feedback - i was stuck "inside the box".
    Bill

  24. #24
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    114
    it turns out there is some register storage in Teensy LC that will live thru a software restart
    - 16 bits of the lptmr compare register. at one point defragster told me not to try to use it
    unless i had enabled it - i only thought i had - see below

    Code:
    // Teensy LC retain data after software restart
    
    // early on you have to enable BOTH the module and the timer
      SIM_SCGC5 = SIM_SCGC5 | SIM_SCGC5_LPTIMER;
      LPTMR0_CSR = LPTMR0_CSR | LPTMR_CSR_TEN;
    // then store data before the restart
      LPTMR0_CMR = srdataw;
    // or read data after after the restart
      srdatar = LPTMR0_CMR;
    // have only tested 8 bit store
    // but should be good for 16
    // here is the software restart
      SCB_AIRCR=0x05FA0004;

  25. #25
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    456
    I haven't looked at it, but this might be relevant.

    Code:
    int x __attribute__((noinit));

Posting Permissions

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