Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Teensy2.0++ Progmem>53% corrupting USB functionality

  1. #1
    Junior Member
    Join Date
    Apr 2020
    Posts
    4

    Teensy2.0++ Progmem>53% corrupting USB functionality

    Hello,

    i am porting a common license PWM-sample-drumbox to teensy2++ over teensyduino/teensy loader V1.51. The project reads 8bit array values from Progmem into a ringbuffer and generates audio with hardware PWM. Everything is working perfect, the code occupies about 12% of progmem, 8% ram.

    Now i fill more and more program memory with these audio-sample arrays for having more audiosamples to play. From a certain point of used program memory - somewhere around 53% - i get a problem: after flashing over usb (and the rebooting display in the loader), windows loses the USB device and the project does not work anymore. I have to replug USB with the button pressed down and flash a smaller project first until the teensy2.0++ will be recognized by USB and working properly again.

    To me it looks like a program occupying more than 53% starts to 'overwrite' parts of the bootloader/USB driver. Having written bootloaders myself (for flashing firmwares over UART/MIDI) i doubt the usb/flashing functionality occupies nearly 50%/64k of the progmem.

    If someone please could give me a hint what might be wrong, most probably i misunderstood something essential about the teensy/usb flashing concept?

    thanks in advance
    Gregor

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,146
    Not used T_2's family - but Paul's bootloader is called 'HalfKay' - and expect whatever space it uses is accounted for in 'available' resources.

    The Teensy family uses MCU's with onboard USB - not an external UART<>USB chip. So when the code crashes the USB stack fails … if it is like the T_3 and later ARM units.

    Common cause there is that some memory corruption from a bad pointer or other code problem that doesn't hit anything under 53% hits something essential as additional resources are consumed.

    As samples are read and acted on guess would be errant pointer or indexing or loading of subsequent additional samples, or a larger or ill formed sample read?

    Without T_2 history and no code to see that is just typical speculation ...

  3. #3
    Senior Member
    Join Date
    May 2017
    Posts
    125
    Hello,

    according forum rules please post your code. Here are a lot of people wich are able to point you in the right direction if code shown.

    My blind guess is, you have function calls wich use a lot of heap (maybe you have local arrays in your code or so).

  4. #4
    Junior Member
    Join Date
    Apr 2020
    Posts
    4
    Code:
    // dsp-L8 Latin Perc Chip (c) DSP Synthesizers 2015
    // Free for non commercial use
    // http://janostman.wordpress.com
    
    // modified by G.Zoll, 04/2020 for miditrigger, multiple kits, teensy2++, ...
    
    #include <avr/interrupt.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <MIDI.h>
    
    #include "samples_909.h"      // 1-8
    #include "samples_MiniPops.h" // 9-16 selected by 9 to GND
    #include "samples_latin.h"    // 17-24 selected by 10 to GND
     
    
    #ifndef cbi
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #endif
    #ifndef sbi
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #endif 
    
    
    #define digitalReadFast(P) bitRead(*digitalPinToPINReg(P), digitalPinToBit(P))                  
    #define digitalWriteFast(P, V) bitWrite(*digitalPinToPortReg(P), digitalPinToBit(P), (V))
    
    const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
    
    int led = 6;
    
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
    
    // arrays with 8 sample lenghts sorted by kits
    
    uint16_t smpLength1[3] = {SampleLength1, SampleLength9, SampleLength17};
    uint16_t smpLength2[3] = {SampleLength2, SampleLength10, SampleLength18};
    uint16_t smpLength3[3] = {SampleLength3, SampleLength11, SampleLength19};
    uint16_t smpLength4[3] = {SampleLength4, SampleLength12, SampleLength20};
    uint16_t smpLength5[3] = {SampleLength5, SampleLength13, SampleLength21};
    uint16_t smpLength6[3] = {SampleLength6, SampleLength14, SampleLength22};
    uint16_t smpLength7[3] = {SampleLength7, SampleLength15, SampleLength23};
    uint16_t smpLength8[3] = {SampleLength8, SampleLength16, SampleLength24};
    
    
    //--------- Ringbuf parameters ----------
    uint8_t Ringbuffer[256];
    uint8_t RingWrite=0;
    uint8_t RingRead=0;
    volatile uint8_t RingCount=0;
    volatile uint16_t SFREQ;
    //-----------------------------------------
    
    ISR(TIMER1_COMPA_vect) {
      
        //-------------------  Ringbuffer handler -------------------------
        
        if (RingCount) {                            //If entry in FIFO..
          OCR2A = Ringbuffer[(RingRead++)];          //Output LSB of 16-bit DAC
          RingCount--;
        }
        
        //-----------------------------------------------------------------
    }
    
    void setup() {
      
        OSCCAL=0xFF;
            
        //8-bit PWM DAC pin
        pinMode(24, OUTPUT);
    
        // inputs for selection of kits
        pinMode(PIN_E0,INPUT_PULLUP);  // E0
        pinMode(PIN_E1,INPUT_PULLUP);  // E1
        
    
        //_______________________________________________ Set up Timer 1 to send a sample every interrupt.
        cli();
        // Set CTC mode
        // Have to set OCR1A *after*, otherwise it gets reset to 0!
        TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
        TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));    
        // No prescaler
        TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
        // Set the compare register (OCR1A).
        // OCR1A is a 16-bit register, so we have to do this with
        // interrupts disabled to be safe.
        //OCR1A = F_CPU / SAMPLE_RATE; 
        // Enable interrupt when TCNT1 == OCR1A
        TIMSK1 |= _BV(OCIE1A);   
        sei();
        
        //OCR1A = 200; //was '400' for 40KHz Samplefreq
    
        // _______________________________________________Set up Timer 2 to do pulse width modulation on D11
    
        // Use internal clock (datasheet p.160)
        ASSR &= ~(_BV(EXCLK) | _BV(AS2));
    
        // Set fast PWM mode  (p.157)
        TCCR2A |= _BV(WGM21) | _BV(WGM20);
        TCCR2B &= ~_BV(WGM22);
    
        // Do non-inverting PWM on pin OC2A (p.155)
        // On the Arduino this is pin 11.
        TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
        TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
        // No prescaler (p.158)
        TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
    
        // Set initial pulse width to the first sample.
        //OCR2A = 128;
    
        //_______________________________________________set timer0 interrupt at 61Hz
        /*  UNUSED
        TCCR0A = 0;// set entire TCCR0A register to 0
        TCCR0B = 0;// same for TCCR0B
        TCNT0  = 0;//initialize counter value to 0
        // set compare match register for 62hz increments
        OCR0A = 255;// = 61Hz
        // turn on CTC mode
        TCCR0A |= (1 << WGM01);
        // Set CS01 and CS00 bits for prescaler 1024
        TCCR0B |= (1 << CS02) | (0 << CS01) | (1 << CS00);  //1024 prescaler 
    
        TIMSK0=0;
        */
    
        // _______________________________________________set up the ADC
        SFREQ=analogRead(0);
        ADCSRA &= ~PS_128;  // remove bits set by Arduino library
        // Choose prescaler PS_128.
        ADCSRA |= PS_128;
        ADMUX = 64;
        sbi(ADCSRA, ADSC);
    
        // midi
          // Initialise MIDI
        MIDI.begin(MIDI_CHANNEL_OMNI);
        MIDI.setThruFilterMode(midi::Thru::Off);
      
        // Initialise MIDI message handlers
        MIDI.setHandleNoteOff(midiNoteOffHandler);
        MIDI.setHandleNoteOn(midiNoteOnHandler);
        //MIDI.setHandleControlChange(midiControlHandler);
             
    }
    
      uint8_t phaccAG,phaccCA,phaccMA,phaccWH,phaccTI,phaccCH,phaccQU,phaccBO;
      uint8_t pitchAG=32;
      uint8_t pitchCA=64;
      uint8_t pitchMA=64;
      uint8_t pitchWH=32;
      uint8_t pitchTI=64;
      uint8_t pitchCH=16;
      uint8_t pitchQU=16;
      uint8_t pitchBO=64;
      uint16_t samplecntSMP1,samplecntSMP2,samplecntSMP3,samplecntSMP4,samplecntSMP5,samplecntSMP6,samplecntSMP7,samplecntSMP8;
      uint16_t samplepntSMP1,samplepntSMP2,samplepntSMP3,samplepntSMP4,samplepntSMP5,samplepntSMP6,samplepntSMP7,samplepntSMP8;
    
      uint8_t samplKit = 0;
      
    void loop() {  
      
      int16_t total;
      uint8_t divider = 0;
      uint8_t MUX=0;
      
      while(1) { 
        
         MIDI.read();
    
        samplKit = 0;
        if (!digitalRead(PIN_E0))  samplKit = 1;
        if (!digitalRead(PIN_E1))  samplKit = 2; 
    
        //------ Add current sample word to ringbuffer FIFO --------------------  
            
        if (RingCount<255) {  //if space in ringbuffer
          total=0;
            if (samplecntSMP1) {
                phaccAG+=pitchAG;
                if (phaccAG & 128) {
                    phaccAG &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL1 + samplepntSMP1)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL9 + samplepntSMP1)-128);
                        break;  
                      case 2:
                        //total+=(pgm_read_byte_near(SMPL17 + samplepntSMP1)-128);
                        total+=(pgm_read_byte_near(SMPL17 + samplepntSMP1)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL1 + samplepntSMP1)-128);
                    samplepntSMP1++;
                    samplecntSMP1--;                
                }
          }
          if (samplecntSMP2) {
                phaccBO+=pitchBO;
                if (phaccBO & 128) {
                    phaccBO &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL2 + samplepntSMP2)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL10 + samplepntSMP2)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL18 + samplepntSMP2)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL2 + samplepntSMP2)-128);
                    samplepntSMP2++;
                    samplecntSMP2--;                
                }
          }
           if (samplecntSMP3) {
                phaccMA+=pitchMA;
                if (phaccMA & 128) {
                    phaccMA &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL3 + samplepntSMP3)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL11 + samplepntSMP3)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL19 + samplepntSMP3)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL3 + samplepntSMP3)-128);
                    samplepntSMP3++;
                    samplecntSMP3--;
                    
                }
          }
           if (samplecntSMP4) {
                phaccQU+=pitchQU;
                if (phaccQU & 128) {
                    phaccQU &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL4 + samplepntSMP4)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL12 + samplepntSMP4)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL20 + samplepntSMP4)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL4 + samplepntSMP4)-128);
                    samplepntSMP4++;
                    samplecntSMP4--;
                    
                }
          }
           if (samplecntSMP5) {
                phaccCA+=pitchCA;
                if (phaccCA & 128) {
                    phaccCA &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL5 + samplepntSMP5)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL13 + samplepntSMP5)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL21 + samplepntSMP5)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL5 + samplepntSMP5)-128);
                    samplepntSMP5++;
                    samplecntSMP5--;
                    
                }
          }    
          if (samplecntSMP6) {
                phaccTI+=pitchTI;
                if (phaccTI & 128) {
                    phaccTI &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL6 + samplepntSMP6)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL14 + samplepntSMP6)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL22 + samplepntSMP6)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL6 + samplepntSMP6)-128);
                    samplepntSMP6++;
                    samplecntSMP6--;
                    
                }
          }  
          if (samplecntSMP7) {
                phaccWH+=pitchWH;
                if (phaccWH & 128) {
                    phaccWH &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL7 + samplepntSMP7)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL15 + samplepntSMP7)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL23 + samplepntSMP7)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL7 + samplepntSMP7)-128);
                    samplepntSMP7++;
                    samplecntSMP7--;
                    
                }
          }  
          if (samplecntSMP8) {
                phaccCH+=pitchCH;
                if (phaccCH & 128) {
                    phaccCH &= 127;
                    switch (samplKit) {
                      case 0:
                        total+=(pgm_read_byte_near(SMPL8 + samplepntSMP8)-128);
                        break;
                      case 1:
                        total+=(pgm_read_byte_near(SMPL16 + samplepntSMP8)-128);
                        break;  
                      case 2:
                        total+=(pgm_read_byte_near(SMPL24 + samplepntSMP8)-128);
                        break;                  
                    }
                    //total+=(pgm_read_byte_near(SMPL8 + samplepntSMP8)-128);
                    samplepntSMP8++;
                    samplecntSMP8--;
                    
                }
          }  
          
          total>>=1;    // divide by 2      
          // if (!(PINB&4)) total>>=1;      // noisegate?
          total+=128;  // make it centered audiowave      
         
          if (total>255) total=255;     // total is int16, truncating to 255 makes sense.
    
          // noisegate
          //uint16_t accSum = samplecntSMP1+samplecntSMP2+samplecntSMP3+samplecntSMP4+samplecntSMP5+samplecntSMP6+samplecntSMP7+samplecntSMP8;
          //if (accSum==0) total = 0;
          
          cli();
          Ringbuffer[RingWrite]=total;
          RingWrite++;
          RingCount++;
          sei();
        }
    
    //----------------------------------------------------------------------------
    
    //----------------- Handle Triggers ------------------------------
    /*
    
            if (PIND&4) {
              samplepntSMP2=0;
              samplecntSMP2=1474;
            }
            if (PIND&8) {
              samplepntAG=0;
              samplecntAG=1720;
            }
            if (PIND&16) {
              samplepntTI=0;
              samplecntTI=3680;
            }
            if (PIND&32) {
              samplepntQU=0;
              samplecntQU=6502;
            }
            if (PIND&64) {
              samplepntMA=0;
              samplecntMA=394;
            }
            if (PIND&128) {
              samplepntCH=0;
              samplecntCH=5596;
            }
    
            if (PINB&1) {
              samplepntCA=0;
              samplecntCA=2174;
            }
             if (PINB&2) {
              samplepntWH=0;
              samplecntWH=2670;
            }
            */
     
    
    //-----------------------------------------------------------------
    
    //--------------- ADC block -------------------------------------
    
      if (!(divider++)) {
        if (!(ADCSRA & 64)) {
    
          uint16_t pitch=((ADCL+(ADCH<<8))>>3)+1;
          //if (MUX==0) pitchAG=pitch;
          //if (MUX==1) pitchTI=pitch;
          //if (MUX==2) pitchQU=pitch;
          if (MUX==3) {
            pitchAG=pitch;
            pitchTI=pitch;
            pitchQU=pitch;
            pitchMA=pitch;
            pitchCH=pitch;
            pitchWH=pitch;        
            pitchCA=pitch;
            pitchBO=pitch;      
          }
          //if (MUX==4) pitchCH=pitch;
          //if (MUX==5) pitchWH=pitch;
    
          MUX++;
          if (MUX==6) MUX=0;
          ADMUX = 64 | MUX; //Select MUX
          sbi(ADCSRA, ADSC); //start next conversation
        }
      }
      
    //---------------------------------------------------------------
      
      } 
    }
    /*  MIDI HANDLERS  */
    void midiNoteOnHandler(byte channel, byte note, byte velocity) {
      digitalWrite(led, HIGH);
      handleMIDINOTE(0x90, note, 127);
    }
    
    void midiNoteOffHandler(byte channel, byte note, byte velocity) {
      digitalWrite(led, LOW);
      handleMIDINOTE(0x80, note, 0);
    }
    
    void midiControlHandler(byte channel, byte number, byte value) {
      if (number==1) {
        pitchAG=value;
        pitchTI=value;
        pitchQU=value;
        pitchMA=value;
        pitchCH=value;
        pitchWH=value;    
        pitchCA=value;
        pitchBO=value;
      }
    }
    
    void handleMIDINOTE(uint8_t message, uint8_t note, uint8_t vel) {
      
      if ((!vel) && (message == 0x90)) message = 0x80;
      if (message == 0x80) {
        
      }
      if (message == 0x90) {
          if (note==36) {
              samplepntSMP1=0;
              //samplecntSMP1=SampleLength1;//1474;
              samplecntSMP1= smpLength1[samplKit];
            }
            if (note==37) {
              samplepntSMP2=0;
              //samplecntSMP2=SampleLength2;
              samplecntSMP2= smpLength2[samplKit];
            }
            if (note==38) {
              samplepntSMP3=0;
              //samplecntSMP3=SampleLength3;
              samplecntSMP3= smpLength3[samplKit];
            }
            if (note==39) {
              samplepntSMP4=0;
              //samplecntSMP4=SampleLength4;
              samplecntSMP4= smpLength4[samplKit];
            }
            if (note==40) {
              samplepntSMP5=0;
              //samplecntSMP5=SampleLength5;
              samplecntSMP5= smpLength5[samplKit];
            }
            if (note==41) {
              samplepntSMP6=0;
              samplecntSMP6=SampleLength6;
              samplecntSMP6= smpLength6[samplKit];
            }
    
            if (note==42) {
              samplepntSMP7=0;
              //samplecntSMP7=SampleLength7;
              samplecntSMP7= smpLength7[samplKit];
            }
             if (note==43) {
              samplepntSMP8=0;
              //samplecntSMP8=SampleLength8;
              samplecntSMP8= smpLength8[samplKit];
            }
       
      }
    }
    example for one of the 8 arrays per drumkit in the external headers:

    Code:
    #define SampleLength11 752  // CONGA & CLAVE
    const unsigned char SMPL11[SampleLength11] PROGMEM =
    {
      125,82,65,93,135,172,181,161,118,74,48,54,88,139,184,207,199,166,124,92,86,109,150,192,217,215,187,146,108,90,100,130,166,191,194,171,132,93,68,68,90,123,151,160,147,115,80,54,50,68,100,132,150,147,125,96,72,66,80,111,144,167,172,158,133,109,99,107,132,162,186,194,183,159,132,116,116,131,156,177,185,176,152,124,103,96,105,125,144,154,149,130,104,83,74,80,
      98,119,134,135,123,103,84,76,81,99,122,141,148,142,127,111,102,105,121,142,161,171,168,154,137,125,123,133,149,166,175,172,158,139,123,116,119,131,145,153,151,138,120,104,94,95,105,119,129,130,123,108,94,86,87,98,113,126,132,130,120,109,102,103,113,129,143,152,152,144,134,126,125,131,143,156,164,164,156,144,133,127,130,137,147,153,152,144,131,119,111,110,115,124,130,131,125,115,103,96,
      96,101,111,120,124,122,116,108,102,102,109,120,130,137,139,134,128,123,122,128,137,147,153,155,150,143,136,133,134,140,147,152,152,147,138,129,123,122,125,130,134,134,130,122,113,107,105,108,114,120,122,120,115,109,104,104,108,115,123,128,129,126,122,119,119,123,130,138,144,145,143,139,135,133,135,140,146,150,150,147,141,135,131,130,132,136,138,138,134,128,121,116,115,116,119,122,123,121,117,112,
      108,107,110,114,119,123,123,121,118,116,116,119,125,131,135,137,136,133,131,131,133,137,142,145,146,145,141,137,135,135,136,139,141,141,138,133,128,124,123,123,125,127,127,124,121,116,113,112,113,116,119,120,120,119,116,114,115,117,121,125,129,130,130,128,127,127,130,133,137,140,142,141,139,137,135,136,138,140,142,141,140,136,133,130,129,129,130,131,130,128,125,121,118,117,117,119,120,121,120,118,
      116,115,115,116,119,122,124,125,125,124,123,124,126,129,132,135,136,136,135,134,134,135,137,139,140,140,139,137,135,133,132,133,133,134,133,131,129,126,123,122,122,122,123,123,122,120,118,116,116,117,118,120,122,122,122,121,121,121,123,125,128,130,131,131,131,131,131,132,134,136,138,138,138,136,135,134,134,134,135,135,135,133,131,129,127,126,126,126,126,125,124,122,121,119,118,119,119,120,121,121,
      120,120,119,120,121,122,124,126,127,127,127,127,128,129,131,133,134,135,135,134,134,134,134,135,135,136,135,135,133,132,130,129,129,129,129,128,127,125,124,122,121,121,121,122,122,121,121,120,119,119,120,121,122,123,124,124,124,125,125,127,128,130,131,132,132,132,132,132,133,134,135,135,135,135,134,133,132,132,131,131,131,130,129,128,127,125,125,124,124,124,124,123,122,121,120,120,121,121,122,122,
      123,123,123,123,124,125,126,127,128,129,129,130,130,130,131,132,133,134,134,134,133,133,133,133,133,133,132,132,131,130,129,128,127,127,127,126,126,125,124,123,122,122,122,122,122,123,123,122,122,122,123,123,124,125,126,127,127,127,128,128,129,130,131,132,132,132,132,132,132,132,133,133,133,132,132,131,130,130,129,129,129,128,128,127,127,126,125,125,125,125,125,125,125,124,124,124,124,125,125,126,
      126,126,126,127,127,127,128,128,129,129,129,129,129,129,129,130,130,130,130,130,130,130,129,129,129,129,129,129,128,128,128,128,128,128,127,127,127,127,127,127,127,127,127,127,127,128,128,128,128,128,128,128,128,128,128,128,
    };

  5. #5
    Junior Member
    Join Date
    Apr 2020
    Posts
    2
    Hello Gregor,

    when you're getting over 53% of flash memory, you're getting over the 64kb border, which means your address pointers are three bytes instead of two. I just had a quick look over your code, but it seems that you use the "pgm_read_byte_near()" macro to read your samples, which takes only a two byte address (as the "_near" suffix implies). Try to use the "pgm_read_byte_far()" macro instead.

    Bye,

    Patrick

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,146
    These start 0:
    Code:
    uint8_t RingWrite=0;
    uint8_t RingRead=0;
    >> the RingWrite++ only increments with no checks to wrap to 0 when > 255 for indexing into :: Ringbuffer[256];

    >> the ISR can reduce RingCount:
    Code:
        if (RingCount) {                            //If entry in FIFO..
          OCR2A = Ringbuffer[(RingRead++)];          //Output LSB of 16-bit DAC
          RingCount--;
        }
    >> That shows too where RingRead++ is incremented - it is never decremented or set to zero when it wraps >255


    Both of those will run through memory off the end of the Ringbuffer[256]; array without bounding checks - it is not a Ring buffer but a list that grows to the end of RAM.

    To be a usable Ring both when '++' - each in one spot need to have a test : if ( RingXXX>255 ) RingXXX = 0;

  7. #7
    Senior Member
    Join Date
    May 2017
    Posts
    125
    Quote Originally Posted by defragster View Post
    These start 0:
    Code:
    uint8_t RingWrite=0;
    uint8_t RingRead=0;
    >> the RingWrite++ only increments with no checks to wrap to 0 when > 255 for indexing into :: Ringbuffer[256];

    >> the ISR can reduce RingCount:
    Code:
        if (RingCount) {                            //If entry in FIFO..
          OCR2A = Ringbuffer[(RingRead++)];          //Output LSB of 16-bit DAC
          RingCount--;
        }
    >> That shows too where RingRead++ is incremented - it is never decremented or set to zero when it wraps >255


    Both of those will run through memory off the end of the Ringbuffer[256]; array without bounding checks - it is not a Ring buffer but a list that grows to the end of RAM.

    To be a usable Ring both when '++' - each in one spot need to have a test : if ( RingXXX>255 ) RingXXX = 0;
    You're right.
    But the following question, if the variables are defined as uint8_t, will they not automatically return to 0 at 255++?

  8. #8
    Junior Member
    Join Date
    Apr 2020
    Posts
    4
    Quote Originally Posted by defragster View Post
    >> the RingWrite++ only increments with no checks to wrap to 0 when > 255 for indexing into :: Ringbuffer[256];
    >> That shows too where RingRead++ is incremented - it is never decremented or set to zero when it wraps >255
    being a uint8_t ... i thought wrapping>255 automatically resets it to 0? how can it ever exceed 255?

  9. #9
    Junior Member
    Join Date
    Apr 2020
    Posts
    4
    Quote Originally Posted by pdaehne View Post
    Hello Gregor,

    when you're getting over 53% of flash memory, you're getting over the 64kb border, which means your address pointers are three bytes instead of two. I just had a quick look over your code, but it seems that you use the "pgm_read_byte_near()" macro to read your samples, which takes only a two byte address (as the "_near" suffix implies). Try to use the "pgm_read_byte_far()" macro instead.

    Bye,

    Patrick
    Thank you Patrick, i will check that.

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,146
    Quote Originally Posted by GrZl View Post
    being a uint8_t ... i thought wrapping>255 automatically resets it to 0? how can it ever exceed 255?
    Correct,it should ...Too used to 32 bit to read the code I posted …

    >I posted this and somehow clicked the 'delete' … restored
    Last edited by defragster; 04-09-2020 at 08:39 AM.

Posting Permissions

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